--- old/src/hotspot/share/gc/shared/modRefBarrierSet.inline.hpp 2019-09-26 16:22:07.421542242 +0200 +++ new/src/hotspot/share/gc/shared/modRefBarrierSet.inline.hpp 2019-09-26 16:22:07.165537850 +0200 @@ -31,6 +31,7 @@ #include "oops/klass.inline.hpp" #include "oops/objArrayOop.hpp" #include "oops/oop.hpp" +#include "oops/valueKlass.hpp" // count is number of array elements being written void ModRefBarrierSet::write_ref_array(HeapWord* start, size_t count) { @@ -152,4 +153,36 @@ bs->write_region(MemRegion((HeapWord*)(void*)dst, size)); } +template +inline void ModRefBarrierSet::AccessBarrier:: +value_copy_in_heap(void* src, void* dst, ValueKlass* md) { + if (HasDecorator::value || (!md->contains_oops())) { + Raw::value_copy(src, dst, md); + } else { + BarrierSetT* bs = barrier_set_cast(BarrierSet::barrier_set()); + // src/dst aren't oops, need offset to adjust oop map offset + const address dst_oop_addr_offset = ((address) dst) - md->first_field_offset(); + typedef typename ValueOopType::type OopType; + + // Pre-barriers... + OopMapBlock* map = md->start_of_nonstatic_oop_maps(); + OopMapBlock* const end = map + md->nonstatic_oop_map_count(); + while (map != end) { + address doop_address = dst_oop_addr_offset + map->offset(); + bs->write_ref_array_pre((OopType*) doop_address, map->count(), false); + map++; + } + + Raw::value_copy(src, dst, md); + + // Post-barriers... + map = md->start_of_nonstatic_oop_maps(); + while (map != end) { + address doop_address = dst_oop_addr_offset + map->offset(); + bs->write_ref_array((HeapWord*) doop_address, map->count()); + map++; + } + } +} + #endif // SHARE_GC_SHARED_MODREFBARRIERSET_INLINE_HPP