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

ruby-changes:39822

From: ko1 <ko1@a...>
Date: Sun, 20 Sep 2015 03:00:30 +0900 (JST)
Subject: [ruby-changes:39822] ko1:r51903 (trunk): * vm_core.h: split rb_call_info_t into several structs.

ko1	2015-09-20 02:59:58 +0900 (Sun, 20 Sep 2015)

  New Revision: 51903

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=51903

  Log:
    * vm_core.h: split rb_call_info_t into several structs.
      * rb_call_info (ci) has compiled fixed information.
      * if ci->flag & VM_CALL_KWARG, then rb_call_info is
        also rb_call_info_with_kwarg. This technique reduce one word
        for major rb_call_info data.
      * rb_calling_info has temporary data (argc, blockptr, recv).
        for each method dispatch. This data is allocated only on
        machine stack.
      * rb_call_cache is for inline method cache.
      Before this patch, only rb_call_info_t data is passed.
      After this patch, above three structs are passed.
      This patch improves:
      * data locarity (rb_call_info is now read-only data).
      * reduce memory consumption (rb_call_info_with_kwarg,
        rb_calling_info).
    * compile.c: use above data.
    * insns.def: ditto.
    * iseq.c: ditto.
    * vm_args.c: ditto.
    * vm_eval.c: ditto.
    * vm_insnhelper.c: ditto.
    * vm_insnhelper.h: ditto.
    * iseq.h: add iseq_compile_data::ci_index and
      iseq_compile_data::ci_kw_indx.
    * tool/instruction.rb: introduce TS_CALLCACHE operand type.

  Modified files:
    trunk/ChangeLog
    trunk/compile.c
    trunk/insns.def
    trunk/iseq.c
    trunk/iseq.h
    trunk/tool/instruction.rb
    trunk/vm.c
    trunk/vm_args.c
    trunk/vm_core.h
    trunk/vm_eval.c
    trunk/vm_insnhelper.c
    trunk/vm_insnhelper.h
Index: insns.def
===================================================================
--- insns.def	(revision 51902)
+++ insns.def	(revision 51903)
@@ -936,14 +936,15 @@ defineclass https://github.com/ruby/ruby/blob/trunk/insns.def#L936
  */
 DEFINE_INSN
 send
-(CALL_INFO ci, ISEQ iseq)
+(CALL_INFO ci, CALL_CACHE cc, ISEQ blockiseq)
 (...)
 (VALUE val) // inc += - (int)(ci->orig_argc + ((ci->flag & VM_CALL_ARGS_BLOCKARG) ? 1 : 0));
 {
-    ci->argc = ci->orig_argc;
-    vm_caller_setup_arg_block(th, reg_cfp, ci, iseq, FALSE);
-    vm_search_method(ci, ci->recv = TOPN(ci->argc));
-    CALL_METHOD(ci);
+    struct rb_calling_info calling;
+
+    vm_caller_setup_arg_block(th, reg_cfp, &calling, ci, blockiseq, FALSE);
+    vm_search_method(ci, cc, calling.recv = TOPN(calling.argc = ci->orig_argc));
+    CALL_METHOD(&calling, ci, cc);
 }
 
 DEFINE_INSN
@@ -967,13 +968,14 @@ opt_str_freeze https://github.com/ruby/ruby/blob/trunk/insns.def#L968
  */
 DEFINE_INSN
 opt_send_without_block
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (...)
 (VALUE val) // inc += -ci->orig_argc;
 {
-    ci->argc = ci->orig_argc;
-    vm_search_method(ci, ci->recv = TOPN(ci->argc));
-    CALL_METHOD(ci);
+    struct rb_calling_info calling;
+    calling.blockptr = NULL;
+    vm_search_method(ci, cc, calling.recv = TOPN(calling.argc = ci->orig_argc));
+    CALL_METHOD(&calling, ci, cc);
 }
 
 /**
@@ -983,15 +985,17 @@ opt_send_without_block https://github.com/ruby/ruby/blob/trunk/insns.def#L985
  */
 DEFINE_INSN
 invokesuper
