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 .espresso .classfile .bytecode .Bytecodes .INVOKEDYNAMIC ;
3435import static com .oracle .svm .interpreter .metadata .Bytecodes .BREAKPOINT ;
3536import static com .oracle .svm .interpreter .metadata .CremaMethodAccess .toJVMCI ;
5253import com .oracle .svm .core .invoke .Target_java_lang_invoke_MemberName ;
5354import com .oracle .svm .core .meta .MethodPointer ;
5455import com .oracle .svm .core .util .VMError ;
55- import com .oracle .svm .espresso .classfile .Constants ;
5656import com .oracle .svm .espresso .classfile .JavaVersion ;
5757import com .oracle .svm .espresso .classfile .ParserMethod ;
5858import com .oracle .svm .espresso .classfile .attributes .CodeAttribute ;
8080 * also abstract methods for vtable calls.
8181 */
8282public class InterpreterResolvedJavaMethod implements ResolvedJavaMethod , CremaMethodAccess {
83+ /**
84+ * This flag denotes a method that was originally native but was substituted by a non-native
85+ * method.
86+ */
87+ private static final int ACC_SUBSTITUTED_NATIVE = 0x80000000 ;
88+
8389 public static final InterpreterResolvedJavaMethod [] EMPTY_ARRAY = new InterpreterResolvedJavaMethod [0 ];
8490 public static final LocalVariableTable EMPTY_LOCAL_VARIABLE_TABLE = new LocalVariableTable (new Local [0 ]);
8591 public static final ExceptionHandler [] EMPTY_EXCEPTION_HANDLERS = new ExceptionHandler [0 ];
@@ -94,9 +100,13 @@ public class InterpreterResolvedJavaMethod implements ResolvedJavaMethod, CremaM
94100 private final Symbol <Name > name ;
95101 private final int maxLocals ;
96102 private final int maxStackSize ;
97- private final int modifiers ;
98- private final boolean isSubstitutedNative ;
99- private final boolean signaturePolymorphic ;
103+ /**
104+ * Contains standard modifiers in the low 16 bits, and non-standard flags in the upper 16 bits.
105+ *
106+ * @see #ACC_SUBSTITUTED_NATIVE
107+ * @see com.oracle.svm.espresso.classfile.Constants
108+ */
109+ private final int flags ;
100110
101111 @ Platforms (Platform .HOSTED_ONLY .class ) //
102112 private ResolvedJavaMethod originalMethod ;
@@ -125,7 +135,7 @@ public InlinedBy(InterpreterResolvedJavaMethod holder, Set<InterpreterResolvedJa
125135 }
126136 }
127137
128- protected InlinedBy inlinedBy ;
138+ protected final InlinedBy inlinedBy ;
129139
130140 public static final int VTBL_NO_ENTRY = -1 ;
131141 public static final int VTBL_ONE_IMPL = -2 ;
@@ -153,57 +163,90 @@ public InlinedBy(InterpreterResolvedJavaMethod holder, Set<InterpreterResolvedJa
153163
154164 // Only called during universe building
155165 @ Platforms (Platform .HOSTED_ONLY .class )
156- protected InterpreterResolvedJavaMethod (ResolvedJavaMethod originalMethod , Symbol <Name > name , int maxLocals , int maxStackSize , int modifiers , InterpreterResolvedObjectType declaringClass ,
157- InterpreterUnresolvedSignature signature , boolean isSubstitutedNative ,
166+ private InterpreterResolvedJavaMethod (ResolvedJavaMethod originalMethod , Symbol <Name > name , int maxLocals , int maxStackSize , int flags ,
167+ InterpreterResolvedObjectType declaringClass , InterpreterUnresolvedSignature signature , Symbol < Signature > signatureSymbol ,
158168 byte [] code , ExceptionHandler [] exceptionHandlers , LineNumberTable lineNumberTable , LocalVariableTable localVariableTable ,
159169 ReferenceConstant <FunctionPointerHolder > nativeEntryPoint , int vtableIndex , int gotOffset , int enterStubOffset , int methodId ) {
160- this (name , maxLocals , maxStackSize , modifiers , isSubstitutedNative , declaringClass , signature , code , exceptionHandlers , lineNumberTable , localVariableTable , nativeEntryPoint , vtableIndex ,
161- gotOffset ,
162- enterStubOffset , methodId , null );
170+ this .name = MetadataUtil .requireNonNull (name );
171+ this .maxLocals = maxLocals ;
172+ this .maxStackSize = maxStackSize ;
173+ this .flags = flags ;
174+ this .declaringClass = MetadataUtil .requireNonNull (declaringClass );
175+ this .signature = MetadataUtil .requireNonNull (signature );
176+ this .signatureSymbol = MetadataUtil .requireNonNull (signatureSymbol );
177+ this .interpretedCode = code ;
178+ this .exceptionHandlers = exceptionHandlers ;
179+ this .lineNumberTable = lineNumberTable ;
180+ this .localVariableTable = localVariableTable ;
181+ this .nativeEntryPoint = nativeEntryPoint ;
182+ this .vtableIndex = vtableIndex ;
183+ this .gotOffset = gotOffset ;
184+ this .enterStubOffset = enterStubOffset ;
185+ this .methodId = methodId ;
186+ this .inlinedBy = new InlinedBy (this , new HashSet <>());
187+ this .intrinsic = null ;
188+
163189 this .originalMethod = originalMethod ;
164- this .needMethodBody = false ;
165- this .inlinedBy = new InterpreterResolvedJavaMethod .InlinedBy (this , new HashSet <>());
166190 }
167191
168- private InterpreterResolvedJavaMethod (Symbol <Name > name ,
169- int maxLocals , int maxStackSize ,
170- int modifiers , boolean isSubstitutedNative ,
171- InterpreterResolvedObjectType declaringClass , InterpreterUnresolvedSignature signature ,
192+ // Used at run-time for deserialization
193+ private InterpreterResolvedJavaMethod (Symbol <Name > name , int maxLocals , int maxStackSize , int flags ,
194+ InterpreterResolvedObjectType declaringClass , InterpreterUnresolvedSignature signature , Symbol <Signature > signatureSymbol ,
172195 byte [] code , ExceptionHandler [] exceptionHandlers , LineNumberTable lineNumberTable , LocalVariableTable localVariableTable ,
173- ReferenceConstant <FunctionPointerHolder > nativeEntryPoint , int vtableIndex , int gotOffset , int enterStubOffset , int methodId , SignaturePolymorphicIntrinsic intrinsic ) {
196+ ReferenceConstant <FunctionPointerHolder > nativeEntryPoint , int vtableIndex , int gotOffset , int enterStubOffset , int methodId ) {
174197 this .name = MetadataUtil .requireNonNull (name );
175198 this .maxLocals = maxLocals ;
176199 this .maxStackSize = maxStackSize ;
177- this .modifiers = modifiers ;
178- this .isSubstitutedNative = isSubstitutedNative ;
200+ this .flags = flags ;
179201 this .declaringClass = MetadataUtil .requireNonNull (declaringClass );
180202 this .signature = MetadataUtil .requireNonNull (signature );
203+ this .signatureSymbol = MetadataUtil .requireNonNull (signatureSymbol );
181204 this .interpretedCode = code ;
182205 this .exceptionHandlers = exceptionHandlers ;
183206 this .lineNumberTable = lineNumberTable ;
184207 this .localVariableTable = localVariableTable ;
185-
186208 this .nativeEntryPoint = nativeEntryPoint ;
187209 this .vtableIndex = vtableIndex ;
188210 this .gotOffset = gotOffset ;
189211 this .enterStubOffset = enterStubOffset ;
190212 this .methodId = methodId ;
191213 this .inlinedBy = new InlinedBy (this , new HashSet <>());
214+ this .intrinsic = null ;
215+ }
192216
193- this .signatureSymbol = CremaMethodAccess .toSymbol (signature , SymbolsSupport .getSignatures ());
194- this .intrinsic = intrinsic ;
195- this .signaturePolymorphic = ParserMethod .isDeclaredSignaturePolymorphic (declaringClass .getSymbolicType (), signatureSymbol , getOriginalModifiers (modifiers , isSubstitutedNative ),
196- JavaVersion .HOST_VERSION );
217+ // Used at run-time for signature-polymorphic instantiation
218+ private InterpreterResolvedJavaMethod (Symbol <Name > name , int maxLocals , int flags ,
219+ InterpreterResolvedObjectType declaringClass , InterpreterUnresolvedSignature signature , Symbol <Signature > signatureSymbol ,
220+ int vtableIndex , int gotOffset , int enterStubOffset , int methodId , SignaturePolymorphicIntrinsic intrinsic ) {
221+ this .name = MetadataUtil .requireNonNull (name );
222+ this .maxLocals = maxLocals ;
223+ this .maxStackSize = 0 ;
224+ this .flags = flags ;
225+ this .declaringClass = MetadataUtil .requireNonNull (declaringClass );
226+ this .signature = MetadataUtil .requireNonNull (signature );
227+ this .signatureSymbol = MetadataUtil .requireNonNull (signatureSymbol );
228+ // not bytecode-interpretable
229+ this .interpretedCode = null ;
230+ this .exceptionHandlers = null ;
231+ this .lineNumberTable = null ;
232+ this .localVariableTable = null ;
233+ this .nativeEntryPoint = null ;
234+ this .vtableIndex = vtableIndex ;
235+ this .gotOffset = gotOffset ;
236+ this .enterStubOffset = enterStubOffset ;
237+ this .methodId = methodId ;
238+ this .inlinedBy = null ;
239+ this .intrinsic = MetadataUtil .requireNonNull (intrinsic );
197240 }
198241
242+ // Used at run-time for the crema sub-class
199243 protected InterpreterResolvedJavaMethod (InterpreterResolvedObjectType declaringClass , ParserMethod m , int vtableIndex ) {
200244 assert RuntimeClassLoading .isSupported ();
201245 this .name = MetadataUtil .requireNonNull (m .getName ());
202246 this .signatureSymbol = MetadataUtil .requireNonNull (m .getSignature ());
203-
204247 this .declaringClass = MetadataUtil .requireNonNull (declaringClass );
205- this .modifiers = m .getFlags () & Constants . JVM_RECOGNIZED_METHOD_MODIFIERS ;
206- this . signaturePolymorphic = ( m . getFlags () & ACC_SIGNATURE_POLYMORPHIC ) ! = 0 ;
248+ this .flags = m .getFlags ();
249+ assert ( flags & ACC_SUBSTITUTED_NATIVE ) = = 0 ;
207250 CodeAttribute codeAttribute = (CodeAttribute ) m .getAttribute (CodeAttribute .NAME );
208251 if (codeAttribute != null ) {
209252 this .maxLocals = codeAttribute .getMaxLocals ();
@@ -224,8 +267,7 @@ protected InterpreterResolvedJavaMethod(InterpreterResolvedObjectType declaringC
224267 this .gotOffset = -2 /* -GOT_NO_ENTRY */ ;
225268 this .enterStubOffset = EST_NO_ENTRY ;
226269 this .methodId = UNKNOWN_METHOD_ID ;
227- this .inlinedBy = new InlinedBy (this , new HashSet <>());
228- this .isSubstitutedNative = false ;
270+ this .inlinedBy = null ;
229271 this .intrinsic = null ;
230272 }
231273
@@ -244,31 +286,46 @@ private static int computeMaxStackSize(CodeAttribute codeAttribute) {
244286 }
245287
246288 @ VisibleForSerialization
247- public static InterpreterResolvedJavaMethod create (String name , int maxLocals , int maxStackSize , int modifiers , InterpreterResolvedObjectType declaringClass ,
289+ public static InterpreterResolvedJavaMethod createForDeserialization (String name , int maxLocals , int maxStackSize , int flags , InterpreterResolvedObjectType declaringClass ,
248290 InterpreterUnresolvedSignature signature ,
249291 byte [] code , ExceptionHandler [] exceptionHandlers , LineNumberTable lineNumberTable , LocalVariableTable localVariableTable ,
250292 ReferenceConstant <FunctionPointerHolder > nativeEntryPoint , int vtableIndex , int gotOffset , int enterStubOffset , int methodId ) {
251293 Symbol <Name > nameSymbol = SymbolsSupport .getNames ().getOrCreate (name );
252- return new InterpreterResolvedJavaMethod (nameSymbol , maxLocals , maxStackSize , modifiers , false , declaringClass , signature , code ,
253- exceptionHandlers , lineNumberTable , localVariableTable , nativeEntryPoint , vtableIndex , gotOffset , enterStubOffset , methodId , null );
294+ Symbol <Signature > signatureSymbol = CremaMethodAccess .toSymbol (signature , SymbolsSupport .getSignatures ());
295+ return new InterpreterResolvedJavaMethod (nameSymbol , maxLocals , maxStackSize , flags , declaringClass , signature , signatureSymbol , code ,
296+ exceptionHandlers , lineNumberTable , localVariableTable , nativeEntryPoint , vtableIndex , gotOffset , enterStubOffset , methodId );
254297 }
255298
256299 // Only called during universe building
257300 @ Platforms (Platform .HOSTED_ONLY .class )
258- public static InterpreterResolvedJavaMethod create (ResolvedJavaMethod originalMethod , String name , int maxLocals , int maxStackSize , int modifiers ,
301+ public static InterpreterResolvedJavaMethod createAtBuildTime (ResolvedJavaMethod originalMethod , String name , int maxLocals , int maxStackSize , int modifiers ,
259302 InterpreterResolvedObjectType declaringClass ,
260303 InterpreterUnresolvedSignature signature , boolean isSubstitutedNative ,
261304 byte [] code , ExceptionHandler [] exceptionHandlers , LineNumberTable lineNumberTable , LocalVariableTable localVariableTable ,
262305 ReferenceConstant <FunctionPointerHolder > nativeEntryPoint , int vtableIndex , int gotOffset , int enterStubOffset , int methodId ) {
263306 Symbol <Name > nameSymbol = SymbolsSupport .getNames ().getOrCreate (name );
264- return new InterpreterResolvedJavaMethod (originalMethod , nameSymbol , maxLocals , maxStackSize , modifiers , declaringClass , signature , isSubstitutedNative , code ,
307+ Symbol <Signature > signatureSymbol = CremaMethodAccess .toSymbol (signature , SymbolsSupport .getSignatures ());
308+ int flags = createFlags (modifiers , declaringClass , signatureSymbol , isSubstitutedNative , originalMethod );
309+ return new InterpreterResolvedJavaMethod (originalMethod , nameSymbol , maxLocals , maxStackSize , flags , declaringClass , signature , signatureSymbol , code ,
265310 exceptionHandlers , lineNumberTable , localVariableTable , nativeEntryPoint , vtableIndex , gotOffset , enterStubOffset , methodId );
266311 }
267312
313+ @ Platforms (Platform .HOSTED_ONLY .class )
314+ private static int createFlags (int modifiers , InterpreterResolvedObjectType declaringClass , Symbol <Signature > signatureSymbol , boolean isSubstitutedNative , ResolvedJavaMethod originalMethod ) {
315+ int newModifiers = modifiers ;
316+ if (ParserMethod .isDeclaredSignaturePolymorphic (declaringClass .getSymbolicType (), signatureSymbol , getOriginalModifiers (modifiers , isSubstitutedNative ), JavaVersion .HOST_VERSION )) {
317+ newModifiers |= ACC_SIGNATURE_POLYMORPHIC ;
318+ }
319+ if (isSubstitutedNative ) {
320+ newModifiers |= ACC_SUBSTITUTED_NATIVE ;
321+ }
322+ return newModifiers ;
323+ }
324+
268325 @ Override
269326 public final boolean isDeclaredSignaturePolymorphic () {
270327 // Note: might not be true for the instantiation of polymorphic signature intrinsics.
271- return signaturePolymorphic ;
328+ return ( flags & ACC_SIGNATURE_POLYMORPHIC ) != 0 ;
272329 }
273330
274331 @ Override
@@ -277,8 +334,9 @@ public final InterpreterResolvedJavaMethod createSignaturePolymorphicIntrinsic(S
277334 assert iid != null ;
278335 assert intrinsic == null ;
279336 int newModifiers ;
337+ boolean isSubstitutedNative = (flags & ACC_SUBSTITUTED_NATIVE ) != 0 ;
280338 if (iid == SignaturePolymorphicIntrinsic .InvokeGeneric ) {
281- newModifiers = getOriginalModifiers (modifiers , isSubstitutedNative ) & ~ACC_VARARGS ;
339+ newModifiers = getOriginalModifiers (flags , isSubstitutedNative ) & ~( ACC_VARARGS | ACC_SUBSTITUTED_NATIVE | ACC_SIGNATURE_POLYMORPHIC ) ;
282340 } else {
283341 newModifiers = ACC_NATIVE | ACC_SYNTHETIC | ACC_FINAL ;
284342 if (iid .isStaticSignaturePolymorphic ()) {
@@ -287,9 +345,8 @@ public final InterpreterResolvedJavaMethod createSignaturePolymorphicIntrinsic(S
287345 }
288346 assert Modifier .isNative (newModifiers );
289347 InterpreterUnresolvedSignature jvmciSignature = CremaMethodAccess .toJVMCI (newSignature , SymbolsSupport .getTypes ());
290- return new InterpreterResolvedJavaMethod (name , jvmciSignature .getParameterCount (true ), 0 , newModifiers , isSubstitutedNative , declaringClass , jvmciSignature ,
291- null , null , null , null , // not bytecode-interpretable
292- null , vtableIndex , gotOffset , enterStubOffset , methodId , iid );
348+ return new InterpreterResolvedJavaMethod (name , jvmciSignature .getParameterCount (true ), newModifiers , declaringClass , jvmciSignature , newSignature ,
349+ vtableIndex , gotOffset , enterStubOffset , methodId , iid );
293350 }
294351
295352 private static int getOriginalModifiers (int modifiers , boolean isSubstitutedNative ) {
@@ -438,7 +495,11 @@ public final LocalVariableTable getLocalVariableTable() {
438495
439496 @ Override
440497 public final int getModifiers () {
441- return modifiers ;
498+ return flags & JVM_RECOGNIZED_METHOD_MODIFIERS ;
499+ }
500+
501+ public int getFlags () {
502+ return flags ;
442503 }
443504
444505 @ Override
@@ -608,6 +669,9 @@ public final boolean isInterpreterExecutable() {
608669 }
609670
610671 public final Set <InterpreterResolvedJavaMethod > getInlinedBy () {
672+ if (inlinedBy == null ) {
673+ return Set .of ();
674+ }
611675 return inlinedBy .inliners ;
612676 }
613677
0 commit comments