9 #include "gc/gc_impl.h"
10 #include "gc/mmtk/mmtk.h"
12 #include "ccan/list/list.h"
16 #include <sys/sysctl.h>
25 size_t total_allocated_objects;
29 unsigned long long next_object_id;
35 struct ccan_list_head ractor_caches;
36 unsigned long live_ractor_cache_count;
38 pthread_mutex_t mutex;
40 pthread_cond_t cond_world_stopped;
41 pthread_cond_t cond_world_started;
42 size_t start_the_world_count;
44 struct rb_gc_vm_context vm_context;
48 struct ccan_list_node list_node;
50 MMTk_Mutator *mutator;
58 MMTK_FINAL_JOB_FINALIZE,
67 VALUE finalizer_array;
72 #ifdef RB_THREAD_LOCAL_SPECIFIER
75 # error We currently need language-supported TLS
83 rb_mmtk_gc_thread_tls = gc_thread_tls;
87 rb_mmtk_is_mutator(
void)
93 rb_mmtk_stop_the_world(
void)
98 if ((err = pthread_mutex_lock(&
objspace->mutex)) != 0) {
99 rb_bug(
"ERROR: cannot lock objspace->mutex: %s", strerror(err));
106 if ((err = pthread_mutex_unlock(&
objspace->mutex)) != 0) {
107 rb_bug(
"ERROR: cannot release objspace->mutex: %s", strerror(err));
112 rb_mmtk_resume_mutators(
void)
117 if ((err = pthread_mutex_lock(&
objspace->mutex)) != 0) {
118 rb_bug(
"ERROR: cannot lock objspace->mutex: %s", strerror(err));
123 pthread_cond_broadcast(&
objspace->cond_world_started);
125 if ((err = pthread_mutex_unlock(&
objspace->mutex)) != 0) {
126 rb_bug(
"ERROR: cannot release objspace->mutex: %s", strerror(err));
135 size_t starting_gc_count =
objspace->gc_count;
136 int lock_lev = rb_gc_vm_lock();
138 if ((err = pthread_mutex_lock(&
objspace->mutex)) != 0) {
139 rb_bug(
"ERROR: cannot lock objspace->mutex: %s", strerror(err));
142 if (
objspace->gc_count == starting_gc_count) {
145 rb_gc_initialize_vm_context(&
objspace->vm_context);
147 mutator->gc_mutator_p =
true;
151 clock_gettime(CLOCK_MONOTONIC, &gc_start_time);
154 rb_gc_save_machine_context();
160 pthread_cond_broadcast(&
objspace->cond_world_stopped);
169 clock_gettime(CLOCK_MONOTONIC, &gc_end_time);
172 (gc_end_time.tv_sec - gc_start_time.tv_sec) * (1000 * 1000 * 1000) +
173 (gc_end_time.tv_nsec - gc_start_time.tv_nsec);
177 if ((err = pthread_mutex_unlock(&
objspace->mutex)) != 0) {
178 rb_bug(
"ERROR: cannot release objspace->mutex: %s", strerror(err));
180 rb_gc_vm_unlock(lock_lev);
184 rb_mmtk_number_of_mutators(
void)
187 return objspace->live_ractor_cache_count;
191 rb_mmtk_get_mutators(
void (*visit_mutator)(MMTk_Mutator *mutator,
void *data),
void *data)
198 ccan_list_for_each(&
objspace->ractor_caches, ractor_cache, list_node) {
199 visit_mutator(ractor_cache->mutator, data);
204 rb_mmtk_scan_gc_roots(
void)
210 pin_value(st_data_t key, st_data_t value, st_data_t data)
212 rb_gc_impl_mark_and_pin((
void *)data, (
VALUE)value);
218 rb_mmtk_scan_objspace(
void)
222 if (
objspace->finalizer_table != NULL) {
229 while (job != NULL) {
231 case MMTK_FINAL_JOB_DFREE:
233 case MMTK_FINAL_JOB_FINALIZE:
234 rb_gc_impl_mark(
objspace, job->as.finalize.object_id);
235 rb_gc_impl_mark(
objspace, job->as.finalize.finalizer_array);
238 rb_bug(
"rb_mmtk_scan_objspace: unknown final job type %d", job->kind);
248 if (mutator->gc_mutator_p) {
251 rb_gc_worker_thread_set_vm_context(&
objspace->vm_context);
253 rb_gc_worker_thread_unset_vm_context(&
objspace->vm_context);
258 rb_mmtk_scan_object_ruby_style(MMTk_ObjectReference
object)
260 rb_gc_mark_children(rb_gc_get_objspace(), (
VALUE)
object);
264 rb_mmtk_call_gc_mark_children(MMTk_ObjectReference
object)
266 rb_gc_mark_children(rb_gc_get_objspace(), (
VALUE)
object);
270 rb_mmtk_call_obj_free(MMTk_ObjectReference
object)
276 rb_gc_worker_thread_set_vm_context(&
objspace->vm_context);
278 rb_gc_worker_thread_unset_vm_context(&
objspace->vm_context);
285 rb_mmtk_vm_live_bytes(
void)
294 RUBY_ASSERT(mmtk_is_reachable((MMTk_ObjectReference)table));
300 job->next =
objspace->finalizer_jobs;
301 job->kind = MMTK_FINAL_JOB_FINALIZE;
303 job->as.finalize.finalizer_array = table;
309 rb_mmtk_update_finalizer_table_i(st_data_t key, st_data_t value, st_data_t data)
312 RUBY_ASSERT(mmtk_is_reachable((MMTk_ObjectReference)value));
317 if (!mmtk_is_reachable((MMTk_ObjectReference)key)) {
329 rb_mmtk_update_finalizer_table(
void)
338 rb_mmtk_update_table_i(
VALUE val,
void *data)
340 if (!mmtk_is_reachable((MMTk_ObjectReference)val)) {
348 rb_mmtk_update_obj_id_tables_obj_to_id_i(st_data_t key, st_data_t val, st_data_t data)
352 if (!mmtk_is_reachable((MMTk_ObjectReference)key)) {
360 rb_mmtk_update_obj_id_tables_id_to_obj_i(st_data_t key, st_data_t val, st_data_t data)
364 if (!mmtk_is_reachable((MMTk_ObjectReference)val)) {
372 rb_mmtk_update_obj_id_tables(
void)
381 rb_mmtk_global_tables_count(
void)
383 return RB_GC_VM_WEAK_TABLE_COUNT;
387 rb_mmtk_update_global_tables(
int table)
391 rb_gc_vm_weak_table_foreach(rb_mmtk_update_table_i, NULL, NULL, (
enum rb_gc_vm_weak_tables)table);
396 rb_mmtk_init_gc_worker_thread,
398 rb_mmtk_stop_the_world,
399 rb_mmtk_resume_mutators,
400 rb_mmtk_block_for_gc,
401 rb_mmtk_number_of_mutators,
402 rb_mmtk_get_mutators,
403 rb_mmtk_scan_gc_roots,
404 rb_mmtk_scan_objspace,
405 rb_mmtk_scan_roots_in_mutator_thread,
406 rb_mmtk_scan_object_ruby_style,
407 rb_mmtk_call_gc_mark_children,
408 rb_mmtk_call_obj_free,
409 rb_mmtk_vm_live_bytes,
410 rb_mmtk_update_global_tables,
411 rb_mmtk_global_tables_count,
412 rb_mmtk_update_finalizer_table,
413 rb_mmtk_update_obj_id_tables,
417 #define RB_MMTK_HEAP_LIMIT_PERC 80
418 #define RB_MMTK_DEFAULT_HEAP_MIN (1024 * 1024)
419 #define RB_MMTK_DEFAULT_HEAP_MAX (rb_mmtk_system_physical_memory() / 100 * RB_MMTK_HEAP_LIMIT_PERC)
421 enum mmtk_heap_mode {
422 RB_MMTK_DYNAMIC_HEAP,
427 rb_mmtk_builder_init(
void)
429 MMTk_Builder *builder = mmtk_builder_default();
434 rb_gc_impl_objspace_alloc(
void)
436 MMTk_Builder *builder = rb_mmtk_builder_init();
437 mmtk_init_binding(builder, NULL, &ruby_upcalls, (MMTk_ObjectReference)
Qundef);
439 return calloc(1,
sizeof(
struct objspace));
443 static void gc_run_finalizers(
void *data);
446 rb_gc_impl_objspace_init(
void *objspace_ptr)
454 objspace->finalizer_table = st_init_numtable();
457 ccan_list_head_init(&
objspace->ractor_caches);
459 objspace->mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
460 objspace->cond_world_stopped = (pthread_cond_t)PTHREAD_COND_INITIALIZER;
461 objspace->cond_world_started = (pthread_cond_t)PTHREAD_COND_INITIALIZER;
465 rb_gc_impl_objspace_free(
void *objspace_ptr)
471 rb_gc_impl_ractor_cache_alloc(
void *objspace_ptr,
void *ractor)
474 if (
objspace->live_ractor_cache_count == 0) {
475 mmtk_initialize_collection(ractor);
477 objspace->live_ractor_cache_count++;
480 ccan_list_add(&
objspace->ractor_caches, &cache->list_node);
482 cache->mutator = mmtk_bind_mutator(cache);
488 rb_gc_impl_ractor_cache_free(
void *objspace_ptr,
void *cache_ptr)
493 ccan_list_del(&cache->list_node);
496 objspace->live_ractor_cache_count--;
498 mmtk_destroy_mutator(cache->mutator);
501 void rb_gc_impl_set_params(
void *objspace_ptr) { }
503 static VALUE gc_verify_internal_consistency(
VALUE self) {
return Qnil; }
506 rb_gc_impl_init(
void)
527 static size_t heap_sizes[6] = {
528 40, 80, 160, 320, 640, 0
532 rb_gc_impl_heap_sizes(
void *objspace_ptr)
538 rb_mmtk_obj_free_iter_wrapper(
VALUE obj,
void *data)
543 rb_gc_obj_free_vm_weak_references(obj);
554 rb_gc_impl_shutdown_free_objects(
void *objspace_ptr)
556 mmtk_set_gc_enabled(
false);
557 each_object(objspace_ptr, rb_mmtk_obj_free_iter_wrapper, objspace_ptr);
558 mmtk_set_gc_enabled(
true);
563 rb_gc_impl_start(
void *objspace_ptr,
bool full_mark,
bool immediate_mark,
bool immediate_sweep,
bool compact)
565 bool enabled = mmtk_gc_enabled_p();
567 mmtk_set_gc_enabled(
true);
570 mmtk_handle_user_collection_request(rb_gc_get_ractor_newobj_cache());
573 mmtk_set_gc_enabled(
false);
578 rb_gc_impl_during_gc_p(
void *objspace_ptr)
585 rb_gc_impl_prepare_heap_i(MMTk_ObjectReference obj,
void *d)
587 rb_gc_prepare_heap_process_object((
VALUE)obj);
591 rb_gc_impl_prepare_heap(
void *objspace_ptr)
593 mmtk_enumerate_objects(rb_gc_impl_prepare_heap_i, NULL);
597 rb_gc_impl_gc_enable(
void *objspace_ptr)
599 mmtk_set_gc_enabled(
true);
603 rb_gc_impl_gc_disable(
void *objspace_ptr,
bool finish_current_gc)
605 mmtk_set_gc_enabled(
false);
609 rb_gc_impl_gc_enabled_p(
void *objspace_ptr)
611 return mmtk_gc_enabled_p();
615 rb_gc_impl_stress_set(
void *objspace_ptr,
VALUE flag)
623 rb_gc_impl_stress_get(
void *objspace_ptr)
631 rb_gc_impl_config_get(
void *objspace_ptr)
638 rb_gc_impl_config_set(
void *objspace_ptr,
VALUE hash)
646 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)
648 #define MMTK_ALLOCATION_SEMANTICS_DEFAULT 0
652 if (alloc_size > 640)
rb_bug(
"too big");
653 for (
int i = 0; i < 5; i++) {
654 if (alloc_size == heap_sizes[i])
break;
655 if (alloc_size < heap_sizes[i]) {
656 alloc_size = heap_sizes[i];
662 mmtk_handle_user_collection_request(ractor_cache);
665 VALUE *alloc_obj = mmtk_alloc(ractor_cache->mutator, alloc_size + 8, MMTk_MIN_OBJ_ALIGN, 0, MMTK_ALLOCATION_SEMANTICS_DEFAULT);
667 alloc_obj[-1] = alloc_size;
668 alloc_obj[0] = flags;
669 alloc_obj[1] = klass;
670 if (alloc_size > 16) alloc_obj[2] = v1;
671 if (alloc_size > 24) alloc_obj[3] = v2;
672 if (alloc_size > 32) alloc_obj[4] = v3;
674 mmtk_post_alloc(ractor_cache->mutator, (
void*)alloc_obj, alloc_size + 8, MMTK_ALLOCATION_SEMANTICS_DEFAULT);
677 mmtk_add_obj_free_candidate(alloc_obj);
679 objspace->total_allocated_objects++;
681 return (
VALUE)alloc_obj;
685 rb_gc_impl_obj_slot_size(
VALUE obj)
687 return ((
VALUE *)obj)[-1];
691 rb_gc_impl_heap_id_for_size(
void *objspace_ptr,
size_t size)
693 for (
int i = 0; i < 5; i++) {
694 if (size == heap_sizes[i])
return i;
695 if (size < heap_sizes[i])
return i;
702 rb_gc_impl_size_allocatable_p(
size_t size)
709 rb_gc_impl_malloc(
void *objspace_ptr,
size_t size)
716 rb_gc_impl_calloc(
void *objspace_ptr,
size_t size)
719 return calloc(1, size);
723 rb_gc_impl_realloc(
void *objspace_ptr,
void *
ptr,
size_t new_size,
size_t old_size)
726 return realloc(
ptr, new_size);
730 rb_gc_impl_free(
void *objspace_ptr,
void *
ptr,
size_t old_size)
736 void rb_gc_impl_adjust_memory_usage(
void *objspace_ptr, ssize_t diff) { }
740 rb_gc_impl_mark(
void *objspace_ptr,
VALUE obj)
745 rb_mmtk_gc_thread_tls->gc_context,
746 (MMTk_ObjectReference)obj,
751 rb_gc_impl_mark_and_move(
void *objspace_ptr,
VALUE *
ptr)
756 rb_gc_impl_mark(objspace_ptr, *
ptr);
760 rb_gc_impl_mark_and_pin(
void *objspace_ptr,
VALUE obj)
765 rb_gc_impl_mark(objspace_ptr, obj);
769 rb_gc_impl_mark_maybe(
void *objspace_ptr,
VALUE obj)
771 if (rb_gc_impl_pointer_to_heap_p(objspace_ptr, (
const void *)obj)) {
772 rb_gc_impl_mark_and_pin(objspace_ptr, obj);
777 rb_gc_impl_mark_weak(
void *objspace_ptr,
VALUE *
ptr)
779 mmtk_mark_weak((MMTk_ObjectReference *)
ptr);
783 rb_gc_impl_remove_weak(
void *objspace_ptr,
VALUE parent_obj,
VALUE *
ptr)
785 mmtk_remove_weak((MMTk_ObjectReference *)
ptr);
790 rb_gc_impl_object_moved_p(
void *objspace_ptr,
VALUE obj)
796 rb_gc_impl_location(
void *objspace_ptr,
VALUE value)
803 rb_gc_impl_writebarrier(
void *objspace_ptr,
VALUE a,
VALUE b)
807 mmtk_object_reference_write_post(cache->mutator, (MMTk_ObjectReference)a);
811 rb_gc_impl_writebarrier_unprotect(
void *objspace_ptr,
VALUE obj)
813 mmtk_register_wb_unprotected_object((MMTk_ObjectReference)obj);
817 rb_gc_impl_writebarrier_remember(
void *objspace_ptr,
VALUE obj)
821 mmtk_object_reference_write_post(cache->mutator, (MMTk_ObjectReference)obj);
826 each_objects_i(MMTk_ObjectReference obj,
void *d)
828 rb_darray(
VALUE) *objs = d;
830 rb_darray_append(objs, (
VALUE)obj);
836 rb_darray(
VALUE) objs;
837 rb_darray_make(&objs, 0);
839 mmtk_enumerate_objects(each_objects_i, &objs);
842 rb_darray_foreach(objs, i, obj_ptr) {
843 if (!mmtk_is_mmtk_object((MMTk_ObjectReference)*obj_ptr))
continue;
845 if (func(*obj_ptr, data) != 0) {
850 rb_darray_free(objs);
854 int (*func)(
void *,
void *, size_t,
void *);
859 rb_gc_impl_each_objects_i(
VALUE obj,
void *d)
863 size_t slot_size = rb_gc_impl_obj_slot_size(obj);
865 return data->func((
void *)obj, (
void *)(obj + slot_size), slot_size, data->data);
869 rb_gc_impl_each_objects(
void *objspace_ptr,
int (*func)(
void *,
void *,
size_t,
void *),
void *data)
876 each_object(objspace_ptr, rb_gc_impl_each_objects_i, &each_objects_data);
880 void (*func)(
VALUE,
void *);
885 rb_gc_impl_each_object_i(
VALUE obj,
void *d)
889 data->func(obj, data->data);
895 rb_gc_impl_each_object(
void *objspace_ptr,
void (*func)(
VALUE,
void *),
void *data)
902 each_object(objspace_ptr, rb_gc_impl_each_object_i, &each_object_data);
907 gc_run_finalizers_get_final(
long i,
void *data)
915 gc_run_finalizers(
void *data)
919 rb_gc_set_pending_interrupt();
921 while (
objspace->finalizer_jobs != NULL) {
923 objspace->finalizer_jobs = job->next;
926 case MMTK_FINAL_JOB_DFREE:
927 job->as.dfree.func(job->as.dfree.data);
929 case MMTK_FINAL_JOB_FINALIZE: {
930 VALUE object_id = job->as.finalize.object_id;
931 VALUE finalizer_array = job->as.finalize.finalizer_array;
933 rb_gc_run_obj_finalizer(
934 job->as.finalize.object_id,
936 gc_run_finalizers_get_final,
937 (
void *)finalizer_array
949 rb_gc_unset_pending_interrupt();
953 rb_gc_impl_make_zombie(
void *objspace_ptr,
VALUE obj,
void (*dfree)(
void *),
void *data)
955 if (dfree == NULL)
return;
960 job->kind = MMTK_FINAL_JOB_DFREE;
961 job->as.dfree.func = dfree;
962 job->as.dfree.data = data;
966 job->next =
objspace->finalizer_jobs;
968 }
while (prev != job->next);
976 rb_gc_impl_define_finalizer(
void *objspace_ptr,
VALUE obj,
VALUE block)
984 if (st_lookup(
objspace->finalizer_table, obj, &data)) {
992 for (i = 0; i <
len; i++) {
1005 st_add_direct(
objspace->finalizer_table, obj, table);
1012 rb_gc_impl_undefine_finalizer(
void *objspace_ptr,
VALUE obj)
1016 st_data_t data = obj;
1017 st_delete(
objspace->finalizer_table, &data, 0);
1022 rb_gc_impl_copy_finalizer(
void *objspace_ptr,
VALUE dest,
VALUE obj)
1031 table = (
VALUE)data;
1032 st_insert(
objspace->finalizer_table, dest, table);
1036 rb_bug(
"rb_gc_copy_finalizer: FL_FINALIZE set but not found in finalizer_table: %s", rb_obj_info(obj));
1041 move_finalizer_from_table_i(st_data_t key, st_data_t val, st_data_t arg)
1051 rb_gc_impl_shutdown_call_finalizer(
void *objspace_ptr)
1055 while (
objspace->finalizer_table->num_entries) {
1062 for (
size_t i = 0; i < registered_candidates.len; i++) {
1063 VALUE obj = (
VALUE)registered_candidates.ptr[i];
1065 if (rb_gc_shutdown_call_finalizer_p(obj)) {
1066 rb_gc_obj_free(objspace_ptr, obj);
1070 mmtk_free_raw_vec_of_obj_ref(registered_candidates);
1077 object_id_cmp(st_data_t x, st_data_t y)
1088 object_id_hash(st_data_t n)
1093 #define OBJ_ID_INCREMENT (RUBY_IMMEDIATE_MASK + 1)
1094 #define OBJ_ID_INITIAL (OBJ_ID_INCREMENT)
1096 static const struct st_hash_type object_id_hash_type = {
1104 objspace->id_to_obj_tbl = st_init_table(&object_id_hash_type);
1105 objspace->obj_to_id_tbl = st_init_numtable();
1106 objspace->next_object_id = OBJ_ID_INITIAL;
1110 rb_gc_impl_object_id(
void *objspace_ptr,
VALUE obj)
1114 unsigned int lev = rb_gc_vm_lock();
1117 if (st_lookup(
objspace->obj_to_id_tbl, (st_data_t)obj, &
id)) {
1124 objspace->next_object_id += OBJ_ID_INCREMENT;
1126 st_insert(
objspace->obj_to_id_tbl, (st_data_t)obj, (st_data_t)
id);
1127 st_insert(
objspace->id_to_obj_tbl, (st_data_t)
id, (st_data_t)obj);
1131 rb_gc_vm_unlock(lev);
1137 rb_gc_impl_object_id_to_ref(
void *objspace_ptr,
VALUE object_id)
1142 if (st_lookup(
objspace->id_to_obj_tbl, object_id, &obj) &&
1143 !rb_gc_impl_garbage_object_p(
objspace, obj)) {
1158 rb_gc_impl_before_fork(
void *objspace_ptr)
1164 rb_gc_impl_after_fork(
void *objspace_ptr, rb_pid_t pid)
1166 mmtk_after_fork(rb_gc_get_ractor_newobj_cache());
1172 rb_gc_impl_set_measure_total_time(
void *objspace_ptr,
VALUE flag)
1180 rb_gc_impl_get_measure_total_time(
void *objspace_ptr)
1188 rb_gc_impl_get_total_time(
void *objspace_ptr)
1196 rb_gc_impl_gc_count(
void *objspace_ptr)
1204 rb_gc_impl_latest_gc_info(
void *objspace_ptr,
VALUE hash_or_key)
1215 rb_bug(
"gc_info_decode: non-hash or symbol given");
1218 #define SET(name, attr) \
1219 if (key == ID2SYM(rb_intern_const(#name))) \
1221 else if (hash != Qnil) \
1222 rb_hash_aset(hash, ID2SYM(rb_intern_const(#name)), (attr));
1240 gc_stat_sym_total_allocated_objects,
1241 gc_stat_sym_total_bytes,
1242 gc_stat_sym_used_bytes,
1243 gc_stat_sym_free_bytes,
1244 gc_stat_sym_starting_heap_address,
1245 gc_stat_sym_last_heap_address,
1249 static VALUE gc_stat_symbols[gc_stat_sym_last];
1252 setup_gc_stat_symbols(
void)
1254 if (gc_stat_symbols[0] == 0) {
1255 #define S(s) gc_stat_symbols[gc_stat_sym_##s] = ID2SYM(rb_intern_const(#s))
1258 S(total_allocated_objects);
1262 S(starting_heap_address);
1263 S(last_heap_address);
1268 rb_gc_impl_stat(
void *objspace_ptr,
VALUE hash_or_sym)
1273 setup_gc_stat_symbols();
1282 rb_bug(
"non-hash or symbol given");
1285 #define SET(name, attr) \
1286 if (key == gc_stat_symbols[gc_stat_sym_##name]) \
1287 return SIZET2NUM(attr); \
1288 else if (hash != Qnil) \
1289 rb_hash_aset(hash, gc_stat_symbols[gc_stat_sym_##name], SIZET2NUM(attr));
1292 SET(time,
objspace->total_gc_time / (1000 * 1000));
1293 SET(total_allocated_objects,
objspace->total_allocated_objects);
1294 SET(total_bytes, mmtk_total_bytes());
1295 SET(used_bytes, mmtk_used_bytes());
1296 SET(free_bytes, mmtk_free_bytes());
1297 SET(starting_heap_address, (
size_t)mmtk_starting_heap_address());
1298 SET(last_heap_address, (
size_t)mmtk_last_heap_address());
1310 rb_gc_impl_stat_heap(
void *objspace_ptr,
VALUE heap_name,
VALUE hash_or_sym)
1322 rb_gc_impl_obj_flags(
void *objspace_ptr,
VALUE obj,
ID* flags,
size_t max)
1328 rb_gc_impl_pointer_to_heap_p(
void *objspace_ptr,
const void *
ptr)
1330 if (
ptr == NULL)
return false;
1331 if ((uintptr_t)
ptr %
sizeof(
void*) != 0)
return false;
1332 return mmtk_is_mmtk_object((MMTk_Address)
ptr);
1336 rb_gc_impl_garbage_object_p(
void *objspace_ptr,
VALUE obj)
1341 void rb_gc_impl_set_event_hook(
void *objspace_ptr,
const rb_event_flag_t event) { }
1344 rb_gc_impl_copy_attributes(
void *objspace_ptr,
VALUE dest,
VALUE obj)
1346 if (mmtk_object_wb_unprotected_p((MMTk_ObjectReference)obj)) {
1347 rb_gc_impl_writebarrier_unprotect(objspace_ptr, dest);
1350 rb_gc_impl_copy_finalizer(objspace_ptr, dest, obj);
1356 rb_gc_impl_active_gc_name(
void)
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
#define RUBY_ATOMIC_PTR_CAS(var, oldval, newval)
Identical to RUBY_ATOMIC_CAS, except it expects its arguments are void*.
#define RB_LIKELY(x)
Asserts that the given Boolean expression likely holds.
#define RB_UNLIKELY(x)
Asserts that the given Boolean expression likely doesn't hold.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
unsigned int rb_postponed_job_handle_t
The type of a handle returned from rb_postponed_job_preregister and passed to rb_postponed_job_trigge...
void rb_postponed_job_trigger(rb_postponed_job_handle_t h)
Triggers a pre-registered job registered with rb_postponed_job_preregister, scheduling it for executi...
rb_postponed_job_handle_t rb_postponed_job_preregister(unsigned int flags, rb_postponed_job_func_t func, void *data)
Pre-registers a func in Ruby's postponed job preregistration table, returning an opaque handle which ...
#define RUBY_INTERNAL_EVENT_FREEOBJ
Object swept.
#define RUBY_INTERNAL_EVENT_GC_START
GC started.
uint32_t rb_event_flag_t
Represents event(s).
static VALUE RB_FL_TEST(VALUE obj, VALUE flags)
Tests if the given flag(s) are set or not.
static void RB_FL_UNSET(VALUE obj, VALUE flags)
Clears the given flag(s).
@ RUBY_FL_FINALIZE
This flag has something to do with finalisers.
#define xfree
Old name of ruby_xfree.
#define Qundef
Old name of RUBY_Qundef.
#define INT2FIX
Old name of RB_INT2FIX.
#define ID2SYM
Old name of RB_ID2SYM.
#define T_BIGNUM
Old name of RUBY_T_BIGNUM.
#define OBJ_FREEZE
Old name of RB_OBJ_FREEZE.
#define FL_SEEN_OBJ_ID
Old name of RUBY_FL_SEEN_OBJ_ID.
#define T_NONE
Old name of RUBY_T_NONE.
#define SIZET2NUM
Old name of RB_SIZE2NUM.
#define xmalloc
Old name of ruby_xmalloc.
#define LONG2FIX
Old name of RB_INT2FIX.
#define FL_FINALIZE
Old name of RUBY_FL_FINALIZE.
#define T_HASH
Old name of RUBY_T_HASH.
#define FL_SET
Old name of RB_FL_SET.
#define rb_ary_new3
Old name of rb_ary_new_from_args.
#define ULL2NUM
Old name of RB_ULL2NUM.
#define Qtrue
Old name of RUBY_Qtrue.
#define INT2NUM
Old name of RB_INT2NUM.
#define Qnil
Old name of RUBY_Qnil.
#define Qfalse
Old name of RUBY_Qfalse.
#define FIX2LONG
Old name of RB_FIX2LONG.
#define T_ARRAY
Old name of RUBY_T_ARRAY.
#define NIL_P
Old name of RB_NIL_P.
#define FL_TEST
Old name of RB_FL_TEST.
#define FL_UNSET
Old name of RB_FL_UNSET.
#define SYMBOL_P
Old name of RB_SYMBOL_P.
void rb_raise(VALUE exc_class, const char *fmt,...)
Exception entry point.
void rb_bug(const char *fmt,...)
Interpreter panic switch.
VALUE rb_eRangeError
RangeError exception.
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
VALUE rb_equal(VALUE lhs, VALUE rhs)
This function is an optimised version of calling #==.
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
VALUE rb_ary_push(VALUE ary, VALUE elem)
Special case of rb_ary_cat() that it adds only one element.
VALUE rb_big_eql(VALUE lhs, VALUE rhs)
Equality, in terms of eql?.
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Inserts or replaces ("upsert"s) the objects into the given hash table.
VALUE rb_hash(VALUE obj)
Calculates a message authentication code of the passed object.
VALUE rb_hash_new(void)
Creates a new, empty hash object.
VALUE rb_obj_id(VALUE obj)
Finds or creates an integer primary key of the given object.
VALUE rb_f_notimplement(int argc, const VALUE *argv, VALUE obj, VALUE marker)
Raises rb_eNotImpError.
static ID rb_intern_const(const char *str)
This is a "tiny optimisation" over rb_intern().
ID rb_intern(const char *name)
Finds or creates a symbol of the given name.
void rb_define_const(VALUE klass, const char *name, VALUE val)
Defines a Ruby level constant under a namespace.
char * ptr
Pointer to the underlying memory region, of at least capa bytes.
int len
Length of the buffer.
bool ruby_free_at_exit_p(void)
Returns whether the Ruby VM will free all memory at shutdown.
#define RB_GC_GUARD(v)
Prevents premature destruction of local objects.
int st_foreach(st_table *q, int_type *w, st_data_t e)
Iteration over the given table.
#define RARRAY_LEN
Just another name of rb_array_len.
#define RARRAY_AREF(a, i)
#define RBASIC(obj)
Convenient casting macro.
int ruby_native_thread_p(void)
Queries if the thread which calls this function is a ruby's thread.
static bool RB_SPECIAL_CONST_P(VALUE obj)
Checks if the given object is of enum ruby_special_consts.
#define RTEST
This is an old name of RB_TEST.
void * rust_closure
The pointer to the Rust-level closure object.
MMTk_ObjectClosureFunction c_function
The function to be called from C.
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
uintptr_t VALUE
Type that represents a Ruby object.
static enum ruby_value_type RB_BUILTIN_TYPE(VALUE obj)
Queries the type of the object.
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.