Search in sources :

Example 11 with CodeVariableElement

use of com.oracle.truffle.dsl.processor.java.model.CodeVariableElement in project graal by oracle.

the class NodeParser method parseFields.

private List<NodeFieldData> parseFields(List<TypeElement> typeHierarchy, List<? extends Element> elements) {
    Set<String> names = new HashSet<>();
    List<NodeFieldData> fields = new ArrayList<>();
    for (VariableElement field : ElementFilter.fieldsIn(elements)) {
        if (field.getModifiers().contains(Modifier.STATIC)) {
            continue;
        } else if (field.getAnnotation(Executed.class) != null) {
            continue;
        }
        if (field.getModifiers().contains(Modifier.PUBLIC) || field.getModifiers().contains(Modifier.PROTECTED)) {
            String name = field.getSimpleName().toString();
            fields.add(new NodeFieldData(field, null, field, false));
            names.add(name);
        }
    }
    List<TypeElement> reversedTypeHierarchy = new ArrayList<>(typeHierarchy);
    Collections.reverse(reversedTypeHierarchy);
    for (TypeElement typeElement : reversedTypeHierarchy) {
        AnnotationMirror nodeChildrenMirror = ElementUtils.findAnnotationMirror(processingEnv, typeElement, NodeFields.class);
        List<AnnotationMirror> children = ElementUtils.collectAnnotations(context, nodeChildrenMirror, "value", typeElement, NodeField.class);
        for (AnnotationMirror mirror : children) {
            String name = ElementUtils.firstLetterLowerCase(ElementUtils.getAnnotationValue(String.class, mirror, "name"));
            TypeMirror type = ElementUtils.getAnnotationValue(TypeMirror.class, mirror, "type");
            if (type != null) {
                NodeFieldData field = new NodeFieldData(typeElement, mirror, new CodeVariableElement(type, name), true);
                if (name.isEmpty()) {
                    field.addError(ElementUtils.getAnnotationValue(mirror, "name"), "Field name cannot be empty.");
                } else if (names.contains(name)) {
                    field.addError(ElementUtils.getAnnotationValue(mirror, "name"), "Duplicate field name '%s'.", name);
                }
                names.add(name);
                fields.add(field);
            } else {
            // Type is null here. This indicates that the type could not be resolved.
            // The Java compiler will subsequently raise the appropriate error.
            }
        }
    }
    for (NodeFieldData nodeFieldData : fields) {
        nodeFieldData.setGetter(findGetter(elements, nodeFieldData.getName(), nodeFieldData.getType()));
    }
    return fields;
}
Also used : TypeElement(javax.lang.model.element.TypeElement) ArrayList(java.util.ArrayList) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) VariableElement(javax.lang.model.element.VariableElement) AnnotationMirror(javax.lang.model.element.AnnotationMirror) NodeFieldData(com.oracle.truffle.dsl.processor.model.NodeFieldData) ArrayCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) HashSet(java.util.HashSet)

Example 12 with CodeVariableElement

use of com.oracle.truffle.dsl.processor.java.model.CodeVariableElement in project graal by oracle.

the class FlatNodeGenFactory method createCheckForPolymorphicSpecialize.

private Element createCheckForPolymorphicSpecialize() {
    final boolean requiresExclude = requiresExclude();
    final boolean requiresCacheCheck = requiresCacheCheck();
    TypeMirror returnType = getType(void.class);
    CodeExecutableElement executable = new CodeExecutableElement(modifiers(PRIVATE), returnType, CHECK_FOR_POLYMORPHIC_SPECIALIZE);
    executable.addParameter(new CodeVariableElement(state.bitSetType, OLD_STATE));
    if (requiresExclude) {
        executable.addParameter(new CodeVariableElement(exclude.bitSetType, OLD_EXCLUDE));
    }
    if (requiresCacheCheck) {
        executable.addParameter(new CodeVariableElement(getType(int.class), OLD_CACHE_COUNT));
    }
    CodeTreeBuilder builder = executable.createBuilder();
    builder.declaration(state.bitSetType, NEW_STATE, state.createMaskedReference(FrameState.load(this), reachableSpecializations.toArray()));
    if (requiresExclude) {
        builder.declaration(exclude.bitSetType, NEW_EXCLUDE, exclude.createReference(FrameState.load(this)));
    }
    builder.startIf().string("(" + OLD_STATE + " ^ " + NEW_STATE + ") != 0");
    if (requiresExclude) {
        builder.string(" || ");
        builder.string("(" + OLD_EXCLUDE + " ^ " + NEW_EXCLUDE + ") != 0");
    }
    if (requiresCacheCheck) {
        builder.string(" || " + OLD_CACHE_COUNT + " < " + COUNT_CACHES + "()");
    }
    // if
    builder.end();
    builder.startBlock().startStatement().startCall("this", REPORT_POLYMORPHIC_SPECIALIZE).end(2);
    // true block
    builder.end();
    return executable;
}
Also used : CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) DeclaredCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror) ArrayCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror) GeneratedTypeMirror(com.oracle.truffle.dsl.processor.java.model.GeneratedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) CodeTreeBuilder(com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)

