Mercurial > hg > truffle
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 |