Mercurial > hg > truffle
annotate src/share/vm/opto/memnode.hpp @ 4710:41406797186b
7113012: G1: rename not-fully-young GCs as "mixed"
Summary: Renamed partially-young GCs as mixed and fully-young GCs as young. Change all external output that includes those terms (GC log and GC ergo log) as well as any comments, fields, methods, etc. The changeset also includes very minor code tidying up (added some curly brackets).
Reviewed-by: johnc, brutisso
author | tonyp |
---|---|
date | Fri, 16 Dec 2011 02:14:27 -0500 |
parents | 1bd45abaa507 |
children | 1dc233a8c7fe |
rev | line source |
---|---|
0 | 1 /* |
2426
1d1603768966
7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents:
2412
diff
changeset
|
2 * Copyright (c) 1997, 2011, 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:
1367
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1367
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:
1367
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_OPTO_MEMNODE_HPP |
26 #define SHARE_VM_OPTO_MEMNODE_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 class MultiNode; | |
36 class PhaseCCP; | |
37 class PhaseTransform; | |
38 | |
39 //------------------------------MemNode---------------------------------------- | |
40 // Load or Store, possibly throwing a NULL pointer exception | |
41 class MemNode : public Node { | |
42 protected: | |
43 #ifdef ASSERT | |
44 const TypePtr* _adr_type; // What kind of memory is being addressed? | |
45 #endif | |
46 virtual uint size_of() const; // Size is bigger (ASSERT only) | |
47 public: | |
48 enum { Control, // When is it safe to do this load? | |
49 Memory, // Chunk of memory is being loaded from | |
50 Address, // Actually address, derived from base | |
51 ValueIn, // Value to store | |
52 OopStore // Preceeding oop store, only in StoreCM | |
53 }; | |
54 protected: | |
55 MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at ) | |
56 : Node(c0,c1,c2 ) { | |
57 init_class_id(Class_Mem); | |
58 debug_only(_adr_type=at; adr_type();) | |
59 } | |
60 MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at, Node *c3 ) | |
61 : Node(c0,c1,c2,c3) { | |
62 init_class_id(Class_Mem); | |
63 debug_only(_adr_type=at; adr_type();) | |
64 } | |
65 MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at, Node *c3, Node *c4) | |
66 : Node(c0,c1,c2,c3,c4) { | |
67 init_class_id(Class_Mem); | |
68 debug_only(_adr_type=at; adr_type();) | |
69 } | |
70 | |
33 | 71 public: |
0 | 72 // Helpers for the optimizer. Documented in memnode.cpp. |
73 static bool detect_ptr_independence(Node* p1, AllocateNode* a1, | |
74 Node* p2, AllocateNode* a2, | |
75 PhaseTransform* phase); | |
76 static bool adr_phi_is_loop_invariant(Node* adr_phi, Node* cast); | |
77 | |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
64
diff
changeset
|
78 static Node *optimize_simple_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
64
diff
changeset
|
79 static Node *optimize_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase); |
0 | 80 // This one should probably be a phase-specific function: |
85
f3b3fe64f59f
6692301: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
74
diff
changeset
|
81 static bool all_controls_dominate(Node* dom, Node* sub); |
0 | 82 |
163 | 83 // Find any cast-away of null-ness and keep its control. |
84 static Node *Ideal_common_DU_postCCP( PhaseCCP *ccp, Node* n, Node* adr ); | |
0 | 85 virtual Node *Ideal_DU_postCCP( PhaseCCP *ccp ); |
86 | |
87 virtual const class TypePtr *adr_type() const; // returns bottom_type of address | |
88 | |
89 // Shared code for Ideal methods: | |
90 Node *Ideal_common(PhaseGVN *phase, bool can_reshape); // Return -1 for short-circuit NULL. | |
91 | |
92 // Helper function for adr_type() implementations. | |
93 static const TypePtr* calculate_adr_type(const Type* t, const TypePtr* cross_check = NULL); | |
94 | |
95 // Raw access function, to allow copying of adr_type efficiently in | |
96 // product builds and retain the debug info for debug builds. | |
97 const TypePtr *raw_adr_type() const { | |
98 #ifdef ASSERT | |
99 return _adr_type; | |
100 #else | |
101 return 0; | |
102 #endif | |
103 } | |
104 | |
105 // Map a load or store opcode to its corresponding store opcode. | |
106 // (Return -1 if unknown.) | |
107 virtual int store_Opcode() const { return -1; } | |
108 | |
109 // What is the type of the value in memory? (T_VOID mean "unspecified".) | |
110 virtual BasicType memory_type() const = 0; | |
29
d5fc211aea19
6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents:
17
diff
changeset
|
111 virtual int memory_size() const { |
d5fc211aea19
6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents:
17
diff
changeset
|
112 #ifdef ASSERT |
d5fc211aea19
6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents:
17
diff
changeset
|
113 return type2aelembytes(memory_type(), true); |
d5fc211aea19
6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents:
17
diff
changeset
|
114 #else |
d5fc211aea19
6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents:
17
diff
changeset
|
115 return type2aelembytes(memory_type()); |
d5fc211aea19
6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents:
17
diff
changeset
|
116 #endif |
d5fc211aea19
6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents:
17
diff
changeset
|
117 } |
0 | 118 |
119 // Search through memory states which precede this node (load or store). | |
120 // Look for an exact match for the address, with no intervening | |
121 // aliased stores. | |
122 Node* find_previous_store(PhaseTransform* phase); | |
123 | |
124 // Can this node (load or store) accurately see a stored value in | |
125 // the given memory state? (The state may or may not be in(Memory).) | |
126 Node* can_see_stored_value(Node* st, PhaseTransform* phase) const; | |
127 | |
128 #ifndef PRODUCT | |
129 static void dump_adr_type(const Node* mem, const TypePtr* adr_type, outputStream *st); | |
130 virtual void dump_spec(outputStream *st) const; | |
131 #endif | |
132 }; | |
133 | |
134 //------------------------------LoadNode--------------------------------------- | |
135 // Load value; requires Memory and Address | |
136 class LoadNode : public MemNode { | |
137 protected: | |
138 virtual uint cmp( const Node &n ) const; | |
139 virtual uint size_of() const; // Size is bigger | |
140 const Type* const _type; // What kind of value is loaded? | |
141 public: | |
142 | |
143 LoadNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *rt ) | |
144 : MemNode(c,mem,adr,at), _type(rt) { | |
145 init_class_id(Class_Load); | |
146 } | |
147 | |
148 // Polymorphic factory method: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
149 static Node* make( PhaseGVN& gvn, Node *c, Node *mem, Node *adr, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
150 const TypePtr* at, const Type *rt, BasicType bt ); |
0 | 151 |
152 virtual uint hash() const; // Check the type | |
153 | |
154 // Handle algebraic identities here. If we have an identity, return the Node | |
155 // we are equivalent to. We look for Load of a Store. | |
156 virtual Node *Identity( PhaseTransform *phase ); | |
157 | |
158 // If the load is from Field memory and the pointer is non-null, we can | |
159 // zero out the control input. | |
160 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
161 | |
163 | 162 // Split instance field load through Phi. |
163 Node* split_through_phi(PhaseGVN *phase); | |
164 | |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
165 // Recover original value from boxed values |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
166 Node *eliminate_autobox(PhaseGVN *phase); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
167 |
0 | 168 // Compute a new Type for this node. Basically we just do the pre-check, |
169 // then call the virtual add() to set the type. | |
170 virtual const Type *Value( PhaseTransform *phase ) const; | |
171 | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
172 // Common methods for LoadKlass and LoadNKlass nodes. |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
173 const Type *klass_value_common( PhaseTransform *phase ) const; |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
174 Node *klass_identity_common( PhaseTransform *phase ); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
175 |
0 | 176 virtual uint ideal_reg() const; |
177 virtual const Type *bottom_type() const; | |
178 // Following method is copied from TypeNode: | |
179 void set_type(const Type* t) { | |
180 assert(t != NULL, "sanity"); | |
181 debug_only(uint check_hash = (VerifyHashTableKeys && _hash_lock) ? hash() : NO_HASH); | |
182 *(const Type**)&_type = t; // cast away const-ness | |
183 // If this node is in the hash table, make sure it doesn't need a rehash. | |
184 assert(check_hash == NO_HASH || check_hash == hash(), "type change must preserve hash code"); | |
185 } | |
186 const Type* type() const { assert(_type != NULL, "sanity"); return _type; }; | |
187 | |
188 // Do not match memory edge | |
189 virtual uint match_edge(uint idx) const; | |
190 | |
191 // Map a load opcode to its corresponding store opcode. | |
192 virtual int store_Opcode() const = 0; | |
193 | |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
33
diff
changeset
|
194 // Check if the load's memory input is a Phi node with the same control. |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
33
diff
changeset
|
195 bool is_instance_field_load_with_local_phi(Node* ctrl); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
33
diff
changeset
|
196 |
0 | 197 #ifndef PRODUCT |
198 virtual void dump_spec(outputStream *st) const; | |
199 #endif | |
1609 | 200 #ifdef ASSERT |
201 // Helper function to allow a raw load without control edge for some cases | |
202 static bool is_immutable_value(Node* adr); | |
203 #endif | |
0 | 204 protected: |
205 const Type* load_array_final_field(const TypeKlassPtr *tkls, | |
206 ciKlass* klass) const; | |
207 }; | |
208 | |
209 //------------------------------LoadBNode-------------------------------------- | |
210 // Load a byte (8bits signed) from memory | |
211 class LoadBNode : public LoadNode { | |
212 public: | |
213 LoadBNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::BYTE ) | |
214 : LoadNode(c,mem,adr,at,ti) {} | |
215 virtual int Opcode() const; | |
216 virtual uint ideal_reg() const { return Op_RegI; } | |
217 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
218 virtual int store_Opcode() const { return Op_StoreB; } | |
219 virtual BasicType memory_type() const { return T_BYTE; } | |
220 }; | |
221 | |
624 | 222 //------------------------------LoadUBNode------------------------------------- |
223 // Load a unsigned byte (8bits unsigned) from memory | |
224 class LoadUBNode : public LoadNode { | |
225 public: | |
226 LoadUBNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt* ti = TypeInt::UBYTE ) | |
227 : LoadNode(c, mem, adr, at, ti) {} | |
228 virtual int Opcode() const; | |
229 virtual uint ideal_reg() const { return Op_RegI; } | |
230 virtual Node* Ideal(PhaseGVN *phase, bool can_reshape); | |
231 virtual int store_Opcode() const { return Op_StoreB; } | |
232 virtual BasicType memory_type() const { return T_BYTE; } | |
233 }; | |
234 | |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
420
diff
changeset
|
235 //------------------------------LoadUSNode------------------------------------- |
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
420
diff
changeset
|
236 // Load an unsigned short/char (16bits unsigned) from memory |
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
420
diff
changeset
|
237 class LoadUSNode : public LoadNode { |
0 | 238 public: |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
420
diff
changeset
|
239 LoadUSNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::CHAR ) |
0 | 240 : LoadNode(c,mem,adr,at,ti) {} |
241 virtual int Opcode() const; | |
242 virtual uint ideal_reg() const { return Op_RegI; } | |
243 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
244 virtual int store_Opcode() const { return Op_StoreC; } | |
245 virtual BasicType memory_type() const { return T_CHAR; } | |
246 }; | |
247 | |
248 //------------------------------LoadINode-------------------------------------- | |
249 // Load an integer from memory | |
250 class LoadINode : public LoadNode { | |
251 public: | |
252 LoadINode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::INT ) | |
253 : LoadNode(c,mem,adr,at,ti) {} | |
254 virtual int Opcode() const; | |
255 virtual uint ideal_reg() const { return Op_RegI; } | |
256 virtual int store_Opcode() const { return Op_StoreI; } | |
257 virtual BasicType memory_type() const { return T_INT; } | |
258 }; | |
259 | |
624 | 260 //------------------------------LoadUI2LNode----------------------------------- |
261 // Load an unsigned integer into long from memory | |
262 class LoadUI2LNode : public LoadNode { | |
263 public: | |
264 LoadUI2LNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeLong* t = TypeLong::UINT) | |
265 : LoadNode(c, mem, adr, at, t) {} | |
266 virtual int Opcode() const; | |
267 virtual uint ideal_reg() const { return Op_RegL; } | |
268 virtual int store_Opcode() const { return Op_StoreL; } | |
269 virtual BasicType memory_type() const { return T_LONG; } | |
270 }; | |
271 | |
0 | 272 //------------------------------LoadRangeNode---------------------------------- |
273 // Load an array length from the array | |
274 class LoadRangeNode : public LoadINode { | |
275 public: | |
276 LoadRangeNode( Node *c, Node *mem, Node *adr, const TypeInt *ti = TypeInt::POS ) | |
277 : LoadINode(c,mem,adr,TypeAryPtr::RANGE,ti) {} | |
278 virtual int Opcode() const; | |
279 virtual const Type *Value( PhaseTransform *phase ) const; | |
280 virtual Node *Identity( PhaseTransform *phase ); | |
366
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
253
diff
changeset
|
281 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
0 | 282 }; |
283 | |
284 //------------------------------LoadLNode-------------------------------------- | |
285 // Load a long from memory | |
286 class LoadLNode : public LoadNode { | |
287 virtual uint hash() const { return LoadNode::hash() + _require_atomic_access; } | |
288 virtual uint cmp( const Node &n ) const { | |
289 return _require_atomic_access == ((LoadLNode&)n)._require_atomic_access | |
290 && LoadNode::cmp(n); | |
291 } | |
292 virtual uint size_of() const { return sizeof(*this); } | |
293 const bool _require_atomic_access; // is piecewise load forbidden? | |
294 | |
295 public: | |
296 LoadLNode( Node *c, Node *mem, Node *adr, const TypePtr* at, | |
297 const TypeLong *tl = TypeLong::LONG, | |
298 bool require_atomic_access = false ) | |
299 : LoadNode(c,mem,adr,at,tl) | |
300 , _require_atomic_access(require_atomic_access) | |
301 {} | |
302 virtual int Opcode() const; | |
303 virtual uint ideal_reg() const { return Op_RegL; } | |
304 virtual int store_Opcode() const { return Op_StoreL; } | |
305 virtual BasicType memory_type() const { return T_LONG; } | |
306 bool require_atomic_access() { return _require_atomic_access; } | |
307 static LoadLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt); | |
308 #ifndef PRODUCT | |
309 virtual void dump_spec(outputStream *st) const { | |
310 LoadNode::dump_spec(st); | |
311 if (_require_atomic_access) st->print(" Atomic!"); | |
312 } | |
313 #endif | |
314 }; | |
315 | |
316 //------------------------------LoadL_unalignedNode---------------------------- | |
317 // Load a long from unaligned memory | |
318 class LoadL_unalignedNode : public LoadLNode { | |
319 public: | |
320 LoadL_unalignedNode( Node *c, Node *mem, Node *adr, const TypePtr* at ) | |
321 : LoadLNode(c,mem,adr,at) {} | |
322 virtual int Opcode() const; | |
323 }; | |
324 | |
325 //------------------------------LoadFNode-------------------------------------- | |
326 // Load a float (64 bits) from memory | |
327 class LoadFNode : public LoadNode { | |
328 public: | |
329 LoadFNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t = Type::FLOAT ) | |
330 : LoadNode(c,mem,adr,at,t) {} | |
331 virtual int Opcode() const; | |
332 virtual uint ideal_reg() const { return Op_RegF; } | |
333 virtual int store_Opcode() const { return Op_StoreF; } | |
334 virtual BasicType memory_type() const { return T_FLOAT; } | |
335 }; | |
336 | |
337 //------------------------------LoadDNode-------------------------------------- | |
338 // Load a double (64 bits) from memory | |
339 class LoadDNode : public LoadNode { | |
340 public: | |
341 LoadDNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t = Type::DOUBLE ) | |
342 : LoadNode(c,mem,adr,at,t) {} | |
343 virtual int Opcode() const; | |
344 virtual uint ideal_reg() const { return Op_RegD; } | |
345 virtual int store_Opcode() const { return Op_StoreD; } | |
346 virtual BasicType memory_type() const { return T_DOUBLE; } | |
347 }; | |
348 | |
349 //------------------------------LoadD_unalignedNode---------------------------- | |
350 // Load a double from unaligned memory | |
351 class LoadD_unalignedNode : public LoadDNode { | |
352 public: | |
353 LoadD_unalignedNode( Node *c, Node *mem, Node *adr, const TypePtr* at ) | |
354 : LoadDNode(c,mem,adr,at) {} | |
355 virtual int Opcode() const; | |
356 }; | |
357 | |
358 //------------------------------LoadPNode-------------------------------------- | |
359 // Load a pointer from memory (either object or array) | |
360 class LoadPNode : public LoadNode { | |
361 public: | |
362 LoadPNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const TypePtr* t ) | |
363 : LoadNode(c,mem,adr,at,t) {} | |
364 virtual int Opcode() const; | |
365 virtual uint ideal_reg() const { return Op_RegP; } | |
366 virtual int store_Opcode() const { return Op_StoreP; } | |
367 virtual BasicType memory_type() const { return T_ADDRESS; } | |
368 // depends_only_on_test is almost always true, and needs to be almost always | |
369 // true to enable key hoisting & commoning optimizations. However, for the | |
370 // special case of RawPtr loads from TLS top & end, the control edge carries | |
371 // the dependence preventing hoisting past a Safepoint instead of the memory | |
372 // edge. (An unfortunate consequence of having Safepoints not set Raw | |
373 // Memory; itself an unfortunate consequence of having Nodes which produce | |
374 // results (new raw memory state) inside of loops preventing all manner of | |
375 // other optimizations). Basically, it's ugly but so is the alternative. | |
376 // See comment in macro.cpp, around line 125 expand_allocate_common(). | |
377 virtual bool depends_only_on_test() const { return adr_type() != TypeRawPtr::BOTTOM; } | |
378 }; | |
379 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
380 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
381 //------------------------------LoadNNode-------------------------------------- |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
382 // Load a narrow oop from memory (either object or array) |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
383 class LoadNNode : public LoadNode { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
384 public: |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
385 LoadNNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const Type* t ) |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
386 : LoadNode(c,mem,adr,at,t) {} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
387 virtual int Opcode() const; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
388 virtual uint ideal_reg() const { return Op_RegN; } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
389 virtual int store_Opcode() const { return Op_StoreN; } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
390 virtual BasicType memory_type() const { return T_NARROWOOP; } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
391 // depends_only_on_test is almost always true, and needs to be almost always |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
392 // true to enable key hoisting & commoning optimizations. However, for the |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
393 // special case of RawPtr loads from TLS top & end, the control edge carries |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
394 // the dependence preventing hoisting past a Safepoint instead of the memory |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
395 // edge. (An unfortunate consequence of having Safepoints not set Raw |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
396 // Memory; itself an unfortunate consequence of having Nodes which produce |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
397 // results (new raw memory state) inside of loops preventing all manner of |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
398 // other optimizations). Basically, it's ugly but so is the alternative. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
399 // See comment in macro.cpp, around line 125 expand_allocate_common(). |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
400 virtual bool depends_only_on_test() const { return adr_type() != TypeRawPtr::BOTTOM; } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
401 }; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
402 |
0 | 403 //------------------------------LoadKlassNode---------------------------------- |
404 // Load a Klass from an object | |
405 class LoadKlassNode : public LoadPNode { | |
406 public: | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
407 LoadKlassNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeKlassPtr *tk ) |
0 | 408 : LoadPNode(c,mem,adr,at,tk) {} |
409 virtual int Opcode() const; | |
410 virtual const Type *Value( PhaseTransform *phase ) const; | |
411 virtual Node *Identity( PhaseTransform *phase ); | |
412 virtual bool depends_only_on_test() const { return true; } | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
413 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
414 // Polymorphic factory method: |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
415 static Node* make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* at, |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
416 const TypeKlassPtr *tk = TypeKlassPtr::OBJECT ); |
0 | 417 }; |
418 | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
419 //------------------------------LoadNKlassNode--------------------------------- |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
420 // Load a narrow Klass from an object. |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
421 class LoadNKlassNode : public LoadNNode { |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
422 public: |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
423 LoadNKlassNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeNarrowOop *tk ) |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
424 : LoadNNode(c,mem,adr,at,tk) {} |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
425 virtual int Opcode() const; |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
426 virtual uint ideal_reg() const { return Op_RegN; } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
427 virtual int store_Opcode() const { return Op_StoreN; } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
428 virtual BasicType memory_type() const { return T_NARROWOOP; } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
429 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
430 virtual const Type *Value( PhaseTransform *phase ) const; |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
431 virtual Node *Identity( PhaseTransform *phase ); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
432 virtual bool depends_only_on_test() const { return true; } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
433 }; |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
434 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
435 |
0 | 436 //------------------------------LoadSNode-------------------------------------- |
437 // Load a short (16bits signed) from memory | |
438 class LoadSNode : public LoadNode { | |
439 public: | |
440 LoadSNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::SHORT ) | |
441 : LoadNode(c,mem,adr,at,ti) {} | |
442 virtual int Opcode() const; | |
443 virtual uint ideal_reg() const { return Op_RegI; } | |
444 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
445 virtual int store_Opcode() const { return Op_StoreC; } | |
446 virtual BasicType memory_type() const { return T_SHORT; } | |
447 }; | |
448 | |
449 //------------------------------StoreNode-------------------------------------- | |
450 // Store value; requires Store, Address and Value | |
451 class StoreNode : public MemNode { | |
452 protected: | |
453 virtual uint cmp( const Node &n ) const; | |
454 virtual bool depends_only_on_test() const { return false; } | |
455 | |
456 Node *Ideal_masked_input (PhaseGVN *phase, uint mask); | |
457 Node *Ideal_sign_extended_input(PhaseGVN *phase, int num_bits); | |
458 | |
459 public: | |
460 StoreNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) | |
461 : MemNode(c,mem,adr,at,val) { | |
462 init_class_id(Class_Store); | |
463 } | |
464 StoreNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store ) | |
465 : MemNode(c,mem,adr,at,val,oop_store) { | |
466 init_class_id(Class_Store); | |
467 } | |
468 | |
469 // Polymorphic factory method: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
470 static StoreNode* make( PhaseGVN& gvn, Node *c, Node *mem, Node *adr, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
471 const TypePtr* at, Node *val, BasicType bt ); |
0 | 472 |
473 virtual uint hash() const; // Check the type | |
474 | |
475 // If the store is to Field memory and the pointer is non-null, we can | |
476 // zero out the control input. | |
477 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
478 | |
479 // Compute a new Type for this node. Basically we just do the pre-check, | |
480 // then call the virtual add() to set the type. | |
481 virtual const Type *Value( PhaseTransform *phase ) const; | |
482 | |
483 // Check for identity function on memory (Load then Store at same address) | |
484 virtual Node *Identity( PhaseTransform *phase ); | |
485 | |
486 // Do not match memory edge | |
487 virtual uint match_edge(uint idx) const; | |
488 | |
489 virtual const Type *bottom_type() const; // returns Type::MEMORY | |
490 | |
491 // Map a store opcode to its corresponding own opcode, trivially. | |
492 virtual int store_Opcode() const { return Opcode(); } | |
493 | |
494 // have all possible loads of the value stored been optimized away? | |
495 bool value_never_loaded(PhaseTransform *phase) const; | |
496 }; | |
497 | |
498 //------------------------------StoreBNode------------------------------------- | |
499 // Store byte to memory | |
500 class StoreBNode : public StoreNode { | |
501 public: | |
502 StoreBNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} | |
503 virtual int Opcode() const; | |
504 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
505 virtual BasicType memory_type() const { return T_BYTE; } | |
506 }; | |
507 | |
508 //------------------------------StoreCNode------------------------------------- | |
509 // Store char/short to memory | |
510 class StoreCNode : public StoreNode { | |
511 public: | |
512 StoreCNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} | |
513 virtual int Opcode() const; | |
514 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
515 virtual BasicType memory_type() const { return T_CHAR; } | |
516 }; | |
517 | |
518 //------------------------------StoreINode------------------------------------- | |
519 // Store int to memory | |
520 class StoreINode : public StoreNode { | |
521 public: | |
522 StoreINode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} | |
523 virtual int Opcode() const; | |
524 virtual BasicType memory_type() const { return T_INT; } | |
525 }; | |
526 | |
527 //------------------------------StoreLNode------------------------------------- | |
528 // Store long to memory | |
529 class StoreLNode : public StoreNode { | |
530 virtual uint hash() const { return StoreNode::hash() + _require_atomic_access; } | |
531 virtual uint cmp( const Node &n ) const { | |
532 return _require_atomic_access == ((StoreLNode&)n)._require_atomic_access | |
533 && StoreNode::cmp(n); | |
534 } | |
535 virtual uint size_of() const { return sizeof(*this); } | |
536 const bool _require_atomic_access; // is piecewise store forbidden? | |
537 | |
538 public: | |
539 StoreLNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, | |
540 bool require_atomic_access = false ) | |
541 : StoreNode(c,mem,adr,at,val) | |
542 , _require_atomic_access(require_atomic_access) | |
543 {} | |
544 virtual int Opcode() const; | |
545 virtual BasicType memory_type() const { return T_LONG; } | |
546 bool require_atomic_access() { return _require_atomic_access; } | |
547 static StoreLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val); | |
548 #ifndef PRODUCT | |
549 virtual void dump_spec(outputStream *st) const { | |
550 StoreNode::dump_spec(st); | |
551 if (_require_atomic_access) st->print(" Atomic!"); | |
552 } | |
553 #endif | |
554 }; | |
555 | |
556 //------------------------------StoreFNode------------------------------------- | |
557 // Store float to memory | |
558 class StoreFNode : public StoreNode { | |
559 public: | |
560 StoreFNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} | |
561 virtual int Opcode() const; | |
562 virtual BasicType memory_type() const { return T_FLOAT; } | |
563 }; | |
564 | |
565 //------------------------------StoreDNode------------------------------------- | |
566 // Store double to memory | |
567 class StoreDNode : public StoreNode { | |
568 public: | |
569 StoreDNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} | |
570 virtual int Opcode() const; | |
571 virtual BasicType memory_type() const { return T_DOUBLE; } | |
572 }; | |
573 | |
574 //------------------------------StorePNode------------------------------------- | |
575 // Store pointer to memory | |
576 class StorePNode : public StoreNode { | |
577 public: | |
578 StorePNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} | |
579 virtual int Opcode() const; | |
580 virtual BasicType memory_type() const { return T_ADDRESS; } | |
581 }; | |
582 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
583 //------------------------------StoreNNode------------------------------------- |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
584 // Store narrow oop to memory |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
585 class StoreNNode : public StoreNode { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
586 public: |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
587 StoreNNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
588 virtual int Opcode() const; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
589 virtual BasicType memory_type() const { return T_NARROWOOP; } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
590 }; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
591 |
0 | 592 //------------------------------StoreCMNode----------------------------------- |
593 // Store card-mark byte to memory for CM | |
594 // The last StoreCM before a SafePoint must be preserved and occur after its "oop" store | |
595 // Preceeding equivalent StoreCMs may be eliminated. | |
596 class StoreCMNode : public StoreNode { | |
985
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
681
diff
changeset
|
597 private: |
1198
8d9bfe6a446b
6920346: G1: "must avoid base_memory and AliasIdxTop"
never
parents:
1100
diff
changeset
|
598 virtual uint hash() const { return StoreNode::hash() + _oop_alias_idx; } |
8d9bfe6a446b
6920346: G1: "must avoid base_memory and AliasIdxTop"
never
parents:
1100
diff
changeset
|
599 virtual uint cmp( const Node &n ) const { |
8d9bfe6a446b
6920346: G1: "must avoid base_memory and AliasIdxTop"
never
parents:
1100
diff
changeset
|
600 return _oop_alias_idx == ((StoreCMNode&)n)._oop_alias_idx |
8d9bfe6a446b
6920346: G1: "must avoid base_memory and AliasIdxTop"
never
parents:
1100
diff
changeset
|
601 && StoreNode::cmp(n); |
8d9bfe6a446b
6920346: G1: "must avoid base_memory and AliasIdxTop"
never
parents:
1100
diff
changeset
|
602 } |
8d9bfe6a446b
6920346: G1: "must avoid base_memory and AliasIdxTop"
never
parents:
1100
diff
changeset
|
603 virtual uint size_of() const { return sizeof(*this); } |
985
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
681
diff
changeset
|
604 int _oop_alias_idx; // The alias_idx of OopStore |
1198
8d9bfe6a446b
6920346: G1: "must avoid base_memory and AliasIdxTop"
never
parents:
1100
diff
changeset
|
605 |
0 | 606 public: |
1198
8d9bfe6a446b
6920346: G1: "must avoid base_memory and AliasIdxTop"
never
parents:
1100
diff
changeset
|
607 StoreCMNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store, int oop_alias_idx ) : |
8d9bfe6a446b
6920346: G1: "must avoid base_memory and AliasIdxTop"
never
parents:
1100
diff
changeset
|
608 StoreNode(c,mem,adr,at,val,oop_store), |
8d9bfe6a446b
6920346: G1: "must avoid base_memory and AliasIdxTop"
never
parents:
1100
diff
changeset
|
609 _oop_alias_idx(oop_alias_idx) { |
8d9bfe6a446b
6920346: G1: "must avoid base_memory and AliasIdxTop"
never
parents:
1100
diff
changeset
|
610 assert(_oop_alias_idx >= Compile::AliasIdxRaw || |
8d9bfe6a446b
6920346: G1: "must avoid base_memory and AliasIdxTop"
never
parents:
1100
diff
changeset
|
611 _oop_alias_idx == Compile::AliasIdxBot && Compile::current()->AliasLevel() == 0, |
8d9bfe6a446b
6920346: G1: "must avoid base_memory and AliasIdxTop"
never
parents:
1100
diff
changeset
|
612 "bad oop alias idx"); |
8d9bfe6a446b
6920346: G1: "must avoid base_memory and AliasIdxTop"
never
parents:
1100
diff
changeset
|
613 } |
0 | 614 virtual int Opcode() const; |
615 virtual Node *Identity( PhaseTransform *phase ); | |
985
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
681
diff
changeset
|
616 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); |
0 | 617 virtual const Type *Value( PhaseTransform *phase ) const; |
618 virtual BasicType memory_type() const { return T_VOID; } // unspecific | |
985
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
681
diff
changeset
|
619 int oop_alias_idx() const { return _oop_alias_idx; } |
0 | 620 }; |
621 | |
622 //------------------------------LoadPLockedNode--------------------------------- | |
623 // Load-locked a pointer from memory (either object or array). | |
624 // On Sparc & Intel this is implemented as a normal pointer load. | |
625 // On PowerPC and friends it's a real load-locked. | |
626 class LoadPLockedNode : public LoadPNode { | |
627 public: | |
628 LoadPLockedNode( Node *c, Node *mem, Node *adr ) | |
629 : LoadPNode(c,mem,adr,TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM) {} | |
630 virtual int Opcode() const; | |
631 virtual int store_Opcode() const { return Op_StorePConditional; } | |
632 virtual bool depends_only_on_test() const { return true; } | |
633 }; | |
634 | |
635 //------------------------------LoadLLockedNode--------------------------------- | |
636 // Load-locked a pointer from memory (either object or array). | |
637 // On Sparc & Intel this is implemented as a normal long load. | |
638 class LoadLLockedNode : public LoadLNode { | |
639 public: | |
640 LoadLLockedNode( Node *c, Node *mem, Node *adr ) | |
641 : LoadLNode(c,mem,adr,TypeRawPtr::BOTTOM, TypeLong::LONG) {} | |
642 virtual int Opcode() const; | |
643 virtual int store_Opcode() const { return Op_StoreLConditional; } | |
644 }; | |
645 | |
646 //------------------------------SCMemProjNode--------------------------------------- | |
647 // This class defines a projection of the memory state of a store conditional node. | |
648 // These nodes return a value, but also update memory. | |
649 class SCMemProjNode : public ProjNode { | |
650 public: | |
651 enum {SCMEMPROJCON = (uint)-2}; | |
652 SCMemProjNode( Node *src) : ProjNode( src, SCMEMPROJCON) { } | |
653 virtual int Opcode() const; | |
654 virtual bool is_CFG() const { return false; } | |
655 virtual const Type *bottom_type() const {return Type::MEMORY;} | |
656 virtual const TypePtr *adr_type() const { return in(0)->in(MemNode::Memory)->adr_type();} | |
657 virtual uint ideal_reg() const { return 0;} // memory projections don't have a register | |
658 virtual const Type *Value( PhaseTransform *phase ) const; | |
659 #ifndef PRODUCT | |
660 virtual void dump_spec(outputStream *st) const {}; | |
661 #endif | |
662 }; | |
663 | |
664 //------------------------------LoadStoreNode--------------------------- | |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
196
diff
changeset
|
665 // Note: is_Mem() method returns 'true' for this class. |
0 | 666 class LoadStoreNode : public Node { |
667 public: | |
668 enum { | |
669 ExpectedIn = MemNode::ValueIn+1 // One more input than MemNode | |
670 }; | |
671 LoadStoreNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex); | |
672 virtual bool depends_only_on_test() const { return false; } | |
673 virtual const Type *bottom_type() const { return TypeInt::BOOL; } | |
674 virtual uint ideal_reg() const { return Op_RegI; } | |
675 virtual uint match_edge(uint idx) const { return idx == MemNode::Address || idx == MemNode::ValueIn; } | |
676 }; | |
677 | |
678 //------------------------------StorePConditionalNode--------------------------- | |
679 // Conditionally store pointer to memory, if no change since prior | |
680 // load-locked. Sets flags for success or failure of the store. | |
681 class StorePConditionalNode : public LoadStoreNode { | |
682 public: | |
683 StorePConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ll ) : LoadStoreNode(c, mem, adr, val, ll) { } | |
684 virtual int Opcode() const; | |
685 // Produces flags | |
686 virtual uint ideal_reg() const { return Op_RegFlags; } | |
687 }; | |
688 | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
689 //------------------------------StoreIConditionalNode--------------------------- |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
690 // Conditionally store int to memory, if no change since prior |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
691 // load-locked. Sets flags for success or failure of the store. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
692 class StoreIConditionalNode : public LoadStoreNode { |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
693 public: |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
694 StoreIConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ii ) : LoadStoreNode(c, mem, adr, val, ii) { } |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
695 virtual int Opcode() const; |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
696 // Produces flags |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
697 virtual uint ideal_reg() const { return Op_RegFlags; } |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
698 }; |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
699 |
0 | 700 //------------------------------StoreLConditionalNode--------------------------- |
701 // Conditionally store long to memory, if no change since prior | |
702 // load-locked. Sets flags for success or failure of the store. | |
703 class StoreLConditionalNode : public LoadStoreNode { | |
704 public: | |
705 StoreLConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ll ) : LoadStoreNode(c, mem, adr, val, ll) { } | |
706 virtual int Opcode() const; | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
707 // Produces flags |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
708 virtual uint ideal_reg() const { return Op_RegFlags; } |
0 | 709 }; |
710 | |
711 | |
712 //------------------------------CompareAndSwapLNode--------------------------- | |
713 class CompareAndSwapLNode : public LoadStoreNode { | |
714 public: | |
715 CompareAndSwapLNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreNode(c, mem, adr, val, ex) { } | |
716 virtual int Opcode() const; | |
717 }; | |
718 | |
719 | |
720 //------------------------------CompareAndSwapINode--------------------------- | |
721 class CompareAndSwapINode : public LoadStoreNode { | |
722 public: | |
723 CompareAndSwapINode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreNode(c, mem, adr, val, ex) { } | |
724 virtual int Opcode() const; | |
725 }; | |
726 | |
727 | |
728 //------------------------------CompareAndSwapPNode--------------------------- | |
729 class CompareAndSwapPNode : public LoadStoreNode { | |
730 public: | |
731 CompareAndSwapPNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreNode(c, mem, adr, val, ex) { } | |
732 virtual int Opcode() const; | |
733 }; | |
734 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
735 //------------------------------CompareAndSwapNNode--------------------------- |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
736 class CompareAndSwapNNode : public LoadStoreNode { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
737 public: |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
738 CompareAndSwapNNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreNode(c, mem, adr, val, ex) { } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
739 virtual int Opcode() const; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
740 }; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
74
diff
changeset
|
741 |
0 | 742 //------------------------------ClearArray------------------------------------- |
743 class ClearArrayNode: public Node { | |
744 public: | |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
986
diff
changeset
|
745 ClearArrayNode( Node *ctrl, Node *arymem, Node *word_cnt, Node *base ) |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
986
diff
changeset
|
746 : Node(ctrl,arymem,word_cnt,base) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
986
diff
changeset
|
747 init_class_id(Class_ClearArray); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
986
diff
changeset
|
748 } |
0 | 749 virtual int Opcode() const; |
750 virtual const Type *bottom_type() const { return Type::MEMORY; } | |
751 // ClearArray modifies array elements, and so affects only the | |
752 // array memory addressed by the bottom_type of its base address. | |
753 virtual const class TypePtr *adr_type() const; | |
754 virtual Node *Identity( PhaseTransform *phase ); | |
755 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
756 virtual uint match_edge(uint idx) const; | |
757 | |
758 // Clear the given area of an object or array. | |
759 // The start offset must always be aligned mod BytesPerInt. | |
760 // The end offset must always be aligned mod BytesPerLong. | |
761 // Return the new memory. | |
762 static Node* clear_memory(Node* control, Node* mem, Node* dest, | |
763 intptr_t start_offset, | |
764 intptr_t end_offset, | |
765 PhaseGVN* phase); | |
766 static Node* clear_memory(Node* control, Node* mem, Node* dest, | |
767 intptr_t start_offset, | |
768 Node* end_offset, | |
769 PhaseGVN* phase); | |
770 static Node* clear_memory(Node* control, Node* mem, Node* dest, | |
771 Node* start_offset, | |
772 Node* end_offset, | |
773 PhaseGVN* phase); | |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
986
diff
changeset
|
774 // Return allocation input memory edge if it is different instance |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
986
diff
changeset
|
775 // or itself if it is the one we are looking for. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
986
diff
changeset
|
776 static bool step_through(Node** np, uint instance_id, PhaseTransform* phase); |
0 | 777 }; |
778 | |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
779 //------------------------------StrIntrinsic------------------------------- |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
780 // Base class for Ideal nodes used in String instrinsic code. |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
781 class StrIntrinsicNode: public Node { |
0 | 782 public: |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
783 StrIntrinsicNode(Node* control, Node* char_array_mem, |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
784 Node* s1, Node* c1, Node* s2, Node* c2): |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
785 Node(control, char_array_mem, s1, c1, s2, c2) { |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
786 } |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
787 |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
788 StrIntrinsicNode(Node* control, Node* char_array_mem, |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
789 Node* s1, Node* s2, Node* c): |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
790 Node(control, char_array_mem, s1, s2, c) { |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
791 } |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
792 |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
793 StrIntrinsicNode(Node* control, Node* char_array_mem, |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
794 Node* s1, Node* s2): |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
795 Node(control, char_array_mem, s1, s2) { |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
796 } |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
797 |
0 | 798 virtual bool depends_only_on_test() const { return false; } |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
985
diff
changeset
|
799 virtual const TypePtr* adr_type() const { return TypeAryPtr::CHARS; } |
0 | 800 virtual uint match_edge(uint idx) const; |
801 virtual uint ideal_reg() const { return Op_RegI; } | |
802 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
4115 | 803 virtual const Type *Value(PhaseTransform *phase) const; |
0 | 804 }; |
805 | |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
806 //------------------------------StrComp------------------------------------- |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
807 class StrCompNode: public StrIntrinsicNode { |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
808 public: |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
809 StrCompNode(Node* control, Node* char_array_mem, |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
810 Node* s1, Node* c1, Node* s2, Node* c2): |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
811 StrIntrinsicNode(control, char_array_mem, s1, c1, s2, c2) {}; |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
812 virtual int Opcode() const; |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
813 virtual const Type* bottom_type() const { return TypeInt::INT; } |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
814 }; |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
815 |
681 | 816 //------------------------------StrEquals------------------------------------- |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
817 class StrEqualsNode: public StrIntrinsicNode { |
681 | 818 public: |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
985
diff
changeset
|
819 StrEqualsNode(Node* control, Node* char_array_mem, |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
820 Node* s1, Node* s2, Node* c): |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
821 StrIntrinsicNode(control, char_array_mem, s1, s2, c) {}; |
681 | 822 virtual int Opcode() const; |
823 virtual const Type* bottom_type() const { return TypeInt::BOOL; } | |
824 }; | |
825 | |
826 //------------------------------StrIndexOf------------------------------------- | |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
827 class StrIndexOfNode: public StrIntrinsicNode { |
681 | 828 public: |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
985
diff
changeset
|
829 StrIndexOfNode(Node* control, Node* char_array_mem, |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
830 Node* s1, Node* c1, Node* s2, Node* c2): |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
831 StrIntrinsicNode(control, char_array_mem, s1, c1, s2, c2) {}; |
681 | 832 virtual int Opcode() const; |
833 virtual const Type* bottom_type() const { return TypeInt::INT; } | |
834 }; | |
835 | |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
836 //------------------------------AryEq--------------------------------------- |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
837 class AryEqNode: public StrIntrinsicNode { |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
838 public: |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
839 AryEqNode(Node* control, Node* char_array_mem, Node* s1, Node* s2): |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
840 StrIntrinsicNode(control, char_array_mem, s1, s2) {}; |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
841 virtual int Opcode() const; |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
842 virtual const Type* bottom_type() const { return TypeInt::BOOL; } |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
843 }; |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
844 |
0 | 845 //------------------------------MemBar----------------------------------------- |
846 // There are different flavors of Memory Barriers to match the Java Memory | |
847 // Model. Monitor-enter and volatile-load act as Aquires: no following ref | |
848 // can be moved to before them. We insert a MemBar-Acquire after a FastLock or | |
849 // volatile-load. Monitor-exit and volatile-store act as Release: no | |
605 | 850 // preceding ref can be moved to after them. We insert a MemBar-Release |
0 | 851 // before a FastUnlock or volatile-store. All volatiles need to be |
852 // serialized, so we follow all volatile-stores with a MemBar-Volatile to | |
605 | 853 // separate it from any following volatile-load. |
0 | 854 class MemBarNode: public MultiNode { |
855 virtual uint hash() const ; // { return NO_HASH; } | |
856 virtual uint cmp( const Node &n ) const ; // Always fail, except on self | |
857 | |
858 virtual uint size_of() const { return sizeof(*this); } | |
859 // Memory type this node is serializing. Usually either rawptr or bottom. | |
860 const TypePtr* _adr_type; | |
861 | |
862 public: | |
863 enum { | |
864 Precedent = TypeFunc::Parms // optional edge to force precedence | |
865 }; | |
866 MemBarNode(Compile* C, int alias_idx, Node* precedent); | |
867 virtual int Opcode() const = 0; | |
868 virtual const class TypePtr *adr_type() const { return _adr_type; } | |
869 virtual const Type *Value( PhaseTransform *phase ) const; | |
870 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
871 virtual uint match_edge(uint idx) const { return 0; } | |
872 virtual const Type *bottom_type() const { return TypeTuple::MEMBAR; } | |
873 virtual Node *match( const ProjNode *proj, const Matcher *m ); | |
874 // Factory method. Builds a wide or narrow membar. | |
875 // Optional 'precedent' becomes an extra edge if not null. | |
876 static MemBarNode* make(Compile* C, int opcode, | |
877 int alias_idx = Compile::AliasIdxBot, | |
878 Node* precedent = NULL); | |
879 }; | |
880 | |
881 // "Acquire" - no following ref can move before (but earlier refs can | |
882 // follow, like an early Load stalled in cache). Requires multi-cpu | |
3849
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
883 // visibility. Inserted after a volatile load. |
0 | 884 class MemBarAcquireNode: public MemBarNode { |
885 public: | |
886 MemBarAcquireNode(Compile* C, int alias_idx, Node* precedent) | |
887 : MemBarNode(C, alias_idx, precedent) {} | |
888 virtual int Opcode() const; | |
889 }; | |
890 | |
891 // "Release" - no earlier ref can move after (but later refs can move | |
892 // up, like a speculative pipelined cache-hitting Load). Requires | |
3849
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
893 // multi-cpu visibility. Inserted before a volatile store. |
0 | 894 class MemBarReleaseNode: public MemBarNode { |
895 public: | |
896 MemBarReleaseNode(Compile* C, int alias_idx, Node* precedent) | |
897 : MemBarNode(C, alias_idx, precedent) {} | |
898 virtual int Opcode() const; | |
899 }; | |
900 | |
3849
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
901 // "Acquire" - no following ref can move before (but earlier refs can |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
902 // follow, like an early Load stalled in cache). Requires multi-cpu |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
903 // visibility. Inserted after a FastLock. |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
904 class MemBarAcquireLockNode: public MemBarNode { |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
905 public: |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
906 MemBarAcquireLockNode(Compile* C, int alias_idx, Node* precedent) |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
907 : MemBarNode(C, alias_idx, precedent) {} |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
908 virtual int Opcode() const; |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
909 }; |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
910 |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
911 // "Release" - no earlier ref can move after (but later refs can move |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
912 // up, like a speculative pipelined cache-hitting Load). Requires |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
913 // multi-cpu visibility. Inserted before a FastUnLock. |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
914 class MemBarReleaseLockNode: public MemBarNode { |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
915 public: |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
916 MemBarReleaseLockNode(Compile* C, int alias_idx, Node* precedent) |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
917 : MemBarNode(C, alias_idx, precedent) {} |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
918 virtual int Opcode() const; |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
919 }; |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
920 |
0 | 921 // Ordering between a volatile store and a following volatile load. |
922 // Requires multi-CPU visibility? | |
923 class MemBarVolatileNode: public MemBarNode { | |
924 public: | |
925 MemBarVolatileNode(Compile* C, int alias_idx, Node* precedent) | |
926 : MemBarNode(C, alias_idx, precedent) {} | |
927 virtual int Opcode() const; | |
928 }; | |
929 | |
930 // Ordering within the same CPU. Used to order unsafe memory references | |
931 // inside the compiler when we lack alias info. Not needed "outside" the | |
932 // compiler because the CPU does all the ordering for us. | |
933 class MemBarCPUOrderNode: public MemBarNode { | |
934 public: | |
935 MemBarCPUOrderNode(Compile* C, int alias_idx, Node* precedent) | |
936 : MemBarNode(C, alias_idx, precedent) {} | |
937 virtual int Opcode() const; | |
938 virtual uint ideal_reg() const { return 0; } // not matched in the AD file | |
939 }; | |
940 | |
941 // Isolation of object setup after an AllocateNode and before next safepoint. | |
942 // (See comment in memnode.cpp near InitializeNode::InitializeNode for semantics.) | |
943 class InitializeNode: public MemBarNode { | |
944 friend class AllocateNode; | |
945 | |
3961
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
946 enum { |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
947 Incomplete = 0, |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
948 Complete = 1, |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
949 WithArraycopy = 2 |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
950 }; |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
951 int _is_complete; |
0 | 952 |
953 public: | |
954 enum { | |
955 Control = TypeFunc::Control, | |
956 Memory = TypeFunc::Memory, // MergeMem for states affected by this op | |
957 RawAddress = TypeFunc::Parms+0, // the newly-allocated raw address | |
958 RawStores = TypeFunc::Parms+1 // zero or more stores (or TOP) | |
959 }; | |
960 | |
961 InitializeNode(Compile* C, int adr_type, Node* rawoop); | |
962 virtual int Opcode() const; | |
963 virtual uint size_of() const { return sizeof(*this); } | |
964 virtual uint ideal_reg() const { return 0; } // not matched in the AD file | |
965 virtual const RegMask &in_RegMask(uint) const; // mask for RawAddress | |
966 | |
967 // Manage incoming memory edges via a MergeMem on in(Memory): | |
968 Node* memory(uint alias_idx); | |
969 | |
970 // The raw memory edge coming directly from the Allocation. | |
971 // The contents of this memory are *always* all-zero-bits. | |
972 Node* zero_memory() { return memory(Compile::AliasIdxRaw); } | |
973 | |
974 // Return the corresponding allocation for this initialization (or null if none). | |
975 // (Note: Both InitializeNode::allocation and AllocateNode::initialization | |
976 // are defined in graphKit.cpp, which sets up the bidirectional relation.) | |
977 AllocateNode* allocation(); | |
978 | |
979 // Anything other than zeroing in this init? | |
980 bool is_non_zero(); | |
981 | |
982 // An InitializeNode must completed before macro expansion is done. | |
983 // Completion requires that the AllocateNode must be followed by | |
984 // initialization of the new memory to zero, then to any initializers. | |
3961
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
985 bool is_complete() { return _is_complete != Incomplete; } |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
986 bool is_complete_with_arraycopy() { return (_is_complete & WithArraycopy) != 0; } |
0 | 987 |
988 // Mark complete. (Must not yet be complete.) | |
989 void set_complete(PhaseGVN* phase); | |
3961
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
990 void set_complete_with_arraycopy() { _is_complete = Complete | WithArraycopy; } |
0 | 991 |
992 #ifdef ASSERT | |
993 // ensure all non-degenerate stores are ordered and non-overlapping | |
994 bool stores_are_sane(PhaseTransform* phase); | |
995 #endif //ASSERT | |
996 | |
997 // See if this store can be captured; return offset where it initializes. | |
998 // Return 0 if the store cannot be moved (any sort of problem). | |
999 intptr_t can_capture_store(StoreNode* st, PhaseTransform* phase); | |
1000 | |
1001 // Capture another store; reformat it to write my internal raw memory. | |
1002 // Return the captured copy, else NULL if there is some sort of problem. | |
1003 Node* capture_store(StoreNode* st, intptr_t start, PhaseTransform* phase); | |
1004 | |
1005 // Find captured store which corresponds to the range [start..start+size). | |
1006 // Return my own memory projection (meaning the initial zero bits) | |
1007 // if there is no such store. Return NULL if there is a problem. | |
1008 Node* find_captured_store(intptr_t start, int size_in_bytes, PhaseTransform* phase); | |
1009 | |
1010 // Called when the associated AllocateNode is expanded into CFG. | |
1011 Node* complete_stores(Node* rawctl, Node* rawmem, Node* rawptr, | |
1012 intptr_t header_size, Node* size_in_bytes, | |
1013 PhaseGVN* phase); | |
1014 | |
1015 private: | |
1016 void remove_extra_zeroes(); | |
1017 | |
1018 // Find out where a captured store should be placed (or already is placed). | |
1019 int captured_store_insertion_point(intptr_t start, int size_in_bytes, | |
1020 PhaseTransform* phase); | |
1021 | |
1022 static intptr_t get_store_offset(Node* st, PhaseTransform* phase); | |
1023 | |
1024 Node* make_raw_address(intptr_t offset, PhaseTransform* phase); | |
1025 | |
1026 bool detect_init_independence(Node* n, bool st_is_pinned, int& count); | |
1027 | |
1028 void coalesce_subword_stores(intptr_t header_size, Node* size_in_bytes, | |
1029 PhaseGVN* phase); | |
1030 | |
1031 intptr_t find_next_fullword_store(uint i, PhaseGVN* phase); | |
1032 }; | |
1033 | |
1034 //------------------------------MergeMem--------------------------------------- | |
1035 // (See comment in memnode.cpp near MergeMemNode::MergeMemNode for semantics.) | |
1036 class MergeMemNode: public Node { | |
1037 virtual uint hash() const ; // { return NO_HASH; } | |
1038 virtual uint cmp( const Node &n ) const ; // Always fail, except on self | |
1039 friend class MergeMemStream; | |
1040 MergeMemNode(Node* def); // clients use MergeMemNode::make | |
1041 | |
1042 public: | |
1043 // If the input is a whole memory state, clone it with all its slices intact. | |
1044 // Otherwise, make a new memory state with just that base memory input. | |
1045 // In either case, the result is a newly created MergeMem. | |
1046 static MergeMemNode* make(Compile* C, Node* base_memory); | |
1047 | |
1048 virtual int Opcode() const; | |
1049 virtual Node *Identity( PhaseTransform *phase ); | |
1050 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
1051 virtual uint ideal_reg() const { return NotAMachineReg; } | |
1052 virtual uint match_edge(uint idx) const { return 0; } | |
1053 virtual const RegMask &out_RegMask() const; | |
1054 virtual const Type *bottom_type() const { return Type::MEMORY; } | |
1055 virtual const TypePtr *adr_type() const { return TypePtr::BOTTOM; } | |
1056 // sparse accessors | |
1057 // Fetch the previously stored "set_memory_at", or else the base memory. | |
1058 // (Caller should clone it if it is a phi-nest.) | |
1059 Node* memory_at(uint alias_idx) const; | |
1060 // set the memory, regardless of its previous value | |
1061 void set_memory_at(uint alias_idx, Node* n); | |
1062 // the "base" is the memory that provides the non-finite support | |
1063 Node* base_memory() const { return in(Compile::AliasIdxBot); } | |
1064 // warning: setting the base can implicitly set any of the other slices too | |
1065 void set_base_memory(Node* def); | |
1066 // sentinel value which denotes a copy of the base memory: | |
1067 Node* empty_memory() const { return in(Compile::AliasIdxTop); } | |
1068 static Node* make_empty_memory(); // where the sentinel comes from | |
1069 bool is_empty_memory(Node* n) const { assert((n == empty_memory()) == n->is_top(), "sanity"); return n->is_top(); } | |
1070 // hook for the iterator, to perform any necessary setup | |
1071 void iteration_setup(const MergeMemNode* other = NULL); | |
1072 // push sentinels until I am at least as long as the other (semantic no-op) | |
1073 void grow_to_match(const MergeMemNode* other); | |
1074 bool verify_sparse() const PRODUCT_RETURN0; | |
1075 #ifndef PRODUCT | |
1076 virtual void dump_spec(outputStream *st) const; | |
1077 #endif | |
1078 }; | |
1079 | |
1080 class MergeMemStream : public StackObj { | |
1081 private: | |
1082 MergeMemNode* _mm; | |
1083 const MergeMemNode* _mm2; // optional second guy, contributes non-empty iterations | |
1084 Node* _mm_base; // loop-invariant base memory of _mm | |
1085 int _idx; | |
1086 int _cnt; | |
1087 Node* _mem; | |
1088 Node* _mem2; | |
1089 int _cnt2; | |
1090 | |
1091 void init(MergeMemNode* mm, const MergeMemNode* mm2 = NULL) { | |
1092 // subsume_node will break sparseness at times, whenever a memory slice | |
1093 // folds down to a copy of the base ("fat") memory. In such a case, | |
1094 // the raw edge will update to base, although it should be top. | |
1095 // This iterator will recognize either top or base_memory as an | |
1096 // "empty" slice. See is_empty, is_empty2, and next below. | |
1097 // | |
1098 // The sparseness property is repaired in MergeMemNode::Ideal. | |
1099 // As long as access to a MergeMem goes through this iterator | |
1100 // or the memory_at accessor, flaws in the sparseness will | |
1101 // never be observed. | |
1102 // | |
1103 // Also, iteration_setup repairs sparseness. | |
1104 assert(mm->verify_sparse(), "please, no dups of base"); | |
1105 assert(mm2==NULL || mm2->verify_sparse(), "please, no dups of base"); | |
1106 | |
1107 _mm = mm; | |
1108 _mm_base = mm->base_memory(); | |
1109 _mm2 = mm2; | |
1110 _cnt = mm->req(); | |
1111 _idx = Compile::AliasIdxBot-1; // start at the base memory | |
1112 _mem = NULL; | |
1113 _mem2 = NULL; | |
1114 } | |
1115 | |
1116 #ifdef ASSERT | |
1117 Node* check_memory() const { | |
1118 if (at_base_memory()) | |
1119 return _mm->base_memory(); | |
1120 else if ((uint)_idx < _mm->req() && !_mm->in(_idx)->is_top()) | |
1121 return _mm->memory_at(_idx); | |
1122 else | |
1123 return _mm_base; | |
1124 } | |
1125 Node* check_memory2() const { | |
1126 return at_base_memory()? _mm2->base_memory(): _mm2->memory_at(_idx); | |
1127 } | |
1128 #endif | |
1129 | |
1130 static bool match_memory(Node* mem, const MergeMemNode* mm, int idx) PRODUCT_RETURN0; | |
1131 void assert_synch() const { | |
1132 assert(!_mem || _idx >= _cnt || match_memory(_mem, _mm, _idx), | |
1133 "no side-effects except through the stream"); | |
1134 } | |
1135 | |
1136 public: | |
1137 | |
1138 // expected usages: | |
1139 // for (MergeMemStream mms(mem->is_MergeMem()); next_non_empty(); ) { ... } | |
1140 // for (MergeMemStream mms(mem1, mem2); next_non_empty2(); ) { ... } | |
1141 | |
1142 // iterate over one merge | |
1143 MergeMemStream(MergeMemNode* mm) { | |
1144 mm->iteration_setup(); | |
1145 init(mm); | |
1146 debug_only(_cnt2 = 999); | |
1147 } | |
1148 // iterate in parallel over two merges | |
1149 // only iterates through non-empty elements of mm2 | |
1150 MergeMemStream(MergeMemNode* mm, const MergeMemNode* mm2) { | |
1151 assert(mm2, "second argument must be a MergeMem also"); | |
1152 ((MergeMemNode*)mm2)->iteration_setup(); // update hidden state | |
1153 mm->iteration_setup(mm2); | |
1154 init(mm, mm2); | |
1155 _cnt2 = mm2->req(); | |
1156 } | |
1157 #ifdef ASSERT | |
1158 ~MergeMemStream() { | |
1159 assert_synch(); | |
1160 } | |
1161 #endif | |
1162 | |
1163 MergeMemNode* all_memory() const { | |
1164 return _mm; | |
1165 } | |
1166 Node* base_memory() const { | |
1167 assert(_mm_base == _mm->base_memory(), "no update to base memory, please"); | |
1168 return _mm_base; | |
1169 } | |
1170 const MergeMemNode* all_memory2() const { | |
1171 assert(_mm2 != NULL, ""); | |
1172 return _mm2; | |
1173 } | |
1174 bool at_base_memory() const { | |
1175 return _idx == Compile::AliasIdxBot; | |
1176 } | |
1177 int alias_idx() const { | |
1178 assert(_mem, "must call next 1st"); | |
1179 return _idx; | |
1180 } | |
1181 | |
1182 const TypePtr* adr_type() const { | |
1183 return Compile::current()->get_adr_type(alias_idx()); | |
1184 } | |
1185 | |
1186 const TypePtr* adr_type(Compile* C) const { | |
1187 return C->get_adr_type(alias_idx()); | |
1188 } | |
1189 bool is_empty() const { | |
1190 assert(_mem, "must call next 1st"); | |
1191 assert(_mem->is_top() == (_mem==_mm->empty_memory()), "correct sentinel"); | |
1192 return _mem->is_top(); | |
1193 } | |
1194 bool is_empty2() const { | |
1195 assert(_mem2, "must call next 1st"); | |
1196 assert(_mem2->is_top() == (_mem2==_mm2->empty_memory()), "correct sentinel"); | |
1197 return _mem2->is_top(); | |
1198 } | |
1199 Node* memory() const { | |
1200 assert(!is_empty(), "must not be empty"); | |
1201 assert_synch(); | |
1202 return _mem; | |
1203 } | |
1204 // get the current memory, regardless of empty or non-empty status | |
1205 Node* force_memory() const { | |
1206 assert(!is_empty() || !at_base_memory(), ""); | |
1207 // Use _mm_base to defend against updates to _mem->base_memory(). | |
1208 Node *mem = _mem->is_top() ? _mm_base : _mem; | |
1209 assert(mem == check_memory(), ""); | |
1210 return mem; | |
1211 } | |
1212 Node* memory2() const { | |
1213 assert(_mem2 == check_memory2(), ""); | |
1214 return _mem2; | |
1215 } | |
1216 void set_memory(Node* mem) { | |
1217 if (at_base_memory()) { | |
1218 // Note that this does not change the invariant _mm_base. | |
1219 _mm->set_base_memory(mem); | |
1220 } else { | |
1221 _mm->set_memory_at(_idx, mem); | |
1222 } | |
1223 _mem = mem; | |
1224 assert_synch(); | |
1225 } | |
1226 | |
1227 // Recover from a side effect to the MergeMemNode. | |
1228 void set_memory() { | |
1229 _mem = _mm->in(_idx); | |
1230 } | |
1231 | |
1232 bool next() { return next(false); } | |
1233 bool next2() { return next(true); } | |
1234 | |
1235 bool next_non_empty() { return next_non_empty(false); } | |
1236 bool next_non_empty2() { return next_non_empty(true); } | |
1237 // next_non_empty2 can yield states where is_empty() is true | |
1238 | |
1239 private: | |
1240 // find the next item, which might be empty | |
1241 bool next(bool have_mm2) { | |
1242 assert((_mm2 != NULL) == have_mm2, "use other next"); | |
1243 assert_synch(); | |
1244 if (++_idx < _cnt) { | |
1245 // Note: This iterator allows _mm to be non-sparse. | |
1246 // It behaves the same whether _mem is top or base_memory. | |
1247 _mem = _mm->in(_idx); | |
1248 if (have_mm2) | |
1249 _mem2 = _mm2->in((_idx < _cnt2) ? _idx : Compile::AliasIdxTop); | |
1250 return true; | |
1251 } | |
1252 return false; | |
1253 } | |
1254 | |
1255 // find the next non-empty item | |
1256 bool next_non_empty(bool have_mm2) { | |
1257 while (next(have_mm2)) { | |
1258 if (!is_empty()) { | |
1259 // make sure _mem2 is filled in sensibly | |
1260 if (have_mm2 && _mem2->is_top()) _mem2 = _mm2->base_memory(); | |
1261 return true; | |
1262 } else if (have_mm2 && !is_empty2()) { | |
1263 return true; // is_empty() == true | |
1264 } | |
1265 } | |
1266 return false; | |
1267 } | |
1268 }; | |
1269 | |
1270 //------------------------------Prefetch--------------------------------------- | |
1271 | |
1272 // Non-faulting prefetch load. Prefetch for many reads. | |
1273 class PrefetchReadNode : public Node { | |
1274 public: | |
1275 PrefetchReadNode(Node *abio, Node *adr) : Node(0,abio,adr) {} | |
1276 virtual int Opcode() const; | |
1277 virtual uint ideal_reg() const { return NotAMachineReg; } | |
1278 virtual uint match_edge(uint idx) const { return idx==2; } | |
1279 virtual const Type *bottom_type() const { return Type::ABIO; } | |
1280 }; | |
1281 | |
1282 // Non-faulting prefetch load. Prefetch for many reads & many writes. | |
1283 class PrefetchWriteNode : public Node { | |
1284 public: | |
1285 PrefetchWriteNode(Node *abio, Node *adr) : Node(0,abio,adr) {} | |
1286 virtual int Opcode() const; | |
1287 virtual uint ideal_reg() const { return NotAMachineReg; } | |
1288 virtual uint match_edge(uint idx) const { return idx==2; } | |
3854 | 1289 virtual const Type *bottom_type() const { return Type::ABIO; } |
1290 }; | |
1291 | |
1292 // Allocation prefetch which may fault, TLAB size have to be adjusted. | |
1293 class PrefetchAllocationNode : public Node { | |
1294 public: | |
1295 PrefetchAllocationNode(Node *mem, Node *adr) : Node(0,mem,adr) {} | |
1296 virtual int Opcode() const; | |
1297 virtual uint ideal_reg() const { return NotAMachineReg; } | |
1298 virtual uint match_edge(uint idx) const { return idx==2; } | |
1367
9e321dcfa5b7
6940726: Use BIS instruction for allocation prefetch on Sparc
kvn
parents:
1198
diff
changeset
|
1299 virtual const Type *bottom_type() const { return ( AllocatePrefetchStyle == 3 ) ? Type::MEMORY : Type::ABIO; } |
0 | 1300 }; |
1972 | 1301 |
1302 #endif // SHARE_VM_OPTO_MEMNODE_HPP |