summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-08-24 06:31:15 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-08-24 06:31:15 +0000
commit7049d9c80d1ba859beb5d68c7a9de37d5c11b8e8 (patch)
treee64aa3d7290f296d3685aa27a3e0997fac84a76d /compile.c
parent4f03f0cb67b0bf6497ffd4051e872905e3b49ead (diff)
downloadruby-7049d9c80d1ba859beb5d68c7a9de37d5c11b8e8.tar.gz
* iseq.h, iseq.c, compile.c: Change the line number data structure
to solve an issue reported at [ruby-dev:44413] [Ruby 1.9 - Bug #5217]. Before this fix, each instruction has an information including line number (iseq::iseq_insn_info_table). Instead of this data structure, recording only line number changing places (iseq::iseq_line_info_table). The order of entries in iseq_line_info_table is ascending order of iseq_line_info_table_entry::position. You can get a line number by an iseq and a program counter with this data structure. This fix reduces memory consumption of iseq (bytecode). On my measurement, a rails application consumes 21.8MB for iseq with this fix on the 32bit CPU. Without this fix, it consumes 24.7MB for iseq [ruby-dev:44415]. * proc.c: ditto. * vm_insnhelper.c: ditto. * vm_method.c: ditto. * vm.c (rb_vm_get_sourceline): change to use rb_iseq_line_no(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33046 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/compile.c b/compile.c
index 53149cafb2..fd800a8840 100644
--- a/compile.c
+++ b/compile.c
@@ -51,7 +51,7 @@ typedef struct iseq_label_data {
typedef struct iseq_insn_data {
LINK_ELEMENT link;
enum ruby_vminsn_type insn_id;
- int line_no;
+ unsigned int line_no;
int operand_size;
int sc_state;
VALUE *operands;
@@ -1283,7 +1283,8 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
{
LABEL *lobj;
INSN *iobj;
- struct iseq_insn_info_entry *insn_info_table;
+ struct iseq_line_info_entry *line_info_table;
+ unsigned int last_line = 0;
LINK_ELEMENT *list;
VALUE *generated_iseq;
@@ -1335,7 +1336,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
/* make instruction sequence */
generated_iseq = ALLOC_N(VALUE, pos);
- insn_info_table = ALLOC_N(struct iseq_insn_info_entry, k);
+ line_info_table = ALLOC_N(struct iseq_line_info_entry, k);
iseq->ic_entries = ALLOC_N(struct iseq_inline_cache_entry, iseq->ic_size);
MEMZERO(iseq->ic_entries, struct iseq_inline_cache_entry, iseq->ic_size);
@@ -1373,7 +1374,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
"operand size miss! (%d for %d)",
iobj->operand_size, len - 1);
xfree(generated_iseq);
- xfree(insn_info_table);
+ xfree(line_info_table);
return 0;
}
@@ -1476,15 +1477,16 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
rb_compile_error(RSTRING_PTR(iseq->filename), iobj->line_no,
"unknown operand type: %c", type);
xfree(generated_iseq);
- xfree(insn_info_table);
+ xfree(line_info_table);
return 0;
}
}
- insn_info_table[k].line_no = iobj->line_no;
- insn_info_table[k].position = pos;
- insn_info_table[k].sp = sp;
- pos += len;
+ if (last_line != iobj->line_no) {
+ line_info_table[k].line_no = last_line = iobj->line_no;
+ line_info_table[k].position = pos;
k++;
+ }
+ pos += len;
break;
}
case ISEQ_ELEMENT_LABEL:
@@ -1512,19 +1514,21 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
if (adjust->line_no != -1) {
if (orig_sp - sp > 0) {
- insn_info_table[k].line_no = adjust->line_no;
- insn_info_table[k].position = pos;
- insn_info_table[k].sp = sp;
+ if (last_line != (unsigned int)adjust->line_no) {
+ line_info_table[k].line_no = last_line = adjust->line_no;
+ line_info_table[k].position = pos;
k++;
+ }
generated_iseq[pos++] = BIN(adjuststack);
generated_iseq[pos++] = orig_sp - sp;
}
else if (orig_sp - sp == 0) {
/* jump to next insn */
- insn_info_table[k].line_no = adjust->line_no;
- insn_info_table[k].position = pos;
- insn_info_table[k].sp = sp;
+ if (last_line != (unsigned int)adjust->line_no) {
+ line_info_table[k].line_no = last_line = adjust->line_no;
+ line_info_table[k].position = pos;
k++;
+ }
generated_iseq[pos++] = BIN(jump);
generated_iseq[pos++] = 0;
}
@@ -1550,10 +1554,12 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
iseq->iseq = (void *)generated_iseq;
iseq->iseq_size = pos;
- iseq->insn_info_table = insn_info_table;
- iseq->insn_info_size = k;
iseq->stack_max = stack_max;
+ line_info_table = ruby_xrealloc(line_info_table, k * sizeof(struct iseq_line_info_entry));
+ iseq->line_info_table = line_info_table;
+ iseq->line_info_size = k;
+
return COMPILE_OK;
}
@@ -5288,6 +5294,7 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
long i, len = RARRAY_LEN(body);
int j;
int line_no = 0;
+
/*
* index -> LABEL *label
*/