8316427: Duplicated code for {obj,type}ArrayKlass::array_klass

Reviewed-by: dholmes, adinn
This commit is contained in:
Coleen Phillimore 2023-09-20 14:38:04 +00:00
parent c43ebd34af
commit 9e00949a26
6 changed files with 68 additions and 133 deletions

View File

@ -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<Klass*>* ArrayKlass::compute_secondary_supers(int num_extra_slots,
Array<InstanceKlass*>* transitive_interfaces) {
// interfaces = { cloneable_klass, serializable_klass };

View File

@ -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; }

View File

@ -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

View File

@ -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<ObjArrayKlass*>(cast(const_cast<const Klass*>(k)));
}

View File

@ -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_ATOMIC>::arraycopy<void>(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);

View File

@ -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<TypeArrayKlass*>(cast(const_cast<const Klass*>(k)));
}