diff options
-rw-r--r-- | debug.c | 2 | ||||
-rw-r--r-- | gc.c | 120 | ||||
-rw-r--r-- | include/ruby/internal/abi.h | 2 | ||||
-rw-r--r-- | include/ruby/internal/core/robject.h | 45 | ||||
-rw-r--r-- | mjit_compile.c | 4 | ||||
-rw-r--r-- | object.c | 33 | ||||
-rw-r--r-- | test/ruby/test_gc_compact.rb | 24 | ||||
-rw-r--r-- | test/ruby/test_mjit.rb | 5 | ||||
-rw-r--r-- | tool/ruby_vm/views/_mjit_compile_ivar.erb | 9 | ||||
-rw-r--r-- | variable.c | 8 | ||||
-rw-r--r-- | yjit/bindgen/src/main.rs | 6 | ||||
-rw-r--r-- | yjit/src/codegen.rs | 21 | ||||
-rw-r--r-- | yjit/src/cruby.rs | 4 | ||||
-rw-r--r-- | yjit/src/cruby_bindings.inc.rs | 7 |
14 files changed, 216 insertions, 74 deletions
@@ -53,7 +53,9 @@ const union { rb_econv_result_t econv_result; enum ruby_preserved_encindex encoding_index; enum ruby_robject_flags robject_flags; +#if !USE_RVARGC enum ruby_robject_consts robject_consts; +#endif enum ruby_rmodule_flags rmodule_flags; enum ruby_rstring_flags rstring_flags; #if !USE_RVARGC @@ -2865,18 +2865,65 @@ rb_newobj(void) return newobj_of(0, T_NONE, 0, 0, 0, FALSE, sizeof(RVALUE)); } -VALUE -rb_newobj_of(VALUE klass, VALUE flags) +static size_t +rb_obj_embedded_size(uint32_t numiv) { - if ((flags & RUBY_T_MASK) == T_OBJECT) { - st_table *index_tbl = RCLASS_IV_INDEX_TBL(klass); + return offsetof(struct RObject, as.ary) + (sizeof(VALUE) * numiv); +} + +static VALUE +rb_class_instance_allocate_internal(VALUE klass, VALUE flags, bool wb_protected) +{ + GC_ASSERT((flags & RUBY_T_MASK) == T_OBJECT); + GC_ASSERT(flags & ROBJECT_EMBED); + + st_table *index_tbl = RCLASS_IV_INDEX_TBL(klass); + uint32_t index_tbl_num_entries = index_tbl == NULL ? 0 : (uint32_t)index_tbl->num_entries; + + size_t size; + bool embed = true; +#if USE_RVARGC + size = rb_obj_embedded_size(index_tbl_num_entries); + if (!rb_gc_size_allocatable_p(size)) { + size = sizeof(struct RObject); + embed = false; + } +#else + size = sizeof(struct RObject); + if (index_tbl_num_entries > ROBJECT_EMBED_LEN_MAX) { + embed = false; + } +#endif + +#if USE_RVARGC + VALUE obj = newobj_of(klass, flags, 0, 0, 0, wb_protected, size); +#else + VALUE obj = newobj_of(klass, flags, Qundef, Qundef, Qundef, wb_protected, size); +#endif - VALUE obj = newobj_of(klass, (flags | ROBJECT_EMBED) & ~FL_WB_PROTECTED , Qundef, Qundef, Qundef, flags & FL_WB_PROTECTED, sizeof(RVALUE)); + if (embed) { +#if USE_RVARGC + uint32_t capa = (uint32_t)((rb_gc_obj_slot_size(obj) - offsetof(struct RObject, as.ary)) / sizeof(VALUE)); + GC_ASSERT(capa >= index_tbl_num_entries); - if (index_tbl && index_tbl->num_entries > ROBJECT_EMBED_LEN_MAX) { - rb_init_iv_list(obj); + ROBJECT(obj)->numiv = capa; + for (size_t i = 0; i < capa; i++) { + ROBJECT(obj)->as.ary[i] = Qundef; } - return obj; +#endif + } + else { + rb_init_iv_list(obj); + } + + return obj; +} + +VALUE +rb_newobj_of(VALUE klass, VALUE flags) +{ + if ((flags & RUBY_T_MASK) == T_OBJECT) { + return rb_class_instance_allocate_internal(klass, (flags | ROBJECT_EMBED) & ~FL_WB_PROTECTED, flags & FL_WB_PROTECTED); } else { return newobj_of(klass, flags & ~FL_WB_PROTECTED, 0, 0, 0, flags & FL_WB_PROTECTED, sizeof(RVALUE)); @@ -2989,17 +3036,7 @@ rb_imemo_new_debug(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0, VALUE rb_class_allocate_instance(VALUE klass) { - st_table *index_tbl = RCLASS_IV_INDEX_TBL(klass); - - VALUE flags = T_OBJECT | ROBJECT_EMBED; - - VALUE obj = newobj_of(klass, flags, Qundef, Qundef, Qundef, RGENGC_WB_PROTECTED_OBJECT, sizeof(RVALUE)); - - if (index_tbl && index_tbl->num_entries > ROBJECT_EMBED_LEN_MAX) { - rb_init_iv_list(obj); - } - - return obj; + return rb_class_instance_allocate_internal(klass, T_OBJECT | ROBJECT_EMBED, RGENGC_WB_PROTECTED_OBJECT); } static inline void @@ -8322,17 +8359,23 @@ gc_compact_destination_pool(rb_objspace_t *objspace, rb_size_pool_t *src_pool, V size_t obj_size; switch (BUILTIN_TYPE(src)) { - case T_STRING: - obj_size = rb_str_size_as_embedded(src); - break; case T_ARRAY: obj_size = rb_ary_size_as_embedded(src); break; + + case T_OBJECT: + obj_size = rb_obj_embedded_size(ROBJECT_NUMIV(src)); + break; + + case T_STRING: + obj_size = rb_str_size_as_embedded(src); + break; + default: return src_pool; } - if (rb_gc_size_allocatable_p(obj_size)) { + if (rb_gc_size_allocatable_p(obj_size)){ return &size_pools[size_pool_idx_for_size(obj_size)]; } else { @@ -9896,12 +9939,37 @@ gc_ref_update_array(rb_objspace_t * objspace, VALUE v) } static void -gc_ref_update_object(rb_objspace_t * objspace, VALUE v) +gc_ref_update_object(rb_objspace_t *objspace, VALUE v) { VALUE *ptr = ROBJECT_IVPTR(v); + uint32_t numiv = ROBJECT_NUMIV(v); + +#if USE_RVARGC + size_t slot_size = rb_gc_obj_slot_size(v); + size_t embed_size = rb_obj_embedded_size(numiv); + if (slot_size >= embed_size && !RB_FL_TEST_RAW(v, ROBJECT_EMBED)) { + // Object can be re-embedded + memcpy(ROBJECT(v)->as.ary, ptr, sizeof(VALUE) * numiv); + RB_FL_SET_RAW(v, ROBJECT_EMBED); + if (ROBJ_TRANSIENT_P(v)) { + ROBJ_TRANSIENT_UNSET(v); + } + else { + xfree(ptr); + } + ptr = ROBJECT(v)->as.ary; + + uint32_t capa = (uint32_t)((slot_size - offsetof(struct RObject, as.ary)) / sizeof(VALUE)); + ROBJECT(v)->numiv = capa; + + // Fill end with Qundef + for (uint32_t i = numiv; i < capa; i++) { + ptr[i] = Qundef; + } + } +#endif - uint32_t i, len = ROBJECT_NUMIV(v); - for (i = 0; i < len; i++) { + for (uint32_t i = 0; i < numiv; i++) { UPDATE_IF_MOVED(objspace, ptr[i]); } } diff --git a/include/ruby/internal/abi.h b/include/ruby/internal/abi.h index ed779f3558..e42a1777ff 100644 --- a/include/ruby/internal/abi.h +++ b/include/ruby/internal/abi.h @@ -22,7 +22,7 @@ * In released versions of Ruby, this number should not be changed since teeny * versions of Ruby should guarantee ABI compatibility. */ -#define RUBY_ABI_VERSION 1 +#define RUBY_ABI_VERSION 2 /* Windows does not support weak symbols so ruby_abi_version will not exist * in the shared library. */ diff --git a/include/ruby/internal/core/robject.h b/include/ruby/internal/core/robject.h index f2028063a6..7823061d8f 100644 --- a/include/ruby/internal/core/robject.h +++ b/include/ruby/internal/core/robject.h @@ -75,6 +75,7 @@ enum ruby_robject_flags { ROBJECT_EMBED = RUBY_FL_USER1 }; +#if !USE_RVARGC /** * This is an enum because GDB wants it (rather than a macro). People need not * bother. @@ -83,6 +84,7 @@ enum ruby_robject_consts { /** Max possible number of instance variables that can be embedded. */ ROBJECT_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(VALUE) }; +#endif struct st_table; @@ -95,6 +97,14 @@ struct RObject { /** Basic part, including flags and class. */ struct RBasic basic; +#if USE_RVARGC + /** + * Number of instance variables. This is per object; objects might + * differ in this field even if they have the identical classes. + */ + uint32_t numiv; +#endif + /** Object's specific fields. */ union { @@ -103,12 +113,13 @@ struct RObject { * this pattern. */ struct { - +#if !USE_RVARGC /** * Number of instance variables. This is per object; objects might * differ in this field even if they have the identical classes. */ uint32_t numiv; +#endif /** Pointer to a C array that holds instance variables. */ VALUE *ivptr; @@ -124,14 +135,38 @@ struct RObject { struct st_table *iv_index_tbl; } heap; - /** - * Embedded instance variables. When an object is small enough, it +#if USE_RVARGC + /* Embedded instance variables. When an object is small enough, it * uses this area to store the instance variables. + * + * This is a length 1 array because: + * 1. GCC has a bug that does not optimize C flexible array members + * (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102452) + * 2. Zero length arrays are not supported by all compilers */ + VALUE ary[1]; +#else + /** + * Embedded instance variables. When an object is small enough, it + * uses this area to store the instance variables. + */ VALUE ary[ROBJECT_EMBED_LEN_MAX]; +#endif } as; }; +/* Offsets for YJIT */ +#ifndef __cplusplus +# if USE_RVARGC +static const int32_t ROBJECT_OFFSET_NUMIV = offsetof(struct RObject, numiv); +# else +static const int32_t ROBJECT_OFFSET_NUMIV = offsetof(struct RObject, as.heap.numiv); +# endif +static const int32_t ROBJECT_OFFSET_AS_HEAP_IVPTR = offsetof(struct RObject, as.heap.ivptr); +static const int32_t ROBJECT_OFFSET_AS_HEAP_IV_INDEX_TBL = offsetof(struct RObject, as.heap.iv_index_tbl); +static const int32_t ROBJECT_OFFSET_AS_ARY = offsetof(struct RObject, as.ary); +#endif + RBIMPL_ATTR_PURE_UNLESS_DEBUG() RBIMPL_ATTR_ARTIFICIAL() /** @@ -146,12 +181,16 @@ ROBJECT_NUMIV(VALUE obj) { RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT); +#if USE_RVARGC + return ROBJECT(obj)->numiv; +#else if (RB_FL_ANY_RAW(obj, ROBJECT_EMBED)) { return ROBJECT_EMBED_LEN_MAX; } else { return ROBJECT(obj)->as.heap.numiv; } +#endif } RBIMPL_ATTR_PURE_UNLESS_DEBUG() diff --git a/mjit_compile.c b/mjit_compile.c index 66deaa9a65..2c7996c258 100644 --- a/mjit_compile.c +++ b/mjit_compile.c @@ -353,12 +353,16 @@ mjit_compile_body(FILE *f, const rb_iseq_t *iseq, struct compile_status *status) // Generate merged ivar guards first if needed if (!status->compile_info->disable_ivar_cache && status->merge_ivar_guards_p) { fprintf(f, " if (UNLIKELY(!(RB_TYPE_P(GET_SELF(), T_OBJECT) && (rb_serial_t)%"PRI_SERIALT_PREFIX"u == RCLASS_SERIAL(RBASIC(GET_SELF())->klass) &&", status->ivar_serial); +#if USE_RVARGC + fprintf(f, "%"PRIuSIZE" < ROBJECT_NUMIV(GET_SELF())", status->max_ivar_index); // index < ROBJECT_NUMIV(obj) +#else if (status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX) { fprintf(f, "%"PRIuSIZE" < ROBJECT_NUMIV(GET_SELF())", status->max_ivar_index); // index < ROBJECT_NUMIV(obj) && !RB_FL_ANY_RAW(obj, ROBJECT_EMBED) } else { fprintf(f, "ROBJECT_EMBED_LEN_MAX == ROBJECT_NUMIV(GET_SELF())"); // index < ROBJECT_NUMIV(obj) && RB_FL_ANY_RAW(obj, ROBJECT_EMBED) } +#endif fprintf(f, "))) {\n"); fprintf(f, " goto ivar_cancel;\n"); fprintf(f, " }\n"); @@ -267,34 +267,13 @@ rb_obj_singleton_class(VALUE obj) MJIT_FUNC_EXPORTED void rb_obj_copy_ivar(VALUE dest, VALUE obj) { - VALUE *dst_buf = 0; - VALUE *src_buf = 0; - uint32_t len = ROBJECT_EMBED_LEN_MAX; + VALUE *dest_buf = ROBJECT_IVPTR(dest); + VALUE *src_buf = ROBJECT_IVPTR(obj); + uint32_t dest_len = ROBJECT_NUMIV(dest); + uint32_t src_len = ROBJECT_NUMIV(obj); + uint32_t len = dest_len < src_len ? dest_len : src_len; - if (RBASIC(obj)->flags & ROBJECT_EMBED) { - src_buf = ROBJECT(obj)->as.ary; - - // embedded -> embedded - if (RBASIC(dest)->flags & ROBJECT_EMBED) { - dst_buf = ROBJECT(dest)->as.ary; - } - // embedded -> extended - else { - dst_buf = ROBJECT(dest)->as.heap.ivptr; - } - } - // extended -> extended - else { - RUBY_ASSERT(!(RBASIC(dest)->flags & ROBJECT_EMBED)); - uint32_t src_len = ROBJECT(obj)->as.heap.numiv; - uint32_t dst_len = ROBJECT(dest)->as.heap.numiv; - - len = src_len < dst_len ? src_len : dst_len; - dst_buf = ROBJECT(dest)->as.heap.ivptr; - src_buf = ROBJECT(obj)->as.heap.ivptr; - } - - MEMCPY(dst_buf, src_buf, VALUE, len); + MEMCPY(dest_buf, src_buf, VALUE, len); } static void diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb index 7d72f3573b..92a2be1174 100644 --- a/test/ruby/test_gc_compact.rb +++ b/test/ruby/test_gc_compact.rb @@ -249,6 +249,30 @@ class TestGCCompact < Test::Unit::TestCase end; end + def test_moving_objects_between_size_pools + assert_separately([], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV) + begin; + class Foo + def add_ivars + 10.times do |i| + instance_variable_set("@foo" + i.to_s, 0) + end + end + end + + OBJ_COUNT = 500 + + GC.verify_compaction_references(expand_heap: true, toward: :empty) + + ary = OBJ_COUNT.times.map { Foo.new } + ary.each(&:add_ivars) + + stats = GC.verify_compaction_references(expand_heap: true, toward: :empty) + + assert_operator(stats[:moved_up][:T_OBJECT], :>=, OBJ_COUNT) + end; + end + def test_moving_strings_up_size_pools omit if !GC.using_rvargc? assert_separately([], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV) diff --git a/test/ruby/test_mjit.rb b/test/ruby/test_mjit.rb index fd7a4e270a..02be88aa32 100644 --- a/test/ruby/test_mjit.rb +++ b/test/ruby/test_mjit.rb @@ -969,23 +969,24 @@ class TestMJIT < Test::Unit::TestCase end def test_heap_promotion_of_ivar_in_the_middle_of_jit + omit if GC.using_rvargc? + assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "true\ntrue\n", success_count: 2, min_calls: 2) begin; class A def initialize @iv0 = nil @iv1 = [] - @iv2 = nil end def test(add) @iv0.nil? - @iv2.nil? add_ivar if add @iv1.empty? end def add_ivar + @iv2 = nil @iv3 = nil end end diff --git a/tool/ruby_vm/views/_mjit_compile_ivar.erb b/tool/ruby_vm/views/_mjit_compile_ivar.erb index 5105584ba3..1425b3b055 100644 --- a/tool/ruby_vm/views/_mjit_compile_ivar.erb +++ b/tool/ruby_vm/views/_mjit_compile_ivar.erb @@ -30,15 +30,24 @@ fprintf(f, " VM_ASSERT((rb_serial_t)%"PRI_SERIALT_PREFIX"u == RCLASS_SERIAL(RBASIC(obj)->klass));\n", ic_copy->entry->class_serial); fprintf(f, " VM_ASSERT(index < ROBJECT_NUMIV(obj));\n"); % if insn.name == 'setinstancevariable' +#if USE_RVARGC + fprintf(f, " if (LIKELY(!RB_OBJ_FROZEN_RAW(obj) && index < ROBJECT_NUMIV(obj))) {\n"); + fprintf(f, " RB_OBJ_WRITE(obj, &ROBJECT_IVPTR(obj)[index], stack[%d]);\n", b->stack_size - 1); +#else fprintf(f, " if (LIKELY(!RB_OBJ_FROZEN_RAW(obj) && %s)) {\n", status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX ? "true" : "RB_FL_ANY_RAW(obj, ROBJECT_EMBED)"); fprintf(f, " RB_OBJ_WRITE(obj, &ROBJECT(obj)->as.%s, stack[%d]);\n", status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX ? "heap.ivptr[index]" : "ary[index]", b->stack_size - 1); +#endif fprintf(f, " }\n"); % else fprintf(f, " VALUE val;\n"); +#if USE_RVARGC + fprintf(f, " if (LIKELY(index < ROBJECT_NUMIV(obj) && (val = ROBJECT_IVPTR(obj)[index]) != Qundef)) {\n"); +#else fprintf(f, " if (LIKELY(%s && (val = ROBJECT(obj)->as.%s) != Qundef)) {\n", status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX ? "true" : "RB_FL_ANY_RAW(obj, ROBJECT_EMBED)", status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX ? "heap.ivptr[index]" : "ary[index]"); +#endif fprintf(f, " stack[%d] = val;\n", b->stack_size); fprintf(f, " }\n"); %end diff --git a/variable.c b/variable.c index def997d201..81258cb47b 100644 --- a/variable.c +++ b/variable.c @@ -1467,6 +1467,8 @@ void rb_obj_transient_heap_evacuate(VALUE obj, int promote) { if (ROBJ_TRANSIENT_P(obj)) { + assert(!RB_FL_TEST_RAW(obj, ROBJECT_EMBED)); + uint32_t len = ROBJECT_NUMIV(obj); const VALUE *old_ptr = ROBJECT_IVPTR(obj); VALUE *new_ptr; @@ -1493,7 +1495,7 @@ init_iv_list(VALUE obj, uint32_t len, uint32_t newsize, st_table *index_tbl) if (RBASIC(obj)->flags & ROBJECT_EMBED) { newptr = obj_ivar_heap_alloc(obj, newsize); MEMCPY(newptr, ptr, VALUE, len); - RBASIC(obj)->flags &= ~ROBJECT_EMBED; + RB_FL_UNSET_RAW(obj, ROBJECT_EMBED); ROBJECT(obj)->as.heap.ivptr = newptr; } else { @@ -1503,7 +1505,11 @@ init_iv_list(VALUE obj, uint32_t len, uint32_t newsize, st_table *index_tbl) for (; len < newsize; len++) { newptr[len] = Qundef; } +#if USE_RVARGC + ROBJECT(obj)->numiv = newsize; +#else ROBJECT(obj)->as.heap.numiv = newsize; +#endif ROBJECT(obj)->as.heap.iv_index_tbl = index_tbl; } diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs index 5d30d7b288..f54addc795 100644 --- a/yjit/bindgen/src/main.rs +++ b/yjit/bindgen/src/main.rs @@ -62,6 +62,9 @@ fn main() { // Import YARV bytecode instruction constants .allowlist_type("ruby_vminsn_type") + // From include/ruby/internal/config.h + .allowlist_var("USE_RVARGC") + // From include/ruby/internal/intern/string.h .allowlist_function("rb_utf8_str_new") .allowlist_function("rb_str_buf_append") @@ -135,7 +138,8 @@ fn main() { // From include/ruby/internal/core/robject.h .allowlist_type("ruby_robject_flags") - .allowlist_type("ruby_robject_consts") + // .allowlist_type("ruby_robject_consts") // Removed when USE_RVARGC + .allowlist_var("ROBJECT_OFFSET_.*") // From include/ruby/internal/core/rarray.h .allowlist_type("ruby_rarray_flags") diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 84f4ff4897..9cd69cd340 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -1966,9 +1966,17 @@ fn gen_get_ivar( ctx.stack_pop(1); } + if USE_RVARGC != 0 { + // Check that the ivar table is big enough + // Check that the slot is inside the ivar table (num_slots > index) + let num_slots = mem_opnd(32, REG0, ROBJECT_OFFSET_NUMIV); + cmp(cb, num_slots, uimm_opnd(ivar_index as u64)); + jle_ptr(cb, counted_exit!(ocb, side_exit, getivar_idx_out_of_range)); + } + // Compile time self is embedded and the ivar index lands within the object let test_result = unsafe { FL_TEST_RAW(comptime_receiver, VALUE(ROBJECT_EMBED.as_usize())) != VALUE(0) }; - if test_result && ivar_index < (ROBJECT_EMBED_LEN_MAX.as_usize()) { + if test_result { // See ROBJECT_IVPTR() from include/ruby/internal/core/robject.h // Guard that self is embedded @@ -1988,7 +1996,7 @@ fn gen_get_ivar( ); // Load the variable - let offs = RUBY_OFFSET_ROBJECT_AS_ARY + (ivar_index * SIZEOF_VALUE) as i32; + let offs = ROBJECT_OFFSET_AS_ARY + (ivar_index * SIZEOF_VALUE) as i32; let ivar_opnd = mem_opnd(64, REG0, offs); mov(cb, REG1, ivar_opnd); @@ -2019,17 +2027,16 @@ fn gen_get_ivar( side_exit, ); - // Check that the extended table is big enough - if ivar_index > (ROBJECT_EMBED_LEN_MAX.as_usize()) { + if USE_RVARGC == 0 { + // Check that the extended table is big enough // Check that the slot is inside the extended table (num_slots > index) - let num_slots = mem_opnd(32, REG0, RUBY_OFFSET_ROBJECT_AS_HEAP_NUMIV); - + let num_slots = mem_opnd(32, REG0, ROBJECT_OFFSET_NUMIV); cmp(cb, num_slots, uimm_opnd(ivar_index as u64)); jle_ptr(cb, counted_exit!(ocb, side_exit, getivar_idx_out_of_range)); } // Get a pointer to the extended table - let tbl_opnd = mem_opnd(64, REG0, RUBY_OFFSET_ROBJECT_AS_HEAP_IVPTR); + let tbl_opnd = mem_opnd(64, REG0, ROBJECT_OFFSET_AS_HEAP_IVPTR); mov(cb, REG0, tbl_opnd); // Read the ivar from the extended table diff --git a/yjit/src/cruby.rs b/yjit/src/cruby.rs index 8cebfd58a5..7c21bd962b 100644 --- a/yjit/src/cruby.rs +++ b/yjit/src/cruby.rs @@ -739,10 +739,6 @@ mod manual_defs { pub const RUBY_OFFSET_RSTRUCT_AS_HEAP_PTR: i32 = 24; // struct RStruct, subfield "as.heap.ptr" pub const RUBY_OFFSET_RSTRUCT_AS_ARY: i32 = 16; // struct RStruct, subfield "as.ary" - pub const RUBY_OFFSET_ROBJECT_AS_ARY: i32 = 16; // struct RObject, subfield "as.ary" - pub const RUBY_OFFSET_ROBJECT_AS_HEAP_NUMIV: i32 = 16; // struct RObject, subfield "as.heap.numiv" - pub const RUBY_OFFSET_ROBJECT_AS_HEAP_IVPTR: i32 = 24; // struct RObject, subfield "as.heap.ivptr" - // Constants from rb_control_frame_t vm_core.h pub const RUBY_OFFSET_CFP_PC: i32 = 0; pub const RUBY_OFFSET_CFP_SP: i32 = 8; diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index 88ad8e563c..b9c239cd23 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -1,5 +1,6 @@ /* automatically generated by rust-bindgen 0.59.2 */ +pub const USE_RVARGC: u32 = 1; pub const INTEGER_REDEFINED_OP_FLAG: u32 = 1; pub const FLOAT_REDEFINED_OP_FLAG: u32 = 2; pub const STRING_REDEFINED_OP_FLAG: u32 = 4; @@ -110,8 +111,10 @@ extern "C" { } pub const ROBJECT_EMBED: ruby_robject_flags = 8192; pub type ruby_robject_flags = u32; -pub const ROBJECT_EMBED_LEN_MAX: ruby_robject_consts = 3; -pub type ruby_robject_consts = u32; +pub const ROBJECT_OFFSET_NUMIV: i32 = 16; +pub const ROBJECT_OFFSET_AS_HEAP_IVPTR: i32 = 24; +pub const ROBJECT_OFFSET_AS_HEAP_IV_INDEX_TBL: i32 = 32; +pub const ROBJECT_OFFSET_AS_ARY: i32 = 24; extern "C" { pub static mut rb_mKernel: VALUE; } |