mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* vm_core.h (rb_call_info_t): add new type `rb_call_inf_t'.
This data structure contains information including inline method cache. After that, `struct iseq_inline_cache_entry' does not need to contain inline cache for method invocation. Other information will be added to this data structure. * vm_core.h (rb_iseq_t): add `callinfo_entries' and `callinfo_size' members to `rb_iseq_t'. * insns.def, compile.c: Use CALL_INFO instead of IC. * tool/instruction.rb: support CALL_INFO as operand type. * vm_insnhelper.c, vm_insnhelper.h: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37121 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
4be0c562a4
commit
7ea3edc409
7 changed files with 107 additions and 51 deletions
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
||||||
|
Tue Oct 9 14:28:18 2012 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* vm_core.h (rb_call_info_t): add new type `rb_call_inf_t'.
|
||||||
|
This data structure contains information including inline method
|
||||||
|
cache. After that, `struct iseq_inline_cache_entry' does not
|
||||||
|
need to contain inline cache for method invocation.
|
||||||
|
Other information will be added to this data structure.
|
||||||
|
|
||||||
|
* vm_core.h (rb_iseq_t): add `callinfo_entries' and `callinfo_size'
|
||||||
|
members to `rb_iseq_t'.
|
||||||
|
|
||||||
|
* insns.def, compile.c: Use CALL_INFO instead of IC.
|
||||||
|
|
||||||
|
* tool/instruction.rb: support CALL_INFO as operand type.
|
||||||
|
|
||||||
|
* vm_insnhelper.c, vm_insnhelper.h: ditto.
|
||||||
|
|
||||||
Sun Oct 7 23:54:33 2012 CHIKANAGA Tomoyuki <nagachika@ruby-lang.org>
|
Sun Oct 7 23:54:33 2012 CHIKANAGA Tomoyuki <nagachika@ruby-lang.org>
|
||||||
|
|
||||||
* ext/zlib/zlib.c (zstream_run_func): don't call inflate() when
|
* ext/zlib/zlib.c (zstream_run_func): don't call inflate() when
|
||||||
|
|
32
compile.c
32
compile.c
|
@ -946,7 +946,7 @@ new_insn_send(rb_iseq_t *iseq, int line_no,
|
||||||
operands[1] = argc;
|
operands[1] = argc;
|
||||||
operands[2] = block;
|
operands[2] = block;
|
||||||
operands[3] = flag;
|
operands[3] = flag;
|
||||||
operands[4] = INT2FIX(iseq->ic_size++);
|
operands[4] = INT2FIX(iseq->callinfo_size++);
|
||||||
iobj = new_insn_core(iseq, line_no, BIN(send), 5, operands);
|
iobj = new_insn_core(iseq, line_no, BIN(send), 5, operands);
|
||||||
return iobj;
|
return iobj;
|
||||||
}
|
}
|
||||||
|
@ -1398,6 +1398,8 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
|
||||||
line_info_table = ALLOC_N(struct iseq_line_info_entry, k);
|
line_info_table = ALLOC_N(struct iseq_line_info_entry, k);
|
||||||
iseq->ic_entries = ALLOC_N(struct iseq_inline_cache_entry, iseq->ic_size);
|
iseq->ic_entries = ALLOC_N(struct iseq_inline_cache_entry, iseq->ic_size);
|
||||||
MEMZERO(iseq->ic_entries, struct iseq_inline_cache_entry, iseq->ic_size);
|
MEMZERO(iseq->ic_entries, struct iseq_inline_cache_entry, iseq->ic_size);
|
||||||
|
iseq->callinfo_entries = ALLOC_N(rb_call_info_t, iseq->callinfo_size);
|
||||||
|
MEMZERO(iseq->callinfo_entries, rb_call_info_t, iseq->callinfo_size);
|
||||||
|
|
||||||
list = FIRST_ELEMENT(anchor);
|
list = FIRST_ELEMENT(anchor);
|
||||||
k = pos = sp = 0;
|
k = pos = sp = 0;
|
||||||
|
@ -1495,12 +1497,21 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
|
||||||
int ic_index = FIX2INT(operands[j]);
|
int ic_index = FIX2INT(operands[j]);
|
||||||
IC ic = &iseq->ic_entries[ic_index];
|
IC ic = &iseq->ic_entries[ic_index];
|
||||||
if (UNLIKELY(ic_index >= iseq->ic_size)) {
|
if (UNLIKELY(ic_index >= iseq->ic_size)) {
|
||||||
rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d",
|
rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d", ic_index, iseq->ic_size);
|
||||||
ic_index, iseq->ic_size);
|
|
||||||
}
|
}
|
||||||
generated_iseq[pos + 1 + j] = (VALUE)ic;
|
generated_iseq[pos + 1 + j] = (VALUE)ic;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case TS_CALLINFO: /* call info */
|
||||||
|
{
|
||||||
|
int ci_index = FIX2INT(operands[j]);
|
||||||
|
CALL_INFO ci = &iseq->callinfo_entries[ci_index];
|
||||||
|
if (UNLIKELY(ci_index >= iseq->callinfo_size)) {
|
||||||
|
rb_bug("iseq_set_sequence: ci_index overflow: index: %d, size: %d", ci_index, iseq->callinfo_size);
|
||||||
|
}
|
||||||
|
generated_iseq[pos + 1 + j] = (VALUE)ci;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case TS_ID: /* ID */
|
case TS_ID: /* ID */
|
||||||
generated_iseq[pos + 1 + j] = SYM2ID(operands[j]);
|
generated_iseq[pos + 1 + j] = SYM2ID(operands[j]);
|
||||||
break;
|
break;
|
||||||
|
@ -1859,7 +1870,7 @@ insn_set_specialized_instruction(rb_iseq_t *iseq, INSN *iobj, int insn_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<iobj->operand_size; i++) {
|
for (i=0; i<iobj->operand_size; i++) {
|
||||||
iobj->operands[i] = INT2FIX(iseq->ic_size++);
|
iobj->operands[i] = INT2FIX(iseq->callinfo_size++);
|
||||||
}
|
}
|
||||||
|
|
||||||
return COMPILE_OK;
|
return COMPILE_OK;
|
||||||
|
@ -5234,9 +5245,12 @@ insn_data_to_s_detail(INSN *iobj)
|
||||||
(OPERAND_AT(iobj, j) & (~1));
|
(OPERAND_AT(iobj, j) & (~1));
|
||||||
rb_str_cat2(str, rb_id2name(entry->id));
|
rb_str_cat2(str, rb_id2name(entry->id));
|
||||||
}
|
}
|
||||||
case TS_IC: /* method cache */
|
case TS_IC: /* inline cache */
|
||||||
rb_str_catf(str, "<ic:%d>", FIX2INT(OPERAND_AT(iobj, j)));
|
rb_str_catf(str, "<ic:%d>", FIX2INT(OPERAND_AT(iobj, j)));
|
||||||
break;
|
break;
|
||||||
|
case TS_CALLINFO: /* call info */
|
||||||
|
rb_str_catf(str, "<callinfo:%d>", FIX2INT(OPERAND_AT(iobj, j)));
|
||||||
|
break;
|
||||||
case TS_CDHASH: /* case/when condition cache */
|
case TS_CDHASH: /* case/when condition cache */
|
||||||
rb_str_cat2(str, "<ch>");
|
rb_str_cat2(str, "<ch>");
|
||||||
break;
|
break;
|
||||||
|
@ -5500,9 +5514,15 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
|
||||||
break;
|
break;
|
||||||
case TS_IC:
|
case TS_IC:
|
||||||
argv[j] = op;
|
argv[j] = op;
|
||||||
if (NUM2INT(op) >= iseq->ic_size)
|
if (NUM2INT(op) >= iseq->ic_size) {
|
||||||
iseq->ic_size = NUM2INT(op) + 1;
|
iseq->ic_size = NUM2INT(op) + 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
case TS_CALLINFO:
|
||||||
|
argv[j] = op;
|
||||||
|
if (NUM2INT(op) >= iseq->callinfo_size) {
|
||||||
|
iseq->callinfo_size = NUM2INT(op) + 1;
|
||||||
|
}
|
||||||
case TS_ID:
|
case TS_ID:
|
||||||
argv[j] = rb_convert_type(op, T_SYMBOL,
|
argv[j] = rb_convert_type(op, T_SYMBOL,
|
||||||
"Symbol", "to_sym");
|
"Symbol", "to_sym");
|
||||||
|
|
50
insns.def
50
insns.def
|
@ -963,7 +963,7 @@ defineclass
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
send
|
send
|
||||||
(ID op_id, rb_num_t op_argc, ISEQ blockiseq, rb_num_t op_flag, IC ic)
|
(ID op_id, rb_num_t op_argc, ISEQ blockiseq, rb_num_t op_flag, CALL_INFO ci)
|
||||||
(...)
|
(...)
|
||||||
(VALUE val) // inc += - (int)(op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));
|
(VALUE val) // inc += - (int)(op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));
|
||||||
{
|
{
|
||||||
|
@ -978,7 +978,7 @@ send
|
||||||
/* get receiver */
|
/* get receiver */
|
||||||
recv = TOPN(num);
|
recv = TOPN(num);
|
||||||
klass = CLASS_OF(recv);
|
klass = CLASS_OF(recv);
|
||||||
me = vm_method_search(id, klass, ic, &defined_class);
|
me = vm_method_search(id, klass, ci, &defined_class);
|
||||||
CALL_METHOD(num, blockptr, flag, id, me, recv, defined_class);
|
CALL_METHOD(num, blockptr, flag, id, me, recv, defined_class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1286,7 +1286,7 @@ opt_case_dispatch
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_plus
|
opt_plus
|
||||||
(IC ic)
|
(CALL_INFO ci)
|
||||||
(VALUE recv, VALUE obj)
|
(VALUE recv, VALUE obj)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
|
@ -1349,7 +1349,7 @@ opt_plus
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_minus
|
opt_minus
|
||||||
(IC ic)
|
(CALL_INFO ci)
|
||||||
(VALUE recv, VALUE obj)
|
(VALUE recv, VALUE obj)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
|
@ -1397,7 +1397,7 @@ opt_minus
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_mult
|
opt_mult
|
||||||
(IC ic)
|
(CALL_INFO ci)
|
||||||
(VALUE recv, VALUE obj)
|
(VALUE recv, VALUE obj)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
|
@ -1450,7 +1450,7 @@ opt_mult
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_div
|
opt_div
|
||||||
(IC ic)
|
(CALL_INFO ci)
|
||||||
(VALUE recv, VALUE obj)
|
(VALUE recv, VALUE obj)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
|
@ -1513,7 +1513,7 @@ opt_div
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_mod
|
opt_mod
|
||||||
(IC ic)
|
(CALL_INFO ci)
|
||||||
(VALUE recv, VALUE obj)
|
(VALUE recv, VALUE obj)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
|
@ -1577,11 +1577,11 @@ opt_mod
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_eq
|
opt_eq
|
||||||
(IC ic)
|
(CALL_INFO ci)
|
||||||
(VALUE recv, VALUE obj)
|
(VALUE recv, VALUE obj)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
val = opt_eq_func(recv, obj, ic);
|
val = opt_eq_func(recv, obj, ci);
|
||||||
|
|
||||||
if (val == Qundef) {
|
if (val == Qundef) {
|
||||||
/* other */
|
/* other */
|
||||||
|
@ -1598,16 +1598,16 @@ opt_eq
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_neq
|
opt_neq
|
||||||
(IC ic, IC ic_eq)
|
(CALL_INFO ci, CALL_INFO ci_eq)
|
||||||
(VALUE recv, VALUE obj)
|
(VALUE recv, VALUE obj)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
extern VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
|
extern VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
|
||||||
const rb_method_entry_t *me = vm_method_search(idNeq, CLASS_OF(recv), ic, 0);
|
const rb_method_entry_t *me = vm_method_search(idNeq, CLASS_OF(recv), ci, 0);
|
||||||
val = Qundef;
|
val = Qundef;
|
||||||
|
|
||||||
if (check_cfunc(me, rb_obj_not_equal)) {
|
if (check_cfunc(me, rb_obj_not_equal)) {
|
||||||
val = opt_eq_func(recv, obj, ic_eq);
|
val = opt_eq_func(recv, obj, ci_eq);
|
||||||
|
|
||||||
if (val != Qundef) {
|
if (val != Qundef) {
|
||||||
val = RTEST(val) ? Qfalse : Qtrue;
|
val = RTEST(val) ? Qfalse : Qtrue;
|
||||||
|
@ -1629,7 +1629,7 @@ opt_neq
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_lt
|
opt_lt
|
||||||
(IC ic)
|
(CALL_INFO ci)
|
||||||
(VALUE recv, VALUE obj)
|
(VALUE recv, VALUE obj)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
|
@ -1673,7 +1673,7 @@ opt_lt
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_le
|
opt_le
|
||||||
(IC ic)
|
(CALL_INFO ci)
|
||||||
(VALUE recv, VALUE obj)
|
(VALUE recv, VALUE obj)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
|
@ -1708,7 +1708,7 @@ opt_le
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_gt
|
opt_gt
|
||||||
(IC ic)
|
(CALL_INFO ci)
|
||||||
(VALUE recv, VALUE obj)
|
(VALUE recv, VALUE obj)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
|
@ -1752,7 +1752,7 @@ opt_gt
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_ge
|
opt_ge
|
||||||
(IC ic)
|
(CALL_INFO ci)
|
||||||
(VALUE recv, VALUE obj)
|
(VALUE recv, VALUE obj)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
|
@ -1786,7 +1786,7 @@ opt_ge
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_ltlt
|
opt_ltlt
|
||||||
(IC ic)
|
(CALL_INFO ci)
|
||||||
(VALUE recv, VALUE obj)
|
(VALUE recv, VALUE obj)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
|
@ -1818,7 +1818,7 @@ opt_ltlt
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_aref
|
opt_aref
|
||||||
(IC ic)
|
(CALL_INFO ci)
|
||||||
(VALUE recv, VALUE obj)
|
(VALUE recv, VALUE obj)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
|
@ -1848,7 +1848,7 @@ opt_aref
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_aset
|
opt_aset
|
||||||
(IC ic)
|
(CALL_INFO ci)
|
||||||
(VALUE recv, VALUE obj, VALUE set)
|
(VALUE recv, VALUE obj, VALUE set)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
|
@ -1881,7 +1881,7 @@ opt_aset
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_length
|
opt_length
|
||||||
(IC ic)
|
(CALL_INFO ci)
|
||||||
(VALUE recv)
|
(VALUE recv)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
|
@ -1916,7 +1916,7 @@ opt_length
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_size
|
opt_size
|
||||||
(IC ic)
|
(CALL_INFO ci)
|
||||||
(VALUE recv)
|
(VALUE recv)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
|
@ -1951,7 +1951,7 @@ opt_size
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_empty_p
|
opt_empty_p
|
||||||
(IC ic)
|
(CALL_INFO ci)
|
||||||
(VALUE recv)
|
(VALUE recv)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
|
@ -1989,7 +1989,7 @@ opt_empty_p
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_succ
|
opt_succ
|
||||||
(IC ic)
|
(CALL_INFO ci)
|
||||||
(VALUE recv)
|
(VALUE recv)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
|
@ -2036,12 +2036,12 @@ opt_succ
|
||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
opt_not
|
opt_not
|
||||||
(IC ic)
|
(CALL_INFO ci)
|
||||||
(VALUE recv)
|
(VALUE recv)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
extern VALUE rb_obj_not(VALUE obj);
|
extern VALUE rb_obj_not(VALUE obj);
|
||||||
const rb_method_entry_t *me = vm_method_search(idNot, CLASS_OF(recv), ic, 0);
|
const rb_method_entry_t *me = vm_method_search(idNot, CLASS_OF(recv), ci, 0);
|
||||||
|
|
||||||
if (check_cfunc(me, rb_obj_not)) {
|
if (check_cfunc(me, rb_obj_not)) {
|
||||||
val = RTEST(recv) ? Qfalse : Qtrue;
|
val = RTEST(recv) ? Qfalse : Qtrue;
|
||||||
|
|
|
@ -706,10 +706,13 @@ class RubyVM
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# skip make operands when body has no reference to this operand
|
||||||
|
# TODO: really needed?
|
||||||
re = /\b#{var}\b/n
|
re = /\b#{var}\b/n
|
||||||
if re =~ insn.body or re =~ insn.sp_inc or insn.rets.any?{|t, v| re =~ v} or re =~ 'ic'
|
if re =~ insn.body or re =~ insn.sp_inc or insn.rets.any?{|t, v| re =~ v} or re =~ 'ic' or re =~ 'ci'
|
||||||
ops << " #{type} #{var} = (#{type})GET_OPERAND(#{i+1});"
|
ops << " #{type} #{var} = (#{type})GET_OPERAND(#{i+1});"
|
||||||
end
|
end
|
||||||
|
|
||||||
n += 1
|
n += 1
|
||||||
}
|
}
|
||||||
@opn = n
|
@opn = n
|
||||||
|
@ -938,6 +941,8 @@ class RubyVM
|
||||||
"TS_GENTRY"
|
"TS_GENTRY"
|
||||||
when /^IC/
|
when /^IC/
|
||||||
"TS_IC"
|
"TS_IC"
|
||||||
|
when /^CALL_INFO/
|
||||||
|
"TS_CALLINFO"
|
||||||
when /^\.\.\./
|
when /^\.\.\./
|
||||||
"TS_VARIABLE"
|
"TS_VARIABLE"
|
||||||
when /^CDHASH/
|
when /^CDHASH/
|
||||||
|
@ -958,7 +963,8 @@ class RubyVM
|
||||||
'TS_VALUE' => 'V',
|
'TS_VALUE' => 'V',
|
||||||
'TS_ID' => 'I',
|
'TS_ID' => 'I',
|
||||||
'TS_GENTRY' => 'G',
|
'TS_GENTRY' => 'G',
|
||||||
'TS_IC' => 'C',
|
'TS_IC' => 'K',
|
||||||
|
'TS_CALLINFO' => 'C',
|
||||||
'TS_CDHASH' => 'H',
|
'TS_CDHASH' => 'H',
|
||||||
'TS_ISEQ' => 'S',
|
'TS_ISEQ' => 'S',
|
||||||
'TS_VARIABLE' => '.',
|
'TS_VARIABLE' => '.',
|
||||||
|
|
19
vm_core.h
19
vm_core.h
|
@ -134,14 +134,21 @@ struct iseq_inline_cache_entry {
|
||||||
VALUE ic_class;
|
VALUE ic_class;
|
||||||
union {
|
union {
|
||||||
VALUE value;
|
VALUE value;
|
||||||
rb_method_entry_t *method;
|
|
||||||
long index;
|
long index;
|
||||||
} ic_value;
|
} ic_value;
|
||||||
union {
|
|
||||||
VALUE defined_class;
|
|
||||||
} ic_value2;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* rb_call_info_t contains calling information including inline cache */
|
||||||
|
typedef struct rb_call_info_struct {
|
||||||
|
/* inline cache: keys */
|
||||||
|
VALUE ic_vmstat;
|
||||||
|
VALUE ic_class;
|
||||||
|
|
||||||
|
/* inline cache: values */
|
||||||
|
rb_method_entry_t *method;
|
||||||
|
VALUE defined_class;
|
||||||
|
} rb_call_info_t;
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
#define GetCoreDataFromValue(obj, type, ptr) do { \
|
#define GetCoreDataFromValue(obj, type, ptr) do { \
|
||||||
(ptr) = (type*)DATA_PTR(obj); \
|
(ptr) = (type*)DATA_PTR(obj); \
|
||||||
|
@ -201,6 +208,9 @@ struct rb_iseq_struct {
|
||||||
struct iseq_inline_cache_entry *ic_entries;
|
struct iseq_inline_cache_entry *ic_entries;
|
||||||
int ic_size;
|
int ic_size;
|
||||||
|
|
||||||
|
rb_call_info_t *callinfo_entries;
|
||||||
|
int callinfo_size;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* argument information
|
* argument information
|
||||||
*
|
*
|
||||||
|
@ -661,6 +671,7 @@ enum vm_special_object_type {
|
||||||
|
|
||||||
/* inline cache */
|
/* inline cache */
|
||||||
typedef struct iseq_inline_cache_entry *IC;
|
typedef struct iseq_inline_cache_entry *IC;
|
||||||
|
typedef rb_call_info_t *CALL_INFO;
|
||||||
|
|
||||||
void rb_vm_change_state(void);
|
void rb_vm_change_state(void);
|
||||||
|
|
||||||
|
|
|
@ -1430,25 +1430,27 @@ vm_setivar(VALUE obj, ID id, VALUE val, IC ic)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const rb_method_entry_t *
|
static inline const rb_method_entry_t *
|
||||||
vm_method_search(VALUE id, VALUE klass, IC ic, VALUE *defined_class_ptr)
|
vm_method_search(VALUE id, VALUE klass, CALL_INFO ci, VALUE *defined_class_ptr)
|
||||||
{
|
{
|
||||||
rb_method_entry_t *me;
|
rb_method_entry_t *me;
|
||||||
#if OPT_INLINE_METHOD_CACHE
|
#if OPT_INLINE_METHOD_CACHE
|
||||||
if (LIKELY(klass == ic->ic_class &&
|
if (LIKELY(klass == ci->ic_class &&
|
||||||
GET_VM_STATE_VERSION() == ic->ic_vmstat)) {
|
GET_VM_STATE_VERSION() == ci->ic_vmstat)) {
|
||||||
me = ic->ic_value.method;
|
me = ci->method;
|
||||||
if (defined_class_ptr)
|
if (defined_class_ptr) {
|
||||||
*defined_class_ptr = ic->ic_value2.defined_class;
|
*defined_class_ptr = ci->defined_class;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VALUE defined_class;
|
VALUE defined_class;
|
||||||
me = rb_method_entry(klass, id, &defined_class);
|
me = rb_method_entry(klass, id, &defined_class);
|
||||||
if (defined_class_ptr)
|
if (defined_class_ptr) {
|
||||||
*defined_class_ptr = defined_class;
|
*defined_class_ptr = defined_class;
|
||||||
ic->ic_class = klass;
|
}
|
||||||
ic->ic_value.method = me;
|
ci->ic_class = klass;
|
||||||
ic->ic_value2.defined_class = defined_class;
|
ci->method = me;
|
||||||
ic->ic_vmstat = GET_VM_STATE_VERSION();
|
ci->defined_class = defined_class;
|
||||||
|
ci->ic_vmstat = GET_VM_STATE_VERSION();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
me = rb_method_entry(klass, id, defined_class_ptr);
|
me = rb_method_entry(klass, id, defined_class_ptr);
|
||||||
|
@ -1773,7 +1775,7 @@ static
|
||||||
inline
|
inline
|
||||||
#endif
|
#endif
|
||||||
VALUE
|
VALUE
|
||||||
opt_eq_func(VALUE recv, VALUE obj, IC ic)
|
opt_eq_func(VALUE recv, VALUE obj, CALL_INFO ci)
|
||||||
{
|
{
|
||||||
if (FIXNUM_2_P(recv, obj) &&
|
if (FIXNUM_2_P(recv, obj) &&
|
||||||
BASIC_OP_UNREDEFINED_P(BOP_EQ, FIXNUM_REDEFINED_OP_FLAG)) {
|
BASIC_OP_UNREDEFINED_P(BOP_EQ, FIXNUM_REDEFINED_OP_FLAG)) {
|
||||||
|
@ -1803,7 +1805,7 @@ opt_eq_func(VALUE recv, VALUE obj, IC ic)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const rb_method_entry_t *me = vm_method_search(idEq, CLASS_OF(recv), ic, 0);
|
const rb_method_entry_t *me = vm_method_search(idEq, CLASS_OF(recv), ci, 0);
|
||||||
|
|
||||||
if (check_cfunc(me, rb_obj_equal)) {
|
if (check_cfunc(me, rb_obj_equal)) {
|
||||||
return recv == obj ? Qtrue : Qfalse;
|
return recv == obj ? Qtrue : Qfalse;
|
||||||
|
|
|
@ -239,7 +239,7 @@ enum vm_regan_acttype {
|
||||||
|
|
||||||
#define CALL_SIMPLE_METHOD(num, id, recv) do { \
|
#define CALL_SIMPLE_METHOD(num, id, recv) do { \
|
||||||
VALUE klass = CLASS_OF(recv), defined_class; \
|
VALUE klass = CLASS_OF(recv), defined_class; \
|
||||||
const rb_method_entry_t *me = vm_method_search((id), klass, ic, &defined_class); \
|
const rb_method_entry_t *me = vm_method_search((id), klass, ci, &defined_class); \
|
||||||
CALL_METHOD((num), 0, 0, (id), me, (recv), defined_class); \
|
CALL_METHOD((num), 0, 0, (id), me, (recv), defined_class); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue