diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-09-19 17:59:58 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-09-19 17:59:58 +0000 |
commit | d5ec9ec308dccaeea2a723e070a98df4159183de (patch) | |
tree | 465a1a57742997ec96f6b248b24604db92028efe /vm_core.h | |
parent | 19499aaeb12b7ea936c871593bf45d842e3d2970 (diff) |
* 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.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51903 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_core.h')
-rw-r--r-- | vm_core.h | 71 |
1 files changed, 44 insertions, 27 deletions
@@ -173,11 +173,6 @@ union iseq_inline_storage_entry { 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 { 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 { /* 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 { 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 { 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 { #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 { /* 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); |