[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]