summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-09-10 06:14:07 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-09-10 06:14:07 +0000
commitea4c97904e37df0937af1742b41f3bb999b785b8 (patch)
treec2e9a9e62f287300406293effd8d28d43ba6fbf8 /compile.c
parentfd31eb3f5c2047415ae741ef7cdd7a5f985ebc7a (diff)
compile: translate iseq in-place
running "ruby -rpp -e 'pp GC.stat'", a reduction in malloc usage is shown: before: :malloc_increase=>118784, :oldmalloc_increase=>1178736, after: :malloc_increase=>99832, :oldmalloc_increase=>1031976, For "ruby -e exit", valgrind reports over 300K reduction in overall allocations (and unnecessary memory copies). before: total heap usage: 49,622 allocs, 20,492 frees, 8,697,493 bytes allocated after: total heap usage: 48,935 allocs, 19,805 frees, 8,373,773 bytes allocated (numbers from x86-64) v2 changes based on ko1 recommendations [ruby-core:64883]: - squashed in-place direct thread translation to avoid alloc+copy - renamed rb_iseq_untranslate_threaded_code to rb_iseq_original_iseq, cache new iseq->iseq_original field. * compile.c (rb_iseq_translate_threaded_code): modify in-place w/o copy (rb_vm_addr2insn): new function for debug (rb_iseq_original_iseq): ditto (iseq_set_sequence): assign iseq_encoded directly [Feature #10185] * vm_core (rb_iseq_t): move original ->iseq to bottom * iseq.c (iseq_free, iseq_free): adjust for new layout (rb_iseq_disasm): use original iseq for dump (iseq_data_to_ary): ditto (rb_iseq_line_trace_each): ditto (rb_iseq_build_for_ruby2cext): use iseq_encoded directly * vm_dump.c (rb_vmdebug_debug_print_pre): use original iseq git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47508 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c47
1 files changed, 41 insertions, 6 deletions
diff --git a/compile.c b/compile.c
index 434d385aa8..5b778e0ccf 100644
--- a/compile.c
+++ b/compile.c
@@ -569,21 +569,56 @@ rb_iseq_translate_threaded_code(rb_iseq_t *iseq)
const void * const *table = rb_vm_get_insns_address_table();
unsigned int i;
- iseq->iseq_encoded = ALLOC_N(VALUE, iseq->iseq_size);
- MEMCPY(iseq->iseq_encoded, iseq->iseq, VALUE, iseq->iseq_size);
-
for (i = 0; i < iseq->iseq_size; /* */ ) {
int insn = (int)iseq->iseq_encoded[i];
int len = insn_len(insn);
iseq->iseq_encoded[i] = (VALUE)table[insn];
i += len;
}
-#else
- iseq->iseq_encoded = iseq->iseq;
#endif
return COMPILE_OK;
}
+#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
+static int
+rb_vm_addr2insn(const void *addr) /* cold path */
+{
+ int insn;
+ const void * const *table = rb_vm_get_insns_address_table();
+
+ for (insn = 0; insn < VM_INSTRUCTION_SIZE; insn++) {
+ if (table[insn] == addr)
+ return insn;
+ }
+ rb_bug("rb_vm_addr2insn: invalid insn address: %p", addr);
+}
+#endif
+
+VALUE *
+rb_iseq_original_iseq(rb_iseq_t *iseq) /* cold path */
+{
+ if (iseq->iseq) return iseq->iseq;
+
+ iseq->iseq = ALLOC_N(VALUE, iseq->iseq_size);
+
+ MEMCPY(iseq->iseq, iseq->iseq_encoded, VALUE, iseq->iseq_size);
+
+#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
+ {
+ unsigned int i;
+
+ for (i = 0; i < iseq->iseq_size; /* */ ) {
+ const void *addr = (const void *)iseq->iseq[i];
+ int insn = (VALUE)rb_vm_addr2insn(addr);
+
+ iseq->iseq[i] = insn;
+ i += insn_len(insn);
+ }
+ }
+#endif
+ return iseq->iseq;
+}
+
/*********************************************/
/* definition of data structure for compiler */
/*********************************************/
@@ -1645,7 +1680,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
}
#endif
- iseq->iseq = (void *)generated_iseq;
+ iseq->iseq_encoded = (void *)generated_iseq;
iseq->iseq_size = pos;
iseq->stack_max = stack_max;