use of com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement in project graal by oracle.
the class FlatNodeGenFactory method createExecuteMethod.
private CodeExecutableElement createExecuteMethod(SpecializationData specialization, ExecutableTypeData executedType, FrameState frameState, boolean originalOverride) {
TypeMirror returnType = executedType.getReturnType();
if (specialization != null) {
frameState.loadFastPathState(specialization);
}
String methodName;
if (originalOverride && executedType.getMethod() != null) {
methodName = executedType.getMethod().getSimpleName().toString();
} else {
methodName = executedType.getUniqueName();
}
CodeExecutableElement executable;
if (originalOverride && executedType.getMethod() != null) {
executable = CodeExecutableElement.clone(context.getEnvironment(), executedType.getMethod());
executable.getAnnotationMirrors().clear();
executable.getModifiers().remove(ABSTRACT);
for (VariableElement var : executable.getParameters()) {
((CodeVariableElement) var).getAnnotationMirrors().clear();
}
if (executedType.getFrameParameter() != null) {
((CodeVariableElement) executable.getParameters().get(0)).setName(FRAME_VALUE);
}
if (executable.isVarArgs()) {
((CodeVariableElement) executable.getParameters().get(executable.getParameters().size() - 1)).setName(VARARGS_NAME);
}
renameOriginalParameters(executedType, executable, frameState);
} else {
executable = frameState.createMethod(modifiers(PUBLIC), returnType, methodName, FRAME_VALUE);
}
executable.getThrownTypes().clear();
if (needsUnexpectedResultException(executedType)) {
executable.getThrownTypes().add(context.getDeclaredType(UnexpectedResultException.class));
}
return executable;
}
use of com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement in project graal by oracle.
the class FlatNodeGenFactory method generateReflectionInfo.
private void generateReflectionInfo(CodeTypeElement clazz) {
clazz.getImplements().add(context.getType(Introspection.Provider.class));
CodeExecutableElement reflection = new CodeExecutableElement(modifiers(PUBLIC), context.getType(Introspection.class), "getIntrospectionData");
CodeTreeBuilder builder = reflection.createBuilder();
List<SpecializationData> filteredSpecializations = new ArrayList<>();
for (SpecializationData s : node.getSpecializations()) {
if (s.getMethod() == null) {
continue;
}
filteredSpecializations.add(s);
}
ArrayCodeTypeMirror objectArray = new ArrayCodeTypeMirror(context.getType(Object.class));
builder.declaration(objectArray, "data", builder.create().startNewArray(objectArray, CodeTreeBuilder.singleString(String.valueOf(filteredSpecializations.size() + 1))).end().build());
builder.declaration(objectArray, "s", (CodeTree) null);
// declare version 0
builder.statement("data[0] = 0");
FrameState frameState = FrameState.load(this);
builder.tree(state.createLoad(frameState));
if (requiresExclude()) {
builder.tree(exclude.createLoad(frameState));
}
int index = 1;
for (SpecializationData specialization : filteredSpecializations) {
builder.startStatement().string("s = ").startNewArray(objectArray, CodeTreeBuilder.singleString("3")).end().end();
builder.startStatement().string("s[0] = ").doubleQuote(specialization.getMethodName()).end();
builder.startIf().tree(state.createContains(frameState, new Object[] { specialization })).end().startBlock();
builder.startStatement().string("s[1] = (byte)0b01 /* active */").end();
TypeMirror listType = new DeclaredCodeTypeMirror((TypeElement) context.getDeclaredType(ArrayList.class).asElement(), Arrays.asList(context.getType(Object.class)));
if (!specialization.getCaches().isEmpty()) {
builder.declaration(listType, "cached", "new ArrayList<>()");
boolean useSpecializationClass = useSpecializationClass(specialization);
String name = createSpecializationLocalName(specialization);
if (useSpecializationClass) {
builder.tree(loadSpecializationClass(frameState, specialization));
if (specialization.hasMultipleInstances()) {
builder.startWhile();
} else {
builder.startIf();
}
builder.string(name, " != null");
builder.end();
builder.startBlock();
}
builder.startStatement().startCall("cached", "add");
builder.startStaticCall(context.getType(Arrays.class), "asList");
for (CacheExpression cache : specialization.getCaches()) {
builder.startGroup();
builder.tree(createCacheReference(frameState, specialization, cache.getParameter()));
builder.end();
}
builder.end();
builder.end().end();
if (useSpecializationClass) {
if (specialization.getMaximumNumberOfInstances() > 1) {
builder.startStatement().string(name, " = ", name, ".next_").end();
}
// cache while or if
builder.end();
}
builder.statement("s[2] = cached");
}
builder.end();
if (mayBeExcluded(specialization)) {
builder.startElseIf().tree(exclude.createContains(frameState, new Object[] { specialization })).end().startBlock();
builder.startStatement().string("s[1] = (byte)0b10 /* excluded */").end();
builder.end();
}
builder.startElseBlock();
builder.startStatement().string("s[1] = (byte)0b00 /* inactive */").end();
builder.end();
builder.startStatement().string("data[", String.valueOf(index), "] = s").end();
index++;
}
builder.startReturn().startStaticCall(context.getType(Introspection.Provider.class), "create").string("data").end().end();
clazz.add(reflection);
}
use of com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement in project graal by oracle.
the class FlatNodeGenFactory method wrapInAMethod.
private CodeTree wrapInAMethod(CodeTreeBuilder parent, SpecializationGroup group, FrameState frameState, String suffix, CodeTree codeTree) {
CodeExecutableElement parentMethod = (CodeExecutableElement) parent.findMethod();
CodeTypeElement parentClass = (CodeTypeElement) parentMethod.getEnclosingElement();
String name = parentMethod.getSimpleName().toString() + "_" + suffix + (boxingSplitIndex++);
CodeExecutableElement method = parentClass.add(frameState.createMethod(modifiers(Modifier.PRIVATE), parentMethod.getReturnType(), name, FRAME_VALUE, STATE_VALUE));
CodeTreeBuilder builder = method.createBuilder();
builder.tree(codeTree);
method.getThrownTypes().addAll(parentMethod.getThrownTypes());
addExplodeLoop(builder, group);
CodeTreeBuilder parentBuilder = parent.create();
parentBuilder.startReturn();
parentBuilder.startCall(method.getSimpleName().toString());
frameState.addReferencesTo(parentBuilder, FRAME_VALUE, STATE_VALUE);
parentBuilder.end();
parentBuilder.end();
return parentBuilder.build();
}
use of com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement in project graal by oracle.
the class FlatNodeGenFactory method createExecute.
private CodeExecutableElement createExecute(CodeTypeElement clazz, ExecutableTypeData type, List<ExecutableTypeData> delegateableTypes) {
final List<SpecializationData> allSpecializations = reachableSpecializations;
final List<SpecializationData> compatibleSpecializations = filterCompatibleSpecializations(type, allSpecializations);
List<SpecializationData> implementedSpecializations;
if (delegateableTypes.isEmpty()) {
implementedSpecializations = compatibleSpecializations;
} else {
implementedSpecializations = filterImplementedSpecializations(type, compatibleSpecializations);
}
FrameState frameState = FrameState.load(this, type, Integer.MAX_VALUE);
CodeExecutableElement method = createExecuteMethod(null, type, frameState, true);
clazz.add(method);
CodeTreeBuilder builder = method.createBuilder();
// do I miss specializations that are reachable from this executable?
if (compatibleSpecializations.size() != implementedSpecializations.size()) {
ExecuteDelegationResult delegation = createExecuteDelegation(builder, frameState, type, delegateableTypes, compatibleSpecializations, implementedSpecializations);
builder.tree(delegation.tree);
if (!delegation.hasFallthrough) {
return method;
}
}
if (implementedSpecializations.isEmpty()) {
implementedSpecializations = compatibleSpecializations;
}
if (implementedSpecializations.isEmpty()) {
builder.tree(createTransferToInterpreterAndInvalidate());
builder.startThrow().startNew(getType(AssertionError.class)).doubleQuote("Delegation failed.").end().end();
} else {
SpecializationGroup group = SpecializationGroup.create(implementedSpecializations);
builder.tree(createFastPath(builder, implementedSpecializations, group, type, frameState));
}
return method;
}
use of com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement in project graal by oracle.
the class FlatNodeGenFactory method createGetCostMethod.
private Element createGetCostMethod() {
TypeMirror returnType = getType(NodeCost.class);
CodeExecutableElement executable = new CodeExecutableElement(modifiers(PUBLIC), returnType, "getCost");
executable.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class)));
CodeTreeBuilder builder = executable.createBuilder();
FrameState frameState = FrameState.load(this);
builder.tree(state.createLoad(frameState));
if (node.needsRewrites(context)) {
builder.startIf().tree(state.createIs(frameState, new Object[0], reachableSpecializationsArray)).end();
builder.startBlock();
builder.startReturn().staticReference(getType(NodeCost.class), "UNINITIALIZED").end();
builder.end();
if (reachableSpecializations.size() == 1 && !reachableSpecializations.iterator().next().hasMultipleInstances()) {
builder.startElseBlock();
builder.startReturn().staticReference(getType(NodeCost.class), "MONOMORPHIC").end();
builder.end();
} else {
builder.startElseIf();
builder.tree(state.createIsOneBitOf(frameState, reachableSpecializationsArray));
builder.end();
builder.startBlock();
List<CodeTree> additionalChecks = new ArrayList<>();
for (SpecializationData specialization : reachableSpecializations) {
if (useSpecializationClass(specialization) && specialization.getMaximumNumberOfInstances() > 1) {
String typeName = createSpecializationTypeName(specialization);
String fieldName = createSpecializationFieldName(specialization);
String localName = createSpecializationLocalName(specialization);
builder.declaration(typeName, localName, "this." + fieldName);
CodeTree check = builder.create().startParantheses().string(localName, " == null || ", localName, ".next_ == null").end().build();
additionalChecks.add(check);
}
}
if (!additionalChecks.isEmpty()) {
builder.startIf().tree(combineTrees(" && ", additionalChecks.toArray(new CodeTree[0]))).end().startBlock();
}
builder.startReturn().staticReference(getType(NodeCost.class), "MONOMORPHIC").end();
if (!additionalChecks.isEmpty()) {
builder.end();
}
builder.end();
builder.startReturn().staticReference(getType(NodeCost.class), "POLYMORPHIC").end();
}
} else {
builder.startReturn().staticReference(getType(NodeCost.class), "MONOMORPHIC").end();
}
return executable;
}
Aggregations