< prev index next >

src/share/vm/gc/shared/barrierSet.inline.hpp

Print this page
rev 12906 : [mq]: gc_interface

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -24,70 +24,293 @@
 
 #ifndef SHARE_VM_GC_SHARED_BARRIERSET_INLINE_HPP
 #define SHARE_VM_GC_SHARED_BARRIERSET_INLINE_HPP
 
 #include "gc/shared/barrierSet.hpp"
-#include "gc/shared/cardTableModRefBS.inline.hpp"
+#include "gc/shared/barrierSetConfig.inline.hpp"
+#include "runtime/access.hpp"
 
-// Inline functions of BarrierSet, which de-virtualize certain
-// performance-critical calls when the barrier is the most common
-// card-table kind.
+namespace AccessInternal {
 
-inline bool BarrierSet::devirtualize_reference_writes() const {
+  template <typename T, T>
+  struct HasOverloadHelper {};
+
+  template <class GCBarrierType, typename FuncType>
+  struct HasOopStoreAtOverload {
+    typedef jint yes;
+    typedef jbyte no;
+
+    template <typename F, typename T>
+    static yes& test(HasOverloadHelper<F, T::oop_store_at>*);
+    template <typename F, typename T>
+    static no& test(...);
+
+    enum {
+      value = sizeof(test<FuncType, GCBarrierType>(0)) == sizeof(yes)
+    };
+  };
+
+  template <class GCBarrierType, BarrierType type, DecoratorSet idecorators, typename T>
+  class AccessBarrierResolverProxy: public AllStatic { };
+
+  template <class GCBarrierType, DecoratorSet idecorators, typename P>
+  class AccessBarrierResolverProxy<GCBarrierType, BARRIER_STORE, idecorators, P>: public AllStatic {
+    template <DecoratorSet decorators, typename T>
+    static typename EnableIf<!DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
+      return (void*)&GCBarrierType::template store<T>;
+    }
+
+    template <DecoratorSet decorators, typename T>
+    static typename EnableIf<DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
+      return (void*)&GCBarrierType::oop_store;
+    }
+
+  public:
+    static void* resolve_barrier_type() {
+      return resolve_barrier_type_internal<idecorators, P>();
+    }
+  };
+
+  template <class GCBarrierType, DecoratorSet idecorators, typename P>
+  class AccessBarrierResolverProxy<GCBarrierType, BARRIER_STORE_AT, idecorators, P>: public AllStatic {
+  public:
+    template <DecoratorSet decorators, typename T>
+    static typename EnableIf<!DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
+      return (void*)&GCBarrierType::template store_at<T>;
+    }
+
+    // resolve_barrier_type_base searches the AccessBarrier class hierarchy for a
+    // matching overload of oop_store_at. The different overloads represent
+    // different base pointer types such as nmethod* oop or Klass*
+    template <class  BarrierType, DecoratorSet decorators, typename T>
+    static typename EnableIf<HasOopStoreAtOverload<BarrierType, typename AccessFunctionTypes<decorators, T>::store_at_func_t>::value, void*>::type resolve_barrier_type_base() {
+      typename AccessFunctionTypes<decorators, T>::store_at_func_t resolved = &BarrierType::oop_store_at;
+      return (void*)resolved;
+    }
+
+    template <class BarrierType, DecoratorSet decorators, typename T>
+    static typename EnableIf<!HasOopStoreAtOverload<BarrierType, typename AccessFunctionTypes<decorators, T>::store_at_func_t>::value, void*>::type resolve_barrier_type_base() {
+      return AccessBarrierResolverProxy<typename BarrierType::SuperAccessBarrier, BARRIER_STORE_AT, decorators, P>::template resolve_barrier_type_base<typename BarrierType::SuperAccessBarrier, decorators, T>();
+    }
+
+    template <DecoratorSet decorators, typename T>
+    static typename EnableIf<DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
+      return resolve_barrier_type_base<GCBarrierType, decorators, T>();
+    }
+
+    static void* resolve_barrier_type() {
+      return resolve_barrier_type_internal<idecorators, P>();
+    }
+  };
+
+  template <class GCBarrierType, DecoratorSet idecorators, typename P>
+  class AccessBarrierResolverProxy<GCBarrierType, BARRIER_LOAD, idecorators, P>: public AllStatic {
+    template <DecoratorSet decorators, typename T>
+    static typename EnableIf<!DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
+      return (void*)&GCBarrierType::template load<T>;
+    }
+
+    template <DecoratorSet decorators, typename T>
+    static typename EnableIf<DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
+      return (void*)&GCBarrierType::oop_load;
+    }
+  public:
+    static void* resolve_barrier_type() {
+      return resolve_barrier_type_internal<idecorators, P>();
+    }
+  };
+
+  template <class GCBarrierType, DecoratorSet idecorators, typename P>
+  class AccessBarrierResolverProxy<GCBarrierType, BARRIER_LOAD_AT, idecorators, P>: public AllStatic {
+    template <DecoratorSet decorators, typename T>
+    static typename EnableIf<!DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
+      return (void*)&GCBarrierType::template load_at<T>;
+    }
+
+    template <DecoratorSet decorators, typename T>
+    static typename EnableIf<DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
+      return (void*)&GCBarrierType::oop_load_at;
+    }
+
+  public:
+    static void* resolve_barrier_type() {
+      return resolve_barrier_type_internal<idecorators, P>();
+    }
+  };
+
+  template <class GCBarrierType, DecoratorSet idecorators, typename P>
+  class AccessBarrierResolverProxy<GCBarrierType, BARRIER_CAS, idecorators, P>: public AllStatic {
+    template <DecoratorSet decorators, typename T>
+    static typename EnableIf<!DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
+      return (void*)&GCBarrierType::template cas<T>;
+    }
+
+    template <DecoratorSet decorators, typename T>
+    static typename EnableIf<DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
+      return (void*)&GCBarrierType::oop_cas;
+    }
+
+  public:
+    static void* resolve_barrier_type() {
+      return resolve_barrier_type_internal<idecorators, P>();
+    }
+  };
+
+  template <class GCBarrierType, DecoratorSet idecorators, typename P>
+  class AccessBarrierResolverProxy<GCBarrierType, BARRIER_CAS_AT, idecorators, P>: public AllStatic {
+    template <DecoratorSet decorators, typename T>
+    static typename EnableIf<!DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
+      return (void*)&GCBarrierType::template cas_at<T>;
+    }
+
+    template <DecoratorSet decorators, typename T>
+    static typename EnableIf<DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
+      return (void*)&GCBarrierType::oop_cas_at;
+    }
+
+  public:
+    static void* resolve_barrier_type() {
+      return resolve_barrier_type_internal<idecorators, P>();
+    }
+  };
+
+  template <class GCBarrierType, DecoratorSet idecorators, typename P>
+  class AccessBarrierResolverProxy<GCBarrierType, BARRIER_SWAP, idecorators, P>: public AllStatic {
+    template <DecoratorSet decorators, typename T>
+    static typename EnableIf<!DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
+      return (void*)&GCBarrierType::template swap<T>;
+    }
+
+    template <DecoratorSet decorators, typename T>
+    static typename EnableIf<DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
+      return (void*)&GCBarrierType::oop_swap;
+    }
+
+  public:
+    static void* resolve_barrier_type() {
+      return resolve_barrier_type_internal<idecorators, P>();
+    }
+  };
+
+  template <class GCBarrierType, DecoratorSet idecorators, typename P>
+  class AccessBarrierResolverProxy<GCBarrierType, BARRIER_SWAP_AT, idecorators, P>: public AllStatic {
+    template <DecoratorSet decorators, typename T>
+    static typename EnableIf<!DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
+      return (void*)&GCBarrierType::template swap_at<T>;
+    }
+
+    template <DecoratorSet decorators, typename T>
+    static typename EnableIf<DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
+      return (void*)&GCBarrierType::oop_swap_at;
+    }
+
+  public:
+    static void* resolve_barrier_type() {
+      return resolve_barrier_type_internal<idecorators, P>();
+    }
+  };
+
+  template <class GCBarrierType, DecoratorSet idecorators, typename P>
+  class AccessBarrierResolverProxy<GCBarrierType, BARRIER_COPY, idecorators, P>: public AllStatic {
+    template <DecoratorSet decorators, typename T>
+    static typename EnableIf<!DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
+      return (void*)&GCBarrierType::template copy<T>;
+    }
+
+    template <DecoratorSet decorators, typename T>
+    static typename EnableIf<DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
+      return (void*)&GCBarrierType::template oop_copy<T>;
+    }
+
+  public:
+    static void* resolve_barrier_type() {
+      return resolve_barrier_type_internal<idecorators, P>();
+    }
+  };
+
+}
+
+template <DecoratorSet decorators, typename T, BarrierType barrier_type>
+void* BarrierSet::resolve_barrier() {
   switch (kind()) {
-  case CardTableForRS:
-  case CardTableExtension:
-    return true;
+#define BARRIER_SET_RESOLVE_BARRIER_CLOSURE(bs_name)  \
+    case bs_name : { \
+      return AccessInternal::AccessBarrierResolverProxy<typename BSNameToType< bs_name >::type::AccessBarrier<decorators>, barrier_type, decorators, T>::resolve_barrier_type(); \
+    } \
+    break;
+    FOR_EACH_CONCRETE_BARRIER_SET_DO(BARRIER_SET_RESOLVE_BARRIER_CLOSURE)
+#undef BARRIER_SET_RESOLVE_BARRIER_CLOSURE
+
   default:
-    return false;
-  }
+    fatal("BarrierSet AccessBarrier resolving not implemented");
+    return NULL;
+  };
 }
 
