< prev index next >

src/share/vm/opto/library_call.cpp

Print this page
rev 12619 : 8174164: SafePointNode::_replaced_nodes breaks with irreducible loops
Reviewed-by:

@@ -275,11 +275,12 @@
   // Helper functions for inlining arraycopy
   bool inline_arraycopy();
   AllocateArrayNode* tightly_coupled_allocation(Node* ptr,
                                                 RegionNode* slow_region);
   JVMState* arraycopy_restore_alloc_state(AllocateArrayNode* alloc, int& saved_reexecute_sp);
-  void arraycopy_move_allocation_here(AllocateArrayNode* alloc, Node* dest, JVMState* saved_jvms, int saved_reexecute_sp);
+  void arraycopy_move_allocation_here(AllocateArrayNode* alloc, Node* dest, JVMState* saved_jvms, int saved_reexecute_sp,
+                                      uint new_idx);
 
   typedef enum { LS_get_add, LS_get_set, LS_cmp_swap, LS_cmp_swap_weak, LS_cmp_exchange } LoadStoreKind;
   MemNode::MemOrd access_kind_to_memord_LS(AccessKind access_kind, bool is_store);
   MemNode::MemOrd access_kind_to_memord(AccessKind access_kind);
   bool inline_unsafe_load_store(BasicType type,  LoadStoreKind kind, AccessKind access_kind);

@@ -4880,20 +4881,21 @@
 // array in the heap that GCs wouldn't expect. Move the allocation
 // after the traps so we don't allocate the array if we
 // deoptimize. This is possible because tightly_coupled_allocation()
 // guarantees there's no observer of the allocated array at this point
 // and the control flow is simple enough.
-void LibraryCallKit::arraycopy_move_allocation_here(AllocateArrayNode* alloc, Node* dest, JVMState* saved_jvms, int saved_reexecute_sp) {
+void LibraryCallKit::arraycopy_move_allocation_here(AllocateArrayNode* alloc, Node* dest, JVMState* saved_jvms,
+                                                    int saved_reexecute_sp, uint new_idx) {
   if (saved_jvms != NULL && !stopped()) {
     assert(alloc != NULL, "only with a tightly coupled allocation");
     // restore JVM state to the state at the arraycopy
     saved_jvms->map()->set_control(map()->control());
     assert(saved_jvms->map()->memory() == map()->memory(), "memory state changed?");
     assert(saved_jvms->map()->i_o() == map()->i_o(), "IO state changed?");
     // If we've improved the types of some nodes (null check) while
     // emitting the guards, propagate them to the current state
-    map()->replaced_nodes().apply(saved_jvms->map());
+    map()->replaced_nodes().apply(saved_jvms->map(), new_idx);
     set_jvms(saved_jvms);
     _reexecute_sp = saved_reexecute_sp;
 
     // Remove the allocation from above the guards
     CallProjections callprojs;

@@ -4947,10 +4949,11 @@
   Node* src_offset  = argument(1);  // type: int
   Node* dest        = argument(2);  // type: oop
   Node* dest_offset = argument(3);  // type: int
   Node* length      = argument(4);  // type: int
 
+  uint new_idx = C->unique();
 
   // Check for allocation before we add nodes that would confuse
   // tightly_coupled_allocation()
   AllocateArrayNode* alloc = tightly_coupled_allocation(dest, NULL);
 

@@ -5162,11 +5165,11 @@
                     Deoptimization::Action_make_not_entrant);
       assert(stopped(), "Should be stopped");
     }
   }
 
-  arraycopy_move_allocation_here(alloc, dest, saved_jvms, saved_reexecute_sp);
+  arraycopy_move_allocation_here(alloc, dest, saved_jvms, saved_reexecute_sp, new_idx);
 
   if (stopped()) {
     return true;
   }
 
< prev index next >