# HG changeset patch # User rkennke # Date 1556809924 -7200 # Thu May 02 17:12:04 2019 +0200 # Node ID 055f40da9497dfcd5329439491c0757bac0b392a # Parent fc7627bf4b01b9a64b99a434ac523f1c7d6fcb37 8223244: Fix usage of ARRAYCOPY_DISJOINT decorator diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -1788,7 +1788,9 @@ } #endif //ASSERT - DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_CHECKCAST; + // Note: checkcast arraycopy is always disjoint. If it were not, then we wouldn't + // need to checkcast. + DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_CHECKCAST | ARRAYCOPY_DISJOINT; bool is_oop = true; if (dest_uninitialized) { decorators |= IS_DEST_UNINITIALIZED; diff --git a/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.cpp --- a/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.cpp @@ -36,12 +36,14 @@ if (type == T_OBJECT || type == T_ARRAY) { #ifdef _LP64 - if (!checkcast && !obj_int) { - // Save count for barrier - __ movptr(r11, count); - } else if (disjoint && obj_int) { - // Save dst in r11 in the disjoint case - __ movq(r11, dst); + if (!checkcast) { + if (!obj_int) { + // Save count for barrier + __ movptr(r11, count); + } else if (disjoint) { + // Save dst in r11 in the disjoint case + __ movq(r11, dst); + } } #else if (disjoint) { @@ -61,13 +63,15 @@ if (type == T_OBJECT || type == T_ARRAY) { #ifdef _LP64 - if (!checkcast && !obj_int) { - // Save count for barrier - count = r11; - } else if (disjoint && obj_int) { - // Use the saved dst in the disjoint case - dst = r11; - } else if (checkcast) { + if (!checkcast) { + if (!obj_int) { + // Save count for barrier + count = r11; + } else if (disjoint) { + // Use the saved dst in the disjoint case + dst = r11; + } + } else { tmp = rscratch1; } #else diff --git a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp --- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp @@ -53,12 +53,14 @@ if (type == T_OBJECT || type == T_ARRAY) { #ifdef _LP64 - if (!checkcast && !obj_int) { - // Save count for barrier - __ movptr(r11, count); - } else if (disjoint && obj_int) { - // Save dst in r11 in the disjoint case - __ movq(r11, dst); + if (!checkcast) { + if (!obj_int) { + // Save count for barrier + __ movptr(r11, count); + } else if (disjoint) { + // Save dst in r11 in the disjoint case + __ movq(r11, dst); + } } #else if (disjoint) { @@ -123,13 +125,15 @@ if (type == T_OBJECT || type == T_ARRAY) { #ifdef _LP64 - if (!checkcast && !obj_int) { - // Save count for barrier - count = r11; - } else if (disjoint && obj_int) { - // Use the saved dst in the disjoint case - dst = r11; - } else if (checkcast) { + if (!checkcast) { + if (!obj_int) { + // Save count for barrier + count = r11; + } else if (disjoint && obj_int) { + // Use the saved dst in the disjoint case + dst = r11; + } + } else { tmp = rscratch1; } #else diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp --- a/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp @@ -1372,7 +1372,9 @@ Address to_element_addr(end_to, count, Address::times_ptr, 0); Address elem_klass_addr(elem, oopDesc::klass_offset_in_bytes()); - DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_CHECKCAST; + // Note: checkcast arraycopy is always disjoint. If it were not, then we wouldn't + // need to checkcast. + DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_CHECKCAST | ARRAYCOPY_DISJOINT; if (dest_uninitialized) { decorators |= IS_DEST_UNINITIALIZED; } diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp --- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp @@ -2149,7 +2149,7 @@ // r9 is used to save r15_thread // 'from', 'to' and 'qword_count' are now valid - DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_DISJOINT; + DecoratorSet decorators = IN_HEAP | IS_ARRAY; if (dest_uninitialized) { decorators |= IS_DEST_UNINITIALIZED; } @@ -2343,7 +2343,9 @@ Address from_element_addr(end_from, count, TIMES_OOP, 0); Address to_element_addr(end_to, count, TIMES_OOP, 0); - DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_CHECKCAST; + // Note: checkcast arraycopy is always disjoint. If it were not, then we wouldn't + // need to checkcast. + DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_CHECKCAST | ARRAYCOPY_DISJOINT; if (dest_uninitialized) { decorators |= IS_DEST_UNINITIALIZED; } diff --git a/src/hotspot/share/runtime/stubRoutines.hpp b/src/hotspot/share/runtime/stubRoutines.hpp --- a/src/hotspot/share/runtime/stubRoutines.hpp +++ b/src/hotspot/share/runtime/stubRoutines.hpp @@ -311,6 +311,7 @@ return dest_uninitialized ? _arrayof_oop_disjoint_arraycopy_uninit : _arrayof_oop_disjoint_arraycopy; } + // Note: checkcast arraycopy is always disjoint. Otherwise we wouldn't need to checkcast. static address checkcast_arraycopy(bool dest_uninitialized = false) { return dest_uninitialized ? _checkcast_arraycopy_uninit : _checkcast_arraycopy; } # HG changeset patch # User rkennke # Date 1558612371 -7200 # Thu May 23 13:52:51 2019 +0200 # Node ID 044536bb4717beacd0d6cde5ebba53133b42b3c9 # Parent 055f40da9497dfcd5329439491c0757bac0b392a 8224667: Shenandoah: Post-LRB cleanup diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp @@ -294,7 +294,7 @@ call->as_CallLeaf()->entry_point() == CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre_entry); } -bool ShenandoahBarrierSetC2::is_shenandoah_wb_call(Node* call) { +bool ShenandoahBarrierSetC2::is_shenandoah_lrb_call(Node* call) { return call->is_CallLeaf() && call->as_CallLeaf()->entry_point() == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_JRT); } @@ -471,7 +471,7 @@ return TypeFunc::make(domain, range); } -const TypeFunc* ShenandoahBarrierSetC2::shenandoah_write_barrier_Type() { +const TypeFunc* ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type() { const Type **fields = TypeTuple::fields(1); fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields); diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp @@ -93,7 +93,7 @@ static ShenandoahBarrierSetC2* bsc2(); static bool is_shenandoah_wb_pre_call(Node* call); - static bool is_shenandoah_wb_call(Node* call); + static bool is_shenandoah_lrb_call(Node* call); static bool is_shenandoah_marking_if(PhaseTransform *phase, Node* n); static bool is_shenandoah_state_load(Node* n); static bool has_only_shenandoah_wb_pre_uses(Node* n); @@ -102,7 +102,7 @@ static const TypeFunc* write_ref_field_pre_entry_Type(); static const TypeFunc* shenandoah_clone_barrier_Type(); - static const TypeFunc* shenandoah_write_barrier_Type(); + static const TypeFunc* shenandoah_load_reference_barrier_Type(); virtual bool has_load_barriers() const { return true; } // This is the entry-point for the backend to perform accesses through the Access API. diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp @@ -1093,7 +1093,7 @@ mm->set_memory_at(Compile::AliasIdxRaw, raw_mem); phase->register_new_node(mm, ctrl); - Node* call = new CallLeafNode(ShenandoahBarrierSetC2::shenandoah_write_barrier_Type(), CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_JRT), "shenandoah_write_barrier", TypeRawPtr::BOTTOM); + Node* call = new CallLeafNode(ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type(), CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_JRT), "shenandoah_load_reference_barrier", TypeRawPtr::BOTTOM); call->init_req(TypeFunc::Control, ctrl); call->init_req(TypeFunc::I_O, phase->C->top()); call->init_req(TypeFunc::Memory, mm); @@ -1535,7 +1535,7 @@ val_phi->init_req(_not_equal, fwd); raw_mem_phi->init_req(_not_equal, raw_mem); - // Call wb-stub and wire up that path in slots 4 + // Call lrb-stub and wire up that path in slots 4 Node* result_mem = NULL; ctrl = if_eq; call_lrb_stub(ctrl, fwd, result_mem, raw_mem, phase); @@ -1979,7 +1979,7 @@ nodes.push(root); for (uint next = 0; next < nodes.size(); next++) { Node *n = nodes.at(next); - if (ShenandoahBarrierSetC2::is_shenandoah_wb_call(n)) { + if (ShenandoahBarrierSetC2::is_shenandoah_lrb_call(n)) { controls.push(n); if (trace) { tty->print("XXXXXX verifying"); n->dump(); } for (uint next2 = 0; next2 < controls.size(); next2++) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp @@ -41,7 +41,7 @@ class ShenandoahBarrierSetC1; class ShenandoahBarrierSetC2; -template +template class ShenandoahUpdateRefsForOopClosure: public BasicOopIterateClosure { private: ShenandoahHeap* _heap; @@ -50,7 +50,7 @@ template inline void do_oop_work(T* p) { oop o; - if (STOREVAL_WRITE_BARRIER) { + if (STOREVAL_EVAC_BARRIER) { o = _heap->evac_update_with_forwarded(p); if (!CompressedOops::is_null(o)) { _bs->enqueue(o); @@ -96,10 +96,10 @@ return true; } -template +template void ShenandoahBarrierSet::write_ref_array_loop(HeapWord* start, size_t count) { assert(UseShenandoahGC && ShenandoahCloneBarrier, "should be enabled"); - ShenandoahUpdateRefsForOopClosure cl; + ShenandoahUpdateRefsForOopClosure cl; T* dst = (T*) start; for (size_t i = 0; i < count; i++) { cl.do_oop(dst++); @@ -113,15 +113,15 @@ if (_heap->is_concurrent_traversal_in_progress()) { ShenandoahEvacOOMScope oom_evac_scope; if (UseCompressedOops) { - write_ref_array_loop(start, count); + write_ref_array_loop(start, count); } else { - write_ref_array_loop(start, count); + write_ref_array_loop(start, count); } } else { if (UseCompressedOops) { - write_ref_array_loop(start, count); + write_ref_array_loop(start, count); } else { - write_ref_array_loop(start, count); + write_ref_array_loop(start, count); } } } @@ -206,10 +206,10 @@ shenandoah_assert_correct(NULL, obj); if (_heap->is_concurrent_traversal_in_progress()) { ShenandoahEvacOOMScope oom_evac_scope; - ShenandoahUpdateRefsForOopClosure cl; + ShenandoahUpdateRefsForOopClosure cl; obj->oop_iterate(&cl); } else { - ShenandoahUpdateRefsForOopClosure cl; + ShenandoahUpdateRefsForOopClosure cl; obj->oop_iterate(&cl); } } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp @@ -35,8 +35,8 @@ private: enum ArrayCopyStoreValMode { NONE, - READ_BARRIER, - WRITE_BARRIER + RESOLVE_BARRIER, + EVAC_BARRIER }; ShenandoahHeap* _heap; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp @@ -199,10 +199,10 @@ switch (storeval_mode) { case NONE: return arraycopy_loop(src, dst, length, bound, disjoint); - case READ_BARRIER: - return arraycopy_loop(src, dst, length, bound, disjoint); - case WRITE_BARRIER: - return arraycopy_loop(src, dst, length, bound, disjoint); + case RESOLVE_BARRIER: + return arraycopy_loop(src, dst, length, bound, disjoint); + case EVAC_BARRIER: + return arraycopy_loop(src, dst, length, bound, disjoint); default: ShouldNotReachHere(); return true; // happy compiler @@ -268,8 +268,8 @@ switch (STOREVAL_MODE) { case NONE: break; - case READ_BARRIER: - case WRITE_BARRIER: + case RESOLVE_BARRIER: + case EVAC_BARRIER: // The write-barrier case cannot really happen. It's traversal-only and traversal // doesn't currently use SATB. And even if it did, it would not be fatal to just do the normal RB here. prev_obj = ShenandoahBarrierSet::resolve_forwarded_not_null(prev_obj); @@ -293,10 +293,10 @@ switch (STOREVAL_MODE) { case NONE: break; - case READ_BARRIER: + case RESOLVE_BARRIER: obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); break; - case WRITE_BARRIER: + case EVAC_BARRIER: if (_heap->in_collection_set(obj)) { oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); if (oopDesc::equals_raw(forw, obj)) { @@ -337,9 +337,9 @@ ArrayCopyStoreValMode storeval_mode; if (heap->has_forwarded_objects()) { if (heap->is_concurrent_traversal_in_progress()) { - storeval_mode = WRITE_BARRIER; + storeval_mode = EVAC_BARRIER; } else if (heap->is_update_refs_in_progress()) { - storeval_mode = READ_BARRIER; + storeval_mode = RESOLVE_BARRIER; } else { assert(heap->is_idle() || heap->is_evacuation_in_progress(), "must not have anything in progress"); storeval_mode = NONE; // E.g. during evac or outside cycle