From 1c5ae5a16343fe8e32876ad38fd4093962dd02c2 Mon Sep 17 00:00:00 2001 From: ko1 Date: Thu, 9 Nov 2017 06:57:24 +0000 Subject: [PATCH] insn_info/insns_info * iseq.h (iseq_line_info_entry): rename to iseq_insn_info_entry. * vm_core.h (rb_iseq_constant_body): rename field name line_info_table to insns_info and also from line_info_size to insns_info_size. * compile.c (INSN): add struct insn_info to contain per insn information. * compile.c (add_insn_info): added to add new insn_info entry. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60726 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- compile.c | 113 +++++++++++++++++++++++++++++++++--------------------- iseq.c | 40 +++++++++---------- iseq.h | 4 +- vm_core.h | 4 +- 4 files changed, 93 insertions(+), 68 deletions(-) diff --git a/compile.c b/compile.c index bcc7dce9fd..e36b530f6f 100644 --- a/compile.c +++ b/compile.c @@ -72,10 +72,12 @@ typedef struct iseq_label_data { typedef struct iseq_insn_data { LINK_ELEMENT link; enum ruby_vminsn_type insn_id; - unsigned int line_no; int operand_size; int sc_state; VALUE *operands; + struct { + int line_no; + } insn_info; } INSN; typedef struct iseq_adjust_data { @@ -1111,7 +1113,7 @@ new_insn_core(rb_iseq_t *iseq, int line_no, iobj->link.type = ISEQ_ELEMENT_INSN; iobj->link.next = 0; iobj->insn_id = insn_id; - iobj->line_no = line_no; + iobj->insn_info.line_no = line_no; iobj->operands = argv; iobj->operand_size = argc; iobj->sc_state = 0; @@ -1679,7 +1681,7 @@ get_ivar_ic_value(rb_iseq_t *iseq,ID id) #define BADINSN_ERROR \ (xfree(generated_iseq), \ - xfree(line_info_table), \ + xfree(insns_info), \ BADINSN_DUMP(anchor, list, NULL), \ COMPILE_ERROR) @@ -1709,7 +1711,7 @@ fix_sp_depth(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) sp = calc_sp_depth(sp, iobj); if (sp < 0) { BADINSN_DUMP(anchor, list, NULL); - COMPILE_ERROR(iseq, iobj->line_no, + COMPILE_ERROR(iseq, iobj->insn_info.line_no, "argument stack underflow (%d)", sp); return -1; } @@ -1717,7 +1719,7 @@ fix_sp_depth(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) stack_max = sp; } - line = iobj->line_no; + line = iobj->insn_info.line_no; /* fprintf(stderr, "insn: %-16s, sp: %d\n", insn_name(iobj->insn_id), sp); */ operands = iobj->operands; insn = iobj->insn_id; @@ -1728,7 +1730,7 @@ fix_sp_depth(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) if (iobj->operand_size != len - 1) { /* printf("operand size miss! (%d, %d)\n", iobj->operand_size, len); */ BADINSN_DUMP(anchor, list, NULL); - COMPILE_ERROR(iseq, iobj->line_no, + COMPILE_ERROR(iseq, iobj->insn_info.line_no, "operand size miss! (%d for %d)", iobj->operand_size, len - 1); return -1; @@ -1740,7 +1742,7 @@ fix_sp_depth(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) LABEL *lobj = (LABEL *)operands[j]; if (!lobj->set) { BADINSN_DUMP(anchor, list, NULL); - COMPILE_ERROR(iseq, iobj->line_no, + COMPILE_ERROR(iseq, iobj->insn_info.line_no, "unknown label: "LABEL_FORMAT, lobj->label_no); return -1; } @@ -1791,18 +1793,50 @@ fix_sp_depth(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) return stack_max; } +static int +add_insn_info(struct iseq_insn_info_entry *insns_info, int insns_info_index, int code_index, LINK_ELEMENT *list) +{ + if (list->type == ISEQ_ELEMENT_INSN) { + INSN *iobj = (INSN *)list; + if (iobj->insn_info.line_no != 0 && + (insns_info_index == 0 || + insns_info[insns_info_index-1].line_no != iobj->insn_info.line_no)) { + insns_info[insns_info_index].position = code_index; + insns_info[insns_info_index].line_no = iobj->insn_info.line_no; + return TRUE; + } + else { + return FALSE; + } + } + else if (list->type == ISEQ_ELEMENT_ADJUST) { + ADJUST *adjust = (ADJUST *)list; + if (insns_info_index > 0 || + insns_info[insns_info_index-1].line_no != adjust->line_no) { + insns_info[insns_info_index].position = code_index; + insns_info[insns_info_index].line_no = adjust->line_no; + return TRUE; + } + else { + return FALSE; + } + } + else { + VM_UNREACHABLE(add_insn_info); + } +} + /** ruby insn object list -> raw instruction sequence */ static int iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) { - struct iseq_line_info_entry *line_info_table; - unsigned int last_line = 0; + struct iseq_insn_info_entry *insns_info; LINK_ELEMENT *list; VALUE *generated_iseq; - int insn_num, code_index, line_info_index, sp = 0; + int insn_num, code_index, insns_info_index, sp = 0; int stack_max = fix_sp_depth(iseq, anchor); if (stack_max < 0) return COMPILE_NG; @@ -1853,7 +1887,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) /* make instruction sequence */ generated_iseq = ALLOC_N(VALUE, code_index); - line_info_table = ALLOC_N(struct iseq_line_info_entry, insn_num); + insns_info = ALLOC_N(struct iseq_insn_info_entry, insn_num); iseq->body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, iseq->body->is_size); iseq->body->ci_entries = (struct rb_call_info *)ruby_xmalloc(sizeof(struct rb_call_info) * iseq->body->ci_size + sizeof(struct rb_call_info_with_kwarg) * iseq->body->ci_kw_size); @@ -1862,7 +1896,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) ISEQ_COMPILE_DATA(iseq)->ci_index = ISEQ_COMPILE_DATA(iseq)->ci_kw_index = 0; list = FIRST_ELEMENT(anchor); - line_info_index = code_index = sp = 0; + insns_info_index = code_index = sp = 0; while (list) { switch (list->type) { @@ -1976,16 +2010,12 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) generated_iseq[code_index + 1 + j] = operands[j]; break; default: - BADINSN_ERROR(iseq, iobj->line_no, + BADINSN_ERROR(iseq, iobj->insn_info.line_no, "unknown operand type: %c", type); return COMPILE_NG; } } - if (last_line != iobj->line_no) { - line_info_table[line_info_index].line_no = last_line = iobj->line_no; - line_info_table[line_info_index].position = code_index; - line_info_index++; - } + if (add_insn_info(insns_info, insns_info_index, code_index, (LINK_ELEMENT *)iobj)) insns_info_index++; code_index += len; break; } @@ -2010,11 +2040,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) if (adjust->line_no != -1) { const int diff = orig_sp - sp; if (diff > 0) { - if (last_line != (unsigned int)adjust->line_no) { - line_info_table[line_info_index].line_no = last_line = adjust->line_no; - line_info_table[line_info_index].position = code_index; - line_info_index++; - } + if (add_insn_info(insns_info, insns_info_index, code_index, (LINK_ELEMENT *)adjust)) insns_info_index++; } if (diff > 1) { generated_iseq[code_index++] = BIN(adjuststack); @@ -2026,7 +2052,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) else if (diff < 0) { int label_no = adjust->label ? adjust->label->label_no : -1; xfree(generated_iseq); - xfree(line_info_table); + xfree(insns_info); debug_list(anchor); COMPILE_ERROR(iseq, adjust->line_no, "iseq_set_sequence: adjust bug to %d %d < %d", @@ -2048,11 +2074,11 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) iseq->body->stack_max = stack_max; /* get rid of memory leak when REALLOC failed */ - iseq->body->line_info_table = line_info_table; + iseq->body->insns_info = insns_info; - REALLOC_N(line_info_table, struct iseq_line_info_entry, line_info_index); - iseq->body->line_info_table = line_info_table; - iseq->body->line_info_size = line_info_index; + REALLOC_N(insns_info, struct iseq_insn_info_entry, insns_info_index); + iseq->body->insns_info = insns_info; + iseq->body->insns_info_size = insns_info_index; return COMPILE_OK; } @@ -2369,7 +2395,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal * pop * jump L1 */ - INSN *popiobj = new_insn_core(iseq, iobj->line_no, + INSN *popiobj = new_insn_core(iseq, iobj->insn_info.line_no, BIN(pop), 0, 0); REPLACE_ELEM(&piobj->link, &popiobj->link); } @@ -2509,7 +2535,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal REMOVE_ELEM(iobj->link.prev); } else if (!iseq_pop_newarray(iseq, pobj)) { - pobj = new_insn_core(iseq, pobj->line_no, BIN(pop), 0, NULL); + pobj = new_insn_core(iseq, pobj->insn_info.line_no, BIN(pop), 0, NULL); INSERT_ELEM_NEXT(&iobj->link, &pobj->link); } if (cond) { @@ -2871,7 +2897,7 @@ new_unified_insn(rb_iseq_t *iseq, list = list->next; } - return new_insn_core(iseq, iobj->line_no, insn_id, argc, operands); + return new_insn_core(iseq, iobj->insn_info.line_no, insn_id, argc, operands); } #endif @@ -2955,7 +2981,7 @@ insn_set_sc_state(rb_iseq_t *iseq, const LINK_ELEMENT *anchor, INSN *iobj, int s if (lobj->sc_state != 0) { if (lobj->sc_state != nstate) { BADINSN_DUMP(anchor, iobj, lobj); - COMPILE_ERROR(iseq, iobj->line_no, + COMPILE_ERROR(iseq, iobj->insn_info.line_no, "insn_set_sc_state error: %d at "LABEL_FORMAT ", %d expected\n", lobj->sc_state, lobj->label_no, nstate); @@ -3059,7 +3085,7 @@ iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) case SCS_XX: goto normal_insn; default: - COMPILE_ERROR(iseq, iobj->line_no, + COMPILE_ERROR(iseq, iobj->insn_info.line_no, "unreachable"); return COMPILE_NG; } @@ -5179,7 +5205,6 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE *node, int poppe return iseq_compile_each0(iseq, ret, node, popped); } - static int iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int popped) { @@ -7013,7 +7038,7 @@ dump_disasm_list_with_cursor(const LINK_ELEMENT *link, const LINK_ELEMENT *curr, { iobj = (INSN *)link; str = insn_data_to_s_detail(iobj); - printf("%04d %-65s(%4u)\n", pos, StringValueCStr(str), iobj->line_no); + printf("%04d %-65s(%4u)\n", pos, StringValueCStr(str), iobj->insn_info.line_no); pos += insn_data_length(iobj); break; } @@ -8101,16 +8126,16 @@ ibf_load_param_keyword(const struct ibf_load *load, const struct rb_iseq_constan } } -static struct iseq_line_info_entry * -ibf_dump_line_info_table(struct ibf_dump *dump, const rb_iseq_t *iseq) +static struct iseq_insn_info_entry * +ibf_dump_insns_info(struct ibf_dump *dump, const rb_iseq_t *iseq) { - return IBF_W(iseq->body->line_info_table, struct iseq_line_info_entry, iseq->body->line_info_size); + return IBF_W(iseq->body->insns_info, struct iseq_insn_info_entry, iseq->body->insns_info_size); } -static struct iseq_line_info_entry * -ibf_load_line_info_table(const struct ibf_load *load, const struct rb_iseq_constant_body *body) +static struct iseq_insn_info_entry * +ibf_load_insns_info(const struct ibf_load *load, const struct rb_iseq_constant_body *body) { - return IBF_R(body->line_info_table, struct iseq_line_info_entry, body->line_info_size); + return IBF_R(body->insns_info, struct iseq_insn_info_entry, body->insns_info_size); } static ID * @@ -8264,7 +8289,7 @@ ibf_dump_iseq_each(struct ibf_dump *dump, const rb_iseq_t *iseq) dump_body.iseq_encoded = ibf_dump_code(dump, iseq); dump_body.param.opt_table = ibf_dump_param_opt_table(dump, iseq); dump_body.param.keyword = ibf_dump_param_keyword(dump, iseq); - dump_body.line_info_table = ibf_dump_line_info_table(dump, iseq); + dump_body.insns_info = ibf_dump_insns_info(dump, iseq); dump_body.local_table = ibf_dump_local_table(dump, iseq); dump_body.catch_table = ibf_dump_catch_table(dump, iseq); dump_body.parent_iseq = ibf_dump_iseq(dump, iseq->body->parent_iseq); @@ -8302,7 +8327,7 @@ ibf_load_iseq_each(const struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t of load_body->is_size = body->is_size; load_body->ci_size = body->ci_size; load_body->ci_kw_size = body->ci_kw_size; - load_body->line_info_size = body->line_info_size; + load_body->insns_info_size = body->insns_info_size; RB_OBJ_WRITE(iseq, &load_body->mark_ary, iseq_mark_ary_create((int)body->mark_ary)); @@ -8334,7 +8359,7 @@ ibf_load_iseq_each(const struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t of load_body->cc_entries = ZALLOC_N(struct rb_call_cache, body->ci_size + body->ci_kw_size); load_body->param.opt_table = ibf_load_param_opt_table(load, body); load_body->param.keyword = ibf_load_param_keyword(load, body); - load_body->line_info_table = ibf_load_line_info_table(load, body); + load_body->insns_info = ibf_load_insns_info(load, body); load_body->local_table = ibf_load_local_table(load, body); load_body->catch_table = ibf_load_catch_table(load, body); load_body->parent_iseq = ibf_load_iseq(load, body->parent_iseq); diff --git a/iseq.c b/iseq.c index db9810f565..ac926b7a18 100644 --- a/iseq.c +++ b/iseq.c @@ -74,7 +74,7 @@ rb_iseq_free(const rb_iseq_t *iseq) if (iseq) { if (iseq->body) { ruby_xfree((void *)iseq->body->iseq_encoded); - ruby_xfree((void *)iseq->body->line_info_table); + ruby_xfree((void *)iseq->body->insns_info); ruby_xfree((void *)iseq->body->local_table); ruby_xfree((void *)iseq->body->is_entries); @@ -157,7 +157,7 @@ iseq_memsize(const rb_iseq_t *iseq) size += sizeof(struct rb_iseq_constant_body); size += body->iseq_size * sizeof(VALUE); - size += body->line_info_size * sizeof(struct iseq_line_info_entry); + size += body->insns_info_size * sizeof(struct iseq_insn_info_entry); size += body->local_table_size * sizeof(ID); if (body->catch_table) { size += iseq_catch_table_bytes(body->catch_table->size); @@ -1217,45 +1217,45 @@ iseqw_to_a(VALUE self) /* TODO: search algorithm is brute force. this should be binary search or so. */ -static const struct iseq_line_info_entry * -get_line_info(const rb_iseq_t *iseq, size_t pos) +static const struct iseq_insn_info_entry * +get_insn_info(const rb_iseq_t *iseq, size_t pos) { - size_t i = 0, size = iseq->body->line_info_size; - const struct iseq_line_info_entry *table = iseq->body->line_info_table; + size_t i = 0, size = iseq->body->insns_info_size; + const struct iseq_insn_info_entry *insns_info = iseq->body->insns_info; const int debug = 0; if (debug) { printf("size: %"PRIuSIZE"\n", size); - printf("table[%"PRIuSIZE"]: position: %d, line: %d, pos: %"PRIuSIZE"\n", - i, table[i].position, table[i].line_no, pos); + printf("insns_info[%"PRIuSIZE"]: position: %d, line: %d, pos: %"PRIuSIZE"\n", + i, insns_info[i].position, insns_info[i].line_no, pos); } if (size == 0) { - return 0; + return NULL; } else if (size == 1) { - return &table[0]; + return &insns_info[0]; } else { for (i=1; i pos) { - return &table[i-1]; + if (insns_info[i].position > pos) { + return &insns_info[i-1]; } } } - return &table[i-1]; + return &insns_info[i-1]; } static unsigned int find_line_no(const rb_iseq_t *iseq, size_t pos) { - const struct iseq_line_info_entry *entry = get_line_info(iseq, pos); + const struct iseq_insn_info_entry *entry = get_insn_info(iseq, pos); if (entry) { return entry->line_no; @@ -2090,8 +2090,8 @@ iseq_data_to_ary(const rb_iseq_t *iseq) rb_ary_push(body, (VALUE)label); } - if (ti < iseq->body->line_info_size && iseq->body->line_info_table[ti].position == pos) { - line = iseq->body->line_info_table[ti].line_no; + if (ti < iseq->body->insns_info_size && iseq->body->insns_info[ti].position == pos) { + line = iseq->body->insns_info[ti].line_no; rb_ary_push(body, INT2FIX(line)); ti++; } diff --git a/iseq.h b/iseq.h index b75cb04757..a4a8c693dd 100644 --- a/iseq.h +++ b/iseq.h @@ -140,9 +140,9 @@ struct rb_compile_option_struct { int debug_level; }; -struct iseq_line_info_entry { +struct iseq_insn_info_entry { unsigned int position; - unsigned int line_no; + int line_no; }; struct iseq_catch_table_entry { diff --git a/vm_core.h b/vm_core.h index 2c8d6cf6c2..a73db7ab43 100644 --- a/vm_core.h +++ b/vm_core.h @@ -383,7 +383,7 @@ struct rb_iseq_constant_body { rb_iseq_location_t location; /* insn info, must be freed */ - const struct iseq_line_info_entry *line_info_table; + const struct iseq_insn_info_entry *insns_info; const ID *local_table; /* must free */ @@ -408,7 +408,7 @@ struct rb_iseq_constant_body { unsigned int is_size; unsigned int ci_size; unsigned int ci_kw_size; - unsigned int line_info_size; + unsigned int insns_info_size; unsigned int stack_max; /* for stack overflow check */ };