diff --git a/src/hotspot/share/oops/arrayKlass.cpp b/src/hotspot/share/oops/arrayKlass.cpp index ecc3da7bd5d..486f317dadd 100644 --- a/src/hotspot/share/oops/arrayKlass.cpp +++ b/src/hotspot/share/oops/arrayKlass.cpp @@ -33,7 +33,7 @@ #include "memory/metaspaceClosure.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" -#include "oops/arrayKlass.hpp" +#include "oops/arrayKlass.inline.hpp" #include "oops/arrayOop.hpp" #include "oops/instanceKlass.hpp" #include "oops/klass.inline.hpp" @@ -116,6 +116,63 @@ void ArrayKlass::complete_create_array_klass(ArrayKlass* k, Klass* super_klass, java_lang_Class::create_mirror(k, Handle(THREAD, k->class_loader()), Handle(THREAD, module), Handle(), Handle(), CHECK); } +ArrayKlass* ArrayKlass::array_klass(int n, TRAPS) { + + assert(dimension() <= n, "check order of chain"); + int dim = dimension(); + if (dim == n) return this; + + // lock-free read needs acquire semantics + if (higher_dimension_acquire() == nullptr) { + + ResourceMark rm(THREAD); + { + // Ensure atomic creation of higher dimensions + MutexLocker mu(THREAD, MultiArray_lock); + + // Check if another thread beat us + if (higher_dimension() == nullptr) { + + // Create multi-dim klass object and link them together + ObjArrayKlass* ak = + ObjArrayKlass::allocate_objArray_klass(class_loader_data(), dim + 1, this, CHECK_NULL); + ak->set_lower_dimension(this); + // use 'release' to pair with lock-free load + release_set_higher_dimension(ak); + assert(ak->is_objArray_klass(), "incorrect initialization of ObjArrayKlass"); + } + } + } + + ObjArrayKlass *ak = higher_dimension(); + THREAD->check_possible_safepoint(); + return ak->array_klass(n, THREAD); +} + +ArrayKlass* ArrayKlass::array_klass_or_null(int n) { + + assert(dimension() <= n, "check order of chain"); + int dim = dimension(); + if (dim == n) return this; + + // lock-free read needs acquire semantics + if (higher_dimension_acquire() == nullptr) { + return nullptr; + } + + ObjArrayKlass *ak = higher_dimension(); + return ak->array_klass_or_null(n); +} + +ArrayKlass* ArrayKlass::array_klass(TRAPS) { + return array_klass(dimension() + 1, THREAD); +} + +ArrayKlass* ArrayKlass::array_klass_or_null() { + return array_klass_or_null(dimension() + 1); +} + + GrowableArray* ArrayKlass::compute_secondary_supers(int num_extra_slots, Array* transitive_interfaces) { // interfaces = { cloneable_klass, serializable_klass }; diff --git a/src/hotspot/share/oops/arrayKlass.hpp b/src/hotspot/share/oops/arrayKlass.hpp index 2c6f401917b..b3d7ca5b32a 100644 --- a/src/hotspot/share/oops/arrayKlass.hpp +++ b/src/hotspot/share/oops/arrayKlass.hpp @@ -53,6 +53,14 @@ class ArrayKlass: public Klass { // Testing operation DEBUG_ONLY(bool is_array_klass_slow() const { return true; }) + // Returns the ObjArrayKlass for n'th dimension. + ArrayKlass* array_klass(int n, TRAPS); + ArrayKlass* array_klass_or_null(int n); + + // Returns the array class with this class as element type. + ArrayKlass* array_klass(TRAPS); + ArrayKlass* array_klass_or_null(); + // Instance variables int dimension() const { return _dimension; } void set_dimension(int dimension) { _dimension = dimension; } diff --git a/src/hotspot/share/oops/objArrayKlass.cpp b/src/hotspot/share/oops/objArrayKlass.cpp index 93695db4e3a..d7cba58b6b3 100644 --- a/src/hotspot/share/oops/objArrayKlass.cpp +++ b/src/hotspot/share/oops/objArrayKlass.cpp @@ -34,7 +34,7 @@ #include "memory/metaspaceClosure.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" -#include "oops/arrayKlass.inline.hpp" +#include "oops/arrayKlass.hpp" #include "oops/instanceKlass.hpp" #include "oops/klass.inline.hpp" #include "oops/objArrayKlass.inline.hpp" @@ -304,63 +304,6 @@ void ObjArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d, } } - -ArrayKlass* ObjArrayKlass::array_klass(int n, TRAPS) { - - assert(dimension() <= n, "check order of chain"); - int dim = dimension(); - if (dim == n) return this; - - // lock-free read needs acquire semantics - if (higher_dimension_acquire() == nullptr) { - - ResourceMark rm(THREAD); - { - // Ensure atomic creation of higher dimensions - MutexLocker mu(THREAD, MultiArray_lock); - - // Check if another thread beat us - if (higher_dimension() == nullptr) { - - // Create multi-dim klass object and link them together - ObjArrayKlass* ak = - ObjArrayKlass::allocate_objArray_klass(class_loader_data(), dim + 1, this, CHECK_NULL); - ak->set_lower_dimension(this); - // use 'release' to pair with lock-free load - release_set_higher_dimension(ak); - assert(ak->is_objArray_klass(), "incorrect initialization of ObjArrayKlass"); - } - } - } - - ObjArrayKlass *ak = higher_dimension(); - THREAD->check_possible_safepoint(); - return ak->array_klass(n, THREAD); -} - -ArrayKlass* ObjArrayKlass::array_klass_or_null(int n) { - - assert(dimension() <= n, "check order of chain"); - int dim = dimension(); - if (dim == n) return this; - - // lock-free read needs acquire semantics - if (higher_dimension_acquire() == nullptr) { - return nullptr; - } - - ObjArrayKlass *ak = higher_dimension(); - return ak->array_klass_or_null(n); -} - -ArrayKlass* ObjArrayKlass::array_klass(TRAPS) { - return array_klass(dimension() + 1, THREAD); -} - -ArrayKlass* ObjArrayKlass::array_klass_or_null() { - return array_klass_or_null(dimension() + 1); -} - bool ObjArrayKlass::can_be_primary_super_slow() const { if (!bottom_klass()->can_be_primary_super()) // array of interfaces diff --git a/src/hotspot/share/oops/objArrayKlass.hpp b/src/hotspot/share/oops/objArrayKlass.hpp index ea1c1482308..6cac60d6335 100644 --- a/src/hotspot/share/oops/objArrayKlass.hpp +++ b/src/hotspot/share/oops/objArrayKlass.hpp @@ -96,14 +96,6 @@ class ObjArrayKlass : public ArrayKlass { arrayOop d, size_t dst_offset, int length, TRAPS); public: - // Returns the ObjArrayKlass for n'th dimension. - virtual ArrayKlass* array_klass(int n, TRAPS); - virtual ArrayKlass* array_klass_or_null(int n); - - // Returns the array class with this class as element type. - virtual ArrayKlass* array_klass(TRAPS); - virtual ArrayKlass* array_klass_or_null(); - static ObjArrayKlass* cast(Klass* k) { return const_cast(cast(const_cast(k))); } diff --git a/src/hotspot/share/oops/typeArrayKlass.cpp b/src/hotspot/share/oops/typeArrayKlass.cpp index 842e37ef78e..38e28edd157 100644 --- a/src/hotspot/share/oops/typeArrayKlass.cpp +++ b/src/hotspot/share/oops/typeArrayKlass.cpp @@ -32,7 +32,7 @@ #include "memory/metadataFactory.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" -#include "oops/arrayKlass.inline.hpp" +#include "oops/arrayKlass.hpp" #include "oops/instanceKlass.hpp" #include "oops/klass.inline.hpp" #include "oops/objArrayKlass.hpp" @@ -170,63 +170,6 @@ void TypeArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos ArrayAccess::arraycopy(s, src_offset, d, dst_offset, (size_t)length << l2es); } -// create a klass of array holding typeArrays -ArrayKlass* TypeArrayKlass::array_klass(int n, TRAPS) { - int dim = dimension(); - assert(dim <= n, "check order of chain"); - if (dim == n) - return this; - - // lock-free read needs acquire semantics - if (higher_dimension_acquire() == nullptr) { - - ResourceMark rm; - JavaThread *jt = THREAD; - { - // Atomic create higher dimension and link into list - MutexLocker mu(THREAD, MultiArray_lock); - - if (higher_dimension() == nullptr) { - Klass* oak = ObjArrayKlass::allocate_objArray_klass( - class_loader_data(), dim + 1, this, CHECK_NULL); - ObjArrayKlass* h_ak = ObjArrayKlass::cast(oak); - h_ak->set_lower_dimension(this); - // use 'release' to pair with lock-free load - release_set_higher_dimension(h_ak); - assert(h_ak->is_objArray_klass(), "incorrect initialization of ObjArrayKlass"); - } - } - } - - ObjArrayKlass* h_ak = higher_dimension(); - THREAD->check_possible_safepoint(); - return h_ak->array_klass(n, THREAD); -} - -// return existing klass of array holding typeArrays -ArrayKlass* TypeArrayKlass::array_klass_or_null(int n) { - int dim = dimension(); - assert(dim <= n, "check order of chain"); - if (dim == n) - return this; - - // lock-free read needs acquire semantics - if (higher_dimension_acquire() == nullptr) { - return nullptr; - } - - ObjArrayKlass* h_ak = higher_dimension(); - return h_ak->array_klass_or_null(n); -} - -ArrayKlass* TypeArrayKlass::array_klass(TRAPS) { - return array_klass(dimension() + 1, THREAD); -} - -ArrayKlass* TypeArrayKlass::array_klass_or_null() { - return array_klass_or_null(dimension() + 1); -} - size_t TypeArrayKlass::oop_size(oop obj) const { assert(obj->is_typeArray(),"must be a type array"); typeArrayOop t = typeArrayOop(obj); diff --git a/src/hotspot/share/oops/typeArrayKlass.hpp b/src/hotspot/share/oops/typeArrayKlass.hpp index 47d235da212..ae23c5324af 100644 --- a/src/hotspot/share/oops/typeArrayKlass.hpp +++ b/src/hotspot/share/oops/typeArrayKlass.hpp @@ -94,14 +94,6 @@ class TypeArrayKlass : public ArrayKlass { inline void oop_oop_iterate_reverse(oop obj, OopClosureType* closure); public: - // Find n'th dimensional array - virtual ArrayKlass* array_klass(int n, TRAPS); - virtual ArrayKlass* array_klass_or_null(int n); - - // Returns the array class with this class as element type - virtual ArrayKlass* array_klass(TRAPS); - virtual ArrayKlass* array_klass_or_null(); - static TypeArrayKlass* cast(Klass* k) { return const_cast(cast(const_cast(k))); }