Skip to content
Permalink
Browse files
8266017: Refactor the *klass::array_klass_impl code to separate the n…
…on-exception-throwing API

Reviewed-by: coleenp, iklam
  • Loading branch information
David Holmes committed Apr 28, 2021
1 parent f75dd80 commit 23180f848f068434d018b741db6f34cd4b6da55d
Showing 8 changed files with 85 additions and 71 deletions.
@@ -1427,11 +1427,9 @@ void InstanceKlass::check_valid_for_instantiation(bool throwError, TRAPS) {
}
}

Klass* InstanceKlass::array_klass_impl(bool or_null, int n, TRAPS) {
Klass* InstanceKlass::array_klass(int n, TRAPS) {
// Need load-acquire for lock-free read
if (array_klasses_acquire() == NULL) {
if (or_null) return NULL;

ResourceMark rm(THREAD);
JavaThread *jt = THREAD->as_Java_thread();
{
@@ -1446,16 +1444,27 @@ Klass* InstanceKlass::array_klass_impl(bool or_null, int n, TRAPS) {
}
}
}
// _this will always be set at this point
// array_klasses() will always be set at this point
ObjArrayKlass* oak = array_klasses();
if (or_null) {
return oak->array_klass(n, THREAD);
}

Klass* InstanceKlass::array_klass_or_null(int n) {
// Need load-acquire for lock-free read
ObjArrayKlass* oak = array_klasses_acquire();
if (oak == NULL) {
return NULL;
} else {
return oak->array_klass_or_null(n);
}
return oak->array_klass(n, THREAD);
}

Klass* InstanceKlass::array_klass_impl(bool or_null, TRAPS) {
return array_klass_impl(or_null, 1, THREAD);
Klass* InstanceKlass::array_klass(TRAPS) {
return array_klass(1, THREAD);
}

Klass* InstanceKlass::array_klass_or_null() {
return array_klass_or_null(1);
}

static int call_class_initializer_counter = 0; // for debugging
@@ -1200,6 +1200,15 @@ class InstanceKlass: public Klass {
// cannot lock it (like the mirror).
// It has to be an object not a Mutex because it's held through java calls.
oop init_lock() const;

// Returns the array class for the n'th dimension
virtual Klass* array_klass(int n, TRAPS);
virtual Klass* array_klass_or_null(int n);

// Returns the array class with this class as element type
virtual Klass* array_klass(TRAPS);
virtual Klass* array_klass_or_null();

private:
void fence_and_clear_init_lock();

@@ -1211,12 +1220,6 @@ class InstanceKlass: public Klass {
/* jni_id_for_impl for jfieldID only */
JNIid* jni_id_for_impl (int offset);

// Returns the array class for the n'th dimension
Klass* array_klass_impl(bool or_null, int n, TRAPS);

// Returns the array class with this class as element type
Klass* array_klass_impl(bool or_null, TRAPS);

// find a local method (returns NULL if not found)
Method* find_method_impl(const Symbol* name,
const Symbol* signature,
@@ -644,33 +644,6 @@ void Klass::set_archived_java_mirror(oop m) {
}
#endif // INCLUDE_CDS_JAVA_HEAP

Klass* Klass::array_klass_or_null(int rank) {
EXCEPTION_MARK;
// No exception can be thrown by array_klass_impl when called with or_null == true.
// (In anycase, the execption mark will fail if it do so)
return array_klass_impl(true, rank, THREAD);
}


Klass* Klass::array_klass_or_null() {
EXCEPTION_MARK;
// No exception can be thrown by array_klass_impl when called with or_null == true.
// (In anycase, the execption mark will fail if it do so)
return array_klass_impl(true, THREAD);
}


Klass* Klass::array_klass_impl(bool or_null, int rank, TRAPS) {
fatal("array_klass should be dispatched to InstanceKlass, ObjArrayKlass or TypeArrayKlass");
return NULL;
}


Klass* Klass::array_klass_impl(bool or_null, TRAPS) {
fatal("array_klass should be dispatched to InstanceKlass, ObjArrayKlass or TypeArrayKlass");
return NULL;
}

void Klass::check_array_allocation_length(int length, int max_length, TRAPS) {
if (length > max_length) {
if (!THREAD->in_retryable_allocation()) {
@@ -503,15 +503,14 @@ class Klass : public Metadata {
}

// array class with specific rank
Klass* array_klass(int rank, TRAPS) { return array_klass_impl(false, rank, THREAD); }
virtual Klass* array_klass(int rank, TRAPS) = 0;

// array class with this klass as element type
Klass* array_klass(TRAPS) { return array_klass_impl(false, THREAD); }
virtual Klass* array_klass(TRAPS) = 0;

// These will return NULL instead of allocating on the heap:
// NB: these can block for a mutex, like other functions with TRAPS arg.
Klass* array_klass_or_null(int rank);
Klass* array_klass_or_null();
virtual Klass* array_klass_or_null(int rank) = 0;
virtual Klass* array_klass_or_null() = 0;

virtual oop protection_domain() const = 0;

@@ -520,8 +519,6 @@ class Klass : public Metadata {
inline oop klass_holder() const;

protected:
virtual Klass* array_klass_impl(bool or_null, int rank, TRAPS);
virtual Klass* array_klass_impl(bool or_null, TRAPS);

// Error handling when length > max_length or length < 0
static void check_array_allocation_length(int length, int max_length, TRAPS);
@@ -310,15 +310,14 @@ void ObjArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d,
}


Klass* ObjArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {
Klass* 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() == NULL) {
if (or_null) return NULL;

ResourceMark rm(THREAD);
{
@@ -341,15 +340,31 @@ Klass* ObjArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {
}

ObjArrayKlass *ak = ObjArrayKlass::cast(higher_dimension());
if (or_null) {
return ak->array_klass_or_null(n);
}
THREAD->as_Java_thread()->check_possible_safepoint();
return ak->array_klass(n, THREAD);
}

Klass* ObjArrayKlass::array_klass_impl(bool or_null, TRAPS) {
return array_klass_impl(or_null, dimension() + 1, THREAD);
Klass* 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() == NULL) {
return NULL;
}

ObjArrayKlass *ak = ObjArrayKlass::cast(higher_dimension());
return ak->array_klass_or_null(n);
}

Klass* ObjArrayKlass::array_klass(TRAPS) {
return array_klass(dimension() + 1, THREAD);
}

Klass* ObjArrayKlass::array_klass_or_null() {
return array_klass_or_null(dimension() + 1);
}

bool ObjArrayKlass::can_be_primary_super_slow() const {
@@ -95,14 +95,14 @@ class ObjArrayKlass : public ArrayKlass {
void do_copy(arrayOop s, size_t src_offset,
arrayOop d, size_t dst_offset,
int length, TRAPS);
protected:
public:
// Returns the ObjArrayKlass for n'th dimension.
virtual Klass* array_klass_impl(bool or_null, int n, TRAPS);
virtual Klass* array_klass(int n, TRAPS);
virtual Klass* array_klass_or_null(int n);

// Returns the array class with this class as element type.
virtual Klass* array_klass_impl(bool or_null, TRAPS);

public:
virtual Klass* array_klass(TRAPS);
virtual Klass* array_klass_or_null();

static ObjArrayKlass* cast(Klass* k) {
return const_cast<ObjArrayKlass*>(cast(const_cast<const Klass*>(k)));
@@ -171,15 +171,14 @@ void TypeArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos
}

// create a klass of array holding typeArrays
Klass* TypeArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {
Klass* 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() == NULL) {
if (or_null) return NULL;

ResourceMark rm;
JavaThread *jt = THREAD->as_Java_thread();
@@ -200,15 +199,32 @@ Klass* TypeArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {
}

ObjArrayKlass* h_ak = ObjArrayKlass::cast(higher_dimension());
if (or_null) {
return h_ak->array_klass_or_null(n);
}
THREAD->as_Java_thread()->check_possible_safepoint();
return h_ak->array_klass(n, THREAD);
}

Klass* TypeArrayKlass::array_klass_impl(bool or_null, TRAPS) {
return array_klass_impl(or_null, dimension() + 1, THREAD);
// return existing klass of array holding typeArrays
Klass* 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() == NULL) {
return NULL;
}

ObjArrayKlass* h_ak = ObjArrayKlass::cast(higher_dimension());
return h_ak->array_klass_or_null(n);
}

Klass* TypeArrayKlass::array_klass(TRAPS) {
return array_klass(dimension() + 1, THREAD);
}

Klass* TypeArrayKlass::array_klass_or_null() {
return array_klass_or_null(dimension() + 1);
}

int TypeArrayKlass::oop_size(oop obj) const {
@@ -93,14 +93,15 @@ class TypeArrayKlass : public ArrayKlass {
template <typename T, typename OopClosureType>
inline void oop_oop_iterate_reverse(oop obj, OopClosureType* closure);

protected:
public:
// Find n'th dimensional array
virtual Klass* array_klass_impl(bool or_null, int n, TRAPS);
virtual Klass* array_klass(int n, TRAPS);
virtual Klass* array_klass_or_null(int n);

// Returns the array class with this class as element type
virtual Klass* array_klass_impl(bool or_null, TRAPS);
virtual Klass* array_klass(TRAPS);
virtual Klass* array_klass_or_null();

public:
static TypeArrayKlass* cast(Klass* k) {
return const_cast<TypeArrayKlass*>(cast(const_cast<const Klass*>(k)));
}

1 comment on commit 23180f8

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 23180f8 Apr 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.