Path: blob/master/src/hotspot/share/gc/z/zBarrierSet.inline.hpp
40957 views
/*1* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223#ifndef SHARE_GC_Z_ZBARRIERSET_INLINE_HPP24#define SHARE_GC_Z_ZBARRIERSET_INLINE_HPP2526#include "gc/z/zBarrierSet.hpp"2728#include "gc/shared/accessBarrierSupport.inline.hpp"29#include "gc/z/zBarrier.inline.hpp"30#include "utilities/debug.hpp"3132template <DecoratorSet decorators, typename BarrierSetT>33template <DecoratorSet expected>34inline void ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::verify_decorators_present() {35if ((decorators & expected) == 0) {36fatal("Using unsupported access decorators");37}38}3940template <DecoratorSet decorators, typename BarrierSetT>41template <DecoratorSet expected>42inline void ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::verify_decorators_absent() {43if ((decorators & expected) != 0) {44fatal("Using unsupported access decorators");45}46}4748template <DecoratorSet decorators, typename BarrierSetT>49inline oop* ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::field_addr(oop base, ptrdiff_t offset) {50assert(base != NULL, "Invalid base");51return reinterpret_cast<oop*>(reinterpret_cast<intptr_t>((void*)base) + offset);52}5354template <DecoratorSet decorators, typename BarrierSetT>55template <typename T>56inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::load_barrier_on_oop_field_preloaded(T* addr, oop o) {57verify_decorators_absent<ON_UNKNOWN_OOP_REF>();5859if (HasDecorator<decorators, AS_NO_KEEPALIVE>::value) {60if (HasDecorator<decorators, ON_STRONG_OOP_REF>::value) {61return ZBarrier::weak_load_barrier_on_oop_field_preloaded(addr, o);62} else if (HasDecorator<decorators, ON_WEAK_OOP_REF>::value) {63return ZBarrier::weak_load_barrier_on_weak_oop_field_preloaded(addr, o);64} else {65assert((HasDecorator<decorators, ON_PHANTOM_OOP_REF>::value), "Must be");66return ZBarrier::weak_load_barrier_on_phantom_oop_field_preloaded(addr, o);67}68} else {69if (HasDecorator<decorators, ON_STRONG_OOP_REF>::value) {70return ZBarrier::load_barrier_on_oop_field_preloaded(addr, o);71} else if (HasDecorator<decorators, ON_WEAK_OOP_REF>::value) {72return ZBarrier::load_barrier_on_weak_oop_field_preloaded(addr, o);73} else {74assert((HasDecorator<decorators, ON_PHANTOM_OOP_REF>::value), "Must be");75return ZBarrier::load_barrier_on_phantom_oop_field_preloaded(addr, o);76}77}78}7980template <DecoratorSet decorators, typename BarrierSetT>81template <typename T>82inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::load_barrier_on_unknown_oop_field_preloaded(oop base, ptrdiff_t offset, T* addr, oop o) {83verify_decorators_present<ON_UNKNOWN_OOP_REF>();8485const DecoratorSet decorators_known_strength =86AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset);8788if (HasDecorator<decorators, AS_NO_KEEPALIVE>::value) {89if (decorators_known_strength & ON_STRONG_OOP_REF) {90return ZBarrier::weak_load_barrier_on_oop_field_preloaded(addr, o);91} else if (decorators_known_strength & ON_WEAK_OOP_REF) {92return ZBarrier::weak_load_barrier_on_weak_oop_field_preloaded(addr, o);93} else {94assert(decorators_known_strength & ON_PHANTOM_OOP_REF, "Must be");95return ZBarrier::weak_load_barrier_on_phantom_oop_field_preloaded(addr, o);96}97} else {98if (decorators_known_strength & ON_STRONG_OOP_REF) {99return ZBarrier::load_barrier_on_oop_field_preloaded(addr, o);100} else if (decorators_known_strength & ON_WEAK_OOP_REF) {101return ZBarrier::load_barrier_on_weak_oop_field_preloaded(addr, o);102} else {103assert(decorators_known_strength & ON_PHANTOM_OOP_REF, "Must be");104return ZBarrier::load_barrier_on_phantom_oop_field_preloaded(addr, o);105}106}107}108109//110// In heap111//112template <DecoratorSet decorators, typename BarrierSetT>113template <typename T>114inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_load_in_heap(T* addr) {115verify_decorators_absent<ON_UNKNOWN_OOP_REF>();116117const oop o = Raw::oop_load_in_heap(addr);118return load_barrier_on_oop_field_preloaded(addr, o);119}120121template <DecoratorSet decorators, typename BarrierSetT>122inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_load_in_heap_at(oop base, ptrdiff_t offset) {123oop* const addr = field_addr(base, offset);124const oop o = Raw::oop_load_in_heap(addr);125126if (HasDecorator<decorators, ON_UNKNOWN_OOP_REF>::value) {127return load_barrier_on_unknown_oop_field_preloaded(base, offset, addr, o);128}129130return load_barrier_on_oop_field_preloaded(addr, o);131}132133template <DecoratorSet decorators, typename BarrierSetT>134template <typename T>135inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_cmpxchg_in_heap(T* addr, oop compare_value, oop new_value) {136verify_decorators_present<ON_STRONG_OOP_REF>();137verify_decorators_absent<AS_NO_KEEPALIVE>();138139ZBarrier::load_barrier_on_oop_field(addr);140return Raw::oop_atomic_cmpxchg_in_heap(addr, compare_value, new_value);141}142143template <DecoratorSet decorators, typename BarrierSetT>144inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_cmpxchg_in_heap_at(oop base, ptrdiff_t offset, oop compare_value, oop new_value) {145verify_decorators_present<ON_STRONG_OOP_REF | ON_UNKNOWN_OOP_REF>();146verify_decorators_absent<AS_NO_KEEPALIVE>();147148// Through Unsafe.CompareAndExchangeObject()/CompareAndSetObject() we can receive149// calls with ON_UNKNOWN_OOP_REF set. However, we treat these as ON_STRONG_OOP_REF,150// with the motivation that if you're doing Unsafe operations on a Reference.referent151// field, then you're on your own anyway.152ZBarrier::load_barrier_on_oop_field(field_addr(base, offset));153return Raw::oop_atomic_cmpxchg_in_heap_at(base, offset, compare_value, new_value);154}155156template <DecoratorSet decorators, typename BarrierSetT>157template <typename T>158inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_xchg_in_heap(T* addr, oop new_value) {159verify_decorators_present<ON_STRONG_OOP_REF>();160verify_decorators_absent<AS_NO_KEEPALIVE>();161162const oop o = Raw::oop_atomic_xchg_in_heap(addr, new_value);163return ZBarrier::load_barrier_on_oop(o);164}165166template <DecoratorSet decorators, typename BarrierSetT>167inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_xchg_in_heap_at(oop base, ptrdiff_t offset, oop new_value) {168verify_decorators_present<ON_STRONG_OOP_REF>();169verify_decorators_absent<AS_NO_KEEPALIVE>();170171const oop o = Raw::oop_atomic_xchg_in_heap_at(base, offset, new_value);172return ZBarrier::load_barrier_on_oop(o);173}174175template <DecoratorSet decorators, typename BarrierSetT>176template <typename T>177inline bool ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,178arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,179size_t length) {180T* src = arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw);181T* dst = arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw);182183if (!HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value) {184// No check cast, bulk barrier and bulk copy185ZBarrier::load_barrier_on_oop_array(src, length);186return Raw::oop_arraycopy_in_heap(NULL, 0, src, NULL, 0, dst, length);187}188189// Check cast and copy each elements190Klass* const dst_klass = objArrayOop(dst_obj)->element_klass();191for (const T* const end = src + length; src < end; src++, dst++) {192const oop elem = ZBarrier::load_barrier_on_oop_field(src);193if (!oopDesc::is_instanceof_or_null(elem, dst_klass)) {194// Check cast failed195return false;196}197198// Cast is safe, since we know it's never a narrowOop199*(oop*)dst = elem;200}201202return true;203}204205template <DecoratorSet decorators, typename BarrierSetT>206inline void ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::clone_in_heap(oop src, oop dst, size_t size) {207ZBarrier::load_barrier_on_oop_fields(src);208Raw::clone_in_heap(src, dst, size);209}210211//212// Not in heap213//214template <DecoratorSet decorators, typename BarrierSetT>215template <typename T>216inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_load_not_in_heap(T* addr) {217verify_decorators_absent<ON_UNKNOWN_OOP_REF>();218219const oop o = Raw::oop_load_not_in_heap(addr);220return load_barrier_on_oop_field_preloaded(addr, o);221}222223template <DecoratorSet decorators, typename BarrierSetT>224template <typename T>225inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_cmpxchg_not_in_heap(T* addr, oop compare_value, oop new_value) {226verify_decorators_present<ON_STRONG_OOP_REF>();227verify_decorators_absent<AS_NO_KEEPALIVE>();228229return Raw::oop_atomic_cmpxchg_not_in_heap(addr, compare_value, new_value);230}231232template <DecoratorSet decorators, typename BarrierSetT>233template <typename T>234inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_xchg_not_in_heap(T* addr, oop new_value) {235verify_decorators_present<ON_STRONG_OOP_REF>();236verify_decorators_absent<AS_NO_KEEPALIVE>();237238return Raw::oop_atomic_xchg_not_in_heap(addr, new_value);239}240241#endif // SHARE_GC_Z_ZBARRIERSET_INLINE_HPP242243244