use of com.oracle.truffle.dsl.processor.model.SpecializationData in project graal by oracle.
the class FlatNodeGenFactory method createFallbackGuard.
private Element createFallbackGuard() {
boolean frameUsed = false;
FrameState frameState = FrameState.load(this);
List<SpecializationData> specializations = new ArrayList<>(reachableSpecializations);
for (ListIterator<SpecializationData> iterator = specializations.listIterator(); iterator.hasNext(); ) {
SpecializationData specialization = iterator.next();
if (specialization.isFallback()) {
iterator.remove();
} else if (!specialization.isReachesFallback()) {
iterator.remove();
} else {
if (specialization.isFrameUsedByGuard()) {
frameUsed = true;
}
}
}
SpecializationGroup group = SpecializationGroup.create(specializations);
ExecutableTypeData executableType = node.findAnyGenericExecutableType(context, -1);
if (!frameUsed) {
frameState.removeValue(FRAME_VALUE);
}
fallbackNeedsState = false;
fallbackNeedsFrame = frameUsed;
state.createLoad(frameState);
CodeExecutableElement method = frameState.createMethod(modifiers(PRIVATE), getType(boolean.class), METHOD_FALLBACK_GUARD, FRAME_VALUE, STATE_VALUE);
CodeTree result = visitSpecializationGroup(CodeTreeBuilder.createBuilder(), group, executableType, frameState, null, NodeExecutionMode.FALLBACK_GUARD);
if (!fallbackNeedsState) {
VariableElement toRemove = null;
for (VariableElement v : method.getParameters()) {
if (v.getSimpleName().toString().equals(STATE_VALUE)) {
toRemove = v;
break;
}
}
if (toRemove != null) {
method.getParameters().remove(toRemove);
}
}
final CodeTreeBuilder builder = method.createBuilder();
for (SpecializationData implemented : specializations) {
if (implemented.getMaximumNumberOfInstances() > 1) {
method.getAnnotationMirrors().add(createExplodeLoop());
break;
}
}
builder.tree(result);
builder.returnTrue();
if (!accessesCachedState(specializations)) {
method.getModifiers().add(STATIC);
}
return method;
}
use of com.oracle.truffle.dsl.processor.model.SpecializationData in project graal by oracle.
the class FlatNodeGenFactory method createRemoveThis.
private CodeTree createRemoveThis(CodeTreeBuilder parent, FrameState frameState, ExecutableTypeData forType, SpecializationData specialization) {
CodeExecutableElement method = removeThisMethods.get(specialization);
String specializationLocalName = createSpecializationLocalName(specialization);
boolean useSpecializationClass = useSpecializationClass(specialization);
if (method == null) {
method = new CodeExecutableElement(context.getType(void.class), "remove" + specialization.getId() + "_");
if (useSpecializationClass) {
method.addParameter(new CodeVariableElement(context.getType(Object.class), specializationLocalName));
}
CodeTreeBuilder builder = method.createBuilder();
builder.declaration(context.getType(Lock.class), "lock", "getLock()");
builder.statement("lock.lock()");
builder.startTryBlock();
String fieldName = createSpecializationFieldName(specialization);
if (!useSpecializationClass || specialization.getMaximumNumberOfInstances() == 1) {
// single instance remove
builder.tree((state.createSet(null, new Object[] { specialization }, false, true)));
if (useSpecializationClass) {
builder.statement("this." + fieldName + " = null");
}
} else {
// multi instance remove
String typeName = createSpecializationTypeName(specialization);
boolean specializedIsNode = specializationClassIsNode(specialization);
builder.declaration(typeName, "prev", "null");
builder.declaration(typeName, "cur", "this." + fieldName);
builder.startWhile();
builder.string("cur != null");
builder.end().startBlock();
builder.startIf().string("cur == ").string(specializationLocalName).end().startBlock();
builder.startIf().string("prev == null").end().startBlock();
builder.statement("this." + fieldName + " = cur.next_");
if (specializedIsNode) {
builder.statement("this.adoptChildren()");
}
builder.end().startElseBlock();
builder.statement("prev.next_ = cur.next_");
if (specializedIsNode) {
builder.statement("prev.adoptChildren()");
}
builder.end();
builder.statement("break");
// if block
builder.end();
builder.statement("prev = cur");
builder.statement("cur = cur.next_");
// while block
builder.end();
builder.startIf().string("this." + fieldName).string(" == null").end().startBlock();
builder.tree((state.createSet(null, Arrays.asList(specialization).toArray(new SpecializationData[0]), false, true)));
builder.end();
}
builder.end().startFinallyBlock();
builder.statement("lock.unlock()");
builder.end();
removeThisMethods.put(specialization, method);
}
CodeTreeBuilder builder = parent.create();
builder.startStatement().startCall(method.getSimpleName().toString());
if (useSpecializationClass) {
builder.string(specializationLocalName);
}
builder.end().end();
builder.tree(createCallExecuteAndSpecialize(forType, frameState));
return builder.build();
}
use of com.oracle.truffle.dsl.processor.model.SpecializationData in project graal by oracle.
the class FlatNodeGenFactory method createTypeCheckOrCast.
private IfTriple createTypeCheckOrCast(FrameState frameState, SpecializationGroup group, TypeGuard typeGuard, NodeExecutionMode specializationExecution, boolean castOnly, boolean forceImplicitCast) {
CodeTreeBuilder prepareBuilder = CodeTreeBuilder.createBuilder();
CodeTreeBuilder checkBuilder = CodeTreeBuilder.createBuilder();
int signatureIndex = typeGuard.getSignatureIndex();
LocalVariable value = frameState.getValue(signatureIndex);
TypeMirror targetType = typeGuard.getType();
if (!ElementUtils.needsCastTo(value.getTypeMirror(), targetType)) {
boolean foundImplicitSubType = false;
if (forceImplicitCast) {
List<ImplicitCastData> casts = typeSystem.lookupByTargetType(targetType);
for (ImplicitCastData cast : casts) {
if (ElementUtils.isSubtype(cast.getSourceType(), targetType)) {
foundImplicitSubType = true;
break;
}
}
}
if (!foundImplicitSubType) {
return null;
}
}
NodeExecutionData execution = node.getChildExecutions().get(signatureIndex);
CodeTreeBuilder castBuilder = prepareBuilder.create();
List<ImplicitCastData> sourceTypes = typeSystem.lookupByTargetType(targetType);
CodeTree valueReference = value.createReference();
if (sourceTypes.isEmpty()) {
checkBuilder.tree(TypeSystemCodeGenerator.check(typeSystem, targetType, valueReference));
castBuilder.tree(TypeSystemCodeGenerator.cast(typeSystem, targetType, valueReference));
} else {
List<SpecializationData> specializations = group.collectSpecializations();
List<Parameter> parameters = new ArrayList<>();
for (SpecializationData otherSpecialization : specializations) {
parameters.add(otherSpecialization.findParameterOrDie(execution));
}
if (specializationExecution.isFastPath() || specializationExecution.isGuardFallback()) {
CodeTree implicitState;
if (specializationExecution.isGuardFallback()) {
implicitState = CodeTreeBuilder.singleString("0b" + allsetMask(sourceTypes.size() + 1));
} else {
implicitState = state.createExtractInteger(frameState, typeGuard);
}
checkBuilder.tree(TypeSystemCodeGenerator.implicitCheckFlat(typeSystem, targetType, valueReference, implicitState));
castBuilder.tree(TypeSystemCodeGenerator.implicitCastFlat(typeSystem, targetType, valueReference, implicitState));
} else {
Parameter parameter = parameters.get(0);
String implicitStateName = createImplicitTypeStateLocalName(parameter);
CodeTree defaultValue = null;
prepareBuilder.declaration(context.getType(int.class), implicitStateName, defaultValue);
CodeTree specializeCall = TypeSystemCodeGenerator.implicitSpecializeFlat(typeSystem, targetType, valueReference);
checkBuilder.startParantheses();
checkBuilder.string(implicitStateName, " = ").tree(specializeCall);
checkBuilder.end();
checkBuilder.string(" != 0");
castBuilder.tree(TypeSystemCodeGenerator.implicitCastFlat(typeSystem, targetType, valueReference, CodeTreeBuilder.singleString(implicitStateName)));
}
}
if (castOnly) {
LocalVariable currentValue = frameState.getValue(execution);
CodeTreeBuilder localsBuilder = CodeTreeBuilder.createBuilder();
LocalVariable castVariable = currentValue.nextName().newType(typeGuard.getType()).accessWith(null);
frameState.setValue(execution, castVariable);
localsBuilder.tree(castVariable.createDeclaration(castBuilder.build()));
return new IfTriple(localsBuilder.build(), null, null);
} else {
return new IfTriple(prepareBuilder.build(), checkBuilder.build(), null);
}
}
use of com.oracle.truffle.dsl.processor.model.SpecializationData in project graal by oracle.
the class FlatNodeGenFactory method filterImplementedSpecializations.
private List<SpecializationData> filterImplementedSpecializations(ExecutableTypeData executable, List<SpecializationData> specializations) {
List<SpecializationData> filteredSpecializations = new ArrayList<>();
TypeMirror returnType = ElementUtils.boxType(context, executable.getReturnType());
for (SpecializationData specialization : specializations) {
TypeMirror specializationReturnType = ElementUtils.boxType(context, specialization.getReturnType().getType());
if (ElementUtils.typeEquals(specializationReturnType, returnType)) {
filteredSpecializations.add(specialization);
}
}
return filteredSpecializations;
}
use of com.oracle.truffle.dsl.processor.model.SpecializationData in project graal by oracle.
the class FlatNodeGenFactory method create.
public CodeTypeElement create(CodeTypeElement clazz) {
for (NodeChildData child : node.getChildren()) {
clazz.addOptional(createAccessChildMethod(child));
}
for (NodeFieldData field : node.getFields()) {
if (!field.isGenerated()) {
continue;
}
clazz.add(new CodeVariableElement(modifiers(PRIVATE, FINAL), field.getType(), field.getName()));
if (field.getGetter() != null && field.getGetter().getModifiers().contains(Modifier.ABSTRACT)) {
CodeExecutableElement method = CodeExecutableElement.clone(context.getEnvironment(), field.getGetter());
method.getModifiers().remove(Modifier.ABSTRACT);
method.createBuilder().startReturn().string("this.").string(field.getName()).end();
clazz.add(method);
}
}
for (ExecutableElement superConstructor : GeneratorUtils.findUserConstructors(node.getTemplateType().asType())) {
clazz.add(createNodeConstructor(clazz, superConstructor));
}
for (NodeExecutionData execution : node.getChildExecutions()) {
if (execution.getChild() != null && execution.getChild().needsGeneratedField()) {
clazz.add(createNodeField(PRIVATE, execution.getNodeType(), nodeFieldName(execution), Child.class));
}
}
createFields(clazz);
TypeMirror genericReturnType = node.getPolymorphicSpecialization().getReturnType().getType();
List<ExecutableTypeData> executableTypes = filterExecutableTypes(node.getExecutableTypes(), reachableSpecializations);
List<ExecutableTypeData> genericExecutableTypes = new ArrayList<>();
List<ExecutableTypeData> specializedExecutableTypes = new ArrayList<>();
List<ExecutableTypeData> voidExecutableTypes = new ArrayList<>();
for (ExecutableTypeData type : executableTypes) {
if (ElementUtils.isVoid(type.getReturnType())) {
voidExecutableTypes.add(type);
} else if (type.hasUnexpectedValue(context) && !ElementUtils.typeEquals(genericReturnType, type.getReturnType())) {
specializedExecutableTypes.add(type);
} else {
genericExecutableTypes.add(type);
}
}
if (genericExecutableTypes.size() > 1) {
boolean hasGenericTypeMatch = false;
for (ExecutableTypeData genericExecutable : genericExecutableTypes) {
if (ElementUtils.typeEquals(genericExecutable.getReturnType(), genericReturnType)) {
hasGenericTypeMatch = true;
break;
}
}
if (hasGenericTypeMatch) {
for (ListIterator<ExecutableTypeData> iterator = genericExecutableTypes.listIterator(); iterator.hasNext(); ) {
ExecutableTypeData executableTypeData = iterator.next();
if (!ElementUtils.typeEquals(genericReturnType, executableTypeData.getReturnType())) {
iterator.remove();
specializedExecutableTypes.add(executableTypeData);
}
}
}
}
SpecializationData fallback = node.getGenericSpecialization();
if (fallback.getMethod() != null && fallback.isReachable()) {
clazz.add(createFallbackGuard());
}
for (ExecutableTypeData type : genericExecutableTypes) {
createExecute(clazz, type, Collections.<ExecutableTypeData>emptyList());
}
for (ExecutableTypeData type : specializedExecutableTypes) {
createExecute(clazz, type, genericExecutableTypes);
}
for (ExecutableTypeData type : voidExecutableTypes) {
List<ExecutableTypeData> genericAndSpecialized = new ArrayList<>();
genericAndSpecialized.addAll(genericExecutableTypes);
genericAndSpecialized.addAll(specializedExecutableTypes);
createExecute(clazz, type, genericAndSpecialized);
}
clazz.addOptional(createExecuteAndSpecialize());
if (shouldReportPolymorphism(node, reachableSpecializations)) {
clazz.addOptional(createCheckForPolymorphicSpecialize());
if (requiresCacheCheck()) {
clazz.addOptional(createCountCaches());
}
}
NodeInfo nodeInfo = node.getTemplateType().getAnnotation(NodeInfo.class);
if (nodeInfo == null || nodeInfo.cost() == NodeCost.MONOMORPHIC) /* the default */
{
clazz.add(createGetCostMethod());
}
for (TypeMirror type : ElementUtils.uniqueSortedTypes(expectedTypes, false)) {
if (!typeSystem.hasType(type)) {
clazz.addOptional(TypeSystemCodeGenerator.createExpectMethod(PRIVATE, typeSystem, context.getType(Object.class), type));
}
}
for (TypeMirror assumptionType : isValidSignatures.values()) {
clazz.add(createIsValid(assumptionType));
}
clazz.getEnclosedElements().addAll(removeThisMethods.values());
for (SpecializationData specialization : specializationClasses.keySet()) {
CodeTypeElement type = specializationClasses.get(specialization);
if (getInsertAccessorSet(true).contains(specialization)) {
type.add(createInsertAccessor(true));
} else if (getInsertAccessorSet(false).contains(specialization)) {
type.add(createInsertAccessor(false));
}
}
if (node.isReflectable()) {
generateReflectionInfo(clazz);
}
return clazz;
}
Aggregations