changeset 7768:28371edb0d4f

Merge
author Lukas Stadler <lukas.stadler@jku.at>
date Mon, 11 Feb 2013 15:56:10 +0100
parents 4a6646d8eb87 (current diff) 859f7ec58a71 (diff)
children 41292de7ac48
files
diffstat 11 files changed, 146 insertions(+), 82 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java	Mon Feb 11 15:55:27 2013 +0100
+++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java	Mon Feb 11 15:56:10 2013 +0100
@@ -37,7 +37,7 @@
         CodeGenTest test = new CodeGenTest() {
 
             @Override
-            public Buffer generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig) {
+            public Buffer generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) {
                 AMD64Assembler asm = new AMD64Assembler(target, registerConfig);
                 Register ret = registerConfig.getReturnRegister(Kind.Int);
                 asm.movl(ret, 8472);
@@ -53,7 +53,7 @@
         CodeGenTest test = new CodeGenTest() {
 
             @Override
-            public Buffer generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig) {
+            public Buffer generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) {
                 AMD64MacroAssembler asm = new AMD64MacroAssembler(target, registerConfig);
                 Register ret = registerConfig.getReturnRegister(Kind.Double);
                 compResult.recordDataReference(asm.codeBuffer.position(), Constant.forDouble(84.72), 8, false);
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Mon Feb 11 15:55:27 2013 +0100
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Mon Feb 11 15:56:10 2013 +0100
@@ -201,7 +201,7 @@
         emitByte(op2 | encode(dst) << 3 | encode(src));
     }
 
-    private void emitOperandHelper(Register reg, Address addr) {
+    protected void emitOperandHelper(Register reg, Address addr) {
         Register base = isLegal(addr.getBase()) ? asRegister(addr.getBase()) : Register.None;
         Register index = isLegal(addr.getIndex()) ? asRegister(addr.getIndex()) : Register.None;
 
--- a/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java	Mon Feb 11 15:55:27 2013 +0100
+++ b/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java	Mon Feb 11 15:56:10 2013 +0100
@@ -38,7 +38,7 @@
 
     public interface CodeGenTest {
 
-        Buffer generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig);
+        Buffer generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc);
     }
 
     public AssemblerTest() {
@@ -51,17 +51,28 @@
 
         CompilationResult compResult = new CompilationResult();
 
-        Buffer codeBuffer = test.generateCode(compResult, codeCache.getTarget(), registerConfig);
+        Signature sig = method.getSignature();
+        JavaType retType = sig.getReturnType(null);
+        JavaType[] argTypes = new JavaType[sig.getParameterCount(false)];
+        for (int i = 0; i < argTypes.length; i++) {
+            argTypes[i] = sig.getParameterType(i, null);
+        }
+        CallingConvention cc = registerConfig.getCallingConvention(CallingConvention.Type.JavaCallee, retType, argTypes, codeCache.getTarget(), false);
+
+        Buffer codeBuffer = test.generateCode(compResult, codeCache.getTarget(), registerConfig, cc);
         compResult.setTargetCode(codeBuffer.close(true), codeBuffer.position());
 
         return codeCache.addMethod(method, compResult, null);
     }
 
-    protected void assertReturn(String methodName, CodeGenTest test, Object expected, Object... args) {
+    protected Object runTest(String methodName, CodeGenTest test, Object... args) {
         Method method = getMethod(methodName);
         InstalledCode code = assembleMethod(method, test);
+        return code.executeVarargs(args);
+    }
 
-        Object actual = code.executeVarargs(args);
+    protected void assertReturn(String methodName, CodeGenTest test, Object expected, Object... args) {
+        Object actual = runTest(methodName, test, args);
         Assert.assertEquals("unexpected return value: " + actual, actual, expected);
     }
 }
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/Generic.java	Mon Feb 11 15:55:27 2013 +0100
+++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/Generic.java	Mon Feb 11 15:56:10 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	Mon Feb 11 15:55:27 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/GenericParser.java	Mon Feb 11 15:56:10 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	Mon Feb 11 15:55:27 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Mon Feb 11 15:56:10 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	Mon Feb 11 15:55:27 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java	Mon Feb 11 15:56:10 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	Mon Feb 11 15:55:27 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java	Mon Feb 11 15:56:10 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	Mon Feb 11 15:55:27 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java	Mon Feb 11 15:56:10 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	Mon Feb 11 15:55:27 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java	Mon Feb 11 15:56:10 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	Mon Feb 11 15:55:27 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemCodeGenerator.java	Mon Feb 11 15:56:10 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;
         }
+
     }
 }