< prev index next >

src/hotspot/share/opto/escape.cpp

Print this page

        

@@ -43,10 +43,13 @@
 #include "gc/g1/g1ThreadLocalData.hpp"
 #endif // INCLUDE_G1GC
 #if INCLUDE_ZGC
 #include "gc/z/c2/zBarrierSetC2.hpp"
 #endif
+#if INCLUDE_SHENANDOAHGC
+#include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp"
+#endif
 
 ConnectionGraph::ConnectionGraph(Compile * C, PhaseIterGVN *igvn) :
   _nodes(C->comp_arena(), C->unique(), C->unique(), NULL),
   _in_worklist(C->comp_arena()),
   _next_pidx(0),

@@ -552,20 +555,28 @@
         // Stored value escapes in unsafe access.
         if ((opcode == Op_StoreP) && adr_type->isa_rawptr()) {
           // Pointer stores in G1 barriers looks like unsafe access.
           // Ignore such stores to be able scalar replace non-escaping
           // allocations.
-#if INCLUDE_G1GC
-          if (UseG1GC && adr->is_AddP()) {
+#if INCLUDE_G1GC || INCLUDE_SHENANDOAHGC
+          if ((UseG1GC || UseShenandoahGC) && adr->is_AddP()) {
             Node* base = get_addp_base(adr);
             if (base->Opcode() == Op_LoadP &&
                 base->in(MemNode::Address)->is_AddP()) {
               adr = base->in(MemNode::Address);
               Node* tls = get_addp_base(adr);
               if (tls->Opcode() == Op_ThreadLocal) {
                 int offs = (int)igvn->find_intptr_t_con(adr->in(AddPNode::Offset), Type::OffsetBot);
-                if (offs == in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset())) {
+#if INCLUDE_G1GC && INCLUDE_SHENANDOAHGC
+                const int buf_offset = in_bytes(UseG1GC ? G1ThreadLocalData::satb_mark_queue_buffer_offset()
+                                                        : ShenandoahThreadLocalData::satb_mark_queue_buffer_offset());
+#elif INCLUDE_G1GC
+                const int buf_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset());
+#else
+                const int buf_offset = in_bytes(ShenandoahThreadLocalData::satb_mark_queue_buffer_offset());
+#endif
+                if (offs == buf_offset) {
                   break; // G1 pre barrier previous oop value store.
                 }
                 if (offs == in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset())) {
                   break; // G1 post barrier card address store.
                 }

@@ -598,10 +609,21 @@
     }
     case Op_ThreadLocal: {
       add_java_object(n, PointsToNode::ArgEscape);
       break;
     }
+#if INCLUDE_SHENANDOAHGC
+    case Op_ShenandoahReadBarrier:
+    case Op_ShenandoahWriteBarrier:
+      // Barriers 'pass through' its arguments. I.e. what goes in, comes out.
+      // It doesn't escape.
+      add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(ShenandoahBarrierNode::ValueIn), delayed_worklist);
+      break;
+    case Op_ShenandoahEnqueueBarrier:
+      add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(1), delayed_worklist);
+      break;
+#endif
     default:
       ; // Do nothing for nodes not related to EA.
   }
   return;
 }

@@ -813,10 +835,21 @@
           add_edge(n_ptn, ptn);
         }
       }
       break;
     }
+#if INCLUDE_SHENANDOAHGC
+    case Op_ShenandoahReadBarrier:
+    case Op_ShenandoahWriteBarrier:
+      // Barriers 'pass through' its arguments. I.e. what goes in, comes out.
+      // It doesn't escape.
+      add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(ShenandoahBarrierNode::ValueIn), NULL);
+      break;
+    case Op_ShenandoahEnqueueBarrier:
+      add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(1), NULL);
+      break;
+#endif
     default: {
       // This method should be called only for EA specific nodes which may
       // miss some edges when they were created.
 #ifdef ASSERT
       n->dump(1);

@@ -2369,11 +2402,12 @@
       Node* uncast_base = base->uncast();
       int opcode = uncast_base->Opcode();
       assert(opcode == Op_ConP || opcode == Op_ThreadLocal ||
              opcode == Op_CastX2P || uncast_base->is_DecodeNarrowPtr() ||
              (uncast_base->is_Mem() && (uncast_base->bottom_type()->isa_rawptr() != NULL)) ||
-             (uncast_base->is_Proj() && uncast_base->in(0)->is_Allocate()), "sanity");
+             (uncast_base->is_Proj() && uncast_base->in(0)->is_Allocate()) ||
+             uncast_base->is_ShenandoahBarrier(), "sanity");
     }
   }
   return base;
 }
 

@@ -3102,10 +3136,11 @@
       if (!split_AddP(n, base)) continue; // wrong type from dead path
     } else if (n->is_Phi() ||
                n->is_CheckCastPP() ||
                n->is_EncodeP() ||
                n->is_DecodeN() ||
+               n->is_ShenandoahBarrier() ||
                (n->is_ConstraintCast() && n->Opcode() == Op_CastPP)) {
       if (visited.test_set(n->_idx)) {
         assert(n->is_Phi(), "loops only through Phi's");
         continue;  // already processed
       }

@@ -3172,10 +3207,11 @@
         alloc_worklist.append_if_missing(use);
       } else if (use->is_Phi() ||
                  use->is_CheckCastPP() ||
                  use->is_EncodeNarrowPtr() ||
                  use->is_DecodeNarrowPtr() ||
+                 use->is_ShenandoahBarrier() ||
                  (use->is_ConstraintCast() && use->Opcode() == Op_CastPP)) {
         alloc_worklist.append_if_missing(use);
 #ifdef ASSERT
       } else if (use->is_Mem()) {
         assert(use->in(MemNode::Address) != n, "EA: missing allocation reference path");

@@ -3202,10 +3238,11 @@
         } else if (!(op == Op_CmpP || op == Op_Conv2B ||
               op == Op_CastP2X || op == Op_StoreCM ||
               op == Op_FastLock || op == Op_AryEq || op == Op_StrComp || op == Op_HasNegatives ||
               op == Op_StrCompressedCopy || op == Op_StrInflatedCopy ||
               op == Op_StrEquals || op == Op_StrIndexOf || op == Op_StrIndexOfChar ||
+              op == Op_ShenandoahWBMemProj ||
               BarrierSet::barrier_set()->barrier_set_c2()->is_gc_barrier_node(use))) {
           n->dump();
           use->dump();
           assert(false, "EA: missing allocation reference path");
         }
< prev index next >