mirror of
https://github.com/ruby/ruby.git
synced 2026-01-28 13:04:22 +00:00
Add rb_gc_object_metadata API
This function replaces the internal rb_obj_gc_flags API. rb_gc_object_metadata returns an array of name and value pairs, with the last element having 0 for the name.
This commit is contained in:
parent
273e35cdcc
commit
7b6e07ea93
Notes:
git
2025-02-19 14:47:47 +00:00
@ -385,8 +385,6 @@ dump_object(VALUE obj, struct dump_config *dc)
|
||||
size_t memsize;
|
||||
struct allocation_info *ainfo = objspace_lookup_allocation_info(obj);
|
||||
rb_io_t *fptr;
|
||||
ID flags[RB_OBJ_GC_FLAGS_MAX];
|
||||
size_t n, i;
|
||||
ID mid;
|
||||
|
||||
if (SPECIAL_CONST_P(obj)) {
|
||||
@ -643,14 +641,24 @@ dump_object(VALUE obj, struct dump_config *dc)
|
||||
dump_append_lu(dc, RB_NUM2ULONG(rb_obj_id(obj)));
|
||||
}
|
||||
|
||||
if ((n = rb_obj_gc_flags(obj, flags, sizeof(flags))) > 0) {
|
||||
dump_append(dc, ", \"flags\":{");
|
||||
for (i=0; i<n; i++) {
|
||||
dump_append(dc, "\"");
|
||||
dump_append(dc, rb_id2name(flags[i]));
|
||||
dump_append(dc, "\":true");
|
||||
if (i != n-1) dump_append(dc, ", ");
|
||||
struct rb_gc_object_metadata_entry *gc_metadata = rb_gc_object_metadata(obj);
|
||||
for (int i = 0; gc_metadata[i].name != 0; i++) {
|
||||
if (i == 0) {
|
||||
dump_append(dc, ", \"flags\":{");
|
||||
}
|
||||
else {
|
||||
dump_append(dc, ", ");
|
||||
}
|
||||
|
||||
dump_append(dc, "\"");
|
||||
dump_append(dc, rb_id2name(gc_metadata[i].name));
|
||||
dump_append(dc, "\":");
|
||||
dump_append_special_const(dc, gc_metadata[i].val);
|
||||
}
|
||||
|
||||
/* If rb_gc_object_metadata had any entries, we need to close the opening
|
||||
* `"flags":{`. */
|
||||
if (gc_metadata[0].name != 0) {
|
||||
dump_append(dc, "}");
|
||||
}
|
||||
|
||||
@ -883,7 +891,4 @@ Init_objspace_dump(VALUE rb_mObjSpace)
|
||||
rb_define_module_function(rb_mObjSpace, "_dump", objspace_dump, 2);
|
||||
rb_define_module_function(rb_mObjSpace, "_dump_all", objspace_dump_all, 4);
|
||||
rb_define_module_function(rb_mObjSpace, "_dump_shapes", objspace_dump_shapes, 2);
|
||||
|
||||
/* force create static IDs */
|
||||
rb_obj_gc_flags(rb_mObjSpace, 0, 0);
|
||||
}
|
||||
|
||||
13
gc.c
13
gc.c
@ -678,7 +678,7 @@ typedef struct gc_function_map {
|
||||
VALUE (*stat_heap)(void *objspace_ptr, VALUE heap_name, VALUE hash_or_sym);
|
||||
const char *(*active_gc_name)(void);
|
||||
// Miscellaneous
|
||||
size_t (*obj_flags)(void *objspace_ptr, VALUE obj, ID* flags, size_t max);
|
||||
struct rb_gc_object_metadata_entry *(*object_metadata)(void *objspace_ptr, VALUE obj);
|
||||
bool (*pointer_to_heap_p)(void *objspace_ptr, const void *ptr);
|
||||
bool (*garbage_object_p)(void *objspace_ptr, VALUE obj);
|
||||
void (*set_event_hook)(void *objspace_ptr, const rb_event_flag_t event);
|
||||
@ -855,7 +855,7 @@ ruby_modular_gc_init(void)
|
||||
load_modular_gc_func(stat_heap);
|
||||
load_modular_gc_func(active_gc_name);
|
||||
// Miscellaneous
|
||||
load_modular_gc_func(obj_flags);
|
||||
load_modular_gc_func(object_metadata);
|
||||
load_modular_gc_func(pointer_to_heap_p);
|
||||
load_modular_gc_func(garbage_object_p);
|
||||
load_modular_gc_func(set_event_hook);
|
||||
@ -938,7 +938,7 @@ ruby_modular_gc_init(void)
|
||||
# define rb_gc_impl_stat_heap rb_gc_functions.stat_heap
|
||||
# define rb_gc_impl_active_gc_name rb_gc_functions.active_gc_name
|
||||
// Miscellaneous
|
||||
# define rb_gc_impl_obj_flags rb_gc_functions.obj_flags
|
||||
# define rb_gc_impl_object_metadata rb_gc_functions.object_metadata
|
||||
# define rb_gc_impl_pointer_to_heap_p rb_gc_functions.pointer_to_heap_p
|
||||
# define rb_gc_impl_garbage_object_p rb_gc_functions.garbage_object_p
|
||||
# define rb_gc_impl_set_event_hook rb_gc_functions.set_event_hook
|
||||
@ -2955,11 +2955,10 @@ rb_gc_active_gc_name(void)
|
||||
return gc_name;
|
||||
}
|
||||
|
||||
// TODO: rearchitect this function to work for a generic GC
|
||||
size_t
|
||||
rb_obj_gc_flags(VALUE obj, ID* flags, size_t max)
|
||||
struct rb_gc_object_metadata_entry *
|
||||
rb_gc_object_metadata(VALUE obj)
|
||||
{
|
||||
return rb_gc_impl_obj_flags(rb_gc_get_objspace(), obj, flags, max);
|
||||
return rb_gc_impl_object_metadata(rb_gc_get_objspace(), obj);
|
||||
}
|
||||
|
||||
/* GC */
|
||||
|
||||
@ -6189,33 +6189,46 @@ rb_gc_impl_writebarrier_remember(void *objspace_ptr, VALUE obj)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: rearchitect this function to work for a generic GC
|
||||
size_t
|
||||
rb_gc_impl_obj_flags(void *objspace_ptr, VALUE obj, ID* flags, size_t max)
|
||||
#define RB_GC_OBJECT_METADATA_ENTRY_COUNT 5
|
||||
static struct rb_gc_object_metadata_entry object_metadata_entries[RB_GC_OBJECT_METADATA_ENTRY_COUNT + 1];
|
||||
|
||||
struct rb_gc_object_metadata_entry *
|
||||
rb_gc_impl_object_metadata(void *objspace_ptr, VALUE obj)
|
||||
{
|
||||
rb_objspace_t *objspace = objspace_ptr;
|
||||
size_t n = 0;
|
||||
static ID ID_marked;
|
||||
static ID ID_wb_protected, ID_old, ID_marking, ID_uncollectible, ID_pinned;
|
||||
static ID ID_wb_protected, ID_old, ID_uncollectible, ID_marking, ID_marked, ID_pinned;
|
||||
|
||||
if (!ID_marked) {
|
||||
#define I(s) ID_##s = rb_intern(#s);
|
||||
I(marked);
|
||||
I(wb_protected);
|
||||
I(old);
|
||||
I(marking);
|
||||
I(uncollectible);
|
||||
I(marking);
|
||||
I(marked);
|
||||
I(pinned);
|
||||
#undef I
|
||||
}
|
||||
|
||||
if (RVALUE_WB_UNPROTECTED(objspace, obj) == 0 && n < max) flags[n++] = ID_wb_protected;
|
||||
if (RVALUE_OLD_P(objspace, obj) && n < max) flags[n++] = ID_old;
|
||||
if (RVALUE_UNCOLLECTIBLE(objspace, obj) && n < max) flags[n++] = ID_uncollectible;
|
||||
if (RVALUE_MARKING(objspace, obj) && n < max) flags[n++] = ID_marking;
|
||||
if (RVALUE_MARKED(objspace, obj) && n < max) flags[n++] = ID_marked;
|
||||
if (RVALUE_PINNED(objspace, obj) && n < max) flags[n++] = ID_pinned;
|
||||
return n;
|
||||
#define SET_ENTRY(na, v) do { \
|
||||
GC_ASSERT(n <= RB_GC_OBJECT_METADATA_ENTRY_COUNT); \
|
||||
object_metadata_entries[n].name = ID_##na; \
|
||||
object_metadata_entries[n].val = v; \
|
||||
n++; \
|
||||
} while (0)
|
||||
|
||||
if (!RVALUE_WB_UNPROTECTED(objspace, obj)) SET_ENTRY(wb_protected, Qtrue);
|
||||
if (RVALUE_OLD_P(objspace, obj)) SET_ENTRY(old, Qtrue);
|
||||
if (RVALUE_UNCOLLECTIBLE(objspace, obj)) SET_ENTRY(uncollectible, Qtrue);
|
||||
if (RVALUE_MARKING(objspace, obj)) SET_ENTRY(marking, Qtrue);
|
||||
if (RVALUE_MARKED(objspace, obj)) SET_ENTRY(marked, Qtrue);
|
||||
if (RVALUE_PINNED(objspace, obj)) SET_ENTRY(pinned, Qtrue);
|
||||
|
||||
object_metadata_entries[n].name = 0;
|
||||
object_metadata_entries[n].val = 0;
|
||||
#undef SET_ENTRY
|
||||
|
||||
return object_metadata_entries;
|
||||
}
|
||||
|
||||
void *
|
||||
|
||||
10
gc/gc_impl.h
10
gc/gc_impl.h
@ -10,6 +10,14 @@
|
||||
*/
|
||||
#include "ruby/ruby.h"
|
||||
|
||||
#ifndef RB_GC_OBJECT_METADATA_ENTRY_DEFINED
|
||||
# define RB_GC_OBJECT_METADATA_ENTRY_DEFINED
|
||||
struct rb_gc_object_metadata_entry {
|
||||
ID name;
|
||||
VALUE val;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef BUILDING_MODULAR_GC
|
||||
# define GC_IMPL_FN
|
||||
#else
|
||||
@ -108,7 +116,7 @@ GC_IMPL_FN VALUE rb_gc_impl_stat(void *objspace_ptr, VALUE hash_or_sym);
|
||||
GC_IMPL_FN VALUE rb_gc_impl_stat_heap(void *objspace_ptr, VALUE heap_name, VALUE hash_or_sym);
|
||||
GC_IMPL_FN const char *rb_gc_impl_active_gc_name(void);
|
||||
// Miscellaneous
|
||||
GC_IMPL_FN size_t rb_gc_impl_obj_flags(void *objspace_ptr, VALUE obj, ID* flags, size_t max);
|
||||
GC_IMPL_FN struct rb_gc_object_metadata_entry *rb_gc_impl_object_metadata(void *objspace_ptr, VALUE obj);
|
||||
GC_IMPL_FN bool rb_gc_impl_pointer_to_heap_p(void *objspace_ptr, const void *ptr);
|
||||
GC_IMPL_FN bool rb_gc_impl_garbage_object_p(void *objspace_ptr, VALUE obj);
|
||||
GC_IMPL_FN void rb_gc_impl_set_event_hook(void *objspace_ptr, const rb_event_flag_t event);
|
||||
|
||||
@ -127,7 +127,13 @@ struct rb_objspace; /* in vm_core.h */
|
||||
rb_wb_protected_newobj_of((ec ? ec : GET_EC()), (c), (f) & ~FL_WB_PROTECTED, s) : \
|
||||
rb_wb_unprotected_newobj_of((c), (f), s))
|
||||
|
||||
#define RB_OBJ_GC_FLAGS_MAX 6 /* used in ext/objspace */
|
||||
#ifndef RB_GC_OBJECT_METADATA_ENTRY_DEFINED
|
||||
# define RB_GC_OBJECT_METADATA_ENTRY_DEFINED
|
||||
struct rb_gc_object_metadata_entry {
|
||||
ID name;
|
||||
VALUE val;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef USE_UNALIGNED_MEMBER_ACCESS
|
||||
# define UNALIGNED_MEMBER_ACCESS(expr) (expr)
|
||||
@ -244,7 +250,7 @@ const char *rb_objspace_data_type_name(VALUE obj);
|
||||
VALUE rb_wb_protected_newobj_of(struct rb_execution_context_struct *, VALUE, VALUE, size_t);
|
||||
VALUE rb_wb_unprotected_newobj_of(VALUE, VALUE, size_t);
|
||||
size_t rb_obj_memsize_of(VALUE);
|
||||
size_t rb_obj_gc_flags(VALUE, ID[], size_t);
|
||||
struct rb_gc_object_metadata_entry *rb_gc_object_metadata(VALUE obj);
|
||||
void rb_gc_mark_values(long n, const VALUE *values);
|
||||
void rb_gc_mark_vm_stack_values(long n, const VALUE *values);
|
||||
void rb_gc_update_values(long n, VALUE *values);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user