зеркало из https://github.com/github/ruby.git
Mark iseq structs with rb_gc_mark_movable
Using rb_gc_mark_movable and a reference update function, we can make instruction sequences movable in memory, and avoid pinning compiled iseqs. ``` require "objspace" iseqs = [] GC.disable 50_000.times do iseqs << RubyVM::InstructionSequence.compile("") end GC.enable GC.compact p ObjectSpace.dump_all(output: :string).lines.grep(/"pinned":true/).count ``` Co-authored-by: Peter Zhu <peter@peterzhu.ca>
This commit is contained in:
Родитель
552647175e
Коммит
a31ca3500d
30
iseq.c
30
iseq.c
|
@ -1386,18 +1386,30 @@ rb_iseq_remove_coverage_all(void)
|
|||
static void
|
||||
iseqw_mark(void *ptr)
|
||||
{
|
||||
rb_gc_mark((VALUE)ptr);
|
||||
rb_gc_mark_movable(*(VALUE *)ptr);
|
||||
}
|
||||
|
||||
static size_t
|
||||
iseqw_memsize(const void *ptr)
|
||||
{
|
||||
return rb_iseq_memsize((const rb_iseq_t *)ptr);
|
||||
return rb_iseq_memsize(*(const rb_iseq_t **)ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
iseqw_ref_update(void *ptr)
|
||||
{
|
||||
VALUE *vptr = ptr;
|
||||
*vptr = rb_gc_location(*vptr);
|
||||
}
|
||||
|
||||
static const rb_data_type_t iseqw_data_type = {
|
||||
"T_IMEMO/iseq",
|
||||
{iseqw_mark, NULL, iseqw_memsize,},
|
||||
{
|
||||
iseqw_mark,
|
||||
RUBY_TYPED_DEFAULT_FREE,
|
||||
iseqw_memsize,
|
||||
iseqw_ref_update,
|
||||
},
|
||||
0, 0, RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED
|
||||
};
|
||||
|
||||
|
@ -1408,11 +1420,9 @@ iseqw_new(const rb_iseq_t *iseq)
|
|||
return iseq->wrapper;
|
||||
}
|
||||
else {
|
||||
union { const rb_iseq_t *in; void *out; } deconst;
|
||||
VALUE obj;
|
||||
deconst.in = iseq;
|
||||
obj = TypedData_Wrap_Struct(rb_cISeq, &iseqw_data_type, deconst.out);
|
||||
RB_OBJ_WRITTEN(obj, Qundef, iseq);
|
||||
rb_iseq_t **ptr;
|
||||
VALUE obj = TypedData_Make_Struct(rb_cISeq, rb_iseq_t *, &iseqw_data_type, ptr);
|
||||
RB_OBJ_WRITE(obj, ptr, iseq);
|
||||
|
||||
/* cache a wrapper object */
|
||||
RB_OBJ_WRITE((VALUE)iseq, &iseq->wrapper, obj);
|
||||
|
@ -1736,7 +1746,9 @@ iseqw_s_compile_option_get(VALUE self)
|
|||
static const rb_iseq_t *
|
||||
iseqw_check(VALUE iseqw)
|
||||
{
|
||||
rb_iseq_t *iseq = DATA_PTR(iseqw);
|
||||
rb_iseq_t **iseq_ptr;
|
||||
TypedData_Get_Struct(iseqw, rb_iseq_t *, &iseqw_data_type, iseq_ptr);
|
||||
rb_iseq_t *iseq = *iseq_ptr;
|
||||
|
||||
if (!ISEQ_BODY(iseq)) {
|
||||
rb_ibf_load_iseq_complete(iseq);
|
||||
|
|
Загрузка…
Ссылка в новой задаче