comparison graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java @ 9478:fb22b4d5f475

Allow distinction between ClassCastException and ArrayStoreException. Add more canonicalizations for check casts.
author Christian Wimmer <christian.wimmer@oracle.com>
date Wed, 01 May 2013 09:21:35 -0700
parents 435bb9425124
children 38b07e59dcbb
comparison
equal deleted inserted replaced
9477:3b02fe9e1983 9478:fb22b4d5f475
36 @Input private ValueNode object; 36 @Input private ValueNode object;
37 private final ResolvedJavaType type; 37 private final ResolvedJavaType type;
38 private final JavaTypeProfile profile; 38 private final JavaTypeProfile profile;
39 39
40 /** 40 /**
41 * Determines the exception thrown by this node if the check fails: {@link ClassCastException}
42 * if false; {@link ArrayStoreException} if true.
43 */
44 private final boolean forStoreCheck;
45
46 /**
41 * Creates a new CheckCast instruction. 47 * Creates a new CheckCast instruction.
42 * 48 *
43 * @param type the type being cast to 49 * @param type the type being cast to
44 * @param object the instruction producing the object 50 * @param object the instruction producing the object
45 */ 51 */
46 public CheckCastNode(ResolvedJavaType type, ValueNode object, JavaTypeProfile profile) { 52 public CheckCastNode(ResolvedJavaType type, ValueNode object, JavaTypeProfile profile, boolean forStoreCheck) {
47 super(StampFactory.declared(type)); 53 super(StampFactory.declared(type));
48 assert type != null; 54 assert type != null;
49 this.type = type; 55 this.type = type;
50 this.object = object; 56 this.object = object;
51 this.profile = profile; 57 this.profile = profile;
58 this.forStoreCheck = forStoreCheck;
59 }
60
61 public boolean isForStoreCheck() {
62 return forStoreCheck;
52 } 63 }
53 64
54 @Override 65 @Override
55 public void lower(LoweringTool tool, LoweringType loweringType) { 66 public void lower(LoweringTool tool, LoweringType loweringType) {
56 tool.getRuntime().lower(this, tool); 67 tool.getRuntime().lower(this, tool);
66 77
67 @Override 78 @Override
68 public ValueNode canonical(CanonicalizerTool tool) { 79 public ValueNode canonical(CanonicalizerTool tool) {
69 assert object() != null : this; 80 assert object() != null : this;
70 81
71 if (type != null) { 82 ResolvedJavaType objectType = object().objectStamp().type();
72 ResolvedJavaType objectType = object().objectStamp().type(); 83 if (objectType != null && type.isAssignableFrom(objectType)) {
73 if (objectType != null && type.isAssignableFrom(objectType)) { 84 // we don't have to check for null types here because they will also pass the
74 // we don't have to check for null types here because they will also pass the 85 // checkcast.
75 // checkcast. 86 return object();
87 }
88 // remove checkcast if the only usage is a more specific checkcast
89 if (usages().count() == 1) {
90 CheckCastNode ccn = usages().filter(CheckCastNode.class).first();
91 if (ccn != null && ccn.type() != null && type.isAssignableFrom(ccn.type())) {
76 return object(); 92 return object();
77 }
78
79 // remove checkcast if the only usage is a more specific checkcast
80 if (usages().count() == 1) {
81 CheckCastNode ccn = usages().filter(CheckCastNode.class).first();
82 if (ccn != null && ccn.type() != null && type.isAssignableFrom(ccn.type())) {
83 return object();
84 }
85 } 93 }
86 } 94 }
87 95
88 if (object().objectStamp().alwaysNull()) { 96 if (object().objectStamp().alwaysNull()) {
89 return object(); 97 return object();
98 }
99 if (tool.assumptions().useOptimisticAssumptions()) {
100 ResolvedJavaType exactType = type.findUniqueConcreteSubtype();
101 if (exactType != null && exactType != type) {
102 // Propagate more precise type information to usages of the checkcast.
103 tool.assumptions().recordConcreteSubtype(type, exactType);
104 return graph().add(new CheckCastNode(exactType, object, profile, forStoreCheck));
105 }
90 } 106 }
91 107
92 return this; 108 return this;
93 } 109 }
94 110