1 /*
   2  * Copyright (c) 2000, 2015, 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 
  25 #ifndef SHARE_VM_GC_SHARED_MODREFBARRIERSET_HPP
  26 #define SHARE_VM_GC_SHARED_MODREFBARRIERSET_HPP
  27 
  28 #include "gc/shared/barrierSet.hpp"
  29 #include "memory/memRegion.hpp"
  30 
  31 class Klass;
  32 
  33 class ModRefBarrierSet: public BarrierSet {
  34 protected:
  35   ModRefBarrierSet(const BarrierSet::FakeRtti& fake_rtti)
  36     : BarrierSet(fake_rtti.add_tag(BarrierSet::ModRef)) { }
  37   ~ModRefBarrierSet() { }
  38 
  39   virtual void write_ref_array_region(MemRegion mr) = 0;
  40 
  41   // These methods serve the only purpose of speeding up build times by reducing
  42   // included files
  43   static Klass* bound_for_array(oop obj);
  44   static bool is_bounded_by(oop obj, Klass* klass);
  45 
  46 public:
  47   // Causes all refs in "mr" to be assumed to be modified.
  48   virtual void invalidate(MemRegion mr) = 0;
  49 
  50   // Operations on arrays, or general regions (e.g., for "clone") may be
  51   // optimized by some barriers.
  52 
  53   // Below length is the # array elements being written
  54   virtual void write_ref_array_pre(oop* dst, int length,
  55                                    bool dest_uninitialized = false) {}
  56   virtual void write_ref_array_pre(narrowOop* dst, int length,
  57                                    bool dest_uninitialized = false) {}
  58   // Below count is the # array elements being written, starting
  59   // at the address "start", which may not necessarily be HeapWord-aligned
  60   inline void write_ref_array(HeapWord* start, size_t count);
  61 
  62   // Static versions, suitable for calling from generated code;
  63   // count is # array elements being written, starting with "start",
  64   // which may not necessarily be HeapWord-aligned.
  65   static void static_write_ref_array_pre(HeapWord* start, size_t count);
  66   static void static_write_ref_array_post(HeapWord* start, size_t count);
  67 
  68   template <DecoratorSet decorators>
  69   inline void write_ref_field_pre(void* addr) {}
  70 
  71   template <DecoratorSet decorators>
  72   inline void write_ref_field_post(void *addr, oop new_value) {}
  73 
  74   // barriers used by klass_oop_store
  75   void klass_update_barrier_set_pre(Klass* klass, oop* p) {}
  76   void klass_update_barrier_set(Klass* klass, oop* p, oop v);
  77 
  78   template <DecoratorSet decorators, typename BarrierSetT>
  79   class AccessBarrier: public BarrierSet::AccessBarrier<decorators> {
  80     typedef BarrierSet::AccessBarrier<decorators> Basic;
  81 
  82   public:
  83     typedef Basic SuperAccessBarrier;
  84 
  85     static void oop_store(void* addr, oop value);
  86 
  87     static oop oop_cas(oop new_value, void* addr, oop compare_value);
  88 
  89     static oop oop_swap(oop new_value, void* addr);
  90 
  91     template <typename T>
  92     static bool oop_copy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length);
  93 
  94     static void clone(oop src, oop dst, size_t size);
  95 
  96     static inline void oop_store_at(oop base, ptrdiff_t offset, oop value) {
  97       oop_store(Basic::field_addr(base, offset), value);
  98     }
  99 
 100     static inline void oop_store_at(Klass* base, ptrdiff_t offset, oop value);
 101 
 102     static inline oop oop_swap_at(oop new_value, oop base, ptrdiff_t offset) {
 103       return oop_swap(new_value, Basic::field_addr(base, offset));
 104     }
 105 
 106     static inline oop oop_cas_at(oop new_value, oop base, ptrdiff_t offset, oop compare_value) {
 107       return oop_cas(new_value, Basic::field_addr(base, offset), compare_value);
 108     }
 109   };
 110 };
 111 
 112 template<>
 113 struct BSTypeToName<ModRefBarrierSet> {
 114   static const BarrierSet::Name value = BarrierSet::ModRef;
 115 };
 116 
 117 template<>
 118 struct BSNameToType<BarrierSet::ModRef> {
 119   typedef ModRefBarrierSet type;
 120 };
 121 
 122 #endif // SHARE_VM_GC_SHARED_MODREFBARRIERSET_HPP