Ruby 4.1.0dev (2026-11-12 revision e6e232d5facd495b6a7f143cf6e9c7960392ca25)
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, bool global);
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);
92/* Returns the offset of a word inside the objspace that is nonzero while that
93 * objspace is incremental-marking, or -1 if the implementation does not support
94 * ZJIT's inline write barrier fast path. ZJIT-generated code skips the call to
95 * rb_gc_writebarrier() when the receiver has neither RUBY_FL_PROMOTED nor
96 * RUBY_FL_SHAREABLE set and the word of the current Ractor's objspace is zero,
97 * so only implementations whose write barrier is a no-op under exactly those
98 * conditions may return a nonnegative offset.
99 */
100GC_IMPL_FN int32_t rb_gc_impl_zjit_writebarrier_required_offset(void);
101GC_IMPL_FN size_t rb_gc_impl_obj_slot_size(VALUE obj);
102GC_IMPL_FN size_t rb_gc_impl_size_slot_size(void *objspace_ptr, size_t size);
103GC_IMPL_FN bool rb_gc_impl_size_allocatable_p(size_t size);
104GC_IMPL_FN size_t rb_gc_impl_max_allocation_size(void);
105// Malloc
106/*
107 * BEWARE: These functions may or may not run under GVL.
108 *
109 * You might want to make them thread-safe.
110 * Garbage collecting inside is possible if and only if you
111 * already have GVL. Also raising exceptions without one is a
112 * total disaster.
113 *
114 * When you absolutely cannot allocate the requested amount of
115 * memory just return NULL (with appropriate errno set).
116 * The caller side takes care of that situation.
117 */
118GC_IMPL_FN void *rb_gc_impl_malloc(void *objspace_ptr, size_t size, bool gc_allowed);
119GC_IMPL_FN void *rb_gc_impl_calloc(void *objspace_ptr, size_t size, bool gc_allowed);
120GC_IMPL_FN void *rb_gc_impl_realloc(void *objspace_ptr, void *ptr, size_t new_size, size_t old_size, bool gc_allowed);
121GC_IMPL_FN void rb_gc_impl_free(void *objspace_ptr, void *ptr, size_t old_size);
122GC_IMPL_FN void rb_gc_impl_adjust_memory_usage(void *objspace_ptr, ssize_t diff);
123// Marking
124GC_IMPL_FN void rb_gc_impl_mark(void *objspace_ptr, VALUE obj);
125GC_IMPL_FN void rb_gc_impl_mark_and_move(void *objspace_ptr, VALUE *ptr);
126GC_IMPL_FN void rb_gc_impl_mark_and_pin(void *objspace_ptr, VALUE obj);
127GC_IMPL_FN void rb_gc_impl_mark_maybe(void *objspace_ptr, VALUE obj);
128// Weak references
129GC_IMPL_FN void rb_gc_impl_declare_weak_references(void *objspace_ptr, VALUE obj);
130GC_IMPL_FN bool rb_gc_impl_handle_weak_references_alive_p(void *objspace_ptr, VALUE obj);
131// Compaction
132GC_IMPL_FN void rb_gc_impl_register_pinning_obj(void *objspace_ptr, VALUE obj);
133GC_IMPL_FN bool rb_gc_impl_object_moved_p(void *objspace_ptr, VALUE obj);
134GC_IMPL_FN bool rb_gc_impl_pinned_p(void *objspace_ptr, VALUE obj);
135GC_IMPL_FN VALUE rb_gc_impl_location(void *objspace_ptr, VALUE value);
136// Write barriers
137GC_IMPL_FN void rb_gc_impl_writebarrier(void *objspace_ptr, VALUE a, VALUE b);
138GC_IMPL_FN void rb_gc_impl_writebarrier_unprotect(void *objspace_ptr, VALUE obj);
139GC_IMPL_FN void rb_gc_impl_writebarrier_remember(void *objspace_ptr, VALUE obj);
140GC_IMPL_FN void rb_gc_impl_obj_became_shareable(void *objspace_ptr, VALUE obj);
141// Heap walking
142GC_IMPL_FN void rb_gc_impl_each_objects(void *objspace_ptr, int (*callback)(void *, void *, size_t, void *), void *data);
143GC_IMPL_FN void rb_gc_impl_each_objects_shareable(void *objspace_ptr, int (*callback)(void *, void *, size_t, void *), void *data);
144GC_IMPL_FN void rb_gc_impl_each_objects_foreign(void *objspace_ptr, int (*callback)(void *, void *, size_t, void *), void *data);
145/* Whether the impl supports multiple per-Ractor objspaces. When false the VM shares a single
146 * objspace and passes the per-Ractor objspace machinery (retire, absorb, ...) straight through. */
147GC_IMPL_FN bool rb_gc_impl_multi_objspace_p(void);
148GC_IMPL_FN bool rb_gc_impl_during_global_gc_p(void *objspace_ptr);
149/* Whether the current collection is a dying thread's final collection of its own
150 * objspace, whose torn-down machine context must not be scanned. */
151GC_IMPL_FN bool rb_gc_impl_during_postmortem_p(void *objspace_ptr);
152/* Whether obj is owned by an objspace other than objspace_ptr. Always false for a single
153 * objspace impl. */
154GC_IMPL_FN bool rb_gc_impl_obj_foreign_p(void *objspace_ptr, VALUE obj);
155GC_IMPL_FN void rb_gc_impl_objspace_set_ractor(void *objspace_ptr, void *ractor);
156GC_IMPL_FN void *rb_gc_impl_obj_ractor(void *objspace_ptr, VALUE obj);
157GC_IMPL_FN bool rb_gc_impl_shref_marked_p(void *objspace_ptr, VALUE obj);
158/* gc.c parked objspace_ptr in its zombie table: a terminated Ractor's objspace that
159 * rb_gc_impl_objspace_absorb later merges. Called under the VM lock, possibly from
160 * inside a global GC sweep (an unjoined Ractor's dfree disowns its objspace), so it
161 * must not allocate through the GC or expect to take a barrier. */
162GC_IMPL_FN void rb_gc_impl_objspace_zombify(void *objspace_ptr);
163GC_IMPL_FN void rb_gc_impl_objspace_absorb(void *dst_ptr, void *src_ptr);
164GC_IMPL_FN void rb_gc_impl_each_object(void *objspace_ptr, void (*func)(VALUE obj, void *data), void *data);
165// Finalizers
166GC_IMPL_FN void rb_gc_impl_make_zombie(void *objspace_ptr, VALUE obj, void (*dfree)(void *), void *data);
167GC_IMPL_FN VALUE rb_gc_impl_define_finalizer(void *objspace_ptr, VALUE obj, VALUE block);
168GC_IMPL_FN void rb_gc_impl_undefine_finalizer(void *objspace_ptr, VALUE obj);
169GC_IMPL_FN void rb_gc_impl_copy_finalizer(void *objspace_ptr, VALUE dest, VALUE obj);
170GC_IMPL_FN void rb_gc_impl_shutdown_call_finalizer(void *objspace_ptr);
171// Forking
172GC_IMPL_FN void rb_gc_impl_before_fork(void *objspace_ptr);
173GC_IMPL_FN void rb_gc_impl_after_fork(void *objspace_ptr, rb_pid_t pid);
174// Statistics
175GC_IMPL_FN void rb_gc_impl_set_measure_total_time(void *objspace_ptr, VALUE flag);
176GC_IMPL_FN bool rb_gc_impl_get_measure_total_time(void *objspace_ptr);
177GC_IMPL_FN unsigned long long rb_gc_impl_get_total_time(void *objspace_ptr);
178GC_IMPL_FN size_t rb_gc_impl_gc_count(void *objspace_ptr);
179GC_IMPL_FN VALUE rb_gc_impl_latest_gc_info(void *objspace_ptr, VALUE key);
180/* A NULL objspace requests cumulative process-wide statistics. Collectors that
181 * do not support them must raise NotImplementedError. */
182GC_IMPL_FN VALUE rb_gc_impl_stat(void *objspace_ptr, VALUE hash_or_sym);
183GC_IMPL_FN VALUE rb_gc_impl_stat_heap(void *objspace_ptr, VALUE heap_name, VALUE hash_or_sym);
184GC_IMPL_FN const char *rb_gc_impl_active_gc_name(void);
185// Miscellaneous
186GC_IMPL_FN struct rb_gc_object_metadata_entry *rb_gc_impl_object_metadata(void *objspace_ptr, VALUE obj);
187GC_IMPL_FN bool rb_gc_impl_live_object_p(void *objspace_ptr, const void *ptr);
188GC_IMPL_FN bool rb_gc_impl_garbage_object_p(void *objspace_ptr, VALUE obj);
189GC_IMPL_FN void rb_gc_impl_set_event_hook(void *objspace_ptr, const rb_event_flag_t event);
190GC_IMPL_FN void rb_gc_impl_copy_attributes(void *objspace_ptr, VALUE dest, VALUE obj);
191
192#undef GC_IMPL_FN
193
194#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