Skip to content

Commit 56915e9

Browse files
authored
Embed mutator in _jl_tls_states_t (mmtk#64)
This PR updates the bindings to work with mmtk/julia#16. * Update the layout of `MMTkMutatorContext` * Do not include `gc.h` in `mmtk.h` * Properly maintain the `MUTATORS` table. Add `mmtk_post_bind_mutator`
1 parent 50d3702 commit 56915e9

File tree

10 files changed

+138
-136
lines changed

10 files changed

+138
-136
lines changed

julia/mmtk_julia.c

Lines changed: 31 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "mmtk_julia.h"
22
#include "mmtk.h"
3+
#include "mmtkMutator.h"
34
#include <stdbool.h>
45
#include <stddef.h>
56
#include "gc.h"
@@ -36,23 +37,6 @@ JL_DLLEXPORT void (jl_mmtk_harness_end)(void)
3637
mmtk_harness_end();
3738
}
3839

39-
STATIC_INLINE void* alloc_default_object(jl_ptls_t ptls, size_t size, int offset) {
40-
int64_t delta = (-offset -(int64_t)(ptls->cursor)) & 15; // aligned to 16
41-
uint64_t aligned_addr = (uint64_t)ptls->cursor + delta;
42-
43-
if(__unlikely(aligned_addr+size > (uint64_t)ptls->limit)) {
44-
jl_ptls_t ptls2 = jl_current_task->ptls;
45-
ptls2->mmtk_mutator_ptr->allocators.immix[0].cursor = ptls2->cursor;
46-
void* res = mmtk_alloc(ptls2->mmtk_mutator_ptr, size, 16, offset, 0);
47-
ptls2->cursor = ptls2->mmtk_mutator_ptr->allocators.immix[0].cursor;
48-
ptls2->limit = ptls2->mmtk_mutator_ptr->allocators.immix[0].limit;
49-
return res;
50-
} else {
51-
ptls->cursor = (void*) (aligned_addr+size);
52-
return (void*) aligned_addr;
53-
}
54-
}
55-
5640
JL_DLLEXPORT jl_value_t *jl_mmtk_gc_alloc_default(jl_ptls_t ptls, int pool_offset,
5741
int osize, void *ty)
5842
{
@@ -62,16 +46,16 @@ JL_DLLEXPORT jl_value_t *jl_mmtk_gc_alloc_default(jl_ptls_t ptls, int pool_offse
6246
jl_value_t *v;
6347
if ((uintptr_t)ty != jl_buff_tag) {
6448
// v needs to be 16 byte aligned, therefore v_tagged needs to be offset accordingly to consider the size of header
65-
jl_taggedvalue_t *v_tagged = (jl_taggedvalue_t *)mmtk_alloc(ptls->mmtk_mutator_ptr, osize, 16, sizeof(jl_taggedvalue_t), 0); // (jl_taggedvalue_t *) alloc_default_object(ptls, osize, sizeof(jl_taggedvalue_t));
49+
jl_taggedvalue_t *v_tagged = (jl_taggedvalue_t *)mmtk_alloc(&ptls->mmtk_mutator, osize, 16, sizeof(jl_taggedvalue_t), 0);
6650
v = jl_valueof(v_tagged);
67-
mmtk_post_alloc(ptls->mmtk_mutator_ptr, v, osize, 0);
51+
mmtk_post_alloc(&ptls->mmtk_mutator, v, osize, 0);
6852
} else {
6953
// allocating an extra word to store the size of buffer objects
70-
jl_taggedvalue_t *v_tagged = (jl_taggedvalue_t *)mmtk_alloc(ptls->mmtk_mutator_ptr, osize + sizeof(jl_taggedvalue_t), 16, 0, 0); // (jl_taggedvalue_t *) alloc_default_object(ptls, osize + sizeof(jl_taggedvalue_t), 0);
54+
jl_taggedvalue_t *v_tagged = (jl_taggedvalue_t *)mmtk_alloc(&ptls->mmtk_mutator, osize + sizeof(jl_taggedvalue_t), 16, 0, 0);
7155
jl_value_t* v_tagged_aligned = ((jl_value_t*)((char*)(v_tagged) + sizeof(jl_taggedvalue_t)));
7256
v = jl_valueof(v_tagged_aligned);
7357
mmtk_store_obj_size_c(v, osize + sizeof(jl_taggedvalue_t));
74-
mmtk_post_alloc(ptls->mmtk_mutator_ptr, v, osize + sizeof(jl_taggedvalue_t), 0);
58+
mmtk_post_alloc(&ptls->mmtk_mutator, v, osize + sizeof(jl_taggedvalue_t), 0);
7559
}
7660

7761
ptls->gc_num.allocd += osize;
@@ -95,7 +79,7 @@ JL_DLLEXPORT jl_value_t *jl_mmtk_gc_alloc_big(jl_ptls_t ptls, size_t sz)
9579
jl_throw(jl_memory_exception);
9680
}
9781

98-
bigval_t *v = (bigval_t*)mmtk_alloc_large(ptls->mmtk_mutator_ptr, allocsz, JL_CACHE_BYTE_ALIGNMENT, 0, 2);
82+
bigval_t *v = (bigval_t*)mmtk_alloc_large(&ptls->mmtk_mutator, allocsz, JL_CACHE_BYTE_ALIGNMENT, 0, 2);
9983

10084
if (v == NULL) {
10185
assert(0 && "Allocation failed");
@@ -107,7 +91,7 @@ JL_DLLEXPORT jl_value_t *jl_mmtk_gc_alloc_big(jl_ptls_t ptls, size_t sz)
10791
ptls->gc_num.bigalloc++;
10892

10993
jl_value_t *result = jl_valueof(&v->header);
110-
mmtk_post_alloc(ptls->mmtk_mutator_ptr, result, allocsz, 2);
94+
mmtk_post_alloc(&ptls->mmtk_mutator, result, allocsz, 2);
11195

11296
return result;
11397
}
@@ -147,7 +131,7 @@ static void mmtk_sweep_malloced_arrays(void) JL_NOTSAFEPOINT
147131
extern void mark_metadata_scanned(jl_value_t* obj);
148132
extern int8_t check_metadata_scanned(jl_value_t* obj);
149133

150-
int8_t object_has_been_scanned(jl_value_t* obj)
134+
int8_t object_has_been_scanned(void* obj)
151135
{
152136
uintptr_t tag = (uintptr_t)jl_typeof(obj);
153137
jl_datatype_t *vt = (jl_datatype_t*)tag;
@@ -164,7 +148,7 @@ int8_t object_has_been_scanned(jl_value_t* obj)
164148
return 0;
165149
}
166150

167-
void mark_object_as_scanned(jl_value_t* obj) {
151+
void mark_object_as_scanned(void* obj) {
168152
if (jl_object_in_image((jl_value_t *)obj)) {
169153
jl_taggedvalue_t *o = jl_astaggedvalue(obj);
170154
o->bits.gc = GC_MARKED;
@@ -185,8 +169,9 @@ void mmtk_exit_from_safepoint(int8_t old_state) {
185169
// it will block until GC is done
186170
// that thread simply exits from block_for_gc without executing finalizers
187171
// when executing finalizers do not let another thread do GC (set a variable such that while that variable is true, no GC can be done)
188-
int8_t set_gc_initial_state(jl_ptls_t ptls)
172+
int8_t set_gc_initial_state(void* ptls_raw)
189173
{
174+
jl_ptls_t ptls = (jl_ptls_t) ptls_raw;
190175
int8_t old_state = jl_atomic_load_relaxed(&((jl_ptls_t)ptls)->gc_state);
191176
jl_atomic_store_release(&((jl_ptls_t)ptls)->gc_state, JL_GC_STATE_WAITING);
192177
if (!jl_safepoint_start_gc()) {
@@ -231,8 +216,9 @@ void wait_for_the_world(void)
231216
}
232217
}
233218

234-
size_t get_lo_size(jl_value_t* obj)
219+
size_t get_lo_size(void* obj_raw)
235220
{
221+
jl_value_t* obj = (jl_value_t*) obj_raw;
236222
jl_taggedvalue_t *v = jl_astaggedvalue(obj);
237223
// bigval_header: but we cannot access the function here. So use container_of instead.
238224
bigval_t* hdr = container_of(v, bigval_t, header);
@@ -246,18 +232,12 @@ void set_jl_last_err(int e)
246232

247233
int get_jl_last_err(void)
248234
{
249-
gc_n_threads = jl_atomic_load_acquire(&jl_n_threads);
250-
gc_all_tls_states = jl_atomic_load_relaxed(&jl_all_tls_states);
251-
for (int t_i = 0; t_i < gc_n_threads; t_i++) {
252-
jl_ptls_t ptls = gc_all_tls_states[t_i];
253-
ptls->cursor = 0;
254-
ptls->limit = 0;
255-
}
256235
return errno;
257236
}
258237

259-
void* get_obj_start_ref(jl_value_t* obj)
238+
void* get_obj_start_ref(void* obj_raw)
260239
{
240+
jl_value_t* obj = (jl_value_t*) obj_raw;
261241
uintptr_t tag = (uintptr_t)jl_typeof(obj);
262242
jl_datatype_t *vt = (jl_datatype_t*)tag;
263243
void* obj_start_ref;
@@ -271,8 +251,9 @@ void* get_obj_start_ref(jl_value_t* obj)
271251
return obj_start_ref;
272252
}
273253

274-
size_t get_so_size(jl_value_t* obj)
254+
size_t get_so_size(void* obj_raw)
275255
{
256+
jl_value_t* obj = (jl_value_t*) obj_raw;
276257
uintptr_t tag = (uintptr_t)jl_typeof(obj);
277258
jl_datatype_t *vt = (jl_datatype_t*)tag;
278259

@@ -392,8 +373,10 @@ size_t get_so_size(jl_value_t* obj)
392373
return 0;
393374
}
394375

395-
void run_finalizer_function(jl_value_t *o, jl_value_t *ff, bool is_ptr)
376+
void run_finalizer_function(void *o_raw, void *ff_raw, bool is_ptr)
396377
{
378+
jl_value_t *o = (jl_value_t*) o_raw;
379+
jl_value_t *ff = (jl_value_t*) ff_raw;
397380
if (is_ptr) {
398381
run_finalizer(jl_current_task, (jl_value_t *)(((uintptr_t)o) | 1), (jl_value_t *)ff);
399382
} else {
@@ -423,7 +406,7 @@ void mmtk_jl_run_pending_finalizers(void* ptls) {
423406
}
424407
}
425408

426-
void mmtk_jl_run_finalizers(jl_ptls_t ptls) {
409+
void mmtk_jl_run_finalizers(void* ptls) {
427410
// Only disable finalizers on current thread
428411
// Doing this on all threads is racy (it's impossible to check
429412
// or wait for finalizers on other threads without dead lock).
@@ -663,7 +646,7 @@ static void jl_gc_queue_remset_mmtk(jl_ptls_t ptls2)
663646
}
664647
}
665648

666-
void calculate_roots(jl_ptls_t ptls)
649+
void calculate_roots(void* ptls_raw)
667650
{
668651
for (int t_i = 0; t_i < gc_n_threads; t_i++)
669652
gc_premark(gc_all_tls_states[t_i]);
@@ -682,8 +665,8 @@ void calculate_roots(jl_ptls_t ptls)
682665
queue_roots();
683666
}
684667

685-
JL_DLLEXPORT void scan_julia_exc_obj(jl_task_t* obj, closure_pointer closure, ProcessEdgeFn process_edge) {
686-
jl_task_t *ta = (jl_task_t*)obj;
668+
JL_DLLEXPORT void scan_julia_exc_obj(void* obj_raw, closure_pointer closure, ProcessEdgeFn process_edge) {
669+
jl_task_t *ta = (jl_task_t*)obj_raw;
687670

688671
if (ta->excstack) { // inlining label `excstack` from mark_loop
689672
// if it is not managed by MMTk, nothing needs to be done because the object does not need to be scanned
@@ -745,8 +728,9 @@ const bool PRINT_OBJ_TYPE = false;
745728
* directly (not an edge), specifying whether to scan the object or not; and only scan the object
746729
* (necessary for boot image / non-MMTk objects)
747730
**/
748-
JL_DLLEXPORT void scan_julia_obj(jl_value_t* obj, closure_pointer closure, ProcessEdgeFn process_edge, ProcessOffsetEdgeFn process_offset_edge)
731+
JL_DLLEXPORT void scan_julia_obj(void* obj_raw, closure_pointer closure, ProcessEdgeFn process_edge, ProcessOffsetEdgeFn process_offset_edge)
749732
{
733+
jl_value_t* obj = (jl_value_t*) obj_raw;
750734
uintptr_t tag = (uintptr_t)jl_typeof(obj);
751735
jl_datatype_t *vt = (jl_datatype_t*)tag; // type of obj
752736

@@ -962,6 +946,10 @@ void update_gc_time(uint64_t inc) {
962946
gc_num.total_time += inc;
963947
}
964948

949+
uintptr_t get_abi_structs_checksum_c(void) {
950+
return sizeof(MMTkMutatorContext);
951+
}
952+
965953
Julia_Upcalls mmtk_upcalls = (Julia_Upcalls) {
966954
.scan_julia_obj = scan_julia_obj,
967955
.scan_julia_exc_obj = scan_julia_exc_obj,
@@ -986,4 +974,5 @@ Julia_Upcalls mmtk_upcalls = (Julia_Upcalls) {
986974
.exit_from_safepoint = mmtk_exit_from_safepoint,
987975
.jl_hrtime = jl_hrtime,
988976
.update_gc_time = update_gc_time,
977+
.get_abi_structs_checksum_c = get_abi_structs_checksum_c,
989978
};

julia/mmtk_julia.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,16 @@
33

44
extern Julia_Upcalls mmtk_upcalls;
55

6-
void calculate_roots(jl_ptls_t ptls);
7-
8-
void run_finalizer_function(jl_value_t *o, jl_value_t *ff, bool is_ptr);
9-
106
int get_jl_last_err(void);
117

128
void set_jl_last_err(int e);
139

14-
size_t get_lo_size(jl_value_t* obj);
15-
16-
int8_t set_gc_initial_state(jl_ptls_t ptls);
17-
1810
void set_gc_final_state(int8_t old_state);
1911

2012
int set_gc_running_state(jl_ptls_t ptls);
2113

2214
void set_gc_old_state(int8_t old_state);
2315

24-
void mark_object_as_scanned(jl_value_t* obj);
25-
26-
int8_t object_has_been_scanned(jl_value_t* obj);
27-
2816
void mmtk_jl_gc_run_all_finalizers(void);
2917

30-
void mmtk_jl_run_finalizers(jl_ptls_t tls);
31-
3218
void mmtk_jl_run_pending_finalizers(void* tls);
33-
34-
JL_DLLEXPORT void scan_julia_obj(jl_value_t* obj, closure_pointer closure, ProcessEdgeFn process_edge, ProcessOffsetEdgeFn process_offset_edge);

mmtk/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ edition = "2018"
1010
[package.metadata.julia]
1111
# Our CI matches the following line and extract mmtk/julia. If this line is updated, please check ci yaml files and make sure it works.
1212
julia_repo = "https://github.com/mmtk/julia.git"
13-
julia_version = "0eeb64b0191b08b0ce7b59a66dea6139db60dbd2"
13+
julia_version = "98a66ba3c0925ea21bfe051a191210eeae7df0f2"
1414

1515
[lib]
1616
crate-type = ["staticlib", "rlib", "dylib"]

mmtk/api/mmtk.h

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
#include <stdbool.h>
55
#include <stddef.h>
66
#include <stdint.h>
7-
#include "gc.h"
87

98
#ifdef __cplusplus
109
extern "C" {
@@ -24,7 +23,7 @@ typedef void (*ProcessOffsetEdgeFn)(closure_pointer closure, void* slot, int off
2423
* Allocation
2524
*/
2625
extern MMTk_Mutator mmtk_bind_mutator(void *tls, int tid);
27-
extern void mmtk_add_mutator_ref(void* mutator_ref);
26+
extern void mmtk_post_bind_mutator(MMTk_Mutator mutator, MMTk_Mutator original_mutator);
2827
extern void mmtk_destroy_mutator(MMTk_Mutator mutator);
2928

3029
extern void* mmtk_alloc(MMTk_Mutator mutator, size_t size,
@@ -78,29 +77,30 @@ extern const void* MMTK_SIDE_LOG_BIT_BASE_ADDRESS;
7877
// * int is 4 bytes
7978
// * size_t is 8 bytes
8079
typedef struct {
81-
void (* scan_julia_obj) (jl_value_t* obj, closure_pointer closure, ProcessEdgeFn process_edge, ProcessOffsetEdgeFn process_offset_edge);
82-
void (* scan_julia_exc_obj) (jl_task_t* obj, closure_pointer closure, ProcessEdgeFn process_edge);
80+
void (* scan_julia_obj) (void* obj, closure_pointer closure, ProcessEdgeFn process_edge, ProcessOffsetEdgeFn process_offset_edge);
81+
void (* scan_julia_exc_obj) (void* obj, closure_pointer closure, ProcessEdgeFn process_edge);
8382
void* (* get_stackbase) (int16_t tid);
84-
void (* calculate_roots) (jl_ptls_t tls);
85-
void (* run_finalizer_function) (jl_value_t* obj, jl_value_t* function, bool is_ptr);
83+
void (* calculate_roots) (void* tls);
84+
void (* run_finalizer_function) (void* obj, void* function, bool is_ptr);
8685
int (* get_jl_last_err) (void);
8786
void (* set_jl_last_err) (int e);
88-
size_t (* get_lo_size) (jl_value_t* obj);
89-
size_t (* get_so_size) (jl_value_t* obj);
90-
void* (* get_obj_start_ref) (jl_value_t* obj);
87+
size_t (* get_lo_size) (void* obj);
88+
size_t (* get_so_size) (void* obj);
89+
void* (* get_obj_start_ref) (void* obj);
9190
void (* wait_for_the_world) (void);
92-
int8_t (* set_gc_initial_state) (jl_ptls_t tls);
91+
int8_t (* set_gc_initial_state) (void* tls);
9392
void (* set_gc_final_state) (int8_t old_state);
9493
void (* set_gc_old_state) (int8_t old_state);
95-
void (* mmtk_jl_run_finalizers) (jl_ptls_t tls);
94+
void (* mmtk_jl_run_finalizers) (void* tls);
9695
void (* jl_throw_out_of_memory_error) (void);
97-
void (* mark_object_as_scanned) (jl_value_t* obj);
98-
int8_t (* object_has_been_scanned) (jl_value_t* obj);
96+
void (* mark_object_as_scanned) (void* obj);
97+
int8_t (* object_has_been_scanned) (void* obj);
9998
void (* sweep_malloced_array) (void);
10099
void (* wait_in_a_safepoint) (void);
101100
void (* exit_from_safepoint) (int8_t old_state);
102101
uint64_t (* jl_hrtime) (void);
103102
void (* update_gc_time) (uint64_t);
103+
uintptr_t (* get_abi_structs_checksum_c) (void);
104104
} Julia_Upcalls;
105105

106106
/**

mmtk/api/mmtkMutator.h

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ typedef struct {
1515
} RustDynPtr;
1616

1717
// These constants should match the constants defind in mmtk::util::alloc::allocators
18-
// const int MAX_BUMP_ALLOCATORS = 6;
19-
// const int MAX_LARGE_OBJECT_ALLOCATORS = 2;
20-
// const int MAX_MALLOC_ALLOCATORS = 1;
21-
// const int MAX_IMMIX_ALLOCATORS = 1;
22-
// const int MAX_MARK_COMPACT_ALLOCATORS = 1;
18+
#define MAX_BUMP_ALLOCATORS 6
19+
#define MAX_LARGE_OBJECT_ALLOCATORS 2
20+
#define MAX_MALLOC_ALLOCATORS 1
21+
#define MAX_IMMIX_ALLOCATORS 1
22+
#define MAX_FREE_LIST_ALLOCATORS 2
23+
#define MAX_MARK_COMPACT_ALLOCATORS 1
2324

2425
// The following types should have the same layout as the types with the same name in MMTk core (Rust)
2526

@@ -51,25 +52,46 @@ typedef struct {
5152
uint8_t _align[7];
5253
uint8_t line_opt_tag;
5354
uintptr_t line_opt;
54-
uint8_t alloc_slow_for_stress;
5555
} ImmixAllocator;
5656

57+
typedef struct {
58+
void* Address;
59+
} FLBlock;
60+
61+
typedef struct {
62+
FLBlock first;
63+
FLBlock last;
64+
size_t size;
65+
char lock;
66+
} FLBlockList;
67+
68+
typedef struct {
69+
void* tls;
70+
void* space;
71+
RustDynPtr plan;
72+
FLBlockList* available_blocks;
73+
FLBlockList* available_blocks_stress;
74+
FLBlockList* unswept_blocks;
75+
FLBlockList* consumed_blocks;
76+
} FreeListAllocator;
77+
5778
typedef struct {
5879
void* tls;
5980
void* space;
6081
RustDynPtr plan;
61-
} MMTkMallocAllocator;
82+
} MMTkMallocAllocator; // Prefix with MMTk to avoid name clash
6283

6384
typedef struct {
6485
BumpAllocator bump_allocator;
6586
} MarkCompactAllocator;
6687

6788
typedef struct {
68-
BumpAllocator bump_pointer[6];
69-
LargeObjectAllocator large_object[2];
70-
MMTkMallocAllocator malloc[1];
71-
ImmixAllocator immix[1];
72-
MarkCompactAllocator markcompact[1];
89+
BumpAllocator bump_pointer[MAX_BUMP_ALLOCATORS];
90+
LargeObjectAllocator large_object[MAX_LARGE_OBJECT_ALLOCATORS];
91+
MMTkMallocAllocator malloc[MAX_MALLOC_ALLOCATORS];
92+
ImmixAllocator immix[MAX_IMMIX_ALLOCATORS];
93+
FreeListAllocator free_list[MAX_FREE_LIST_ALLOCATORS];
94+
MarkCompactAllocator markcompact[MAX_MARK_COMPACT_ALLOCATORS];
7395
} Allocators;
7496

7597
typedef struct {
@@ -81,9 +103,10 @@ typedef struct {
81103

82104
typedef struct {
83105
Allocators allocators;
84-
void* barrier;
106+
RustDynPtr barrier;
85107
void* mutator_tls;
86108
RustDynPtr plan;
87109
MutatorConfig config;
88110
} MMTkMutatorContext;
111+
89112
#endif // MMTK_MUTATOR_HPP

0 commit comments

Comments
 (0)