changeset 7755:e8c71b8562e3

Merge
author Christian Humer <christian.humer@gmail.com>
date Mon, 11 Feb 2013 10:41:29 +0100
parents 3cec97eb3b5f (diff) 52fd6491fca8 (current diff)
children 859f7ec58a71 10f1c713f4f0
files graal/com.oracle.graal.api.interpreter/overview.html graal/com.oracle.graal.api.interpreter/src/com/oracle/graal/api/interpreter/Interpreter.java graal/com.oracle.graal.api.interpreter/src/com/oracle/graal/api/interpreter/RuntimeInterpreterInterface.java graal/com.oracle.graal.api.interpreter/src/com/oracle/graal/api/interpreter/VirtualMachineComponent.java graal/com.oracle.graal.api.test/src/com/oracle/graal/api/test/GraalTest.java graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/X86InstructionDecoder.java graal/com.oracle.graal.interpreter/overview.html graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/BytecodeInterpreter.java graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/Frame.java graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/InterpreterCallable.java graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/InterpreterException.java graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/InterpreterFrame.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MaterializeNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewObjectArrayNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewPrimitiveArrayNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GlobalValueNumberingPhase.java
diffstat 8 files changed, 128 insertions(+), 75 deletions(-) [+]
line wrap: on
line diff
--- 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;
+
 }
--- 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
--- 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();
             }
 
--- 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<ExecutableTypeData> 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<ExecutableTypeData> findGenericExecutableTypes(ProcessorContext context) {
--- 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++) {
--- 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<TypeMirror> typeMirrors = new ArrayList<>();
+        Set<TypeMirror> typeMirrors = new LinkedHashSet<>();
 
         for (ExecutableTypeData typeData : nodeData.getExecutableTypes()) {
             typeMirrors.add(typeData.getType().getPrimitiveType());
--- 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<TypeDef> createTypeDefinitions(ParameterSpec returnType, List<? extends ParameterSpec> parameters) {
+    protected List<TypeDef> createTypeDefinitions(ParameterSpec returnType, List<? extends ParameterSpec> parameters) {
         List<TypeDef> typeDefs = new ArrayList<>();
 
-        TypeMirror[] types = returnType.getAllowedTypes();
         List<ParameterSpec> 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;
                     }
--- 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;
         }
+
     }
 }