-template <class T> void BarrierSet::write_ref_field_pre(T* field, oop new_val) {
-  if (devirtualize_reference_writes()) {
-    barrier_set_cast<CardTableModRefBS>(this)->inline_write_ref_field_pre(field, new_val);
-  } else {
-    write_ref_field_pre_work(field, new_val);
-  }
+template <DecoratorSet decorators>
+void* BarrierSet::resolve_clone_barrier() {
+  switch (kind()) {
+#define BARRIER_SET_RESOLVE_BARRIER_CLOSURE(bs_name)  \
+    case bs_name : { \
+      return (void*)&BSNameToType< bs_name >::type::AccessBarrier<decorators>::clone; \
+    } \
+    break;
+    FOR_EACH_CONCRETE_BARRIER_SET_DO(BARRIER_SET_RESOLVE_BARRIER_CLOSURE)
+#undef BARRIER_SET_RESOLVE_BARRIER_CLOSURE
+
+  default:
+    fatal("BarrierSet AccessBarrier resolving not implemented");
+    return NULL;
+  };
 }
 
-void BarrierSet::write_ref_field(void* field, oop new_val, bool release) {
-  if (devirtualize_reference_writes()) {
-    barrier_set_cast<CardTableModRefBS>(this)->inline_write_ref_field(field, new_val, release);
-  } else {
-    write_ref_field_work(field, new_val, release);
-  }
+template <DecoratorSet decorators>
+inline void BarrierSet::AccessBarrier<decorators>::oop_store(void* addr, oop value) {
+  Basic::template oop_store<oop>(addr, value);
 }
 
-// count is number of array elements being written
-void BarrierSet::write_ref_array(HeapWord* start, size_t count) {
-  assert(count <= (size_t)max_intx, "count too large");
-  HeapWord* end = (HeapWord*)((char*)start + (count*heapOopSize));
-  // In the case of compressed oops, start and end may potentially be misaligned;
-  // so we need to conservatively align the first downward (this is not
-  // strictly necessary for current uses, but a case of good hygiene and,
-  // if you will, aesthetics) and the second upward (this is essential for
-  // current uses) to a HeapWord boundary, so we mark all cards overlapping
-  // this write. If this evolves in the future to calling a
-  // logging barrier of narrow oop granularity, like the pre-barrier for G1
-  // (mentioned here merely by way of example), we will need to change this
-  // interface, so it is "exactly precise" (if i may be allowed the adverbial
-  // redundancy for emphasis) and does not include narrow oop slots not
-  // included in the original write interval.
-  HeapWord* aligned_start = (HeapWord*)align_size_down((uintptr_t)start, HeapWordSize);
-  HeapWord* aligned_end   = (HeapWord*)align_size_up  ((uintptr_t)end,   HeapWordSize);
-  // If compressed oops were not being used, these should already be aligned
-  assert(UseCompressedOops || (aligned_start == start && aligned_end == end),
-         "Expected heap word alignment of start and end");
-  write_ref_array_work(MemRegion(aligned_start, aligned_end));
+template <DecoratorSet decorators>
+inline void BarrierSet::AccessBarrier<decorators>::oop_store_at(oop base, ptrdiff_t offset, oop value) {
+  Basic::template oop_store_at<oop>((void*)base, offset, value);
 }
 
+template <DecoratorSet decorators>
+inline void BarrierSet::AccessBarrier<decorators>::oop_store_at(nmethod* base, ptrdiff_t offset, oop value) {
+  Basic::template oop_store_at<oop>((void*)base, offset, value);
+}
 
-inline void BarrierSet::write_region(MemRegion mr) {
-  if (devirtualize_reference_writes()) {
-    barrier_set_cast<CardTableModRefBS>(this)->inline_write_region(mr);
-  } else {
-    write_region_work(mr);
-  }
+template <DecoratorSet decorators>
+inline void BarrierSet::AccessBarrier<decorators>::oop_store_at(Klass* base, ptrdiff_t offset, oop value) {
+  Basic::template oop_store_at<oop>((void*)base, offset, value);
+}
+
+template <DecoratorSet decorators>
+inline oop BarrierSet::AccessBarrier<decorators>::oop_load(void* addr) {
+  return Basic::template oop_load<oop>(addr);
+}
+
+template <DecoratorSet decorators>
+inline oop BarrierSet::AccessBarrier<decorators>::oop_load_at(oop base, ptrdiff_t offset) {
+  return Basic::template oop_load_at<oop>((void*)base, offset);
+}
+
+template <DecoratorSet decorators>
+inline oop BarrierSet::AccessBarrier<decorators>::oop_cas(oop new_value, void* addr, oop compare_value) {
+  return Basic::template oop_cas<oop>(new_value, addr, compare_value);
+}
+
+template <DecoratorSet decorators>
+inline oop BarrierSet::AccessBarrier<decorators>::oop_cas_at(oop new_value, oop base, ptrdiff_t offset, oop compare_value) {
+  return Basic::template oop_cas_at<oop>(new_value, (void*)base, offset, compare_value);
+}
+
+template <DecoratorSet decorators>
+inline oop BarrierSet::AccessBarrier<decorators>::oop_swap(oop new_value, void* addr) {
+  return Basic::template oop_swap<oop>(new_value, addr);
+}
+
+template <DecoratorSet decorators>
+inline oop BarrierSet::AccessBarrier<decorators>::oop_swap_at(oop new_value, oop base, ptrdiff_t offset) {
+  return Basic::template oop_swap_at<oop>(new_value, (void*)base, offset);
 }
 
 #endif // SHARE_VM_GC_SHARED_BARRIERSET_INLINE_HPP
< prev index next >