Skip to content

Commit cb62ea3

Browse files
authored
Update (2023.05.17, 2nd)
30554: LA port of 8301995: Move invokedynamic resolution information out of ConstantPoolCacheEntry 30553: LA port of 8304301: Remove the global option SuperWordMaxVectorSize 30552: LA port of 8231349: Move intrinsic stubs generation to compiler runtime initialization code
1 parent 979f814 commit cb62ea3

8 files changed

+168
-59
lines changed

src/hotspot/cpu/loongarch/globals_loongarch.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
3-
* Copyright (c) 2015, 2022, Loongson Technology. All rights reserved.
3+
* Copyright (c) 2015, 2023, Loongson Technology. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
66
* This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,8 @@ define_pd_global(bool, ImplicitNullChecks, true); // Generate code for im
3636
define_pd_global(bool, TrapBasedNullChecks, false);
3737
define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs passed to check cast
3838

39+
define_pd_global(bool, DelayCompilerStubsGeneration, COMPILER2_OR_JVMCI);
40+
3941
define_pd_global(uintx, CodeCacheSegmentSize, 64 COMPILER1_AND_COMPILER2_PRESENT(+64)); // Tiered compilation has large code-entry alignment.
4042

4143
// Ideally, this should be cache line size,

src/hotspot/cpu/loongarch/interp_masm_loongarch.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ class InterpreterMacroAssembler: public MacroAssembler {
120120
void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2));
121121
void get_method_counters(Register method, Register mcs, Label& skip);
122122

123+
void load_resolved_indy_entry(Register cache, Register index);
124+
123125
// load cpool->resolved_references(index);
124126
void load_resolved_reference_at_index(Register result, Register index, Register tmp);
125127

src/hotspot/cpu/loongarch/interp_masm_loongarch_64.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,18 @@ void InterpreterMacroAssembler::get_method_counters(Register method,
323323
bind(has_counters);
324324
}
325325

