Skip to content

Commit 4bee207

Browse files
committed
8377554: Load card table base and other values via AOTRuntimeConstants in AOT code
Reviewed-by: kvn, asmehra
1 parent e0b040a commit 4bee207

23 files changed

+329
-18
lines changed

src/hotspot/cpu/aarch64/aarch64.ad

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3403,11 +3403,13 @@ encode %{
34033403
} else if (rtype == relocInfo::metadata_type) {
34043404
__ mov_metadata(dst_reg, (Metadata*)con);
34053405
} else {
3406-
assert(rtype == relocInfo::none, "unexpected reloc type");
3406+
assert(rtype == relocInfo::none || rtype == relocInfo::external_word_type, "unexpected reloc type");
3407+
// load fake address constants using a normal move
34073408
if (! __ is_valid_AArch64_address(con) ||
34083409
con < (address)(uintptr_t)os::vm_page_size()) {
34093410
__ mov(dst_reg, con);
34103411
} else {
3412+
// no reloc so just use adrp and add
34113413
uint64_t offset;
34123414
__ adrp(dst_reg, con, offset);
34133415
__ add(dst_reg, dst_reg, offset);
@@ -4535,6 +4537,18 @@ operand immP_1()
45354537
interface(CONST_INTER);
45364538
%}
45374539

4540+
// AOT Runtime Constants Address
4541+
operand immAOTRuntimeConstantsAddress()
4542+
%{
4543+
// Check if the address is in the range of AOT Runtime Constants
4544+
predicate(AOTRuntimeConstants::contains((address)(n->get_ptr())));
4545+
match(ConP);
4546+
4547+
op_cost(0);
4548+
format %{ %}
4549+
interface(CONST_INTER);
4550+
%}
4551+
45384552
// Float and Double operands
45394553
// Double Immediate
45404554
operand immD()
@@ -6898,6 +6912,20 @@ instruct loadConP1(iRegPNoSp dst, immP_1 con)
68986912
ins_pipe(ialu_imm);
68996913
%}
69006914

6915+
instruct loadAOTRCAddress(iRegPNoSp dst, immAOTRuntimeConstantsAddress con)
6916+
%{
6917+
match(Set dst con);
6918+
6919+
ins_cost(INSN_COST);
6920+
format %{ "adr $dst, $con\t# AOT Runtime Constants Address" %}
6921+
6922+
ins_encode %{
6923+
__ load_aotrc_address($dst$$Register, (address)$con$$constant);
6924+
%}
6925+
6926+
ins_pipe(ialu_imm);
6927+
%}
6928+
69016929
// Load Narrow Pointer Constant
69026930

69036931
instruct loadConN(iRegNNoSp dst, immN con)

src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "c1/c1_ValueStack.hpp"
3434
#include "ci/ciArrayKlass.hpp"
3535
#include "ci/ciInstance.hpp"
36+
#include "code/aotCodeCache.hpp"
3637
#include "code/compiledIC.hpp"
3738
#include "gc/shared/collectedHeap.hpp"
3839
#include "gc/shared/gc_globals.hpp"
@@ -532,6 +533,15 @@ void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_cod
532533

533534
case T_LONG: {
534535
assert(patch_code == lir_patch_none, "no patching handled here");
536+
#if INCLUDE_CDS
537+
if (AOTCodeCache::is_on_for_dump()) {
538+
address b = c->as_pointer();
539+
if (AOTRuntimeConstants::contains(b)) {
540+
__ load_aotrc_address(dest->as_register_lo(), b);
541+
break;
542+
}
543+
}
544+
#endif
535545
__ mov(dest->as_register_lo(), (intptr_t)c->as_jlong());
536546
break;
537547
}

src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*/
2424

