ruby-changes:34728
From: normal <ko1@a...>
Date: Mon, 14 Jul 2014 16:06:50 +0900 (JST)
Subject: [ruby-changes:34728] normal:r46811 (trunk): vm_core.h (struct rb_iseq_struct): reduce to 296 bytes on 64-bit
normal 2014-07-14 16:06:26 +0900 (Mon, 14 Jul 2014) New Revision: 46811 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=46811 Log: vm_core.h (struct rb_iseq_struct): reduce to 296 bytes on 64-bit Most iseq do not have a catch_table, so avoid needlessly adding 4-8 bytes to the struct for the common case. Changes from v2: - iseq_catch_table_size removed, use if (...) for (;...;) Changes from v1: - renamed iseq->_catch_table to iseq->catch_table - iseq_catch_table_bytes: made a static inline function - iseq_catch_table_size: new function replaces the iseq_catch_table_each iterator macro * iseq.h (struct iseq_catch_table): new flexible array struct (iseq_catch_table_bytes): allocated size function * vm_core.h (struct rb_iseq_struct): uupdate catch_table member * compile.c (iseq_set_exception_table): update for struct changes * iseq.c (iseq_free): ditto * iseq.c (iseq_memsize): ditto * iseq.c (rb_iseq_disasm): ditto * iseq.c (iseq_data_to_ary): ditto * iseq.c (rb_iseq_build_for_ruby2cext): ditto (untested) * vm.c (vm_exec): ditto * vm_core.h (struct rb_iseq_struct): ditto * vm_insnhelper.c (vm_throw): ditto Modified files: trunk/ChangeLog trunk/compile.c trunk/iseq.c trunk/iseq.h trunk/vm.c trunk/vm_core.h trunk/vm_insnhelper.c Index: ChangeLog =================================================================== --- ChangeLog (revision 46810) +++ ChangeLog (revision 46811) @@ -1,3 +1,18 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Mon Jul 14 16:04:41 2014 Eric Wong <e@8...> + + * iseq.h (struct iseq_catch_table): new flexible array struct + (iseq_catch_table_bytes): allocated size function + * vm_core.h (struct rb_iseq_struct): update catch_table member + * compile.c (iseq_set_exception_table): update for struct changes + * iseq.c (iseq_free): ditto + * iseq.c (iseq_memsize): ditto + * iseq.c (rb_iseq_disasm): ditto + * iseq.c (iseq_data_to_ary): ditto + * iseq.c (rb_iseq_build_for_ruby2cext): ditto (untested) + * vm.c (vm_exec): ditto + * vm_core.h (struct rb_iseq_struct): ditto + * vm_insnhelper.c (vm_throw): ditto + Sun Jul 13 17:49:52 2014 SHIBATA Hiroshi <shibata.hiroshi@g...> * ext/openssl/ossl_cipher.c: Fix call to ciphers class method and Index: vm_core.h =================================================================== --- vm_core.h (revision 46810) +++ vm_core.h (revision 46811) @@ -274,8 +274,7 @@ struct rb_iseq_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L274 ID *arg_keyword_table; /* catch table */ - struct iseq_catch_table_entry *catch_table; - int catch_table_size; + struct iseq_catch_table *catch_table; /* for child iseq */ struct rb_iseq_struct *parent_iseq; Index: iseq.c =================================================================== --- iseq.c (revision 46810) +++ iseq.c (revision 46811) @@ -141,7 +141,9 @@ iseq_memsize(const void *ptr) https://github.com/ruby/ruby/blob/trunk/iseq.c#L141 size += iseq->iseq_size * sizeof(VALUE); size += iseq->line_info_size * sizeof(struct iseq_line_info_entry); size += iseq->local_table_size * sizeof(ID); - size += iseq->catch_table_size * sizeof(struct iseq_catch_table_entry); + if (iseq->catch_table) { + size += iseq_catch_table_bytes(iseq->catch_table->size); + } size += iseq->arg_opts * sizeof(VALUE); size += iseq->is_size * sizeof(union iseq_inline_storage_entry); size += iseq->callinfo_size * sizeof(rb_call_info_t); @@ -1400,11 +1402,11 @@ rb_iseq_disasm(VALUE self) https://github.com/ruby/ruby/blob/trunk/iseq.c#L1402 rb_str_cat2(str, "\n"); /* show catch table information */ - if (iseqdat->catch_table_size != 0) { + if (iseqdat->catch_table) { rb_str_cat2(str, "== catch table\n"); } - for (i = 0; i < iseqdat->catch_table_size; i++) { - struct iseq_catch_table_entry *entry = &iseqdat->catch_table[i]; + if (iseqdat->catch_table) for (i = 0; i < iseqdat->catch_table->size; i++) { + struct iseq_catch_table_entry *entry = &iseqdat->catch_table->entries[i]; rb_str_catf(str, "| catch type: %-6s st: %04d ed: %04d sp: %04d cont: %04d\n", catch_type((int)entry->type), (int)entry->start, @@ -1413,7 +1415,7 @@ rb_iseq_disasm(VALUE self) https://github.com/ruby/ruby/blob/trunk/iseq.c#L1415 rb_str_concat(str, rb_iseq_disasm(entry->iseq)); } } - if (iseqdat->catch_table_size != 0) { + if (iseqdat->catch_table) { rb_str_cat2(str, "|-------------------------------------" "-----------------------------------\n"); } @@ -1845,9 +1847,9 @@ iseq_data_to_ary(rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/iseq.c#L1847 nbody = body; /* exception */ - for (i=0; i<iseq->catch_table_size; i++) { + if (iseq->catch_table) for (i=0; i<iseq->catch_table->size; i++) { VALUE ary = rb_ary_new(); - struct iseq_catch_table_entry *entry = &iseq->catch_table[i]; + struct iseq_catch_table_entry *entry = &iseq->catch_table->entries[i]; rb_ary_push(ary, exception_type2symbol(entry->type)); if (entry->iseq) { rb_iseq_t *eiseq; @@ -2117,8 +2119,14 @@ rb_iseq_build_for_ruby2cext( https://github.com/ruby/ruby/blob/trunk/iseq.c#L2119 ALLOC_AND_COPY(iseq->line_info_table, line_info_table, struct iseq_line_info_entry, iseq->line_info_size); - ALLOC_AND_COPY(iseq->catch_table, catch_table, - struct iseq_catch_table_entry, iseq->catch_table_size); + /* + * FIXME: probably broken, but this function is probably unused + * and should be removed + */ + if (iseq->catch_table) { + MEMCPY(&iseq->catch_table->entries, catch_table, + struct iseq_catch_table_entry, iseq->catch_table->size); + } ALLOC_AND_COPY(iseq->arg_opt_table, arg_opt_table, VALUE, iseq->arg_opts); Index: iseq.h =================================================================== --- iseq.h (revision 46810) +++ iseq.h (revision 46811) @@ -68,6 +68,18 @@ struct iseq_catch_table_entry { https://github.com/ruby/ruby/blob/trunk/iseq.h#L68 unsigned long sp; }; +PACKED_STRUCT_UNALIGNED(struct iseq_catch_table { + int size; + struct iseq_catch_table_entry entries[1]; /* flexible array */ +}); + +static inline int +iseq_catch_table_bytes(int n) +{ + return sizeof(struct iseq_catch_table) + + (n - 1) * sizeof(struct iseq_catch_table_entry); +} + #define INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE (512) struct iseq_compile_data_storage { Index: compile.c =================================================================== --- compile.c (revision 46810) +++ compile.c (revision 46811) @@ -1681,12 +1681,15 @@ iseq_set_exception_table(rb_iseq_t *iseq https://github.com/ruby/ruby/blob/trunk/compile.c#L1681 tlen = (int)RARRAY_LEN(iseq->compile_data->catch_table_ary); tptr = RARRAY_CONST_PTR(iseq->compile_data->catch_table_ary); - iseq->catch_table = tlen ? ALLOC_N(struct iseq_catch_table_entry, tlen) : 0; - iseq->catch_table_size = tlen; + iseq->catch_table = 0; + if (tlen > 0) { + iseq->catch_table = xmalloc(iseq_catch_table_bytes(tlen)); + iseq->catch_table->size = tlen; + } - for (i = 0; i < tlen; i++) { + if (iseq->catch_table) for (i = 0; i < iseq->catch_table->size; i++) { ptr = RARRAY_CONST_PTR(tptr[i]); - entry = &iseq->catch_table[i]; + entry = &iseq->catch_table->entries[i]; entry->type = (enum catch_type)(ptr[0] & 0xffff); entry->start = label_get_position((LABEL *)(ptr[1] & ~1)); entry->end = label_get_position((LABEL *)(ptr[2] & ~1)); Index: vm.c =================================================================== --- vm.c (revision 46810) +++ vm.c (revision 46811) @@ -1383,6 +1383,7 @@ vm_exec(rb_thread_t *th) https://github.com/ruby/ruby/blob/trunk/vm.c#L1383 else { int i; struct iseq_catch_table_entry *entry; + struct iseq_catch_table *ct; unsigned long epc, cont_pc, cont_sp; VALUE catch_iseqval; rb_control_frame_t *cfp; @@ -1417,8 +1418,9 @@ vm_exec(rb_thread_t *th) https://github.com/ruby/ruby/blob/trunk/vm.c#L1418 SET_THROWOBJ_STATE(err, state = TAG_BREAK); } else { - for (i = 0; i < cfp->iseq->catch_table_size; i++) { - entry = &cfp->iseq->catch_table[i]; + ct = cfp->iseq->catch_table; + if (ct) for (i = 0; i < ct->size; i++) { + entry = &ct->entries[i]; if (entry->start < epc && entry->end >= epc) { if (entry->type == CATCH_TYPE_ENSURE) { catch_iseqval = entry->iseq; @@ -1458,8 +1460,9 @@ vm_exec(rb_thread_t *th) https://github.com/ruby/ruby/blob/trunk/vm.c#L1460 } if (state == TAG_RAISE) { - for (i = 0; i < cfp->iseq->catch_table_size; i++) { - entry = &cfp->iseq->catch_table[i]; + ct = cfp->iseq->catch_table; + if (ct) for (i = 0; i < ct->size; i++) { + entry = &ct->entries[i]; if (entry->start < epc && entry->end >= epc) { if (entry->type == CATCH_TYPE_RESCUE || @@ -1473,8 +1476,9 @@ vm_exec(rb_thread_t *th) https://github.com/ruby/ruby/blob/trunk/vm.c#L1476 } } else if (state == TAG_RETRY) { - for (i = 0; i < cfp->iseq->catch_table_size; i++) { - entry = &cfp->iseq->catch_table[i]; + ct = cfp->iseq->catch_table; + if (ct) for (i = 0; i < ct->size; i++) { + entry = &ct->entries[i]; if (entry->start < epc && entry->end >= epc) { if (entry->type == CATCH_TYPE_ENSURE) { @@ -1499,8 +1503,9 @@ vm_exec(rb_thread_t *th) https://github.com/ruby/ruby/blob/trunk/vm.c#L1503 type = CATCH_TYPE_BREAK; search_restart_point: - for (i = 0; i < cfp->iseq->catch_table_size; i++) { - entry = &cfp->iseq->catch_table[i]; + ct = cfp->iseq->catch_table; + if (ct) for (i = 0; i < ct->size; i++) { + entry = &ct->entries[i]; if (entry->start < epc && entry->end >= epc) { if (entry->type == CATCH_TYPE_ENSURE) { @@ -1536,8 +1541,9 @@ vm_exec(rb_thread_t *th) https://github.com/ruby/ruby/blob/trunk/vm.c#L1541 goto search_restart_point; } else { - for (i = 0; i < cfp->iseq->catch_table_size; i++) { - entry = &cfp->iseq->catch_table[i]; + ct = cfp->iseq->catch_table; + if (ct) for (i = 0; i < ct->size; i++) { + entry = &ct->entries[i]; if (entry->start < epc && entry->end >= epc) { if (entry->type == CATCH_TYPE_ENSURE) { Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 46810) +++ vm_insnhelper.c (revision 46811) @@ -646,10 +646,12 @@ vm_throw(rb_thread_t *th, rb_control_fra https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L646 if (cfp->ep == ep) { VALUE epc = cfp->pc - cfp->iseq->iseq_encoded; rb_iseq_t *iseq = cfp->iseq; + struct iseq_catch_table *ct = iseq->catch_table; + struct iseq_catch_table_entry *entry; int i; - for (i=0; i<iseq->catch_table_size; i++) { - struct iseq_catch_table_entry *entry = &iseq->catch_table[i]; + for (i=0; i<ct->size; i++) { + entry = &ct->entries[i]; if (entry->type == CATCH_TYPE_BREAK && entry->start < epc && entry->end >= epc) { -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/