Skip to content

Commit 00c32e2

Browse files
committed
Initial commit for MMTk support
This commit only supports initializing MMTk with NoGC and object allocation.
1 parent 868d63f commit 00c32e2

19 files changed

+3659
-0
lines changed

gc/mmtk.c

Lines changed: 363 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,363 @@
1+
// clang -I.. -L mmtk/target/debug -lmmtk_ruby -undefined dynamic_lookup -g -O3 -dynamiclib -o ../build/libgc.mmtk.dylib mmtk.c
2+
3+
#include <stdbool.h>
4+
5+
#include "gc/gc.h"
6+
#include "gc/gc_impl.h"
7+
#include "gc/mmtk.h"
8+
9+
bool
10+
rb_mmtk_is_mutator(void)
11+
{
12+
return ruby_native_thread_p();
13+
}
14+
15+
static size_t
16+
rb_mmtk_vm_live_bytes(void)
17+
{
18+
return 0;
19+
}
20+
21+
// Bootup
22+
MMTk_RubyUpcalls ruby_upcalls = {
23+
NULL,
24+
NULL,
25+
rb_mmtk_is_mutator,
26+
NULL,
27+
NULL,
28+
NULL,
29+
NULL,
30+
NULL,
31+
NULL,
32+
NULL,
33+
NULL,
34+
NULL,
35+
NULL,
36+
NULL,
37+
NULL,
38+
NULL,
39+
NULL,
40+
NULL,
41+
NULL,
42+
NULL,
43+
NULL,
44+
NULL,
45+
rb_mmtk_vm_live_bytes,
46+
NULL,
47+
NULL,
48+
NULL,
49+
NULL,
50+
NULL,
51+
NULL,
52+
NULL,
53+
NULL,
54+
NULL,
55+
NULL,
56+
NULL,
57+
NULL,
58+
NULL,
59+
NULL,
60+
NULL,
61+
};
62+
63+
void *
64+
rb_gc_impl_objspace_alloc(void)
65+
{
66+
MMTk_Builder *builder = mmtk_builder_default();
67+
mmtk_init_binding(builder, NULL, &ruby_upcalls);
68+
69+
return NULL;
70+
}
71+
72+
static st_table *obj_id_to_obj_table_alloc(void);
73+
74+
void rb_gc_impl_objspace_init(void *objspace_ptr) { }
75+
76+
void rb_gc_impl_objspace_free(void *objspace_ptr) { }
77+
78+
void *
79+
rb_gc_impl_ractor_cache_alloc(void *objspace_ptr)
80+
{
81+
// TODO: pass not NULL to tls
82+
return mmtk_bind_mutator(NULL);
83+
}
84+
85+
void
86+
rb_gc_impl_ractor_cache_free(void *objspace_ptr, void *cache)
87+
{
88+
// TODO: implement mmtk_destroy_mutator
89+
}
90+
91+
void rb_gc_impl_set_params(void *objspace_ptr) { }
92+
93+
void rb_gc_impl_init(void) { }
94+
95+
void rb_gc_impl_initial_stress_set(VALUE flag) { }
96+
97+
static size_t size_pool_sizes[6] = {
98+
40, 80, 160, 320, 640, 0
99+
};
100+
101+
size_t *
102+
rb_gc_impl_size_pool_sizes(void *objspace_ptr)
103+
{
104+
return size_pool_sizes;
105+
}
106+
107+
// Shutdown
108+
void rb_gc_impl_shutdown_free_objects(void *objspace_ptr) { }
109+
110+
// GC
111+
void
112+
rb_gc_impl_start(void *objspace_ptr, bool full_mark, bool immediate_mark, bool immediate_sweep, bool compact)
113+
{
114+
// TODO
115+
}
116+
117+
bool
118+
rb_gc_impl_during_gc_p(void *objspace_ptr)
119+
{
120+
// TODO
121+
return false;
122+
}
123+
124+
void
125+
rb_gc_impl_prepare_heap(void *objspace_ptr)
126+
{
127+
// TODO
128+
}
129+
130+
void
131+
rb_gc_impl_gc_enable(void *objspace_ptr)
132+
{
133+
// TODO
134+
}
135+
136+
void
137+
rb_gc_impl_gc_disable(void *objspace_ptr, bool finish_current_gc)
138+
{
139+
// TODO
140+
}
141+
142+
bool
143+
rb_gc_impl_gc_enabled_p(void *objspace_ptr)
144+
{
145+
// TODO
146+
return true;
147+
}
148+
149+
void
150+
rb_gc_impl_stress_set(void *objspace_ptr, VALUE flag)
151+
{
152+
// TODO
153+
}
154+
155+
VALUE
156+
rb_gc_impl_stress_get(void *objspace_ptr)
157+
{
158+
// TODO
159+
return Qfalse;
160+
}
161+
162+
VALUE
163+
rb_gc_impl_config_get(void *objspace_ptr)
164+
{
165+
// TODO
166+
return rb_hash_new();
167+
}
168+
VALUE
169+
rb_gc_impl_config_set(void *objspace_ptr, VALUE hash)
170+
{
171+
// TODO
172+
return hash;
173+
}
174+
175+
// Object allocation
176+
177+
VALUE
178+
rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, bool wb_protected, size_t alloc_size)
179+
{
180+
#define MMTK_MIN_OBJ_ALIGN 8
181+
#define MMTK_ALLOCATION_SEMANTICS_DEFAULT 0
182+
if (alloc_size > 640) rb_bug("too big");
183+
for (int i = 0; i < 5; i++) {
184+
if (alloc_size == size_pool_sizes[i]) break;
185+
if (alloc_size < size_pool_sizes[i]) {
186+
alloc_size = size_pool_sizes[i];
187+
break;
188+
}
189+
}
190+
191+
VALUE *alloc_obj = mmtk_alloc(cache_ptr, alloc_size + 8, MMTK_MIN_OBJ_ALIGN, 0, MMTK_ALLOCATION_SEMANTICS_DEFAULT);
192+
alloc_obj++;
193+
alloc_obj[-1] = alloc_size;
194+
alloc_obj[0] = flags;
195+
alloc_obj[1] = klass;
196+
if (alloc_size > 16) alloc_obj[2] = v1;
197+
if (alloc_size > 24) alloc_obj[3] = v2;
198+
if (alloc_size > 32) alloc_obj[4] = v3;
199+
200+
201+
if (rb_gc_shutdown_call_finalizer_p((VALUE)alloc_obj)) {
202+
mmtk_add_obj_free_candidate(alloc_obj);
203+
}
204+
205+
return (VALUE)alloc_obj;
206+
}
207+
208+
size_t
209+
rb_gc_impl_obj_slot_size(VALUE obj)
210+
{
211+
return ((VALUE *)obj)[-1];
212+
}
213+
214+
size_t
215+
rb_gc_impl_size_pool_id_for_size(void *objspace_ptr, size_t size)
216+
{
217+
for (int i = 0; i < 5; i++) {
218+
if (size == size_pool_sizes[i]) return i;
219+
if (size < size_pool_sizes[i]) return i;
220+
}
221+
222+
rb_bug("size too big");
223+
}
224+
225+
bool
226+
rb_gc_impl_size_allocatable_p(size_t size)
227+
{
228+
return size <= 640;
229+
}
230+
231+
// Malloc
232+
void *
233+
rb_gc_impl_malloc(void *objspace_ptr, size_t size)
234+
{
235+
// TODO: don't use system malloc
236+
return malloc(size);
237+
}
238+
239+
void *
240+
rb_gc_impl_calloc(void *objspace_ptr, size_t size)
241+
{
242+
// TODO: don't use system calloc
243+
return calloc(1, size);
244+
}
245+
246+
void *
247+
rb_gc_impl_realloc(void *objspace_ptr, void *ptr, size_t new_size, size_t old_size)
248+
{
249+
// TODO: don't use system realloc
250+
return realloc(ptr, new_size);
251+
}
252+
253+
void
254+
rb_gc_impl_free(void *objspace_ptr, void *ptr, size_t old_size)
255+
{
256+
// TODO: don't use system free
257+
free(ptr);
258+
}
259+
260+
void rb_gc_impl_adjust_memory_usage(void *objspace_ptr, ssize_t diff) { }
261+
// Marking
262+
void
263+
rb_gc_impl_mark(void *objspace_ptr, VALUE obj)
264+
{
265+
rb_bug("unimplemented");
266+
}
267+
268+
void
269+
rb_gc_impl_mark_and_move(void *objspace_ptr, VALUE *ptr)
270+
{
271+
rb_bug("unimplemented");
272+
}
273+
274+
void
275+
rb_gc_impl_mark_and_pin(void *objspace_ptr, VALUE obj)
276+
{
277+
rb_bug("unimplemented");
278+
}
279+
280+
void
281+
rb_gc_impl_mark_maybe(void *objspace_ptr, VALUE obj) {
282+
rb_bug("unimplemented");
283+
}
284+
285+
void
286+
rb_gc_impl_mark_weak(void *objspace_ptr, VALUE *ptr) {
287+
rb_bug("unimplemented");
288+
}
289+
290+
void
291+
rb_gc_impl_remove_weak(void *objspace_ptr, VALUE parent_obj, VALUE *ptr)
292+
{
293+
rb_bug("unimplemented");
294+
}
295+
296+
void
297+
rb_gc_impl_objspace_mark(void *objspace_ptr)
298+
{
299+
rb_bug("unimplemented");
300+
}
301+
302+
// Compaction
303+
bool
304+
rb_gc_impl_object_moved_p(void *objspace_ptr, VALUE obj)
305+
{
306+
rb_bug("unimplemented");
307+
}
308+
309+
VALUE
310+
rb_gc_impl_location(void *objspace_ptr, VALUE value)
311+
{
312+
rb_bug("unimplemented");
313+
}
314+
// Write barriers
315+
void rb_gc_impl_writebarrier(void *objspace_ptr, VALUE a, VALUE b) { }
316+
void rb_gc_impl_writebarrier_unprotect(void *objspace_ptr, VALUE obj) { }
317+
void rb_gc_impl_writebarrier_remember(void *objspace_ptr, VALUE obj) { }
318+
// Heap walking
319+
void rb_gc_impl_each_objects(void *objspace_ptr, int (*callback)(void *, void *, size_t, void *), void *data) { }
320+
void rb_gc_impl_each_object(void *objspace_ptr, void (*func)(VALUE obj, void *data), void *data) { }
321+
// Finalizers
322+
void
323+
rb_gc_impl_make_zombie(void *objspace_ptr, VALUE obj, void (*dfree)(void *), void *data)
324+
{
325+
// TODO: real implementation of making zombie
326+
dfree(data);
327+
}
328+
329+
VALUE rb_gc_impl_define_finalizer(void *objspace_ptr, VALUE obj, VALUE block) { }
330+
VALUE rb_gc_impl_undefine_finalizer(void *objspace_ptr, VALUE obj) { }
331+
void rb_gc_impl_copy_finalizer(void *objspace_ptr, VALUE dest, VALUE obj) { }
332+
333+
void
334+
rb_gc_impl_shutdown_call_finalizer(void *objspace_ptr)
335+
{
336+
struct MMTk_RawVecOfObjRef registered_candidates = mmtk_get_all_obj_free_candidates();
337+
for (size_t i = 0; i < registered_candidates.len; i++) {
338+
VALUE obj = (VALUE)registered_candidates.ptr[i];
339+
340+
if (rb_gc_shutdown_call_finalizer_p(obj)) {
341+
rb_gc_obj_free(objspace_ptr, obj);
342+
}
343+
}
344+
mmtk_free_raw_vec_of_obj_ref(registered_candidates);
345+
}
346+
347+
// Object ID
348+
VALUE rb_gc_impl_object_id(void *objspace_ptr, VALUE obj) { }
349+
VALUE rb_gc_impl_object_id_to_ref(void *objspace_ptr, VALUE object_id) { }
350+
// Statistics
351+
VALUE rb_gc_impl_set_measure_total_time(void *objspace_ptr, VALUE flag) { }
352+
VALUE rb_gc_impl_get_measure_total_time(void *objspace_ptr) { }
353+
VALUE rb_gc_impl_get_profile_total_time(void *objspace_ptr) { }
354+
size_t rb_gc_impl_gc_count(void *objspace_ptr) { }
355+
VALUE rb_gc_impl_latest_gc_info(void *objspace_ptr, VALUE key) { }
356+
size_t rb_gc_impl_stat(void *objspace_ptr, VALUE hash_or_sym) { }
357+
size_t rb_gc_impl_stat_heap(void *objspace_ptr, VALUE heap_name, VALUE hash_or_sym) { }
358+
// Miscellaneous
359+
size_t rb_gc_impl_obj_flags(void *objspace_ptr, VALUE obj, ID* flags, size_t max) { }
360+
bool rb_gc_impl_pointer_to_heap_p(void *objspace_ptr, const void *ptr) { }
361+
bool rb_gc_impl_garbage_object_p(void *objspace_ptr, VALUE obj) { }
362+
void rb_gc_impl_set_event_hook(void *objspace_ptr, const rb_event_flag_t event) { }
363+
void rb_gc_impl_copy_attributes(void *objspace_ptr, VALUE dest, VALUE obj) { }

0 commit comments

Comments
 (0)