Mercurial > hg > graal-compiler
annotate src/share/vm/opto/cfgnode.hpp @ 3992:d1bdeef3e3e2
7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76
Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing.
Reviewed-by: tonyp, brutisso, ysr
author | johnc |
---|---|
date | Wed, 12 Oct 2011 10:25:51 -0700 |
parents | c7b60b601eb4 |
children | d092d1b31229 |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
400
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
400
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
400
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_OPTO_CFGNODE_HPP |
26 #define SHARE_VM_OPTO_CFGNODE_HPP | |
27 | |
28 #include "opto/multnode.hpp" | |
29 #include "opto/node.hpp" | |
30 #include "opto/opcodes.hpp" | |
31 #include "opto/type.hpp" | |
32 | |
0 | 33 // Portions of code courtesy of Clifford Click |
34 | |
35 // Optimization - Graph Style | |
36 | |
37 class Matcher; | |
38 class Node; | |
39 class RegionNode; | |
40 class TypeNode; | |
41 class PhiNode; | |
42 class GotoNode; | |
43 class MultiNode; | |
44 class MultiBranchNode; | |
45 class IfNode; | |
46 class PCTableNode; | |
47 class JumpNode; | |
48 class CatchNode; | |
49 class NeverBranchNode; | |
50 class ProjNode; | |
51 class CProjNode; | |
52 class IfTrueNode; | |
53 class IfFalseNode; | |
54 class CatchProjNode; | |
55 class JProjNode; | |
56 class JumpProjNode; | |
57 class SCMemProjNode; | |
58 class PhaseIdealLoop; | |
59 | |
60 //------------------------------RegionNode------------------------------------- | |
61 // The class of RegionNodes, which can be mapped to basic blocks in the | |
62 // program. Their inputs point to Control sources. PhiNodes (described | |
63 // below) have an input point to a RegionNode. Merged data inputs to PhiNodes | |
64 // correspond 1-to-1 with RegionNode inputs. The zero input of a PhiNode is | |
65 // the RegionNode, and the zero input of the RegionNode is itself. | |
66 class RegionNode : public Node { | |
67 public: | |
68 // Node layout (parallels PhiNode): | |
69 enum { Region, // Generally points to self. | |
70 Control // Control arcs are [1..len) | |
71 }; | |
72 | |
73 RegionNode( uint required ) : Node(required) { | |
74 init_class_id(Class_Region); | |
75 init_req(0,this); | |
76 } | |
77 | |
78 Node* is_copy() const { | |
79 const Node* r = _in[Region]; | |
80 if (r == NULL) | |
81 return nonnull_req(); | |
82 return NULL; // not a copy! | |
83 } | |
84 PhiNode* has_phi() const; // returns an arbitrary phi user, or NULL | |
85 PhiNode* has_unique_phi() const; // returns the unique phi user, or NULL | |
86 // Is this region node unreachable from root? | |
87 bool is_unreachable_region(PhaseGVN *phase) const; | |
88 virtual int Opcode() const; | |
89 virtual bool pinned() const { return (const Node *)in(0) == this; } | |
90 virtual bool is_CFG () const { return true; } | |
91 virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash | |
92 virtual bool depends_only_on_test() const { return false; } | |
93 virtual const Type *bottom_type() const { return Type::CONTROL; } | |
94 virtual const Type *Value( PhaseTransform *phase ) const; | |
95 virtual Node *Identity( PhaseTransform *phase ); | |
96 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
97 virtual const RegMask &out_RegMask() const; | |
98 }; | |
99 | |
100 //------------------------------JProjNode-------------------------------------- | |
101 // jump projection for node that produces multiple control-flow paths | |
102 class JProjNode : public ProjNode { | |
103 public: | |
104 JProjNode( Node* ctrl, uint idx ) : ProjNode(ctrl,idx) {} | |
105 virtual int Opcode() const; | |
106 virtual bool is_CFG() const { return true; } | |
107 virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash | |
108 virtual const Node* is_block_proj() const { return in(0); } | |
109 virtual const RegMask& out_RegMask() const; | |
110 virtual uint ideal_reg() const { return 0; } | |
111 }; | |
112 | |
113 //------------------------------PhiNode---------------------------------------- | |
114 // PhiNodes merge values from different Control paths. Slot 0 points to the | |
115 // controlling RegionNode. Other slots map 1-for-1 with incoming control flow | |
116 // paths to the RegionNode. For speed reasons (to avoid another pass) we | |
117 // can turn PhiNodes into copys in-place by NULL'ing out their RegionNode | |
118 // input in slot 0. | |
119 class PhiNode : public TypeNode { | |
120 const TypePtr* const _adr_type; // non-null only for Type::MEMORY nodes. | |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
121 const int _inst_id; // Instance id of the memory slice. |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
122 const int _inst_index; // Alias index of the instance memory slice. |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
123 // Array elements references have the same alias_idx but different offset. |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
124 const int _inst_offset; // Offset of the instance memory slice. |
0 | 125 // Size is bigger to hold the _adr_type field. |
126 virtual uint hash() const; // Check the type | |
127 virtual uint cmp( const Node &n ) const; | |
128 virtual uint size_of() const { return sizeof(*this); } | |
129 | |
130 // Determine if CMoveNode::is_cmove_id can be used at this join point. | |
131 Node* is_cmove_id(PhaseTransform* phase, int true_path); | |
132 | |
133 public: | |
134 // Node layout (parallels RegionNode): | |
135 enum { Region, // Control input is the Phi's region. | |
136 Input // Input values are [1..len) | |
137 }; | |
138 | |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
139 PhiNode( Node *r, const Type *t, const TypePtr* at = NULL, |
223 | 140 const int iid = TypeOopPtr::InstanceTop, |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
141 const int iidx = Compile::AliasIdxTop, |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
142 const int ioffs = Type::OffsetTop ) |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
143 : TypeNode(t,r->req()), |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
144 _adr_type(at), |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
145 _inst_id(iid), |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
146 _inst_index(iidx), |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
147 _inst_offset(ioffs) |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
148 { |
0 | 149 init_class_id(Class_Phi); |
150 init_req(0, r); | |
151 verify_adr_type(); | |
152 } | |
153 // create a new phi with in edges matching r and set (initially) to x | |
154 static PhiNode* make( Node* r, Node* x ); | |
155 // extra type arguments override the new phi's bottom_type and adr_type | |
156 static PhiNode* make( Node* r, Node* x, const Type *t, const TypePtr* at = NULL ); | |
157 // create a new phi with narrowed memory type | |
158 PhiNode* slice_memory(const TypePtr* adr_type) const; | |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
64
diff
changeset
|
159 PhiNode* split_out_instance(const TypePtr* at, PhaseIterGVN *igvn) const; |
0 | 160 // like make(r, x), but does not initialize the in edges to x |
161 static PhiNode* make_blank( Node* r, Node* x ); | |
162 | |
163 // Accessors | |
164 RegionNode* region() const { Node* r = in(Region); assert(!r || r->is_Region(), ""); return (RegionNode*)r; } | |
165 | |
166 Node* is_copy() const { | |
167 // The node is a real phi if _in[0] is a Region node. | |
168 DEBUG_ONLY(const Node* r = _in[Region];) | |
169 assert(r != NULL && r->is_Region(), "Not valid control"); | |
170 return NULL; // not a copy! | |
171 } | |
172 | |
400
cc80376deb0c
6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents:
235
diff
changeset
|
173 bool is_tripcount() const; |
cc80376deb0c
6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents:
235
diff
changeset
|
174 |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
175 // Determine a unique non-trivial input, if any. |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
176 // Ignore casts if it helps. Return NULL on failure. |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
177 Node* unique_input(PhaseTransform *phase); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
178 |
0 | 179 // Check for a simple dead loop. |
180 enum LoopSafety { Safe = 0, Unsafe, UnsafeLoop }; | |
181 LoopSafety simple_data_loop_check(Node *in) const; | |
182 // Is it unsafe data loop? It becomes a dead loop if this phi node removed. | |
183 bool is_unsafe_data_reference(Node *in) const; | |
184 int is_diamond_phi() const; | |
185 virtual int Opcode() const; | |
186 virtual bool pinned() const { return in(0) != 0; } | |
187 virtual const TypePtr *adr_type() const { verify_adr_type(true); return _adr_type; } | |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
188 |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
189 const int inst_id() const { return _inst_id; } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
190 const int inst_index() const { return _inst_index; } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
191 const int inst_offset() const { return _inst_offset; } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
192 bool is_same_inst_field(const Type* tp, int id, int index, int offset) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
193 return type()->basic_type() == tp->basic_type() && |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
194 inst_id() == id && |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
195 inst_index() == index && |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
196 inst_offset() == offset && |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
197 type()->higher_equal(tp); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
198 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
17
diff
changeset
|
199 |
0 | 200 virtual const Type *Value( PhaseTransform *phase ) const; |
201 virtual Node *Identity( PhaseTransform *phase ); | |
202 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
203 virtual const RegMask &out_RegMask() const; | |
204 virtual const RegMask &in_RegMask(uint) const; | |
205 #ifndef PRODUCT | |
206 virtual void dump_spec(outputStream *st) const; | |
207 #endif | |
208 #ifdef ASSERT | |
209 void verify_adr_type(VectorSet& visited, const TypePtr* at) const; | |
210 void verify_adr_type(bool recursive = false) const; | |
211 #else //ASSERT | |
212 void verify_adr_type(bool recursive = false) const {} | |
213 #endif //ASSERT | |
214 }; | |
215 | |
216 //------------------------------GotoNode--------------------------------------- | |
217 // GotoNodes perform direct branches. | |
218 class GotoNode : public Node { | |
219 public: | |
3842 | 220 GotoNode( Node *control ) : Node(control) {} |
0 | 221 virtual int Opcode() const; |
222 virtual bool pinned() const { return true; } | |
223 virtual bool is_CFG() const { return true; } | |
224 virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash | |
225 virtual const Node *is_block_proj() const { return this; } | |
226 virtual bool depends_only_on_test() const { return false; } | |
227 virtual const Type *bottom_type() const { return Type::CONTROL; } | |
228 virtual const Type *Value( PhaseTransform *phase ) const; | |
229 virtual Node *Identity( PhaseTransform *phase ); | |
230 virtual const RegMask &out_RegMask() const; | |
231 }; | |
232 | |
233 //------------------------------CProjNode-------------------------------------- | |
234 // control projection for node that produces multiple control-flow paths | |
235 class CProjNode : public ProjNode { | |
236 public: | |
237 CProjNode( Node *ctrl, uint idx ) : ProjNode(ctrl,idx) {} | |
238 virtual int Opcode() const; | |
239 virtual bool is_CFG() const { return true; } | |
240 virtual uint hash() const { return NO_HASH; } // CFG nodes do not hash | |
241 virtual const Node *is_block_proj() const { return in(0); } | |
242 virtual const RegMask &out_RegMask() const; | |
243 virtual uint ideal_reg() const { return 0; } | |
244 }; | |
245 | |
246 //---------------------------MultiBranchNode----------------------------------- | |
247 // This class defines a MultiBranchNode, a MultiNode which yields multiple | |
248 // control values. These are distinguished from other types of MultiNodes | |
249 // which yield multiple values, but control is always and only projection #0. | |
250 class MultiBranchNode : public MultiNode { | |
251 public: | |
252 MultiBranchNode( uint required ) : MultiNode(required) { | |
253 init_class_id(Class_MultiBranch); | |
254 } | |
127 | 255 // returns required number of users to be well formed. |
256 virtual int required_outcnt() const = 0; | |
0 | 257 }; |
258 | |
259 //------------------------------IfNode----------------------------------------- | |
260 // Output selected Control, based on a boolean test | |
261 class IfNode : public MultiBranchNode { | |
262 // Size is bigger to hold the probability field. However, _prob does not | |
263 // change the semantics so it does not appear in the hash & cmp functions. | |
264 virtual uint size_of() const { return sizeof(*this); } | |
265 public: | |
266 | |
267 // Degrees of branch prediction probability by order of magnitude: | |
268 // PROB_UNLIKELY_1e(N) is a 1 in 1eN chance. | |
269 // PROB_LIKELY_1e(N) is a 1 - PROB_UNLIKELY_1e(N) | |
270 #define PROB_UNLIKELY_MAG(N) (1e- ## N ## f) | |
271 #define PROB_LIKELY_MAG(N) (1.0f-PROB_UNLIKELY_MAG(N)) | |
272 | |
273 // Maximum and minimum branch prediction probabilties | |
274 // 1 in 1,000,000 (magnitude 6) | |
275 // | |
276 // Although PROB_NEVER == PROB_MIN and PROB_ALWAYS == PROB_MAX | |
277 // they are used to distinguish different situations: | |
278 // | |
279 // The name PROB_MAX (PROB_MIN) is for probabilities which correspond to | |
280 // very likely (unlikely) but with a concrete possibility of a rare | |
281 // contrary case. These constants would be used for pinning | |
282 // measurements, and as measures for assertions that have high | |
283 // confidence, but some evidence of occasional failure. | |
284 // | |
285 // The name PROB_ALWAYS (PROB_NEVER) is to stand for situations for which | |
286 // there is no evidence at all that the contrary case has ever occurred. | |
287 | |
288 #define PROB_NEVER PROB_UNLIKELY_MAG(6) | |
289 #define PROB_ALWAYS PROB_LIKELY_MAG(6) | |
290 | |
291 #define PROB_MIN PROB_UNLIKELY_MAG(6) | |
292 #define PROB_MAX PROB_LIKELY_MAG(6) | |
293 | |
294 // Static branch prediction probabilities | |
295 // 1 in 10 (magnitude 1) | |
296 #define PROB_STATIC_INFREQUENT PROB_UNLIKELY_MAG(1) | |
297 #define PROB_STATIC_FREQUENT PROB_LIKELY_MAG(1) | |
298 | |
299 // Fair probability 50/50 | |
300 #define PROB_FAIR (0.5f) | |
301 | |
302 // Unknown probability sentinel | |
303 #define PROB_UNKNOWN (-1.0f) | |
304 | |
305 // Probability "constructors", to distinguish as a probability any manifest | |
306 // constant without a names | |
307 #define PROB_LIKELY(x) ((float) (x)) | |
308 #define PROB_UNLIKELY(x) (1.0f - (float)(x)) | |
309 | |
310 // Other probabilities in use, but without a unique name, are documented | |
311 // here for lack of a better place: | |
312 // | |
313 // 1 in 1000 probabilities (magnitude 3): | |
314 // threshold for converting to conditional move | |
315 // likelihood of null check failure if a null HAS been seen before | |
316 // likelihood of slow path taken in library calls | |
317 // | |
318 // 1 in 10,000 probabilities (magnitude 4): | |
319 // threshold for making an uncommon trap probability more extreme | |
320 // threshold for for making a null check implicit | |
321 // likelihood of needing a gc if eden top moves during an allocation | |
322 // likelihood of a predicted call failure | |
323 // | |
324 // 1 in 100,000 probabilities (magnitude 5): | |
325 // threshold for ignoring counts when estimating path frequency | |
326 // likelihood of FP clipping failure | |
327 // likelihood of catching an exception from a try block | |
328 // likelihood of null check failure if a null has NOT been seen before | |
329 // | |
330 // Magic manifest probabilities such as 0.83, 0.7, ... can be found in | |
331 // gen_subtype_check() and catch_inline_exceptions(). | |
332 | |
333 float _prob; // Probability of true path being taken. | |
334 float _fcnt; // Frequency counter | |
335 IfNode( Node *control, Node *b, float p, float fcnt ) | |
336 : MultiBranchNode(2), _prob(p), _fcnt(fcnt) { | |
337 init_class_id(Class_If); | |
338 init_req(0,control); | |
339 init_req(1,b); | |
340 } | |
341 virtual int Opcode() const; | |
342 virtual bool pinned() const { return true; } | |
343 virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; } | |
344 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
345 virtual const Type *Value( PhaseTransform *phase ) const; | |
127 | 346 virtual int required_outcnt() const { return 2; } |
0 | 347 virtual const RegMask &out_RegMask() const; |
348 void dominated_by(Node* prev_dom, PhaseIterGVN* igvn); | |
349 int is_range_check(Node* &range, Node* &index, jint &offset); | |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
350 Node* fold_compares(PhaseGVN* phase); |
0 | 351 static Node* up_one_dom(Node* curr, bool linear_only = false); |
352 | |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
353 // Takes the type of val and filters it through the test represented |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
354 // by if_proj and returns a more refined type if one is produced. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
355 // Returns NULL is it couldn't improve the type. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
356 static const TypeInt* filtered_int_type(PhaseGVN* phase, Node* val, Node* if_proj); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
357 |
0 | 358 #ifndef PRODUCT |
359 virtual void dump_spec(outputStream *st) const; | |
360 #endif | |
361 }; | |
362 | |
363 class IfTrueNode : public CProjNode { | |
364 public: | |
365 IfTrueNode( IfNode *ifnode ) : CProjNode(ifnode,1) { | |
366 init_class_id(Class_IfTrue); | |
367 } | |
368 virtual int Opcode() const; | |
369 virtual Node *Identity( PhaseTransform *phase ); | |
370 }; | |
371 | |
372 class IfFalseNode : public CProjNode { | |
373 public: | |
374 IfFalseNode( IfNode *ifnode ) : CProjNode(ifnode,0) { | |
375 init_class_id(Class_IfFalse); | |
376 } | |
377 virtual int Opcode() const; | |
378 virtual Node *Identity( PhaseTransform *phase ); | |
379 }; | |
380 | |
381 | |
382 //------------------------------PCTableNode------------------------------------ | |
383 // Build an indirect branch table. Given a control and a table index, | |
384 // control is passed to the Projection matching the table index. Used to | |
385 // implement switch statements and exception-handling capabilities. | |
386 // Undefined behavior if passed-in index is not inside the table. | |
387 class PCTableNode : public MultiBranchNode { | |
388 virtual uint hash() const; // Target count; table size | |
389 virtual uint cmp( const Node &n ) const; | |
390 virtual uint size_of() const { return sizeof(*this); } | |
391 | |
392 public: | |
393 const uint _size; // Number of targets | |
394 | |
395 PCTableNode( Node *ctrl, Node *idx, uint size ) : MultiBranchNode(2), _size(size) { | |
396 init_class_id(Class_PCTable); | |
397 init_req(0, ctrl); | |
398 init_req(1, idx); | |
399 } | |
400 virtual int Opcode() const; | |
401 virtual const Type *Value( PhaseTransform *phase ) const; | |
402 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
403 virtual const Type *bottom_type() const; | |
404 virtual bool pinned() const { return true; } | |
127 | 405 virtual int required_outcnt() const { return _size; } |
0 | 406 }; |
407 | |
408 //------------------------------JumpNode--------------------------------------- | |
409 // Indirect branch. Uses PCTable above to implement a switch statement. | |
410 // It emits as a table load and local branch. | |
411 class JumpNode : public PCTableNode { | |
412 public: | |
413 JumpNode( Node* control, Node* switch_val, uint size) : PCTableNode(control, switch_val, size) { | |
414 init_class_id(Class_Jump); | |
415 } | |
416 virtual int Opcode() const; | |
417 virtual const RegMask& out_RegMask() const; | |
418 virtual const Node* is_block_proj() const { return this; } | |
419 }; | |
420 | |
421 class JumpProjNode : public JProjNode { | |
422 virtual uint hash() const; | |
423 virtual uint cmp( const Node &n ) const; | |
424 virtual uint size_of() const { return sizeof(*this); } | |
425 | |
426 private: | |
427 const int _dest_bci; | |
428 const uint _proj_no; | |
429 const int _switch_val; | |
430 public: | |
431 JumpProjNode(Node* jumpnode, uint proj_no, int dest_bci, int switch_val) | |
432 : JProjNode(jumpnode, proj_no), _dest_bci(dest_bci), _proj_no(proj_no), _switch_val(switch_val) { | |
433 init_class_id(Class_JumpProj); | |
434 } | |
435 | |
436 virtual int Opcode() const; | |
437 virtual const Type* bottom_type() const { return Type::CONTROL; } | |
438 int dest_bci() const { return _dest_bci; } | |
439 int switch_val() const { return _switch_val; } | |
440 uint proj_no() const { return _proj_no; } | |
441 #ifndef PRODUCT | |
442 virtual void dump_spec(outputStream *st) const; | |
443 #endif | |
444 }; | |
445 | |
446 //------------------------------CatchNode-------------------------------------- | |
447 // Helper node to fork exceptions. "Catch" catches any exceptions thrown by | |
448 // a just-prior call. Looks like a PCTableNode but emits no code - just the | |
449 // table. The table lookup and branch is implemented by RethrowNode. | |
450 class CatchNode : public PCTableNode { | |
451 public: | |
452 CatchNode( Node *ctrl, Node *idx, uint size ) : PCTableNode(ctrl,idx,size){ | |
453 init_class_id(Class_Catch); | |
454 } | |
455 virtual int Opcode() const; | |
456 virtual const Type *Value( PhaseTransform *phase ) const; | |
457 }; | |
458 | |
459 // CatchProjNode controls which exception handler is targetted after a call. | |
460 // It is passed in the bci of the target handler, or no_handler_bci in case | |
461 // the projection doesn't lead to an exception handler. | |
462 class CatchProjNode : public CProjNode { | |
463 virtual uint hash() const; | |
464 virtual uint cmp( const Node &n ) const; | |
465 virtual uint size_of() const { return sizeof(*this); } | |
466 | |
467 private: | |
468 const int _handler_bci; | |
469 | |
470 public: | |
471 enum { | |
472 fall_through_index = 0, // the fall through projection index | |
473 catch_all_index = 1, // the projection index for catch-alls | |
474 no_handler_bci = -1 // the bci for fall through or catch-all projs | |
475 }; | |
476 | |
477 CatchProjNode(Node* catchnode, uint proj_no, int handler_bci) | |
478 : CProjNode(catchnode, proj_no), _handler_bci(handler_bci) { | |
479 init_class_id(Class_CatchProj); | |
480 assert(proj_no != fall_through_index || handler_bci < 0, "fall through case must have bci < 0"); | |
481 } | |
482 | |
483 virtual int Opcode() const; | |
484 virtual Node *Identity( PhaseTransform *phase ); | |
485 virtual const Type *bottom_type() const { return Type::CONTROL; } | |
486 int handler_bci() const { return _handler_bci; } | |
487 bool is_handler_proj() const { return _handler_bci >= 0; } | |
488 #ifndef PRODUCT | |
489 virtual void dump_spec(outputStream *st) const; | |
490 #endif | |
491 }; | |
492 | |
493 | |
494 //---------------------------------CreateExNode-------------------------------- | |
495 // Helper node to create the exception coming back from a call | |
496 class CreateExNode : public TypeNode { | |
497 public: | |
498 CreateExNode(const Type* t, Node* control, Node* i_o) : TypeNode(t, 2) { | |
499 init_req(0, control); | |
500 init_req(1, i_o); | |
501 } | |
502 virtual int Opcode() const; | |
503 virtual Node *Identity( PhaseTransform *phase ); | |
504 virtual bool pinned() const { return true; } | |
505 uint match_edge(uint idx) const { return 0; } | |
506 virtual uint ideal_reg() const { return Op_RegP; } | |
507 }; | |
508 | |
509 //------------------------------NeverBranchNode------------------------------- | |
510 // The never-taken branch. Used to give the appearance of exiting infinite | |
511 // loops to those algorithms that like all paths to be reachable. Encodes | |
512 // empty. | |
513 class NeverBranchNode : public MultiBranchNode { | |
514 public: | |
515 NeverBranchNode( Node *ctrl ) : MultiBranchNode(1) { init_req(0,ctrl); } | |
516 virtual int Opcode() const; | |
517 virtual bool pinned() const { return true; }; | |
518 virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; } | |
127 | 519 virtual const Type *Value( PhaseTransform *phase ) const; |
520 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
521 virtual int required_outcnt() const { return 2; } | |
0 | 522 virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { } |
523 virtual uint size(PhaseRegAlloc *ra_) const { return 0; } | |
524 #ifndef PRODUCT | |
525 virtual void format( PhaseRegAlloc *, outputStream *st ) const; | |
526 #endif | |
527 }; | |
1972 | 528 |
529 #endif // SHARE_VM_OPTO_CFGNODE_HPP |