< prev index next >

src/hotspot/share/opto/arraycopynode.cpp

Print this page

        

@@ -28,10 +28,13 @@
 #include "gc/shared/c2/cardTableBarrierSetC2.hpp"
 #include "opto/arraycopynode.hpp"
 #include "opto/graphKit.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "utilities/macros.hpp"
+#if INCLUDE_SHENANDOAHGC
+#include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp"
+#endif
 
 ArrayCopyNode::ArrayCopyNode(Compile* C, bool alloc_tightly_coupled, bool has_negative_length_guard)
   : CallNode(arraycopy_type(), NULL, TypeRawPtr::BOTTOM),
     _alloc_tightly_coupled(alloc_tightly_coupled),
     _has_negative_length_guard(has_negative_length_guard),

@@ -203,10 +206,15 @@
       type = Type::get_const_basic_type(bt);
     }
 
     Node* v = LoadNode::make(*phase, ctl, mem->memory_at(fieldidx), next_src, adr_type, type, bt, MemNode::unordered);
     v = phase->transform(v);
+#if INCLUDE_SHENANDOAHGC
+    if (UseShenandoahGC && bt == T_OBJECT) {
+      v = ShenandoahBarrierSetC2::bsc2()->arraycopy_load_reference_barrier(phase, v);
+    }
+#endif
     Node* s = StoreNode::make(*phase, ctl, mem->memory_at(fieldidx), next_dest, adr_type, v, bt, MemNode::unordered);
     s = phase->transform(s);
     mem->set_memory_at(fieldidx, s);
   }
 

@@ -371,18 +379,28 @@
     bool same_alias = (alias_idx_src == alias_idx_dest);
 
     if (count > 0) {
       Node* v = LoadNode::make(*phase, forward_ctl, start_mem_src, adr_src, atp_src, value_type, copy_type, MemNode::unordered);
       v = phase->transform(v);
+#if INCLUDE_SHENANDOAHGC
+      if (UseShenandoahGC && copy_type == T_OBJECT) {
+        v = ShenandoahBarrierSetC2::bsc2()->arraycopy_load_reference_barrier(phase, v);
+      }
+#endif
       mem = StoreNode::make(*phase, forward_ctl, mem, adr_dest, atp_dest, v, copy_type, MemNode::unordered);
       mem = phase->transform(mem);
       for (int i = 1; i < count; i++) {
         Node* off  = phase->MakeConX(type2aelembytes(copy_type) * i);
         Node* next_src = phase->transform(new AddPNode(base_src,adr_src,off));
         Node* next_dest = phase->transform(new AddPNode(base_dest,adr_dest,off));
         v = LoadNode::make(*phase, forward_ctl, same_alias ? mem : start_mem_src, next_src, atp_src, value_type, copy_type, MemNode::unordered);
         v = phase->transform(v);
+#if INCLUDE_SHENANDOAHGC
+        if (UseShenandoahGC && copy_type == T_OBJECT) {
+          v = ShenandoahBarrierSetC2::bsc2()->arraycopy_load_reference_barrier(phase, v);
+        }
+#endif
         mem = StoreNode::make(*phase, forward_ctl,mem,next_dest,atp_dest,v, copy_type, MemNode::unordered);
         mem = phase->transform(mem);
       }
     } else if(can_reshape) {
       PhaseIterGVN* igvn = phase->is_IterGVN();

@@ -420,15 +438,25 @@
         Node* off  = phase->MakeConX(type2aelembytes(copy_type) * i);
         Node* next_src = phase->transform(new AddPNode(base_src,adr_src,off));
         Node* next_dest = phase->transform(new AddPNode(base_dest,adr_dest,off));
         Node* v = LoadNode::make(*phase, backward_ctl, same_alias ? mem : start_mem_src, next_src, atp_src, value_type, copy_type, MemNode::unordered);
         v = phase->transform(v);
+#if INCLUDE_SHENANDOAHGC
+        if (UseShenandoahGC && copy_type == T_OBJECT) {
+          v = ShenandoahBarrierSetC2::bsc2()->arraycopy_load_reference_barrier(phase, v);
+        }
+#endif
         mem = StoreNode::make(*phase, backward_ctl,mem,next_dest,atp_dest,v, copy_type, MemNode::unordered);
         mem = phase->transform(mem);
       }
       Node* v = LoadNode::make(*phase, backward_ctl, same_alias ? mem : start_mem_src, adr_src, atp_src, value_type, copy_type, MemNode::unordered);
       v = phase->transform(v);
+#if INCLUDE_SHENANDOAHGC
+      if (UseShenandoahGC && copy_type == T_OBJECT) {
+        v = ShenandoahBarrierSetC2::bsc2()->arraycopy_load_reference_barrier(phase, v);
+      }
+#endif
       mem = StoreNode::make(*phase, backward_ctl, mem, adr_dest, atp_dest, v, copy_type, MemNode::unordered);
       mem = phase->transform(mem);
     } else if(can_reshape) {
       PhaseIterGVN* igvn = phase->is_IterGVN();
       igvn->_worklist.push(adr_src);

@@ -483,11 +511,12 @@
       remove_dead_region(phase, can_reshape);
     }
   } else {
     if (in(TypeFunc::Control) != ctl) {
       // we can't return new memory and control from Ideal at parse time
-      assert(!is_clonebasic(), "added control for clone?");
+      assert(!is_clonebasic() || UseShenandoahGC, "added control for clone?");
+      phase->record_for_igvn(this);
       return false;
     }
   }
   return true;
 }
< prev index next >