summaryrefslogtreecommitdiff
path: root/vm_core.h
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-09-19 17:59:58 (GMT)
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-09-19 17:59:58 (GMT)
commitd5ec9ec308dccaeea2a723e070a98df4159183de (patch)
tree465a1a57742997ec96f6b248b24604db92028efe /vm_core.h
parent19499aaeb12b7ea936c871593bf45d842e3d2970 (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.h71
1 files changed, 44 insertions, 27 deletions
diff --git a/vm_core.h b/vm_core.h
index 4b7d946..f9e4f04 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -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);