< prev index next >

src/share/vm/opto/library_call.cpp

Print this page

        

*** 40,49 **** --- 40,54 ---- #include "opto/runtime.hpp" #include "opto/subnode.hpp" #include "prims/nativeLookup.hpp" #include "runtime/sharedRuntime.hpp" #include "utilities/macros.hpp" + #if INCLUDE_ALL_GCS + #include "gc_implementation/shenandoah/shenandoahRuntime.hpp" + #include "gc_implementation/shenandoah/c2/shenandoahBarrierSetC2.hpp" + #include "gc_implementation/shenandoah/c2/shenandoahSupport.hpp" + #endif class LibraryIntrinsic : public InlineCallGenerator { // Extend the set of intrinsics known to the runtime: public: private:
*** 2428,2438 **** // is enabled, we need to log the value in the referent field in an SATB buffer. // This routine performs some compile time filters and generates suitable // runtime filters that guard the pre-barrier code. // Also add memory barrier for non volatile load from the referent field // to prevent commoning of loads across safepoint. ! if (!UseG1GC && !need_mem_bar) return; // Some compile time checks. // If offset is a constant, is it java_lang_ref_Reference::_reference_offset? --- 2433,2443 ---- // is enabled, we need to log the value in the referent field in an SATB buffer. // This routine performs some compile time filters and generates suitable // runtime filters that guard the pre-barrier code. // Also add memory barrier for non volatile load from the referent field // to prevent commoning of loads across safepoint. ! if (!(UseG1GC || UseShenandoahGC) && !need_mem_bar) return; // Some compile time checks. // If offset is a constant, is it java_lang_ref_Reference::_reference_offset?
*** 2685,2694 **** --- 2690,2707 ---- // the barriers get omitted and the unsafe reference begins to "pollute" // the alias analysis of the rest of the graph, either Compile::can_alias // or Compile::must_alias will throw a diagnostic assert.) bool need_mem_bar = (alias_type->adr_type() == TypeOopPtr::BOTTOM); + #if INCLUDE_ALL_GCS + // Work around JDK-8220714 bug. This is done for Shenandoah only, until + // the shared code fix is upstreamed and properly tested there. + if (UseShenandoahGC) { + need_mem_bar |= is_native_ptr; + } + #endif + // If we are reading the value of the referent field of a Reference // object (either by using Unsafe directly or through reflection) // then, if G1 is enabled, we need to record the referent in an // SATB log buffer using the pre-barrier mechanism. // Also we need to add memory barrier to prevent commoning reads
*** 2744,2753 **** --- 2757,2771 ---- if (!is_store) { MemNode::MemOrd mo = is_volatile ? MemNode::acquire : MemNode::unordered; // To be valid, unsafe loads may depend on other conditions than // the one that guards them: pin the Load node load = make_load(control(), adr, value_type, type, adr_type, mo, LoadNode::Pinned, is_volatile, unaligned, mismatched); + #if INCLUDE_ALL_GCS + if (UseShenandoahGC && (type == T_OBJECT || type == T_ARRAY)) { + load = ShenandoahBarrierSetC2::bsc2()->load_reference_barrier(this, load); + } + #endif // load value switch (type) { case T_BOOLEAN: case T_CHAR: case T_BYTE:
*** 2797,2806 **** --- 2815,2829 ---- } } if (is_volatile) { if (!is_store) { + #if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + load = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(load); + } + #endif Node* mb = insert_mem_bar(Op_MemBarAcquire, load); mb->as_MemBar()->set_trailing_load(); } else { if (!support_IRIW_for_not_multiple_copy_atomic_cpu) { Node* mb = insert_mem_bar(Op_MemBarVolatile, store);
*** 3109,3118 **** --- 3132,3146 ---- #ifdef _LP64 if (adr->bottom_type()->is_ptr_to_narrowoop()) { load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->get_ptr_type())); } #endif + #if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + load_store = ShenandoahBarrierSetC2::bsc2()->load_reference_barrier(this, load_store); + } + #endif if (can_move_pre_barrier()) { // Don't need to load pre_val. The old value is returned by load_store. // The pre_barrier can execute after the xchg as long as no safepoint // gets inserted between them. pre_barrier(false /* do_load */,
*** 4544,4553 **** --- 4572,4595 ---- // Compute the length also, if needed: Node* countx = size; countx = _gvn.transform(new (C) SubXNode(countx, MakeConX(base_off))); countx = _gvn.transform(new (C) URShiftXNode(countx, intcon(LogBytesPerLong) )); + #if INCLUDE_ALL_GCS + if (UseShenandoahGC && ShenandoahCloneBarrier) { + assert (src->is_AddP(), "for clone the src should be the interior ptr"); + assert (dest->is_AddP(), "for clone the dst should be the interior ptr"); + + // Make sure that references in the cloned object are updated for Shenandoah. + make_runtime_call(RC_LEAF|RC_NO_FP, + OptoRuntime::shenandoah_clone_barrier_Type(), + CAST_FROM_FN_PTR(address, ShenandoahRuntime::shenandoah_clone_barrier), + "shenandoah_clone_barrier", TypePtr::BOTTOM, + src->in(AddPNode::Base)); + } + #endif + const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; bool disjoint_bases = true; generate_unchecked_arraycopy(raw_adr_type, T_LONG, disjoint_bases, src, NULL, dest, NULL, countx, /*dest_uninitialized*/true);
*** 5280,5290 **** checked_value = cv; } // At this point we know we do not need type checks on oop stores. // Let's see if we need card marks: ! if (alloc != NULL && use_ReduceInitialCardMarks()) { // If we do not need card marks, copy using the jint or jlong stub. copy_type = LP64_ONLY(UseCompressedOops ? T_INT : T_LONG) NOT_LP64(T_INT); assert(type2aelembytes(basic_elem_type) == type2aelembytes(copy_type), "sizes agree"); } --- 5322,5332 ---- checked_value = cv; } // At this point we know we do not need type checks on oop stores. // Let's see if we need card marks: ! if (alloc != NULL && use_ReduceInitialCardMarks() && ! UseShenandoahGC) { // If we do not need card marks, copy using the jint or jlong stub. copy_type = LP64_ONLY(UseCompressedOops ? T_INT : T_LONG) NOT_LP64(T_INT); assert(type2aelembytes(basic_elem_type) == type2aelembytes(copy_type), "sizes agree"); }
*** 6316,6325 **** --- 6358,6373 ---- const TypeOopPtr* object_type = TypeOopPtr::make_from_klass(klass); Node* no_ctrl = NULL; Node* result = make_load(no_ctrl, adr, object_type, T_OBJECT, MemNode::unordered); + #if INCLUDE_ALL_GCS + if (UseShenandoahGC) { + result = ShenandoahBarrierSetC2::bsc2()->load_reference_barrier(this, result); + } + #endif + // Use the pre-barrier to record the value in the referent field pre_barrier(false /* do_load */, control(), NULL /* obj */, NULL /* adr */, max_juint /* alias_idx */, NULL /* val */, NULL /* val_type */, result /* pre_val */,
*** 6372,6381 **** --- 6420,6435 ---- leading_membar = insert_mem_bar(Op_MemBarVolatile); // StoreLoad barrier } // Build the load. MemNode::MemOrd mo = is_vol ? MemNode::acquire : MemNode::unordered; Node* loadedField = make_load(NULL, adr, type, bt, adr_type, mo, LoadNode::DependsOnlyOnTest, is_vol); + #if INCLUDE_ALL_GCS + if (UseShenandoahGC && (bt == T_OBJECT || bt == T_ARRAY)) { + loadedField = ShenandoahBarrierSetC2::bsc2()->load_reference_barrier(this, loadedField); + } + #endif + // If reference is volatile, prevent following memory ops from // floating up past the volatile read. Also prevents commoning // another volatile read. if (is_vol) { // Memory barrier includes bogus read of value to force load BEFORE membar
< prev index next >