326+
void InterpreterMacroAssembler::load_resolved_indy_entry(Register cache, Register index) {
327+
// Get index out of bytecode pointer, get_cache_entry_pointer_at_bcp
328+
get_cache_index_at_bcp(index, 1, sizeof(u4));
329+
// Get address of invokedynamic array
330+
ld_d(cache, FP, frame::interpreter_frame_cache_offset * wordSize);
331+
ld_d(cache, Address(cache, in_bytes(ConstantPoolCache::invokedynamic_entries_offset())));
332+
// Scale the index to be the entry index * sizeof(ResolvedInvokeDynamicInfo)
333+
slli_d(index, index, log2i_exact(sizeof(ResolvedIndyEntry)));
334+
addi_d(cache, cache, Array<ResolvedIndyEntry>::base_offset_in_bytes());
335+
add_d(cache, cache, index);
336+
}
337+
326338
// Load object from cpool->resolved_references(index)
327339
void InterpreterMacroAssembler::load_resolved_reference_at_index(
328340
Register result, Register index, Register tmp) {

src/hotspot/cpu/loongarch/loongarch_64.ad

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,10 @@ const int Matcher::scalable_vector_reg_size(const BasicType bt) {
11031103
return -1;
11041104
}
11051105

1106+
const int Matcher::superword_max_vector_size(const BasicType bt) {
1107+
return Matcher::max_vector_size(bt);
1108+
}
1109+
11061110
// Vector ideal reg
11071111
const uint Matcher::vector_ideal_reg(int size) {
11081112
assert(MaxVectorSize == 16 || MaxVectorSize == 32, "");

src/hotspot/cpu/loongarch/stubGenerator_loongarch_64.cpp

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5505,7 +5505,7 @@ class StubGenerator: public StubCodeGenerator {
55055505
};
55065506

55075507
// Initialization
5508-
void generate_initial() {
5508+
void generate_initial_stubs() {
55095509
// Generates all stubs and initializes the entry points
55105510

55115511
//-------------------------------------------------------------
@@ -5529,6 +5529,11 @@ class StubGenerator: public StubCodeGenerator {
55295529
CAST_FROM_FN_PTR(address,
55305530
SharedRuntime::throw_delayed_StackOverflowError));
55315531

5532+
// Initialize table for copy memory (arraycopy) check.
5533+
if (UnsafeCopyMemory::_table == nullptr) {
5534+
UnsafeCopyMemory::create_table(8);
5535+
}
5536+
55325537
if (UseCRC32Intrinsics) {
55335538
// set table address before stub generation which use it
55345539
StubRoutines::_crc_table_adr = (address)StubRoutines::la::_crc_table;
@@ -5540,7 +5545,7 @@ class StubGenerator: public StubCodeGenerator {
55405545
}
55415546
}
55425547

5543-
void generate_phase1() {
5548+
void generate_continuation_stubs() {
55445549
// Continuation stubs:
55455550
StubRoutines::_cont_thaw = generate_cont_thaw();
55465551
StubRoutines::_cont_returnBarrier = generate_cont_returnBarrier();
@@ -5550,7 +5555,7 @@ class StubGenerator: public StubCodeGenerator {
55505555
JFR_ONLY(StubRoutines::_jfr_write_checkpoint = StubRoutines::_jfr_write_checkpoint_stub->entry_point();)
55515556
}
55525557

5553-
void generate_all() {
5558+
void generate_final_stubs() {
55545559
// Generates all stubs and initializes the entry points
55555560

55565561
// These entry points require SharedInfo::stack0 to be set up in
@@ -5571,10 +5576,6 @@ class StubGenerator: public StubCodeGenerator {
55715576
CAST_FROM_FN_PTR(address,
55725577
SharedRuntime::throw_NullPointerException_at_call));
55735578

5574-
StubRoutines::la::_vector_iota_indices = generate_iota_indices("iota_indices");
5575-
5576-
// entry points that are platform specific
5577-
55785579
// support for verify_oop (must happen after universe_init)
55795580
if (VerifyOops) {
55805581
StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop();
@@ -5591,10 +5592,14 @@ class StubGenerator: public StubCodeGenerator {
55915592
StubRoutines::_dcos = generate_dsin_dcos(/* isCos = */ true);
55925593
}
55935594

5594-
if (UseBigIntegerShiftIntrinsic) {
5595-
StubRoutines::_bigIntegerLeftShiftWorker = generate_bigIntegerLeftShift();
5595+
BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
5596+
if (bs_nm != NULL) {
5597+
StubRoutines::la::_method_entry_barrier = generate_method_entry_barrier();
55965598
}
5599+
}
55975600

5601+
void generate_compiler_stubs() {
5602+
#if COMPILER2_OR_JVMCI
55985603
#ifdef COMPILER2
55995604
if (UseMulAddIntrinsic) {
56005605
StubRoutines::_mulAdd = generate_mulAdd();
@@ -5613,8 +5618,14 @@ class StubGenerator: public StubCodeGenerator {
56135618
// because it's faster for the sizes of modulus we care about.
56145619
StubRoutines::_montgomerySquare = g.generate_multiply();
56155620
}
5621+
5622+
if (UseBigIntegerShiftIntrinsic) {
5623+
StubRoutines::_bigIntegerLeftShiftWorker = generate_bigIntegerLeftShift();
5624+
}
56165625
#endif
56175626

5627+
StubRoutines::la::_vector_iota_indices = generate_iota_indices("iota_indices");
5628+
56185629
if (UseAESIntrinsics) {
56195630
StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock(false);
56205631
StubRoutines::_aescrypt_decryptBlock = generate_aescrypt_decryptBlock(false);
@@ -5640,28 +5651,31 @@ class StubGenerator: public StubCodeGenerator {
56405651

56415652
generate_string_indexof_stubs();
56425653

5643-
BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
5644-
if (bs_nm != NULL) {
5645-
StubRoutines::la::_method_entry_barrier = generate_method_entry_barrier();
5646-
}
5654+
#endif // COMPILER2_OR_JVMCI
56475655
}
56485656

56495657
public:
5650-
StubGenerator(CodeBuffer* code, int phase) : StubCodeGenerator(code) {
5651-
if (phase == 0) {
5652-
generate_initial();
5653-
} else if (phase == 1) {
5654-
generate_phase1(); // stubs that must be available for the interpreter
5655-
} else {
5656-
generate_all();
5657-
}
5658+
StubGenerator(CodeBuffer* code, StubsKind kind) : StubCodeGenerator(code) {
5659+
switch(kind) {
5660+
case Initial_stubs:
5661+
generate_initial_stubs();
5662+
break;
5663+
case Continuation_stubs:
5664+
generate_continuation_stubs();
5665+
break;
5666+
case Compiler_stubs:
5667+
generate_compiler_stubs();
5668+
break;
5669+
case Final_stubs:
5670+
generate_final_stubs();
5671+
break;
5672+
default:
5673+
fatal("unexpected stubs kind: %d", kind);
5674+
break;
5675+
};
56585676
}
56595677
}; // end class declaration
56605678

5661-
#define UCM_TABLE_MAX_ENTRIES 7
5662-
void StubGenerator_generate(CodeBuffer* code, int phase) {
5663-
if (UnsafeCopyMemory::_table == NULL) {
5664-
UnsafeCopyMemory::create_table(UCM_TABLE_MAX_ENTRIES);
5665-
}
5666-
StubGenerator g(code, phase);
5679+
void StubGenerator_generate(CodeBuffer* code, StubCodeGenerator::StubsKind kind) {
5680+
StubGenerator g(code, kind);
56675681
}

src/hotspot/cpu/loongarch/stubRoutines_loongarch.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,11 @@ static bool returns_to_call_stub(address return_pc){
3535
}
3636

3737
enum platform_dependent_constants {
38-
code_size1 = 20000, // simply increase if too small (assembler will crash if too small)
39-
code_size2 = 60000 // simply increase if too small (assembler will crash if too small)
38+
// simply increase sizes if too small (assembler will crash if too small)
39+
_initial_stubs_code_size = 20000,
40+
_continuation_stubs_code_size = 2000,
41+
_compiler_stubs_code_size = 60000,
42+
_final_stubs_code_size = 60000
4043
};
4144

4245
class la {

src/hotspot/cpu/loongarch/templateInterpreterGenerator_loongarch.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -585,13 +585,17 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
585585

586586
const Register cache = T4;
587587
const Register index = T3;
588-
__ get_cache_and_index_at_bcp(cache, index, 1, index_size);
589-
590-
const Register flags = cache;
591-
__ alsl_d(AT, index, cache, Address::times_ptr - 1);
592-
__ ld_w(flags, AT, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
593-
__ andi(flags, flags, ConstantPoolCacheEntry::parameter_size_mask);
594-
__ alsl_d(SP, flags, SP, Interpreter::logStackElementSize - 1);
588+
if (index_size == sizeof(u4)) {
589+
__ load_resolved_indy_entry(cache, index);
590+
__ ld_hu(cache, Address(cache, in_bytes(ResolvedIndyEntry::num_parameters_offset())));
591+
__ alsl_d(SP, cache, SP, Interpreter::logStackElementSize - 1);
592+
} else {
593+
__ get_cache_and_index_at_bcp(cache, index, 1, index_size);
594+
__ alsl_d(AT, index, cache, Address::times_ptr - 1);
595+
__ ld_d(cache, AT, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
596+
__ andi(cache, cache, ConstantPoolCacheEntry::parameter_size_mask);
597+
__ alsl_d(SP, cache, SP, Interpreter::logStackElementSize - 1);
598+
}
595599

596600
__ check_and_handle_popframe(TREG);
597601
__ check_and_handle_earlyret(TREG);

src/hotspot/cpu/loongarch/templateTable_loongarch_64.cpp

Lines changed: 90 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2256,14 +2256,82 @@ void TemplateTable::load_field_cp_cache_entry(Register obj,
22562256
}
22572257
}
22582258

2259+
// The Rmethod register is input and overwritten to be the adapter method for the
2260+
// indy call. Return address (ra) is set to the return address for the adapter and
2261+
// an appendix may be pushed to the stack. Registers A0-A3 are clobbered.
2262+
void TemplateTable::load_invokedynamic_entry(Register method) {
2263+
// setup registers
2264+
const Register appendix = A0;
2265+
const Register cache = A2;
2266+
const Register index = A3;
2267+
assert_different_registers(method, appendix, cache, index);
2268+
2269+
__ save_bcp();
2270+
2271+
Label resolved;
2272+
2273+
__ load_resolved_indy_entry(cache, index);
2274+
__ ld_d(method, Address(cache, in_bytes(ResolvedIndyEntry::method_offset())));
2275+
__ membar(Assembler::Membar_mask_bits(Assembler::LoadLoad | Assembler::LoadStore));
2276+
2277+
// Compare the method to zero
2278+
__ bnez(method, resolved);
2279+
2280+
Bytecodes::Code code = bytecode();
2281+
2282+
// Call to the interpreter runtime to resolve invokedynamic
2283+
address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
2284+
__ li(method, code); // this is essentially Bytecodes::_invokedynamic
2285+
__ call_VM(noreg, entry, method);
2286+
// Update registers with resolved info
2287+
__ load_resolved_indy_entry(cache, index);
2288+
__ ld_d(method, Address(cache, in_bytes(ResolvedIndyEntry::method_offset())));
2289+
__ membar(Assembler::Membar_mask_bits(Assembler::LoadLoad | Assembler::LoadStore));
2290+
2291+
#ifdef ASSERT
2292+
__ bnez(method, resolved);
2293+
__ stop("Should be resolved by now");
2294+
#endif // ASSERT
2295+
__ bind(resolved);
2296+
2297+
Label L_no_push;
2298+
// Check if there is an appendix
2299+
__ ld_bu(index, Address(cache, in_bytes(ResolvedIndyEntry::flags_offset())));
2300+
__ andi(AT, index, 1UL << ResolvedIndyEntry::has_appendix_shift);
2301+
__ beqz(AT, L_no_push);
2302+
2303+
// Get appendix
2304+
__ ld_hu(index, Address(cache, in_bytes(ResolvedIndyEntry::resolved_references_index_offset())));
2305+
// Push the appendix as a trailing parameter
2306+
// since the parameter_size includes it.
2307+
__ push(method);
2308+
__ move(method, index);
2309+
__ load_resolved_reference_at_index(appendix, method, A1);
2310+
__ verify_oop(appendix);
2311+
__ pop(method);
2312+
__ push(appendix); // push appendix (MethodType, CallSite, etc.)
2313+
__ bind(L_no_push);
2314+
2315+
// compute return type
2316+
__ ld_bu(index, Address(cache, in_bytes(ResolvedIndyEntry::result_type_offset())));
2317+
// load return address
2318+
// Return address is loaded into ra and not pushed to the stack like x86
2319+
{
2320+
const address table_addr = (address) Interpreter::invoke_return_entry_table_for(code);
2321+
__ li(AT, table_addr);
2322+
__ alsl_d(AT, index, AT, 3-1);
2323+
__ ld_d(RA, AT, 0);
2324+
}
2325+
}
2326+
22592327
// get the method, itable_index and flags of the current invoke
22602328
void TemplateTable::load_invoke_cp_cache_entry(int byte_no,
22612329
Register method,
22622330
Register itable_index,
22632331
Register flags,
22642332
bool is_invokevirtual,
22652333
bool is_invokevfinal, /*unused*/
2266-
bool is_invokedynamic) {
2334+
bool is_invokedynamic /*unused*/) {
22672335
// setup registers
22682336
const Register cache = T3;
22692337
const Register index = T1;
@@ -2284,7 +2352,7 @@ void TemplateTable::load_invoke_cp_cache_entry(int byte_no,
22842352
const int index_offset = in_bytes(ConstantPoolCache::base_offset() +
22852353
ConstantPoolCacheEntry::f2_offset());
22862354

2287-
size_t index_size = (is_invokedynamic ? sizeof(u4): sizeof(u2));
2355+
size_t index_size = sizeof(u2);
22882356
resolve_cache_and_index(byte_no, cache, index, index_size);
22892357

22902358
__ alsl_d(AT, index, cache, Address::times_ptr - 1);
@@ -3172,7 +3240,7 @@ void TemplateTable::prepare_invoke(int byte_no,
31723240

31733241
load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual, false, is_invokedynamic);
31743242

3175-
if (is_invokedynamic || is_invokehandle) {
3243+
if (is_invokehandle) {
31763244
Label L_no_push;
31773245
__ li(AT, (1 << ConstantPoolCacheEntry::has_appendix_shift));
31783246
__ andr(AT, AT, flags);
@@ -3497,32 +3565,32 @@ void TemplateTable::invokehandle(int byte_no) {
34973565
__ jump_from_interpreted(T2_method);
34983566
}
34993567

3500-
void TemplateTable::invokedynamic(int byte_no) {
3501-
transition(vtos, vtos);
3502-
assert(byte_no == f1_byte, "use this argument");
3568+
void TemplateTable::invokedynamic(int byte_no) {
3569+
transition(vtos, vtos);
3570+
assert(byte_no == f1_byte, "use this argument");
35033571

3504-
const Register T2_callsite = T2;
3572+
const Register T2_callsite = T2;
35053573

3506-
prepare_invoke(byte_no, Rmethod, T2_callsite);
3574+
load_invokedynamic_entry(Rmethod);
35073575

3508-
// T2: CallSite object (from cpool->resolved_references[f1])
3509-
// Rmethod: MH.linkToCallSite method (from f2)
3576+
// T2: CallSite object (from cpool->resolved_references[f1])
3577+
// Rmethod: MH.linkToCallSite method (from f2)
35103578

3511-
// Note: T2_callsite is already pushed by prepare_invoke
3512-
// %%% should make a type profile for any invokedynamic that takes a ref argument
3513-
// profile this call
3514-
__ profile_call(T4);
3579+
// Note: T2_callsite is already pushed by prepare_invoke
3580+
// %%% should make a type profile for any invokedynamic that takes a ref argument
3581+
// profile this call
3582+
__ profile_call(T4);
35153583

3516-
// T8: tmp, used for mdp
3517-
// Rmethod: callee
3518-
// T4: tmp
3519-
// is_virtual: false
3520-
__ profile_arguments_type(T8, Rmethod, T4, false);
3584+
// T8: tmp, used for mdp
3585+
// Rmethod: callee
3586+
// T4: tmp
3587+
// is_virtual: false
3588+
__ profile_arguments_type(T8, Rmethod, T4, false);
35213589

3522-
__ verify_oop(T2_callsite);
3590+
__ verify_oop(T2_callsite);
35233591

3524-
__ jump_from_interpreted(Rmethod);
3525-
}
3592+
__ jump_from_interpreted(Rmethod);
3593+
}
35263594

35273595
//-----------------------------------------------------------------------------
35283596
// Allocation

0 commit comments

Comments
 (0)