# HG changeset patch # User Christian Humer # Date 1360575689 -3600 # Node ID e8c71b8562e3bdc6b4935df928532bab685fab3b # Parent 3cec97eb3b5f6b8e20c2e2afe226ff339786ccfc# Parent 52fd6491fca8ae7c987825adaca9269c7d7b844e Merge diff -r 52fd6491fca8 -r e8c71b8562e3 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/Generic.java --- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/Generic.java Fri Feb 08 18:05:40 2013 +0100 +++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/Generic.java Mon Feb 11 10:41:29 2013 +0100 @@ -30,4 +30,7 @@ @Retention(RetentionPolicy.CLASS) @Target({ElementType.METHOD}) public @interface Generic { + + boolean useSpecializations() default true; + } diff -r 52fd6491fca8 -r e8c71b8562e3 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/GenericParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/GenericParser.java Fri Feb 08 18:05:40 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/GenericParser.java Mon Feb 11 10:41:29 2013 +0100 @@ -53,7 +53,9 @@ @Override public SpecializationData create(TemplateMethod method) { - return new SpecializationData(method, true, false); + SpecializationData data = new SpecializationData(method, true, false); + data.setUseSpecializationsForGeneric(Utils.getAnnotationValueBoolean(data.getMarkerAnnotation(), "useSpecializations")); + return data; } @Override diff -r 52fd6491fca8 -r e8c71b8562e3 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Fri Feb 08 18:05:40 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Mon Feb 11 10:41:29 2013 +0100 @@ -427,27 +427,32 @@ addValueParameters(method, node.getGenericSpecialization(), true); CodeTreeBuilder builder = method.createBuilder(); - boolean ifStarted = false; - for (int i = 0; i < node.getSpecializations().length; i++) { - SpecializationData specialization = node.getSpecializations()[i]; - if (specialization.isUninitialized()) { - continue; - } - if (!specialization.isGeneric()) { - if (!ifStarted) { - builder.startIf(); - ifStarted = true; + + if (node.getGenericSpecialization().isUseSpecializationsForGeneric()) { + boolean ifStarted = false; + for (int i = 0; i < node.getSpecializations().length; i++) { + SpecializationData specialization = node.getSpecializations()[i]; + if (specialization.isUninitialized()) { + continue; + } + if (!specialization.isGeneric()) { + if (!ifStarted) { + builder.startIf(); + ifStarted = true; + } else { + builder.startElseIf(); + } + emitGuards(getContext(), builder, "", specialization, false, true); + builder.end().startBlock(); } else { - builder.startElseIf(); + builder.startElseBlock(); } - emitGuards(getContext(), builder, "", specialization, false, true); - builder.end().startBlock(); - } else { - builder.startElseBlock(); + + emitInvokeDoMethod(builder, specialization, 0); + builder.end(); } - - emitInvokeDoMethod(builder, specialization, 0); - builder.end(); + } else { + emitInvokeDoMethod(builder, node.getGenericSpecialization(), 0); } return method; } @@ -529,57 +534,77 @@ NodeData node = specialization.getNode(); TypeSystemData typeSystem = node.getTypeSystem(); - if (!type.isVoid()) { - builder.startStatement().type(specialization.getReturnType().getActualType()).string(" result").end(); - } - + ExecutableTypeData castedType = node.findExecutableType(type); TypeData primaryType = specialization.getReturnType().getActualTypeData(typeSystem); ExecutableTypeData execType = specialization.getNode().findExecutableType(primaryType); - boolean needsTry = !specialization.getReturnType().getActualTypeData(typeSystem).isGeneric(); - if (needsTry) { - builder.startTryBlock(); - } + boolean needsTry = execType.hasUnexpectedValue(getContext()); + boolean returnVoid = type.isVoid(); - builder.startStatement(); - if (!type.isVoid()) { - builder.string("result = "); - } - buildExecute(builder, null, execType); - builder.end(); // statement + CodeTree primaryExecuteCall = null; + + CodeTreeBuilder executeBuilder = CodeTreeBuilder.createBuilder(); + buildExecute(executeBuilder, null, execType); + primaryExecuteCall = executeBuilder.getRoot(); if (needsTry) { - builder.end().startCatchBlock(getUnexpectedValueException(), "ex"); + if (!returnVoid) { + builder.declaration(primaryType.getPrimitiveType(), "value"); + } + builder.startTryBlock(); - if (!type.isVoid()) { - builder.startReturn(); - if (!type.isGeneric()) { - startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.expectTypeMethodName(type)); - } + if (returnVoid) { + builder.statement(primaryExecuteCall); + } else { + builder.startStatement(); + builder.string("value = "); + builder.tree(primaryExecuteCall); + builder.end(); + } - builder.string("ex.getResult()"); + builder.end().startCatchBlock(getUnexpectedValueException(), "ex"); + if (returnVoid) { + builder.string("// ignore").newLine(); + } else { + builder.startReturn(); + builder.tree(castPrimaryExecute(node, castedType, CodeTreeBuilder.singleString("ex.getResult()"))); + builder.end(); + } + builder.end(); - if (!type.isGeneric()) { - builder.end().end(); - } - builder.end(); // return + if (!returnVoid) { + builder.startReturn(); + builder.tree(castPrimaryExecute(node, castedType, CodeTreeBuilder.singleString("value"))); + builder.end(); + } + } else { + if (returnVoid) { + builder.statement(primaryExecuteCall); } else { - builder.string("// ignore").newLine(); + builder.startReturn(); + builder.tree(castPrimaryExecute(node, castedType, primaryExecuteCall)); + builder.end(); } } - builder.end(); // try/catch + } + + private CodeTree castPrimaryExecute(NodeData node, ExecutableTypeData castedType, CodeTree value) { + if (castedType.getType().isVoid()) { + return value; + } + if (castedType.getType().isGeneric()) { + return value; + } - if (!type.isVoid()) { - builder.startReturn(); - if (!type.isGeneric()) { - startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.expectTypeMethodName(type)); - } - builder.string("result"); - if (!type.isGeneric()) { - builder.end().end(); - } - builder.end(); // return + CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); + if (castedType.hasUnexpectedValue(getContext())) { + startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.expectTypeMethodName(castedType.getType())); + } else { + startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.asTypeMethodName(castedType.getType())); } + builder.tree(value); + builder.end().end(); + return builder.getRoot(); } private void buildFunctionalExecuteMethod(CodeTreeBuilder builder, SpecializationData specialization) { @@ -794,16 +819,22 @@ addValueParameterNames(specializeCall, nextSpecialization.getNode().getGenericSpecialization(), exceptionSpec != null ? exceptionSpec.getName() : null, true); specializeCall.end().end(); + TypeData expectedType = currentSpecialization.getReturnType().getActualTypeData(currentSpecialization.getNode().getTypeSystem()); if (canThrowUnexpected) { builder.startReturn(); - TypeData expectedType = currentSpecialization.getReturnType().getActualTypeData(currentSpecialization.getNode().getTypeSystem()); startCallTypeSystemMethod(context, builder, currentSpecialization.getNode(), TypeSystemCodeGenerator.expectTypeMethodName(expectedType)); builder.tree(specializeCall.getRoot()); builder.end().end(); builder.end(); // return } else { builder.startReturn(); - builder.tree(specializeCall.getRoot()); + if (!expectedType.isVoid() && !expectedType.isGeneric()) { + startCallTypeSystemMethod(context, builder, currentSpecialization.getNode(), TypeSystemCodeGenerator.asTypeMethodName(expectedType)); + builder.tree(specializeCall.getRoot()); + builder.end().end(); + } else { + builder.tree(specializeCall.getRoot()); + } builder.end(); } diff -r 52fd6491fca8 -r e8c71b8562e3 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java Fri Feb 08 18:05:40 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java Mon Feb 11 10:41:29 2013 +0100 @@ -128,22 +128,29 @@ public ExecutableTypeData findGenericExecutableType(ProcessorContext context) { List types = findGenericExecutableTypes(context); - if (types.size() == 1) { + if (types.isEmpty()) { + return null; + } else if (types.size() == 1) { return types.get(0); - } else { - ExecutableTypeData execType = null; - for (ExecutableTypeData type : types) { - TypeData returnType = type.getReturnType().getActualTypeData(getTypeSystem()); - if (!returnType.isVoid()) { - if (execType != null) { - // multiple generic types not allowed - return null; - } - execType = type; + } else if (types.size() == 2) { + if (types.get(0).getType().isVoid()) { + return types.get(1); + } else if (types.get(1).getType().isVoid()) { + return types.get(0); + } + } + + ExecutableTypeData execType = null; + for (ExecutableTypeData type : types) { + TypeData returnType = type.getReturnType().getActualTypeData(getTypeSystem()); + if (returnType.isGeneric()) { + if (execType != null) { + return null; } + execType = type; } - return execType; } + return execType; } private List findGenericExecutableTypes(ProcessorContext context) { diff -r 52fd6491fca8 -r e8c71b8562e3 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java Fri Feb 08 18:05:40 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java Mon Feb 11 10:41:29 2013 +0100 @@ -33,7 +33,7 @@ private final SpecializationThrowsData[] exceptions; private SpecializationGuardData[] guards; private ShortCircuitData[] shortCircuits; - + private boolean useSpecializationsForGeneric = true; private NodeData node; public SpecializationData(TemplateMethod template, int order, SpecializationThrowsData[] exceptions) { @@ -97,6 +97,14 @@ return shortCircuits; } + void setUseSpecializationsForGeneric(boolean useSpecializationsForGeneric) { + this.useSpecializationsForGeneric = useSpecializationsForGeneric; + } + + public boolean isUseSpecializationsForGeneric() { + return useSpecializationsForGeneric; + } + public SpecializationData findNextSpecialization() { SpecializationData[] specializations = node.getSpecializations(); for (int i = 0; i < specializations.length - 1; i++) { diff -r 52fd6491fca8 -r e8c71b8562e3 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java Fri Feb 08 18:05:40 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java Mon Feb 11 10:41:29 2013 +0100 @@ -66,7 +66,7 @@ } private static TypeMirror[] nodeTypeMirrors(NodeData nodeData) { - List typeMirrors = new ArrayList<>(); + Set typeMirrors = new LinkedHashSet<>(); for (ExecutableTypeData typeData : nodeData.getExecutableTypes()) { typeMirrors.add(typeData.getType().getPrimitiveType()); diff -r 52fd6491fca8 -r e8c71b8562e3 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java Fri Feb 08 18:05:40 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java Mon Feb 11 10:41:29 2013 +0100 @@ -233,10 +233,9 @@ return new ActualParameter(specification, resolvedType); } - protected static List createTypeDefinitions(ParameterSpec returnType, List parameters) { + protected List createTypeDefinitions(ParameterSpec returnType, List parameters) { List typeDefs = new ArrayList<>(); - TypeMirror[] types = returnType.getAllowedTypes(); List allParams = new ArrayList<>(); allParams.add(returnType); allParams.addAll(parameters); @@ -244,10 +243,11 @@ int defIndex = 0; for (ParameterSpec spec : allParams) { TypeMirror[] allowedTypes = spec.getAllowedTypes(); + TypeMirror[] types = spec.getAllowedTypes(); if (types != null && allowedTypes.length > 1) { TypeDef foundDef = null; for (TypeDef def : typeDefs) { - if (Arrays.equals(spec.getAllowedTypes(), def.getTypes())) { + if (Arrays.equals(allowedTypes, def.getTypes())) { foundDef = def; break; } diff -r 52fd6491fca8 -r e8c71b8562e3 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemCodeGenerator.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemCodeGenerator.java Fri Feb 08 18:05:40 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemCodeGenerator.java Mon Feb 11 10:41:29 2013 +0100 @@ -215,6 +215,7 @@ method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE)); CodeTreeBuilder body = method.createBuilder(); + body.startAssert().startCall(isTypeMethodName(type)).string(LOCAL_VALUE).end().end(); body.startReturn().cast(type.getPrimitiveType(), body.create().string(LOCAL_VALUE).getTree()).end(); return method; @@ -233,5 +234,6 @@ return method; } + } }