From 22af2e9084d869b0d1eb24e4c11bc1fd62b7c50d Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Sun, 25 Sep 2022 21:07:18 +1300 Subject: [PATCH] Rework vm_core to use `int first_lineno` struct member. --- compile.c | 6 +++--- gc.c | 5 ++--- iseq.c | 6 +++--- lib/mjit/compiler.rb | 4 ++-- mjit.c | 26 ++++++++++---------------- mjit_c.rb | 7 ++++++- proc.c | 6 +++--- vm_backtrace.c | 4 ++-- vm_core.h | 4 ++-- vm_method.c | 2 +- 10 files changed, 34 insertions(+), 36 deletions(-) diff --git a/compile.c b/compile.c index 26b10ff43c..d9a17560be 100644 --- a/compile.c +++ b/compile.c @@ -766,7 +766,7 @@ rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node) end->rescued = LABEL_RESCUE_END; ADD_TRACE(ret, RUBY_EVENT_B_CALL); - NODE dummy_line_node = generate_dummy_line_node(FIX2INT(ISEQ_BODY(iseq)->location.first_lineno), -1); + NODE dummy_line_node = generate_dummy_line_node(ISEQ_BODY(iseq)->location.first_lineno, -1); ADD_INSN (ret, &dummy_line_node, nop); ADD_LABEL(ret, start); CHECK(COMPILE(ret, "block body", node->nd_body)); @@ -12024,7 +12024,7 @@ ibf_dump_iseq_each(struct ibf_dump *dump, const rb_iseq_t *iseq) ibf_dump_write_small_value(dump, location_pathobj_index); ibf_dump_write_small_value(dump, location_base_label_index); ibf_dump_write_small_value(dump, location_label_index); - ibf_dump_write_small_value(dump, body->location.first_lineno); + ibf_dump_write_small_value(dump, RB_INT2NUM(body->location.first_lineno)); ibf_dump_write_small_value(dump, body->location.node_id); ibf_dump_write_small_value(dump, body->location.code_location.beg_pos.lineno); ibf_dump_write_small_value(dump, body->location.code_location.beg_pos.column); @@ -12195,7 +12195,7 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset) load_body->variable.flip_count = variable_flip_count; load_body->variable.script_lines = Qnil; - load_body->location.first_lineno = location_first_lineno; + load_body->location.first_lineno = RB_NUM2INT(location_first_lineno); load_body->location.node_id = location_node_id; load_body->location.code_location.beg_pos.lineno = location_code_location_beg_pos_lineno; load_body->location.code_location.beg_pos.column = location_code_location_beg_pos_column; diff --git a/gc.c b/gc.c index ecb4aa7e20..d026139d7b 100644 --- a/gc.c +++ b/gc.c @@ -13804,11 +13804,10 @@ rb_raw_iseq_info(char *const buff, const size_t buff_size, const rb_iseq_t *iseq { if (buff_size > 0 && ISEQ_BODY(iseq) && ISEQ_BODY(iseq)->location.label && !RB_TYPE_P(ISEQ_BODY(iseq)->location.pathobj, T_MOVED)) { VALUE path = rb_iseq_path(iseq); - VALUE n = ISEQ_BODY(iseq)->location.first_lineno; + int n = ISEQ_BODY(iseq)->location.first_lineno; snprintf(buff, buff_size, " %s@%s:%d", RSTRING_PTR(ISEQ_BODY(iseq)->location.label), - RSTRING_PTR(path), - n ? FIX2INT(n) : 0 ); + RSTRING_PTR(path), n); } } diff --git a/iseq.c b/iseq.c index 5f2143baa9..a4792d81fd 100644 --- a/iseq.c +++ b/iseq.c @@ -598,7 +598,7 @@ iseq_location_setup(rb_iseq_t *iseq, VALUE name, VALUE path, VALUE realpath, int rb_iseq_pathobj_set(iseq, path, realpath); RB_OBJ_WRITE(iseq, &loc->label, name); RB_OBJ_WRITE(iseq, &loc->base_label, name); - loc->first_lineno = RB_INT2NUM(first_lineno); + loc->first_lineno = first_lineno; if (code_location) { loc->node_id = node_id; loc->code_location = *code_location; @@ -1235,7 +1235,7 @@ rb_iseq_base_label(const rb_iseq_t *iseq) VALUE rb_iseq_first_lineno(const rb_iseq_t *iseq) { - return ISEQ_BODY(iseq)->location.first_lineno; + return RB_INT2NUM(ISEQ_BODY(iseq)->location.first_lineno); } VALUE @@ -3164,7 +3164,7 @@ iseq_data_to_ary(const rb_iseq_t *iseq) rb_ary_push(val, iseq_body->location.label); rb_ary_push(val, rb_iseq_path(iseq)); rb_ary_push(val, rb_iseq_realpath(iseq)); - rb_ary_push(val, iseq_body->location.first_lineno); + rb_ary_push(val, RB_INT2NUM(iseq_body->location.first_lineno)); rb_ary_push(val, ID2SYM(type)); rb_ary_push(val, locals); rb_ary_push(val, params); diff --git a/lib/mjit/compiler.rb b/lib/mjit/compiler.rb index 254ecc885f..49f28ab690 100644 --- a/lib/mjit/compiler.rb +++ b/lib/mjit/compiler.rb @@ -785,8 +785,8 @@ module RubyVM::MJIT if C.mjit_opts.verbose >= 1 # print beforehand because ISeq may be GCed during copy job. child_location = child_iseq.body.location - $stderr.puts "JIT inline: #{child_location.label}@#{C.rb_iseq_path(child_iseq)}:#{child_location.first_lineno} " \ - "=> #{iseq.body.location.label}@#{C.rb_iseq_path(iseq)}:#{iseq.body.location.first_lineno}" + $stderr.puts "JIT inline: #{child_location.label}@#{C.rb_iseq_path(child_iseq)}:#{C.rb_iseq_first_lineno(child_iseq)} " \ + "=> #{iseq.body.location.label}@#{C.rb_iseq_path(iseq)}:#{C.rb_iseq_first_lineno(iseq)}" end if !precompile_inlinable_child_iseq(f, child_iseq, status, ci, cc, pos) return false diff --git a/mjit.c b/mjit.c index 1997eaa939..80743a150b 100644 --- a/mjit.c +++ b/mjit.c @@ -707,15 +707,12 @@ mjit_compact(char* c_file) char funcname[MAXPATHLEN]; sprint_funcname(funcname, child_unit); - long iseq_lineno = 0; - if (FIXNUM_P(ISEQ_BODY(child_unit->iseq)->location.first_lineno)) - // FIX2INT may fallback to rb_num2long(), which is a method call and dangerous in MJIT worker. So using only FIX2LONG. - iseq_lineno = FIX2LONG(ISEQ_BODY(child_unit->iseq)->location.first_lineno); + int iseq_lineno = ISEQ_BODY(child_unit->iseq)->location.first_lineno; const char *sep = "@"; const char *iseq_label = RSTRING_PTR(ISEQ_BODY(child_unit->iseq)->location.label); const char *iseq_path = RSTRING_PTR(rb_iseq_path(child_unit->iseq)); if (!iseq_label) iseq_label = sep = ""; - fprintf(f, "\n/* %s%s%s:%ld */\n", iseq_label, sep, iseq_path, iseq_lineno); + fprintf(f, "\n/* %s%s%s:%d */\n", iseq_label, sep, iseq_path, iseq_lineno); success &= mjit_compile(f, child_unit->iseq, funcname, child_unit->id); } @@ -875,24 +872,21 @@ mjit_compile_unit(struct rb_mjit_unit *unit) compile_prelude(f); // To make MJIT worker thread-safe against GC.compact, copy ISeq values while `in_jit` is true. - long iseq_lineno = 0; - if (FIXNUM_P(ISEQ_BODY(unit->iseq)->location.first_lineno)) - // FIX2INT may fallback to rb_num2long(), which is a method call and dangerous in MJIT worker. So using only FIX2LONG. - iseq_lineno = FIX2LONG(ISEQ_BODY(unit->iseq)->location.first_lineno); + int iseq_lineno = ISEQ_BODY(unit->iseq)->location.first_lineno; char *iseq_label = alloca(RSTRING_LEN(ISEQ_BODY(unit->iseq)->location.label) + 1); char *iseq_path = alloca(RSTRING_LEN(rb_iseq_path(unit->iseq)) + 1); strcpy(iseq_label, RSTRING_PTR(ISEQ_BODY(unit->iseq)->location.label)); strcpy(iseq_path, RSTRING_PTR(rb_iseq_path(unit->iseq))); - verbose(2, "start compilation: %s@%s:%ld -> %s", iseq_label, iseq_path, iseq_lineno, c_file); - fprintf(f, "/* %s@%s:%ld */\n\n", iseq_label, iseq_path, iseq_lineno); + verbose(2, "start compilation: %s@%s:%d -> %s", iseq_label, iseq_path, iseq_lineno, c_file); + fprintf(f, "/* %s@%s:%d */\n\n", iseq_label, iseq_path, iseq_lineno); bool success = mjit_compile(f, unit->iseq, funcname, unit->id); fclose(f); if (!success) { if (!mjit_opts.save_temps) remove_file(c_file); - verbose(1, "JIT failure: %s@%s:%ld -> %s", iseq_label, iseq_path, iseq_lineno, c_file); + verbose(1, "JIT failure: %s@%s:%d -> %s", iseq_label, iseq_path, iseq_lineno, c_file); return 1; } @@ -1372,9 +1366,9 @@ mjit_notify_waitpid(int exit_code) rb_iseq_t *iseq = current_cc_unit->iseq; if ((uintptr_t)func > (uintptr_t)LAST_JIT_ISEQ_FUNC) { double end_time = real_ms_time(); - verbose(1, "JIT success (%.1fms): %s@%s:%ld -> %s", + verbose(1, "JIT success (%.1fms): %s@%s:%d -> %s", end_time - current_cc_ms, RSTRING_PTR(ISEQ_BODY(iseq)->location.label), - RSTRING_PTR(rb_iseq_path(iseq)), FIX2LONG(ISEQ_BODY(iseq)->location.first_lineno), c_file); + RSTRING_PTR(rb_iseq_path(iseq)), ISEQ_BODY(iseq)->location.first_lineno, c_file); add_to_list(current_cc_unit, &active_units); } @@ -1531,7 +1525,7 @@ mjit_recompile(const rb_iseq_t *iseq) return; verbose(1, "JIT recompile: %s@%s:%d", RSTRING_PTR(ISEQ_BODY(iseq)->location.label), - RSTRING_PTR(rb_iseq_path(iseq)), FIX2INT(ISEQ_BODY(iseq)->location.first_lineno)); + RSTRING_PTR(rb_iseq_path(iseq)), ISEQ_BODY(iseq)->location.first_lineno); VM_ASSERT(ISEQ_BODY(iseq)->jit_unit != NULL); mjit_add_iseq_to_process(iseq, &ISEQ_BODY(iseq)->jit_unit->compile_info, true); @@ -2011,7 +2005,7 @@ mjit_dump_total_calls(void) ccan_list_for_each(&active_units.head, unit, unode) { const rb_iseq_t *iseq = unit->iseq; fprintf(stderr, "%8ld: %s@%s:%d\n", ISEQ_BODY(iseq)->total_calls, RSTRING_PTR(ISEQ_BODY(iseq)->location.label), - RSTRING_PTR(rb_iseq_path(iseq)), FIX2INT(ISEQ_BODY(iseq)->location.first_lineno)); + RSTRING_PTR(rb_iseq_path(iseq)), ISEQ_BODY(iseq)->location.first_lineno); } } #endif diff --git a/mjit_c.rb b/mjit_c.rb index 6b316860be..d8e5628bda 100644 --- a/mjit_c.rb +++ b/mjit_c.rb @@ -32,6 +32,11 @@ module RubyVM::MJIT Primitive.cexpr! 'rb_iseq_path((rb_iseq_t *)NUM2PTR(_iseq_addr))' end + def rb_iseq_first_lineno(iseq) + _iseq_addr = iseq.to_i + Primitive.cexpr! 'rb_iseq_first_lineno((rb_iseq_t *)NUM2PTR(_iseq_addr))' + end + def vm_ci_argc(ci) _ci_addr = ci.to_i Primitive.cexpr! 'UINT2NUM(vm_ci_argc((CALL_INFO)NUM2PTR(_ci_addr)))' @@ -461,7 +466,7 @@ module RubyVM::MJIT pathobj: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), pathobj)"), true], base_label: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), base_label)"), true], label: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), label)"), true], - first_lineno: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), first_lineno)"), true], + first_lineno: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), first_lineno)"), true], node_id: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), node_id)")], code_location: [self.rb_code_location_t, Primitive.cexpr!("OFFSETOF((*((struct rb_iseq_location_struct *)NULL)), code_location)")], ) diff --git a/proc.c b/proc.c index fb182efe46..50db2daa46 100644 --- a/proc.c +++ b/proc.c @@ -1363,7 +1363,7 @@ iseq_location(const rb_iseq_t *iseq) if (!iseq) return Qnil; rb_iseq_check(iseq); loc[0] = rb_iseq_path(iseq); - loc[1] = ISEQ_BODY(iseq)->location.first_lineno; + loc[1] = RB_INT2NUM(ISEQ_BODY(iseq)->location.first_lineno); return rb_ary_new4(2, loc); } @@ -1544,7 +1544,7 @@ rb_block_to_s(VALUE self, const struct rb_block *block, const char *additional_i const rb_iseq_t *iseq = rb_iseq_check(block->as.captured.code.iseq); rb_str_catf(str, "%p %"PRIsVALUE":%d", (void *)self, rb_iseq_path(iseq), - FIX2INT(ISEQ_BODY(iseq)->location.first_lineno)); + ISEQ_BODY(iseq)->location.first_lineno); } break; case block_type_symbol: @@ -3506,7 +3506,7 @@ proc_binding(VALUE self) if (iseq) { rb_iseq_check(iseq); RB_OBJ_WRITE(bindval, &bind->pathobj, ISEQ_BODY(iseq)->location.pathobj); - bind->first_lineno = FIX2INT(rb_iseq_first_lineno(iseq)); + bind->first_lineno = ISEQ_BODY(iseq)->location.first_lineno; } else { RB_OBJ_WRITE(bindval, &bind->pathobj, diff --git a/vm_backtrace.c b/vm_backtrace.c index 2e898507df..3aae59bf68 100644 --- a/vm_backtrace.c +++ b/vm_backtrace.c @@ -46,7 +46,7 @@ calc_pos(const rb_iseq_t *iseq, const VALUE *pc, int *lineno, int *node_id) VM_ASSERT(! ISEQ_BODY(iseq)->local_table_size); return 0; } - if (lineno) *lineno = FIX2INT(ISEQ_BODY(iseq)->location.first_lineno); + if (lineno) *lineno = ISEQ_BODY(iseq)->location.first_lineno; #ifdef USE_ISEQ_NODE_ID if (node_id) *node_id = -1; #endif @@ -105,7 +105,7 @@ rb_vm_get_sourceline(const rb_control_frame_t *cfp) return line; } else { - return FIX2INT(rb_iseq_first_lineno(iseq)); + return ISEQ_BODY(iseq)->location.first_lineno; } } else { diff --git a/vm_core.h b/vm_core.h index 7dc53399b4..e11838a59a 100644 --- a/vm_core.h +++ b/vm_core.h @@ -310,7 +310,7 @@ typedef struct rb_iseq_location_struct { VALUE pathobj; /* String (path) or Array [path, realpath]. Frozen. */ VALUE base_label; /* String */ VALUE label; /* String */ - VALUE first_lineno; + int first_lineno; int node_id; rb_code_location_t code_location; } rb_iseq_location_t; @@ -1193,7 +1193,7 @@ extern const rb_data_type_t ruby_binding_data_type; typedef struct { const struct rb_block block; const VALUE pathobj; - unsigned short first_lineno; + int first_lineno; } rb_binding_t; /* used by compile time and send insn */ diff --git a/vm_method.c b/vm_method.c index 03ab66d580..08e91ea039 100644 --- a/vm_method.c +++ b/vm_method.c @@ -909,7 +909,7 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil } if (iseq) { rb_compile_warning(RSTRING_PTR(rb_iseq_path(iseq)), - FIX2INT(ISEQ_BODY(iseq)->location.first_lineno), + ISEQ_BODY(iseq)->location.first_lineno, "previous definition of %"PRIsVALUE" was here", rb_id2str(old_def->original_id)); }