< prev index next >

src/hotspot/share/opto/macro.cpp

Print this page

        

@@ -45,13 +45,17 @@
 #include "opto/rootnode.hpp"
 #include "opto/runtime.hpp"
 #include "opto/subnode.hpp"
 #include "opto/type.hpp"
 #include "runtime/sharedRuntime.hpp"
+#include "utilities/macros.hpp"
 #if INCLUDE_G1GC
 #include "gc/g1/g1ThreadLocalData.hpp"
 #endif // INCLUDE_G1GC
+#if INCLUDE_SHENANDOAHGC
+#include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp"
+#endif
 
 
 //
 // Replace any references to "oldref" in inputs to "use" with "newref".
 // Returns the number of replacements made.

@@ -432,11 +436,15 @@
         return NULL;  // can't find a value on this path
       }
       if (val == mem) {
         values.at_put(j, mem);
       } else if (val->is_Store()) {
-        values.at_put(j, val->in(MemNode::ValueIn));
+        Node* n = val->in(MemNode::ValueIn);
+#if INCLUDE_SHENANDOAHGC
+        n = ShenandoahBarrierNode::skip_through_barrier(n);
+#endif
+        values.at_put(j, n);
       } else if(val->is_Proj() && val->in(0) == alloc) {
         values.at_put(j, _igvn.zerocon(ft));
       } else if (val->is_Phi()) {
         val = value_from_mem_phi(val, ft, phi_type, adr_t, alloc, value_phis, level-1);
         if (val == NULL) {

@@ -544,11 +552,15 @@
   if (mem != NULL) {
     if (mem == start_mem || mem == alloc_mem) {
       // hit a sentinel, return appropriate 0 value
       return _igvn.zerocon(ft);
     } else if (mem->is_Store()) {
-      return mem->in(MemNode::ValueIn);
+      Node* n = mem->in(MemNode::ValueIn);
+#if INCLUDE_SHENANDOAHGC
+      n = ShenandoahBarrierNode::skip_through_barrier(n);
+#endif
+      return n;
     } else if (mem->is_Phi()) {
       // attempt to produce a Phi reflecting the values on the input paths of the Phi
       Node_Stack value_phis(a, 8);
       Node * phi = value_from_mem_phi(mem, ft, ftype, adr_t, alloc, &value_phis, ValueSearchLimit);
       if (phi != NULL) {

@@ -621,10 +633,11 @@
         }
         for (DUIterator_Fast kmax, k = use->fast_outs(kmax);
                                    k < kmax && can_eliminate; k++) {
           Node* n = use->fast_out(k);
           if (!n->is_Store() && n->Opcode() != Op_CastP2X &&
+              SHENANDOAHGC_ONLY((!UseShenandoahGC || !ShenandoahBarrierSetC2::is_shenandoah_wb_pre_call(n)) &&)
               !(n->is_ArrayCopy() &&
                 n->as_ArrayCopy()->is_clonebasic() &&
                 n->in(ArrayCopyNode::Dest) == use)) {
             DEBUG_ONLY(disq_node = n;)
             if (n->is_Load() || n->is_LoadStore()) {

@@ -932,10 +945,13 @@
           } else {
             eliminate_gc_barrier(n);
           }
           k -= (oc2 - use->outcnt());
         }
+        if (UseShenandoahGC) {
+          _igvn.remove_dead_node(use);
+        }
       } else if (use->is_ArrayCopy()) {
         // Disconnect ArrayCopy node
         ArrayCopyNode* ac = use->as_ArrayCopy();
         assert(ac->is_arraycopy_validated() ||
                ac->is_copyof_validated() ||

@@ -1354,10 +1370,21 @@
       ? new LoadPNode      (ctrl, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM, MemNode::unordered)
       : new LoadPLockedNode(contended_region, contended_phi_rawmem, eden_top_adr, MemNode::acquire);
 
     transform_later(old_eden_top);
     // Add to heap top to get a new heap top
+
+    Node* init_size_in_bytes = size_in_bytes;
+
+#if INCLUDE_SHENANDOAHGC
+    if (UseShenandoahGC) {
+      // Allocate several words more for the Shenandoah brooks pointer.
+      size_in_bytes = new AddXNode(size_in_bytes, _igvn.MakeConX(ShenandoahBrooksPointer::byte_size()));
+      transform_later(size_in_bytes);
+    }
+#endif
+
     Node *new_eden_top = new AddPNode(top(), old_eden_top, size_in_bytes);
     transform_later(new_eden_top);
     // Check for needing a GC; compare against heap end
     Node *needgc_cmp = new CmpPNode(new_eden_top, eden_end);
     transform_later(needgc_cmp);

@@ -1444,14 +1471,22 @@
       transform_later(new_alloc_bytes);
       fast_oop_rawmem = make_store(fast_oop_ctrl, store_eden_top, alloc_bytes_adr,
                                    0, new_alloc_bytes, T_LONG);
     }
 
+#if INCLUDE_SHENANDOAHGC
+    if (UseShenandoahGC) {
+      // Bump up object for Shenandoah brooks pointer.
+      fast_oop = new AddPNode(top(), fast_oop, _igvn.MakeConX(ShenandoahBrooksPointer::byte_size()));
+      transform_later(fast_oop);
+    }
+#endif
+
     InitializeNode* init = alloc->initialization();
     fast_oop_rawmem = initialize_object(alloc,
                                         fast_oop_ctrl, fast_oop_rawmem, fast_oop,
-                                        klass_node, length, size_in_bytes);
+                                        klass_node, length, init_size_in_bytes);
 
     // If initialization is performed by an array copy, any required
     // MemBarStoreStore was already added. If the object does not
     // escape no need for a MemBarStoreStore. If the object does not
     // escape in its initializer and memory barrier (MemBarStoreStore or

@@ -1735,10 +1770,17 @@
     ciKlass* k = _igvn.type(klass_node)->is_klassptr()->klass();
     if (k->is_array_klass())    // we know the exact header size in most cases:
       header_size = Klass::layout_helper_header_size(k->layout_helper());
   }
 
+#if INCLUDE_SHENANDOAHGC
+  if (UseShenandoahGC) {
+    // Initialize Shenandoah brooks pointer to point to the object itself.
+    rawmem = make_store(control, rawmem, object, ShenandoahBrooksPointer::byte_offset(), object, T_OBJECT);
+  }
+#endif
+
   // Clear the object body, if necessary.
   if (init == NULL) {
     // The init has somehow disappeared; be cautious and clear everything.
     //
     // This can happen if a node is allocated but an uncommon trap occurs
< prev index next >