Example 13 with CodeVariableElement

use of com.oracle.truffle.dsl.processor.java.model.CodeVariableElement in project graal by oracle.

the class FlatNodeGenFactory method createIsValid.

private Element createIsValid(TypeMirror assumptionType) {
    CodeExecutableElement isValid = new CodeExecutableElement(modifiers(PRIVATE, STATIC), getType(boolean.class), "isValid_");
    CodeTreeBuilder builder = isValid.createBuilder();
    if (assumptionType.getKind() == TypeKind.ARRAY) {
        isValid.addAnnotationMirror(new CodeAnnotationMirror(context.getDeclaredType(ExplodeLoop.class)));
        isValid.addParameter(new CodeVariableElement(getType(Assumption[].class), "assumptions"));
        builder.startIf().string("assumptions == null").end().startBlock().returnFalse().end();
        builder.startFor().startGroup().type(((ArrayType) assumptionType).getComponentType()).string(" assumption : assumptions").end().end();
        builder.startBlock();
        builder.startIf().string("assumption == null || !assumption.isValid()").end();
        builder.startBlock();
        builder.returnFalse();
        builder.end();
        builder.end();
        builder.returnTrue();
    } else {
        isValid.addParameter(new CodeVariableElement(getType(Assumption.class), "assumption"));
        builder.startReturn().string("assumption != null && assumption.isValid()").end();
    }
    return isValid;
}
Also used : CodeAnnotationMirror(com.oracle.truffle.dsl.processor.java.model.CodeAnnotationMirror) ArrayType(javax.lang.model.type.ArrayType) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) CodeTreeBuilder(com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder) Assumption(com.oracle.truffle.api.Assumption)

Example 14 with CodeVariableElement

use of com.oracle.truffle.dsl.processor.java.model.CodeVariableElement 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();
}
Also used : CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) SpecializationData(com.oracle.truffle.dsl.processor.model.SpecializationData) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) CodeTreeBuilder(com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder) Lock(java.util.concurrent.locks.Lock)

Example 15 with CodeVariableElement

use of com.oracle.truffle.dsl.processor.java.model.CodeVariableElement 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;
}
Also used : ExecutableTypeData(com.oracle.truffle.dsl.processor.model.ExecutableTypeData) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) NodeChildData(com.oracle.truffle.dsl.processor.model.NodeChildData) NodeExecutionData(com.oracle.truffle.dsl.processor.model.NodeExecutionData) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) SpecializationData(com.oracle.truffle.dsl.processor.model.SpecializationData) NodeFieldData(com.oracle.truffle.dsl.processor.model.NodeFieldData) DeclaredCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror) ArrayCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror) GeneratedTypeMirror(com.oracle.truffle.dsl.processor.java.model.GeneratedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) NodeInfo(com.oracle.truffle.api.nodes.NodeInfo) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) Child(com.oracle.truffle.api.nodes.Node.Child)

Aggregations

CodeVariableElement (com.oracle.truffle.dsl.processor.java.model.CodeVariableElement)22 CodeExecutableElement (com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement)14 TypeMirror (javax.lang.model.type.TypeMirror)12 CodeTreeBuilder (com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)8 ArrayCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror)8 VariableElement (javax.lang.model.element.VariableElement)8 ArrayList (java.util.ArrayList)7 GeneratedTypeMirror (com.oracle.truffle.dsl.processor.java.model.GeneratedTypeMirror)6 DeclaredCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror)5 SpecializationData (com.oracle.truffle.dsl.processor.model.SpecializationData)5 ExecutableElement (javax.lang.model.element.ExecutableElement)5 CodeTypeElement (com.oracle.truffle.dsl.processor.java.model.CodeTypeElement)4 TypeElement (javax.lang.model.element.TypeElement)4 Child (com.oracle.truffle.api.nodes.Node.Child)3 CodeAnnotationMirror (com.oracle.truffle.dsl.processor.java.model.CodeAnnotationMirror)3 CodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror)3 NodeChildData (com.oracle.truffle.dsl.processor.model.NodeChildData)3 NodeExecutionData (com.oracle.truffle.dsl.processor.model.NodeExecutionData)3 Parameter (com.oracle.truffle.dsl.processor.model.Parameter)3 Assumption (com.oracle.truffle.api.Assumption)2