Skip to content

Re-work of arrays meta-data #1452

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 26 commits into
base: lworld
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 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
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
393 changes: 393 additions & 0 deletions Test.java

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions make/test/BuildMicrobenchmark.gmk
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ $(eval $(call SetupJavaCompilation, BUILD_JDK_MICROBENCHMARK, \
--add-exports java.base/jdk.internal.foreign=ALL-UNNAMED \
--add-exports java.base/jdk.internal.misc=ALL-UNNAMED \
--add-exports java.base/jdk.internal.util=ALL-UNNAMED \
--add-exports java.base/jdk.internal.value=ALL-UNNAMED \
--add-exports java.base/jdk.internal.vm=ALL-UNNAMED \
--add-exports java.base/sun.invoke.util=ALL-UNNAMED \
--add-exports java.base/sun.security.util=ALL-UNNAMED \
Expand Down
12 changes: 9 additions & 3 deletions src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1204,14 +1204,20 @@ void LIRGenerator::do_NewObjectArray(NewObjectArray* x) {
length.load_item_force(FrameMap::r19_opr);
LIR_Opr len = length.result();

ciKlass* obj = (ciKlass*) x->exact_type();
CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info, x->is_null_free());
ciKlass* obj = ciObjArrayKlass::make(x->klass(), true);

bool is_flat = obj->is_loaded() && obj->is_flat_array_klass();
bool is_null_free = obj->is_loaded() && obj->as_array_klass()->is_elem_null_free();

CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info, is_null_free);
if (obj == ciEnv::unloaded_ciobjarrayklass()) {
BAILOUT("encountered unloaded_ciobjarrayklass due to out of memory error");
}

assert(!obj->is_loaded() || obj->get_Klass()->is_refArray_klass() || obj->get_Klass()->is_flatArray_klass(), "We should not allocate arrays of objArrayKlass type");
klass2reg_with_patching(klass_reg, obj, patching_info);
__ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, T_OBJECT, klass_reg, slow_path, true, x->is_null_free());
// TODO Tobias rename arg
__ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, T_OBJECT, klass_reg, slow_path, true, is_null_free || is_flat);

