8266017: Refactor the *klass::array_klass_impl code to separate the non-exception-throwing API

Reviewed-by: coleenp, iklam
This commit is contained in:
David Holmes 2021-04-28 20:52:50 +00:00
parent f75dd80254
commit 23180f848f
8 changed files with 86 additions and 72 deletions

View file

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

View file

@ -1200,6 +1200,15 @@ public:
// 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 @@ private:
/* 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,

View file

@ -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()) {

View file

@ -503,15 +503,14 @@ protected:
}
// 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 @@ protected:
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);

View file

@ -310,7 +310,7 @@ 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();
@ -318,7 +318,6 @@ Klass* ObjArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {
// 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 {

View file

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

View file

@ -171,7 +171,7 @@ 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)
@ -179,7 +179,6 @@ Klass* TypeArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {
// 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 {

View file

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