-(CALL_INFO ci, ISEQ iseq)
+(CALL_INFO ci, CALL_CACHE cc, ISEQ blockiseq)
 (...)
 (VALUE val) // inc += - (int)(ci->orig_argc + ((ci->flag & VM_CALL_ARGS_BLOCKARG) ? 1 : 0));
 {
-    ci->argc = ci->orig_argc;
-    vm_caller_setup_arg_block(th, reg_cfp, ci, iseq, TRUE);
-    ci->recv = GET_SELF();
-    vm_search_super_method(th, GET_CFP(), ci);
-    CALL_METHOD(ci);
+    struct rb_calling_info calling;
+    calling.argc = ci->orig_argc;
+
+    vm_caller_setup_arg_block(th, reg_cfp, &calling, ci, blockiseq, TRUE);
+    calling.recv = GET_SELF();
+    vm_search_super_method(th, GET_CFP(), &calling, ci, cc);
+    CALL_METHOD(&calling, ci, cc);
 }
 
 /**
@@ -1005,10 +1009,12 @@ invokeblock https://github.com/ruby/ruby/blob/trunk/insns.def#L1009
 (...)
 (VALUE val)  // inc += 1 - ci->orig_argc;
 {
-    ci->argc = ci->orig_argc;
-    ci->blockptr = 0;
-    ci->recv = GET_SELF();
-    val = vm_invoke_block(th, GET_CFP(), ci);
+    struct rb_calling_info calling;
+    calling.argc = ci->orig_argc;
+    calling.blockptr = NULL;
+    calling.recv = GET_SELF();
+
+    val = vm_invoke_block(th, GET_CFP(), &calling, ci);
     if (val == Qundef) {
 	RESTORE_REGS();
 	NEXT_INSN();
@@ -1260,7 +1266,7 @@ opt_case_dispatch https://github.com/ruby/ruby/blob/trunk/insns.def#L1266
  */
 DEFINE_INSN
 opt_plus
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1323,7 +1329,7 @@ opt_plus https://github.com/ruby/ruby/blob/trunk/insns.def#L1329
  */
 DEFINE_INSN
 opt_minus
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1371,7 +1377,7 @@ opt_minus https://github.com/ruby/ruby/blob/trunk/insns.def#L1377
  */
 DEFINE_INSN
 opt_mult
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1421,7 +1427,7 @@ opt_mult https://github.com/ruby/ruby/blob/trunk/insns.def#L1427
  */
 DEFINE_INSN
 opt_div
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1484,7 +1490,7 @@ opt_div https://github.com/ruby/ruby/blob/trunk/insns.def#L1490
  */
 DEFINE_INSN
 opt_mod
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1551,11 +1557,11 @@ opt_mod https://github.com/ruby/ruby/blob/trunk/insns.def#L1557
  */
 DEFINE_INSN
 opt_eq
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
-    val = opt_eq_func(recv, obj, ci);
+    val = opt_eq_func(recv, obj, ci, cc);
 
     if (val == Qundef) {
 	/* other */
@@ -1572,16 +1578,17 @@ opt_eq https://github.com/ruby/ruby/blob/trunk/insns.def#L1578
  */
 DEFINE_INSN
 opt_neq
-(CALL_INFO ci, CALL_INFO ci_eq)
+(CALL_INFO ci, CALL_CACHE cc, CALL_INFO ci_eq, CALL_CACHE cc_eq)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
     extern VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
-    vm_search_method(ci, recv);
+    vm_search_method(ci, cc, recv);
+
     val = Qundef;
 
-    if (check_cfunc(ci->me, rb_obj_not_equal)) {
-	val = opt_eq_func(recv, obj, ci_eq);
+    if (check_cfunc(cc->me, rb_obj_not_equal)) {
+	val = opt_eq_func(recv, obj, ci_eq, cc_eq);
 
 	if (val != Qundef) {
 	    val = RTEST(val) ? Qfalse : Qtrue;
@@ -1603,7 +1610,7 @@ opt_neq https://github.com/ruby/ruby/blob/trunk/insns.def#L1610
  */
 DEFINE_INSN
 opt_lt
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1647,7 +1654,7 @@ opt_lt https://github.com/ruby/ruby/blob/trunk/insns.def#L1654
  */
 DEFINE_INSN
 opt_le
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1682,7 +1689,7 @@ opt_le https://github.com/ruby/ruby/blob/trunk/insns.def#L1689
  */
 DEFINE_INSN
 opt_gt
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1726,7 +1733,7 @@ opt_gt https://github.com/ruby/ruby/blob/trunk/insns.def#L1733
  */
 DEFINE_INSN
 opt_ge
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1760,7 +1767,7 @@ opt_ge https://github.com/ruby/ruby/blob/trunk/insns.def#L1767
  */
 DEFINE_INSN
 opt_ltlt
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1792,7 +1799,7 @@ opt_ltlt https://github.com/ruby/ruby/blob/trunk/insns.def#L1799
  */
 DEFINE_INSN
 opt_aref
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1822,7 +1829,7 @@ opt_aref https://github.com/ruby/ruby/blob/trunk/insns.def#L1829
  */
 DEFINE_INSN
 opt_aset
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (VALUE recv, VALUE obj, VALUE set)
 (VALUE val)
 {
@@ -1855,7 +1862,7 @@ opt_aset https://github.com/ruby/ruby/blob/trunk/insns.def#L1862
  */
 DEFINE_INSN
 opt_aset_with
-(CALL_INFO ci, VALUE key)
+(CALL_INFO ci, CALL_CACHE cc, VALUE key)
 (VALUE recv, VALUE val)
 (VALUE val)
 {
@@ -1877,7 +1884,7 @@ opt_aset_with https://github.com/ruby/ruby/blob/trunk/insns.def#L1884
  */
 DEFINE_INSN
 opt_aref_with
-(CALL_INFO ci, VALUE key)
+(CALL_INFO ci, CALL_CACHE cc, VALUE key)
 (VALUE recv)
 (VALUE val)
 {
@@ -1898,7 +1905,7 @@ opt_aref_with https://github.com/ruby/ruby/blob/trunk/insns.def#L1905
  */
 DEFINE_INSN
 opt_length
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (VALUE recv)
 (VALUE val)
 {
@@ -1933,7 +1940,7 @@ opt_length https://github.com/ruby/ruby/blob/trunk/insns.def#L1940
  */
 DEFINE_INSN
 opt_size
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (VALUE recv)
 (VALUE val)
 {
@@ -1968,7 +1975,7 @@ opt_size https://github.com/ruby/ruby/blob/trunk/insns.def#L1975
  */
 DEFINE_INSN
 opt_empty_p
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (VALUE recv)
 (VALUE val)
 {
@@ -2006,7 +2013,7 @@ opt_empty_p https://github.com/ruby/ruby/blob/trunk/insns.def#L2013
  */
 DEFINE_INSN
 opt_succ
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (VALUE recv)
 (VALUE val)
 {
@@ -2049,14 +2056,15 @@ opt_succ https://github.com/ruby/ruby/blob/trunk/insns.def#L2056
  */
 DEFINE_INSN
 opt_not
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (VALUE recv)
 (VALUE val)
 {
     extern VALUE rb_obj_not(VALUE obj);
-    vm_search_method(ci, recv);
 
-    if (check_cfunc(ci->me, rb_obj_not)) {
+    vm_search_method(ci, cc, recv);
+
+    if (check_cfunc(cc->me, rb_obj_not)) {
 	val = RTEST(recv) ? Qfalse : Qtrue;
     }
     else {
@@ -2092,7 +2100,7 @@ opt_regexpmatch1 https://github.com/ruby/ruby/blob/trunk/insns.def#L2100
  */
 DEFINE_INSN
 opt_regexpmatch2
-(CALL_INFO ci)
+(CALL_INFO ci, CALL_CACHE cc)
 (VALUE obj2, VALUE obj1)
 (VALUE val)
 {
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 51902)
+++ ChangeLog	(revision 51903)
@@ -1,3 +1,42 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sun Sep 20 02:46:34 2015  Koichi Sasada  <ko1@a...>
+
+	* vm_core.h: split rb_call_info_t into several structs.
+	  * rb_call_info (ci) has compiled fixed information.
+	  * if ci->flag & VM_CALL_KWARG, then rb_call_info is
+	    also rb_call_info_with_kwarg. This technique reduce one word
+	    for major rb_call_info data.
+	  * rb_calling_info has temporary data (argc, blockptr, recv).
+	    for each method dispatch. This data is allocated only on
+	    machine stack.
+	  * rb_call_cache is for inline method cache.
+
+	  Before this patch, only rb_call_info_t data is passed.
+	  After this patch, above three structs are passed.
+
+	  This patch improves:
+	  * data locarity (rb_call_info is now read-only data).
+	  * reduce memory consumption (rb_call_info_with_kwarg,
+	    rb_calling_info).
+
+	* compile.c: use above data.
+
+	* insns.def: ditto.
+
+	* iseq.c: ditto.
+
+	* vm_args.c: ditto.
+
+	* vm_eval.c: ditto.
+
+	* vm_insnhelper.c: ditto.
+
+	* vm_insnhelper.h: ditto.
+
+	* iseq.h: add iseq_compile_data::ci_index and
+	  iseq_compile_data::ci_kw_indx.
+
+	* tool/instruction.rb: introduce TS_CALLCACHE operand type.
+
 Sun Sep 20 02:18:10 2015  Tanaka Akira  <akr@f...>
 
 	* test/lib/envutil.rb: mkfifo command based File.mkfifo method
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 51902)
+++ vm_core.h	(revision 51903)
@@ -173,11 +173,6 @@ union iseq_inline_storage_entry { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L173
 struct rb_thread_struct;
 struct rb_control_frame_struct;
 
-typedef struct rb_call_info_kw_arg_struct {
-    int keyword_len;
-    VALUE keywords[1];
-} rb_call_info_kw_arg_t;
-
 enum method_missing_reason {
     MISSING_NOENTRY   = 0x00,
     MISSING_PRIVATE   = 0x01,
@@ -188,14 +183,30 @@ enum method_missing_reason { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L183
     MISSING_NONE      = 0x20
 };
 
-/* rb_call_info_t contains calling information including inline cache */
-typedef struct rb_call_info_struct {
+struct rb_call_info {
     /* fixed at compile time */
     ID mid;
     unsigned int flag;
     int orig_argc;
-    const rb_call_info_kw_arg_t *kw_arg;
+};
+
+struct rb_call_info_kw_arg {
+    int keyword_len;
+    VALUE keywords[1];
+};
+
+struct rb_call_info_with_kwarg {
+    struct rb_call_info ci;
+    struct rb_call_info_kw_arg *kw_arg;
+};
+
+struct rb_calling_info {
+    struct rb_block_struct *blockptr;
+    VALUE recv;
+    int argc;
+};
 
+struct rb_call_cache {
     /* inline cache: keys */
     rb_serial_t method_state;
     rb_serial_t class_serial;
@@ -203,18 +214,14 @@ typedef struct rb_call_info_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L214
     /* inline cache: values */
     const rb_callable_method_entry_t *me;
 
-    /* temporary values for method calling */
-    struct rb_block_struct *blockptr;
-    VALUE recv;
-    int argc;
+    VALUE (*call)(struct rb_thread_struct *th, struct rb_control_frame_struct *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc);
+
     union {
 	unsigned int index; /* used by ivar */
 	enum method_missing_reason method_missing_reason; /* used by method_missing */
 	int inc_sp; /* used by cfunc */
     } aux;
-
-    VALUE (*call)(struct rb_thread_struct *th, struct rb_control_frame_struct *cfp, struct rb_call_info_struct *ci);
-} rb_call_info_t;
+};
 
 #if 1
 #define GetCoreDataFromValue(obj, type, ptr) do { \
@@ -337,12 +344,19 @@ struct rb_iseq_constant_body { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L344
     struct rb_iseq_struct *local_iseq; /* local_iseq->flip_cnt can be modified */
 
     union iseq_inline_storage_entry *is_entries;
-    rb_call_info_t *callinfo_entries;
+    struct rb_call_info *ci_entries; /* struct rb_call_info ci_entries[ci_size];
+				      * struct rb_call_info_with_kwarg cikw_entries[ci_kw_size];
+				      * So that:
+				      * struct rb_call_info_with_kwarg *cikw_entries = &body->ci_entries[ci_size];
+				      */
+    struct rb_call_cache *cc_entries; /* size is ci_size = ci_kw_size */
+
     const VALUE mark_ary;     /* Array: includes operands which should be GC marked */
 
     unsigned int local_table_size;
     unsigned int is_size;
-    unsigned int callinfo_size;
+    unsigned int ci_size;
+    unsigned int ci_kw_size;
     unsigned int line_info_size;
 };
 
@@ -632,7 +646,7 @@ typedef struct rb_thread_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L646
     const rb_callable_method_entry_t *passed_bmethod_me;
 
     /* for cfunc */
-    rb_call_info_t *passed_ci;
+    struct rb_calling_info *calling;
 
     /* for load(true) */
     VALUE top_self;
@@ -827,14 +841,16 @@ enum vm_check_match_type { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L841
 #define VM_CHECKMATCH_TYPE_MASK   0x03
 #define VM_CHECKMATCH_ARRAY       0x04
 
-#define VM_CALL_ARGS_SPLAT      (0x01 << 1) /* m(*args) */
-#define VM_CALL_ARGS_BLOCKARG   (0x01 << 2) /* m(&block) */
-#define VM_CALL_FCALL           (0x01 << 3) /* m(...) */
-#define VM_CALL_VCALL           (0x01 << 4) /* m */
-#define VM_CALL_TAILCALL        (0x01 << 5) /* located at tail position */
-#define VM_CALL_SUPER           (0x01 << 6) /* super */
-#define VM_CALL_OPT_SEND        (0x01 << 7) /* internal flag */
-#define VM_CALL_ARGS_SIMPLE     (0x01 << 8) /* (ci->flag & (SPLAT|BLOCKARG)) && blockiseq == NULL && ci->kw_arg == NULL */
+#define VM_CALL_ARGS_SPLAT      (0x01 << 0) /* m(*args) */
+#define VM_CALL_ARGS_BLOCKARG   (0x01 << 1) /* m(&block) */
+#define VM_CALL_FCALL           (0x01 << 2) /* m(...) */
+#define VM_CALL_VCALL           (0x01 << 3) /* m */
+#define VM_CALL_ARGS_SIMPLE     (0x01 << 4) /* (ci->flag & (SPLAT|BLOCKARG)) && blockiseq == NULL && ci->kw_arg == NULL */
+#define VM_CALL_BLOCKISEQ       (0x01 << 5) /* has blockiseq */
+#define VM_CALL_KWARG           (0x01 << 6) /* has kwarg */
+#define VM_CALL_TAILCALL        (0x01 << 7) /* located at tail position */
+#define VM_CALL_SUPER           (0x01 << 8) /* super */
+#define VM_CALL_OPT_SEND        (0x01 << 9) /* internal flag */
 
 enum vm_special_object_type {
     VM_SPECIAL_OBJECT_VMCORE = 1,
@@ -878,7 +894,8 @@ enum vm_svar_index { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L894
 
 /* inline cache */
 typedef struct iseq_inline_cache_entry *IC;
-typedef rb_call_info_t *CALL_INFO;
+typedef struct rb_call_info *CALL_INFO;
+typedef struct rb_call_cache *CALL_CACHE;
 
 void rb_vm_change_state(void);
 
Index: iseq.c
===================================================================
--- iseq.c	(revision 51902)
+++ iseq.c	(revision 51903)
@@ -74,14 +74,14 @@ rb_iseq_free(const rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/iseq.c#L74
 	ruby_xfree((void *)iseq->body->local_table);
 	ruby_xfree((void *)iseq->body->is_entries);
 
-	if (iseq->body->callinfo_entries) {
+	if (iseq->body->ci_entries) {
 	    unsigned int i;
-	    for (i=0; i<iseq->body->callinfo_size; i++) {
-		/* TODO: revisit callinfo data structure */
-		const rb_call_info_kw_arg_t *kw_arg = iseq->body->callinfo_entries[i].kw_arg;
+	    struct rb_call_info_with_kwarg *ci_kw_entries = (struct rb_call_info_with_kwarg *)&iseq->body->ci_entries[iseq->body->ci_size];
+	    for (i=0; i<iseq->body->ci_kw_size; i++) {
+		const struct rb_call_info_kw_arg *kw_arg = ci_kw_entries[i].kw_arg;
 		ruby_xfree((void *)kw_arg);
 	    }
-	    ruby_xfree(iseq->body->callinfo_entries);
+	    ruby_xfree(iseq->body->ci_entries);
 	}
 	ruby_xfree((void *)iseq->body->catch_table);
 	ruby_xfree((void *)iseq->body->param.opt_table);
@@ -161,7 +161,7 @@ iseq_memsize(const rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/iseq.c#L161
     }
 
     if (body) {
-	rb_call_info_t *ci_entries = body->callinfo_entries;
+	struct rb_call_info_with_kwarg *ci_kw_entries = (struct rb_call_info_with_kwarg *)&body->ci_entries[body->ci_size];
 
 	size += sizeof(struct rb_iseq_constant_body);
 	size += body->iseq_size * sizeof(VALUE);
@@ -173,13 +173,14 @@ iseq_memsize(const rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/iseq.c#L173
 	size += (body->param.opt_num + 1) * sizeof(VALUE);
 	size += param_keyword_size(body->param.keyword);
 	size += body->is_size * sizeof(union iseq_inline_storage_entry);
-	size += body->callinfo_size * sizeof(rb_call_info_t);
+	size += body->ci_size * sizeof(struct rb_call_info);
+	size += body->ci_kw_size * sizeof(struct rb_call_info_with_kwarg);
 
-	if (ci_entries) {
+	if (ci_kw_entries) {
 	    unsigned int i;
 
-	    for (i = 0; i < body->callinfo_size; i++) {
-		const rb_call_info_kw_arg_t *kw_arg = ci_entries[i].kw_arg;
+	    for (i = 0; i < body->ci_kw_size; i++) {
+		const struct rb_call_info_kw_arg *kw_arg = ci_kw_entries[i].kw_arg;
 
 		if (kw_arg) {
 		    size += rb_call_info_kw_arg_bytes(kw_arg->keyword_len);
@@ -1267,7 +1268,7 @@ rb_insn_operand_intern(const rb_iseq_t * https://github.com/ruby/ruby/blob/trunk/iseq.c#L1268
 
       case TS_CALLINFO:
 	{
-	    rb_call_info_t *ci = (rb_call_info_t *)op;
+	    struct rb_call_info *ci = (struct rb_call_info *)op;
 	    VALUE ary = rb_ary_new();
 
 	    if (ci->mid) {
@@ -1276,8 +1277,8 @@ rb_insn_operand_intern(const rb_iseq_t * https://github.com/ruby/ruby/blob/trunk/iseq.c#L1277
 
 	    rb_ary_push(ary, rb_sprintf("argc:%d", ci->orig_argc));
 
-	    if (ci->kw_arg) {
-		rb_ary_push(ary, rb_sprintf("kw:%d", ci->kw_arg->keyword_len));
+	    if (ci->flag & VM_CALL_KWARG) {
+		rb_ary_push(ary, rb_sprintf("kw:%d", ((struct rb_call_info_with_kwarg *)ci)->kw_arg->keyword_len));
 	    }
 
 	    if (ci->flag) {
@@ -1288,6 +1289,7 @@ rb_insn_operand_intern(const rb_iseq_t * https://github.com/ruby/ruby/blob/trunk/iseq.c#L1289
 		if (ci->flag & VM_CALL_VCALL) rb_ary_push(flags, rb_str_new2("VCALL"));
 		if (ci->flag & VM_CALL_TAILCALL) rb_ary_push(flags, rb_str_new2("TAILCALL"));
 		if (ci->flag & VM_CALL_SUPER) rb_ary_push(flags, rb_str_new2("SUPER"));
+		if (ci->flag & VM_CALL_KWARG) rb_ary_push(flags, rb_str_new2("KWARG"));
 		if (ci->flag & VM_CALL_OPT_SEND) rb_ary_push(flags, rb_str_new2("SNED")); /* maybe not reachable */
 		if (ci->flag & VM_CALL_ARGS_SIMPLE) rb_ary_push(flags, rb_str_new2("ARGS_SIMPLE")); /* maybe not reachable */
 		rb_ary_push(ary, rb_ary_join(flags, rb_str_new2("|")));
@@ -1296,6 +1298,10 @@ rb_insn_operand_intern(const rb_iseq_t * https://github.com/ruby/ruby/blob/trunk/iseq.c#L1298
 	}
 	break;
 
+      case TS_CALLCACHE:
+	ret = rb_str_new2("<callcache>");
+	break;
+
       case TS_CDHASH:
 	ret = rb_str_new2("<cdhash>");
 	break;
@@ -1883,20 +1889,21 @@ iseq_data_to_ary(const rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/iseq.c#L1889
 		break;
 	      case TS_CALLINFO:
 		{
-		    rb_call_info_t *ci = (rb_call_info_t *)*seq;
+		    struct rb_call_info *ci = (struct rb_call_info *)*seq;
 		    VALUE e = rb_hash_new();
 		    int orig_argc = ci->orig_argc;
 
 		    rb_hash_aset(e, ID2SYM(rb_intern("mid")), ci->mid ? ID2SYM(ci->mid) : Qnil);
 		    rb_hash_aset(e, ID2SYM(rb_intern("flag")), UINT2NUM(ci->flag));
 
-		    if (ci->kw_arg) {
+		    if (ci->flag & VM_CALL_KWARG) {
+			struct rb_call_info_with_kwarg *ci_kw = (struct rb_call_info_with_kwarg *)ci;
 			int i;
-			VALUE kw = rb_ary_new2((long)ci->kw_arg->keyword_len);
+			VALUE kw = rb_ary_new2((long)ci_kw->kw_arg->keyword_len);
 
-			orig_argc -= ci->kw_arg->keyword_len;
-			for (i = 0; i < ci->kw_arg->keyword_len; i++) {
-			    rb_ary_push(kw, ci->kw_arg->keywords[i]);
+			orig_argc -= ci_kw->kw_arg->keyword_len;
+			for (i = 0; i < ci_kw->kw_arg->keyword_len; i++) {
+			    rb_ary_push(kw, ci_kw->kw_arg->keywords[i]);
 			}
 			rb_hash_aset(e, ID2SYM(rb_intern("kw_arg")), kw);
 		    }
@@  (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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