Skip to content

Commit 0bff076

Browse files
authored
Make YJIT a GC root rather than an object (#11343)
YJIT currently uses the YJIT root object to mark objects during GC and update references during compaction. This object otherwise serves no purpose. This commit changes it YJIT to be step when marking the GC root. This saves some memory from being allocated from the system and the GC.
1 parent 868d63f commit 0bff076

File tree

5 files changed

+21
-35
lines changed

5 files changed

+21
-35
lines changed

common.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7503,6 +7503,7 @@ gc.$(OBJEXT): {$(VPATH)}vm_core.h
75037503
gc.$(OBJEXT): {$(VPATH)}vm_debug.h
75047504
gc.$(OBJEXT): {$(VPATH)}vm_opts.h
75057505
gc.$(OBJEXT): {$(VPATH)}vm_sync.h
7506+
gc.$(OBJEXT): {$(VPATH)}yjit.h
75067507
goruby.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
75077508
goruby.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
75087509
goruby.$(OBJEXT): $(CCAN_DIR)/list/list.h

gc.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@
122122
#include "vm_sync.h"
123123
#include "vm_callinfo.h"
124124
#include "ractor_core.h"
125+
#include "yjit.h"
125126

126127
#include "builtin.h"
127128
#include "shape.h"
@@ -2474,6 +2475,15 @@ rb_gc_mark_roots(void *objspace, const char **categoryp)
24742475
MARK_CHECKPOINT("global_tbl");
24752476
rb_gc_mark_global_tbl();
24762477

2478+
#if USE_YJIT
2479+
void rb_yjit_root_mark(void); // in Rust
2480+
2481+
if (rb_yjit_enabled_p) {
2482+
MARK_CHECKPOINT("YJIT");
2483+
rb_yjit_root_mark();
2484+
}
2485+
#endif
2486+
24772487
MARK_CHECKPOINT("finish");
24782488
#undef MARK_CHECKPOINT
24792489
}
@@ -3152,6 +3162,14 @@ rb_gc_update_vm_references(void *objspace)
31523162
global_symbols.ids = rb_gc_impl_location(objspace, global_symbols.ids);
31533163
global_symbols.dsymbol_fstr_hash = rb_gc_impl_location(objspace, global_symbols.dsymbol_fstr_hash);
31543164
gc_update_table_refs(objspace, global_symbols.str_sym);
3165+
3166+
#if USE_YJIT
3167+
void rb_yjit_root_update_references(void); // in Rust
3168+
3169+
if (rb_yjit_enabled_p) {
3170+
rb_yjit_root_update_references();
3171+
}
3172+
#endif
31553173
}
31563174

31573175
void

yjit.c

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,24 +1156,6 @@ struct yjit_root_struct {
11561156
bool unused; // empty structs are not legal in C99
11571157
};
11581158

1159-
static size_t
1160-
yjit_root_memsize(const void *ptr)
1161-
{
1162-
// Count off-gc-heap allocation size of the dependency table
1163-
return 0; // TODO: more accurate accounting
1164-
}
1165-
1166-
void rb_yjit_root_mark(void *ptr); // in Rust
1167-
void rb_yjit_root_update_references(void *ptr); // in Rust
1168-
1169-
// Custom type for interacting with the GC
1170-
// TODO: make this write barrier protected
1171-
static const rb_data_type_t yjit_root_type = {
1172-
"yjit_root",
1173-
{rb_yjit_root_mark, RUBY_DEFAULT_FREE, yjit_root_memsize, rb_yjit_root_update_references},
1174-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
1175-
};
1176-
11771159
// For dealing with refinements
11781160
void
11791161
rb_yjit_invalidate_all_method_lookup_assumptions(void)
@@ -1256,12 +1238,3 @@ VALUE rb_yjit_enable(rb_execution_context_t *ec, VALUE self, VALUE gen_stats, VA
12561238

12571239
// Preprocessed yjit.rb generated during build
12581240
#include "yjit.rbinc"
1259-
1260-
// Initialize the GC hooks
1261-
void
1262-
rb_yjit_init_gc_hooks(void)
1263-
{
1264-
struct yjit_root_struct *root;
1265-
VALUE yjit_root = TypedData_Make_Struct(0, struct yjit_root_struct, &yjit_root_type, root);
1266-
rb_vm_register_global_object(yjit_root);
1267-
}

yjit/src/invariants.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ pub extern "C" fn rb_yjit_constant_state_changed(id: ID) {
345345
/// Callback for marking GC objects inside [Invariants].
346346
/// See `struct yjijt_root_struct` in C.
347347
#[no_mangle]
348-
pub extern "C" fn rb_yjit_root_mark(_: *mut c_void) {
348+
pub extern "C" fn rb_yjit_root_mark() {
349349
// Call rb_gc_mark on exit location's raw_samples to
350350
// wrap frames in a GC allocated object. This needs to be called
351351
// at the same time as root mark.
@@ -374,7 +374,7 @@ pub extern "C" fn rb_yjit_root_mark(_: *mut c_void) {
374374
}
375375

376376
#[no_mangle]
377-
pub extern "C" fn rb_yjit_root_update_references(_: *mut c_void) {
377+
pub extern "C" fn rb_yjit_root_update_references() {
378378
if unsafe { INVARIANTS.is_none() } {
379379
return;
380380
}

yjit/src/yjit.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,6 @@ fn yjit_init() {
7575
let _ = std::fs::remove_file(&perf_map);
7676
println!("YJIT perf map: {perf_map}");
7777
}
78-
79-
// Initialize the GC hooks. Do this at last as some code depend on Rust initialization.
80-
extern "C" {
81-
fn rb_yjit_init_gc_hooks();
82-
}
83-
unsafe { rb_yjit_init_gc_hooks() }
8478
}
8579

8680
/// At the moment, we abort in all cases we panic.

0 commit comments

Comments
 (0)