Mercurial > hg > graal-compiler
annotate src/share/vm/opto/memnode.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 | a92cdbac8b9e |
children | 1bd45abaa507 |
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); | |
803 }; | |
804 | |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
805 //------------------------------StrComp------------------------------------- |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
806 class StrCompNode: public StrIntrinsicNode { |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
807 public: |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
808 StrCompNode(Node* control, Node* char_array_mem, |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
809 Node* s1, Node* c1, Node* s2, Node* c2): |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
810 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
|
811 virtual int Opcode() const; |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
812 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
|
813 }; |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
814 |
681 | 815 //------------------------------StrEquals------------------------------------- |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
816 class StrEqualsNode: public StrIntrinsicNode { |
681 | 817 public: |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
985
diff
changeset
|
818 StrEqualsNode(Node* control, Node* char_array_mem, |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
819 Node* s1, Node* s2, Node* c): |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
820 StrIntrinsicNode(control, char_array_mem, s1, s2, c) {}; |
681 | 821 virtual int Opcode() const; |
822 virtual const Type* bottom_type() const { return TypeInt::BOOL; } | |
823 }; | |
824 | |
825 //------------------------------StrIndexOf------------------------------------- | |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
826 class StrIndexOfNode: public StrIntrinsicNode { |
681 | 827 public: |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
985
diff
changeset
|
828 StrIndexOfNode(Node* control, Node* char_array_mem, |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
829 Node* s1, Node* c1, Node* s2, Node* c2): |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
830 StrIntrinsicNode(control, char_array_mem, s1, c1, s2, c2) {}; |
681 | 831 virtual int Opcode() const; |
832 virtual const Type* bottom_type() const { return TypeInt::INT; } | |
833 }; | |
834 | |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
835 //------------------------------AryEq--------------------------------------- |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
836 class AryEqNode: public StrIntrinsicNode { |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
837 public: |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
1972
diff
changeset
|
838 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
|
839 StrIntrinsicNode(control, char_array_mem, s1, s2) {}; |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
840 virtual int Opcode() const; |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
841 virtual const Type* bottom_type() const { return TypeInt::BOOL; } |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
842 }; |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
164
diff
changeset
|
843 |
0 | 844 //------------------------------MemBar----------------------------------------- |
845 // There are different flavors of Memory Barriers to match the Java Memory | |
846 // Model. Monitor-enter and volatile-load act as Aquires: no following ref | |
847 // can be moved to before them. We insert a MemBar-Acquire after a FastLock or | |
848 // volatile-load. Monitor-exit and volatile-store act as Release: no | |
605 | 849 // preceding ref can be moved to after them. We insert a MemBar-Release |
0 | 850 // before a FastUnlock or volatile-store. All volatiles need to be |
851 // serialized, so we follow all volatile-stores with a MemBar-Volatile to | |
605 | 852 // separate it from any following volatile-load. |
0 | 853 class MemBarNode: public MultiNode { |
854 virtual uint hash() const ; // { return NO_HASH; } | |
855 virtual uint cmp( const Node &n ) const ; // Always fail, except on self | |
856 | |
857 virtual uint size_of() const { return sizeof(*this); } | |
858 // Memory type this node is serializing. Usually either rawptr or bottom. | |
859 const TypePtr* _adr_type; | |
860 | |
861 public: | |
862 enum { | |
863 Precedent = TypeFunc::Parms // optional edge to force precedence | |
864 }; | |
865 MemBarNode(Compile* C, int alias_idx, Node* precedent); | |
866 virtual int Opcode() const = 0; | |
867 virtual const class TypePtr *adr_type() const { return _adr_type; } | |
868 virtual const Type *Value( PhaseTransform *phase ) const; | |
869 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
870 virtual uint match_edge(uint idx) const { return 0; } | |
871 virtual const Type *bottom_type() const { return TypeTuple::MEMBAR; } | |
872 virtual Node *match( const ProjNode *proj, const Matcher *m ); | |
873 // Factory method. Builds a wide or narrow membar. | |
874 // Optional 'precedent' becomes an extra edge if not null. | |
875 static MemBarNode* make(Compile* C, int opcode, | |
876 int alias_idx = Compile::AliasIdxBot, | |
877 Node* precedent = NULL); | |
878 }; | |
879 | |
880 // "Acquire" - no following ref can move before (but earlier refs can | |
881 // 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
|
882 // visibility. Inserted after a volatile load. |
0 | 883 class MemBarAcquireNode: public MemBarNode { |
884 public: | |
885 MemBarAcquireNode(Compile* C, int alias_idx, Node* precedent) | |
886 : MemBarNode(C, alias_idx, precedent) {} | |
887 virtual int Opcode() const; | |
888 }; | |
889 | |
890 // "Release" - no earlier ref can move after (but later refs can move | |
891 // 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
|
892 // multi-cpu visibility. Inserted before a volatile store. |
0 | 893 class MemBarReleaseNode: public MemBarNode { |
894 public: | |
895 MemBarReleaseNode(Compile* C, int alias_idx, Node* precedent) | |
896 : MemBarNode(C, alias_idx, precedent) {} | |
897 virtual int Opcode() const; | |
898 }; | |
899 | |
3849
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
900 // "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
|
901 // 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
|
902 // visibility. Inserted after a FastLock. |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
903 class MemBarAcquireLockNode: public MemBarNode { |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
904 public: |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
905 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
|
906 : MemBarNode(C, alias_idx, precedent) {} |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
907 virtual int Opcode() const; |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
908 }; |
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 // "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
|
911 // 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
|
912 // multi-cpu visibility. Inserted before a FastUnLock. |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
913 class MemBarReleaseLockNode: public MemBarNode { |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
914 public: |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
915 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
|
916 : MemBarNode(C, alias_idx, precedent) {} |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
917 virtual int Opcode() const; |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
918 }; |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
2426
diff
changeset
|
919 |
0 | 920 // Ordering between a volatile store and a following volatile load. |
921 // Requires multi-CPU visibility? | |
922 class MemBarVolatileNode: public MemBarNode { | |
923 public: | |
924 MemBarVolatileNode(Compile* C, int alias_idx, Node* precedent) | |
925 : MemBarNode(C, alias_idx, precedent) {} | |
926 virtual int Opcode() const; | |
927 }; | |
928 | |
929 // Ordering within the same CPU. Used to order unsafe memory references | |
930 // inside the compiler when we lack alias info. Not needed "outside" the | |
931 // compiler because the CPU does all the ordering for us. | |
932 class MemBarCPUOrderNode: public MemBarNode { | |
933 public: | |
934 MemBarCPUOrderNode(Compile* C, int alias_idx, Node* precedent) | |
935 : MemBarNode(C, alias_idx, precedent) {} | |
936 virtual int Opcode() const; | |
937 virtual uint ideal_reg() const { return 0; } // not matched in the AD file | |
938 }; | |
939 | |
940 // Isolation of object setup after an AllocateNode and before next safepoint. | |
941 // (See comment in memnode.cpp near InitializeNode::InitializeNode for semantics.) | |
942 class InitializeNode: public MemBarNode { | |
943 friend class AllocateNode; | |
944 | |
3961
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
945 enum { |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
946 Incomplete = 0, |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
947 Complete = 1, |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
948 WithArraycopy = 2 |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
949 }; |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
950 int _is_complete; |
0 | 951 |
952 public: | |
953 enum { | |
954 Control = TypeFunc::Control, | |
955 Memory = TypeFunc::Memory, // MergeMem for states affected by this op | |
956 RawAddress = TypeFunc::Parms+0, // the newly-allocated raw address | |
957 RawStores = TypeFunc::Parms+1 // zero or more stores (or TOP) | |
958 }; | |
959 | |
960 InitializeNode(Compile* C, int adr_type, Node* rawoop); | |
961 virtual int Opcode() const; | |
962 virtual uint size_of() const { return sizeof(*this); } | |
963 virtual uint ideal_reg() const { return 0; } // not matched in the AD file | |
964 virtual const RegMask &in_RegMask(uint) const; // mask for RawAddress | |
965 | |
966 // Manage incoming memory edges via a MergeMem on in(Memory): | |
967 Node* memory(uint alias_idx); | |
968 | |
969 // The raw memory edge coming directly from the Allocation. | |
970 // The contents of this memory are *always* all-zero-bits. | |
971 Node* zero_memory() { return memory(Compile::AliasIdxRaw); } | |
972 | |
973 // Return the corresponding allocation for this initialization (or null if none). | |
974 // (Note: Both InitializeNode::allocation and AllocateNode::initialization | |
975 // are defined in graphKit.cpp, which sets up the bidirectional relation.) | |
976 AllocateNode* allocation(); | |
977 | |
978 // Anything other than zeroing in this init? | |
979 bool is_non_zero(); | |
980 | |
981 // An InitializeNode must completed before macro expansion is done. | |
982 // Completion requires that the AllocateNode must be followed by | |
983 // 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
|
984 bool is_complete() { return _is_complete != Incomplete; } |
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
985 bool is_complete_with_arraycopy() { return (_is_complete & WithArraycopy) != 0; } |
0 | 986 |
987 // Mark complete. (Must not yet be complete.) | |
988 void set_complete(PhaseGVN* phase); | |
3961
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3854
diff
changeset
|
989 void set_complete_with_arraycopy() { _is_complete = Complete | WithArraycopy; } |
0 | 990 |
991 #ifdef ASSERT | |
992 // ensure all non-degenerate stores are ordered and non-overlapping | |
993 bool stores_are_sane(PhaseTransform* phase); | |
994 #endif //ASSERT | |
995 | |
996 // See if this store can be captured; return offset where it initializes. | |
997 // Return 0 if the store cannot be moved (any sort of problem). | |
998 intptr_t can_capture_store(StoreNode* st, PhaseTransform* phase); | |
999 | |
1000 // Capture another store; reformat it to write my internal raw memory. | |
1001 // Return the captured copy, else NULL if there is some sort of problem. | |
1002 Node* capture_store(StoreNode* st, intptr_t start, PhaseTransform* phase); | |
1003 | |
1004 // Find captured store which corresponds to the range [start..start+size). | |
1005 // Return my own memory projection (meaning the initial zero bits) | |
1006 // if there is no such store. Return NULL if there is a problem. | |
1007 Node* find_captured_store(intptr_t start, int size_in_bytes, PhaseTransform* phase); | |
1008 | |
1009 // Called when the associated AllocateNode is expanded into CFG. | |
1010 Node* complete_stores(Node* rawctl, Node* rawmem, Node* rawptr, | |
1011 intptr_t header_size, Node* size_in_bytes, | |
1012 PhaseGVN* phase); | |
1013 | |
1014 private: | |
1015 void remove_extra_zeroes(); | |
1016 | |
1017 // Find out where a captured store should be placed (or already is placed). | |
1018 int captured_store_insertion_point(intptr_t start, int size_in_bytes, | |
1019 PhaseTransform* phase); | |
1020 | |
1021 static intptr_t get_store_offset(Node* st, PhaseTransform* phase); | |
1022 | |
1023 Node* make_raw_address(intptr_t offset, PhaseTransform* phase); | |
1024 | |
1025 bool detect_init_independence(Node* n, bool st_is_pinned, int& count); | |
1026 | |
1027 void coalesce_subword_stores(intptr_t header_size, Node* size_in_bytes, | |
1028 PhaseGVN* phase); | |
1029 | |
1030 intptr_t find_next_fullword_store(uint i, PhaseGVN* phase); | |
1031 }; | |
1032 | |
1033 //------------------------------MergeMem--------------------------------------- | |
1034 // (See comment in memnode.cpp near MergeMemNode::MergeMemNode for semantics.) | |
1035 class MergeMemNode: public Node { | |
1036 virtual uint hash() const ; // { return NO_HASH; } | |
1037 virtual uint cmp( const Node &n ) const ; // Always fail, except on self | |
1038 friend class MergeMemStream; | |
1039 MergeMemNode(Node* def); // clients use MergeMemNode::make | |
1040 | |
1041 public: | |
1042 // If the input is a whole memory state, clone it with all its slices intact. | |
1043 // Otherwise, make a new memory state with just that base memory input. | |
1044 // In either case, the result is a newly created MergeMem. | |
1045 static MergeMemNode* make(Compile* C, Node* base_memory); | |
1046 | |
1047 virtual int Opcode() const; | |
1048 virtual Node *Identity( PhaseTransform *phase ); | |
1049 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); | |
1050 virtual uint ideal_reg() const { return NotAMachineReg; } | |
1051 virtual uint match_edge(uint idx) const { return 0; } | |
1052 virtual const RegMask &out_RegMask() const; | |
1053 virtual const Type *bottom_type() const { return Type::MEMORY; } | |
1054 virtual const TypePtr *adr_type() const { return TypePtr::BOTTOM; } | |
1055 // sparse accessors | |
1056 // Fetch the previously stored "set_memory_at", or else the base memory. | |
1057 // (Caller should clone it if it is a phi-nest.) | |
1058 Node* memory_at(uint alias_idx) const; | |
1059 // set the memory, regardless of its previous value | |
1060 void set_memory_at(uint alias_idx, Node* n); | |
1061 // the "base" is the memory that provides the non-finite support | |
1062 Node* base_memory() const { return in(Compile::AliasIdxBot); } | |
1063 // warning: setting the base can implicitly set any of the other slices too | |
1064 void set_base_memory(Node* def); | |
1065 // sentinel value which denotes a copy of the base memory: | |
1066 Node* empty_memory() const { return in(Compile::AliasIdxTop); } | |
1067 static Node* make_empty_memory(); // where the sentinel comes from | |
1068 bool is_empty_memory(Node* n) const { assert((n == empty_memory()) == n->is_top(), "sanity"); return n->is_top(); } | |
1069 // hook for the iterator, to perform any necessary setup | |
1070 void iteration_setup(const MergeMemNode* other = NULL); | |
1071 // push sentinels until I am at least as long as the other (semantic no-op) | |
1072 void grow_to_match(const MergeMemNode* other); | |
1073 bool verify_sparse() const PRODUCT_RETURN0; | |
1074 #ifndef PRODUCT | |
1075 virtual void dump_spec(outputStream *st) const; | |
1076 #endif | |
1077 }; | |
1078 | |
1079 class MergeMemStream : public StackObj { | |
1080 private: | |
1081 MergeMemNode* _mm; | |
1082 const MergeMemNode* _mm2; // optional second guy, contributes non-empty iterations | |
1083 Node* _mm_base; // loop-invariant base memory of _mm | |
1084 int _idx; | |
1085 int _cnt; | |
1086 Node* _mem; | |
1087 Node* _mem2; | |
1088 int _cnt2; | |
1089 | |
1090 void init(MergeMemNode* mm, const MergeMemNode* mm2 = NULL) { | |
1091 // subsume_node will break sparseness at times, whenever a memory slice | |
1092 // folds down to a copy of the base ("fat") memory. In such a case, | |
1093 // the raw edge will update to base, although it should be top. | |
1094 // This iterator will recognize either top or base_memory as an | |
1095 // "empty" slice. See is_empty, is_empty2, and next below. | |
1096 // | |
1097 // The sparseness property is repaired in MergeMemNode::Ideal. | |
1098 // As long as access to a MergeMem goes through this iterator | |
1099 // or the memory_at accessor, flaws in the sparseness will | |
1100 // never be observed. | |
1101 // | |
1102 // Also, iteration_setup repairs sparseness. | |
1103 assert(mm->verify_sparse(), "please, no dups of base"); | |
1104 assert(mm2==NULL || mm2->verify_sparse(), "please, no dups of base"); | |
1105 | |
1106 _mm = mm; | |
1107 _mm_base = mm->base_memory(); | |
1108 _mm2 = mm2; | |
1109 _cnt = mm->req(); | |
1110 _idx = Compile::AliasIdxBot-1; // start at the base memory | |
1111 _mem = NULL; | |
1112 _mem2 = NULL; | |
1113 } | |
1114 | |
1115 #ifdef ASSERT | |
1116 Node* check_memory() const { | |
1117 if (at_base_memory()) | |
1118 return _mm->base_memory(); | |
1119 else if ((uint)_idx < _mm->req() && !_mm->in(_idx)->is_top()) | |
1120 return _mm->memory_at(_idx); | |
1121 else | |
1122 return _mm_base; | |
1123 } | |
1124 Node* check_memory2() const { | |
1125 return at_base_memory()? _mm2->base_memory(): _mm2->memory_at(_idx); | |
1126 } | |
1127 #endif | |
1128 | |
1129 static bool match_memory(Node* mem, const MergeMemNode* mm, int idx) PRODUCT_RETURN0; | |
1130 void assert_synch() const { | |
1131 assert(!_mem || _idx >= _cnt || match_memory(_mem, _mm, _idx), | |
1132 "no side-effects except through the stream"); | |
1133 } | |
1134 | |
1135 public: | |
1136 | |
1137 // expected usages: | |
1138 // for (MergeMemStream mms(mem->is_MergeMem()); next_non_empty(); ) { ... } | |
1139 // for (MergeMemStream mms(mem1, mem2); next_non_empty2(); ) { ... } | |
1140 | |
1141 // iterate over one merge | |
1142 MergeMemStream(MergeMemNode* mm) { | |
1143 mm->iteration_setup(); | |
1144 init(mm); | |
1145 debug_only(_cnt2 = 999); | |
1146 } | |
1147 // iterate in parallel over two merges | |
1148 // only iterates through non-empty elements of mm2 | |
1149 MergeMemStream(MergeMemNode* mm, const MergeMemNode* mm2) { | |
1150 assert(mm2, "second argument must be a MergeMem also"); | |
1151 ((MergeMemNode*)mm2)->iteration_setup(); // update hidden state | |
1152 mm->iteration_setup(mm2); | |
1153 init(mm, mm2); | |
1154 _cnt2 = mm2->req(); | |
1155 } | |
1156 #ifdef ASSERT | |
1157 ~MergeMemStream() { | |
1158 assert_synch(); | |
1159 } | |
1160 #endif | |
1161 | |
1162 MergeMemNode* all_memory() const { | |
1163 return _mm; | |
1164 } | |
1165 Node* base_memory() const { | |
1166 assert(_mm_base == _mm->base_memory(), "no update to base memory, please"); | |
1167 return _mm_base; | |
1168 } | |
1169 const MergeMemNode* all_memory2() const { | |
1170 assert(_mm2 != NULL, ""); | |
1171 return _mm2; | |
1172 } | |
1173 bool at_base_memory() const { | |
1174 return _idx == Compile::AliasIdxBot; | |
1175 } | |
1176 int alias_idx() const { | |
1177 assert(_mem, "must call next 1st"); | |
1178 return _idx; | |
1179 } | |
1180 | |
1181 const TypePtr* adr_type() const { | |
1182 return Compile::current()->get_adr_type(alias_idx()); | |
1183 } | |
1184 | |
1185 const TypePtr* adr_type(Compile* C) const { | |
1186 return C->get_adr_type(alias_idx()); | |
1187 } | |
1188 bool is_empty() const { | |
1189 assert(_mem, "must call next 1st"); | |
1190 assert(_mem->is_top() == (_mem==_mm->empty_memory()), "correct sentinel"); | |
1191 return _mem->is_top(); | |
1192 } | |
1193 bool is_empty2() const { | |
1194 assert(_mem2, "must call next 1st"); | |
1195 assert(_mem2->is_top() == (_mem2==_mm2->empty_memory()), "correct sentinel"); | |
1196 return _mem2->is_top(); | |
1197 } | |
1198 Node* memory() const { | |
1199 assert(!is_empty(), "must not be empty"); | |
1200 assert_synch(); | |
1201 return _mem; | |
1202 } | |
1203 // get the current memory, regardless of empty or non-empty status | |
1204 Node* force_memory() const { | |
1205 assert(!is_empty() || !at_base_memory(), ""); | |
1206 // Use _mm_base to defend against updates to _mem->base_memory(). | |
1207 Node *mem = _mem->is_top() ? _mm_base : _mem; | |
1208 assert(mem == check_memory(), ""); | |
1209 return mem; | |
1210 } | |
1211 Node* memory2() const { | |
1212 assert(_mem2 == check_memory2(), ""); | |
1213 return _mem2; | |
1214 } | |
1215 void set_memory(Node* mem) { | |
1216 if (at_base_memory()) { | |
1217 // Note that this does not change the invariant _mm_base. | |
1218 _mm->set_base_memory(mem); | |
1219 } else { | |
1220 _mm->set_memory_at(_idx, mem); | |
1221 } | |
1222 _mem = mem; | |
1223 assert_synch(); | |
1224 } | |
1225 | |
1226 // Recover from a side effect to the MergeMemNode. | |
1227 void set_memory() { | |
1228 _mem = _mm->in(_idx); | |
1229 } | |
1230 | |
1231 bool next() { return next(false); } | |
1232 bool next2() { return next(true); } | |
1233 | |
1234 bool next_non_empty() { return next_non_empty(false); } | |
1235 bool next_non_empty2() { return next_non_empty(true); } | |
1236 // next_non_empty2 can yield states where is_empty() is true | |
1237 | |
1238 private: | |
1239 // find the next item, which might be empty | |
1240 bool next(bool have_mm2) { | |
1241 assert((_mm2 != NULL) == have_mm2, "use other next"); | |
1242 assert_synch(); | |
1243 if (++_idx < _cnt) { | |
1244 // Note: This iterator allows _mm to be non-sparse. | |
1245 // It behaves the same whether _mem is top or base_memory. | |
1246 _mem = _mm->in(_idx); | |
1247 if (have_mm2) | |
1248 _mem2 = _mm2->in((_idx < _cnt2) ? _idx : Compile::AliasIdxTop); | |
1249 return true; | |
1250 } | |
1251 return false; | |
1252 } | |
1253 | |
1254 // find the next non-empty item | |
1255 bool next_non_empty(bool have_mm2) { | |
1256 while (next(have_mm2)) { | |
1257 if (!is_empty()) { | |
1258 // make sure _mem2 is filled in sensibly | |
1259 if (have_mm2 && _mem2->is_top()) _mem2 = _mm2->base_memory(); | |
1260 return true; | |
1261 } else if (have_mm2 && !is_empty2()) { | |
1262 return true; // is_empty() == true | |
1263 } | |
1264 } | |
1265 return false; | |
1266 } | |
1267 }; | |
1268 | |
1269 //------------------------------Prefetch--------------------------------------- | |
1270 | |
1271 // Non-faulting prefetch load. Prefetch for many reads. | |
1272 class PrefetchReadNode : public Node { | |
1273 public: | |
1274 PrefetchReadNode(Node *abio, Node *adr) : Node(0,abio,adr) {} | |
1275 virtual int Opcode() const; | |
1276 virtual uint ideal_reg() const { return NotAMachineReg; } | |
1277 virtual uint match_edge(uint idx) const { return idx==2; } | |
1278 virtual const Type *bottom_type() const { return Type::ABIO; } | |
1279 }; | |
1280 | |
1281 // Non-faulting prefetch load. Prefetch for many reads & many writes. | |
1282 class PrefetchWriteNode : public Node { | |
1283 public: | |
1284 PrefetchWriteNode(Node *abio, Node *adr) : Node(0,abio,adr) {} | |
1285 virtual int Opcode() const; | |
1286 virtual uint ideal_reg() const { return NotAMachineReg; } | |
1287 virtual uint match_edge(uint idx) const { return idx==2; } | |
3854 | 1288 virtual const Type *bottom_type() const { return Type::ABIO; } |
1289 }; | |
1290 | |
1291 // Allocation prefetch which may fault, TLAB size have to be adjusted. | |
1292 class PrefetchAllocationNode : public Node { | |
1293 public: | |
1294 PrefetchAllocationNode(Node *mem, Node *adr) : Node(0,mem,adr) {} | |
1295 virtual int Opcode() const; | |
1296 virtual uint ideal_reg() const { return NotAMachineReg; } | |
1297 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
|
1298 virtual const Type *bottom_type() const { return ( AllocatePrefetchStyle == 3 ) ? Type::MEMORY : Type::ABIO; } |
0 | 1299 }; |
1972 | 1300 |
1301 #endif // SHARE_VM_OPTO_MEMNODE_HPP |