Skip to content

Commit 7efc385

Browse files
InterpreterResolvedJavaMethod: Store internal flags and modifiers in an int
1 parent 1ff0271 commit 7efc385

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

@@ -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, ResolvedMember {
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,37 +267,51 @@ 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

232274
@VisibleForSerialization
233-
public static InterpreterResolvedJavaMethod create(String name, int maxLocals, int maxStackSize, int modifiers, InterpreterResolvedObjectType declaringClass,
275+
public static InterpreterResolvedJavaMethod createForDeserialization(String name, int maxLocals, int maxStackSize, int flags, InterpreterResolvedObjectType declaringClass,
234276
InterpreterUnresolvedSignature signature,
235277
byte[] code, ExceptionHandler[] exceptionHandlers, LineNumberTable lineNumberTable, LocalVariableTable localVariableTable,
236278
ReferenceConstant<FunctionPointerHolder> nativeEntryPoint, int vtableIndex, int gotOffset, int enterStubOffset, int methodId) {
237279
Symbol<Name> nameSymbol = SymbolsSupport.getNames().getOrCreate(name);
238-
return new InterpreterResolvedJavaMethod(nameSymbol, maxLocals, maxStackSize, modifiers, false, declaringClass, signature, code,
239-
exceptionHandlers, lineNumberTable, localVariableTable, nativeEntryPoint, vtableIndex, gotOffset, enterStubOffset, methodId, null);
280+
Symbol<Signature> signatureSymbol = CremaMethodAccess.toSymbol(signature, SymbolsSupport.getSignatures());
281+
return new InterpreterResolvedJavaMethod(nameSymbol, maxLocals, maxStackSize, flags, declaringClass, signature, signatureSymbol, code,
282+
exceptionHandlers, lineNumberTable, localVariableTable, nativeEntryPoint, vtableIndex, gotOffset, enterStubOffset, methodId);
240283
}
241284

242285
// Only called during universe building
243286
@Platforms(Platform.HOSTED_ONLY.class)
244-
public static InterpreterResolvedJavaMethod create(ResolvedJavaMethod originalMethod, String name, int maxLocals, int maxStackSize, int modifiers,
287+
public static InterpreterResolvedJavaMethod createAtBuildTime(ResolvedJavaMethod originalMethod, String name, int maxLocals, int maxStackSize, int modifiers,
245288
InterpreterResolvedObjectType declaringClass,
246289
InterpreterUnresolvedSignature signature, boolean isSubstitutedNative,
247290
byte[] code, ExceptionHandler[] exceptionHandlers, LineNumberTable lineNumberTable, LocalVariableTable localVariableTable,
248291
ReferenceConstant<FunctionPointerHolder> nativeEntryPoint, int vtableIndex, int gotOffset, int enterStubOffset, int methodId) {
249292
Symbol<Name> nameSymbol = SymbolsSupport.getNames().getOrCreate(name);
250-
return new InterpreterResolvedJavaMethod(originalMethod, nameSymbol, maxLocals, maxStackSize, modifiers, declaringClass, signature, isSubstitutedNative, code,
293+
Symbol<Signature> signatureSymbol = CremaMethodAccess.toSymbol(signature, SymbolsSupport.getSignatures());
294+
int flags = createFlags(modifiers, declaringClass, signatureSymbol, isSubstitutedNative, originalMethod);
295+
return new InterpreterResolvedJavaMethod(originalMethod, nameSymbol, maxLocals, maxStackSize, flags, declaringClass, signature, signatureSymbol, code,
251296
exceptionHandlers, lineNumberTable, localVariableTable, nativeEntryPoint, vtableIndex, gotOffset, enterStubOffset, methodId);
252297
}
253298

299+
@Platforms(Platform.HOSTED_ONLY.class)
300+
private static int createFlags(int modifiers, InterpreterResolvedObjectType declaringClass, Symbol<Signature> signatureSymbol, boolean isSubstitutedNative, ResolvedJavaMethod originalMethod) {
301+
int newModifiers = modifiers;
302+
if (ParserMethod.isDeclaredSignaturePolymorphic(declaringClass.getSymbolicType(), signatureSymbol, getOriginalModifiers(modifiers, isSubstitutedNative), JavaVersion.HOST_VERSION)) {
303+
newModifiers |= ACC_SIGNATURE_POLYMORPHIC;
304+
}
305+
if (isSubstitutedNative) {
306+
newModifiers |= ACC_SUBSTITUTED_NATIVE;
307+
}
308+
return newModifiers;
309+
}
310+
254311
@Override
255312
public final boolean isDeclaredSignaturePolymorphic() {
256313
// Note: might not be true for the instantiation of polymorphic signature intrinsics.
257-
return signaturePolymorphic;
314+
return (flags & ACC_SIGNATURE_POLYMORPHIC) != 0;
258315
}
259316

260317
@Override
@@ -263,8 +320,9 @@ public final InterpreterResolvedJavaMethod createSignaturePolymorphicIntrinsic(S
263320
assert iid != null;
264321
assert intrinsic == null;
265322
int newModifiers;
323+
boolean isSubstitutedNative = (flags & ACC_SUBSTITUTED_NATIVE) != 0;
266324
if (iid == SignaturePolymorphicIntrinsic.InvokeGeneric) {
267-
newModifiers = getOriginalModifiers(modifiers, isSubstitutedNative) & ~ACC_VARARGS;
325+
newModifiers = getOriginalModifiers(flags, isSubstitutedNative) & ~(ACC_VARARGS | ACC_SUBSTITUTED_NATIVE | ACC_SIGNATURE_POLYMORPHIC);
268326
} else {
269327
newModifiers = ACC_NATIVE | ACC_SYNTHETIC | ACC_FINAL;
270328
if (iid.isStaticSignaturePolymorphic()) {
@@ -273,9 +331,8 @@ public final InterpreterResolvedJavaMethod createSignaturePolymorphicIntrinsic(S
273331
}
274332
assert Modifier.isNative(newModifiers);
275333
InterpreterUnresolvedSignature jvmciSignature = CremaMethodAccess.toJVMCI(newSignature, SymbolsSupport.getTypes());
276-
return new InterpreterResolvedJavaMethod(name, jvmciSignature.getParameterCount(true), 0, newModifiers, isSubstitutedNative, declaringClass, jvmciSignature,
277-
null, null, null, null, // not bytecode-interpretable
278-
null, vtableIndex, gotOffset, enterStubOffset, methodId, iid);
334+
return new InterpreterResolvedJavaMethod(name, jvmciSignature.getParameterCount(true), newModifiers, declaringClass, jvmciSignature, newSignature,
335+
vtableIndex, gotOffset, enterStubOffset, methodId, iid);
279336
}
280337

281338
private static int getOriginalModifiers(int modifiers, boolean isSubstitutedNative) {
@@ -424,7 +481,11 @@ public final LocalVariableTable getLocalVariableTable() {
424481

425482
@Override
426483
public final int getModifiers() {
427-
return modifiers;
484+
return flags & JVM_RECOGNIZED_METHOD_MODIFIERS;
485+
}
486+
487+
public int getFlags() {
488+
return flags;
428489
}
429490

430491
@Override
@@ -594,6 +655,9 @@ public final boolean isInterpreterExecutable() {
594655
}
595656

596657
public final Set<InterpreterResolvedJavaMethod> getInlinedBy() {
658+
if (inlinedBy == null) {
659+
return Set.of();
660+
}
597661
return inlinedBy.inliners;
598662
}
599663

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)