Skip to content

Commit 21eb88f

Browse files
authored
Add C2 slowpath allocation barrier (#205)
mmtk/mmtk-core#785 Add the missing C2 slow-path allocation barrier. The C2 slow-path allocation code can do deoptimization after the allocation and before returning to C2 compiled code. The deoptimization itself contains a safepoint. For generational plans, if a GC happens at this safepoint, the allocated object will be promoted, and all the subsequent field initialization should be recorded. The solution is to unconditionally treat this object as being written if the object is not in nursery, and record this object in the modbuf. This is also the solution for G1: https://github.com/mmtk/openjdk/blob/e1e420b3c4fd627218e45ec977972561c559acec/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp#L136-L160
1 parent a557dd4 commit 21eb88f

File tree

7 files changed

+50
-3
lines changed

7 files changed

+50
-3
lines changed

mmtk/Cargo.lock

Lines changed: 9 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mmtk/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ once_cell = "1.10.0"
3030
# - change branch
3131
# - change repo name
3232
# But other changes including adding/removing whitespaces in commented lines may break the CI.
33-
mmtk = { git = "https://github.com/mmtk/mmtk-core.git", rev = "08fd8ab0cfaa240a6e9a401afaec963ec0de8be5" }
33+
mmtk = { git = "https://github.com/mmtk/mmtk-core.git", rev = "c634762cf1417fe2d8f17b1b7b41e14a951044c3" }
3434
# Uncomment the following to build locally
3535
# mmtk = { path = "../repos/mmtk-core" }
3636

mmtk/src/api.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,15 @@ pub extern "C" fn mmtk_array_copy_post(
382382
.memory_region_copy_post(src..src + bytes, dst..dst + bytes);
383383
}
384384

385+
/// C2 Slowpath allocation barrier
386+
#[no_mangle]
387+
pub extern "C" fn mmtk_object_probable_write(
388+
mutator: &'static mut Mutator<OpenJDK>,
389+
obj: ObjectReference,
390+
) {
391+
mutator.barrier().object_probable_write(obj);
392+
}
393+
385394
// finalization
386395
#[no_mangle]
387396
pub extern "C" fn add_finalizer(object: ObjectReference) {

openjdk/barriers/mmtkObjectBarrier.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,25 @@
22
#include "mmtkObjectBarrier.hpp"
33
#include "runtime/interfaceSupport.inline.hpp"
44

5+
void MMTkObjectBarrierSetRuntime::object_probable_write(oop new_obj) const {
6+
#if MMTK_ENABLE_BARRIER_FASTPATH
7+
// Do fast-path check before entering mmtk rust code, to improve mutator performance.
8+
// This is identical to calling `mmtk_object_probable_write` directly without a fast-path.
9+
intptr_t addr = (intptr_t) (void*) new_obj;
10+
uint8_t* meta_addr = (uint8_t*) (SIDE_METADATA_BASE_ADDRESS + (addr >> 6));
11+
intptr_t shift = (addr >> 3) & 0b111;
12+
uint8_t byte_val = *meta_addr;
13+
if (((byte_val >> shift) & 1) == 1) {
14+
// Only promoted objects will reach here.
15+
// The duplicated unlog bit check inside slow-path still remains correct.
16+
mmtk_object_probable_write((MMTk_Mutator) &Thread::current()->third_party_heap_mutator, (void*) new_obj);
17+
}
18+
#else
19+
// The slow-call will do the unlog bit check again (same as the above fast-path check)
20+
mmtk_object_probable_write((MMTk_Mutator) &Thread::current()->third_party_heap_mutator, (void*) new_obj);
21+
#endif
22+
}
23+
524
void MMTkObjectBarrierSetRuntime::object_reference_write_post(oop src, oop* slot, oop target) const {
625
#if MMTK_ENABLE_BARRIER_FASTPATH
726
intptr_t addr = (intptr_t) (void*) src;

openjdk/barriers/mmtkObjectBarrier.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class MMTkObjectBarrierSetRuntime: public MMTkBarrierSetRuntime {
2525
virtual void object_reference_array_copy_post(oop* src, oop* dst, size_t count) const override {
2626
object_reference_array_copy_post_call((void*) src, (void*) dst, count);
2727
}
28+
virtual void object_probable_write(oop new_obj) const override;
2829
};
2930

3031
class MMTkObjectBarrierSetAssembler: public MMTkBarrierSetAssembler {

openjdk/mmtk.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ extern void mmtk_array_copy_pre(MMTk_Mutator mutator, void* src, void* dst, size
6161
/// Full array-copy post-barrier
6262
extern void mmtk_array_copy_post(MMTk_Mutator mutator, void* src, void* dst, size_t count);
6363

64+
/// C2 slowpath allocation barrier
65+
extern void mmtk_object_probable_write(MMTk_Mutator mutator, void* obj);
66+
6467
extern void release_buffer(void** buffer, size_t len, size_t cap);
6568

6669
extern bool is_in_mmtk_spaces(void* ref);

openjdk/mmtkBarrierSet.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ class MMTkBarrierSetRuntime: public CHeapObj<mtGC> {
8787
virtual void object_reference_array_copy_pre(oop* src, oop* dst, size_t count) const {};
8888
/// Full arraycopy post-barrier
8989
virtual void object_reference_array_copy_post(oop* src, oop* dst, size_t count) const {};
90+
/// Called at the end of every C2 slowpath allocation.
91+
/// Deoptimization can happen after C2 slowpath allocation, and the newly allocated object can be promoted.
92+
/// So this callback is requierd for any generational collectors.
93+
virtual void object_probable_write(oop new_obj) const {};
9094
};
9195

9296
class MMTkBarrierC1;
@@ -134,6 +138,10 @@ class MMTkBarrierSet : public BarrierSet {
134138
virtual void on_thread_attach(JavaThread* thread);
135139
virtual void on_thread_detach(JavaThread* thread);
136140

141+
virtual void on_slowpath_allocation_exit(JavaThread* thread, oop new_obj) override {
142+
runtime()->object_probable_write(new_obj);
143+
}
144+
137145
// Inform the BarrierSet that the the covered heap region that starts
138146
// with "base" has been changed to have the given size (possibly from 0,
139147
// for initialization.)

0 commit comments

Comments
 (0)