Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support storing the code that builds the code model #305

Open
wants to merge 23 commits into
base: code-reflection
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0d53ba1
Add option to indicate how to store code model
mabbay Jan 22, 2025
4cdc021
Make TEXT the default storage mechanism for code models
mabbay Jan 22, 2025
c3a71f9
Support storing code that builds code model
mabbay Feb 10, 2025
132fb5f
Add JavaType -> Type mapping for Block.Parameter
mabbay Feb 10, 2025
d4d3a25
Add a program to test storing code that builds code model
mabbay Feb 10, 2025
16b1608
Define parsing code in the enum CodeModelStorageOption
mabbay Feb 10, 2025
54e4c30
Apply fixes from Maurizio
mabbay Feb 11, 2025
21c12cb
Reformat code
mabbay Feb 11, 2025
86a3959
Support storing code that builds code model
mabbay Feb 23, 2025
cd302fc
Add comment
mabbay Feb 23, 2025
f832790
Merge branch 'code-reflection' into code-model-storage-option
mabbay Feb 24, 2025
e9fcd8c
Add missing imports
mabbay Feb 25, 2025
c232366
Ensure that block params are inserted in the correct order
mabbay Feb 26, 2025
a1d134c
Pass arrayType instead of eleType in OpBuilder.buildArray
mabbay Feb 28, 2025
5f02f73
Fix almost all test failures of SwitchExpressionTest2 (one remaining)
mabbay Mar 1, 2025
c17be6b
Fix the remaining test failures of SwitchExpressionTest2
mabbay Mar 3, 2025
cd143c3
Fix some of the test failures (3 remains)
mabbay Mar 3, 2025
ee0f906
Fix the remaining compiler tests failures
mabbay Mar 6, 2025
0e49cce
Load OpFactory and TypeElementFactory before invocation of opMethod o…
mabbay Mar 6, 2025
966005c
Merge branch 'code-reflection' into code-model-storage-option
mabbay Mar 12, 2025
95f227e
Don't rely on the assumption of 1d array
mabbay Mar 19, 2025
2e30920
Make opMethod descriptor consistent for both storage options.
mabbay Mar 26, 2025
bf96a44
Changes in code due to making opMethod signature uniform
mabbay Mar 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -442,14 +442,21 @@ private void generateQuotedFieldInitializer(CodeBuilder cob) {
NameAndTypeEntry natMH = cp.nameAndTypeEntry(DEFAULT_NAME, CD_MethodHandle);
// push the receiver on the stack for operand of put field instruction
cob.aload(0)
// load class data: CodeReflectionSupport.HANDLE_MAKE_QUOTED and quotableOpGetter
.ldc(cp.constantDynamicEntry(cp.bsmEntry(bsmDataAt, List.of(cp.intEntry(2))), natMH))
// load op string from field
.ldc(cp.constantDynamicEntry(cp.bsmEntry(bsmDataAt, List.of(cp.intEntry(1))), natMH));
MethodType mtype = quotableOpGetterInfo.getMethodType();
if (quotableOpGetterInfo.getReferenceKind() != MethodHandleInfo.REF_invokeStatic) {
mtype = mtype.insertParameterTypes(0, implClass);
}
// load arguments to quotableOpGetter: ExtendedOp.FACTORY and CORE_TYPE_FACTORY
cob.fieldAccess(Opcode.GETSTATIC, CodeReflectionSupport.EXTENDED_OP_CLASS.describeConstable().get(),
"FACTORY", CodeReflectionSupport.OP_FACTORY_CLASS.describeConstable().get());
cob.fieldAccess(Opcode.GETSTATIC, CodeReflectionSupport.CORE_TYPE_FACTORY_CLASS.describeConstable().get(),
"CORE_TYPE_FACTORY",
CodeReflectionSupport.TYPE_ELEMENT_FACTORY_CLASS.describeConstable().get());
cob.invokevirtual(CD_MethodHandle, "invokeExact", mtype.describeConstable().get());
cob.checkcast(CodeReflectionSupport.FUNC_OP_CLASS.describeConstable().get());

// load captured args in array

@@ -476,6 +483,11 @@ static class CodeReflectionSupport {
static final Class<?> QUOTED_CLASS;
static final Class<?> QUOTABLE_CLASS;
static final MethodHandle HANDLE_MAKE_QUOTED;
static final Class<?> EXTENDED_OP_CLASS;
static final Class<?> OP_FACTORY_CLASS;
static final Class<?> CORE_TYPE_FACTORY_CLASS;
static final Class<?> TYPE_ELEMENT_FACTORY_CLASS;
static final Class<?> FUNC_OP_CLASS;

static {
try {
@@ -484,10 +496,14 @@ static class CodeReflectionSupport {
QUOTED_CLASS = cl.loadClass("jdk.incubator.code.Quoted");
QUOTABLE_CLASS = cl.loadClass("jdk.incubator.code.Quotable");
Class<?> quotedHelper = cl.loadClass("jdk.incubator.code.internal.QuotedHelper");
Class<?> funcOp = cl.loadClass("jdk.incubator.code.op.CoreOp$FuncOp");
FUNC_OP_CLASS = cl.loadClass("jdk.incubator.code.op.CoreOp$FuncOp");
MethodHandle makeQuoted = Lookup.IMPL_LOOKUP.findStatic(quotedHelper, "makeQuoted",
MethodType.methodType(QUOTED_CLASS, MethodHandles.Lookup.class, funcOp, Object[].class));
MethodType.methodType(QUOTED_CLASS, MethodHandles.Lookup.class, FUNC_OP_CLASS, Object[].class));
HANDLE_MAKE_QUOTED = makeQuoted.bindTo(Lookup.IMPL_LOOKUP);
EXTENDED_OP_CLASS = cl.loadClass("jdk.incubator.code.op.ExtendedOp");
OP_FACTORY_CLASS = cl.loadClass("jdk.incubator.code.op.OpFactory");
CORE_TYPE_FACTORY_CLASS = cl.loadClass("jdk.incubator.code.type.CoreTypeFactory");
TYPE_ELEMENT_FACTORY_CLASS = cl.loadClass("jdk.incubator.code.type.TypeElementFactory");
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
11 changes: 8 additions & 3 deletions src/jdk.incubator.code/share/classes/jdk/incubator/code/Op.java
Original file line number Diff line number Diff line change
@@ -40,8 +40,12 @@
import com.sun.tools.javac.util.Context;
import jdk.incubator.code.internal.ReflectMethods;
import jdk.incubator.code.op.CoreOp.FuncOp;
import jdk.incubator.code.op.ExtendedOp;
import jdk.incubator.code.op.OpFactory;
import jdk.incubator.code.type.CoreTypeFactory;
import jdk.incubator.code.type.FunctionType;
import jdk.incubator.code.type.MethodRef;
import jdk.incubator.code.type.TypeElementFactory;
import jdk.incubator.code.writer.OpWriter;
import jdk.internal.access.SharedSecrets;

@@ -526,17 +530,18 @@ private static Optional<FuncOp> createCodeModel(Method method) {
case '.', ';', '[', '/': sig[i] = '$';
}
}
String opMethodName = "op$" + new String(sig);
String opMethodName = new String(sig);
Method opMethod;
try {
// @@@ Use method handle with full power mode
opMethod = method.getDeclaringClass().getDeclaredMethod(opMethodName);
opMethod = method.getDeclaringClass().getDeclaredMethod(opMethodName, OpFactory.class,
TypeElementFactory.class);
} catch (NoSuchMethodException e) {
return Optional.empty();
}
opMethod.setAccessible(true);
try {
FuncOp funcOp = (FuncOp) opMethod.invoke(null);
FuncOp funcOp = (FuncOp) opMethod.invoke(null, ExtendedOp.FACTORY, CoreTypeFactory.CORE_TYPE_FACTORY);
return Optional.of(funcOp);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
Original file line number Diff line number Diff line change
@@ -54,13 +54,15 @@
import jdk.incubator.code.Value;
import jdk.incubator.code.op.CoreOp;
import jdk.incubator.code.op.CoreOp.*;
import jdk.incubator.code.op.OpFactory;
import jdk.incubator.code.parser.OpParser;
import jdk.incubator.code.type.ArrayType;
import jdk.incubator.code.type.FieldRef;
import jdk.incubator.code.type.FunctionType;
import jdk.incubator.code.type.JavaType;
import jdk.incubator.code.type.MethodRef;
import jdk.incubator.code.type.PrimitiveType;
import jdk.incubator.code.type.TypeElementFactory;
import jdk.incubator.code.type.VarType;
import java.util.ArrayList;
import java.util.Arrays;
@@ -92,6 +94,8 @@ public final class BytecodeGenerator {
StringConcatFactory.class.describeConstable().orElseThrow(),
"makeConcat",
CD_CallSite);
private static final MethodTypeDesc opMethodDesc = MethodTypeDesc.of(FuncOp.class.describeConstable().get(),
OpFactory.class.describeConstable().get(), TypeElementFactory.class.describeConstable().get());

/**
* Transforms the invokable operation to bytecode encapsulated in a method of hidden class and exposed
@@ -165,7 +169,7 @@ public static <O extends Op & Op.Invokable> byte[] generateClassData(MethodHandl
LambdaOp lop = lambdaSink.get(i);
if (quotable.get(i)) {
// return (FuncOp) OpParser.fromOpString(opText)
clb.withMethod("op$lambda$" + i, MethodTypeDesc.of(FuncOp.class.describeConstable().get()),
clb.withMethod("op$lambda$" + i, opMethodDesc,
ClassFile.ACC_PUBLIC | ClassFile.ACC_STATIC | ClassFile.ACC_SYNTHETIC, mb -> mb.withCode(cb -> cb
.loadConstant(quote(lop).toText())
.invoke(Opcode.INVOKESTATIC, OpParser.class.describeConstable().get(),
@@ -901,7 +905,7 @@ private void generate() {
MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.STATIC,
className,
"op$lambda$" + lambdaIndex,
MethodTypeDesc.of(FuncOp.class.describeConstable().get()))));
opMethodDesc)));
quotable.set(lambdaSink.size());
} else {
cob.invokedynamic(DynamicCallSiteDesc.of(
Loading