2525
#include "asm/macroAssembler.inline.hpp"
26+
#include "code/aotCodeCache.hpp"
2627
#include "gc/g1/g1BarrierSet.hpp"
2728
#include "gc/g1/g1BarrierSetAssembler.hpp"
2829
#include "gc/g1/g1BarrierSetRuntime.hpp"
@@ -243,9 +244,25 @@ static void generate_post_barrier(MacroAssembler* masm,
243244
assert_different_registers(store_addr, new_val, thread, tmp1, tmp2, noreg, rscratch1);
244245

245246
// Does store cross heap regions?
246-
__ eor(tmp1, store_addr, new_val); // tmp1 := store address ^ new value
247-
__ lsr(tmp1, tmp1, G1HeapRegion::LogOfHRGrainBytes); // tmp1 := ((store address ^ new value) >> LogOfHRGrainBytes)
248-
__ cbz(tmp1, done);
247+
#if INCLUDE_CDS
248+
// AOT code needs to load the barrier grain shift from the aot
249+
// runtime constants area in the code cache otherwise we can compile
250+
// it as an immediate operand
251+
if (AOTCodeCache::is_on_for_dump()) {
252+
address grain_shift_address = (address)AOTRuntimeConstants::grain_shift_address();
253+
__ eor(tmp1, store_addr, new_val);
254+
__ lea(tmp2, ExternalAddress(grain_shift_address));
255+
__ ldrb(tmp2, tmp2);
256+
__ lsrv(tmp1, tmp1, tmp2);
257+
__ cbz(tmp1, done);
258+
} else
259+
#endif
260+
{
261+
__ eor(tmp1, store_addr, new_val); // tmp1 := store address ^ new value
262+
__ lsr(tmp1, tmp1, G1HeapRegion::LogOfHRGrainBytes); // tmp1 := ((store address ^ new value) >> LogOfHRGrainBytes)
263+
__ cbz(tmp1, done);
264+
}
265+
249266
// Crosses regions, storing null?
250267
if (new_val_may_be_null) {
251268
__ cbz(new_val, done);

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5754,13 +5754,35 @@ void MacroAssembler::adrp(Register reg1, const Address &dest, uint64_t &byte_off
57545754
}
57555755

57565756
void MacroAssembler::load_byte_map_base(Register reg) {
5757+
#if INCLUDE_CDS
5758+
if (AOTCodeCache::is_on_for_dump()) {
5759+
address byte_map_base_adr = AOTRuntimeConstants::card_table_base_address();
5760+
lea(reg, ExternalAddress(byte_map_base_adr));
5761+
ldr(reg, Address(reg));
5762+
return;
5763+
}
5764+
#endif
57575765
CardTableBarrierSet* ctbs = CardTableBarrierSet::barrier_set();
57585766

57595767
// Strictly speaking the card table base isn't an address at all, and it might
57605768
// even be negative. It is thus materialised as a constant.
57615769
mov(reg, (uint64_t)ctbs->card_table_base_const());
57625770
}
57635771

5772+
void MacroAssembler::load_aotrc_address(Register reg, address a) {
5773+
#if INCLUDE_CDS
5774+
assert(AOTRuntimeConstants::contains(a), "address out of range for data area");
5775+
if (AOTCodeCache::is_on_for_dump()) {
5776+
// all aotrc field addresses should be registered in the AOTCodeCache address table
5777+
lea(reg, ExternalAddress(a));
5778+
} else {
5779+
mov(reg, (uint64_t)a);
5780+
}
5781+
#else
5782+
ShouldNotReachHere();
5783+
#endif
5784+
}
5785+
57645786
void MacroAssembler::build_frame(int framesize) {
57655787
assert(framesize >= 2 * wordSize, "framesize must include space for FP/LR");
57665788
assert(framesize % (2*wordSize) == 0, "must preserve 2*wordSize alignment");

src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,6 +1476,9 @@ class MacroAssembler: public Assembler {
14761476
// Load the base of the cardtable byte map into reg.
14771477
void load_byte_map_base(Register reg);
14781478

1479+
// Load a constant address in the AOT Runtime Constants area
1480+
void load_aotrc_address(Register reg, address a);
1481+
14791482
// Prolog generator routines to support switch between x86 code and
14801483
// generated ARM code
14811484

src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "c1/c1_ValueStack.hpp"
3333
#include "ci/ciArrayKlass.hpp"
3434
#include "ci/ciInstance.hpp"
35+
#include "code/aotCodeCache.hpp"
3536
#include "compiler/oopMap.hpp"
3637
#include "gc/shared/collectedHeap.hpp"
3738
#include "gc/shared/gc_globals.hpp"
@@ -535,6 +536,15 @@ void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_cod
535536

536537
case T_LONG: {
537538
assert(patch_code == lir_patch_none, "no patching handled here");
539+
#if INCLUDE_CDS
540+
if (AOTCodeCache::is_on_for_dump()) {
541+
address b = c->as_pointer();
542+
if (AOTRuntimeConstants::contains(b)) {
543+
__ load_aotrc_address(dest->as_register_lo(), b);
544+
break;
545+
}
546+
}
547+
#endif
538548
__ movptr(dest->as_register_lo(), (intptr_t)c->as_jlong());
539549
break;
540550
}

src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*/
2424

2525
#include "asm/macroAssembler.inline.hpp"
26+
#include "code/aotCodeCache.hpp"
2627
#include "gc/g1/g1BarrierSet.hpp"
2728
#include "gc/g1/g1BarrierSetAssembler.hpp"
2829
#include "gc/g1/g1BarrierSetRuntime.hpp"
@@ -268,6 +269,16 @@ void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm,
268269
__ bind(done);
269270
}
270271

272+
#if INCLUDE_CDS
273+
// return a register that differs from reg1, reg2, reg3 and reg4
274+
275+
static Register pick_different_reg(Register reg1, Register reg2 = noreg, Register reg3= noreg, Register reg4 = noreg) {
276+
RegSet available = (RegSet::of(rscratch1, rscratch2, rax, rbx) + rdx -
277+
RegSet::of(reg1, reg2, reg3, reg4));
278+
return *(available.begin());
279+
}
280+
#endif // INCLUDE_CDS
281+
271282
static void generate_post_barrier(MacroAssembler* masm,
272283
const Register store_addr,
273284
const Register new_val,
@@ -280,10 +291,32 @@ static void generate_post_barrier(MacroAssembler* masm,
280291

281292
Label L_done;
282293
// Does store cross heap regions?
283-
__ movptr(tmp1, store_addr); // tmp1 := store address
284-
__ xorptr(tmp1, new_val); // tmp1 := store address ^ new value
285-
__ shrptr(tmp1, G1HeapRegion::LogOfHRGrainBytes); // ((store address ^ new value) >> LogOfHRGrainBytes) == 0?
286-
__ jccb(Assembler::equal, L_done);
294+
#if INCLUDE_CDS
295+
// AOT code needs to load the barrier grain shift from the aot
296+
// runtime constants area in the code cache otherwise we can compile
297+
// it as an immediate operand
298+
299+
if (AOTCodeCache::is_on_for_dump()) {
300+
address grain_shift_addr = AOTRuntimeConstants::grain_shift_address();
301+
Register save = pick_different_reg(rcx, tmp1, new_val, store_addr);
302+
__ push(save);
303+
__ movptr(save, store_addr);
304+
__ xorptr(save, new_val);
305+
__ push(rcx);
306+
__ lea(rcx, ExternalAddress(grain_shift_addr));
307+
__ movl(rcx, Address(rcx, 0));
308+
__ shrptr(save);
309+
__ pop(rcx);
310+
__ pop(save);
311+
__ jcc(Assembler::equal, L_done);
312+
} else
313+
#endif // INCLUDE_CDS
314+
{
315+
__ movptr(tmp1, store_addr); // tmp1 := store address
316+
__ xorptr(tmp1, new_val); // tmp1 := store address ^ new value
317+
__ shrptr(tmp1, G1HeapRegion::LogOfHRGrainBytes); // ((store address ^ new value) >> LogOfHRGrainBytes) == 0?
318+
__ jccb(Assembler::equal, L_done);
319+
}
287320

288321
// Crosses regions, storing null?
289322
if (new_val_may_be_null) {

src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*/
2424

2525
#include "asm/macroAssembler.inline.hpp"
26+
#include "code/aotCodeCache.hpp"
2627
#include "gc/shared/barrierSet.hpp"
2728
#include "gc/shared/cardTable.hpp"
2829
#include "gc/shared/cardTableBarrierSet.hpp"
@@ -111,7 +112,15 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl
111112
__ shrptr(end, CardTable::card_shift());
112113
__ subptr(end, addr); // end --> cards count
113114

114-
__ mov64(tmp, (intptr_t)ctbs->card_table_base_const());
115+
#if INCLUDE_CDS
116+
if (AOTCodeCache::is_on_for_dump()) {
117+
__ lea(tmp, ExternalAddress(AOTRuntimeConstants::card_table_base_address()));
118+
__ movq(tmp, Address(tmp, 0));
119+
} else
120+
#endif
121+
{
122+
__ mov64(tmp, (intptr_t)ctbs->card_table_base_const());
123+
}
115124
__ addptr(addr, tmp);
116125
__ BIND(L_loop);
117126
__ movb(Address(addr, count, Address::times_1), 0);
@@ -121,7 +130,7 @@ __ BIND(L_loop);
121130
__ BIND(L_done);
122131
}
123132

124-
void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register obj, Address dst) {
133+
void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register obj, Address dst, Register rscratch) {
125134
// Does a store check for the oop in register obj. The content of
126135
// register obj is destroyed afterwards.
127136
CardTableBarrierSet* ctbs = CardTableBarrierSet::barrier_set();
@@ -136,6 +145,13 @@ void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register ob
136145
// never need to be relocated. On 64bit however the value may be too
137146
// large for a 32bit displacement.
138147
intptr_t byte_map_base = (intptr_t)ctbs->card_table_base_const();
148+
#if INCLUDE_CDS
149+
if (AOTCodeCache::is_on_for_dump()) {
150+
__ lea(rscratch, ExternalAddress(AOTRuntimeConstants::card_table_base_address()));
151+
__ movq(rscratch, Address(rscratch, 0));
152+
card_addr = Address(rscratch, obj, Address::times_1, 0);
153+
} else
154+
#endif
139155
if (__ is_simm32(byte_map_base)) {
140156
card_addr = Address(noreg, obj, Address::times_1, byte_map_base);
141157
} else {
@@ -174,10 +190,10 @@ void CardTableBarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorS
174190
if (needs_post_barrier) {
175191
// flatten object address if needed
176192
if (!precise || (dst.index() == noreg && dst.disp() == 0)) {
177-
store_check(masm, dst.base(), dst);
193+
store_check(masm, dst.base(), dst, tmp2);
178194
} else {
179195
__ lea(tmp1, dst);
180-
store_check(masm, tmp1, dst);
196+
store_check(masm, tmp1, dst, tmp2);
181197
}
182198
}
183199
}

src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class CardTableBarrierSetAssembler: public BarrierSetAssembler {
3333
virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
3434
Register addr, Register count) {}
3535

36-
void store_check(MacroAssembler* masm, Register obj, Address dst);
36+
void store_check(MacroAssembler* masm, Register obj, Address dst, Register rscratch);
3737

3838
virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, Register tmp);
3939

src/hotspot/cpu/x86/macroAssembler_x86.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10034,6 +10034,20 @@ void MacroAssembler::restore_legacy_gprs() {
1003410034
addq(rsp, 16 * wordSize);
1003510035
}
1003610036

10037+
void MacroAssembler::load_aotrc_address(Register reg, address a) {
10038+
#if INCLUDE_CDS
10039+
assert(AOTRuntimeConstants::contains(a), "address out of range for data area");
10040+
if (AOTCodeCache::is_on_for_dump()) {
10041+
// all aotrc field addresses should be registered in the AOTCodeCache address table
10042+
lea(reg, ExternalAddress(a));
10043+
} else {
10044+
mov64(reg, (uint64_t)a);
10045+
}
10046+
#else
10047+
ShouldNotReachHere();
10048+
#endif
10049+
}
10050+
1003710051
void MacroAssembler::setcc(Assembler::Condition comparison, Register dst) {
1003810052
if (VM_Version::supports_apx_f()) {
1003910053
esetzucc(comparison, dst);

0 commit comments

Comments
 (0)