зеркало из https://github.com/github/ruby.git
* vm_core.h, compile.c: declare struct iseq_inline_cache_entry.
Inline cache (IC) entries are no longer GC managed object. IC entries are freed when ISeq is freed. * iseq.c: fix mark, free, memsize functions for above change. * insns.def: remove rb_gc_write_barrier(). * vm_insnhelper.c (vm_method_search): ditto. * tool/instruction.rb, template/insns_info.inc.tmpl (insn_iclen): added. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24085 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
762f9b28c6
Коммит
20d9aefccb
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
Mon Jul 13 17:49:11 2009 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* vm_core.h, compile.c: declare struct iseq_inline_cache_entry.
|
||||
Inline cache (IC) entries are no longer GC managed object.
|
||||
IC entries are freed when ISeq is freed.
|
||||
|
||||
* iseq.c: fix mark, free, memsize functions for above change.
|
||||
|
||||
* insns.def: remove rb_gc_write_barrier().
|
||||
|
||||
* vm_insnhelper.c (vm_method_search): ditto.
|
||||
|
||||
* tool/instruction.rb, template/insns_info.inc.tmpl (insn_iclen):
|
||||
added.
|
||||
|
||||
Mon Jul 13 13:35:08 2009 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* insns.def, vm_insnhelper.c (getinstancevariable):
|
||||
|
|
27
compile.c
27
compile.c
|
@ -12,6 +12,7 @@
|
|||
#include "ruby/ruby.h"
|
||||
|
||||
#define USE_INSN_STACK_INCREASE 1
|
||||
#define USE_INSN_ICLEN 1
|
||||
#include "vm_core.h"
|
||||
#include "iseq.h"
|
||||
#include "insns.inc"
|
||||
|
@ -1260,6 +1261,8 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
|
|||
struct iseq_insn_info_entry *insn_info_table;
|
||||
LINK_ELEMENT *list;
|
||||
VALUE *generated_iseq;
|
||||
int ic_size = 0;
|
||||
int ic_index = 0;
|
||||
|
||||
int k, pos, sp, stack_max = 0, line = 0;
|
||||
|
||||
|
@ -1273,6 +1276,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
|
|||
iobj = (INSN *)list;
|
||||
line = iobj->line_no;
|
||||
pos += insn_data_length(iobj);
|
||||
ic_size += insn_iclen(iobj->insn_id);
|
||||
k++;
|
||||
break;
|
||||
}
|
||||
|
@ -1310,6 +1314,9 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
|
|||
/* make instruction sequence */
|
||||
generated_iseq = ALLOC_N(VALUE, pos);
|
||||
insn_info_table = ALLOC_N(struct iseq_insn_info_entry, k);
|
||||
iseq->ic_entries = ALLOC_N(struct iseq_inline_cache_entry, ic_size);
|
||||
MEMZERO(iseq->ic_entries, struct iseq_inline_cache_entry, ic_size);
|
||||
iseq->ic_size = ic_size;
|
||||
|
||||
list = FIRST_ELEMENT(anchor);
|
||||
k = pos = sp = 0;
|
||||
|
@ -1318,7 +1325,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
|
|||
switch (list->type) {
|
||||
case ISEQ_ELEMENT_INSN:
|
||||
{
|
||||
int j, len, insn, iclen = 0, i;
|
||||
int j, len, insn, iclen = 0;
|
||||
const char *types;
|
||||
VALUE *operands;
|
||||
|
||||
|
@ -1337,12 +1344,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
|
|||
generated_iseq[pos] = insn;
|
||||
types = insn_op_types(insn);
|
||||
len = insn_len(insn);
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
if (types[i] == TS_IC) {
|
||||
iclen++;
|
||||
}
|
||||
}
|
||||
iclen = insn_iclen(insn);
|
||||
|
||||
/* operand check */
|
||||
if (iobj->operand_size + iclen != len - 1) {
|
||||
|
@ -1432,9 +1434,12 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
|
|||
}
|
||||
case TS_IC: /* inline cache */
|
||||
{
|
||||
VALUE v = (VALUE)NEW_INLINE_CACHE_ENTRY();
|
||||
generated_iseq[pos + 1 + j] = v;
|
||||
iseq_add_mark_object(iseq, v);
|
||||
IC ic = &iseq->ic_entries[ic_index++];
|
||||
if (UNLIKELY(ic_index > ic_size)) {
|
||||
rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d",
|
||||
ic_index, ic_size);
|
||||
}
|
||||
generated_iseq[pos + 1 + j] = (VALUE)ic;
|
||||
break;
|
||||
}
|
||||
case TS_ID: /* ID */
|
||||
|
@ -5241,8 +5246,6 @@ iseq_build_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
|
|||
argv[j] = (VALUE)rb_global_entry(SYM2ID(op));
|
||||
break;
|
||||
case TS_IC:
|
||||
argv[j] = (VALUE)NEW_INLINE_CACHE_ENTRY();
|
||||
iseq_add_mark_object(iseq, argv[j]);
|
||||
break;
|
||||
case TS_ID:
|
||||
argv[j] = rb_convert_type(op, T_SYMBOL,
|
||||
|
|
|
@ -1223,7 +1223,7 @@ setinlinecache
|
|||
{
|
||||
IC ic = GET_CONST_INLINE_CACHE(dst);
|
||||
|
||||
ic->ic_value = rb_gc_write_barrier(val);
|
||||
ic->ic_value = val;
|
||||
ic->ic_vmstat = GET_VM_STATE_VERSION() - ruby_vm_const_missing_count;
|
||||
ruby_vm_const_missing_count = 0;
|
||||
}
|
||||
|
|
12
iseq.c
12
iseq.c
|
@ -74,6 +74,7 @@ iseq_free(void *ptr)
|
|||
RUBY_FREE_UNLESS_NULL(iseq->iseq);
|
||||
RUBY_FREE_UNLESS_NULL(iseq->insn_info_table);
|
||||
RUBY_FREE_UNLESS_NULL(iseq->local_table);
|
||||
RUBY_FREE_UNLESS_NULL(iseq->ic_entries);
|
||||
RUBY_FREE_UNLESS_NULL(iseq->catch_table);
|
||||
RUBY_FREE_UNLESS_NULL(iseq->arg_opt_table);
|
||||
compile_data_free(iseq->compile_data);
|
||||
|
@ -86,11 +87,12 @@ iseq_free(void *ptr)
|
|||
static void
|
||||
iseq_mark(void *ptr)
|
||||
{
|
||||
rb_iseq_t *iseq;
|
||||
RUBY_MARK_ENTER("iseq");
|
||||
|
||||
if (ptr) {
|
||||
iseq = ptr;
|
||||
int i;
|
||||
rb_iseq_t *iseq = ptr;
|
||||
|
||||
RUBY_GC_INFO("%s @ %s\n", RSTRING_PTR(iseq->name), RSTRING_PTR(iseq->filename));
|
||||
RUBY_MARK_UNLESS_NULL(iseq->mark_ary);
|
||||
RUBY_MARK_UNLESS_NULL(iseq->name);
|
||||
|
@ -102,6 +104,11 @@ iseq_mark(void *ptr)
|
|||
/* RUBY_MARK_UNLESS_NULL(iseq->cached_special_block); */
|
||||
RUBY_MARK_UNLESS_NULL(iseq->orig);
|
||||
|
||||
for (i=0; i<iseq->ic_size; i++) {
|
||||
RUBY_MARK_UNLESS_NULL(iseq->ic_entries[i].ic_class);
|
||||
RUBY_MARK_UNLESS_NULL(iseq->ic_entries[i].ic_value);
|
||||
}
|
||||
|
||||
if (iseq->compile_data != 0) {
|
||||
RUBY_MARK_UNLESS_NULL(iseq->compile_data->mark_ary);
|
||||
RUBY_MARK_UNLESS_NULL(iseq->compile_data->err_info);
|
||||
|
@ -129,6 +136,7 @@ iseq_memsize(void *ptr)
|
|||
size += iseq->local_table_size * sizeof(ID);
|
||||
size += iseq->catch_table_size * sizeof(struct iseq_catch_table_entry);
|
||||
size += iseq->arg_opts * sizeof(VALUE);
|
||||
size += iseq->ic_size * sizeof(struct iseq_inline_cache_entry);
|
||||
|
||||
if (iseq->compile_data) {
|
||||
struct iseq_compile_data_storage *cur;
|
||||
|
|
|
@ -23,6 +23,10 @@ static const int insn_len_info[] = {
|
|||
<%= operands_num_info %>
|
||||
};
|
||||
|
||||
static const int insn_iclen_info[] = {
|
||||
<%= icoperands_num_info %>
|
||||
};
|
||||
|
||||
#ifdef USE_INSN_RET_NUM
|
||||
static const int insn_stack_push_num_info[] = {
|
||||
<%= stack_num_info %>
|
||||
|
@ -81,3 +85,11 @@ insn_ret_num(int insn)
|
|||
return insn_stack_push_num_info[insn];
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_INSN_ICLEN
|
||||
static int
|
||||
insn_iclen(int insn)
|
||||
{
|
||||
return insn_iclen_info[insn];
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -977,6 +977,8 @@ class RubyVM
|
|||
# operands info
|
||||
operands_info = ''
|
||||
operands_num_info = ''
|
||||
icoperands_num_info = ''
|
||||
|
||||
@insns.each{|insn|
|
||||
opes = insn.opes
|
||||
operands_info << ' '
|
||||
|
@ -987,6 +989,12 @@ class RubyVM
|
|||
|
||||
num = opes.size + 1
|
||||
operands_num_info << " #{num},\n"
|
||||
|
||||
icnum = 0
|
||||
opes.each{|e|
|
||||
icnum += 1 if e[0] == 'IC'
|
||||
}
|
||||
icoperands_num_info << " #{icnum},\n"
|
||||
}
|
||||
|
||||
# stack num
|
||||
|
|
24
vm_core.h
24
vm_core.h
|
@ -106,6 +106,18 @@ typedef struct rb_compile_option_struct {
|
|||
int debug_level;
|
||||
} rb_compile_option_t;
|
||||
|
||||
struct iseq_inline_cache_entry {
|
||||
long ic_vmstat;
|
||||
VALUE ic_class;
|
||||
union {
|
||||
NODE *method;
|
||||
VALUE value;
|
||||
} value;
|
||||
#define ic_value value.value
|
||||
#define ic_method value.method
|
||||
#define ic_index ic_vmstat
|
||||
};
|
||||
|
||||
#if 1
|
||||
#define GetCoreDataFromValue(obj, type, ptr) do { \
|
||||
ptr = (type*)DATA_PTR(obj); \
|
||||
|
@ -143,6 +155,9 @@ struct rb_iseq_struct {
|
|||
/* method, class frame: sizeof(vars) + 1, block frame: sizeof(vars) */
|
||||
int local_size;
|
||||
|
||||
struct iseq_inline_cache_entry *ic_entries;
|
||||
int ic_size;
|
||||
|
||||
/**
|
||||
* argument information
|
||||
*
|
||||
|
@ -522,13 +537,8 @@ typedef struct {
|
|||
(VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_CFUNC)
|
||||
|
||||
|
||||
/* inline (method|const) cache */
|
||||
#define NEW_INLINE_CACHE_ENTRY() NEW_NODE_LONGLIFE(NODE_WHILE, Qundef, 0, 0)
|
||||
#define ic_class u1.value
|
||||
#define ic_method u2.node
|
||||
#define ic_value u2.value
|
||||
#define ic_vmstat u3.value
|
||||
typedef NODE *IC;
|
||||
/* inline cache */
|
||||
typedef struct iseq_inline_cache_entry *IC;
|
||||
|
||||
void rb_vm_change_state(void);
|
||||
|
||||
|
|
|
@ -1180,7 +1180,7 @@ vm_getivar(VALUE obj, ID id, IC ic)
|
|||
VALUE klass = RBASIC(obj)->klass;
|
||||
|
||||
if (ic->ic_class == klass) {
|
||||
long index = ic->ic_vmstat;
|
||||
long index = ic->ic_index;
|
||||
long len = ROBJECT_NUMIV(obj);
|
||||
VALUE *ptr = ROBJECT_IVPTR(obj);
|
||||
|
||||
|
@ -1199,8 +1199,8 @@ vm_getivar(VALUE obj, ID id, IC ic)
|
|||
if (index < len) {
|
||||
val = ptr[index];
|
||||
}
|
||||
ic->ic_class = CLASS_OF(obj);
|
||||
ic->ic_vmstat = index;
|
||||
ic->ic_class = RBASIC(obj)->klass;
|
||||
ic->ic_index = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1231,8 +1231,8 @@ vm_method_search(VALUE id, VALUE klass, IC ic)
|
|||
}
|
||||
else {
|
||||
mn = rb_method_node(klass, id);
|
||||
ic->ic_class = rb_gc_write_barrier(klass);
|
||||
ic->ic_method = (NODE *)rb_gc_write_barrier((VALUE)mn);
|
||||
ic->ic_class = klass;
|
||||
ic->ic_method = mn;
|
||||
ic->ic_vmstat = GET_VM_STATE_VERSION();
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче