Skip to content

Commit c2c23d3

Browse files
authored
Refactor barrier interface (#177)
* Add arraycopy barrier; remove clone barrier; barrier elision * wip * object_reference_write * WIP array_copy * Update array copy barrier * Update array copy barrier * wip C1 barrier * Fix C1 barrier * refactor * pre barrier slow path * minor * add `enable_oop_arraycopy_prologue` * Fix * Cleanup * cleanup * switch to post-barrier * cleanup * WIP: Move more shared methods out of object barrier * Move C1 common code to MMTkBarrierSetC1 * cleanup * minor * minor * Update * Add comments * Update Cargo.toml * Update * Update Cargo.lock * rename `array_copy` -> `memory_region_copy` * Update * Update mmtk-core * Update Cargo.lock * minor * Add newline * Rename * Update mmtk-core
1 parent efcae2f commit c2c23d3

15 files changed

+441
-269
lines changed

mmtk/Cargo.lock

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mmtk/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ lto = true
1717
[package.metadata.openjdk]
1818
# Our CI matches the following line and extract mmtk/openjdk. If this line is updated, please check ci yaml files and make sure it works.
1919
openjdk_repo = "https://github.com/mmtk/openjdk.git"
20-
openjdk_version = "ad1809129d6288e7f8226990840e5d32aab0ea34"
20+
openjdk_version = "c82e5c44adced4383162826c2c3933a83cfb139b"
2121

2222
[dependencies]
2323
libc = "0.2"
@@ -29,7 +29,7 @@ once_cell = "1.10.0"
2929
# - change branch
3030
# - change repo name
3131
# But other changes including adding/removing whitespaces in commented lines may break the CI.
32-
mmtk = { git = "https://github.com/mmtk/mmtk-core.git", rev = "4ae23b1dc0e14f62c196c12c93818e00e9de7cc5" }
32+
mmtk = { git = "https://github.com/mmtk/mmtk-core.git", rev = "9473d7b4b92747d3c0998af3c41a6ef50c9c94e3" }
3333
# Uncomment the following to build locally
3434
# mmtk = { path = "../repos/mmtk-core" }
3535

mmtk/src/api.rs

+56-5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use mmtk::plan::BarrierSelector;
99
use mmtk::scheduler::GCController;
1010
use mmtk::scheduler::GCWorker;
1111
use mmtk::util::alloc::AllocatorSelector;
12+
use mmtk::util::constants::LOG_BYTES_IN_ADDRESS;
1213
use mmtk::util::opaque_pointer::*;
1314
use mmtk::util::{Address, ObjectReference};
1415
use mmtk::AllocationSemantics;
@@ -308,21 +309,71 @@ pub extern "C" fn executable() -> bool {
308309
true
309310
}
310311

312+
/// Full pre barrier
311313
#[no_mangle]
312-
pub extern "C" fn post_write_barrier(mutator: &'static mut Mutator<OpenJDK>, obj: ObjectReference) {
314+
pub extern "C" fn mmtk_object_reference_write_pre(
315+
mutator: &'static mut Mutator<OpenJDK>,
316+
src: ObjectReference,
317+
slot: Address,
318+
target: ObjectReference,
319+
) {
320+
mutator
321+
.barrier()
322+
.object_reference_write_pre(src, slot, target);
323+
}
324+
325+
/// Full post barrier
326+
#[no_mangle]
327+
pub extern "C" fn mmtk_object_reference_write_post(
328+
mutator: &'static mut Mutator<OpenJDK>,
329+
src: ObjectReference,
330+
slot: Address,
331+
target: ObjectReference,
332+
) {
333+
mutator
334+
.barrier()
335+
.object_reference_write_post(src, slot, target);
336+
}
337+
338+
/// Barrier slow-path call
339+
#[no_mangle]
340+
pub extern "C" fn mmtk_object_reference_write_slow(
341+
mutator: &'static mut Mutator<OpenJDK>,
342+
src: ObjectReference,
343+
slot: Address,
344+
target: ObjectReference,
345+
) {
346+
mutator
347+
.barrier()
348+
.object_reference_write_slow(src, slot, target);
349+
}
350+
351+
/// Array-copy pre-barrier
352+
#[no_mangle]
353+
pub extern "C" fn mmtk_array_copy_pre(
354+
mutator: &'static mut Mutator<OpenJDK>,
355+
src: Address,
356+
dst: Address,
357+
count: usize,
358+
) {
359+
let bytes = count << LOG_BYTES_IN_ADDRESS;
313360
mutator
314361
.barrier()
315-
.post_write_barrier(mmtk::plan::BarrierWriteTarget::Object(obj))
362+
.memory_region_copy_pre(src..src + bytes, dst..dst + bytes);
316363
}
317364

365+
/// Array-copy post-barrier
318366
#[no_mangle]
319-
pub extern "C" fn post_write_barrier_slow(
367+
pub extern "C" fn mmtk_array_copy_post(
320368
mutator: &'static mut Mutator<OpenJDK>,
321-
obj: ObjectReference,
369+
src: Address,
370+
dst: Address,
371+
count: usize,
322372
) {
373+
let bytes = count << LOG_BYTES_IN_ADDRESS;
323374
mutator
324375
.barrier()
325-
.post_write_barrier_slow(mmtk::plan::BarrierWriteTarget::Object(obj))
376+
.memory_region_copy_post(src..src + bytes, dst..dst + bytes);
326377
}
327378

328379
// finalization

mmtk/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ extern crate lazy_static;
55
extern crate once_cell;
66

77
use std::collections::HashMap;
8+
use std::ops::Range;
89
use std::ptr::null_mut;
910
use std::sync::atomic::AtomicUsize;
1011
use std::sync::Mutex;
@@ -129,6 +130,7 @@ impl VMBinding for OpenJDK {
129130
type VMReferenceGlue = reference_glue::VMReferenceGlue;
130131

131132
type VMEdge = OpenJDKEdge;
133+
type VMMemorySlice = Range<Address>;
132134
}
133135

134136
use std::sync::atomic::AtomicBool;

openjdk/barriers/mmtkObjectBarrier.cpp

+45-67
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,31 @@
22
#include "mmtkObjectBarrier.hpp"
33
#include "runtime/interfaceSupport.inline.hpp"
44

5-
void MMTkObjectBarrierSetRuntime::record_modified_node_slow(void* obj) {
6-
::post_write_barrier_slow((MMTk_Mutator) &Thread::current()->third_party_heap_mutator, (void*) obj);
7-
}
8-
9-
void MMTkObjectBarrierSetRuntime::record_modified_node_full(void* obj) {
10-
::post_write_barrier((MMTk_Mutator) &Thread::current()->third_party_heap_mutator, (void*) obj);
11-
}
12-
13-
void MMTkObjectBarrierSetRuntime::record_modified_node(oop src) {
14-
#if MMTK_ENABLE_OBJECT_BARRIER_FASTPATH
5+
void MMTkObjectBarrierSetRuntime::object_reference_write_post(oop src, oop* slot, oop target) const {
6+
#if MMTK_ENABLE_BARRIER_FASTPATH
157
intptr_t addr = (intptr_t) (void*) src;
168
uint8_t* meta_addr = (uint8_t*) (SIDE_METADATA_BASE_ADDRESS + (addr >> 6));
179
intptr_t shift = (addr >> 3) & 0b111;
1810
uint8_t byte_val = *meta_addr;
1911
if (((byte_val >> shift) & 1) == 1) {
20-
record_modified_node_slow((void*) src);
12+
// MMTkObjectBarrierSetRuntime::object_reference_write_pre_slow()((void*) src);
13+
object_reference_write_slow_call((void*) src, (void*) slot, (void*) target);
2114
}
2215
#else
23-
record_modified_node_full((void*) src);
16+
object_reference_write_post_call((void*) src, (void*) slot, (void*) target);
2417
#endif
2518
}
2619

2720
#define __ masm->
2821

29-
void MMTkObjectBarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Address dst, Register val, Register tmp1, Register tmp2) {
30-
bool in_heap = (decorators & IN_HEAP) != 0;
31-
bool as_normal = (decorators & AS_NORMAL) != 0;
32-
assert((decorators & IS_DEST_UNINITIALIZED) == 0, "unsupported");
33-
34-
if (!in_heap || val == noreg) {
35-
BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2);
36-
return;
37-
}
38-
39-
BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2);
40-
41-
record_modified_node(masm, dst.base(), tmp1, tmp2);
42-
}
43-
44-
void MMTkObjectBarrierSetAssembler::record_modified_node(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2) {
45-
#if MMTK_ENABLE_OBJECT_BARRIER_FASTPATH
22+
void MMTkObjectBarrierSetAssembler::object_reference_write_post(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2) const {
23+
if (can_remove_barrier(decorators, val, /* skip_const_null */ true)) return;
24+
#if MMTK_ENABLE_BARRIER_FASTPATH
4625
Label done;
4726

4827
Register tmp3 = rscratch1;
4928
Register tmp4 = rscratch2;
29+
Register obj = dst.base();
5030
assert_different_registers(obj, tmp2, tmp3);
5131
assert_different_registers(tmp4, rcx);
5232

@@ -69,18 +49,32 @@ void MMTkObjectBarrierSetAssembler::record_modified_node(MacroAssembler* masm, R
6949
__ cmpptr(tmp2, 1);
7050
__ jcc(Assembler::notEqual, done);
7151

72-
assert_different_registers(c_rarg0, obj);
7352
__ movptr(c_rarg0, obj);
74-
__ call_VM_leaf_base(CAST_FROM_FN_PTR(address, MMTkObjectBarrierSetRuntime::record_modified_node_slow), 1);
53+
__ lea(c_rarg1, dst);
54+
__ movptr(c_rarg2, val == noreg ? (int32_t) NULL_WORD : val);
55+
__ call_VM_leaf_base(FN_ADDR(MMTkBarrierSetRuntime::object_reference_write_slow_call), 3);
7556

7657
__ bind(done);
7758
#else
78-
assert_different_registers(c_rarg0, obj);
7959
__ movptr(c_rarg0, obj);
80-
__ call_VM_leaf_base(CAST_FROM_FN_PTR(address, MMTkObjectBarrierSetRuntime::record_modified_node_full), 1);
60+
__ lea(c_rarg1, dst);
61+
__ movptr(c_rarg2, val == noreg ? (int32_t) NULL_WORD : val);
62+
__ call_VM_leaf_base(FN_ADDR(MMTkBarrierSetRuntime::object_reference_write_post_call), 3);
8163
#endif
8264
}
8365

66+
void MMTkObjectBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register src, Register dst, Register count) {
67+
const bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
68+
if ((type == T_OBJECT || type == T_ARRAY) && !dest_uninitialized) {
69+
__ pusha();
70+
__ movptr(c_rarg0, src);
71+
__ movptr(c_rarg1, dst);
72+
__ movptr(c_rarg2, count);
73+
__ call_VM_leaf_base(FN_ADDR(MMTkBarrierSetRuntime::object_reference_array_copy_post_call), 3);
74+
__ popa();
75+
}
76+
}
77+
8478
#undef __
8579

8680
#ifdef ASSERT
@@ -89,7 +83,7 @@ void MMTkObjectBarrierSetAssembler::record_modified_node(MacroAssembler* masm, R
8983
#define __ gen->lir()->
9084
#endif
9185

92-
void MMTkObjectBarrierSetC1::record_modified_node(LIRAccess& access, LIR_Opr src, LIR_Opr slot, LIR_Opr new_val) {
86+
void MMTkObjectBarrierSetC1::object_reference_write_post(LIRAccess& access, LIR_Opr src, LIR_Opr slot, LIR_Opr new_val) const {
9387
LIRGenerator* gen = access.gen();
9488
DecoratorSet decorators = access.decorators();
9589
if ((decorators & IN_HEAP) == 0) return;
@@ -123,35 +117,31 @@ void MMTkObjectBarrierSetC1::record_modified_node(LIRAccess& access, LIR_Opr src
123117
new_val = new_val_reg;
124118
}
125119
assert(new_val->is_register(), "must be a register at this point");
126-
CodeStub* slow = new MMTkObjectBarrierStub(src, slot, new_val);
120+
CodeStub* slow = new MMTkC1BarrierStub(src, slot, new_val);
127121

128-
#if MMTK_ENABLE_OBJECT_BARRIER_FASTPATH
122+
#if MMTK_ENABLE_BARRIER_FASTPATH
129123
LIR_Opr addr = src;
130124
// uint8_t* meta_addr = (uint8_t*) (SIDE_METADATA_BASE_ADDRESS + (addr >> 6));
131125
LIR_Opr offset = gen->new_pointer_register();
132126
__ move(addr, offset);
133-
__ shift_right(offset, 6, offset);
127+
__ unsigned_shift_right(offset, 6, offset);
134128
LIR_Opr base = gen->new_pointer_register();
135129
__ move(LIR_OprFact::longConst(SIDE_METADATA_BASE_ADDRESS), base);
136130
LIR_Address* meta_addr = new LIR_Address(base, offset, T_BYTE);
137-
// intptr_t shift = (addr >> 3) & 0b111;
138-
LIR_Opr shift_long = gen->new_pointer_register();
139-
__ move(addr, shift_long);
140-
__ shift_right(shift_long, 3, shift_long);
141-
__ logical_and(shift_long, LIR_OprFact::longConst(0b111), shift_long);
142-
LIR_Opr shift_int = gen->new_register(T_INT);
143-
__ convert(Bytecodes::_l2i, shift_long, shift_int);
144-
LIR_Opr shift = LIRGenerator::shiftCountOpr();
145-
__ move(shift_int, shift);
146131
// uint8_t byte_val = *meta_addr;
147132
LIR_Opr byte_val = gen->new_register(T_INT);
148133
__ move(meta_addr, byte_val);
134+
// intptr_t shift = (addr >> 3) & 0b111;
135+
LIR_Opr shift = gen->new_register(T_INT);
136+
__ move(addr, shift);
137+
__ unsigned_shift_right(shift, 3, shift);
138+
__ logical_and(shift, LIR_OprFact::intConst(0b111), shift);
149139
// if (((byte_val >> shift) & 1) == 1) slow;
150140
LIR_Opr result = byte_val;
151-
__ shift_right(result, shift, result, LIR_OprFact::illegalOpr);
141+
__ unsigned_shift_right(result, shift, result, LIR_OprFact::illegalOpr);
152142
__ logical_and(result, LIR_OprFact::intConst(1), result);
153143
__ cmp(lir_cond_equal, result, LIR_OprFact::intConst(1));
154-
__ branch(lir_cond_equal, LP64_ONLY(T_LONG) NOT_LP64(T_INT), slow);
144+
__ branch(lir_cond_equal, T_BYTE, slow);
155145
#else
156146
__ jump(slow);
157147
#endif
@@ -163,24 +153,12 @@ void MMTkObjectBarrierSetC1::record_modified_node(LIRAccess& access, LIR_Opr src
163153

164154
#define __ ideal.
165155

166-
const TypeFunc* record_modified_node_entry_Type() {
167-
const Type **fields = TypeTuple::fields(1);
168-
fields[TypeFunc::Parms+0] = TypeOopPtr::BOTTOM; // oop src
169-
const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
170-
fields = TypeTuple::fields(0);
171-
const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
172-
return TypeFunc::make(domain, range);
173-
}
174-
175-
void MMTkObjectBarrierSetC2::record_modified_node(GraphKit* kit, Node* src, Node* val) const {
176-
if (val != NULL && val->is_Con()) {
177-
const Type* t = val->bottom_type();
178-
if (t == TypePtr::NULL_PTR) return;
179-
}
156+
void MMTkObjectBarrierSetC2::object_reference_write_post(GraphKit* kit, Node* src, Node* slot, Node* val) const {
157+
if (can_remove_barrier(kit, &kit->gvn(), src, slot, val, /* skip_const_null */ true)) return;
180158

181159
MMTkIdealKit ideal(kit, true);
182160

183-
#if MMTK_ENABLE_OBJECT_BARRIER_FASTPATH
161+
#if MMTK_ENABLE_BARRIER_FASTPATH
184162
Node* no_base = __ top();
185163
float unlikely = PROB_UNLIKELY(0.999);
186164

@@ -193,12 +171,12 @@ void MMTkObjectBarrierSetC2::record_modified_node(GraphKit* kit, Node* src, Node
193171
Node* result = __ AndI(__ URShiftI(byte, shift), __ ConI(1));
194172

195173
__ if_then(result, BoolTest::ne, zero, unlikely); {
196-
const TypeFunc* tf = __ func_type(TypeOopPtr::BOTTOM);
197-
Node* x = __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, MMTkObjectBarrierSetRuntime::record_modified_node_slow), "record_modified_node", src);
174+
const TypeFunc* tf = __ func_type(TypeOopPtr::BOTTOM, TypeOopPtr::BOTTOM, TypeOopPtr::BOTTOM);
175+
Node* x = __ make_leaf_call(tf, FN_ADDR(MMTkBarrierSetRuntime::object_reference_write_slow_call), "mmtk_barrier_call", src, slot, val);
198176
} __ end_if();
199177
#else
200-
const TypeFunc* tf = __ func_type(TypeOopPtr::BOTTOM);
201-
Node* x = __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, MMTkObjectBarrierSetRuntime::record_modified_node_full), "record_modified_node", src);
178+
const TypeFunc* tf = __ func_type(TypeOopPtr::BOTTOM, TypeOopPtr::BOTTOM, TypeOopPtr::BOTTOM);
179+
Node* x = __ make_leaf_call(tf, FN_ADDR(MMTkBarrierSetRuntime::object_reference_write_post_call), "mmtk_barrier_call", src, slot, val);
202180
#endif
203181

204182
kit->final_sync(ideal); // Final sync IdealKit and GraphKit.

0 commit comments

Comments
 (0)