LIR_Opr result = rlock_result(x);
__ move(reg, result);
Expand Down
8 changes: 4 additions & 4 deletions src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -747,16 +747,16 @@ 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, Klass::_lh_array_tag_ref_value); // new "[Ljava/lang/Object;"
__ br(Assembler::EQ, ok);
__ cmpw(t0, Klass::_lh_array_tag_vt_value); // new "[LVT;"
__ cmpw(t0, Klass::_lh_array_tag_flat_value); // new "[LVT;"
__ br(Assembler::EQ, ok);
__ stop("assert(is an object or inline type array klass)");
break;
case C1StubId::new_null_free_array_id:
__ cmpw(t0, Klass::_lh_array_tag_vt_value); // the array can be a flat array.
__ cmpw(t0, Klass::_lh_array_tag_flat_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, Klass::_lh_array_tag_ref_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
6 changes: 0 additions & 6 deletions src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2262,12 +2262,6 @@ void MacroAssembler::test_markword_is_inline_type(Register markword, Label& is_i
br(Assembler::EQ, is_inline_type);
}

void MacroAssembler::test_klass_is_inline_type(Register klass, Register temp_reg, Label& is_inline_type) {
ldrh(temp_reg, Address(klass, Klass::access_flags_offset()));
andr(temp_reg, temp_reg, JVM_ACC_IDENTITY);
cbz(temp_reg, is_inline_type);
}

void MacroAssembler::test_oop_is_not_inline_type(Register object, Register tmp, Label& not_inline_type) {
assert_different_registers(tmp, rscratch1);
cbz(object, not_inline_type);
Expand Down
1 change: 0 additions & 1 deletion src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,6 @@ class MacroAssembler: public Assembler {
void test_markword_is_inline_type(Register markword, Label& is_inline_type);

// inlineKlass queries, kills temp_reg
void test_klass_is_inline_type(Register klass, Register temp_reg, Label& is_inline_type);
void test_oop_is_not_inline_type(Register object, Register tmp, Label& not_inline_type);

void test_field_is_null_free_inline_type(Register flags, Register temp_reg, Label& is_null_free);
Expand Down
2 changes: 1 addition & 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,7 @@ 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 : Klass::_lh_array_tag_ref_value;
Label ok;
__ lwz(R0, in_bytes(Klass::layout_helper_offset()), R4_ARG2);
__ srawi(R0, R0, Klass::_lh_array_tag_shift);
Expand Down
2 changes: 1 addition & 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,7 @@ 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 : Klass::_lh_array_tag_ref_value);
__ mv(t0, tag);
__ beq(t0, tmp, ok);
__ stop("assert(is an array klass)");
Expand Down
3 changes: 1 addition & 2 deletions src/hotspot/cpu/s390/c1_Runtime1_s390.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,8 +396,7 @@ OopMapSet* Runtime1::generate_code_for(C1StubId id, StubAssembler* sasm) {
__ mem2reg_opt(t0, Address(klass, Klass::layout_helper_offset()), false);
__ 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);
? Klass::_lh_array_tag_type_value : Klass::_lh_array_tag_ref_value);
__ compare32_and_branch(t0, tag, Assembler::bcondEqual, ok);
__ stop("assert(is an array klass)");
__ should_not_reach_here();
Expand Down
6 changes: 6 additions & 0 deletions src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1392,11 +1392,13 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
if (!k->is_loaded()) {
klass2reg_with_patching(k_RInfo, op->info_for_patch());
} else {
assert(!k->get_Klass()->is_refArray_klass(), "sanity");
__ mov_metadata(k_RInfo, k->constant_encoding());
}
__ verify_oop(obj);

if (op->fast_check()) {
// TODO Tobias is this correct?
// get object class
// not a safepoint as obj null check happens earlier
if (UseCompressedClassPointers) {
Expand Down Expand Up @@ -2853,6 +2855,8 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
// subtype which we can't check or src is the same array as dst
// but not necessarily exactly of type default_type.
Label known_ok, halt;
assert(default_type->get_Klass()->is_typeArray_klass() || default_type->get_Klass()->is_refArray_klass() || default_type->get_Klass()->is_flatArray_klass(), "should be");

__ mov_metadata(tmp, default_type->constant_encoding());
if (UseCompressedClassPointers) {
__ encode_klass_not_null(tmp, rscratch1);
Expand Down Expand Up @@ -3092,6 +3096,8 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
__ load_klass(tmp, obj, tmp_load_klass);
__ push(tmp);
__ mov_metadata(tmp, exact_klass->constant_encoding());
assert(!exact_klass->get_Klass()->is_array_klass() || exact_klass->get_Klass()->is_typeArray_klass() || exact_klass->get_Klass()->is_refArray_klass() || exact_klass->get_Klass()->is_flatArray_klass(), "should be");

__ cmpptr(tmp, Address(rsp, 0));
__ jcc(Assembler::equal, ok);
__ stop("exact klass and actual klass differ");
Expand Down
12 changes: 9 additions & 3 deletions src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1206,13 +1206,19 @@ void LIRGenerator::do_NewObjectArray(NewObjectArray* x) {
length.load_item_force(FrameMap::rbx_opr);
LIR_Opr len = length.result();

ciKlass* obj = (ciKlass*) x->exact_type();
CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info, x->is_null_free());
ciKlass* obj = ciObjArrayKlass::make(x->klass(), true);

bool is_flat = obj->is_loaded() && obj->is_flat_array_klass();
bool is_null_free = obj->is_loaded() && obj->as_array_klass()->is_elem_null_free();

CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info, is_null_free);
if (obj == ciEnv::unloaded_ciobjarrayklass()) {
BAILOUT("encountered unloaded_ciobjarrayklass due to out of memory error");
}
assert(!obj->is_loaded() || obj->get_Klass()->is_refArray_klass() || obj->get_Klass()->is_flatArray_klass(), "We should not allocate arrays of objArrayKlass type");
klass2reg_with_patching(klass_reg, obj, patching_info);
__ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, T_OBJECT, klass_reg, slow_path, true, x->is_null_free());
// TODO Tobias rename arg
__ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, T_OBJECT, klass_reg, slow_path, true, is_null_free || is_flat);

LIR_Opr result = rlock_result(x);
__ move(reg, result);
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 @@ -911,16 +911,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, (Klass::_lh_array_tag_ref_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, (Klass::_lh_array_tag_ref_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
6 changes: 0 additions & 6 deletions src/hotspot/cpu/x86/macroAssembler_x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2357,12 +2357,6 @@ void MacroAssembler::test_markword_is_inline_type(Register markword, Label& is_i
jcc(Assembler::equal, is_inline_type);
}

void MacroAssembler::test_klass_is_inline_type(Register klass, Register temp_reg, Label& is_inline_type) {
load_unsigned_short(temp_reg, Address(klass, Klass::access_flags_offset()));
testl(temp_reg, JVM_ACC_IDENTITY);
jcc(Assembler::zero, is_inline_type);
}

void MacroAssembler::test_oop_is_not_inline_type(Register object, Register tmp, Label& not_inline_type) {
testptr(object, object);
jcc(Assembler::zero, not_inline_type);
Expand Down
1 change: 0 additions & 1 deletion src/hotspot/cpu/x86/macroAssembler_x86.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ class MacroAssembler: public Assembler {
void test_markword_is_inline_type(Register markword, Label& is_inline_type);

// inlineKlass queries, kills temp_reg
void test_klass_is_inline_type(Register klass, Register temp_reg, Label& is_inline_type);
void test_oop_is_not_inline_type(Register object, Register tmp, Label& not_inline_type);

void test_field_is_null_free_inline_type(Register flags, Register temp_reg, Label& is_null_free);
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/c1/c1_GraphBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3514,6 +3514,7 @@ ValueStack* GraphBuilder::state_at_entry() {
int idx = 0;
if (!method()->is_static()) {
// we should always see the receiver
// TODO Tobias Flat does not imply null-free anymore
state->store_local(idx, new Local(method()->holder(), objectType, idx,
/*receiver*/ true, /*null_free*/ method()->holder()->is_flat_array_klass()));
idx = 1;
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/c1/c1_Instruction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ class Instruction: public CompilationResourceObj {

enum InstructionFlag {
NeedsNullCheckFlag = 0,
NeverNullFlag, // For "Q" signatures
NeverNullFlag,
CanTrapFlag,
DirectCompareFlag,
IsSafepointFlag,
Expand Down
29 changes: 29 additions & 0 deletions src/hotspot/share/c1/c1_LIRGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "ci/ciInlineKlass.hpp"
#include "ci/ciInstance.hpp"
#include "ci/ciObjArray.hpp"
#include "ci/ciObjArrayKlass.hpp"
#include "ci/ciUtilities.hpp"
#include "compiler/compilerDefinitions.inline.hpp"
#include "compiler/compilerOracle.hpp"
Expand Down Expand Up @@ -897,6 +898,12 @@ void LIRGenerator::arraycopy_helper(Intrinsic* x, int* flagsp, ciArrayKlass** ex
}
}
*flagsp = flags;

// TODO Tobias
if (expected_type != nullptr && expected_type->is_obj_array_klass()) {
expected_type = ciObjArrayKlass::make(expected_type->as_array_klass()->element_klass(), true);
}

*expected_typep = (ciArrayKlass*)expected_type;
}

Expand Down Expand Up @@ -1923,6 +1930,7 @@ void LIRGenerator::do_StoreIndexed(StoreIndexed* x) {

if (is_loaded_flat_array) {
// TODO 8350865 This is currently dead code
assert(false, "NOT dead anymore");
if (!x->value()->is_null_free()) {
__ null_check(value.result(), new CodeEmitInfo(range_check_info));
}
Expand Down Expand Up @@ -2814,6 +2822,16 @@ ciKlass* LIRGenerator::profile_type(ciMethodData* md, int md_base_offset, int md
assert(type == nullptr || type->is_klass(), "type should be class");
exact_klass = (type != nullptr && type->is_loaded()) ? (ciKlass*)type : nullptr;

// TODO Tobias
if (exact_klass != nullptr && exact_klass->is_obj_array_klass()) {
if (exact_klass->as_obj_array_klass()->element_klass()->is_inlinetype()) {
// Could be flat, null free etc.
exact_klass = nullptr;
} else {
exact_klass = ciObjArrayKlass::make(exact_klass->as_array_klass()->element_klass(), true);
}
}

do_update = exact_klass == nullptr || ciTypeEntries::valid_ciklass(profiled_k) != exact_klass;
}

Expand Down Expand Up @@ -2851,6 +2869,17 @@ ciKlass* LIRGenerator::profile_type(ciMethodData* md, int md_base_offset, int md
exact_klass = exact_signature_k;
}
}

// TODO Tobias
if (exact_klass != nullptr && exact_klass->is_obj_array_klass()) {
if (exact_klass->as_obj_array_klass()->element_klass()->is_inlinetype()) {
// Could be flat, null free etc.
exact_klass = nullptr;
} else {
exact_klass = ciObjArrayKlass::make(exact_klass->as_array_klass()->element_klass(), true);
}
}

do_update = exact_klass == nullptr || ciTypeEntries::valid_ciklass(profiled_k) != exact_klass;
}

Expand Down
25 changes: 13 additions & 12 deletions src/hotspot/share/c1/c1_Runtime1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,8 +419,8 @@ JRT_ENTRY(void, Runtime1::new_object_array(JavaThread* current, Klass* array_kla
// (This may have to change if this code changes!)
assert(array_klass->is_klass(), "not a class");
Handle holder(current, array_klass->klass_holder()); // keep the klass alive
Klass* elem_klass = ArrayKlass::cast(array_klass)->element_klass();
objArrayOop obj = oopFactory::new_objArray(elem_klass, length, CHECK);
Klass* elem_klass = ObjArrayKlass::cast(array_klass)->element_klass();
objArrayOop obj = oopFactory::new_objArray(elem_klass, length, ArrayKlass::ArrayProperties::DEFAULT, CHECK);
current->set_vm_result_oop(obj);
// This is pretty rare but this runtime patch is stressful to deoptimization
// if we deoptimize here so force a deopt to stress the path.
Expand All @@ -439,17 +439,12 @@ JRT_ENTRY(void, Runtime1::new_null_free_array(JavaThread* current, Klass* array_
// (This may have to change if this code changes!)
assert(array_klass->is_klass(), "not a class");
Handle holder(THREAD, array_klass->klass_holder()); // keep the klass alive
Klass* elem_klass = ArrayKlass::cast(array_klass)->element_klass();
Klass* elem_klass = ObjArrayKlass::cast(array_klass)->element_klass();
assert(elem_klass->is_inline_klass(), "must be");
InlineKlass* vk = InlineKlass::cast(elem_klass);
// Logically creates elements, ensure klass init
elem_klass->initialize(CHECK);
arrayOop obj= nullptr;
if (UseArrayFlattening && vk->has_non_atomic_layout()) {
obj = oopFactory::new_flatArray(elem_klass, length, LayoutKind::NON_ATOMIC_FLAT, CHECK);
} else {
obj = oopFactory::new_null_free_objArray(elem_klass, length, CHECK);
}
arrayOop obj= oopFactory::new_objArray(elem_klass, length, ArrayKlass::ArrayProperties::NULL_RESTRICTED, CHECK);
current->set_vm_result_oop(obj);
// This is pretty rare but this runtime patch is stressful to deoptimization
// if we deoptimize here so force a deopt to stress the path.
Expand Down Expand Up @@ -516,7 +511,7 @@ JRT_ENTRY(void, Runtime1::load_flat_array(JavaThread* current, flatArrayOopDesc*
NOT_PRODUCT(_load_flat_array_slowcase_cnt++;)
assert(array->length() > 0 && index < array->length(), "already checked");
flatArrayHandle vah(current, array);
oop obj = array->read_value_from_flat_array(index, CHECK);
oop obj = array->obj_at(index, CHECK);
current->set_vm_result_oop(obj);
JRT_END

Expand All @@ -531,7 +526,7 @@ JRT_ENTRY(void, Runtime1::store_flat_array(JavaThread* current, flatArrayOopDesc
SharedRuntime::throw_and_post_jvmti_exception(current, vmSymbols::java_lang_NullPointerException());
} else {
assert(array->klass()->is_flatArray_klass(), "should not be called");
array->write_value_to_flat_array(value, index, CHECK);
array->obj_at_put(index, value, CHECK);
}
JRT_END

Expand Down Expand Up @@ -1199,6 +1194,12 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* current, C1StubId stub_id ))
{ Bytecode_anewarray anew(caller_method(), caller_method->bcp_from(bci));
Klass* ek = caller_method->constants()->klass_at(anew.index(), CHECK);
k = ek->array_klass(CHECK);
if (!k->is_typeArray_klass() && !k->is_refArray_klass() && !k->is_flatArray_klass()) {
k = ObjArrayKlass::cast(k)->klass_with_properties(ArrayKlass::ArrayProperties::DEFAULT, THREAD);
}
if (k->is_flatArray_klass()) {
deoptimize_for_flat = true;
}
}
break;
case Bytecodes::_ldc:
Expand Down Expand Up @@ -1252,7 +1253,7 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* current, C1StubId stub_id ))
tty->print_cr("Deoptimizing for patching null-free field reference");
}
if (deoptimize_for_flat) {
tty->print_cr("Deoptimizing for patching flat field reference");
tty->print_cr("Deoptimizing for patching flat field or array reference");
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/share/cds/archiveHeapWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ void ArchiveHeapWriter::ensure_buffer_space(size_t min_bytes) {

objArrayOop ArchiveHeapWriter::allocate_root_segment(size_t offset, int element_count) {
HeapWord* mem = offset_to_buffered_address<HeapWord *>(offset);
memset(mem, 0, objArrayOopDesc::object_size(element_count));
memset(mem, 0, refArrayOopDesc::object_size(element_count));

// The initialization code is copied from MemAllocator::finish and ObjArrayAllocator::initialize.
if (UseCompactObjectHeaders) {
Expand Down Expand Up @@ -220,7 +220,7 @@ void ArchiveHeapWriter::copy_roots_to_buffer(GrowableArrayCHeap<oop, mtClassShar
"Pre-condition: Roots start at aligned boundary: %zu", _buffer_used);

int max_elem_count = ((MIN_GC_REGION_ALIGNMENT - arrayOopDesc::header_size_in_bytes()) / heapOopSize);
assert(objArrayOopDesc::object_size(max_elem_count)*HeapWordSize == MIN_GC_REGION_ALIGNMENT,
assert(refArrayOopDesc::object_size(max_elem_count)*HeapWordSize == MIN_GC_REGION_ALIGNMENT,
"Should match exactly");

HeapRootSegments segments(_buffer_used,
Expand Down Expand Up @@ -334,7 +334,7 @@ void ArchiveHeapWriter::copy_source_objs_to_buffer(GrowableArrayCHeap<oop, mtCla
}

size_t ArchiveHeapWriter::filler_array_byte_size(int length) {
size_t byte_size = objArrayOopDesc::object_size(length) * HeapWordSize;
size_t byte_size = refArrayOopDesc::object_size(length) * HeapWordSize;
return byte_size;
}

Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/cds/archiveUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ bool ArchiveUtils::has_aot_initialized_mirror(InstanceKlass* src_ik) {

size_t HeapRootSegments::size_in_bytes(size_t seg_idx) {
assert(seg_idx < _count, "In range");
return objArrayOopDesc::object_size(size_in_elems(seg_idx)) * HeapWordSize;
return refArrayOopDesc::object_size(size_in_elems(seg_idx)) * HeapWordSize;
}

int HeapRootSegments::size_in_elems(size_t seg_idx) {
Expand Down
Loading