Ruby 4.1.0dev (2026-09-05 revision ce1eaf724f17561a1978f61d780b8977230930c8)
gc_impl.h
1#ifndef GC_GC_IMPL_H
2#define GC_GC_IMPL_H
11#include "ruby/ruby.h"
12
13#include <stddef.h>
14#include <stdint.h>
15
16enum rb_gc_zjit_fastpath_kind {
17 RB_GC_ZJIT_FASTPATH_DEFAULT = 1,
18 RB_GC_ZJIT_FASTPATH_MMTK = 2,
19};
20
21#define RB_GC_ZJIT_FASTPATH_DATA_WORDS 19
22
24 uintptr_t words[RB_GC_ZJIT_FASTPATH_DATA_WORDS];
25};
26
28 enum rb_gc_zjit_fastpath_kind kind;
29 union rb_gc_zjit_fastpath_data data;
30};
31
32#ifndef RB_GC_OBJECT_METADATA_ENTRY_DEFINED
33# define RB_GC_OBJECT_METADATA_ENTRY_DEFINED
35 ID name;
36 VALUE val;
37};
38#endif
39
40#ifdef BUILDING_MODULAR_GC
41# define GC_IMPL_FN
42#else
43// `GC_IMPL_FN` is an implementation detail of `!USE_MODULAR_GC` builds
44// to have the default GC in the same translation unit as gc.c for
45// the sake of optimizer visibility. It expands to nothing unless
46// you're the default GC.
47//
48// For the default GC, do not copy-paste this when implementing
49// these functions. This takes advantage of internal linkage winning
50// when appearing first. See C99 6.2.2p4.
51# define GC_IMPL_FN static
52#endif
53
54// Bootup
55GC_IMPL_FN void *rb_gc_impl_objspace_alloc(void);
56GC_IMPL_FN void rb_gc_impl_objspace_init(void *objspace_ptr);
57GC_IMPL_FN void *rb_gc_impl_ractor_cache_alloc(void *objspace_ptr, void *ractor);
58GC_IMPL_FN void rb_gc_impl_objspace_retire_gc(void *objspace_ptr);
59GC_IMPL_FN void rb_gc_impl_set_params(void *objspace_ptr);
60GC_IMPL_FN void rb_gc_impl_init(void);
61// Shutdown
62GC_IMPL_FN void rb_gc_impl_shutdown_free_objects(void *objspace_ptr);
63GC_IMPL_FN void rb_gc_impl_objspace_free(void *objspace_ptr);
64GC_IMPL_FN void rb_gc_impl_ractor_cache_free(void *objspace_ptr, void *cache);
65// GC
66GC_IMPL_FN void rb_gc_impl_start(void *objspace_ptr, bool full_mark, bool immediate_mark, bool immediate_sweep, bool compact);
67GC_IMPL_FN bool rb_gc_impl_during_gc_p(void *objspace_ptr);
68GC_IMPL_FN void rb_gc_impl_prepare_heap(void *objspace_ptr);
69GC_IMPL_FN void rb_gc_impl_gc_enable(void *objspace_ptr);
70GC_IMPL_FN void rb_gc_impl_gc_disable(void *objspace_ptr, bool finish_current_gc);
71GC_IMPL_FN bool rb_gc_impl_gc_enabled_p(void *objspace_ptr);
72GC_IMPL_FN bool rb_gc_impl_user_gc_disabled_set(void *objspace_ptr, bool disable);
73GC_IMPL_FN bool rb_gc_impl_user_gc_disabled_p(void *objspace_ptr);
74GC_IMPL_FN void rb_gc_impl_gc_rest(void *objspace_ptr);
75GC_IMPL_FN void rb_gc_impl_stress_set(void *objspace_ptr, VALUE flag);
76GC_IMPL_FN VALUE rb_gc_impl_stress_get(void *objspace_ptr);
77GC_IMPL_FN VALUE rb_gc_impl_config_get(void *objspace_ptr);
78GC_IMPL_FN void rb_gc_impl_config_set(void *objspace_ptr, VALUE hash);
79GC_IMPL_FN struct rb_gc_vm_context *rb_gc_impl_get_vm_context(void *objspace_ptr);
80// Object allocation
81GC_IMPL_FN VALUE rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags, bool wb_protected, size_t alloc_size, size_t *actual_alloc_size);
82/* This is an (optional) function that allows the GC implementation to return
83 * metadata for ZJIT's fast path object allocator. Returns `true` if ZJIT can
84 * use the fast path allocator, `false` otherwise.
85 *
86 * The GC is provided `alloc_size`, `flags`, and `class` which describe the
87 * object to be allocated. The GC can use this information to perform
88 * precomputation and fill `fastpath` with GC-specific metadata. ZJIT owns the
89 * generated instruction sequence; see zjit/src/gc_fastpath.rs.
90 */
91GC_IMPL_FN bool rb_gc_impl_zjit_new_obj_fastpath(void *objspace_ptr, size_t alloc_size, VALUE flags, VALUE klass, struct rb_gc_zjit_fastpath *fastpath);
92GC_IMPL_FN size_t rb_gc_impl_obj_slot_size(VALUE obj);
93GC_IMPL_FN size_t rb_gc_impl_size_slot_size(void *objspace_ptr, size_t size);
94GC_IMPL_FN bool rb_gc_impl_size_allocatable_p(size_t size);
95GC_IMPL_FN size_t rb_gc_impl_max_allocation_size(void);
96// Malloc
97/*
98 * BEWARE: These functions may or may not run under GVL.
99 *
100 * You might want to make them thread-safe.
101 * Garbage collecting inside is possible if and only if you
102 * already have GVL. Also raising exceptions without one is a
103 * total disaster.
104 *
105 * When you absolutely cannot allocate the requested amount of
106 * memory just return NULL (with appropriate errno set).
107 * The caller side takes care of that situation.
108 */
109GC_IMPL_FN void *rb_gc_impl_malloc(void *objspace_ptr, size_t size, bool gc_allowed);
110GC_IMPL_FN void *rb_gc_impl_calloc(void *objspace_ptr, size_t size, bool gc_allowed);
111GC_IMPL_FN void *rb_gc_impl_realloc(void *objspace_ptr, void *ptr, size_t new_size, size_t old_size, bool gc_allowed);
112GC_IMPL_FN void rb_gc_impl_free(void *objspace_ptr, void *ptr, size_t old_size);
113GC_IMPL_FN void rb_gc_impl_adjust_memory_usage(void *objspace_ptr, ssize_t diff);
114// Marking
115GC_IMPL_FN void rb_gc_impl_mark(void *objspace_ptr, VALUE obj);
116GC_IMPL_FN void rb_gc_impl_mark_and_move(void *objspace_ptr, VALUE *ptr);
117GC_IMPL_FN void rb_gc_impl_mark_and_pin(void *objspace_ptr, VALUE obj);
118GC_IMPL_FN void rb_gc_impl_mark_maybe(void *objspace_ptr, VALUE obj);
119// Weak references
120GC_IMPL_FN void rb_gc_impl_declare_weak_references(void *objspace_ptr, VALUE obj);
121GC_IMPL_FN bool rb_gc_impl_handle_weak_references_alive_p(void *objspace_ptr, VALUE obj);
122// Compaction
123GC_IMPL_FN void rb_gc_impl_register_pinning_obj(void *objspace_ptr, VALUE obj);
124GC_IMPL_FN bool rb_gc_impl_object_moved_p(void *objspace_ptr, VALUE obj);
125GC_IMPL_FN bool rb_gc_impl_pinned_p(void *objspace_ptr, VALUE obj);
126GC_IMPL_FN VALUE rb_gc_impl_location(void *objspace_ptr, VALUE value);
127// Write barriers
128GC_IMPL_FN void rb_gc_impl_writebarrier(void *objspace_ptr, VALUE a, VALUE b);
129GC_IMPL_FN void rb_gc_impl_writebarrier_unprotect(void *objspace_ptr, VALUE obj);
130GC_IMPL_FN void rb_gc_impl_writebarrier_remember(void *objspace_ptr, VALUE obj);
131GC_IMPL_FN void rb_gc_impl_obj_became_shareable(void *objspace_ptr, VALUE obj);
132// Heap walking
133GC_IMPL_FN void rb_gc_impl_each_objects(void *objspace_ptr, int (*callback)(void *, void *, size_t, void *), void *data);
134GC_IMPL_FN void rb_gc_impl_each_objects_shareable(void *objspace_ptr, int (*callback)(void *, void *, size_t, void *), void *data);
135GC_IMPL_FN void rb_gc_impl_each_objects_foreign(void *objspace_ptr, int (*callback)(void *, void *, size_t, void *), void *data);
136/* Whether the impl supports multiple per-Ractor objspaces. When false the VM shares a single
137 * objspace and passes the per-Ractor objspace machinery (retire, absorb, ...) straight through. */
138GC_IMPL_FN bool rb_gc_impl_multi_objspace_p(void);
139GC_IMPL_FN bool rb_gc_impl_during_global_gc_p(void *objspace_ptr);
140/* Whether the current collection is a dying thread's final collection of its own
141 * objspace, whose torn-down machine context must not be scanned. */
142GC_IMPL_FN bool rb_gc_impl_during_postmortem_p(void *objspace_ptr);
143/* Whether obj is owned by an objspace other than objspace_ptr. Always false for a single
144 * objspace impl. */
145GC_IMPL_FN bool rb_gc_impl_obj_foreign_p(void *objspace_ptr, VALUE obj);
146GC_IMPL_FN bool rb_gc_impl_shref_marked_p(void *objspace_ptr, VALUE obj);
147GC_IMPL_FN size_t rb_gc_impl_heap_page_count(void *objspace_ptr);
148GC_IMPL_FN void rb_gc_impl_objspace_absorb(void *dst_ptr, void *src_ptr);
149GC_IMPL_FN void rb_gc_impl_each_object(void *objspace_ptr, void (*func)(VALUE obj, void *data), void *data);
150// Finalizers
151GC_IMPL_FN void rb_gc_impl_make_zombie(void *objspace_ptr, VALUE obj, void (*dfree)(void *), void *data);
152GC_IMPL_FN VALUE rb_gc_impl_define_finalizer(void *objspace_ptr, VALUE obj, VALUE block);
153GC_IMPL_FN void rb_gc_impl_undefine_finalizer(void *objspace_ptr, VALUE obj);
154GC_IMPL_FN void rb_gc_impl_copy_finalizer(void *objspace_ptr, VALUE dest, VALUE obj);
155GC_IMPL_FN void rb_gc_impl_shutdown_call_finalizer(void *objspace_ptr);
156// Forking
157GC_IMPL_FN void rb_gc_impl_before_fork(void *objspace_ptr);
158GC_IMPL_FN void rb_gc_impl_after_fork(void *objspace_ptr, rb_pid_t pid);
159// Statistics
160GC_IMPL_FN void rb_gc_impl_set_measure_total_time(void *objspace_ptr, VALUE flag);
161GC_IMPL_FN bool rb_gc_impl_get_measure_total_time(void *objspace_ptr);
162GC_IMPL_FN unsigned long long rb_gc_impl_get_total_time(void *objspace_ptr);
163GC_IMPL_FN size_t rb_gc_impl_gc_count(void *objspace_ptr);
164GC_IMPL_FN VALUE rb_gc_impl_latest_gc_info(void *objspace_ptr, VALUE key);
165GC_IMPL_FN VALUE rb_gc_impl_stat(void *objspace_ptr, VALUE hash_or_sym);
166GC_IMPL_FN VALUE rb_gc_impl_stat_heap(void *objspace_ptr, VALUE heap_name, VALUE hash_or_sym);
167GC_IMPL_FN const char *rb_gc_impl_active_gc_name(void);
168// Miscellaneous
169GC_IMPL_FN struct rb_gc_object_metadata_entry *rb_gc_impl_object_metadata(void *objspace_ptr, VALUE obj);
170GC_IMPL_FN bool rb_gc_impl_live_object_p(void *objspace_ptr, const void *ptr);
171GC_IMPL_FN bool rb_gc_impl_garbage_object_p(void *objspace_ptr, VALUE obj);
172GC_IMPL_FN void rb_gc_impl_set_event_hook(void *objspace_ptr, const rb_event_flag_t event);
173GC_IMPL_FN void rb_gc_impl_copy_attributes(void *objspace_ptr, VALUE dest, VALUE obj);
174
175#undef GC_IMPL_FN
176
177#endif
uint32_t rb_event_flag_t
Represents event(s).
Definition event.h:108
Definition gc_impl.h:34
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
Definition value.h:52
uintptr_t VALUE
Type that represents a Ruby object.
Definition value.h:40