Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
39971d3
First step: creation of refArrayKlass for references arrays
fparain May 9, 2025
460b45b
More fixes for RefArrayKlass
fparain May 14, 2025
b6a098b
Fix aarch64 build
fparain May 14, 2025
275033a
More fixes related to RefArrayKlass
fparain May 21, 2025
6f280b7
Merge remote-tracking branch 'upstream/lworld' into array_klasses
fparain May 22, 2025
ccb5c9b
Repurpose objArrayOop as an abstraction layer
fparain May 30, 2025
19460e9
Reparenting of FlatArrayKlass and cleanup of ObjArrayKlass
fparain Jun 11, 2025
a663392
Split array meta-data for regular object arrays
fparain Jun 26, 2025
4e75990
Move special arrays to new array framework
fparain Jul 1, 2025
787ee0d
Fix the multiple Java mirrors issue
fparain Jul 3, 2025
65199b5
Enable full flattening and fixing tests
fparain Jul 3, 2025
5b4ba85
Untabiby refArrayKlass.hpp
fparain Jul 7, 2025
8e80376
Fix indentation
fparain Jul 7, 2025
2d4c1f3
Untabify again
fparain Jul 7, 2025
332f004
Compiler tests fixes from @TobiHartmann
fparain Jul 7, 2025
9920fdd
Remove obsolete Unsage.isFlatArray API
fparain Jul 7, 2025
c00f61f
Fix copy of zero-length null-restricted arrays
fparain Jul 9, 2025
d199084
Fix microbenchmark using obsolete API
fparain Jul 9, 2025
901ef0d
Revert InstanceKlass::_array_klasses to ObjArrayKlass
fparain Jul 28, 2025
bcbba86
JIT support for new array metadata
TobiHartmann Jul 30, 2025
e0a0cfe
Check for arrays before calling is_identity_class()
fparain Jul 30, 2025
c3b4a34
Some more fixes
TobiHartmann Jul 31, 2025
3e2ff09
Merge branch 'array_klasses' of github.com:fparain/valhalla into arra…
TobiHartmann Jul 31, 2025
864a602
Fix assertion
fparain Jul 31, 2025
8144142
Merge branch 'array_klasses' of https://github.com/fparain/valhalla i…
fparain Jul 31, 2025
d3596f4
Fix arrays layout helper tags
fparain Jul 31, 2025
ec674fd
Fix duplicated field
fparain Aug 8, 2025
10457af
Fix array var handles compilation and invoke tests
liach Aug 11, 2025
efb5111
Merge pull request #3 from liach/fix/parain-array-vh
TobiHartmann Aug 13, 2025
cd068e6
Fixed building CDS in non-preview mode
matias9927 Aug 13, 2025
a4d6a4d
Many more fixes of JIT code
TobiHartmann Aug 14, 2025
eb0e5b9
Removed unnecessary comment
matias9927 Aug 14, 2025
2dd1fa3
Coleen's CDS changes
TobiHartmann Aug 19, 2025
73e10bb
Disabled CDS in preview mode
matias9927 Aug 19, 2025
fb62328
Disable CDS with no_shared_spaces
matias9927 Aug 20, 2025
78f321a
Merge commit 'refs/pull/1452/head' of github.com:openjdk/valhalla int…
matias9927 Aug 20, 2025
285d732
Avoid creating mirror for refined array klasses
matias9927 Aug 21, 2025
29fbe68
Merge pull request #4 from matias9927/array_klasses_cds
TobiHartmann Aug 22, 2025
2268012
Deopt fixes
TobiHartmann Aug 26, 2025
c23fe38
Cleanup
TobiHartmann Aug 26, 2025
09a20e2
Fix misidentification of array kind
fparain Aug 26, 2025
80a9477
Restore flattening flags behavior and other small fixes
fparain Aug 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ OopMapSet* Runtime1::generate_code_for(C1StubId id, StubAssembler* sasm) {
__ stop("assert(is a type array klass)");
break;
case C1StubId::new_object_array_id:
__ cmpw(t0, Klass::_lh_array_tag_obj_value); // new "[Ljava/lang/Object;"
__ cmpw(t0, (UseNewCode2 ? Klass::_lh_array_tag_ref_value : Klass::_lh_array_tag_obj_value)); // new "[Ljava/lang/Object;"
__ br(Assembler::EQ, ok);
__ cmpw(t0, Klass::_lh_array_tag_vt_value); // new "[LVT;"
__ br(Assembler::EQ, ok);
Expand All @@ -756,7 +756,7 @@ OopMapSet* Runtime1::generate_code_for(C1StubId id, StubAssembler* sasm) {
case C1StubId::new_null_free_array_id:
__ cmpw(t0, Klass::_lh_array_tag_vt_value); // the array can be a flat array.
__ br(Assembler::EQ, ok);
__ cmpw(t0, Klass::_lh_array_tag_obj_value); // the array cannot be a flat array (due to InlineArrayElementMaxFlatSize, etc)
__ cmpw(t0, (UseNewCode2 ? Klass::_lh_array_tag_ref_value : Klass::_lh_array_tag_obj_value)); // the array cannot be a flat array (due to the InlineArrayElementMaxFlatSize, etc.)
__ br(Assembler::EQ, ok);
__ stop("assert(is an object or inline type array klass)");
break;
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,8 @@ OopMapSet* Runtime1::generate_code_for(C1StubId id, StubAssembler* sasm) {
#ifdef ASSERT
// Assert object type is really an array of the proper kind.
{
int tag = (id == C1StubId::new_type_array_id) ? Klass::_lh_array_tag_type_value : Klass::_lh_array_tag_obj_value;
int tag = (id == C1StubId::new_type_array_id) ? Klass::_lh_array_tag_type_value :
(UseNewCode2 ? Klass::_lh_array_tag_ref_value : Klass::_lh_array_tag_obj_value);
Label ok;
__ lwz(R0, in_bytes(Klass::layout_helper_offset()), R4_ARG2);
__ srawi(R0, R0, Klass::_lh_array_tag_shift);
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,8 @@ OopMapSet* Runtime1::generate_code_for(C1StubId id, StubAssembler* sasm) {
Register tmp = obj;
__ lwu(tmp, Address(klass, Klass::layout_helper_offset()));
__ sraiw(tmp, tmp, Klass::_lh_array_tag_shift);
int tag = ((id == C1StubId::new_type_array_id) ? Klass::_lh_array_tag_type_value : Klass::_lh_array_tag_obj_value);
int tag = ((id == C1StubId::new_type_array_id) ? Klass::_lh_array_tag_type_value :
(UseNewCode2 ? Klass::_lh_array_tag_ref_value : Klass::_lh_array_tag_obj_value));
__ mv(t0, tag);
__ beq(t0, tmp, ok);
__ stop("assert(is an array klass)");
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/cpu/s390/c1_Runtime1_s390.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ OopMapSet* Runtime1::generate_code_for(C1StubId id, StubAssembler* sasm) {
__ z_sra(t0, Klass::_lh_array_tag_shift);
int tag = ((id == C1StubId::new_type_array_id)
? Klass::_lh_array_tag_type_value
: Klass::_lh_array_tag_obj_value);
: (UseNewCode2 ? Klass::_lh_array_tag_ref_value : Klass::_lh_array_tag_obj_value));
__ compare32_and_branch(t0, tag, Assembler::bcondEqual, ok);
__ stop("assert(is an array klass)");
__ should_not_reach_here();
Expand Down
8 changes: 4 additions & 4 deletions src/hotspot/cpu/x86/c1_Runtime1_x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1121,16 +1121,16 @@ OopMapSet* Runtime1::generate_code_for(C1StubId id, StubAssembler* sasm) {
__ stop("assert(is a type array klass)");
break;
case C1StubId::new_object_array_id:
__ cmpl(t0, Klass::_lh_array_tag_obj_value); // new "[Ljava/lang/Object;"
__ cmpl(t0, (UseNewCode2 ? Klass::_lh_array_tag_ref_value : Klass::_lh_array_tag_obj_value)); // new "[Ljava/lang/Object;"
__ jcc(Assembler::equal, ok);
__ cmpl(t0, Klass::_lh_array_tag_vt_value); // new "[LVT;"
__ cmpl(t0, Klass::_lh_array_tag_flat_value); // new "[LVT;"
__ jcc(Assembler::equal, ok);
__ stop("assert(is an object or inline type array klass)");
break;
case C1StubId::new_null_free_array_id:
__ cmpl(t0, Klass::_lh_array_tag_vt_value); // the array can be a flat array.
__ cmpl(t0, Klass::_lh_array_tag_flat_value); // the array can be a flat array.
__ jcc(Assembler::equal, ok);
__ cmpl(t0, Klass::_lh_array_tag_obj_value); // the array cannot be a flat array (due to InlineArrayElementMaxFlatSize, etc)
__ cmpl(t0, (UseNewCode2 ? Klass::_lh_array_tag_ref_value : Klass::_lh_array_tag_obj_value)); // the array cannot be a flat array (due to InlineArrayElementMaxFlatSize, etc)
__ jcc(Assembler::equal, ok);
__ stop("assert(is an object or inline type array klass)");
break;
Expand Down
4 changes: 3 additions & 1 deletion src/hotspot/share/cds/cppVtables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "oops/instanceStackChunkKlass.hpp"
#include "oops/methodData.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/refArrayKlass.hpp"
#include "oops/typeArrayKlass.hpp"
#include "runtime/arguments.hpp"
#include "utilities/globalDefinitions.hpp"
Expand Down Expand Up @@ -67,7 +68,8 @@
f(ObjArrayKlass) \
f(TypeArrayKlass) \
f(FlatArrayKlass) \
f(InlineKlass)
f(InlineKlass) \
f(RefArrayKlass)

class CppVtableInfo {
intptr_t _vtable_size;
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/jvmci/vmStructs_jvmci.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,7 @@
declare_constant(Klass::_lh_array_tag_shift) \
declare_constant(Klass::_lh_array_tag_type_value) \
declare_constant(Klass::_lh_array_tag_obj_value) \
declare_constant(Klass::_lh_array_tag_ref_value) \
\
declare_constant(markWord::no_hash) \
\
Expand Down
9 changes: 7 additions & 2 deletions src/hotspot/share/oops/arrayKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
#include "oops/refArrayKlass.hpp"
#include "runtime/handles.inline.hpp"

void* ArrayKlass::operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) throw() {
Expand Down Expand Up @@ -159,8 +160,12 @@ ArrayKlass* ArrayKlass::array_klass(int n, TRAPS) {

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, false, CHECK_NULL);
ObjArrayKlass* ak = nullptr;
if (UseNewCode2) {
ak = RefArrayKlass::allocate_refArray_klass(class_loader_data(), dim + 1, this, false, CHECK_NULL);
} else {
ak = ObjArrayKlass::allocate_objArray_klass(class_loader_data(), dim + 1, this, false, CHECK_NULL);
}
// use 'release' to pair with lock-free load
release_set_higher_dimension(ak);
assert(ak->lower_dimension() == this, "lower dimension mismatch");
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/oops/flatArrayKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ jint FlatArrayKlass::array_layout_helper(InlineKlass* vk, LayoutKind lk) {
int esize = log2i_exact(round_up_power_of_2(vk->layout_size_in_bytes(lk)));
int hsize = arrayOopDesc::base_offset_in_bytes(etype);
bool null_free = lk != LayoutKind::NULLABLE_ATOMIC_FLAT;
int lh = Klass::array_layout_helper(_lh_array_tag_vt_value, null_free, hsize, etype, esize);
int lh = Klass::array_layout_helper(_lh_array_tag_flat_value, null_free, hsize, etype, esize);

assert(lh < (int)_lh_neutral_value, "must look like an array layout");
assert(layout_helper_is_array(lh), "correct kind");
Expand Down
9 changes: 8 additions & 1 deletion src/hotspot/share/oops/inlineKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/refArrayKlass.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/safepointVerifiers.hpp"
Expand Down Expand Up @@ -306,7 +307,13 @@ ObjArrayKlass* InlineKlass::null_free_reference_array(TRAPS) {

// Check if update has already taken place
if (null_free_reference_array_klass() == nullptr) {
ObjArrayKlass* k = ObjArrayKlass::allocate_objArray_klass(class_loader_data(), 1, this, true, CHECK_NULL);
ObjArrayKlass* k = nullptr;

if (UseNewCode2) {
k = RefArrayKlass::allocate_refArray_klass(class_loader_data(), 1, this, true, CHECK_NULL);
} else {
k = ObjArrayKlass::allocate_objArray_klass(class_loader_data(), 1, this, true, CHECK_NULL);
}

// use 'release' to pair with lock-free load
Atomic::release_store(adr_null_free_reference_array_klass(), k);
Expand Down
8 changes: 7 additions & 1 deletion src/hotspot/share/oops/instanceKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
#include "oops/recordComponent.hpp"
#include "oops/symbol.hpp"
#include "oops/inlineKlass.hpp"
#include "oops/refArrayKlass.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/jvmtiRedefineClasses.hpp"
#include "prims/jvmtiThreadState.hpp"
Expand Down Expand Up @@ -1813,7 +1814,12 @@ ArrayKlass* InstanceKlass::array_klass(int n, TRAPS) {

// Check if another thread created the array klass while we were waiting for the lock.
if (array_klasses() == nullptr) {
ObjArrayKlass* k = ObjArrayKlass::allocate_objArray_klass(class_loader_data(), 1, this, false, CHECK_NULL);
ObjArrayKlass* k = nullptr;
if (UseNewCode2) {
k = RefArrayKlass::allocate_refArray_klass(class_loader_data(), 1, this, false, CHECK_NULL);
} else {
k = ObjArrayKlass::allocate_objArray_klass(class_loader_data(), 1, this, false, CHECK_NULL);
}
// use 'release' to pair with lock-free load
release_set_array_klasses(k);
}
Expand Down
8 changes: 6 additions & 2 deletions src/hotspot/share/oops/klass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,12 +297,16 @@ jint Klass::array_layout_helper(BasicType etype) {
int hsize = arrayOopDesc::base_offset_in_bytes(etype);
int esize = type2aelembytes(etype);
bool isobj = (etype == T_OBJECT);
int tag = isobj ? _lh_array_tag_obj_value : _lh_array_tag_type_value;
int tag = isobj ? (UseNewCode2 ? _lh_array_tag_ref_value : _lh_array_tag_obj_value) : _lh_array_tag_type_value;
int lh = array_layout_helper(tag, false, hsize, etype, exact_log2(esize));

assert(lh < (int)_lh_neutral_value, "must look like an array layout");
assert(layout_helper_is_array(lh), "correct kind");
assert(layout_helper_is_objArray(lh) == isobj, "correct kind");
if (UseNewCode2) {
assert(layout_helper_is_refArray(lh) == isobj, "correct kind");
} else {
assert(layout_helper_is_objArray(lh) == isobj, "correct kind");
}
assert(layout_helper_is_typeArray(lh) == !isobj, "correct kind");
assert(layout_helper_header_size(lh) == hsize, "correct decode");
assert(layout_helper_element_type(lh) == etype, "correct decode");
Expand Down
54 changes: 33 additions & 21 deletions src/hotspot/share/oops/klass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,22 @@ class Klass : public Metadata {
friend class JVMCIVMStructs;
public:
// Klass Kinds for all subclasses of Klass
enum KlassKind : u2 {
InstanceKlassKind,
InlineKlassKind,
InstanceRefKlassKind,
InstanceMirrorKlassKind,
InstanceClassLoaderKlassKind,
InstanceStackChunkKlassKind,
TypeArrayKlassKind,
FlatArrayKlassKind,
ObjArrayKlassKind,
UnknownKlassKind
};

static const uint KLASS_KIND_COUNT = ObjArrayKlassKind + 1;
enum KlassKind : u2
{
InstanceKlassKind,
InlineKlassKind,
InstanceRefKlassKind,
InstanceMirrorKlassKind,
InstanceClassLoaderKlassKind,
InstanceStackChunkKlassKind,
TypeArrayKlassKind,
ObjArrayKlassKind,
RefArrayKlassKind,
FlatArrayKlassKind,
UnknownKlassKind
};

static const uint KLASS_KIND_COUNT = FlatArrayKlassKind + 1;
protected:

// If you add a new field that points to any metaspace object, you
Expand Down Expand Up @@ -463,18 +465,19 @@ class Klass : public Metadata {
static const int _lh_element_type_mask = right_n_bits(BitsPerByte); // shifted mask
static const int _lh_header_size_shift = BitsPerByte*2;
static const int _lh_header_size_mask = right_n_bits(BitsPerByte); // shifted mask
static const int _lh_array_tag_bits = 3;
static const int _lh_array_tag_bits = 4;
static const int _lh_array_tag_shift = BitsPerInt - _lh_array_tag_bits;

static const unsigned int _lh_array_tag_type_value = 0Xfffffffc;
static const unsigned int _lh_array_tag_vt_value = 0Xfffffffd;
static const unsigned int _lh_array_tag_obj_value = 0Xfffffffe;
static const unsigned int _lh_array_tag_flat_value = 0Xfffffffa;
static const unsigned int _lh_array_tag_ref_value = 0Xfffffff8;
static const unsigned int _lh_array_tag_obj_value = 0Xfffffff9;

// null-free array flag bit under the array tag bits, shift one more to get array tag value
static const int _lh_null_free_shift = _lh_array_tag_shift - 1;
static const int _lh_null_free_mask = 1;

static const jint _lh_array_tag_flat_value_bit_inplace = (jint) (1 << _lh_array_tag_shift);
static const jint _lh_array_tag_flat_value_bit_inplace = (jint) (1 << (_lh_array_tag_shift + 1));

static int layout_helper_size_in_bytes(jint lh) {
assert(lh > (jint)_lh_neutral_value, "must be instance");
Expand All @@ -496,11 +499,18 @@ class Klass : public Metadata {
static bool layout_helper_is_objArray(jint lh) {
return (juint)_lh_array_tag_obj_value == (juint)(lh >> _lh_array_tag_shift);
}
static bool layout_helper_is_refArray(jint lh) {
return (juint)_lh_array_tag_ref_value == (juint)(lh >> _lh_array_tag_shift);
}
static bool layout_helper_is_flatArray(jint lh) {
return (juint)_lh_array_tag_vt_value == (juint)(lh >> _lh_array_tag_shift);
return (juint)_lh_array_tag_flat_value == (juint)(lh >> _lh_array_tag_shift);
}
static bool layout_helper_is_null_free(jint lh) {
assert(layout_helper_is_flatArray(lh) || layout_helper_is_objArray(lh), "must be array of inline types");
if (UseNewCode2) {
assert(layout_helper_is_flatArray(lh) || layout_helper_is_refArray(lh), "must be array of inline types");
} else {
assert(layout_helper_is_flatArray(lh) || layout_helper_is_objArray(lh), "must be array of inline types");
}
return ((lh >> _lh_null_free_shift) & _lh_null_free_mask);
}
static jint layout_helper_set_null_free(jint lh) {
Expand Down Expand Up @@ -687,6 +697,7 @@ class Klass : public Metadata {
virtual bool is_instance_klass_slow() const { return false; }
virtual bool is_array_klass_slow() const { return false; }
virtual bool is_objArray_klass_slow() const { return false; }
virtual bool is_refArray_klass_slow() const { return false; }
virtual bool is_typeArray_klass_slow() const { return false; }
virtual bool is_flatArray_klass_slow() const { return false; }
#endif // ASSERT
Expand Down Expand Up @@ -714,7 +725,8 @@ class Klass : public Metadata {
bool is_array_klass() const { return assert_same_query( _kind >= TypeArrayKlassKind, is_array_klass_slow()); }
bool is_stack_chunk_instance_klass() const { return _kind == InstanceStackChunkKlassKind; }
bool is_flatArray_klass() const { return assert_same_query( _kind == FlatArrayKlassKind, is_flatArray_klass_slow()); }
bool is_objArray_klass() const { return assert_same_query( _kind == ObjArrayKlassKind, is_objArray_klass_slow()); }
bool is_objArray_klass() const { return assert_same_query( _kind == ObjArrayKlassKind || _kind == RefArrayKlassKind, is_objArray_klass_slow()); }
bool is_refArray_klass() const { return assert_same_query( _kind == RefArrayKlassKind, is_refArray_klass_slow()); }
bool is_typeArray_klass() const { return assert_same_query( _kind == TypeArrayKlassKind, is_typeArray_klass_slow()); }
#undef assert_same_query

Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/oops/objArrayKlass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class ObjArrayKlass : public ArrayKlass {
// must add this field to ObjArrayKlass::metaspace_pointers_do().
Klass* _bottom_klass; // The one-dimensional type (InstanceKlass or TypeArrayKlass)

protected:
// Constructor
ObjArrayKlass(int n, Klass* element_klass, Symbol* name, bool null_free);
static ObjArrayKlass* allocate(ClassLoaderData* loader_data, int n, Klass* k, Symbol* name, bool null_free, TRAPS);
Expand Down
2 changes: 2 additions & 0 deletions src/hotspot/share/oops/oopsHierarchy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ typedef class arrayOopDesc* arrayOop;
typedef class objArrayOopDesc* objArrayOop;
typedef class typeArrayOopDesc* typeArrayOop;
typedef class flatArrayOopDesc* flatArrayOop;
typedef class refArrayOopDesc* refArrayOop;

#else

Expand Down Expand Up @@ -157,6 +158,7 @@ DEF_OOP(array);
DEF_OOP(objArray);
DEF_OOP(typeArray);
DEF_OOP(flatArray);
DEF_OOP(refArray);

#endif // CHECK_UNHANDLED_OOPS

Expand Down
Loading