src/hotspot/share/gc/z/zBarrierSet.inline.hpp
changeset 50525 767cdb97f103
child 50875 2217b2fc29ea
equal deleted inserted replaced
50524:04f4e983c2f7 50525:767cdb97f103
       
     1 /*
       
     2  * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 #ifndef SHARE_GC_Z_ZBARRIERSET_INLINE_HPP
       
    25 #define SHARE_GC_Z_ZBARRIERSET_INLINE_HPP
       
    26 
       
    27 #include "gc/shared/accessBarrierSupport.inline.hpp"
       
    28 #include "gc/z/zBarrier.inline.hpp"
       
    29 #include "gc/z/zBarrierSet.hpp"
       
    30 #include "utilities/debug.hpp"
       
    31 
       
    32 template <DecoratorSet decorators, typename BarrierSetT>
       
    33 template <DecoratorSet expected>
       
    34 inline void ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::verify_decorators_present() {
       
    35   if ((decorators & expected) == 0) {
       
    36     fatal("Using unsupported access decorators");
       
    37   }
       
    38 }
       
    39 
       
    40 template <DecoratorSet decorators, typename BarrierSetT>
       
    41 template <DecoratorSet expected>
       
    42 inline void ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::verify_decorators_absent() {
       
    43   if ((decorators & expected) != 0) {
       
    44     fatal("Using unsupported access decorators");
       
    45   }
       
    46 }
       
    47 
       
    48 template <DecoratorSet decorators, typename BarrierSetT>
       
    49 inline oop* ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::field_addr(oop base, ptrdiff_t offset) {
       
    50   assert(base != NULL, "Invalid base");
       
    51   return reinterpret_cast<oop*>(reinterpret_cast<intptr_t>((void*)base) + offset);
       
    52 }
       
    53 
       
    54 template <DecoratorSet decorators, typename BarrierSetT>
       
    55 template <typename T>
       
    56 inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::load_barrier_on_oop_field_preloaded(T* addr, oop o) {
       
    57   verify_decorators_absent<ON_UNKNOWN_OOP_REF>();
       
    58 
       
    59   if (HasDecorator<decorators, AS_NO_KEEPALIVE>::value) {
       
    60     if (HasDecorator<decorators, ON_STRONG_OOP_REF>::value) {
       
    61       return ZBarrier::weak_load_barrier_on_oop_field_preloaded(addr, o);
       
    62     } else if (HasDecorator<decorators, ON_WEAK_OOP_REF>::value) {
       
    63       return ZBarrier::weak_load_barrier_on_weak_oop_field_preloaded(addr, o);
       
    64     } else {
       
    65       return ZBarrier::weak_load_barrier_on_phantom_oop_field_preloaded(addr, o);
       
    66     }
       
    67   } else {
       
    68     if (HasDecorator<decorators, ON_STRONG_OOP_REF>::value) {
       
    69       return ZBarrier::load_barrier_on_oop_field_preloaded(addr, o);
       
    70     } else if (HasDecorator<decorators, ON_WEAK_OOP_REF>::value) {
       
    71       return ZBarrier::load_barrier_on_weak_oop_field_preloaded(addr, o);
       
    72     } else {
       
    73       return ZBarrier::load_barrier_on_phantom_oop_field_preloaded(addr, o);
       
    74     }
       
    75   }
       
    76 }
       
    77 
       
    78 template <DecoratorSet decorators, typename BarrierSetT>
       
    79 template <typename T>
       
    80 inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::load_barrier_on_unknown_oop_field_preloaded(oop base, ptrdiff_t offset, T* addr, oop o) {
       
    81   verify_decorators_present<ON_UNKNOWN_OOP_REF>();
       
    82 
       
    83   const DecoratorSet decorators_known_strength =
       
    84     AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset);
       
    85 
       
    86   if (HasDecorator<decorators, AS_NO_KEEPALIVE>::value) {
       
    87     if (decorators_known_strength & ON_STRONG_OOP_REF) {
       
    88       return ZBarrier::weak_load_barrier_on_oop_field_preloaded(addr, o);
       
    89     } else if (decorators_known_strength & ON_WEAK_OOP_REF) {
       
    90       return ZBarrier::weak_load_barrier_on_weak_oop_field_preloaded(addr, o);
       
    91     } else {
       
    92       return ZBarrier::weak_load_barrier_on_phantom_oop_field_preloaded(addr, o);
       
    93     }
       
    94   } else {
       
    95     if (decorators_known_strength & ON_STRONG_OOP_REF) {
       
    96       return ZBarrier::load_barrier_on_oop_field_preloaded(addr, o);
       
    97     } else if (decorators_known_strength & ON_WEAK_OOP_REF) {
       
    98       return ZBarrier::load_barrier_on_weak_oop_field_preloaded(addr, o);
       
    99     } else {
       
   100       return ZBarrier::load_barrier_on_phantom_oop_field_preloaded(addr, o);
       
   101     }
       
   102   }
       
   103 }
       
   104 
       
   105 //
       
   106 // In heap
       
   107 //
       
   108 template <DecoratorSet decorators, typename BarrierSetT>
       
   109 template <typename T>
       
   110 inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_load_in_heap(T* addr) {
       
   111   verify_decorators_absent<ON_UNKNOWN_OOP_REF>();
       
   112 
       
   113   const oop o = Raw::oop_load_in_heap(addr);
       
   114   return load_barrier_on_oop_field_preloaded(addr, o);
       
   115 }
       
   116 
       
   117 template <DecoratorSet decorators, typename BarrierSetT>
       
   118 inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_load_in_heap_at(oop base, ptrdiff_t offset) {
       
   119   oop* const addr = field_addr(base, offset);
       
   120   const oop o = Raw::oop_load_in_heap(addr);
       
   121 
       
   122   if (HasDecorator<decorators, ON_UNKNOWN_OOP_REF>::value) {
       
   123     return load_barrier_on_unknown_oop_field_preloaded(base, offset, addr, o);
       
   124   }
       
   125 
       
   126   return load_barrier_on_oop_field_preloaded(addr, o);
       
   127 }
       
   128 
       
   129 template <DecoratorSet decorators, typename BarrierSetT>
       
   130 template <typename T>
       
   131 inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_cmpxchg_in_heap(oop new_value, T* addr, oop compare_value) {
       
   132   verify_decorators_present<ON_STRONG_OOP_REF>();
       
   133   verify_decorators_absent<AS_NO_KEEPALIVE>();
       
   134 
       
   135   ZBarrier::load_barrier_on_oop_field(addr);
       
   136   return Raw::oop_atomic_cmpxchg_in_heap(new_value, addr, compare_value);
       
   137 }
       
   138 
       
   139 template <DecoratorSet decorators, typename BarrierSetT>
       
   140 inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_cmpxchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset, oop compare_value) {
       
   141   verify_decorators_present<ON_STRONG_OOP_REF | ON_UNKNOWN_OOP_REF>();
       
   142   verify_decorators_absent<AS_NO_KEEPALIVE>();
       
   143 
       
   144   // Through Unsafe.CompareAndExchangeObject()/CompareAndSetObject() we can recieve
       
   145   // calls with ON_UNKNOWN_OOP_REF set. However, we treat these as ON_STRONG_OOP_REF,
       
   146   // with the motivation that if you're doing Unsafe operations on a Reference.referent
       
   147   // field, then you're on your own anyway.
       
   148   ZBarrier::load_barrier_on_oop_field(field_addr(base, offset));
       
   149   return Raw::oop_atomic_cmpxchg_in_heap_at(new_value, base, offset, compare_value);
       
   150 }
       
   151 
       
   152 template <DecoratorSet decorators, typename BarrierSetT>
       
   153 template <typename T>
       
   154 inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_xchg_in_heap(oop new_value, T* addr) {
       
   155   verify_decorators_present<ON_STRONG_OOP_REF>();
       
   156   verify_decorators_absent<AS_NO_KEEPALIVE>();
       
   157 
       
   158   const oop o = Raw::oop_atomic_xchg_in_heap(new_value, addr);
       
   159   return ZBarrier::load_barrier_on_oop(o);
       
   160 }
       
   161 
       
   162 template <DecoratorSet decorators, typename BarrierSetT>
       
   163 inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_xchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset) {
       
   164   verify_decorators_present<ON_STRONG_OOP_REF>();
       
   165   verify_decorators_absent<AS_NO_KEEPALIVE>();
       
   166 
       
   167   const oop o = Raw::oop_atomic_xchg_in_heap_at(new_value, base, offset);
       
   168   return ZBarrier::load_barrier_on_oop(o);
       
   169 }
       
   170 
       
   171 template <DecoratorSet decorators, typename BarrierSetT>
       
   172 template <typename T>
       
   173 inline bool ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
       
   174                                                                                        arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
       
   175                                                                                        size_t length) {
       
   176   T* src = arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw);
       
   177   T* dst = arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw);
       
   178 
       
   179   if (!HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value) {
       
   180     // No check cast, bulk barrier and bulk copy
       
   181     ZBarrier::load_barrier_on_oop_array(src, length);
       
   182     return Raw::oop_arraycopy_in_heap(NULL, 0, src, NULL, 0, dst, length);
       
   183   }
       
   184 
       
   185   // Check cast and copy each elements
       
   186   Klass* const dst_klass = objArrayOop(dst_obj)->element_klass();
       
   187   for (const T* const end = src + length; src < end; src++, dst++) {
       
   188     const oop elem = ZBarrier::load_barrier_on_oop_field(src);
       
   189     if (!oopDesc::is_instanceof_or_null(elem, dst_klass)) {
       
   190       // Check cast failed
       
   191       return false;
       
   192     }
       
   193 
       
   194     // Cast is safe, since we know it's never a narrowOop
       
   195     *(oop*)dst = elem;
       
   196   }
       
   197 
       
   198   return true;
       
   199 }
       
   200 
       
   201 template <DecoratorSet decorators, typename BarrierSetT>
       
   202 inline void ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::clone_in_heap(oop src, oop dst, size_t size) {
       
   203   ZBarrier::load_barrier_on_oop_fields(src);
       
   204   Raw::clone_in_heap(src, dst, size);
       
   205 }
       
   206 
       
   207 //
       
   208 // Not in heap
       
   209 //
       
   210 template <DecoratorSet decorators, typename BarrierSetT>
       
   211 template <typename T>
       
   212 inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_load_not_in_heap(T* addr) {
       
   213   const oop o = Raw::oop_load_not_in_heap(addr);
       
   214 
       
   215   if (HasDecorator<decorators, ON_PHANTOM_OOP_REF>::value) {
       
   216     return load_barrier_on_oop_field_preloaded(addr, o);
       
   217   }
       
   218 
       
   219   verify_decorators_present<ON_STRONG_OOP_REF>();
       
   220   verify_decorators_absent<AS_NO_KEEPALIVE>();
       
   221 
       
   222   return o;
       
   223 }
       
   224 
       
   225 template <DecoratorSet decorators, typename BarrierSetT>
       
   226 template <typename T>
       
   227 inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_cmpxchg_not_in_heap(oop new_value, T* addr, oop compare_value) {
       
   228   verify_decorators_present<ON_STRONG_OOP_REF>();
       
   229   verify_decorators_absent<AS_NO_KEEPALIVE>();
       
   230 
       
   231   return Raw::oop_atomic_cmpxchg_not_in_heap(new_value, addr, compare_value);
       
   232 }
       
   233 
       
   234 template <DecoratorSet decorators, typename BarrierSetT>
       
   235 template <typename T>
       
   236 inline oop ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_atomic_xchg_not_in_heap(oop new_value, T* addr) {
       
   237   verify_decorators_present<ON_STRONG_OOP_REF>();
       
   238   verify_decorators_absent<AS_NO_KEEPALIVE>();
       
   239 
       
   240   return Raw::oop_atomic_xchg_not_in_heap(new_value, addr);
       
   241 }
       
   242 
       
   243 #endif // SHARE_GC_Z_ZBARRIERSET_INLINE_HPP