/*
 * Copyright (c) 2017, 2022, 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.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_OOPS_ACCESSBACKEND_HPP
#define SHARE_OOPS_ACCESSBACKEND_HPP

#include "gc/shared/barrierSetConfig.hpp"
#include "memory/allocation.hpp"
#include "metaprogramming/enableIf.hpp"
#include "oops/accessDecorators.hpp"
#include "oops/oopsHierarchy.hpp"
#include "runtime/globals.hpp"
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"

#include <type_traits>

// This metafunction returns either oop or narrowOop depending on whether
// an access needs to use compressed oops or not.
template <DecoratorSet decorators>
struct HeapOopType: AllStatic {
  static const bool needs_oop_compress = HasDecorator<decorators, INTERNAL_CONVERT_COMPRESSED_OOP>::value &&
                                         HasDecorator<decorators, INTERNAL_RT_USE_COMPRESSED_OOPS>::value;
  using type = std::conditional_t<needs_oop_compress, narrowOop, oop>;
};

namespace AccessInternal {
  enum BarrierType {
    BARRIER_STORE,
    BARRIER_STORE_AT,
    BARRIER_LOAD,
    BARRIER_LOAD_AT,
    BARRIER_ATOMIC_CMPXCHG,
    BARRIER_ATOMIC_CMPXCHG_AT,
    BARRIER_ATOMIC_XCHG,
    BARRIER_ATOMIC_XCHG_AT,
    BARRIER_ARRAYCOPY,
    BARRIER_CLONE
  };

  template <DecoratorSet decorators, typename T>
  struct MustConvertCompressedOop: public std::integral_constant<bool,
    HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value &&
    std::is_same<typename HeapOopType<decorators>::type, narrowOop>::value &&
    std::is_same<T, oop>::value> {};

  // This metafunction returns an appropriate oop type if the value is oop-like
  // and otherwise returns the same type T.
  template <DecoratorSet decorators, typename T>
  struct EncodedType: AllStatic {
    using type = std::conditional_t<HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value,
                                    typename HeapOopType<decorators>::type,
                                    T>;
  };

  template <DecoratorSet decorators>
  inline typename HeapOopType<decorators>::type*
  oop_field_addr(oop base, ptrdiff_t byte_offset) {
    return reinterpret_cast<typename HeapOopType<decorators>::type*>(
             reinterpret_cast<intptr_t>((void*)base) + byte_offset);
  }

  template <DecoratorSet decorators, typename T>
  struct AccessFunctionTypes {
    typedef T (*load_at_func_t)(oop base, ptrdiff_t offset);
    typedef void (*store_at_func_t)(oop base, ptrdiff_t offset, T value);
    typedef T (*atomic_cmpxchg_at_func_t)(oop base, ptrdiff_t offset, T compare_value, T new_value);
    typedef T (*atomic_xchg_at_func_t)(oop base, ptrdiff_t offset, T new_value);

    typedef T (*load_func_t)(void* addr);
    typedef void (*store_func_t)(void* addr, T value);
    typedef T (*atomic_cmpxchg_func_t)(void* addr, T compare_value, T new_value);
    typedef T (*atomic_xchg_func_t)(void* addr, T new_value);

    typedef bool (*arraycopy_func_t)(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
                                     arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
                                     size_t length);
    typedef void (*clone_func_t)(oop src, oop dst, size_t size);
  };

  template <DecoratorSet decorators>
  struct AccessFunctionTypes<decorators, void> {
    typedef bool (*arraycopy_func_t)(arrayOop src_obj, size_t src_offset_in_bytes, void* src,
                                     arrayOop dst_obj, size_t dst_offset_in_bytes, void* dst,
                                     size_t length);
  };

  template <DecoratorSet decorators, typename T, BarrierType barrier> struct AccessFunction {};

#define ACCESS_GENERATE_ACCESS_FUNCTION(bt, func)                   \
  template <DecoratorSet decorators, typename T>                    \
  struct AccessFunction<decorators, T, bt>: AllStatic{              \
    typedef typename AccessFunctionTypes<decorators, T>::func type; \
  }
  ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_STORE, store_func_t);
  ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_STORE_AT, store_at_func_t);
  ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_LOAD, load_func_t);
  ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_LOAD_AT, load_at_func_t);
  ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_ATOMIC_CMPXCHG, atomic_cmpxchg_func_t);
  ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_ATOMIC_CMPXCHG_AT, atomic_cmpxchg_at_func_t);
  ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_ATOMIC_XCHG, atomic_xchg_func_t);
  ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_ATOMIC_XCHG_AT, atomic_xchg_at_func_t);
  ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_ARRAYCOPY, arraycopy_func_t);
  ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_CLONE, clone_func_t);
#undef ACCESS_GENERATE_ACCESS_FUNCTION

  template <DecoratorSet decorators, typename T, BarrierType barrier_type>
  typename AccessFunction<decorators, T, barrier_type>::type resolve_barrier();

  template <DecoratorSet decorators, typename T, BarrierType barrier_type>
  typename AccessFunction<decorators, T, barrier_type>::type resolve_oop_barrier();

  void* field_addr(oop base, ptrdiff_t offset);

  // Forward calls to Copy:: in the cpp file to reduce dependencies and allow
  // faster build times, given how frequently included access is.
  void arraycopy_arrayof_conjoint_oops(void* src, void* dst, size_t length);
  void arraycopy_conjoint_oops(oop* src, oop* dst, size_t length);
  void arraycopy_conjoint_oops(narrowOop* src, narrowOop* dst, size_t length);

  void arraycopy_disjoint_words(void* src, void* dst, size_t length);
  void arraycopy_disjoint_words_atomic(void* src, void* dst, size_t length);

  template<typename T>
  void arraycopy_conjoint(T* src, T* dst, size_t length);
  template<typename T>
  void arraycopy_arrayof_conjoint(T* src, T* dst, size_t length);
  template<typename T>
  void arraycopy_conjoint_atomic(T* src, T* dst, size_t length);
}

// This mask specifies what decorators are relevant for raw accesses. When passing
// accesses to the raw layer, irrelevant decorators are removed.
const DecoratorSet RAW_DECORATOR_MASK = INTERNAL_DECORATOR_MASK | MO_DECORATOR_MASK |
                                        ARRAYCOPY_DECORATOR_MASK | IS_NOT_NULL;

// The RawAccessBarrier performs raw accesses with additional knowledge of
// memory ordering, so that OrderAccess/Atomic is called when necessary.
// It additionally handles compressed oops, and hence is not completely "raw"
// strictly speaking.
template <DecoratorSet decorators>
class RawAccessBarrier: public AllStatic {
protected:
  static inline void* field_addr(oop base, ptrdiff_t byte_offset) {
    return AccessInternal::field_addr(base, byte_offset);
  }

protected:
  // Only encode if INTERNAL_VALUE_IS_OOP
  template <DecoratorSet idecorators, typename T>
  static inline typename EnableIf<
    AccessInternal::MustConvertCompressedOop<idecorators, T>::value,
    typename HeapOopType<idecorators>::type>::type
  encode_internal(T value);

  template <DecoratorSet idecorators, typename T>
  static inline typename EnableIf<
    !AccessInternal::MustConvertCompressedOop<idecorators, T>::value, T>::type
  encode_internal(T value) {
    return value;
  }

  template <typename T>
  static inline typename AccessInternal::EncodedType<decorators, T>::type
  encode(T value) {
    return encode_internal<decorators, T>(value);
  }

  // Only decode if INTERNAL_VALUE_IS_OOP
  template <DecoratorSet idecorators, typename T>
  static inline typename EnableIf<
    AccessInternal::MustConvertCompressedOop<idecorators, T>::value, T>::type
  decode_internal(typename HeapOopType<idecorators>::type value);

  template <DecoratorSet idecorators, typename T>
  static inline typename EnableIf<
    !AccessInternal::MustConvertCompressedOop<idecorators, T>::value, T>::type
  decode_internal(T value) {
    return value;
  }

  template <typename T>
  static inline T decode(typename AccessInternal::EncodedType<decorators, T>::type value) {
    return decode_internal<decorators, T>(value);
  }

protected:
  template <DecoratorSet ds, typename T>
  static typename EnableIf<
    HasDecorator<ds, MO_SEQ_CST>::value, T>::type
  load_internal(void* addr);

  template <DecoratorSet ds, typename T>
  static typename EnableIf<
    HasDecorator<ds, MO_ACQUIRE>::value, T>::type
  load_internal(void* addr);

  template <DecoratorSet ds, typename T>
  static typename EnableIf<
    HasDecorator<ds, MO_RELAXED>::value, T>::type
  load_internal(void* addr);

  template <DecoratorSet ds, typename T>
  static inline typename EnableIf<
    HasDecorator<ds, MO_UNORDERED>::value, T>::type
  load_internal(void* addr) {
    return *reinterpret_cast<T*>(addr);
  }

  template <DecoratorSet ds, typename T>
  static typename EnableIf<
    HasDecorator<ds, MO_SEQ_CST>::value>::type
  store_internal(void* addr, T value);

  template <DecoratorSet ds, typename T>
  static typename EnableIf<
    HasDecorator<ds, MO_RELEASE>::value>::type
  store_internal(void* addr, T value);

  template <DecoratorSet ds, typename T>
  static typename EnableIf<
    HasDecorator<ds, MO_RELAXED>::value>::type
  store_internal(void* addr, T value);

  template <DecoratorSet ds, typename T>
  static inline typename EnableIf<
    HasDecorator<ds, MO_UNORDERED>::value>::type
  store_internal(void* addr, T value) {
    *reinterpret_cast<T*>(addr) = value;
  }

  template <DecoratorSet ds, typename T>
  static typename EnableIf<
    HasDecorator<ds, MO_SEQ_CST>::value, T>::type
  atomic_cmpxchg_internal(void* addr, T compare_value, T new_value);

  template <DecoratorSet ds, typename T>
  static typename EnableIf<
    HasDecorator<ds, MO_RELAXED>::value, T>::type
  atomic_cmpxchg_internal(void* addr, T compare_value, T new_value);

  template <DecoratorSet ds, typename T>
  static typename EnableIf<
    HasDecorator<ds, MO_SEQ_CST>::value, T>::type
  atomic_xchg_internal(void* addr, T new_value);

public:
  template <typename T>
  static inline void store(void* addr, T value) {
    store_internal<decorators>(addr, value);
  }

  template <typename T>
  static inline T load(void* addr) {
    return load_internal<decorators, T>(addr);
  }

  template <typename T>
  static inline T atomic_cmpxchg(void* addr, T compare_value, T new_value) {
    return atomic_cmpxchg_internal<decorators>(addr, compare_value, new_value);
  }

  template <typename T>
  static inline T atomic_xchg(void* addr, T new_value) {
    return atomic_xchg_internal<decorators>(addr, new_value);
  }

  template <typename T>
  static bool arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
                        arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
                        size_t length);

  template <typename T>
  static void oop_store(void* addr, T value);
  template <typename T>
  static void oop_store_at(oop base, ptrdiff_t offset, T value);

  template <typename T>
  static T oop_load(void* addr);
  template <typename T>
  static T oop_load_at(oop base, ptrdiff_t offset);

  template <typename T>
  static T oop_atomic_cmpxchg(void* addr, T compare_value, T new_value);
  template <typename T>
  static T oop_atomic_cmpxchg_at(oop base, ptrdiff_t offset, T compare_value, T new_value);

  template <typename T>
  static T oop_atomic_xchg(void* addr, T new_value);
  template <typename T>
  static T oop_atomic_xchg_at(oop base, ptrdiff_t offset, T new_value);

  template <typename T>
  static void store_at(oop base, ptrdiff_t offset, T value) {
    store(field_addr(base, offset), value);
  }

  template <typename T>
  static T load_at(oop base, ptrdiff_t offset) {
    return load<T>(field_addr(base, offset));
  }

  template <typename T>
  static T atomic_cmpxchg_at(oop base, ptrdiff_t offset, T compare_value, T new_value) {
    return atomic_cmpxchg(field_addr(base, offset), compare_value, new_value);
  }

  template <typename T>
  static T atomic_xchg_at(oop base, ptrdiff_t offset, T new_value) {
    return atomic_xchg(field_addr(base, offset), new_value);
  }

  template <typename T>
  static bool oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
                            arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
                            size_t length);

  static void clone(oop src, oop dst, size_t size);
};

namespace AccessInternal {
  DEBUG_ONLY(void check_access_thread_state());
#define assert_access_thread_state() DEBUG_ONLY(check_access_thread_state())
}

// Below is the implementation of the first 4 steps of the template pipeline:
// * Step 1: Set default decorators and decay types. This step gets rid of CV qualifiers
//           and sets default decorators to sensible values.
// * Step 2: Reduce types. This step makes sure there is only a single T type and not
//           multiple types. The P type of the address and T type of the value must
//           match.
// * Step 3: Pre-runtime dispatch. This step checks whether a runtime call can be
//           avoided, and in that case avoids it (calling raw accesses or
//           primitive accesses in a build that does not require primitive GC barriers)
// * Step 4: Runtime-dispatch. This step performs a runtime dispatch to the corresponding
//           BarrierSet::AccessBarrier accessor that attaches GC-required barriers
//           to the access.

namespace AccessInternal {
  template <typename T>
  struct OopOrNarrowOopInternal: AllStatic {
    typedef oop type;
  };

  template <>
  struct OopOrNarrowOopInternal<narrowOop>: AllStatic {
    typedef narrowOop type;
  };

  // This metafunction returns a canonicalized oop/narrowOop type for a passed
  // in oop-like types passed in from oop_* overloads where the user has sworn
  // that the passed in values should be oop-like (e.g. oop, oopDesc*, arrayOop,
  // narrowOoop, instanceOopDesc*, and random other things).
  // In the oop_* overloads, it must hold that if the passed in type T is not
  // narrowOop, then it by contract has to be one of many oop-like types implicitly
  // convertible to oop, and hence returns oop as the canonical oop type.
  // If it turns out it was not, then the implicit conversion to oop will fail
  // to compile, as desired.
  template <typename T>
  struct OopOrNarrowOop: AllStatic {
    typedef typename OopOrNarrowOopInternal<std::decay_t<T>>::type type;
  };

  inline void* field_addr(oop base, ptrdiff_t byte_offset) {
    return reinterpret_cast<void*>(reinterpret_cast<intptr_t>((void*)base) + byte_offset);
  }
  // Step 4: Runtime dispatch
  // The RuntimeDispatch class is responsible for performing a runtime dispatch of the
  // accessor. This is required when the access either depends on whether compressed oops
  // is being used, or it depends on which GC implementation was chosen (e.g. requires GC
  // barriers). The way it works is that a function pointer initially pointing to an
  // accessor resolution function gets called for each access. Upon first invocation,
  // it resolves which accessor to be used in future invocations and patches the
  // function pointer to this new accessor.

  template <DecoratorSet decorators, typename T, BarrierType type>
  struct RuntimeDispatch: AllStatic {};

  template <DecoratorSet decorators, typename T>
  struct RuntimeDispatch<decorators, T, BARRIER_STORE>: AllStatic {
    typedef typename AccessFunction<decorators, T, BARRIER_STORE>::type func_t;
    static func_t _store_func;

    static void store_init(void* addr, T value);

    static inline void store(void* addr, T value) {
      assert_access_thread_state();
      _store_func(addr, value);
    }
  };

  template <DecoratorSet decorators, typename T>
  struct RuntimeDispatch<decorators, T, BARRIER_STORE_AT>: AllStatic {
    typedef typename AccessFunction<decorators, T, BARRIER_STORE_AT>::type func_t;
    static func_t _store_at_func;

    static void store_at_init(oop base, ptrdiff_t offset, T value);

    static inline void store_at(oop base, ptrdiff_t offset, T value) {
      assert_access_thread_state();
      _store_at_func(base, offset, value);
    }
  };

  template <DecoratorSet decorators, typename T>
  struct RuntimeDispatch<decorators, T, BARRIER_LOAD>: AllStatic {
    typedef typename AccessFunction<decorators, T, BARRIER_LOAD>::type func_t;
    static func_t _load_func;

    static T load_init(void* addr);

    static inline T load(void* addr) {
      assert_access_thread_state();
      return _load_func(addr);
    }
  };

  template <DecoratorSet decorators, typename T>
  struct RuntimeDispatch<decorators, T, BARRIER_LOAD_AT>: AllStatic {
    typedef typename AccessFunction<decorators, T, BARRIER_LOAD_AT>::type func_t;
    static func_t _load_at_func;

    static T load_at_init(oop base, ptrdiff_t offset);

    static inline T load_at(oop base, ptrdiff_t offset) {
      assert_access_thread_state();
      return _load_at_func(base, offset);
    }
  };

  template <DecoratorSet decorators, typename T>
  struct RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG>: AllStatic {
    typedef typename AccessFunction<decorators, T, BARRIER_ATOMIC_CMPXCHG>::type func_t;
    static func_t _atomic_cmpxchg_func;

    static T atomic_cmpxchg_init(void* addr, T compare_value, T new_value);

    static inline T atomic_cmpxchg(void* addr, T compare_value, T new_value) {
      assert_access_thread_state();
      return _atomic_cmpxchg_func(addr, compare_value, new_value);
    }
  };

  template <DecoratorSet decorators, typename T>
  struct RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG_AT>: AllStatic {
    typedef typename AccessFunction<decorators, T, BARRIER_ATOMIC_CMPXCHG_AT>::type func_t;
    static func_t _atomic_cmpxchg_at_func;

    static T atomic_cmpxchg_at_init(oop base, ptrdiff_t offset, T compare_value, T new_value);

    static inline T atomic_cmpxchg_at(oop base, ptrdiff_t offset, T compare_value, T new_value) {
      assert_access_thread_state();
      return _atomic_cmpxchg_at_func(base, offset, compare_value, new_value);
    }
  };

  template <DecoratorSet decorators, typename T>
  struct RuntimeDispatch<decorators, T, BARRIER_ATOMIC_XCHG>: AllStatic {
    typedef typename AccessFunction<decorators, T, BARRIER_ATOMIC_XCHG>::type func_t;
    static func_t _atomic_xchg_func;

    static T atomic_xchg_init(void* addr, T new_value);

    static inline T atomic_xchg(void* addr, T new_value) {
      assert_access_thread_state();
      return _atomic_xchg_func(addr, new_value);
    }
  };

  template <DecoratorSet decorators, typename T>
  struct RuntimeDispatch<decorators, T, BARRIER_ATOMIC_XCHG_AT>: AllStatic {
    typedef typename AccessFunction<decorators, T, BARRIER_ATOMIC_XCHG_AT>::type func_t;
    static func_t _atomic_xchg_at_func;

    static T atomic_xchg_at_init(oop base, ptrdiff_t offset, T new_value);

    static inline T atomic_xchg_at(oop base, ptrdiff_t offset, T new_value) {
      assert_access_thread_state();
      return _atomic_xchg_at_func(base, offset, new_value);
    }
  };

  template <DecoratorSet decorators, typename T>
  struct RuntimeDispatch<decorators, T, BARRIER_ARRAYCOPY>: AllStatic {
    typedef typename AccessFunction<decorators, T, BARRIER_ARRAYCOPY>::type func_t;
    static func_t _arraycopy_func;

    static bool arraycopy_init(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
                               arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
                               size_t length);

    static inline bool arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
                                 arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
                                 size_t length) {
      assert_access_thread_state();
      return _arraycopy_func(src_obj, src_offset_in_bytes, src_raw,
                             dst_obj, dst_offset_in_bytes, dst_raw,
                             length);
    }
  };

  template <DecoratorSet decorators, typename T>
  struct RuntimeDispatch<decorators, T, BARRIER_CLONE>: AllStatic {
    typedef typename AccessFunction<decorators, T, BARRIER_CLONE>::type func_t;
    static func_t _clone_func;

    static void clone_init(oop src, oop dst, size_t size);

    static inline void clone(oop src, oop dst, size_t size) {
      assert_access_thread_state();
      _clone_func(src, dst, size);
    }
  };

  // Initialize the function pointers to point to the resolving function.
  template <DecoratorSet decorators, typename T>
  typename AccessFunction<decorators, T, BARRIER_STORE>::type
  RuntimeDispatch<decorators, T, BARRIER_STORE>::_store_func = &store_init;

  template <DecoratorSet decorators, typename T>
  typename AccessFunction<decorators, T, BARRIER_STORE_AT>::type
  RuntimeDispatch<decorators, T, BARRIER_STORE_AT>::_store_at_func = &store_at_init;

  template <DecoratorSet decorators, typename T>
  typename AccessFunction<decorators, T, BARRIER_LOAD>::type
  RuntimeDispatch<decorators, T, BARRIER_LOAD>::_load_func = &load_init;

  template <DecoratorSet decorators, typename T>
  typename AccessFunction<decorators, T, BARRIER_LOAD_AT>::type
  RuntimeDispatch<decorators, T, BARRIER_LOAD_AT>::_load_at_func = &load_at_init;

  template <DecoratorSet decorators, typename T>
  typename AccessFunction<decorators, T, BARRIER_ATOMIC_CMPXCHG>::type
  RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG>::_atomic_cmpxchg_func = &atomic_cmpxchg_init;

  template <DecoratorSet decorators, typename T>
  typename AccessFunction<decorators, T, BARRIER_ATOMIC_CMPXCHG_AT>::type
  RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG_AT>::_atomic_cmpxchg_at_func = &atomic_cmpxchg_at_init;

  template <DecoratorSet decorators, typename T>
  typename AccessFunction<decorators, T, BARRIER_ATOMIC_XCHG>::type
  RuntimeDispatch<decorators, T, BARRIER_ATOMIC_XCHG>::_atomic_xchg_func = &atomic_xchg_init;

  template <DecoratorSet decorators, typename T>
  typename AccessFunction<decorators, T, BARRIER_ATOMIC_XCHG_AT>::type
  RuntimeDispatch<decorators, T, BARRIER_ATOMIC_XCHG_AT>::_atomic_xchg_at_func = &atomic_xchg_at_init;

  template <DecoratorSet decorators, typename T>
  typename AccessFunction<decorators, T, BARRIER_ARRAYCOPY>::type
  RuntimeDispatch<decorators, T, BARRIER_ARRAYCOPY>::_arraycopy_func = &arraycopy_init;

  template <DecoratorSet decorators, typename T>
  typename AccessFunction<decorators, T, BARRIER_CLONE>::type
  RuntimeDispatch<decorators, T, BARRIER_CLONE>::_clone_func = &clone_init;

  // Step 3: Pre-runtime dispatching.
  // The PreRuntimeDispatch class is responsible for filtering the barrier strength
  // decorators. That is, for AS_RAW, it hardwires the accesses without a runtime
  // dispatch point. Otherwise it goes through a runtime check if hardwiring was
  // not possible.
  struct PreRuntimeDispatch: AllStatic {
    template<DecoratorSet decorators>
    struct CanHardwireRaw: public std::integral_constant<
      bool,
      !HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value || // primitive access
      !HasDecorator<decorators, INTERNAL_CONVERT_COMPRESSED_OOP>::value || // don't care about compressed oops (oop* address)
      HasDecorator<decorators, INTERNAL_RT_USE_COMPRESSED_OOPS>::value> // we can infer we use compressed oops (narrowOop* address)
    {};

    static const DecoratorSet convert_compressed_oops = INTERNAL_RT_USE_COMPRESSED_OOPS | INTERNAL_CONVERT_COMPRESSED_OOP;

    template<DecoratorSet decorators>
    static bool is_hardwired_primitive() {
      return !HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value;
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      HasDecorator<decorators, AS_RAW>::value && CanHardwireRaw<decorators>::value>::type
    store(void* addr, T value) {
      typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
      if (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value) {
        Raw::oop_store(addr, value);
      } else {
        Raw::store(addr, value);
      }
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      HasDecorator<decorators, AS_RAW>::value && !CanHardwireRaw<decorators>::value>::type
    store(void* addr, T value) {
      if (UseCompressedOops) {
        const DecoratorSet expanded_decorators = decorators | convert_compressed_oops;
        PreRuntimeDispatch::store<expanded_decorators>(addr, value);
      } else {
        const DecoratorSet expanded_decorators = decorators & ~convert_compressed_oops;
        PreRuntimeDispatch::store<expanded_decorators>(addr, value);
      }
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      !HasDecorator<decorators, AS_RAW>::value>::type
    store(void* addr, T value) {
      if (is_hardwired_primitive<decorators>()) {
        const DecoratorSet expanded_decorators = decorators | AS_RAW;
        PreRuntimeDispatch::store<expanded_decorators>(addr, value);
      } else {
        RuntimeDispatch<decorators, T, BARRIER_STORE>::store(addr, value);
      }
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      HasDecorator<decorators, AS_RAW>::value>::type
    store_at(oop base, ptrdiff_t offset, T value) {
      store<decorators>(field_addr(base, offset), value);
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      !HasDecorator<decorators, AS_RAW>::value>::type
    store_at(oop base, ptrdiff_t offset, T value) {
      if (is_hardwired_primitive<decorators>()) {
        const DecoratorSet expanded_decorators = decorators | AS_RAW;
        PreRuntimeDispatch::store_at<expanded_decorators>(base, offset, value);
      } else {
        RuntimeDispatch<decorators, T, BARRIER_STORE_AT>::store_at(base, offset, value);
      }
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      HasDecorator<decorators, AS_RAW>::value && CanHardwireRaw<decorators>::value, T>::type
    load(void* addr) {
      typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
      if (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value) {
        return Raw::template oop_load<T>(addr);
      } else {
        return Raw::template load<T>(addr);
      }
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      HasDecorator<decorators, AS_RAW>::value && !CanHardwireRaw<decorators>::value, T>::type
    load(void* addr) {
      if (UseCompressedOops) {
        const DecoratorSet expanded_decorators = decorators | convert_compressed_oops;
        return PreRuntimeDispatch::load<expanded_decorators, T>(addr);
      } else {
        const DecoratorSet expanded_decorators = decorators & ~convert_compressed_oops;
        return PreRuntimeDispatch::load<expanded_decorators, T>(addr);
      }
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      !HasDecorator<decorators, AS_RAW>::value, T>::type
    load(void* addr) {
      if (is_hardwired_primitive<decorators>()) {
        const DecoratorSet expanded_decorators = decorators | AS_RAW;
        return PreRuntimeDispatch::load<expanded_decorators, T>(addr);
      } else {
        return RuntimeDispatch<decorators, T, BARRIER_LOAD>::load(addr);
      }
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      HasDecorator<decorators, AS_RAW>::value, T>::type
    load_at(oop base, ptrdiff_t offset) {
      return load<decorators, T>(field_addr(base, offset));
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      !HasDecorator<decorators, AS_RAW>::value, T>::type
    load_at(oop base, ptrdiff_t offset) {
      if (is_hardwired_primitive<decorators>()) {
        const DecoratorSet expanded_decorators = decorators | AS_RAW;
        return PreRuntimeDispatch::load_at<expanded_decorators, T>(base, offset);
      } else {
        return RuntimeDispatch<decorators, T, BARRIER_LOAD_AT>::load_at(base, offset);
      }
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      HasDecorator<decorators, AS_RAW>::value && CanHardwireRaw<decorators>::value, T>::type
    atomic_cmpxchg(void* addr, T compare_value, T new_value) {
      typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
      if (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value) {
        return Raw::oop_atomic_cmpxchg(addr, compare_value, new_value);
      } else {
        return Raw::atomic_cmpxchg(addr, compare_value, new_value);
      }
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      HasDecorator<decorators, AS_RAW>::value && !CanHardwireRaw<decorators>::value, T>::type
    atomic_cmpxchg(void* addr, T compare_value, T new_value) {
      if (UseCompressedOops) {
        const DecoratorSet expanded_decorators = decorators | convert_compressed_oops;
        return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(addr, compare_value, new_value);
      } else {
        const DecoratorSet expanded_decorators = decorators & ~convert_compressed_oops;
        return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(addr, compare_value, new_value);
      }
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      !HasDecorator<decorators, AS_RAW>::value, T>::type
    atomic_cmpxchg(void* addr, T compare_value, T new_value) {
      if (is_hardwired_primitive<decorators>()) {
        const DecoratorSet expanded_decorators = decorators | AS_RAW;
        return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(addr, compare_value, new_value);
      } else {
        return RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG>::atomic_cmpxchg(addr, compare_value, new_value);
      }
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      HasDecorator<decorators, AS_RAW>::value, T>::type
    atomic_cmpxchg_at(oop base, ptrdiff_t offset, T compare_value, T new_value) {
      return atomic_cmpxchg<decorators>(field_addr(base, offset), compare_value, new_value);
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      !HasDecorator<decorators, AS_RAW>::value, T>::type
    atomic_cmpxchg_at(oop base, ptrdiff_t offset, T compare_value, T new_value) {
      if (is_hardwired_primitive<decorators>()) {
        const DecoratorSet expanded_decorators = decorators | AS_RAW;
        return PreRuntimeDispatch::atomic_cmpxchg_at<expanded_decorators>(base, offset, compare_value, new_value);
      } else {
        return RuntimeDispatch<decorators, T, BARRIER_ATOMIC_CMPXCHG_AT>::atomic_cmpxchg_at(base, offset, compare_value, new_value);
      }
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      HasDecorator<decorators, AS_RAW>::value && CanHardwireRaw<decorators>::value, T>::type
    atomic_xchg(void* addr, T new_value) {
      typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
      if (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value) {
        return Raw::oop_atomic_xchg(addr, new_value);
      } else {
        return Raw::atomic_xchg(addr, new_value);
      }
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      HasDecorator<decorators, AS_RAW>::value && !CanHardwireRaw<decorators>::value, T>::type
    atomic_xchg(void* addr, T new_value) {
      if (UseCompressedOops) {
        const DecoratorSet expanded_decorators = decorators | convert_compressed_oops;
        return PreRuntimeDispatch::atomic_xchg<expanded_decorators>(addr, new_value);
      } else {
        const DecoratorSet expanded_decorators = decorators & ~convert_compressed_oops;
        return PreRuntimeDispatch::atomic_xchg<expanded_decorators>(addr, new_value);
      }
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      !HasDecorator<decorators, AS_RAW>::value, T>::type
    atomic_xchg(void* addr, T new_value) {
      if (is_hardwired_primitive<decorators>()) {
        const DecoratorSet expanded_decorators = decorators | AS_RAW;
        return PreRuntimeDispatch::atomic_xchg<expanded_decorators>(addr, new_value);
      } else {
        return RuntimeDispatch<decorators, T, BARRIER_ATOMIC_XCHG>::atomic_xchg(addr, new_value);
      }
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      HasDecorator<decorators, AS_RAW>::value, T>::type
    atomic_xchg_at(oop base, ptrdiff_t offset, T new_value) {
      return atomic_xchg<decorators>(field_addr(base, offset), new_value);
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      !HasDecorator<decorators, AS_RAW>::value, T>::type
    atomic_xchg_at(oop base, ptrdiff_t offset, T new_value) {
      if (is_hardwired_primitive<decorators>()) {
        const DecoratorSet expanded_decorators = decorators | AS_RAW;
        return PreRuntimeDispatch::atomic_xchg<expanded_decorators>(base, offset, new_value);
      } else {
        return RuntimeDispatch<decorators, T, BARRIER_ATOMIC_XCHG_AT>::atomic_xchg_at(base, offset, new_value);
      }
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      HasDecorator<decorators, AS_RAW>::value && CanHardwireRaw<decorators>::value, bool>::type
    arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
              arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
              size_t length) {
      typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
      if (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value) {
        return Raw::oop_arraycopy(src_obj, src_offset_in_bytes, src_raw,
                                  dst_obj, dst_offset_in_bytes, dst_raw,
                                  length);
      } else {
        return Raw::arraycopy(src_obj, src_offset_in_bytes, src_raw,
                              dst_obj, dst_offset_in_bytes, dst_raw,
                              length);
      }
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      HasDecorator<decorators, AS_RAW>::value && !CanHardwireRaw<decorators>::value, bool>::type
    arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
              arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
              size_t length) {
      if (UseCompressedOops) {
        const DecoratorSet expanded_decorators = decorators | convert_compressed_oops;
        return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw,
                                                                  dst_obj, dst_offset_in_bytes, dst_raw,
                                                                  length);
      } else {
        const DecoratorSet expanded_decorators = decorators & ~convert_compressed_oops;
        return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw,
                                                                  dst_obj, dst_offset_in_bytes, dst_raw,
                                                                  length);
      }
    }

    template <DecoratorSet decorators, typename T>
    inline static typename EnableIf<
      !HasDecorator<decorators, AS_RAW>::value, bool>::type
    arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
              arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
              size_t length) {
      if (is_hardwired_primitive<decorators>()) {
        const DecoratorSet expanded_decorators = decorators | AS_RAW;
        return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw,
                                                                  dst_obj, dst_offset_in_bytes, dst_raw,
                                                                  length);
      } else {
        return RuntimeDispatch<decorators, T, BARRIER_ARRAYCOPY>::arraycopy(src_obj, src_offset_in_bytes, src_raw,
                                                                            dst_obj, dst_offset_in_bytes, dst_raw,
                                                                            length);
      }
    }

    template <DecoratorSet decorators>
    inline static typename EnableIf<
      HasDecorator<decorators, AS_RAW>::value>::type
    clone(oop src, oop dst, size_t size) {
      typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
      Raw::clone(src, dst, size);
    }

    template <DecoratorSet decorators>
    inline static typename EnableIf<
      !HasDecorator<decorators, AS_RAW>::value>::type
    clone(oop src, oop dst, size_t size) {
      RuntimeDispatch<decorators, oop, BARRIER_CLONE>::clone(src, dst, size);
    }
  };

  // Step 2: Reduce types.
  // Enforce that for non-oop types, T and P have to be strictly the same.
  // P is the type of the address and T is the type of the values.
  // As for oop types, it is allow to send T in {narrowOop, oop} and
  // P in {narrowOop, oop, HeapWord*}. The following rules apply according to
  // the subsequent table. (columns are P, rows are T)
  // |           | HeapWord  |   oop   | narrowOop |
  // |   oop     |  rt-comp  | hw-none |  hw-comp  |
  // | narrowOop |     x     |    x    |  hw-none  |
  //
  // x means not allowed
  // rt-comp means it must be checked at runtime whether the oop is compressed.
  // hw-none means it is statically known the oop will not be compressed.
  // hw-comp means it is statically known the oop will be compressed.

  template <DecoratorSet decorators, typename T>
  inline void store_reduce_types(T* addr, T value) {
    PreRuntimeDispatch::store<decorators>(addr, value);
  }

  template <DecoratorSet decorators>
  inline void store_reduce_types(narrowOop* addr, oop value) {
    const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
                                             INTERNAL_RT_USE_COMPRESSED_OOPS;
    PreRuntimeDispatch::store<expanded_decorators>(addr, value);
  }

  template <DecoratorSet decorators>
  inline void store_reduce_types(narrowOop* addr, narrowOop value) {
    const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
                                             INTERNAL_RT_USE_COMPRESSED_OOPS;
    PreRuntimeDispatch::store<expanded_decorators>(addr, value);
  }

  template <DecoratorSet decorators>
  inline void store_reduce_types(HeapWord* addr, oop value) {
    const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP;
    PreRuntimeDispatch::store<expanded_decorators>(addr, value);
  }

  template <DecoratorSet decorators, typename T>
  inline T atomic_cmpxchg_reduce_types(T* addr, T compare_value, T new_value) {
    return PreRuntimeDispatch::atomic_cmpxchg<decorators>(addr, compare_value, new_value);
  }

  template <DecoratorSet decorators>
  inline oop atomic_cmpxchg_reduce_types(narrowOop* addr, oop compare_value, oop new_value) {
    const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
                                             INTERNAL_RT_USE_COMPRESSED_OOPS;
    return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(addr, compare_value, new_value);
  }

  template <DecoratorSet decorators>
  inline narrowOop atomic_cmpxchg_reduce_types(narrowOop* addr, narrowOop compare_value, narrowOop new_value) {
    const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
                                             INTERNAL_RT_USE_COMPRESSED_OOPS;
    return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(addr, compare_value, new_value);
  }

  template <DecoratorSet decorators>
  inline oop atomic_cmpxchg_reduce_types(HeapWord* addr,
                                         oop compare_value,
                                         oop new_value) {
    const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP;
    return PreRuntimeDispatch::atomic_cmpxchg<expanded_decorators>(addr, compare_value, new_value);
  }

  template <DecoratorSet decorators, typename T>
  inline T atomic_xchg_reduce_types(T* addr, T new_value) {
    const DecoratorSet expanded_decorators = decorators;
    return PreRuntimeDispatch::atomic_xchg<expanded_decorators>(addr, new_value);
  }

  template <DecoratorSet decorators>
  inline oop atomic_xchg_reduce_types(narrowOop* addr, oop new_value) {
    const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
                                             INTERNAL_RT_USE_COMPRESSED_OOPS;
    return PreRuntimeDispatch::atomic_xchg<expanded_decorators>(addr, new_value);
  }

  template <DecoratorSet decorators>
  inline narrowOop atomic_xchg_reduce_types(narrowOop* addr, narrowOop new_value) {
    const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
                                             INTERNAL_RT_USE_COMPRESSED_OOPS;
    return PreRuntimeDispatch::atomic_xchg<expanded_decorators>(addr, new_value);
  }

  template <DecoratorSet decorators>
  inline oop atomic_xchg_reduce_types(HeapWord* addr, oop new_value) {
    const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP;
    return PreRuntimeDispatch::atomic_xchg<expanded_decorators>(addr, new_value);
  }

  template <DecoratorSet decorators, typename T>
  inline T load_reduce_types(T* addr) {
    return PreRuntimeDispatch::load<decorators, T>(addr);
  }

  template <DecoratorSet decorators, typename T>
  inline typename OopOrNarrowOop<T>::type load_reduce_types(narrowOop* addr) {
    const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
                                             INTERNAL_RT_USE_COMPRESSED_OOPS;
    return PreRuntimeDispatch::load<expanded_decorators, typename OopOrNarrowOop<T>::type>(addr);
  }

  template <DecoratorSet decorators, typename T>
  inline oop load_reduce_types(HeapWord* addr) {
    const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP;
    return PreRuntimeDispatch::load<expanded_decorators, oop>(addr);
  }

  template <DecoratorSet decorators, typename T>
  inline bool arraycopy_reduce_types(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
                                     arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
                                     size_t length) {
    return PreRuntimeDispatch::arraycopy<decorators>(src_obj, src_offset_in_bytes, src_raw,
                                                     dst_obj, dst_offset_in_bytes, dst_raw,
                                                     length);
  }

  template <DecoratorSet decorators>
  inline bool arraycopy_reduce_types(arrayOop src_obj, size_t src_offset_in_bytes, HeapWord* src_raw,
                                     arrayOop dst_obj, size_t dst_offset_in_bytes, HeapWord* dst_raw,
                                     size_t length) {
    const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP;
    return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw,
                                                              dst_obj, dst_offset_in_bytes, dst_raw,
                                                              length);
  }

  template <DecoratorSet decorators>
  inline bool arraycopy_reduce_types(arrayOop src_obj, size_t src_offset_in_bytes, narrowOop* src_raw,
                                     arrayOop dst_obj, size_t dst_offset_in_bytes, narrowOop* dst_raw,
                                     size_t length) {
    const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
                                             INTERNAL_RT_USE_COMPRESSED_OOPS;
    return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw,
                                                              dst_obj, dst_offset_in_bytes, dst_raw,
                                                              length);
  }

  // Step 1: Set default decorators. This step remembers if a type was volatile
  // and then sets the MO_RELAXED decorator by default. Otherwise, a default
  // memory ordering is set for the access, and the implied decorator rules
  // are applied to select sensible defaults for decorators that have not been
  // explicitly set. For example, default object referent strength is set to strong.
  // This step also decays the types passed in (e.g. getting rid of CV qualifiers
  // and references from the types). This step also perform some type verification
  // that the passed in types make sense.

  template <DecoratorSet decorators, typename T>
  static void verify_types(){
    // If this fails to compile, then you have sent in something that is
    // not recognized as a valid primitive type to a primitive Access function.
    STATIC_ASSERT((HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value || // oops have already been validated
                   (std::is_pointer<T>::value || std::is_integral<T>::value) ||
                    std::is_floating_point<T>::value)); // not allowed primitive type
  }

  template <DecoratorSet decorators, typename P, typename T>
  inline void store(P* addr, T value) {
    verify_types<decorators, T>();
    using DecayedP = std::decay_t<P>;
    using DecayedT = std::decay_t<T>;
    DecayedT decayed_value = value;
    // If a volatile address is passed in but no memory ordering decorator,
    // set the memory ordering to MO_RELAXED by default.
    const DecoratorSet expanded_decorators = DecoratorFixup<
      (std::is_volatile<P>::value && !HasDecorator<decorators, MO_DECORATOR_MASK>::value) ?
      (MO_RELAXED | decorators) : decorators>::value;
    store_reduce_types<expanded_decorators>(const_cast<DecayedP*>(addr), decayed_value);
  }

  template <DecoratorSet decorators, typename T>
  inline void store_at(oop base, ptrdiff_t offset, T value) {
    verify_types<decorators, T>();
    using DecayedT = std::decay_t<T>;
    DecayedT decayed_value = value;
    const DecoratorSet expanded_decorators = DecoratorFixup<decorators |
                                             (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value ?
                                              INTERNAL_CONVERT_COMPRESSED_OOP : DECORATORS_NONE)>::value;
    PreRuntimeDispatch::store_at<expanded_decorators>(base, offset, decayed_value);
  }

  template <DecoratorSet decorators, typename P, typename T>
  inline T load(P* addr) {
    verify_types<decorators, T>();
    using DecayedP = std::decay_t<P>;
    using DecayedT = std::conditional_t<HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value,
                                        typename OopOrNarrowOop<T>::type,
                                        std::decay_t<T>>;
    // If a volatile address is passed in but no memory ordering decorator,
    // set the memory ordering to MO_RELAXED by default.
    const DecoratorSet expanded_decorators = DecoratorFixup<
      (std::is_volatile<P>::value && !HasDecorator<decorators, MO_DECORATOR_MASK>::value) ?
      (MO_RELAXED | decorators) : decorators>::value;
    return load_reduce_types<expanded_decorators, DecayedT>(const_cast<DecayedP*>(addr));
  }

  template <DecoratorSet decorators, typename T>
  inline T load_at(oop base, ptrdiff_t offset) {
    verify_types<decorators, T>();
    using DecayedT = std::conditional_t<HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value,
                                        typename OopOrNarrowOop<T>::type,
                                        std::decay_t<T>>;
    // Expand the decorators (figure out sensible defaults)
    // Potentially remember if we need compressed oop awareness
    const DecoratorSet expanded_decorators = DecoratorFixup<decorators |
                                             (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value ?
                                              INTERNAL_CONVERT_COMPRESSED_OOP : DECORATORS_NONE)>::value;
    return PreRuntimeDispatch::load_at<expanded_decorators, DecayedT>(base, offset);
  }

  template <DecoratorSet decorators, typename P, typename T>
  inline T atomic_cmpxchg(P* addr, T compare_value, T new_value) {
    verify_types<decorators, T>();
    using DecayedP = std::decay_t<P>;
    using DecayedT = std::decay_t<T>;
    DecayedT new_decayed_value = new_value;
    DecayedT compare_decayed_value = compare_value;
    const DecoratorSet expanded_decorators = DecoratorFixup<
      (!HasDecorator<decorators, MO_DECORATOR_MASK>::value) ?
      (MO_SEQ_CST | decorators) : decorators>::value;
    return atomic_cmpxchg_reduce_types<expanded_decorators>(const_cast<DecayedP*>(addr),
                                                            compare_decayed_value,
                                                            new_decayed_value);
  }

  template <DecoratorSet decorators, typename T>
  inline T atomic_cmpxchg_at(oop base, ptrdiff_t offset, T compare_value, T new_value) {
    verify_types<decorators, T>();
    using DecayedT = std::decay_t<T>;
    DecayedT new_decayed_value = new_value;
    DecayedT compare_decayed_value = compare_value;
    // Determine default memory ordering
    const DecoratorSet expanded_decorators = DecoratorFixup<
      (!HasDecorator<decorators, MO_DECORATOR_MASK>::value) ?
      (MO_SEQ_CST | decorators) : decorators>::value;
    // Potentially remember that we need compressed oop awareness
    const DecoratorSet final_decorators = expanded_decorators |
                                          (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value ?
                                           INTERNAL_CONVERT_COMPRESSED_OOP : DECORATORS_NONE);
    return PreRuntimeDispatch::atomic_cmpxchg_at<final_decorators>(base, offset, compare_decayed_value,
                                                                   new_decayed_value);
  }

  template <DecoratorSet decorators, typename P, typename T>
  inline T atomic_xchg(P* addr, T new_value) {
    verify_types<decorators, T>();
    using DecayedP = std::decay_t<P>;
    using DecayedT = std::decay_t<T>;
    DecayedT new_decayed_value = new_value;
    // atomic_xchg is only available in SEQ_CST flavour.
    const DecoratorSet expanded_decorators = DecoratorFixup<decorators | MO_SEQ_CST>::value;
    return atomic_xchg_reduce_types<expanded_decorators>(const_cast<DecayedP*>(addr),
                                                         new_decayed_value);
  }

  template <DecoratorSet decorators, typename T>
  inline T atomic_xchg_at(oop base, ptrdiff_t offset, T new_value) {
    verify_types<decorators, T>();
    using DecayedT = std::decay_t<T>;
    DecayedT new_decayed_value = new_value;
    // atomic_xchg is only available in SEQ_CST flavour.
    const DecoratorSet expanded_decorators = DecoratorFixup<decorators | MO_SEQ_CST |
                                             (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value ?
                                              INTERNAL_CONVERT_COMPRESSED_OOP : DECORATORS_NONE)>::value;
    return PreRuntimeDispatch::atomic_xchg_at<expanded_decorators>(base, offset, new_decayed_value);
  }

  template <DecoratorSet decorators, typename T>
  inline bool arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, const T* src_raw,
                        arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
                        size_t length) {
    STATIC_ASSERT((HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value ||
                   (std::is_same<T, void>::value || std::is_integral<T>::value) ||
                    std::is_floating_point<T>::value)); // arraycopy allows type erased void elements
    using DecayedT = std::decay_t<T>;
    const DecoratorSet expanded_decorators = DecoratorFixup<decorators | IS_ARRAY | IN_HEAP>::value;
    return arraycopy_reduce_types<expanded_decorators>(src_obj, src_offset_in_bytes, const_cast<DecayedT*>(src_raw),
                                                       dst_obj, dst_offset_in_bytes, const_cast<DecayedT*>(dst_raw),
                                                       length);
  }

  template <DecoratorSet decorators>
  inline void clone(oop src, oop dst, size_t size) {
    const DecoratorSet expanded_decorators = DecoratorFixup<decorators>::value;
    PreRuntimeDispatch::clone<expanded_decorators>(src, dst, size);
  }

  // Infer the type that should be returned from an Access::oop_load.
  template <typename P, DecoratorSet decorators>
  class OopLoadProxy: public StackObj {
  private:
    P *const _addr;
  public:
    explicit OopLoadProxy(P* addr) : _addr(addr) {}

    inline operator oop() {
      return load<decorators | INTERNAL_VALUE_IS_OOP, P, oop>(_addr);
    }

    inline operator narrowOop() {
      return load<decorators | INTERNAL_VALUE_IS_OOP, P, narrowOop>(_addr);
    }

    template <typename T>
    inline bool operator ==(const T& other) const {
      return load<decorators | INTERNAL_VALUE_IS_OOP, P, T>(_addr) == other;
    }

    template <typename T>
    inline bool operator !=(const T& other) const {
      return load<decorators | INTERNAL_VALUE_IS_OOP, P, T>(_addr) != other;
    }

    inline bool operator ==(std::nullptr_t) const {
      return load<decorators | INTERNAL_VALUE_IS_OOP, P, oop>(_addr) == nullptr;
    }

    inline bool operator !=(std::nullptr_t) const {
      return load<decorators | INTERNAL_VALUE_IS_OOP, P, oop>(_addr) != nullptr;
    }
  };

  // Infer the type that should be returned from an Access::load_at.
  template <DecoratorSet decorators>
  class LoadAtProxy: public StackObj {
  private:
    const oop _base;
    const ptrdiff_t _offset;
  public:
    LoadAtProxy(oop base, ptrdiff_t offset) : _base(base), _offset(offset) {}

    template <typename T>
    inline operator T() const {
      return load_at<decorators, T>(_base, _offset);
    }

    template <typename T>
    inline bool operator ==(const T& other) const { return load_at<decorators, T>(_base, _offset) == other; }

    template <typename T>
    inline bool operator !=(const T& other) const { return load_at<decorators, T>(_base, _offset) != other; }
  };

  // Infer the type that should be returned from an Access::oop_load_at.
  template <DecoratorSet decorators>
  class OopLoadAtProxy: public StackObj {
  private:
    const oop _base;
    const ptrdiff_t _offset;
  public:
    OopLoadAtProxy(oop base, ptrdiff_t offset) : _base(base), _offset(offset) {}

    inline operator oop() const {
      return load_at<decorators | INTERNAL_VALUE_IS_OOP, oop>(_base, _offset);
    }

    inline operator narrowOop() const {
      return load_at<decorators | INTERNAL_VALUE_IS_OOP, narrowOop>(_base, _offset);
    }

    template <typename T>
    inline bool operator ==(const T& other) const {
      return load_at<decorators | INTERNAL_VALUE_IS_OOP, T>(_base, _offset) == other;
    }

    template <typename T>
    inline bool operator !=(const T& other) const {
      return load_at<decorators | INTERNAL_VALUE_IS_OOP, T>(_base, _offset) != other;
    }
  };
}

#endif // SHARE_OOPS_ACCESSBACKEND_HPP
