Skip to content

Commit 4474cf9

Browse files
InterpreterResolvedJavaMethod: Store internal flags and modifiers in an int
1 parent 6ca3caf commit 4474cf9

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.espresso.classfile.bytecode.Bytecodes.INVOKEDYNAMIC;
3435
import static com.oracle.svm.interpreter.metadata.Bytecodes.BREAKPOINT;
3536
import static com.oracle.svm.interpreter.metadata.CremaMethodAccess.toJVMCI;
@@ -52,7 +53,6 @@
5253
import com.oracle.svm.core.invoke.Target_java_lang_invoke_MemberName;
5354
import com.oracle.svm.core.meta.MethodPointer;
5455
import com.oracle.svm.core.util.VMError;
55-
import com.oracle.svm.espresso.classfile.Constants;
5656
import com.oracle.svm.espresso.classfile.JavaVersion;
5757
import com.oracle.svm.espresso.classfile.ParserMethod;
5858
import com.oracle.svm.espresso.classfile.attributes.CodeAttribute;
@@ -80,6 +80,12 @@
8080
* also abstract methods for vtable calls.
8181
*/
8282
public 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

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)