comparison graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java @ 18330:fe77c26ccde6

Truffle: fix stable array canonicalization
author Andreas Woess <andreas.woess@jku.at>
date Mon, 10 Nov 2014 19:03:06 +0100
parents 9619ba4daf4c
children f0a8b72315c1
comparison
equal deleted inserted replaced
18329:75e72d395820 18330:fe77c26ccde6
25 import com.oracle.graal.api.meta.*; 25 import com.oracle.graal.api.meta.*;
26 import com.oracle.graal.graph.Node; 26 import com.oracle.graal.graph.Node;
27 import com.oracle.graal.nodes.*; 27 import com.oracle.graal.nodes.*;
28 import com.oracle.graal.nodes.java.*; 28 import com.oracle.graal.nodes.java.*;
29 import com.oracle.graal.phases.common.*; 29 import com.oracle.graal.phases.common.*;
30 import com.oracle.truffle.api.*; 30 import com.oracle.graal.truffle.nodes.*;
31 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
31 import com.oracle.truffle.api.nodes.Node.Child; 32 import com.oracle.truffle.api.nodes.Node.Child;
33 import com.oracle.truffle.api.nodes.Node.Children;
32 34
33 final class PartialEvaluatorCanonicalizer extends CanonicalizerPhase.CustomCanonicalizer { 35 final class PartialEvaluatorCanonicalizer extends CanonicalizerPhase.CustomCanonicalizer {
34 36
35 private final MetaAccessProvider metaAccess; 37 private final MetaAccessProvider metaAccess;
36 private final ConstantReflectionProvider constantReflection; 38 private final ConstantReflectionProvider constantReflection;
50 return node; 52 return node;
51 } 53 }
52 54
53 private Node canonicalizeLoadField(LoadFieldNode loadFieldNode) { 55 private Node canonicalizeLoadField(LoadFieldNode loadFieldNode) {
54 if (!loadFieldNode.isStatic() && loadFieldNode.object().isConstant() && !loadFieldNode.object().isNullConstant()) { 56 if (!loadFieldNode.isStatic() && loadFieldNode.object().isConstant() && !loadFieldNode.object().isNullConstant()) {
55 if (loadFieldNode.field().isFinal() || (loadFieldNode.getKind() == Kind.Object && loadFieldNode.field().getAnnotation(Child.class) != null) || 57 ResolvedJavaField field = loadFieldNode.field();
56 loadFieldNode.field().getAnnotation(CompilerDirectives.CompilationFinal.class) != null) { 58 JavaType fieldType = field.getType();
57 JavaConstant constant = loadFieldNode.field().readValue(loadFieldNode.object().asJavaConstant()); 59 if (field.isFinal() || field.getAnnotation(CompilationFinal.class) != null ||
58 assert verifyFieldValue(loadFieldNode.field(), constant); 60 (fieldType.getKind() == Kind.Object && (field.getAnnotation(Child.class) != null || field.getAnnotation(Children.class) != null))) {
59 return ConstantNode.forConstant(constant, metaAccess); 61 JavaConstant constant = field.readValue(loadFieldNode.object().asJavaConstant());
62 assert verifyFieldValue(field, constant);
63 if (constant.isNonNull() && fieldType.getKind() == Kind.Object && fieldType.getComponentType() != null &&
64 (field.getAnnotation(CompilationFinal.class) != null || field.getAnnotation(Children.class) != null)) {
65 int stableDimensions = getDeclaredArrayDimensions(fieldType);
66 return StableArrayConstantNode.forStableArrayConstant(constant, stableDimensions, true, metaAccess);
67 } else {
68 return ConstantNode.forConstant(constant, metaAccess);
69 }
60 } 70 }
61 } 71 }
62 return loadFieldNode; 72 return loadFieldNode;
63 } 73 }
64 74
65 private Node canonicalizeLoadIndex(LoadIndexedNode loadIndexedNode) { 75 private Node canonicalizeLoadIndex(LoadIndexedNode loadIndexedNode) {
66 if (loadIndexedNode.array().isConstant() && loadIndexedNode.index().isConstant()) { 76 if (loadIndexedNode.array() instanceof StableArrayConstantNode && loadIndexedNode.index().isConstant()) {
77 StableArrayConstantNode stableArray = (StableArrayConstantNode) loadIndexedNode.array();
67 int index = loadIndexedNode.index().asJavaConstant().asInt(); 78 int index = loadIndexedNode.index().asJavaConstant().asInt();
68 79
69 JavaConstant constant = constantReflection.readArrayElement(loadIndexedNode.array().asJavaConstant(), index); 80 JavaConstant constant = constantReflection.readArrayElement(loadIndexedNode.array().asJavaConstant(), index);
70 if (constant != null) { 81 if (constant != null) {
71 return ConstantNode.forConstant(constant, metaAccess); 82 if (stableArray.getStableDimensions() > 1 && constant.isNonNull()) {
83 return StableArrayConstantNode.forStableArrayConstant(constant, stableArray.getStableDimensions() - 1, stableArray.isCompilationFinal(), metaAccess);
84 } else if (constant.isNonNull() || stableArray.isCompilationFinal()) {
85 return ConstantNode.forConstant(constant, metaAccess);
86 }
72 } 87 }
73 } 88 }
74 return loadIndexedNode; 89 return loadIndexedNode;
90 }
91
92 private static int getDeclaredArrayDimensions(JavaType type) {
93 int dimensions = 0;
94 JavaType componentType = type;
95 while ((componentType = componentType.getComponentType()) != null) {
96 dimensions++;
97 }
98 return dimensions;
75 } 99 }
76 100
77 private boolean verifyFieldValue(ResolvedJavaField field, JavaConstant constant) { 101 private boolean verifyFieldValue(ResolvedJavaField field, JavaConstant constant) {
78 assert field.getAnnotation(Child.class) == null || constant.isNull() || 102 assert field.getAnnotation(Child.class) == null || constant.isNull() ||
79 metaAccess.lookupJavaType(com.oracle.truffle.api.nodes.Node.class).isAssignableFrom(metaAccess.lookupJavaType(constant)) : "@Child field value must be a Node: " + field + 103 metaAccess.lookupJavaType(com.oracle.truffle.api.nodes.Node.class).isAssignableFrom(metaAccess.lookupJavaType(constant)) : "@Child field value must be a Node: " + field +
80 ", but was: " + constant; 104 ", but was: " + constant;
105 assert field.getAnnotation(Children.class) == null || constant.isNull() || metaAccess.lookupJavaType(constant).isArray() : "@Children field value must be an array: " + field + ", but was: " +
106 constant;
81 return true; 107 return true;
82 } 108 }
83 } 109 }