Skip to content

Commit 233b57d

Browse files
InterpreterResolvedJavaMethod: Store internal flags and modifiers in an int
1 parent 37f3c5b commit 233b57d

File tree

3 files changed

+110
-46
lines changed

3 files changed

+110
-46
lines changed

substratevm/src/com.oracle.svm.interpreter.metadata/src/com/oracle/svm/interpreter/metadata/InterpreterResolvedJavaMethod.java

Lines changed: 104 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import static com.oracle.svm.espresso.classfile.Constants.ACC_STATIC;
3131
import static com.oracle.svm.espresso.classfile.Constants.ACC_SYNTHETIC;
3232
import static com.oracle.svm.espresso.classfile.Constants.ACC_VARARGS;
33+
import static com.oracle.svm.espresso.classfile.Constants.JVM_RECOGNIZED_METHOD_MODIFIERS;
3334
import static com.oracle.svm.interpreter.metadata.Bytecodes.BREAKPOINT;
3435
import static com.oracle.svm.interpreter.metadata.CremaMethodAccess.toJVMCI;
3536

@@ -51,7 +52,6 @@
5152
import com.oracle.svm.core.invoke.Target_java_lang_invoke_MemberName;
5253
import com.oracle.svm.core.meta.MethodPointer;
5354
import com.oracle.svm.core.util.VMError;
54-
import com.oracle.svm.espresso.classfile.Constants;
5555
import com.oracle.svm.espresso.classfile.JavaVersion;
5656
import com.oracle.svm.espresso.classfile.ParserMethod;
5757
import com.oracle.svm.espresso.classfile.attributes.CodeAttribute;
@@ -79,6 +79,12 @@
7979
* also abstract methods for vtable calls.
8080
*/
8181
public 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

substratevm/src/com.oracle.svm.interpreter.metadata/src/com/oracle/svm/interpreter/metadata/serialization/Serializers.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ public static ValueSerializer<ReferenceConstant<?>> newReferenceConstantSerializ
640640
String name = context.readReference(in);
641641
int maxLocals = LEB128.readUnsignedInt(in);
642642
int maxStackSize = LEB128.readUnsignedInt(in);
643-
int modifiers = LEB128.readUnsignedInt(in);
643+
int flags = LEB128.readUnsignedInt(in);
644644
InterpreterResolvedObjectType declaringClass = context.readReference(in);
645645
InterpreterUnresolvedSignature signature = context.readReference(in);
646646
byte[] code = context.readReference(in);
@@ -654,14 +654,14 @@ public static ValueSerializer<ReferenceConstant<?>> newReferenceConstantSerializ
654654
int enterStubOffset = LEB128.readUnsignedInt(in);
655655
int methodId = LEB128.readUnsignedInt(in);
656656

657-
return InterpreterResolvedJavaMethod.create(name, maxLocals, maxStackSize, modifiers, declaringClass, signature, code, exceptionHandlers, lineNumberTable, localVariableTable,
658-
nativeEntryPoint, vtableIndex, gotOffset, enterStubOffset, methodId);
657+
return InterpreterResolvedJavaMethod.createForDeserialization(name, maxLocals, maxStackSize, flags, declaringClass, signature, code, exceptionHandlers, lineNumberTable,
658+
localVariableTable, nativeEntryPoint, vtableIndex, gotOffset, enterStubOffset, methodId);
659659
},
660660
(context, out, value) -> {
661661
String name = value.getName();
662662
int maxLocals = value.getMaxLocals();
663663
int maxStackSize = value.getMaxStackSize();
664-
int modifiers = value.getModifiers();
664+
int flags = value.getFlags();
665665
InterpreterResolvedObjectType declaringClass = value.getDeclaringClass();
666666
InterpreterUnresolvedSignature signature = value.getSignature();
667667
byte[] code = value.getInterpretedCode();
@@ -682,7 +682,7 @@ public static ValueSerializer<ReferenceConstant<?>> newReferenceConstantSerializ
682682
context.writeReference(out, name);
683683
LEB128.writeUnsignedInt(out, maxLocals);
684684
LEB128.writeUnsignedInt(out, maxStackSize);
685-
LEB128.writeUnsignedInt(out, modifiers);
685+
LEB128.writeUnsignedInt(out, flags);
686686
context.writeReference(out, declaringClass);
687687
context.writeReference(out, signature);
688688
context.writeReference(out, code);

substratevm/src/com.oracle.svm.interpreter/src/com/oracle/svm/interpreter/BuildTimeInterpreterUniverse.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ public static InterpreterResolvedJavaMethod createResolveJavaMethod(ResolvedJava
218218
}
219219

220220
LineNumberTable lineNumberTable = originalMethod.getLineNumberTable();
221-
return InterpreterResolvedJavaMethod.create(
221+
return InterpreterResolvedJavaMethod.createAtBuildTime(
222222
originalMethod,
223223
name,
224224
maxLocals,

0 commit comments

Comments
 (0)