mirror of
https://github.com/ruby/ruby.git
synced 2026-11-08 01:20:26 +08:00
Faster rb_gc_handle_weak_references
Pass objspace throughout the call chain. For a script with 100k callcaches, major GC time improved for bothh single-ractor and multi-ractor. | Configuration | Baseline | Patched | Δ | |---|---|---|---| | single-ractor | 14.04 ms/major GC | 13.60 ms/major GC | **-3.1%** | | multi-ractor | 18.55 ms/major GC | 17.25 ms/major GC | **-7.0%** |
This commit is contained in:
parent
eb1a765b9a
commit
b62abdae8b
Notes:
git
2026-10-28 22:46:35 +00:00
12
cont.c
12
cont.c
@ -1506,14 +1506,14 @@ cont_save_machine_stack(rb_thread_t *th, rb_context_t *cont)
|
||||
}
|
||||
|
||||
static void
|
||||
cont_handle_weak_references(void *ptr)
|
||||
cont_handle_weak_references(void *ptr, void *objspace)
|
||||
{
|
||||
rb_context_t *cont = ptr;
|
||||
|
||||
if (!cont) return;
|
||||
|
||||
if (!rb_gc_handle_weak_references_alive_p(cont->saved_ec.gen_fields_cache.obj) ||
|
||||
!rb_gc_handle_weak_references_alive_p(cont->saved_ec.gen_fields_cache.fields_obj)) {
|
||||
if (!rb_gc_handle_weak_references_alive_p(objspace, cont->saved_ec.gen_fields_cache.obj) ||
|
||||
!rb_gc_handle_weak_references_alive_p(objspace, cont->saved_ec.gen_fields_cache.fields_obj)) {
|
||||
cont->saved_ec.gen_fields_cache.obj = Qundef;
|
||||
cont->saved_ec.gen_fields_cache.fields_obj = Qundef;
|
||||
}
|
||||
@ -2267,14 +2267,14 @@ rb_cont_call(int argc, VALUE *argv, VALUE contval)
|
||||
*/
|
||||
|
||||
static void
|
||||
fiber_handle_weak_references(void *ptr)
|
||||
fiber_handle_weak_references(void *ptr, void *objspace)
|
||||
{
|
||||
rb_fiber_t *fiber = ptr;
|
||||
|
||||
if (!fiber) return;
|
||||
|
||||
if (!rb_gc_handle_weak_references_alive_p(fiber->cont.saved_ec.gen_fields_cache.obj) ||
|
||||
!rb_gc_handle_weak_references_alive_p(fiber->cont.saved_ec.gen_fields_cache.fields_obj)) {
|
||||
if (!rb_gc_handle_weak_references_alive_p(objspace, fiber->cont.saved_ec.gen_fields_cache.obj) ||
|
||||
!rb_gc_handle_weak_references_alive_p(objspace, fiber->cont.saved_ec.gen_fields_cache.fields_obj)) {
|
||||
fiber->cont.saved_ec.gen_fields_cache.obj = Qundef;
|
||||
fiber->cont.saved_ec.gen_fields_cache.fields_obj = Qundef;
|
||||
}
|
||||
|
||||
@ -160,13 +160,19 @@ allocation_info_tracer_memsize(const void *ptr)
|
||||
return size;
|
||||
}
|
||||
|
||||
struct allocation_info_weak_reference_arg {
|
||||
struct traceobj_arg *arg;
|
||||
void *objspace;
|
||||
};
|
||||
|
||||
static int
|
||||
allocation_info_tracer_weak_reference_i(st_data_t key, st_data_t value, st_data_t data)
|
||||
{
|
||||
struct traceobj_arg *arg = (struct traceobj_arg *)data;
|
||||
struct allocation_info_weak_reference_arg *wrarg = (struct allocation_info_weak_reference_arg *)data;
|
||||
struct traceobj_arg *arg = wrarg->arg;
|
||||
struct allocation_info *info = (struct allocation_info *)value;
|
||||
|
||||
if (rb_gc_handle_weak_references_alive_p((VALUE)key)) {
|
||||
if (rb_gc_handle_weak_references_alive_p(wrarg->objspace, (VALUE)key)) {
|
||||
return ST_CONTINUE;
|
||||
}
|
||||
|
||||
@ -184,11 +190,12 @@ allocation_info_tracer_weak_reference_i(st_data_t key, st_data_t value, st_data_
|
||||
}
|
||||
|
||||
static void
|
||||
allocation_info_tracer_weak_reference(void *ptr)
|
||||
allocation_info_tracer_weak_reference(void *ptr, void *objspace)
|
||||
{
|
||||
struct traceobj_arg *arg = (struct traceobj_arg *)ptr;
|
||||
struct allocation_info_weak_reference_arg wrarg = {arg, objspace};
|
||||
|
||||
st_foreach(arg->object_table, allocation_info_tracer_weak_reference_i, (st_data_t)arg);
|
||||
st_foreach(arg->object_table, allocation_info_tracer_weak_reference_i, (st_data_t)&wrarg);
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
22
gc.c
22
gc.c
@ -1501,16 +1501,22 @@ rb_gc_declare_weak_references(VALUE obj)
|
||||
rb_gc_impl_declare_weak_references(rb_gc_get_objspace(), obj);
|
||||
}
|
||||
|
||||
bool
|
||||
rb_gc_handle_weak_references_alive_p(VALUE obj)
|
||||
static inline bool
|
||||
gc_weak_reference_alive_p(void *objspace, VALUE obj)
|
||||
{
|
||||
if (SPECIAL_CONST_P(obj)) return true;
|
||||
|
||||
return rb_gc_impl_handle_weak_references_alive_p(rb_gc_get_objspace(), obj);
|
||||
return rb_gc_impl_handle_weak_references_alive_p(objspace, obj);
|
||||
}
|
||||
|
||||
bool
|
||||
rb_gc_handle_weak_references_alive_p(void *objspace, VALUE obj)
|
||||
{
|
||||
return gc_weak_reference_alive_p(objspace, obj);
|
||||
}
|
||||
|
||||
void
|
||||
rb_gc_handle_weak_references(VALUE obj)
|
||||
rb_gc_handle_weak_references(void *objspace, VALUE obj)
|
||||
{
|
||||
switch (BUILTIN_TYPE(obj)) {
|
||||
case T_DATA:
|
||||
@ -1518,7 +1524,7 @@ rb_gc_handle_weak_references(VALUE obj)
|
||||
const rb_data_type_t *type = RTYPEDDATA_TYPE(obj);
|
||||
|
||||
if (type->function.handle_weak_references) {
|
||||
(type->function.handle_weak_references)(RTYPEDDATA_GET_DATA(obj));
|
||||
(type->function.handle_weak_references)(RTYPEDDATA_GET_DATA(obj), objspace);
|
||||
}
|
||||
else {
|
||||
rb_bug(
|
||||
@ -1534,8 +1540,8 @@ rb_gc_handle_weak_references(VALUE obj)
|
||||
case imemo_callcache: {
|
||||
struct rb_callcache *cc = (struct rb_callcache *)obj;
|
||||
if (cc->klass != Qundef &&
|
||||
(!rb_gc_handle_weak_references_alive_p(cc->klass) ||
|
||||
!rb_gc_handle_weak_references_alive_p((VALUE)cc->cme_))) {
|
||||
(!gc_weak_reference_alive_p(objspace, cc->klass) ||
|
||||
!gc_weak_reference_alive_p(objspace, (VALUE)cc->cme_))) {
|
||||
vm_cc_invalidate(cc);
|
||||
}
|
||||
break;
|
||||
@ -1544,7 +1550,7 @@ rb_gc_handle_weak_references(VALUE obj)
|
||||
struct rb_subclasses *subs = (struct rb_subclasses *)obj;
|
||||
VALUE *entries = rb_imemo_subclasses_entries(obj);
|
||||
for (uint32_t i = 0; i < subs->count; i++) {
|
||||
if (entries[i] && !rb_gc_handle_weak_references_alive_p(entries[i])) {
|
||||
if (entries[i] && !gc_weak_reference_alive_p(objspace, entries[i])) {
|
||||
entries[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7665,7 +7665,7 @@ gc_update_weak_references(rb_objspace_t *objspace)
|
||||
VALUE *obj_ptr;
|
||||
rb_darray_foreach(objspace->weak_references, i, obj_ptr) {
|
||||
gc_mark_set_parent(objspace, *obj_ptr);
|
||||
rb_gc_handle_weak_references(*obj_ptr);
|
||||
rb_gc_handle_weak_references(objspace, *obj_ptr);
|
||||
gc_mark_set_parent_invalid(objspace);
|
||||
}
|
||||
|
||||
|
||||
2
gc/gc.h
2
gc/gc.h
@ -122,7 +122,7 @@ MODULAR_GC_FN void rb_gc_before_updating_jit_code(void);
|
||||
MODULAR_GC_FN void rb_gc_after_updating_jit_code(void);
|
||||
MODULAR_GC_FN bool rb_gc_obj_shareable_p(VALUE);
|
||||
MODULAR_GC_FN void rb_gc_rp(VALUE);
|
||||
MODULAR_GC_FN void rb_gc_handle_weak_references(VALUE obj);
|
||||
MODULAR_GC_FN void rb_gc_handle_weak_references(void *objspace, VALUE obj);
|
||||
MODULAR_GC_FN bool rb_gc_obj_needs_cleanup_p(VALUE obj);
|
||||
|
||||
/* True when a dead T_DATA of this type cannot have its dfree run during a parallel
|
||||
|
||||
@ -363,7 +363,7 @@ rb_mmtk_handle_weak_references(MMTk_ObjectReference mmtk_object, bool moving)
|
||||
|
||||
marking_parent_object = object;
|
||||
|
||||
rb_gc_handle_weak_references(object);
|
||||
rb_gc_handle_weak_references(rb_gc_get_objspace(), object);
|
||||
|
||||
if (moving) {
|
||||
rb_gc_update_object_references(rb_gc_get_objspace(), object);
|
||||
|
||||
@ -981,7 +981,7 @@ wbcheck_process_weak_references(rb_wbcheck_objspace_t *objspace)
|
||||
|
||||
for (size_t i = 0; i < objspace->weak_references->count; i++) {
|
||||
VALUE obj = objspace->weak_references->items[i];
|
||||
rb_gc_handle_weak_references(obj);
|
||||
rb_gc_handle_weak_references(objspace, obj);
|
||||
}
|
||||
|
||||
objspace->weak_references->count = 0;
|
||||
|
||||
@ -295,7 +295,7 @@ struct rb_data_type_struct {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void (*handle_weak_references)(void *);
|
||||
void (*handle_weak_references)(void *, void *objspace);
|
||||
|
||||
/**
|
||||
* This field is reserved for future extension. For now, it must be
|
||||
|
||||
@ -306,7 +306,7 @@ int rb_objspace_garbage_object_p(VALUE obj);
|
||||
int rb_objspace_foreign_object_p(VALUE obj);
|
||||
int rb_objspace_live_object_p(VALUE obj);
|
||||
void rb_gc_declare_weak_references(VALUE obj);
|
||||
bool rb_gc_handle_weak_references_alive_p(VALUE obj);
|
||||
bool rb_gc_handle_weak_references_alive_p(void *objspace, VALUE obj);
|
||||
|
||||
void rb_objspace_each_objects(
|
||||
int (*callback)(void *start, void *end, size_t stride, void *data),
|
||||
|
||||
@ -781,12 +781,12 @@ cc_refinement_set_compact(void *ptr)
|
||||
}
|
||||
|
||||
static void
|
||||
cc_refinement_set_handle_weak_references(void *ptr)
|
||||
cc_refinement_set_handle_weak_references(void *ptr, void *objspace)
|
||||
{
|
||||
struct cc_refinement_entries *e = ptr;
|
||||
size_t write = 0;
|
||||
for (size_t read = 0; read < e->len; read++) {
|
||||
if (rb_gc_handle_weak_references_alive_p(e->entries[read])) {
|
||||
if (rb_gc_handle_weak_references_alive_p(objspace, e->entries[read])) {
|
||||
e->entries[write++] = e->entries[read];
|
||||
}
|
||||
}
|
||||
|
||||
16
weakmap.c
16
weakmap.c
@ -113,8 +113,10 @@ wmap_compact(void *ptr)
|
||||
static int
|
||||
rb_wmap_handle_weak_references_i(st_data_t key, st_data_t val, st_data_t arg)
|
||||
{
|
||||
if (rb_gc_handle_weak_references_alive_p(key) &&
|
||||
rb_gc_handle_weak_references_alive_p(val)) {
|
||||
void *objspace = (void *)arg;
|
||||
|
||||
if (rb_gc_handle_weak_references_alive_p(objspace, key) &&
|
||||
rb_gc_handle_weak_references_alive_p(objspace, val)) {
|
||||
return ST_CONTINUE;
|
||||
}
|
||||
else {
|
||||
@ -123,11 +125,11 @@ rb_wmap_handle_weak_references_i(st_data_t key, st_data_t val, st_data_t arg)
|
||||
}
|
||||
|
||||
static void
|
||||
wmap_handle_weak_references(void *ptr)
|
||||
wmap_handle_weak_references(void *ptr, void *objspace)
|
||||
{
|
||||
struct weakmap *w = ptr;
|
||||
|
||||
st_foreach(w->table, rb_wmap_handle_weak_references_i, (st_data_t)0);
|
||||
st_foreach(w->table, rb_wmap_handle_weak_references_i, (st_data_t)objspace);
|
||||
}
|
||||
|
||||
static const rb_data_type_t rb_weakmap_type = {
|
||||
@ -616,7 +618,7 @@ wkmap_compact(void *ptr)
|
||||
static int
|
||||
rb_wkmap_handle_weak_references_i(st_data_t key, st_data_t val, st_data_t arg)
|
||||
{
|
||||
if (rb_gc_handle_weak_references_alive_p(key)) {
|
||||
if (rb_gc_handle_weak_references_alive_p((void *)arg, key)) {
|
||||
return ST_CONTINUE;
|
||||
}
|
||||
else {
|
||||
@ -625,11 +627,11 @@ rb_wkmap_handle_weak_references_i(st_data_t key, st_data_t val, st_data_t arg)
|
||||
}
|
||||
|
||||
static void
|
||||
wkmap_handle_weak_references(void *ptr)
|
||||
wkmap_handle_weak_references(void *ptr, void *objspace)
|
||||
{
|
||||
struct weakkeymap *w = ptr;
|
||||
|
||||
st_foreach(w->table, rb_wkmap_handle_weak_references_i, (st_data_t)0);
|
||||
st_foreach(w->table, rb_wkmap_handle_weak_references_i, (st_data_t)objspace);
|
||||
}
|
||||
|
||||
static const rb_data_type_t rb_weakkeymap_type = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user