Skip to content
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

8331006: [lworld] Support of null markers for nullable flat fields #1078

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
Expand Up @@ -1855,6 +1855,11 @@ void MacroAssembler::test_field_is_flat(Register flags, Register temp_reg, Label
tbnz(flags, ResolvedFieldEntry::is_flat_shift, is_flat);
}

void MacroAssembler::test_field_has_null_marker(Register flags, Register temp_reg, Label& has_null_marker) {
assert(temp_reg == noreg, "not needed"); // keep signature uniform with x86
tbnz(flags, ResolvedFieldEntry::has_null_marker_shift, has_null_marker);
}

void MacroAssembler::test_oop_prototype_bit(Register oop, Register temp_reg, int32_t test_bit, bool jmp_set, Label& jmp_label) {
Label test_mark_word;
// load mark word
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
Expand Up @@ -649,6 +649,7 @@ class MacroAssembler: public Assembler {
void test_field_is_null_free_inline_type(Register flags, Register temp_reg, Label& is_null_free);
void test_field_is_not_null_free_inline_type(Register flags, Register temp_reg, Label& not_null_free);
void test_field_is_flat(Register flags, Register temp_reg, Label& is_flat);
void test_field_has_null_marker(Register flags, Register temp_reg, Label& has_null_marker);

// Check oops for special arrays, i.e. flat arrays and/or null-free arrays
void test_oop_prototype_bit(Register oop, Register temp_reg, int32_t test_bit, bool jmp_set, Label& jmp_label);
Expand Down
45 changes: 34 additions & 11 deletions src/hotspot/cpu/aarch64/templateTable_aarch64.cpp
Expand Up @@ -172,7 +172,7 @@ void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
Label L_patch_done;

switch (bc) {
case Bytecodes::_fast_qputfield:
case Bytecodes::_fast_vputfield:
case Bytecodes::_fast_aputfield:
case Bytecodes::_fast_bputfield:
case Bytecodes::_fast_zputfield:
Expand Down Expand Up @@ -2817,8 +2817,9 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
__ push(atos);
__ b(Done);
} else {
Label is_flat, nonnull, is_inline_type, rewrite_inline;
Label is_flat, nonnull, is_inline_type, has_null_marker, rewrite_inline;
__ test_field_is_null_free_inline_type(flags, noreg /*temp*/, is_inline_type);
__ test_field_has_null_marker(flags, noreg /*temp*/, has_null_marker);
// Non-inline field case
__ load_heap_oop(r0, field, rscratch1, rscratch2);
__ push(atos);
Expand All @@ -2843,9 +2844,14 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
__ read_flat_field(klass, field_index, off, inline_klass /* temp */, r0);
__ verify_oop(r0);
__ push(atos);
__ b(rewrite_inline);
__ bind(has_null_marker);
call_VM(r0, CAST_FROM_FN_PTR(address, InterpreterRuntime::read_nullable_flat_field), obj, cache);
__ verify_oop(r0);
__ push(atos);
__ bind(rewrite_inline);
if (rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_qgetfield, bc, r1);
patch_bytecode(Bytecodes::_fast_vgetfield, bc, r1);
}
__ b(Done);
}
Expand Down Expand Up @@ -3089,8 +3095,9 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
do_oop_store(_masm, field, r0, IN_HEAP);
__ b(Done);
} else {
Label is_inline_type, is_flat, rewrite_not_inline, rewrite_inline;
Label is_inline_type, is_flat, has_null_marker, rewrite_not_inline, rewrite_inline;
__ test_field_is_null_free_inline_type(flags, noreg /*temp*/, is_inline_type);
__ test_field_has_null_marker(flags, noreg /*temp*/, has_null_marker);
// Not an inline type
pop_and_check_object(obj);
// Store into the field
Expand All @@ -3117,9 +3124,14 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
__ data_for_oop(r0, r0, inline_klass);
__ add(obj, obj, off);
__ access_value_copy(IN_HEAP, r0, obj, inline_klass);
__ b(rewrite_inline);
__ bind(has_null_marker);
assert_different_registers(r0, cache, r19);
pop_and_check_object(r19);
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::write_nullable_flat_field), r19, r0, cache);
__ bind(rewrite_inline);
if (rc == may_rewrite) {
patch_bytecode(Bytecodes::_fast_qputfield, bc, r19, true, byte_no);
patch_bytecode(Bytecodes::_fast_vputfield, bc, r19, true, byte_no);
}
__ b(Done);
}
Expand Down Expand Up @@ -3262,7 +3274,7 @@ void TemplateTable::jvmti_post_fast_field_mod() {
// to do it for every data type, we use the saved values as the
// jvalue object.
switch (bytecode()) { // load values into the jvalue object
case Bytecodes::_fast_qputfield: //fall through
case Bytecodes::_fast_vputfield: //fall through
case Bytecodes::_fast_aputfield: __ push_ptr(r0); break;
case Bytecodes::_fast_bputfield: // fall through
case Bytecodes::_fast_zputfield: // fall through
Expand All @@ -3289,7 +3301,7 @@ void TemplateTable::jvmti_post_fast_field_mod() {
r19, c_rarg2, c_rarg3);

switch (bytecode()) { // restore tos values
case Bytecodes::_fast_qputfield: //fall through
case Bytecodes::_fast_vputfield: //fall through
case Bytecodes::_fast_aputfield: __ pop_ptr(r0); break;
case Bytecodes::_fast_bputfield: // fall through
case Bytecodes::_fast_zputfield: // fall through
Expand Down Expand Up @@ -3340,9 +3352,10 @@ void TemplateTable::fast_storefield(TosState state)

// access field
switch (bytecode()) {
case Bytecodes::_fast_qputfield: //fall through
case Bytecodes::_fast_vputfield:
{
Label is_flat, done;
Label is_flat, has_null_marker, done;
__ test_field_has_null_marker(r3, noreg /* temp */, has_null_marker);
__ null_check(r0);
fparain marked this conversation as resolved.
Show resolved Hide resolved
__ test_field_is_flat(r3, noreg /* temp */, is_flat);
// field is not flat
Expand All @@ -3354,6 +3367,11 @@ void TemplateTable::fast_storefield(TosState state)
__ data_for_oop(r0, r0, r4);
__ lea(rscratch1, field);
__ access_value_copy(IN_HEAP, r0, rscratch1, r4);
__ b(done);
__ bind(has_null_marker);
__ load_field_entry(r4, r1);
__ mov(r1, r2);
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::write_nullable_flat_field), r1, r0, r4);
__ bind(done);
}
break;
Expand Down Expand Up @@ -3452,10 +3470,11 @@ void TemplateTable::fast_accessfield(TosState state)

// access field
switch (bytecode()) {
case Bytecodes::_fast_qgetfield:
case Bytecodes::_fast_vgetfield:
{
Register index = r4, klass = r5, inline_klass = r6, tmp = r7;
Label is_flat, nonnull, Done;
Label is_flat, has_null_marker, nonnull, Done;
__ test_field_has_null_marker(r3, noreg /*temp*/, has_null_marker);
__ test_field_is_flat(r3, noreg /* temp */, is_flat);
// field is not flat
__ load_heap_oop(r0, field, rscratch1, rscratch2);
Expand All @@ -3473,6 +3492,10 @@ void TemplateTable::fast_accessfield(TosState state)
__ ldr(klass, Address(r2, in_bytes(ResolvedFieldEntry::field_holder_offset())));
__ read_flat_field(klass, index, r1, tmp /* temp */, r0);
__ verify_oop(r0);
__ b(Done);
__ bind(has_null_marker);
call_VM(r0, CAST_FROM_FN_PTR(address, InterpreterRuntime::read_nullable_flat_field), r0, r2);
__ verify_oop(r0);
__ bind(Done);
}
break;
Expand Down
6 changes: 6 additions & 0 deletions src/hotspot/cpu/x86/macroAssembler_x86.cpp
Expand Up @@ -3018,6 +3018,12 @@ void MacroAssembler::test_field_is_flat(Register flags, Register temp_reg, Label
jcc(Assembler::notEqual, is_flat);
}

void MacroAssembler::test_field_has_null_marker(Register flags, Register temp_reg, Label& has_null_marker) {
movl(temp_reg, flags);
testl(temp_reg, 1 << ResolvedFieldEntry::has_null_marker_shift);
jcc(Assembler::notEqual, has_null_marker);
}

void MacroAssembler::test_oop_prototype_bit(Register oop, Register temp_reg, int32_t test_bit, bool jmp_set, Label& jmp_label) {
Label test_mark_word;
// load mark word
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/cpu/x86/macroAssembler_x86.hpp
Expand Up @@ -123,6 +123,7 @@ class MacroAssembler: public Assembler {
void test_field_is_null_free_inline_type(Register flags, Register temp_reg, Label& is_null_free);
void test_field_is_not_null_free_inline_type(Register flags, Register temp_reg, Label& not_null_free);
void test_field_is_flat(Register flags, Register temp_reg, Label& is_flat);
void test_field_has_null_marker(Register flags, Register temp_reg, Label& has_null_marker);

// Check oops for special arrays, i.e. flat arrays and/or null-free arrays
void test_oop_prototype_bit(Register oop, Register temp_reg, int32_t test_bit, bool jmp_set, Label& jmp_label);
Expand Down Expand Up @@ -416,7 +417,6 @@ class MacroAssembler: public Assembler {
void data_for_value_array_index(Register array, Register array_klass,
Register index, Register data);


void load_heap_oop(Register dst, Address src, Register tmp1 = noreg,
Register thread_tmp = noreg, DecoratorSet decorators = 0);
void load_heap_oop_not_null(Register dst, Address src, Register tmp1 = noreg,
Expand Down