Skip to content

Commit f5defe3

Browse files
committed
WIP: Fix compilation for AArch64.
1 parent 2e31937 commit f5defe3

15 files changed

+328
-102
lines changed

openjdk/cpu/aarch64/mmtkBarrierSetAssembler_aarch64.cpp

Lines changed: 75 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,16 @@
2525
#include "asm/macroAssembler.inline.hpp"
2626
#include "interpreter/interp_masm.hpp"
2727
#include "mmtkBarrierSet.hpp"
28-
#include "mmtkBarrierSetAssembler_aarch64.hpp"
2928
#include "mmtkBarrierSetC1.hpp"
3029
#include "mmtkMutator.hpp"
3130
#include "runtime/sharedRuntime.hpp"
3231
#include "utilities/macros.hpp"
3332
#include "c1/c1_LIRAssembler.hpp"
3433
#include "c1/c1_MacroAssembler.hpp"
3534

35+
#include "utilities/macros.hpp"
36+
#include CPU_HEADER(mmtkBarrierSetAssembler)
37+
3638
#define __ masm->
3739

3840
void MMTkBarrierSetAssembler::eden_allocate(MacroAssembler* masm, Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register tmp1, Register tmp2, Label& slow_case) {
@@ -129,61 +131,95 @@ void MMTkBarrierSetAssembler::eden_allocate(MacroAssembler* masm, Register obj,
129131

130132
#undef __
131133

132-
#define __ sasm->
133-
134-
void MMTkBarrierSetAssembler::generate_c1_write_barrier_runtime_stub(StubAssembler* sasm) const {
135-
// printf("xxx MMTkBarrierSetAssembler::generate_c1_write_barrier_runtime_stub\n");
136-
// See also void G1BarrierSetAssembler::generate_c1_post_barrier_runtime_stub(StubAssembler* sasm)
137-
__ prologue("mmtk_write_barrier", false);
134+
//////////////////// Assembler for C1 ////////////////////
138135

139-
Label done, runtime;
136+
// Generate runtime stubs for the "runtime code blobs" in MMTkBarrierSetC1
140137

141-
// void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg)
142-
// ld(reg, Address(fp, offset_in_words * BytesPerWord));
143-
// ra is free to use here, because call prologue/epilogue handles it
144-
// Zheyuan: Code works by swaping rscratch2 and rscratch1, and I dont know why
145-
const Register src = rscratch2;
146-
const Register slot = rscratch1;
147-
const Register new_val = lr;
148-
__ load_parameter(0, src);
149-
__ load_parameter(1, slot);
150-
__ load_parameter(2, new_val);
151-
152-
__ bind(runtime);
138+
#define __ sasm->
153139

154-
// Push integer registers x7, x10-x17, x28-x31.
155-
// t2, a0-a7, t3-t6
140+
void MMTkBarrierSetAssembler::generate_c1_runtime_stub_general(StubAssembler* sasm, const char* name, address entry_point, int argc) {
141+
__ prologue(name, false);
156142
__ push_call_clobbered_registers();
157143

158-
if (mmtk_enable_barrier_fastpath) {
159-
__ call_VM_leaf(FN_ADDR(MMTkBarrierSetRuntime::object_reference_write_slow_call), src, slot, new_val);
160-
} else {
161-
__ call_VM_leaf(FN_ADDR(MMTkBarrierSetRuntime::object_reference_write_post_call), src, slot, new_val);
144+
if (argc > 0) __ load_parameter(0, c_rarg0);
145+
if (argc > 1) __ load_parameter(1, c_rarg1);
146+
if (argc > 2) __ load_parameter(2, c_rarg2);
147+
if (argc > 3) {
148+
guarantee(false, "Too many args");
162149
}
163150

151+
__ call_VM_leaf(entry_point, 3);
152+
164153
__ pop_call_clobbered_registers();
154+
__ epilogue();
155+
}
165156

166-
__ bind(done);
157+
// void foo(){
158+
// Label done, runtime;
167159

168-
__ epilogue();
160+
// // void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg)
161+
// // ld(reg, Address(fp, offset_in_words * BytesPerWord));
162+
// // ra is free to use here, because call prologue/epilogue handles it
163+
// // Zheyuan: Code works by swaping rscratch2 and rscratch1, and I dont know why
164+
// const Register src = rscratch2;
165+
// const Register slot = rscratch1;
166+
// const Register new_val = lr;
167+
// __ load_parameter(0, src);
168+
// __ load_parameter(1, slot);
169+
// __ load_parameter(2, new_val);
170+
171+
// __ bind(runtime);
172+
173+
// // Push integer registers x7, x10-x17, x28-x31.
174+
// // t2, a0-a7, t3-t6
175+
// __ push_call_clobbered_registers();
176+
177+
// if (mmtk_enable_barrier_fastpath) {
178+
// __ call_VM_leaf(FN_ADDR(MMTkBarrierSetRuntime::object_reference_write_slow_call), src, slot, new_val);
179+
// } else {
180+
// __ call_VM_leaf(FN_ADDR(MMTkBarrierSetRuntime::object_reference_write_post_call), src, slot, new_val);
181+
// }
182+
183+
// __ pop_call_clobbered_registers();
184+
185+
// __ bind(done);
186+
187+
// __ epilogue();
188+
// }
189+
190+
void MMTkBarrierSetAssembler::generate_c1_load_reference_runtime_stub(StubAssembler* sasm) {
191+
generate_c1_runtime_stub_general(sasm, "c1_load_reference_runtime_stub", FN_ADDR(MMTkBarrierSetRuntime::load_reference_call), 1);
192+
}
193+
194+
void MMTkBarrierSetAssembler::generate_c1_object_reference_write_pre_runtime_stub(StubAssembler* sasm) {
195+
generate_c1_runtime_stub_general(sasm, "c1_object_reference_write_pre_stub", FN_ADDR(MMTkBarrierSetRuntime::object_reference_write_pre_call), 3);
196+
}
197+
198+
void MMTkBarrierSetAssembler::generate_c1_object_reference_write_post_runtime_stub(StubAssembler* sasm) {
199+
generate_c1_runtime_stub_general(sasm, "c1_object_reference_write_post_stub", FN_ADDR(MMTkBarrierSetRuntime::object_reference_write_post_call), 3);
200+
}
201+
202+
void MMTkBarrierSetAssembler::generate_c1_object_reference_write_slow_runtime_stub(StubAssembler* sasm) {
203+
generate_c1_runtime_stub_general(sasm, "c1_object_reference_write_slow_stub", FN_ADDR(MMTkBarrierSetRuntime::object_reference_write_slow_call), 3);
169204
}
170205

171206
#undef __
172207

208+
// Generate code stubs
209+
173210
#define __ ce->masm()->
174211

175-
void MMTkBarrierSetAssembler::generate_c1_write_barrier_stub_call(LIR_Assembler* ce, MMTkC1BarrierStub* stub) {
176-
// printf("xxx MMTkBarrierSetAssembler::generate_c1_write_barrier_stub_call\n");
177-
// See also void G1BarrierSetAssembler::gen_post_barrier_stub(LIR_Assembler* ce, G1PostBarrierStub* stub)
178-
MMTkBarrierSetC1* bs = (MMTkBarrierSetC1*) BarrierSet::barrier_set()->barrier_set_c1();
212+
void MMTkBarrierSetAssembler::generate_c1_ref_load_barrier_stub_call(LIR_Assembler* ce, MMTkC1ReferenceLoadBarrierStub* stub) {
213+
MMTkBarrierSetC1* bs = (MMTkBarrierSetC1*)BarrierSet::barrier_set()->barrier_set_c1();
214+
179215
__ bind(*stub->entry());
180-
assert(stub->src->is_register(), "Precondition");
181-
assert(stub->slot->is_register(), "Precondition");
182-
assert(stub->new_val->is_register(), "Precondition");
183-
ce->store_parameter(stub->src->as_pointer_register(), 0);
184-
ce->store_parameter(stub->slot->as_pointer_register(), 1);
185-
ce->store_parameter(stub->new_val->as_pointer_register(), 2);
186-
__ far_call(RuntimeAddress(bs->_write_barrier_c1_runtime_code_blob->code_begin()));
216+
assert(stub->val->is_register(), "Precondition.");
217+
218+
Register val_reg = stub->val->as_register();
219+
220+
__ cbz(val_reg, *stub->continuation());
221+
ce->store_parameter(stub->val->as_register(), 0);
222+
__ far_call(RuntimeAddress(bs->load_reference_c1_runtime_code_blob()->code_begin()));
187223
__ b(*stub->continuation());
188224
}
189225

openjdk/cpu/aarch64/mmtkBarrierSetAssembler_aarch64.hpp

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,16 @@
55
#include "gc/shared/barrierSetAssembler.hpp"
66

77
class MMTkBarrierSetC1;
8-
class MMTkC1BarrierStub;
8+
class MMTkC1ReferenceLoadBarrierStub;
99
class LIR_Assembler;
1010
class StubAssembler;
1111

1212
class MMTkBarrierSetAssembler: public BarrierSetAssembler {
13-
friend class MMTkBarrierSetC1;
14-
1513
protected:
1614
/// Full pre-barrier
17-
virtual void object_reference_write_pre(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2) const {}
15+
virtual void object_reference_write_pre(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) const {}
1816
/// Full post-barrier
19-
virtual void object_reference_write_post(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2) const {}
17+
virtual void object_reference_write_post(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) const {}
2018

2119
/// Barrier elision test
2220
virtual bool can_remove_barrier(DecoratorSet decorators, Register val, bool skip_const_null) const {
@@ -26,9 +24,6 @@ class MMTkBarrierSetAssembler: public BarrierSetAssembler {
2624
return !in_heap || (skip_const_null && val == noreg);
2725
}
2826

29-
/// Generate C1 write barrier slow-call assembly code
30-
virtual void generate_c1_write_barrier_runtime_stub(StubAssembler* sasm) const;
31-
3227
public:
3328
virtual void eden_allocate(MacroAssembler* masm,
3429
Register obj, // result: pointer to object after successful allocation
@@ -39,12 +34,24 @@ class MMTkBarrierSetAssembler: public BarrierSetAssembler {
3934
Label& slow_case // continuation point if fast allocation fails
4035
);
4136
virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) {
42-
if (type == T_OBJECT || type == T_ARRAY) object_reference_write_pre(masm, decorators, dst, val, tmp1, tmp2);
37+
if (type == T_OBJECT || type == T_ARRAY) object_reference_write_pre(masm, decorators, dst, val, tmp1, tmp2, tmp3);
4338
BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3);
44-
if (type == T_OBJECT || type == T_ARRAY) object_reference_write_post(masm, decorators, dst, val, tmp1, tmp2);
39+
if (type == T_OBJECT || type == T_ARRAY) object_reference_write_post(masm, decorators, dst, val, tmp1, tmp2, tmp3);
4540
}
4641

47-
/// Generate C1 write barrier slow-call stub
48-
static void generate_c1_write_barrier_stub_call(LIR_Assembler* ce, MMTkC1BarrierStub* stub);
42+
//////////////////// Assembler for C1 ////////////////////
43+
44+
// Generate runtime stubs for the "runtime code blobs" in MMTkBarrierSetC1
45+
private:
46+
static void generate_c1_runtime_stub_general(StubAssembler* sasm, const char* name, address func, int argc);
47+
public:
48+
static void generate_c1_load_reference_runtime_stub(StubAssembler* sasm);
49+
static void generate_c1_object_reference_write_pre_runtime_stub(StubAssembler* sasm);
50+
static void generate_c1_object_reference_write_post_runtime_stub(StubAssembler* sasm);
51+
static void generate_c1_object_reference_write_slow_runtime_stub(StubAssembler* sasm);
52+
53+
// Generate slow-path code stubs
54+
public:
55+
static void generate_c1_ref_load_barrier_stub_call(LIR_Assembler* ce, MMTkC1ReferenceLoadBarrierStub* stub);
4956
};
5057
#endif // MMTK_OPENJDK_MMTK_BARRIER_SET_ASSEMBLER_AARCH64_HPP
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#ifndef MMTK_OPENJDK_MMTK_NO_BARRIER_SET_ASSEMBLER_AARCH64_HPP
22
#define MMTK_OPENJDK_MMTK_NO_BARRIER_SET_ASSEMBLER_AARCH64_HPP
33

4+
#include "utilities/macros.hpp"
5+
#include CPU_HEADER(mmtkBarrierSetAssembler)
6+
47
class MMTkNoBarrierSetAssembler: public MMTkBarrierSetAssembler {};
58
#endif // MMTK_OPENJDK_MMTK_NO_BARRIER_SET_ASSEMBLER_AARCH64_HPP

openjdk/cpu/aarch64/mmtkObjectBarrierSetAssembler_aarch64.cpp

Lines changed: 4 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,52 +2,13 @@
22
#include "mmtkObjectBarrier.hpp"
33
#include "runtime/interfaceSupport.inline.hpp"
44

5+
//////////////////// Assembler ////////////////////
6+
57
#define __ masm->
68

7-
void MMTkObjectBarrierSetAssembler::object_reference_write_post(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2) const {
8-
// tmp1 and tmp2 is from MacroAssembler::access_store_at
9-
// For do_oop_store, we have three tmps, x28/t3, x29/t4, x13/a3
10-
// printf("object_reference_write_post\n");
11-
// if (can_remove_barrier(decorators, val, /* skip_const_null */ true)) return;
9+
void MMTkObjectBarrierSetAssembler::object_reference_write_post(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) const {
1210
if (can_remove_barrier(decorators, val, /* skip_const_null */ true)) return;
13-
Register obj = dst.base();
14-
15-
if (mmtk_enable_barrier_fastpath) {
16-
Label done;
17-
18-
assert_different_registers(obj, tmp1, tmp2);
19-
assert_different_registers(val, tmp1, tmp2);
20-
assert(tmp1->is_valid(), "need temp reg");
21-
assert(tmp2->is_valid(), "need temp reg");
22-
// tmp1 = load-byte (SIDE_METADATA_BASE_ADDRESS + (obj >> 6));
23-
__ mov(tmp1, obj);
24-
__ lsr(tmp1, tmp1, 6); // tmp1 = obj >> 6;
25-
__ mov(tmp2, SIDE_METADATA_BASE_ADDRESS);
26-
__ add(tmp1, tmp1, tmp2); // tmp1 = SIDE_METADATA_BASE_ADDRESS + (obj >> 6);
27-
__ ldrb(tmp1, Address(tmp1, 0));
28-
// tmp2 = (obj >> 3) & 7
29-
__ mov(tmp2, obj);
30-
__ lsr(tmp2, tmp2, 3);
31-
__ andr(tmp2, tmp2, 7);
32-
// tmp1 = tmp1 >> tmp2
33-
__ lsrv(tmp1, tmp1, tmp2);
34-
// if ((tmp1 & 1) == 1) fall through to slowpath;
35-
// equivalently ((tmp1 & 1) == 0) go to done
36-
__ andr(tmp1, tmp1, 1);
37-
__ cbz(tmp1, done);
38-
// setup calling convention
39-
__ mov(c_rarg0, obj);
40-
__ lea(c_rarg1, dst);
41-
__ mov(c_rarg2, val == noreg ? zr : val);
42-
__ call_VM_leaf(FN_ADDR(MMTkBarrierSetRuntime::object_reference_write_slow_call), 3);
43-
44-
__ bind(done);
45-
} else {
46-
__ mov(c_rarg0, obj);
47-
__ lea(c_rarg1, dst);
48-
__ mov(c_rarg2, val == noreg ? zr : val);
49-
__ call_VM_leaf(FN_ADDR(MMTkBarrierSetRuntime::object_reference_write_post_call), 3);
50-
}
11+
object_reference_write_pre_or_post(masm, decorators, dst, val, tmp1, tmp2, tmp3, /* pre = */ false);
5112
}
5213

5314
void MMTkObjectBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
#ifndef MMTK_OPENJDK_MMTK_OBJECT_BARRIER_SET_ASSEMBLER_AARCH64_HPP
22
#define MMTK_OPENJDK_MMTK_OBJECT_BARRIER_SET_ASSEMBLER_AARCH64_HPP
33

4-
class MMTkObjectBarrierSetAssembler: public MMTkBarrierSetAssembler {
4+
#include "utilities/macros.hpp"
5+
#include CPU_HEADER(mmtkUnlogBitBarrierSetAssembler)
6+
7+
//////////////////// Assembler ////////////////////
8+
9+
class MMTkObjectBarrierSetAssembler: public MMTkUnlogBitBarrierSetAssembler {
510
protected:
6-
virtual void object_reference_write_post(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2) const override;
11+
virtual void object_reference_write_post(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) const override;
712
public:
813
virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
914
Register src, Register dst, Register count, Register tmp, RegSet saved_regs) override;
1015
};
16+
1117
#endif // MMTK_OPENJDK_MMTK_OBJECT_BARRIER_SET_ASSEMBLER_AARCH64_HPP
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#include "precompiled.hpp"
2+
#include "mmtkSATBBarrier.hpp"
3+
#include "runtime/interfaceSupport.inline.hpp"
4+
5+
//////////////////// Assembler ////////////////////
6+
7+
#define __ masm->
8+
9+
void MMTkSATBBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register dst, Address src, Register tmp1, Register tmp_thread) {
10+
bool on_oop = type == T_OBJECT || type == T_ARRAY;
11+
bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
12+
bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
13+
bool on_reference = on_weak || on_phantom;
14+
15+
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
16+
17+
if (mmtk_enable_reference_load_barrier) {
18+
if (on_oop && on_reference) {
19+
Label done;
20+
21+
assert_different_registers(dst, tmp1);
22+
23+
// No slow-call if SATB is not active
24+
// intptr_t tmp1_q = CONCURRENT_MARKING_ACTIVE;
25+
__ movptr(tmp1, intptr_t(&CONCURRENT_MARKING_ACTIVE));
26+
// Load with zero extension to 32 bits.
27+
// uint32_t tmp1_l = (uint32_t)(*(unt8_t*)tmp1_q);
28+
__ ldrb(tmp1, Address(tmp1, 0));
29+
// if (tmp1_l == 0) goto done;
30+
__ cbz(tmp1, done);
31+
// if (dst == 0) goto done;
32+
__ cbz(dst, done);
33+
// Do slow-call
34+
__ push_call_clobbered_registers();
35+
__ mov(c_rarg0, dst);
36+
__ MacroAssembler::call_VM_leaf(FN_ADDR(MMTkBarrierSetRuntime::load_reference_call), 1);
37+
__ pop_call_clobbered_registers();
38+
__ bind(done);
39+
}
40+
}
41+
}
42+
43+
void MMTkSATBBarrierSetAssembler::object_reference_write_pre(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) const {
44+
if (can_remove_barrier(decorators, val, /* skip_const_null */ false)) return;
45+
object_reference_write_pre_or_post(masm, decorators, dst, val, tmp1, tmp2, tmp3, /* pre = */ true);
46+
}
47+
48+
void MMTkSATBBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, Register src, Register dst, Register count, RegSet saved_regs) {
49+
if (is_oop) {
50+
Label done;
51+
// Skip the runtime call if count is zero.
52+
__ cbz(count, done);
53+
__ push_call_clobbered_registers();
54+
__ mov(c_rarg0, src);
55+
__ mov(c_rarg1, dst);
56+
__ mov(c_rarg2, count);
57+
__ call_VM_leaf(FN_ADDR(MMTkBarrierSetRuntime::object_reference_array_copy_pre_call), 3);
58+
__ pop_call_clobbered_registers();
59+
__ bind(done);
60+
}
61+
}
62+
63+
#undef __
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifndef MMTK_OPENJDK_MMTK_SATB_BARRIER_SET_ASSEMBLER_AARCH64_HPP
2+
#define MMTK_OPENJDK_MMTK_SATB_BARRIER_SET_ASSEMBLER_AARCH64_HPP
3+
4+
#include "utilities/macros.hpp"
5+
#include CPU_HEADER(mmtkUnlogBitBarrierSetAssembler)
6+
7+
//////////////////// Assembler ////////////////////
8+
9+
class MMTkSATBBarrierSetAssembler: public MMTkUnlogBitBarrierSetAssembler {
10+
protected:
11+
virtual void object_reference_write_pre(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) const override;
12+
public:
13+
virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, Register src, Register dst, Register count, RegSet saved_regs) override;
14+
virtual void load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register dst, Address src, Register tmp1, Register tmp2) override;
15+
};
16+
17+
#endif // MMTK_OPENJDK_MMTK_SATB_BARRIER_SET_ASSEMBLER_AARCH64_HPP

0 commit comments

Comments
 (0)