# HG changeset patch # User Christian Humer # Date 1395344411 -3600 # Node ID ab8a5b82fe7335e95905a0ed5922b020db143af7 # Parent 2a4b6003ef03d3d0d202d5975730b67b2fa42117# Parent 0111aa258537484e8291ca86f74bdaaa4e5f205c Merge. diff -r 0111aa258537 -r ab8a5b82fe73 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java Thu Mar 20 19:42:30 2014 +0100 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java Thu Mar 20 20:40:11 2014 +0100 @@ -64,7 +64,7 @@ TestRootNode node = TestHelper.createRoot(Node1Factory.getInstance()); assertEquals("(int,boolean)", executeWith(node, 42, false)); assertEquals("(int,int)", executeWith(node, 42, 42)); - assertEquals(NodeCost.NONE, node.getNode().getCost()); + assertEquals(NodeCost.POLYMORPHIC, node.getNode().getCost()); assertParent(node.getNode(), node.getNode().getLeft()); assertParent(node.getNode(), node.getNode().getRight()); } @@ -75,7 +75,7 @@ assertEquals("(int,boolean)", executeWith(node, 42, false)); assertEquals("(boolean,boolean)", executeWith(node, true, false)); assertEquals("(int,int)", executeWith(node, 42, 42)); - assertEquals(NodeCost.NONE, node.getNode().getCost()); + assertEquals(NodeCost.POLYMORPHIC, node.getNode().getCost()); assertParent(node.getNode(), node.getNode().getLeft()); assertParent(node.getNode(), node.getNode().getRight()); } diff -r 0111aa258537 -r ab8a5b82fe73 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java Thu Mar 20 19:42:30 2014 +0100 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java Thu Mar 20 20:40:11 2014 +0100 @@ -42,7 +42,7 @@ assertEquals(21, executeWith(node, false, false)); assertEquals(42, executeWith(node, 21, 21)); assertEquals("(boolean,int)", executeWith(node, false, 42)); - assertEquals(NodeCost.NONE, node.getNode().getCost()); + assertEquals(NodeCost.POLYMORPHIC, node.getNode().getCost()); } @SuppressWarnings("unused") diff -r 0111aa258537 -r ab8a5b82fe73 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Thu Mar 20 19:42:30 2014 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Thu Mar 20 20:40:11 2014 +0100 @@ -98,13 +98,17 @@ return param.getLocalName(); } - private static CodeTree createAccessChild(NodeExecutionData targetExecution) { + private static CodeTree createAccessChild(NodeExecutionData targetExecution, String thisReference) { + String reference = thisReference; + if (reference == null) { + reference = "this"; + } CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); Element accessElement = targetExecution.getChild().getAccessElement(); if (accessElement == null || accessElement.getKind() == ElementKind.METHOD) { - builder.string("this.").string(targetExecution.getChild().getName()); + builder.string(reference).string(".").string(targetExecution.getChild().getName()); } else if (accessElement.getKind() == ElementKind.FIELD) { - builder.string("this.").string(accessElement.getSimpleName().toString()); + builder.string(reference).string(".").string(accessElement.getSimpleName().toString()); } else { throw new AssertionError(); } @@ -357,7 +361,7 @@ nodes.nullLiteral(); arguments.string(valueName(parameter.getPreviousParameter())); } - nodes.tree(createAccessChild(executionData)); + nodes.tree(createAccessChild(executionData, null)); arguments.string(valueName(parameter)); empty = false; } @@ -928,12 +932,6 @@ var.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getChildAnnotation())); clazz.add(var); - CodeExecutableElement setter = new CodeExecutableElement(modifiers(PROTECTED), context.getType(void.class), "setNext0"); - setter.getParameters().add(new CodeVariableElement(clazz.asType(), "next0")); - CodeTreeBuilder builder = setter.createBuilder(); - builder.statement("this.next0 = insert(next0)"); - clazz.add(setter); - CodeExecutableElement genericCachedExecute = createCachedExecute(node, node.getPolymorphicSpecialization()); clazz.add(genericCachedExecute); @@ -948,41 +946,21 @@ } if (needsInvokeCopyConstructorMethod()) { - clazz.add(createInvokeCopyConstructor(clazz.asType(), null)); - clazz.add(createCopyPolymorphicConstructor(clazz.asType())); + clazz.add(createCopy(clazz.asType(), null)); } if (node.getGenericSpecialization() != null && node.getGenericSpecialization().isReachable()) { clazz.add(createGenericExecute(node, rootGroup)); } - clazz.add(createGetCost(node, null, NodeCost.MONOMORPHIC)); } protected boolean needsInvokeCopyConstructorMethod() { return getModel().getNode().isPolymorphic(); } - protected CodeExecutableElement createGetCost(NodeData node, SpecializationData specialization, NodeCost cost) { - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getTruffleTypes().getNodeCost(), "getCost"); - - TypeMirror nodeInfoKind = context.getTruffleTypes().getNodeCost(); - - CodeTreeBuilder builder = method.createBuilder(); - if (node.isPolymorphic() && specialization == null) { - // assume next0 exists - builder.startIf().string("next0 != null && next0.getCost() != ").staticReference(nodeInfoKind, "UNINITIALIZED").end(); - builder.startBlock(); - builder.startReturn().staticReference(nodeInfoKind, "POLYMORPHIC").end(); - builder.end(); - } - - builder.startReturn().staticReference(nodeInfoKind, cost.name()).end(); - return method; - } - - protected CodeExecutableElement createInvokeCopyConstructor(TypeMirror baseType, SpecializationData specialization) { - CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), baseType, "invokeCopyConstructor"); + protected CodeExecutableElement createCopy(TypeMirror baseType, SpecializationData specialization) { + CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), baseType, "copyWithConstructor"); if (specialization == null) { method.getModifiers().add(ABSTRACT); } else { @@ -998,36 +976,6 @@ return method; } - protected CodeExecutableElement createCopyPolymorphicConstructor(TypeMirror baseType) { - CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), baseType, "copyPolymorphic"); - CodeTreeBuilder builder = method.createBuilder(); - CodeTreeBuilder nullBuilder = builder.create(); - CodeTreeBuilder oldBuilder = builder.create(); - CodeTreeBuilder resetBuilder = builder.create(); - - for (ActualParameter param : getModel().getSignatureParameters()) { - NodeExecutionData execution = param.getSpecification().getExecution(); - - CodeTree access = createAccessChild(execution); - - String oldName = "old" + Utils.firstLetterUpperCase(param.getLocalName()); - oldBuilder.declaration(execution.getChild().getNodeData().getNodeType(), oldName, access); - nullBuilder.startStatement().tree(access).string(" = null").end(); - resetBuilder.startStatement().tree(access).string(" = ").string(oldName).end(); - } - - builder.tree(oldBuilder.getRoot()); - builder.tree(nullBuilder.getRoot()); - - builder.startStatement().type(baseType).string(" copy = "); - builder.startCall("invokeCopyConstructor").end(); - builder.end(); - - builder.tree(resetBuilder.getRoot()); - builder.startReturn().string("copy").end(); - return method; - } - private List createImplicitChildrenAccessors() { NodeData node = getModel().getNode(); // Map> expectTypes = new HashMap<>(); @@ -1280,7 +1228,7 @@ private CodeExecutableElement createGenericExecuteAndSpecialize(final NodeData node, SpecializationGroup rootGroup) { TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getType(); - CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), genericReturnType, EXECUTE_SPECIALIZE_NAME); + CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), genericReturnType, EXECUTE_SPECIALIZE_NAME); method.addParameter(new CodeVariableElement(getContext().getType(int.class), "minimumState")); addInternalValueParameters(method, node.getGenericSpecialization(), true, false); method.addParameter(new CodeVariableElement(getContext().getType(String.class), "reason")); @@ -1341,7 +1289,7 @@ private CodeExecutableElement createGenericExecute(NodeData node, SpecializationGroup group) { TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getType(); - CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), genericReturnType, EXECUTE_GENERIC_NAME); + CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), genericReturnType, EXECUTE_GENERIC_NAME); if (!node.needsFrame(getContext())) { method.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getSlowPath())); @@ -1816,11 +1764,16 @@ String uninitializedName = nodeSpecializationClassName(node.getUninitializedSpecialization()); CodeTreeBuilder builder = parent.create(); - builder.declaration(getElement().asType(), "currentCopy", currentNode + ".copyPolymorphic()"); + builder.declaration(getElement().asType(), "currentCopy", currentNode + ".copyWithConstructor()"); + for (ActualParameter param : getModel().getSignatureParameters()) { + NodeExecutionData execution = param.getSpecification().getExecution(); + builder.startStatement().tree(createAccessChild(execution, "currentCopy")).string(" = ").nullLiteral().end(); + } + builder.startStatement().string("currentCopy.next0 = ").startNew(uninitializedName).string("currentCopy").end().end(); + builder.declaration(polyClassName, "polymorphic", builder.create().startNew(polyClassName).string(currentNode).end()); + builder.startStatement().string("polymorphic.next0 = ").string("currentCopy").end(); builder.startStatement().startCall(currentNode, "replace").string("polymorphic").string("message").end().end(); - builder.startStatement().startCall("polymorphic", "setNext0").string("currentCopy").end().end(); - builder.startStatement().startCall("currentCopy", "setNext0").startNew(uninitializedName).string(currentNode).end().end().end(); builder.startReturn(); builder.startCall("currentCopy.next0", EXECUTE_POLYMORPHIC_NAME); @@ -2300,7 +2253,7 @@ private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeExecutionData targetExecution, ExecutableTypeData targetExecutable, ActualParameter unexpectedParameter) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); if (targetExecution != null) { - builder.tree(createAccessChild(targetExecution)); + builder.tree(createAccessChild(targetExecution, null)); builder.string("."); } @@ -2465,7 +2418,7 @@ } CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodePolymorphicClassName(node), baseType, false); - clazz.getAnnotationMirrors().add(createNodeInfo(node, NodeCost.NONE)); + clazz.getAnnotationMirrors().add(createNodeInfo(node, NodeCost.POLYMORPHIC)); for (ActualParameter polymorphParameter : polymorph.getSignatureParameters()) { if (!polymorphParameter.getTypeSystemType().isGeneric()) { @@ -2508,11 +2461,10 @@ } if (needsInvokeCopyConstructorMethod()) { - clazz.add(createInvokeCopyConstructor(nodeGen.asType(), specialization)); + clazz.add(createCopy(nodeGen.asType(), specialization)); } createCachedExecuteMethods(specialization); - clazz.add(createGetCost(specialization.getNode(), specialization, NodeCost.NONE)); } private ExecutableElement createUpdateType(ActualParameter parameter) { @@ -2558,7 +2510,7 @@ } else if (specialization.isUninitialized()) { cost = NodeCost.UNINITIALIZED; } else if (specialization.isPolymorphic()) { - cost = NodeCost.NONE; + cost = NodeCost.POLYMORPHIC; } else if (specialization.isSpecialized()) { cost = NodeCost.MONOMORPHIC; } else { @@ -2594,13 +2546,7 @@ getElement().add(createUpdateTypes(nodeGen.asType())); } if (needsInvokeCopyConstructorMethod()) { - clazz.add(createInvokeCopyConstructor(nodeGen.asType(), specialization)); - } - - if (specialization.isGeneric()) { - clazz.add(createGetCost(specialization.getNode(), specialization, NodeCost.MEGAMORPHIC)); - } else if (specialization.isUninitialized()) { - clazz.add(createGetCost(specialization.getNode(), specialization, NodeCost.UNINITIALIZED)); + clazz.add(createCopy(nodeGen.asType(), specialization)); } } @@ -2726,9 +2672,9 @@ builder.end(); builder.startElseBlock(); - builder.startStatement().startCall("setNext0"); + builder.startStatement().string("next0 = "); builder.startNew(nodeSpecializationClassName(node.getUninitializedSpecialization())).string("this").end(); - builder.end().end(); + builder.end(); CodeTreeBuilder specializeCall = new CodeTreeBuilder(builder); specializeCall.startCall(EXECUTE_SPECIALIZE_NAME);