Skip to content

Commit 8477926

Browse files
committed
8383997: [lworld] Buffering via SharedRuntime::store_inline_type_fields_to_buf is slow
Reviewed-by: mchevalier
1 parent 530e74c commit 8477926

3 files changed

Lines changed: 50 additions & 17 deletions

File tree

src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12685,20 +12685,30 @@ class StubGenerator: public StubCodeGenerator {
1268512685
__ ldpd(j_farg3, j_farg2, Address(__ post(sp, 2 * wordSize)));
1268612686
__ ldpd(j_farg1, j_farg0, Address(__ post(sp, 2 * wordSize)));
1268712687

12688-
__ leave();
12689-
1269012688
// check for pending exceptions
1269112689
Label pending;
1269212690
__ ldr(rscratch1, Address(rthread, in_bytes(Thread::pending_exception_offset())));
1269312691
__ cbnz(rscratch1, pending);
1269412692

1269512693
if (has_res) {
12694+
// We just called SharedRuntime::store_inline_type_fields_to_buf. Check if we still
12695+
// need to initialize the buffer and if so, call the inline class specific pack handler.
12696+
Label skip_pack;
1269612697
__ get_vm_result_oop(r0, rthread);
12698+
__ get_vm_result_metadata(rscratch1, rthread);
12699+
__ cbz(rscratch1, skip_pack);
12700+
__ ldr(rscratch1, Address(rscratch1, InlineKlass::adr_members_offset()));
12701+
__ ldr(rscratch1, Address(rscratch1, InlineKlass::pack_handler_offset()));
12702+
__ blr(rscratch1);
12703+
__ membar(Assembler::StoreStore);
12704+
__ bind(skip_pack);
1269712705
}
1269812706

12707+
__ leave();
1269912708
__ ret(lr);
1270012709

1270112710
__ bind(pending);
12711+
__ leave();
1270212712
__ far_jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
1270312713

1270412714
// -------------

src/hotspot/cpu/x86/stubGenerator_x86_64.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "gc/shared/barrierSetNMethod.hpp"
3333
#include "gc/shared/gc_globals.hpp"
3434
#include "memory/universe.hpp"
35+
#include "oops/inlineKlass.hpp"
3536
#include "prims/jvmtiExport.hpp"
3637
#include "prims/upcallLinker.hpp"
3738
#include "runtime/arguments.hpp"
@@ -5002,7 +5003,18 @@ address StubGenerator::generate_return_value_stub(address destination, const cha
50025003
__ jcc(Assembler::notEqual, pending);
50035004

50045005
if (has_res) {
5006+
// We just called SharedRuntime::store_inline_type_fields_to_buf. Check if we still
5007+
// need to initialize the buffer and if so, call the inline class specific pack handler.
5008+
Label skip_pack;
50055009
__ get_vm_result_oop(rax);
5010+
__ get_vm_result_metadata(rscratch1);
5011+
__ testptr(rscratch1, rscratch1);
5012+
__ jcc(Assembler::zero, skip_pack);
5013+
__ movptr(rscratch1, Address(rscratch1, InlineKlass::adr_members_offset()));
5014+
__ movptr(rscratch1, Address(rscratch1, InlineKlass::pack_handler_offset()));
5015+
__ call(rscratch1);
5016+
__ membar(Assembler::StoreStore);
5017+
__ bind(skip_pack);
50065018
}
50075019

50085020
__ ret(0);

src/hotspot/share/runtime/sharedRuntime.cpp

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4291,32 +4291,43 @@ JRT_END
42914291
// from field's values in registers.
42924292
JRT_BLOCK_ENTRY(void, SharedRuntime::store_inline_type_fields_to_buf(JavaThread* current, intptr_t res))
42934293
{
4294-
ResourceMark rm;
4295-
RegisterMap reg_map(current,
4296-
RegisterMap::UpdateMap::include,
4297-
RegisterMap::ProcessFrames::include,
4298-
RegisterMap::WalkContinuation::skip);
4299-
frame stubFrame = current->last_frame();
4300-
frame callerFrame = stubFrame.sender(&reg_map);
4301-
4302-
#ifdef ASSERT
4303-
InlineKlass* verif_vk = InlineKlass::returned_inline_klass(reg_map);
4304-
#endif
4305-
43064294
if (!is_set_nth_bit(res, 0)) {
43074295
// We're not returning with inline type fields in registers (the
43084296
// calling convention didn't allow it for this inline klass)
43094297
assert(!Metaspace::contains((void*)res), "should be oop or pointer in buffer area");
43104298
current->set_vm_result_oop((oopDesc*)res);
4311-
assert(verif_vk == nullptr, "broken calling convention");
4299+
current->set_vm_result_metadata(nullptr);
43124300
return;
43134301
}
43144302

43154303
clear_nth_bit(res, 0);
43164304
InlineKlass* vk = (InlineKlass*)res;
4317-
assert(verif_vk == vk, "broken calling convention");
43184305
assert(Metaspace::contains((void*)res), "should be klass");
43194306

4307+
if (!vk->contains_oops()) {
4308+
// No oop fields. Initialize the fields by calling the pack handler from
4309+
// the stub which is much faster (see 'generate_return_value_stub').
4310+
// Signal this by setting the metadata result to the value klass.
4311+
JRT_BLOCK;
4312+
{
4313+
oop vt = vk->allocate_instance(CHECK);
4314+
current->set_vm_result_oop(vt);
4315+
current->set_vm_result_metadata(vk);
4316+
}
4317+
JRT_BLOCK_END;
4318+
return;
4319+
}
4320+
4321+
ResourceMark rm;
4322+
RegisterMap reg_map(current,
4323+
RegisterMap::UpdateMap::include,
4324+
RegisterMap::ProcessFrames::include,
4325+
RegisterMap::WalkContinuation::skip);
4326+
frame stubFrame = current->last_frame();
4327+
stubFrame.sender(&reg_map);
4328+
4329+
assert(vk == InlineKlass::returned_inline_klass(reg_map), "broken calling convention");
4330+
43204331
// Allocate handles for every oop field so they are safe in case of
43214332
// a safepoint when allocating
43224333
GrowableArray<Handle> handles;
@@ -4325,9 +4336,9 @@ JRT_BLOCK_ENTRY(void, SharedRuntime::store_inline_type_fields_to_buf(JavaThread*
43254336
// It's unsafe to safepoint until we are here
43264337
JRT_BLOCK;
43274338
{
4328-
JavaThread* THREAD = current;
43294339
oop vt = vk->realloc_result(reg_map, handles, CHECK);
43304340
current->set_vm_result_oop(vt);
4341+
current->set_vm_result_metadata(nullptr);
43314342
}
43324343
JRT_BLOCK_END;
43334344
}

0 commit comments

Comments
 (0)