diff options
author | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-09-10 06:14:07 +0000 |
---|---|---|
committer | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-09-10 06:14:07 +0000 |
commit | ea4c97904e37df0937af1742b41f3bb999b785b8 (patch) | |
tree | c2e9a9e62f287300406293effd8d28d43ba6fbf8 /compile.c | |
parent | fd31eb3f5c2047415ae741ef7cdd7a5f985ebc7a (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.c | 47 |
1 files changed, 41 insertions, 6 deletions
@@ -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; |