24
24
*/
25
25
package jdk .internal .foreign .abi ;
26
26
27
+ import java .lang .classfile .Annotation ;
27
28
import java .lang .classfile .ClassFile ;
28
29
import java .lang .classfile .CodeBuilder ;
29
30
import java .lang .classfile .Label ;
46
47
import jdk .internal .foreign .abi .Binding .ShiftRight ;
47
48
import jdk .internal .foreign .abi .Binding .VMLoad ;
48
49
import jdk .internal .foreign .abi .Binding .VMStore ;
50
+ import jdk .internal .vm .annotation .ForceInline ;
49
51
import sun .security .action .GetBooleanAction ;
52
+ import sun .security .action .GetIntegerAction ;
50
53
import sun .security .action .GetPropertyAction ;
51
54
52
55
import java .io .IOException ;
56
+ import java .lang .classfile .attribute .RuntimeVisibleAnnotationsAttribute ;
53
57
import java .lang .constant .ClassDesc ;
54
58
import java .lang .constant .ConstantDesc ;
55
59
import java .lang .constant .DynamicConstantDesc ;
@@ -77,6 +81,8 @@ public class BindingSpecializer {
77
81
= GetPropertyAction .privilegedGetProperty ("jdk.internal.foreign.abi.Specializer.DUMP_CLASSES_DIR" );
78
82
private static final boolean PERFORM_VERIFICATION
79
83
= GetBooleanAction .privilegedGetProperty ("jdk.internal.foreign.abi.Specializer.PERFORM_VERIFICATION" );
84
+ private static final int SCOPE_DEDUP_DEPTH
85
+ = GetIntegerAction .privilegedGetProperty ("jdk.internal.foreign.abi.Specializer.SCOPE_DEDUP_DEPTH" , 2 );
80
86
81
87
// Bunch of helper constants
82
88
private static final int CLASSFILE_VERSION = ClassFileFormatVersion .latest ().major ();
@@ -99,6 +105,7 @@ public class BindingSpecializer {
99
105
private static final ClassDesc CD_ValueLayout_OfFloat = referenceClassDesc (ValueLayout .OfFloat .class );
100
106
private static final ClassDesc CD_ValueLayout_OfDouble = referenceClassDesc (ValueLayout .OfDouble .class );
101
107
private static final ClassDesc CD_AddressLayout = referenceClassDesc (AddressLayout .class );
108
+ private static final ClassDesc CD_ForceInline = referenceClassDesc (ForceInline .class );
102
109
103
110
private static final MethodTypeDesc MTD_NEW_BOUNDED_ARENA = MethodTypeDesc .of (CD_Arena , CD_long );
104
111
private static final MethodTypeDesc MTD_NEW_EMPTY_ARENA = MethodTypeDesc .of (CD_Arena );
@@ -196,8 +203,9 @@ private static byte[] specializeHelper(MethodType leafType, MethodType callerMet
196
203
clb .withFlags (ACC_PUBLIC + ACC_FINAL + ACC_SUPER )
197
204
.withSuperclass (CD_Object )
198
205
.withVersion (CLASSFILE_VERSION , 0 )
199
- .withMethodBody (METHOD_NAME , methodTypeDesc (callerMethodType ), ACC_PUBLIC | ACC_STATIC ,
200
- cb -> new BindingSpecializer (cb , callerMethodType , callingSequence , abi , leafType ).specialize ());
206
+ .withMethod (METHOD_NAME , methodTypeDesc (callerMethodType ), ACC_PUBLIC | ACC_STATIC ,
207
+ mb -> mb .with (RuntimeVisibleAnnotationsAttribute .of (Annotation .of (CD_ForceInline )))
208
+ .withCode (cb -> new BindingSpecializer (cb , callerMethodType , callingSequence , abi , leafType ).specialize ()));
201
209
});
202
210
203
211
if (DUMP_CLASSES_DIR != null ) {
@@ -502,11 +510,19 @@ private void emitAcquireScope() {
502
510
503
511
// start with 1 scope to maybe acquire on the stack
504
512
assert curScopeLocalIdx != -1 ;
505
- boolean hasOtherScopes = curScopeLocalIdx != 0 ;
506
- for (int i = 0 ; i < curScopeLocalIdx ; i ++) {
513
+ boolean hasLookup = false ;
514
+
515
+ // Here we check if the current scope has not been already acquired.
516
+ // To do that, we generate many comparisons (one per cached scope).
517
+ // Note that we always skip comparisons against the very first cached scope
518
+ // (as that is the function address, which typically belongs to another scope).
519
+ // We also stop the comparisons at SCOPE_DEDUP_DEPTH, to keep a lid on the size
520
+ // of the generated code.
521
+ for (int i = 1 ; i < curScopeLocalIdx && i <= SCOPE_DEDUP_DEPTH ; i ++) {
507
522
cb .dup () // dup for comparison
508
523
.aload (scopeSlots [i ])
509
524
.if_acmpeq (skipAcquire );
525
+ hasLookup = true ;
510
526
}
511
527
512
528
// 1 scope to acquire on the stack
@@ -516,10 +532,10 @@ private void emitAcquireScope() {
516
532
cb .invokevirtual (CD_MemorySessionImpl , "acquire0" , MTD_ACQUIRE0 ) // call acquire on the other
517
533
.astore (nextScopeLocal ); // store off one to release later
518
534
519
- if (hasOtherScopes ) { // avoid ASM generating a bunch of nops for the dead code
535
+ if (hasLookup ) { // avoid ASM generating a bunch of nops for the dead code
520
536
cb .goto_ (end )
521
- .labelBinding (skipAcquire )
522
- .pop (); // drop scope
537
+ .labelBinding (skipAcquire )
538
+ .pop (); // drop scope
523
539
}
524
540
525
541
cb .labelBinding (end );
0 commit comments