1 /*
2  * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
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  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  *
23  */
24 
25 #include "precompiled.hpp"
26 #include "gc/shared/c2/barrierSetC2.hpp"
27 #include "opto/arraycopynode.hpp"
28 #include "opto/convertnode.hpp"
29 #include "opto/graphKit.hpp"
30 #include "opto/idealKit.hpp"
31 #include "opto/macro.hpp"
32 #include "opto/narrowptrnode.hpp"
33 #include "opto/runtime.hpp"
34 #include "utilities/macros.hpp"
35 
36 // By default this is a no-op.
resolve_address(C2Access & access) const37 void BarrierSetC2::resolve_address(C2Access& access) const { }
38 
barrier_set_state() const39 void* C2ParseAccess::barrier_set_state() const {
40   return _kit->barrier_set_state();
41 }
42 
gvn() const43 PhaseGVN& C2ParseAccess::gvn() const { return _kit->gvn(); }
44 
needs_cpu_membar() const45 bool C2Access::needs_cpu_membar() const {
46   bool mismatched   = (_decorators & C2_MISMATCHED) != 0;
47   bool is_unordered = (_decorators & MO_UNORDERED) != 0;
48 
49   bool anonymous = (_decorators & C2_UNSAFE_ACCESS) != 0;
50   bool in_heap   = (_decorators & IN_HEAP) != 0;
51   bool in_native = (_decorators & IN_NATIVE) != 0;
52   bool is_mixed  = !in_heap && !in_native;
53 
54   bool is_write  = (_decorators & C2_WRITE_ACCESS) != 0;
55   bool is_read   = (_decorators & C2_READ_ACCESS) != 0;
56   bool is_atomic = is_read && is_write;
57 
58   if (is_atomic) {
59     // Atomics always need to be wrapped in CPU membars
60     return true;
61   }
62 
63   if (anonymous) {
64     // We will need memory barriers unless we can determine a unique
65     // alias category for this reference.  (Note:  If for some reason
66     // the barriers get omitted and the unsafe reference begins to "pollute"
67     // the alias analysis of the rest of the graph, either Compile::can_alias
68     // or Compile::must_alias will throw a diagnostic assert.)
69     if (is_mixed || !is_unordered || (mismatched && !_addr.type()->isa_aryptr())) {
70       return true;
71     }
72   } else {
73     assert(!is_mixed, "not unsafe");
74   }
75 
76   return false;
77 }
78 
store_at_resolved(C2Access & access,C2AccessValue & val) const79 Node* BarrierSetC2::store_at_resolved(C2Access& access, C2AccessValue& val) const {
80   DecoratorSet decorators = access.decorators();
81 
82   bool mismatched = (decorators & C2_MISMATCHED) != 0;
83   bool unaligned = (decorators & C2_UNALIGNED) != 0;
84   bool unsafe = (decorators & C2_UNSAFE_ACCESS) != 0;
85   bool requires_atomic_access = (decorators & MO_UNORDERED) == 0;
86 
87   bool in_native = (decorators & IN_NATIVE) != 0;
88   assert(!in_native || (unsafe && !access.is_oop()), "not supported yet");
89 
90   MemNode::MemOrd mo = access.mem_node_mo();
91 
92   Node* store;
93   if (access.is_parse_access()) {
94     C2ParseAccess& parse_access = static_cast<C2ParseAccess&>(access);
95 
96     GraphKit* kit = parse_access.kit();
97     if (access.type() == T_DOUBLE) {
98       Node* new_val = kit->dstore_rounding(val.node());
99       val.set_node(new_val);
100     }
101 
102     store = kit->store_to_memory(kit->control(), access.addr().node(), val.node(), access.type(),
103                                      access.addr().type(), mo, requires_atomic_access, unaligned, mismatched, unsafe);
104   } else {
105     assert(!requires_atomic_access, "not yet supported");
106     assert(access.is_opt_access(), "either parse or opt access");
107     C2OptAccess& opt_access = static_cast<C2OptAccess&>(access);
108     Node* ctl = opt_access.ctl();
109     MergeMemNode* mm = opt_access.mem();
110     PhaseGVN& gvn = opt_access.gvn();
111     const TypePtr* adr_type = access.addr().type();
112     int alias = gvn.C->get_alias_index(adr_type);
113     Node* mem = mm->memory_at(alias);
114 
115     StoreNode* st = StoreNode::make(gvn, ctl, mem, access.addr().node(), adr_type, val.node(), access.type(), mo);
116     if (unaligned) {
117       st->set_unaligned_access();
118     }
119     if (mismatched) {
120       st->set_mismatched_access();
121     }
122     store = gvn.transform(st);
123     if (store == st) {
124       mm->set_memory_at(alias, st);
125     }
126   }
127   access.set_raw_access(store);
128 
129   return store;
130 }
131 
load_at_resolved(C2Access & access,const Type * val_type) const132 Node* BarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) const {
133   DecoratorSet decorators = access.decorators();
134 
135   Node* adr = access.addr().node();
136   const TypePtr* adr_type = access.addr().type();
137 
138   bool mismatched = (decorators & C2_MISMATCHED) != 0;
139   bool requires_atomic_access = (decorators & MO_UNORDERED) == 0;
140   bool unaligned = (decorators & C2_UNALIGNED) != 0;
141   bool control_dependent = (decorators & C2_CONTROL_DEPENDENT_LOAD) != 0;
142   bool unknown_control = (decorators & C2_UNKNOWN_CONTROL_LOAD) != 0;
143   bool unsafe = (decorators & C2_UNSAFE_ACCESS) != 0;
144   bool immutable = (decorators & C2_IMMUTABLE_MEMORY) != 0;
145 
146   bool in_native = (decorators & IN_NATIVE) != 0;
147 
148   MemNode::MemOrd mo = access.mem_node_mo();
149   LoadNode::ControlDependency dep = unknown_control ? LoadNode::UnknownControl : LoadNode::DependsOnlyOnTest;
150 
151   Node* load;
152   if (access.is_parse_access()) {
153     C2ParseAccess& parse_access = static_cast<C2ParseAccess&>(access);
154     GraphKit* kit = parse_access.kit();
155     Node* control = control_dependent ? kit->control() : NULL;
156 
157     if (immutable) {
158       assert(!requires_atomic_access, "can't ensure atomicity");
159       Compile* C = Compile::current();
160       Node* mem = kit->immutable_memory();
161       load = LoadNode::make(kit->gvn(), control, mem, adr,
162                             adr_type, val_type, access.type(), mo, dep, unaligned,
163                             mismatched, unsafe, access.barrier_data());
164       load = kit->gvn().transform(load);
165     } else {
166       load = kit->make_load(control, adr, val_type, access.type(), adr_type, mo,
167                             dep, requires_atomic_access, unaligned, mismatched, unsafe,
168                             access.barrier_data());
169     }
170   } else {
171     assert(!requires_atomic_access, "not yet supported");
172     assert(access.is_opt_access(), "either parse or opt access");
173     C2OptAccess& opt_access = static_cast<C2OptAccess&>(access);
174     Node* control = control_dependent ? opt_access.ctl() : NULL;
175     MergeMemNode* mm = opt_access.mem();
176     PhaseGVN& gvn = opt_access.gvn();
177     Node* mem = mm->memory_at(gvn.C->get_alias_index(adr_type));
178     load = LoadNode::make(gvn, control, mem, adr, adr_type, val_type, access.type(), mo,
179                           dep, unaligned, mismatched, unsafe, access.barrier_data());
180     load = gvn.transform(load);
181   }
182   access.set_raw_access(load);
183 
184   return load;
185 }
186 
187 class C2AccessFence: public StackObj {
188   C2Access& _access;
189   Node* _leading_membar;
190 
191 public:
C2AccessFence(C2Access & access)192   C2AccessFence(C2Access& access) :
193     _access(access), _leading_membar(NULL) {
194     GraphKit* kit = NULL;
195     if (access.is_parse_access()) {
196       C2ParseAccess& parse_access = static_cast<C2ParseAccess&>(access);
197       kit = parse_access.kit();
198     }
199     DecoratorSet decorators = access.decorators();
200 
201     bool is_write = (decorators & C2_WRITE_ACCESS) != 0;
202     bool is_read = (decorators & C2_READ_ACCESS) != 0;
203     bool is_atomic = is_read && is_write;
204 
205     bool is_volatile = (decorators & MO_SEQ_CST) != 0;
206     bool is_release = (decorators & MO_RELEASE) != 0;
207 
208     if (is_atomic) {
209       assert(kit != NULL, "unsupported at optimization time");
210       // Memory-model-wise, a LoadStore acts like a little synchronized
211       // block, so needs barriers on each side.  These don't translate
212       // into actual barriers on most machines, but we still need rest of
213       // compiler to respect ordering.
214       if (is_release) {
215         _leading_membar = kit->insert_mem_bar(Op_MemBarRelease);
216       } else if (is_volatile) {
217         if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
218           _leading_membar = kit->insert_mem_bar(Op_MemBarVolatile);
219         } else {
220           _leading_membar = kit->insert_mem_bar(Op_MemBarRelease);
221         }
222       }
223     } else if (is_write) {
224       // If reference is volatile, prevent following memory ops from
225       // floating down past the volatile write.  Also prevents commoning
226       // another volatile read.
227       if (is_volatile || is_release) {
228         assert(kit != NULL, "unsupported at optimization time");
229         _leading_membar = kit->insert_mem_bar(Op_MemBarRelease);
230       }
231     } else {
232       // Memory barrier to prevent normal and 'unsafe' accesses from
233       // bypassing each other.  Happens after null checks, so the
234       // exception paths do not take memory state from the memory barrier,
235       // so there's no problems making a strong assert about mixing users
236       // of safe & unsafe memory.
237       if (is_volatile && support_IRIW_for_not_multiple_copy_atomic_cpu) {
238         assert(kit != NULL, "unsupported at optimization time");
239         _leading_membar = kit->insert_mem_bar(Op_MemBarVolatile);
240       }
241     }
242 
243     if (access.needs_cpu_membar()) {
244       assert(kit != NULL, "unsupported at optimization time");
245       kit->insert_mem_bar(Op_MemBarCPUOrder);
246     }
247 
248     if (is_atomic) {
249       // 4984716: MemBars must be inserted before this
250       //          memory node in order to avoid a false
251       //          dependency which will confuse the scheduler.
252       access.set_memory();
253     }
254   }
255 
~C2AccessFence()256   ~C2AccessFence() {
257     GraphKit* kit = NULL;
258     if (_access.is_parse_access()) {
259       C2ParseAccess& parse_access = static_cast<C2ParseAccess&>(_access);
260       kit = parse_access.kit();
261     }
262     DecoratorSet decorators = _access.decorators();
263 
264     bool is_write = (decorators & C2_WRITE_ACCESS) != 0;
265     bool is_read = (decorators & C2_READ_ACCESS) != 0;
266     bool is_atomic = is_read && is_write;
267 
268     bool is_volatile = (decorators & MO_SEQ_CST) != 0;
269     bool is_acquire = (decorators & MO_ACQUIRE) != 0;
270 
271     // If reference is volatile, prevent following volatiles ops from
272     // floating up before the volatile access.
273     if (_access.needs_cpu_membar()) {
274       kit->insert_mem_bar(Op_MemBarCPUOrder);
275     }
276 
277     if (is_atomic) {
278       assert(kit != NULL, "unsupported at optimization time");
279       if (is_acquire || is_volatile) {
280         Node* n = _access.raw_access();
281         Node* mb = kit->insert_mem_bar(Op_MemBarAcquire, n);
282         if (_leading_membar != NULL) {
283           MemBarNode::set_load_store_pair(_leading_membar->as_MemBar(), mb->as_MemBar());
284         }
285       }
286     } else if (is_write) {
287       // If not multiple copy atomic, we do the MemBarVolatile before the load.
288       if (is_volatile && !support_IRIW_for_not_multiple_copy_atomic_cpu) {
289         assert(kit != NULL, "unsupported at optimization time");
290         Node* n = _access.raw_access();
291         Node* mb = kit->insert_mem_bar(Op_MemBarVolatile, n); // Use fat membar
292         if (_leading_membar != NULL) {
293           MemBarNode::set_store_pair(_leading_membar->as_MemBar(), mb->as_MemBar());
294         }
295       }
296     } else {
297       if (is_volatile || is_acquire) {
298         assert(kit != NULL, "unsupported at optimization time");
299         Node* n = _access.raw_access();
300         assert(_leading_membar == NULL || support_IRIW_for_not_multiple_copy_atomic_cpu, "no leading membar expected");
301         Node* mb = kit->insert_mem_bar(Op_MemBarAcquire, n);
302         mb->as_MemBar()->set_trailing_load();
303       }
304     }
305   }
306 };
307 
store_at(C2Access & access,C2AccessValue & val) const308 Node* BarrierSetC2::store_at(C2Access& access, C2AccessValue& val) const {
309   C2AccessFence fence(access);
310   resolve_address(access);
311   return store_at_resolved(access, val);
312 }
313 
load_at(C2Access & access,const Type * val_type) const314 Node* BarrierSetC2::load_at(C2Access& access, const Type* val_type) const {
315   C2AccessFence fence(access);
316   resolve_address(access);
317   return load_at_resolved(access, val_type);
318 }
319 
mem_node_mo() const320 MemNode::MemOrd C2Access::mem_node_mo() const {
321   bool is_write = (_decorators & C2_WRITE_ACCESS) != 0;
322   bool is_read = (_decorators & C2_READ_ACCESS) != 0;
323   if ((_decorators & MO_SEQ_CST) != 0) {
324     if (is_write && is_read) {
325       // For atomic operations
326       return MemNode::seqcst;
327     } else if (is_write) {
328       return MemNode::release;
329     } else {
330       assert(is_read, "what else?");
331       return MemNode::acquire;
332     }
333   } else if ((_decorators & MO_RELEASE) != 0) {
334     return MemNode::release;
335   } else if ((_decorators & MO_ACQUIRE) != 0) {
336     return MemNode::acquire;
337   } else if (is_write) {
338     // Volatile fields need releasing stores.
339     // Non-volatile fields also need releasing stores if they hold an
340     // object reference, because the object reference might point to
341     // a freshly created object.
342     // Conservatively release stores of object references.
343     return StoreNode::release_if_reference(_type);
344   } else {
345     return MemNode::unordered;
346   }
347 }
348 
fixup_decorators()349 void C2Access::fixup_decorators() {
350   bool default_mo = (_decorators & MO_DECORATOR_MASK) == 0;
351   bool is_unordered = (_decorators & MO_UNORDERED) != 0 || default_mo;
352   bool anonymous = (_decorators & C2_UNSAFE_ACCESS) != 0;
353 
354   bool is_read = (_decorators & C2_READ_ACCESS) != 0;
355   bool is_write = (_decorators & C2_WRITE_ACCESS) != 0;
356 
357   if (AlwaysAtomicAccesses && is_unordered) {
358     _decorators &= ~MO_DECORATOR_MASK; // clear the MO bits
359     _decorators |= MO_RELAXED; // Force the MO_RELAXED decorator with AlwaysAtomicAccess
360   }
361 
362   _decorators = AccessInternal::decorator_fixup(_decorators);
363 
364   if (is_read && !is_write && anonymous) {
365     // To be valid, unsafe loads may depend on other conditions than
366     // the one that guards them: pin the Load node
367     _decorators |= C2_CONTROL_DEPENDENT_LOAD;
368     _decorators |= C2_UNKNOWN_CONTROL_LOAD;
369     const TypePtr* adr_type = _addr.type();
370     Node* adr = _addr.node();
371     if (!needs_cpu_membar() && adr_type->isa_instptr()) {
372       assert(adr_type->meet(TypePtr::NULL_PTR) != adr_type->remove_speculative(), "should be not null");
373       intptr_t offset = Type::OffsetBot;
374       AddPNode::Ideal_base_and_offset(adr, &gvn(), offset);
375       if (offset >= 0) {
376         int s = Klass::layout_helper_size_in_bytes(adr_type->isa_instptr()->klass()->layout_helper());
377         if (offset < s) {
378           // Guaranteed to be a valid access, no need to pin it
379           _decorators ^= C2_CONTROL_DEPENDENT_LOAD;
380           _decorators ^= C2_UNKNOWN_CONTROL_LOAD;
381         }
382       }
383     }
384   }
385 }
386 
387 //--------------------------- atomic operations---------------------------------
388 
pin_atomic_op(C2AtomicParseAccess & access) const389 void BarrierSetC2::pin_atomic_op(C2AtomicParseAccess& access) const {
390   if (!access.needs_pinning()) {
391     return;
392   }
393   // SCMemProjNodes represent the memory state of a LoadStore. Their
394   // main role is to prevent LoadStore nodes from being optimized away
395   // when their results aren't used.
396   assert(access.is_parse_access(), "entry not supported at optimization time");
397   C2ParseAccess& parse_access = static_cast<C2ParseAccess&>(access);
398   GraphKit* kit = parse_access.kit();
399   Node* load_store = access.raw_access();
400   assert(load_store != NULL, "must pin atomic op");
401   Node* proj = kit->gvn().transform(new SCMemProjNode(load_store));
402   kit->set_memory(proj, access.alias_idx());
403 }
404 
set_memory()405 void C2AtomicParseAccess::set_memory() {
406   Node *mem = _kit->memory(_alias_idx);
407   _memory = mem;
408 }
409 
atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess & access,Node * expected_val,Node * new_val,const Type * value_type) const410 Node* BarrierSetC2::atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess& access, Node* expected_val,
411                                                    Node* new_val, const Type* value_type) const {
412   GraphKit* kit = access.kit();
413   MemNode::MemOrd mo = access.mem_node_mo();
414   Node* mem = access.memory();
415 
416   Node* adr = access.addr().node();
417   const TypePtr* adr_type = access.addr().type();
418 
419   Node* load_store = NULL;
420 
421   if (access.is_oop()) {
422 #ifdef _LP64
423     if (adr->bottom_type()->is_ptr_to_narrowoop()) {
424       Node *newval_enc = kit->gvn().transform(new EncodePNode(new_val, new_val->bottom_type()->make_narrowoop()));
425       Node *oldval_enc = kit->gvn().transform(new EncodePNode(expected_val, expected_val->bottom_type()->make_narrowoop()));
426       load_store = new CompareAndExchangeNNode(kit->control(), mem, adr, newval_enc, oldval_enc, adr_type, value_type->make_narrowoop(), mo);
427     } else
428 #endif
429     {
430       load_store = new CompareAndExchangePNode(kit->control(), mem, adr, new_val, expected_val, adr_type, value_type->is_oopptr(), mo);
431     }
432   } else {
433     switch (access.type()) {
434       case T_BYTE: {
435         load_store = new CompareAndExchangeBNode(kit->control(), mem, adr, new_val, expected_val, adr_type, mo);
436         break;
437       }
438       case T_SHORT: {
439         load_store = new CompareAndExchangeSNode(kit->control(), mem, adr, new_val, expected_val, adr_type, mo);
440         break;
441       }
442       case T_INT: {
443         load_store = new CompareAndExchangeINode(kit->control(), mem, adr, new_val, expected_val, adr_type, mo);
444         break;
445       }
446       case T_LONG: {
447         load_store = new CompareAndExchangeLNode(kit->control(), mem, adr, new_val, expected_val, adr_type, mo);
448         break;
449       }
450       default:
451         ShouldNotReachHere();
452     }
453   }
454 
455   load_store->as_LoadStore()->set_barrier_data(access.barrier_data());
456   load_store = kit->gvn().transform(load_store);
457 
458   access.set_raw_access(load_store);
459   pin_atomic_op(access);
460 
461 #ifdef _LP64
462   if (access.is_oop() && adr->bottom_type()->is_ptr_to_narrowoop()) {
463     return kit->gvn().transform(new DecodeNNode(load_store, load_store->get_ptr_type()));
464   }
465 #endif
466 
467   return load_store;
468 }
469 
atomic_cmpxchg_bool_at_resolved(C2AtomicParseAccess & access,Node * expected_val,Node * new_val,const Type * value_type) const470 Node* BarrierSetC2::atomic_cmpxchg_bool_at_resolved(C2AtomicParseAccess& access, Node* expected_val,
471                                                     Node* new_val, const Type* value_type) const {
472   GraphKit* kit = access.kit();
473   DecoratorSet decorators = access.decorators();
474   MemNode::MemOrd mo = access.mem_node_mo();
475   Node* mem = access.memory();
476   bool is_weak_cas = (decorators & C2_WEAK_CMPXCHG) != 0;
477   Node* load_store = NULL;
478   Node* adr = access.addr().node();
479 
480   if (access.is_oop()) {
481 #ifdef _LP64
482     if (adr->bottom_type()->is_ptr_to_narrowoop()) {
483       Node *newval_enc = kit->gvn().transform(new EncodePNode(new_val, new_val->bottom_type()->make_narrowoop()));
484       Node *oldval_enc = kit->gvn().transform(new EncodePNode(expected_val, expected_val->bottom_type()->make_narrowoop()));
485       if (is_weak_cas) {
486         load_store = new WeakCompareAndSwapNNode(kit->control(), mem, adr, newval_enc, oldval_enc, mo);
487       } else {
488         load_store = new CompareAndSwapNNode(kit->control(), mem, adr, newval_enc, oldval_enc, mo);
489       }
490     } else
491 #endif
492     {
493       if (is_weak_cas) {
494         load_store = new WeakCompareAndSwapPNode(kit->control(), mem, adr, new_val, expected_val, mo);
495       } else {
496         load_store = new CompareAndSwapPNode(kit->control(), mem, adr, new_val, expected_val, mo);
497       }
498     }
499   } else {
500     switch(access.type()) {
501       case T_BYTE: {
502         if (is_weak_cas) {
503           load_store = new WeakCompareAndSwapBNode(kit->control(), mem, adr, new_val, expected_val, mo);
504         } else {
505           load_store = new CompareAndSwapBNode(kit->control(), mem, adr, new_val, expected_val, mo);
506         }
507         break;
508       }
509       case T_SHORT: {
510         if (is_weak_cas) {
511           load_store = new WeakCompareAndSwapSNode(kit->control(), mem, adr, new_val, expected_val, mo);
512         } else {
513           load_store = new CompareAndSwapSNode(kit->control(), mem, adr, new_val, expected_val, mo);
514         }
515         break;
516       }
517       case T_INT: {
518         if (is_weak_cas) {
519           load_store = new WeakCompareAndSwapINode(kit->control(), mem, adr, new_val, expected_val, mo);
520         } else {
521           load_store = new CompareAndSwapINode(kit->control(), mem, adr, new_val, expected_val, mo);
522         }
523         break;
524       }
525       case T_LONG: {
526         if (is_weak_cas) {
527           load_store = new WeakCompareAndSwapLNode(kit->control(), mem, adr, new_val, expected_val, mo);
528         } else {
529           load_store = new CompareAndSwapLNode(kit->control(), mem, adr, new_val, expected_val, mo);
530         }
531         break;
532       }
533       default:
534         ShouldNotReachHere();
535     }
536   }
537 
538   load_store->as_LoadStore()->set_barrier_data(access.barrier_data());
539   load_store = kit->gvn().transform(load_store);
540 
541   access.set_raw_access(load_store);
542   pin_atomic_op(access);
543 
544   return load_store;
545 }
546 
atomic_xchg_at_resolved(C2AtomicParseAccess & access,Node * new_val,const Type * value_type) const547 Node* BarrierSetC2::atomic_xchg_at_resolved(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const {
548   GraphKit* kit = access.kit();
549   Node* mem = access.memory();
550   Node* adr = access.addr().node();
551   const TypePtr* adr_type = access.addr().type();
552   Node* load_store = NULL;
553 
554   if (access.is_oop()) {
555 #ifdef _LP64
556     if (adr->bottom_type()->is_ptr_to_narrowoop()) {
557       Node *newval_enc = kit->gvn().transform(new EncodePNode(new_val, new_val->bottom_type()->make_narrowoop()));
558       load_store = kit->gvn().transform(new GetAndSetNNode(kit->control(), mem, adr, newval_enc, adr_type, value_type->make_narrowoop()));
559     } else
560 #endif
561     {
562       load_store = new GetAndSetPNode(kit->control(), mem, adr, new_val, adr_type, value_type->is_oopptr());
563     }
564   } else  {
565     switch (access.type()) {
566       case T_BYTE:
567         load_store = new GetAndSetBNode(kit->control(), mem, adr, new_val, adr_type);
568         break;
569       case T_SHORT:
570         load_store = new GetAndSetSNode(kit->control(), mem, adr, new_val, adr_type);
571         break;
572       case T_INT:
573         load_store = new GetAndSetINode(kit->control(), mem, adr, new_val, adr_type);
574         break;
575       case T_LONG:
576         load_store = new GetAndSetLNode(kit->control(), mem, adr, new_val, adr_type);
577         break;
578       default:
579         ShouldNotReachHere();
580     }
581   }
582 
583   load_store->as_LoadStore()->set_barrier_data(access.barrier_data());
584   load_store = kit->gvn().transform(load_store);
585 
586   access.set_raw_access(load_store);
587   pin_atomic_op(access);
588 
589 #ifdef _LP64
590   if (access.is_oop() && adr->bottom_type()->is_ptr_to_narrowoop()) {
591     return kit->gvn().transform(new DecodeNNode(load_store, load_store->get_ptr_type()));
592   }
593 #endif
594 
595   return load_store;
596 }
597 
atomic_add_at_resolved(C2AtomicParseAccess & access,Node * new_val,const Type * value_type) const598 Node* BarrierSetC2::atomic_add_at_resolved(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const {
599   Node* load_store = NULL;
600   GraphKit* kit = access.kit();
601   Node* adr = access.addr().node();
602   const TypePtr* adr_type = access.addr().type();
603   Node* mem = access.memory();
604 
605   switch(access.type()) {
606     case T_BYTE:
607       load_store = new GetAndAddBNode(kit->control(), mem, adr, new_val, adr_type);
608       break;
609     case T_SHORT:
610       load_store = new GetAndAddSNode(kit->control(), mem, adr, new_val, adr_type);
611       break;
612     case T_INT:
613       load_store = new GetAndAddINode(kit->control(), mem, adr, new_val, adr_type);
614       break;
615     case T_LONG:
616       load_store = new GetAndAddLNode(kit->control(), mem, adr, new_val, adr_type);
617       break;
618     default:
619       ShouldNotReachHere();
620   }
621 
622   load_store->as_LoadStore()->set_barrier_data(access.barrier_data());
623   load_store = kit->gvn().transform(load_store);
624 
625   access.set_raw_access(load_store);
626   pin_atomic_op(access);
627 
628   return load_store;
629 }
630 
atomic_cmpxchg_val_at(C2AtomicParseAccess & access,Node * expected_val,Node * new_val,const Type * value_type) const631 Node* BarrierSetC2::atomic_cmpxchg_val_at(C2AtomicParseAccess& access, Node* expected_val,
632                                           Node* new_val, const Type* value_type) const {
633   C2AccessFence fence(access);
634   resolve_address(access);
635   return atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, value_type);
636 }
637 
atomic_cmpxchg_bool_at(C2AtomicParseAccess & access,Node * expected_val,Node * new_val,const Type * value_type) const638 Node* BarrierSetC2::atomic_cmpxchg_bool_at(C2AtomicParseAccess& access, Node* expected_val,
639                                            Node* new_val, const Type* value_type) const {
640   C2AccessFence fence(access);
641   resolve_address(access);
642   return atomic_cmpxchg_bool_at_resolved(access, expected_val, new_val, value_type);
643 }
644 
atomic_xchg_at(C2AtomicParseAccess & access,Node * new_val,const Type * value_type) const645 Node* BarrierSetC2::atomic_xchg_at(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const {
646   C2AccessFence fence(access);
647   resolve_address(access);
648   return atomic_xchg_at_resolved(access, new_val, value_type);
649 }
650 
atomic_add_at(C2AtomicParseAccess & access,Node * new_val,const Type * value_type) const651 Node* BarrierSetC2::atomic_add_at(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const {
652   C2AccessFence fence(access);
653   resolve_address(access);
654   return atomic_add_at_resolved(access, new_val, value_type);
655 }
656 
arraycopy_payload_base_offset(bool is_array)657 int BarrierSetC2::arraycopy_payload_base_offset(bool is_array) {
658   // Exclude the header but include array length to copy by 8 bytes words.
659   // Can't use base_offset_in_bytes(bt) since basic type is unknown.
660   int base_off = is_array ? arrayOopDesc::length_offset_in_bytes() :
661                             instanceOopDesc::base_offset_in_bytes();
662   // base_off:
663   // 8  - 32-bit VM
664   // 12 - 64-bit VM, compressed klass
665   // 16 - 64-bit VM, normal klass
666   if (base_off % BytesPerLong != 0) {
667     assert(UseCompressedClassPointers, "");
668     if (is_array) {
669       // Exclude length to copy by 8 bytes words.
670       base_off += sizeof(int);
671     } else {
672       // Include klass to copy by 8 bytes words.
673       base_off = instanceOopDesc::klass_offset_in_bytes();
674     }
675     assert(base_off % BytesPerLong == 0, "expect 8 bytes alignment");
676   }
677   return base_off;
678 }
679 
clone(GraphKit * kit,Node * src_base,Node * dst_base,Node * size,bool is_array) const680 void BarrierSetC2::clone(GraphKit* kit, Node* src_base, Node* dst_base, Node* size, bool is_array) const {
681   int base_off = arraycopy_payload_base_offset(is_array);
682   Node* payload_size = size;
683   Node* offset = kit->MakeConX(base_off);
684   payload_size = kit->gvn().transform(new SubXNode(payload_size, offset));
685   payload_size = kit->gvn().transform(new URShiftXNode(payload_size, kit->intcon(LogBytesPerLong)));
686   ArrayCopyNode* ac = ArrayCopyNode::make(kit, false, src_base, offset,  dst_base, offset, payload_size, true, false);
687   if (is_array) {
688     ac->set_clone_array();
689   } else {
690     ac->set_clone_inst();
691   }
692   Node* n = kit->gvn().transform(ac);
693   if (n == ac) {
694     const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
695     ac->_adr_type = TypeRawPtr::BOTTOM;
696     kit->set_predefined_output_for_runtime_call(ac, ac->in(TypeFunc::Memory), raw_adr_type);
697   } else {
698     kit->set_all_memory(n);
699   }
700 }
701 
obj_allocate(PhaseMacroExpand * macro,Node * ctrl,Node * mem,Node * toobig_false,Node * size_in_bytes,Node * & i_o,Node * & needgc_ctrl,Node * & fast_oop_ctrl,Node * & fast_oop_rawmem,intx prefetch_lines) const702 Node* BarrierSetC2::obj_allocate(PhaseMacroExpand* macro, Node* ctrl, Node* mem, Node* toobig_false, Node* size_in_bytes,
703                                  Node*& i_o, Node*& needgc_ctrl,
704                                  Node*& fast_oop_ctrl, Node*& fast_oop_rawmem,
705                                  intx prefetch_lines) const {
706 
707   Node* eden_top_adr;
708   Node* eden_end_adr;
709 
710   macro->set_eden_pointers(eden_top_adr, eden_end_adr);
711 
712   // Load Eden::end.  Loop invariant and hoisted.
713   //
714   // Note: We set the control input on "eden_end" and "old_eden_top" when using
715   //       a TLAB to work around a bug where these values were being moved across
716   //       a safepoint.  These are not oops, so they cannot be include in the oop
717   //       map, but they can be changed by a GC.   The proper way to fix this would
718   //       be to set the raw memory state when generating a  SafepointNode.  However
719   //       this will require extensive changes to the loop optimization in order to
720   //       prevent a degradation of the optimization.
721   //       See comment in memnode.hpp, around line 227 in class LoadPNode.
722   Node *eden_end = macro->make_load(ctrl, mem, eden_end_adr, 0, TypeRawPtr::BOTTOM, T_ADDRESS);
723 
724   // We need a Region for the loop-back contended case.
725   enum { fall_in_path = 1, contended_loopback_path = 2 };
726   Node *contended_region;
727   Node *contended_phi_rawmem;
728   if (UseTLAB) {
729     contended_region = toobig_false;
730     contended_phi_rawmem = mem;
731   } else {
732     contended_region = new RegionNode(3);
733     contended_phi_rawmem = new PhiNode(contended_region, Type::MEMORY, TypeRawPtr::BOTTOM);
734     // Now handle the passing-too-big test.  We fall into the contended
735     // loop-back merge point.
736     contended_region    ->init_req(fall_in_path, toobig_false);
737     contended_phi_rawmem->init_req(fall_in_path, mem);
738     macro->transform_later(contended_region);
739     macro->transform_later(contended_phi_rawmem);
740   }
741 
742   // Load(-locked) the heap top.
743   // See note above concerning the control input when using a TLAB
744   Node *old_eden_top = UseTLAB
745     ? new LoadPNode      (ctrl, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM, MemNode::unordered)
746     : new LoadPLockedNode(contended_region, contended_phi_rawmem, eden_top_adr, MemNode::acquire);
747 
748   macro->transform_later(old_eden_top);
749   // Add to heap top to get a new heap top
750   Node *new_eden_top = new AddPNode(macro->top(), old_eden_top, size_in_bytes);
751   macro->transform_later(new_eden_top);
752   // Check for needing a GC; compare against heap end
753   Node *needgc_cmp = new CmpPNode(new_eden_top, eden_end);
754   macro->transform_later(needgc_cmp);
755   Node *needgc_bol = new BoolNode(needgc_cmp, BoolTest::ge);
756   macro->transform_later(needgc_bol);
757   IfNode *needgc_iff = new IfNode(contended_region, needgc_bol, PROB_UNLIKELY_MAG(4), COUNT_UNKNOWN);
758   macro->transform_later(needgc_iff);
759 
760   // Plug the failing-heap-space-need-gc test into the slow-path region
761   Node *needgc_true = new IfTrueNode(needgc_iff);
762   macro->transform_later(needgc_true);
763   needgc_ctrl = needgc_true;
764 
765   // No need for a GC.  Setup for the Store-Conditional
766   Node *needgc_false = new IfFalseNode(needgc_iff);
767   macro->transform_later(needgc_false);
768 
769   i_o = macro->prefetch_allocation(i_o, needgc_false, contended_phi_rawmem,
770                                    old_eden_top, new_eden_top, prefetch_lines);
771 
772   Node* fast_oop = old_eden_top;
773 
774   // Store (-conditional) the modified eden top back down.
775   // StorePConditional produces flags for a test PLUS a modified raw
776   // memory state.
777   if (UseTLAB) {
778     Node* store_eden_top =
779       new StorePNode(needgc_false, contended_phi_rawmem, eden_top_adr,
780                      TypeRawPtr::BOTTOM, new_eden_top, MemNode::unordered);
781     macro->transform_later(store_eden_top);
782     fast_oop_ctrl = needgc_false; // No contention, so this is the fast path
783     fast_oop_rawmem = store_eden_top;
784   } else {
785     Node* store_eden_top =
786       new StorePConditionalNode(needgc_false, contended_phi_rawmem, eden_top_adr,
787                                 new_eden_top, fast_oop/*old_eden_top*/);
788     macro->transform_later(store_eden_top);
789     Node *contention_check = new BoolNode(store_eden_top, BoolTest::ne);
790     macro->transform_later(contention_check);
791     store_eden_top = new SCMemProjNode(store_eden_top);
792     macro->transform_later(store_eden_top);
793 
794     // If not using TLABs, check to see if there was contention.
795     IfNode *contention_iff = new IfNode (needgc_false, contention_check, PROB_MIN, COUNT_UNKNOWN);
796     macro->transform_later(contention_iff);
797     Node *contention_true = new IfTrueNode(contention_iff);
798     macro->transform_later(contention_true);
799     // If contention, loopback and try again.
800     contended_region->init_req(contended_loopback_path, contention_true);
801     contended_phi_rawmem->init_req(contended_loopback_path, store_eden_top);
802 
803     // Fast-path succeeded with no contention!
804     Node *contention_false = new IfFalseNode(contention_iff);
805     macro->transform_later(contention_false);
806     fast_oop_ctrl = contention_false;
807 
808     // Bump total allocated bytes for this thread
809     Node* thread = new ThreadLocalNode();
810     macro->transform_later(thread);
811     Node* alloc_bytes_adr = macro->basic_plus_adr(macro->top()/*not oop*/, thread,
812                                                   in_bytes(JavaThread::allocated_bytes_offset()));
813     Node* alloc_bytes = macro->make_load(fast_oop_ctrl, store_eden_top, alloc_bytes_adr,
814                                          0, TypeLong::LONG, T_LONG);
815 #ifdef _LP64
816     Node* alloc_size = size_in_bytes;
817 #else
818     Node* alloc_size = new ConvI2LNode(size_in_bytes);
819     macro->transform_later(alloc_size);
820 #endif
821     Node* new_alloc_bytes = new AddLNode(alloc_bytes, alloc_size);
822     macro->transform_later(new_alloc_bytes);
823     fast_oop_rawmem = macro->make_store(fast_oop_ctrl, store_eden_top, alloc_bytes_adr,
824                                         0, new_alloc_bytes, T_LONG);
825   }
826   return fast_oop;
827 }
828 
829 #define XTOP LP64_ONLY(COMMA phase->top())
830 
clone_at_expansion(PhaseMacroExpand * phase,ArrayCopyNode * ac) const831 void BarrierSetC2::clone_at_expansion(PhaseMacroExpand* phase, ArrayCopyNode* ac) const {
832   Node* ctrl = ac->in(TypeFunc::Control);
833   Node* mem = ac->in(TypeFunc::Memory);
834   Node* src = ac->in(ArrayCopyNode::Src);
835   Node* src_offset = ac->in(ArrayCopyNode::SrcPos);
836   Node* dest = ac->in(ArrayCopyNode::Dest);
837   Node* dest_offset = ac->in(ArrayCopyNode::DestPos);
838   Node* length = ac->in(ArrayCopyNode::Length);
839 
840   Node* payload_src = phase->basic_plus_adr(src, src_offset);
841   Node* payload_dst = phase->basic_plus_adr(dest, dest_offset);
842 
843   const char* copyfunc_name = "arraycopy";
844   address     copyfunc_addr = phase->basictype2arraycopy(T_LONG, NULL, NULL, true, copyfunc_name, true);
845 
846   const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
847   const TypeFunc* call_type = OptoRuntime::fast_arraycopy_Type();
848 
849   Node* call = phase->make_leaf_call(ctrl, mem, call_type, copyfunc_addr, copyfunc_name, raw_adr_type, payload_src, payload_dst, length XTOP);
850   phase->transform_later(call);
851 
852   phase->igvn().replace_node(ac, call);
853 }
854