3030import static com .oracle .svm .espresso .classfile .Constants .ACC_STATIC ;
3131import static com .oracle .svm .espresso .classfile .Constants .ACC_SYNTHETIC ;
3232import static com .oracle .svm .espresso .classfile .Constants .ACC_VARARGS ;
33+ import static com .oracle .svm .espresso .classfile .Constants .JVM_RECOGNIZED_METHOD_MODIFIERS ;
3334import static com .oracle .svm .interpreter .metadata .Bytecodes .BREAKPOINT ;
3435import static com .oracle .svm .interpreter .metadata .CremaMethodAccess .toJVMCI ;
3536
5152import com .oracle .svm .core .invoke .Target_java_lang_invoke_MemberName ;
5253import com .oracle .svm .core .meta .MethodPointer ;
5354import com .oracle .svm .core .util .VMError ;
54- import com .oracle .svm .espresso .classfile .Constants ;
5555import com .oracle .svm .espresso .classfile .JavaVersion ;
5656import com .oracle .svm .espresso .classfile .ParserMethod ;
5757import com .oracle .svm .espresso .classfile .attributes .CodeAttribute ;
7979 * also abstract methods for vtable calls.
8080 */
8181public class InterpreterResolvedJavaMethod implements ResolvedJavaMethod , CremaMethodAccess {
82+ /**
83+ * This flag denotes a method that was originally native but was substituted by a non-native
84+ * method.
85+ */
86+ private static final int ACC_SUBSTITUTED_NATIVE = 0x80000000 ;
87+
8288 public static final InterpreterResolvedJavaMethod [] EMPTY_ARRAY = new InterpreterResolvedJavaMethod [0 ];
8389 public static final LocalVariableTable EMPTY_LOCAL_VARIABLE_TABLE = new LocalVariableTable (new Local [0 ]);
8490 public static final ExceptionHandler [] EMPTY_EXCEPTION_HANDLERS = new ExceptionHandler [0 ];
@@ -93,9 +99,13 @@ public class InterpreterResolvedJavaMethod implements ResolvedJavaMethod, CremaM
9399 private final Symbol <Name > name ;
94100 private final int maxLocals ;
95101 private final int maxStackSize ;
96- private final int modifiers ;
97- private final boolean isSubstitutedNative ;
98- private final boolean signaturePolymorphic ;
102+ /**
103+ * Contains standard modifiers in the low 16 bits, and non-standard flags in the upper 16 bits.
104+ *
105+ * @see #ACC_SUBSTITUTED_NATIVE
106+ * @see com.oracle.svm.espresso.classfile.Constants
107+ */
108+ private final int flags ;
99109
100110 @ Platforms (Platform .HOSTED_ONLY .class ) //
101111 private ResolvedJavaMethod originalMethod ;
@@ -124,7 +134,7 @@ public InlinedBy(InterpreterResolvedJavaMethod holder, Set<InterpreterResolvedJa
124134 }
125135 }
126136
127- protected InlinedBy inlinedBy ;
137+ protected final InlinedBy inlinedBy ;
128138
129139 public static final int VTBL_NO_ENTRY = -1 ;
130140 public static final int VTBL_ONE_IMPL = -2 ;
@@ -152,57 +162,90 @@ public InlinedBy(InterpreterResolvedJavaMethod holder, Set<InterpreterResolvedJa
152162
153163 // Only called during universe building
154164 @ Platforms (Platform .HOSTED_ONLY .class )
155- protected InterpreterResolvedJavaMethod (ResolvedJavaMethod originalMethod , Symbol <Name > name , int maxLocals , int maxStackSize , int modifiers , InterpreterResolvedObjectType declaringClass ,
156- InterpreterUnresolvedSignature signature , boolean isSubstitutedNative ,
165+ private InterpreterResolvedJavaMethod (ResolvedJavaMethod originalMethod , Symbol <Name > name , int maxLocals , int maxStackSize , int flags ,
166+ InterpreterResolvedObjectType declaringClass , InterpreterUnresolvedSignature signature , Symbol < Signature > signatureSymbol ,
157167 byte [] code , ExceptionHandler [] exceptionHandlers , LineNumberTable lineNumberTable , LocalVariableTable localVariableTable ,
158168 ReferenceConstant <FunctionPointerHolder > nativeEntryPoint , int vtableIndex , int gotOffset , int enterStubOffset , int methodId ) {
159- this (name , maxLocals , maxStackSize , modifiers , isSubstitutedNative , declaringClass , signature , code , exceptionHandlers , lineNumberTable , localVariableTable , nativeEntryPoint , vtableIndex ,
160- gotOffset ,
161- enterStubOffset , methodId , null );
169+ this .name = MetadataUtil .requireNonNull (name );
170+ this .maxLocals = maxLocals ;
171+ this .maxStackSize = maxStackSize ;
172+ this .flags = flags ;
173+ this .declaringClass = MetadataUtil .requireNonNull (declaringClass );
174+ this .signature = MetadataUtil .requireNonNull (signature );
175+ this .signatureSymbol = MetadataUtil .requireNonNull (signatureSymbol );
176+ this .interpretedCode = code ;
177+ this .exceptionHandlers = exceptionHandlers ;
178+ this .lineNumberTable = lineNumberTable ;
179+ this .localVariableTable = localVariableTable ;
180+ this .nativeEntryPoint = nativeEntryPoint ;
181+ this .vtableIndex = vtableIndex ;
182+ this .gotOffset = gotOffset ;
183+ this .enterStubOffset = enterStubOffset ;
184+ this .methodId = methodId ;
185+ this .inlinedBy = new InlinedBy (this , new HashSet <>());
186+ this .intrinsic = null ;
187+
162188 this .originalMethod = originalMethod ;
163- this .needMethodBody = false ;
164- this .inlinedBy = new InterpreterResolvedJavaMethod .InlinedBy (this , new HashSet <>());
165189 }
166190
167- private InterpreterResolvedJavaMethod (Symbol <Name > name ,
168- int maxLocals , int maxStackSize ,
169- int modifiers , boolean isSubstitutedNative ,
170- InterpreterResolvedObjectType declaringClass , InterpreterUnresolvedSignature signature ,
191+ // Used at run-time for deserialization
192+ private InterpreterResolvedJavaMethod (Symbol <Name > name , int maxLocals , int maxStackSize , int flags ,
193+ InterpreterResolvedObjectType declaringClass , InterpreterUnresolvedSignature signature , Symbol <Signature > signatureSymbol ,
171194 byte [] code , ExceptionHandler [] exceptionHandlers , LineNumberTable lineNumberTable , LocalVariableTable localVariableTable ,
172- ReferenceConstant <FunctionPointerHolder > nativeEntryPoint , int vtableIndex , int gotOffset , int enterStubOffset , int methodId , SignaturePolymorphicIntrinsic intrinsic ) {
195+ ReferenceConstant <FunctionPointerHolder > nativeEntryPoint , int vtableIndex , int gotOffset , int enterStubOffset , int methodId ) {
173196 this .name = MetadataUtil .requireNonNull (name );
174197 this .maxLocals = maxLocals ;
175198 this .maxStackSize = maxStackSize ;
176- this .modifiers = modifiers ;
177- this .isSubstitutedNative = isSubstitutedNative ;
199+ this .flags = flags ;
178200 this .declaringClass = MetadataUtil .requireNonNull (declaringClass );
179201 this .signature = MetadataUtil .requireNonNull (signature );
202+ this .signatureSymbol = MetadataUtil .requireNonNull (signatureSymbol );
180203 this .interpretedCode = code ;
181204 this .exceptionHandlers = exceptionHandlers ;
182205 this .lineNumberTable = lineNumberTable ;
183206 this .localVariableTable = localVariableTable ;
184-
185207 this .nativeEntryPoint = nativeEntryPoint ;
186208 this .vtableIndex = vtableIndex ;
187209 this .gotOffset = gotOffset ;
188210 this .enterStubOffset = enterStubOffset ;
189211 this .methodId = methodId ;
190212 this .inlinedBy = new InlinedBy (this , new HashSet <>());
213+ this .intrinsic = null ;
214+ }
191215
192- this .signatureSymbol = CremaMethodAccess .toSymbol (signature , SymbolsSupport .getSignatures ());
193- this .intrinsic = intrinsic ;
194- this .signaturePolymorphic = ParserMethod .isDeclaredSignaturePolymorphic (declaringClass .getSymbolicType (), signatureSymbol , getOriginalModifiers (modifiers , isSubstitutedNative ),
195- JavaVersion .HOST_VERSION );
216+ // Used at run-time for signature-polymorphic instantiation
217+ private InterpreterResolvedJavaMethod (Symbol <Name > name , int maxLocals , int flags ,
218+ InterpreterResolvedObjectType declaringClass , InterpreterUnresolvedSignature signature , Symbol <Signature > signatureSymbol ,
219+ int vtableIndex , int gotOffset , int enterStubOffset , int methodId , SignaturePolymorphicIntrinsic intrinsic ) {
220+ this .name = MetadataUtil .requireNonNull (name );
221+ this .maxLocals = maxLocals ;
222+ this .maxStackSize = 0 ;
223+ this .flags = flags ;
224+ this .declaringClass = MetadataUtil .requireNonNull (declaringClass );
225+ this .signature = MetadataUtil .requireNonNull (signature );
226+ this .signatureSymbol = MetadataUtil .requireNonNull (signatureSymbol );
227+ // not bytecode-interpretable
228+ this .interpretedCode = null ;
229+ this .exceptionHandlers = null ;
230+ this .lineNumberTable = null ;
231+ this .localVariableTable = null ;
232+ this .nativeEntryPoint = null ;
233+ this .vtableIndex = vtableIndex ;
234+ this .gotOffset = gotOffset ;
235+ this .enterStubOffset = enterStubOffset ;
236+ this .methodId = methodId ;
237+ this .inlinedBy = null ;
238+ this .intrinsic = MetadataUtil .requireNonNull (intrinsic );
196239 }
197240
241+ // Used at run-time for the crema sub-class
198242 protected InterpreterResolvedJavaMethod (InterpreterResolvedObjectType declaringClass , ParserMethod m , int vtableIndex ) {
199243 assert RuntimeClassLoading .isSupported ();
200244 this .name = MetadataUtil .requireNonNull (m .getName ());
201245 this .signatureSymbol = MetadataUtil .requireNonNull (m .getSignature ());
202-
203246 this .declaringClass = MetadataUtil .requireNonNull (declaringClass );
204- this .modifiers = m .getFlags () & Constants . JVM_RECOGNIZED_METHOD_MODIFIERS ;
205- this . signaturePolymorphic = ( m . getFlags () & ACC_SIGNATURE_POLYMORPHIC ) ! = 0 ;
247+ this .flags = m .getFlags ();
248+ assert ( flags & ACC_SUBSTITUTED_NATIVE ) = = 0 ;
206249 CodeAttribute codeAttribute = (CodeAttribute ) m .getAttribute (CodeAttribute .NAME );
207250 if (codeAttribute != null ) {
208251 this .maxLocals = codeAttribute .getMaxLocals ();
@@ -223,37 +266,51 @@ protected InterpreterResolvedJavaMethod(InterpreterResolvedObjectType declaringC
223266 this .gotOffset = -2 /* -GOT_NO_ENTRY */ ;
224267 this .enterStubOffset = EST_NO_ENTRY ;
225268 this .methodId = UNKNOWN_METHOD_ID ;
226- this .inlinedBy = new InlinedBy (this , new HashSet <>());
227- this .isSubstitutedNative = false ;
269+ this .inlinedBy = null ;
228270 this .intrinsic = null ;
229271 }
230272
231273 @ VisibleForSerialization
232- public static InterpreterResolvedJavaMethod create (String name , int maxLocals , int maxStackSize , int modifiers , InterpreterResolvedObjectType declaringClass ,
274+ public static InterpreterResolvedJavaMethod createForDeserialization (String name , int maxLocals , int maxStackSize , int flags , InterpreterResolvedObjectType declaringClass ,
233275 InterpreterUnresolvedSignature signature ,
234276 byte [] code , ExceptionHandler [] exceptionHandlers , LineNumberTable lineNumberTable , LocalVariableTable localVariableTable ,
235277 ReferenceConstant <FunctionPointerHolder > nativeEntryPoint , int vtableIndex , int gotOffset , int enterStubOffset , int methodId ) {
236278 Symbol <Name > nameSymbol = SymbolsSupport .getNames ().getOrCreate (name );
237- return new InterpreterResolvedJavaMethod (nameSymbol , maxLocals , maxStackSize , modifiers , false , declaringClass , signature , code ,
238- exceptionHandlers , lineNumberTable , localVariableTable , nativeEntryPoint , vtableIndex , gotOffset , enterStubOffset , methodId , null );
279+ Symbol <Signature > signatureSymbol = CremaMethodAccess .toSymbol (signature , SymbolsSupport .getSignatures ());
280+ return new InterpreterResolvedJavaMethod (nameSymbol , maxLocals , maxStackSize , flags , declaringClass , signature , signatureSymbol , code ,
281+ exceptionHandlers , lineNumberTable , localVariableTable , nativeEntryPoint , vtableIndex , gotOffset , enterStubOffset , methodId );
239282 }
240283
241284 // Only called during universe building
242285 @ Platforms (Platform .HOSTED_ONLY .class )
243- public static InterpreterResolvedJavaMethod create (ResolvedJavaMethod originalMethod , String name , int maxLocals , int maxStackSize , int modifiers ,
286+ public static InterpreterResolvedJavaMethod createAtBuildTime (ResolvedJavaMethod originalMethod , String name , int maxLocals , int maxStackSize , int modifiers ,
244287 InterpreterResolvedObjectType declaringClass ,
245288 InterpreterUnresolvedSignature signature , boolean isSubstitutedNative ,
246289 byte [] code , ExceptionHandler [] exceptionHandlers , LineNumberTable lineNumberTable , LocalVariableTable localVariableTable ,
247290 ReferenceConstant <FunctionPointerHolder > nativeEntryPoint , int vtableIndex , int gotOffset , int enterStubOffset , int methodId ) {
248291 Symbol <Name > nameSymbol = SymbolsSupport .getNames ().getOrCreate (name );
249- return new InterpreterResolvedJavaMethod (originalMethod , nameSymbol , maxLocals , maxStackSize , modifiers , declaringClass , signature , isSubstitutedNative , code ,
292+ Symbol <Signature > signatureSymbol = CremaMethodAccess .toSymbol (signature , SymbolsSupport .getSignatures ());
293+ int flags = createFlags (modifiers , declaringClass , signatureSymbol , isSubstitutedNative , originalMethod );
294+ return new InterpreterResolvedJavaMethod (originalMethod , nameSymbol , maxLocals , maxStackSize , flags , declaringClass , signature , signatureSymbol , code ,
250295 exceptionHandlers , lineNumberTable , localVariableTable , nativeEntryPoint , vtableIndex , gotOffset , enterStubOffset , methodId );
251296 }
252297
298+ @ Platforms (Platform .HOSTED_ONLY .class )
299+ private static int createFlags (int modifiers , InterpreterResolvedObjectType declaringClass , Symbol <Signature > signatureSymbol , boolean isSubstitutedNative , ResolvedJavaMethod originalMethod ) {
300+ int newModifiers = modifiers ;
301+ if (ParserMethod .isDeclaredSignaturePolymorphic (declaringClass .getSymbolicType (), signatureSymbol , getOriginalModifiers (modifiers , isSubstitutedNative ), JavaVersion .HOST_VERSION )) {
302+ newModifiers |= ACC_SIGNATURE_POLYMORPHIC ;
303+ }
304+ if (isSubstitutedNative ) {
305+ newModifiers |= ACC_SUBSTITUTED_NATIVE ;
306+ }
307+ return newModifiers ;
308+ }
309+
253310 @ Override
254311 public final boolean isDeclaredSignaturePolymorphic () {
255312 // Note: might not be true for the instantiation of polymorphic signature intrinsics.
256- return signaturePolymorphic ;
313+ return ( flags & ACC_SIGNATURE_POLYMORPHIC ) != 0 ;
257314 }
258315
259316 @ Override
@@ -262,8 +319,9 @@ public final InterpreterResolvedJavaMethod createSignaturePolymorphicIntrinsic(S
262319 assert iid != null ;
263320 assert intrinsic == null ;
264321 int newModifiers ;
322+ boolean isSubstitutedNative = (flags & ACC_SUBSTITUTED_NATIVE ) != 0 ;
265323 if (iid == SignaturePolymorphicIntrinsic .InvokeGeneric ) {
266- newModifiers = getOriginalModifiers (modifiers , isSubstitutedNative ) & ~ACC_VARARGS ;
324+ newModifiers = getOriginalModifiers (flags , isSubstitutedNative ) & ~( ACC_VARARGS | ACC_SUBSTITUTED_NATIVE | ACC_SIGNATURE_POLYMORPHIC ) ;
267325 } else {
268326 newModifiers = ACC_NATIVE | ACC_SYNTHETIC | ACC_FINAL ;
269327 if (iid .isStaticSignaturePolymorphic ()) {
@@ -272,9 +330,8 @@ public final InterpreterResolvedJavaMethod createSignaturePolymorphicIntrinsic(S
272330 }
273331 assert Modifier .isNative (newModifiers );
274332 InterpreterUnresolvedSignature jvmciSignature = CremaMethodAccess .toJVMCI (newSignature , SymbolsSupport .getTypes ());
275- return new InterpreterResolvedJavaMethod (name , jvmciSignature .getParameterCount (true ), 0 , newModifiers , isSubstitutedNative , declaringClass , jvmciSignature ,
276- null , null , null , null , // not bytecode-interpretable
277- null , vtableIndex , gotOffset , enterStubOffset , methodId , iid );
333+ return new InterpreterResolvedJavaMethod (name , jvmciSignature .getParameterCount (true ), newModifiers , declaringClass , jvmciSignature , newSignature ,
334+ vtableIndex , gotOffset , enterStubOffset , methodId , iid );
278335 }
279336
280337 private static int getOriginalModifiers (int modifiers , boolean isSubstitutedNative ) {
@@ -423,7 +480,11 @@ public final LocalVariableTable getLocalVariableTable() {
423480
424481 @ Override
425482 public final int getModifiers () {
426- return modifiers ;
483+ return flags & JVM_RECOGNIZED_METHOD_MODIFIERS ;
484+ }
485+
486+ public int getFlags () {
487+ return flags ;
427488 }
428489
429490 @ Override
@@ -593,6 +654,9 @@ public final boolean isInterpreterExecutable() {
593654 }
594655
595656 public final Set <InterpreterResolvedJavaMethod > getInlinedBy () {
657+ if (inlinedBy == null ) {
658+ return Set .of ();
659+ }
596660 return inlinedBy .inliners ;
597661 }
598662
0 commit comments