1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Separate TS_IVC and TS_ICVARC in is_entries buffers

This allows us to treat cvar caches differently than ivar caches.
This commit is contained in:
Jemma Issroff 2022-07-18 15:38:12 -04:00 committed by Aaron Patterson
parent 3ac9956dee
commit 85ea46730d
Notes: git 2022-07-19 06:06:52 +09:00
4 changed files with 54 additions and 14 deletions

View file

@ -2074,6 +2074,25 @@ get_ivar_ic_value(rb_iseq_t *iseq,ID id)
return val; return val;
} }
static inline VALUE
get_cvar_ic_value(rb_iseq_t *iseq,ID id)
{
VALUE val;
struct rb_id_table *tbl = ISEQ_COMPILE_DATA(iseq)->ivar_cache_table;
if (tbl) {
if (rb_id_table_lookup(tbl,id,&val)) {
return val;
}
}
else {
tbl = rb_id_table_create(1);
ISEQ_COMPILE_DATA(iseq)->ivar_cache_table = tbl;
}
val = INT2FIX(ISEQ_BODY(iseq)->icvarc_size++);
rb_id_table_insert(tbl,id,val);
return val;
}
#define BADINSN_DUMP(anchor, list, dest) \ #define BADINSN_DUMP(anchor, list, dest) \
dump_disasm_list_with_cursor(FIRST_ELEMENT(anchor), list, dest) dump_disasm_list_with_cursor(FIRST_ELEMENT(anchor), list, dest)
@ -2412,7 +2431,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
} }
break; break;
} }
/* [ TS_(ICVARC|IVC) ... | TS_ISE | TS_IC ] */ /* [ TS_IVC | TS_ICVARC | TS_ISE | TS_IC ] */
case TS_IC: /* inline cache: constants */ case TS_IC: /* inline cache: constants */
case TS_ISE: /* inline storage entry: `once` insn */ case TS_ISE: /* inline storage entry: `once` insn */
case TS_ICVARC: /* inline cvar cache */ case TS_ICVARC: /* inline cvar cache */
@ -9336,7 +9355,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
} }
ADD_INSN2(ret, node, setclassvariable, ADD_INSN2(ret, node, setclassvariable,
ID2SYM(node->nd_vid), ID2SYM(node->nd_vid),
get_ivar_ic_value(iseq,node->nd_vid)); get_cvar_ic_value(iseq,node->nd_vid));
break; break;
} }
case NODE_OP_ASGN1: case NODE_OP_ASGN1:
@ -9463,7 +9482,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
if (!popped) { if (!popped) {
ADD_INSN2(ret, node, getclassvariable, ADD_INSN2(ret, node, getclassvariable,
ID2SYM(node->nd_vid), ID2SYM(node->nd_vid),
get_ivar_ic_value(iseq,node->nd_vid)); get_cvar_ic_value(iseq,node->nd_vid));
} }
break; break;
} }
@ -10339,12 +10358,17 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor,
} }
break; break;
case TS_IVC: /* inline ivar cache */ case TS_IVC: /* inline ivar cache */
case TS_ICVARC: /* inline cvar cache */
argv[j] = op; argv[j] = op;
if (NUM2UINT(op) >= ISEQ_BODY(iseq)->ivc_size) { if (NUM2UINT(op) >= ISEQ_BODY(iseq)->ivc_size) {
ISEQ_BODY(iseq)->ivc_size = NUM2INT(op) + 1; ISEQ_BODY(iseq)->ivc_size = NUM2INT(op) + 1;
} }
break; break;
case TS_ICVARC: /* inline cvar cache */
argv[j] = op;
if (NUM2UINT(op) >= ISEQ_BODY(iseq)->icvarc_size) {
ISEQ_BODY(iseq)->icvarc_size = NUM2INT(op) + 1;
}
break;
case TS_CALLDATA: case TS_CALLDATA:
argv[j] = iseq_build_callinfo_from_hash(iseq, op); argv[j] = iseq_build_callinfo_from_hash(iseq, op);
break; break;
@ -11807,6 +11831,7 @@ ibf_dump_iseq_each(struct ibf_dump *dump, const rb_iseq_t *iseq)
ibf_dump_write_small_value(dump, body->variable.flip_count); ibf_dump_write_small_value(dump, body->variable.flip_count);
ibf_dump_write_small_value(dump, body->local_table_size); ibf_dump_write_small_value(dump, body->local_table_size);
ibf_dump_write_small_value(dump, body->ivc_size); ibf_dump_write_small_value(dump, body->ivc_size);
ibf_dump_write_small_value(dump, body->icvarc_size);
ibf_dump_write_small_value(dump, body->ise_size); ibf_dump_write_small_value(dump, body->ise_size);
ibf_dump_write_small_value(dump, body->ic_size); ibf_dump_write_small_value(dump, body->ic_size);
ibf_dump_write_small_value(dump, body->ci_size); ibf_dump_write_small_value(dump, body->ci_size);
@ -11918,6 +11943,7 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset)
const unsigned int local_table_size = (unsigned int)ibf_load_small_value(load, &reading_pos); const unsigned int local_table_size = (unsigned int)ibf_load_small_value(load, &reading_pos);
const unsigned int ivc_size = (unsigned int)ibf_load_small_value(load, &reading_pos); const unsigned int ivc_size = (unsigned int)ibf_load_small_value(load, &reading_pos);
const unsigned int icvarc_size = (unsigned int)ibf_load_small_value(load, &reading_pos);
const unsigned int ise_size = (unsigned int)ibf_load_small_value(load, &reading_pos); const unsigned int ise_size = (unsigned int)ibf_load_small_value(load, &reading_pos);
const unsigned int ic_size = (unsigned int)ibf_load_small_value(load, &reading_pos); const unsigned int ic_size = (unsigned int)ibf_load_small_value(load, &reading_pos);
@ -11966,6 +11992,7 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset)
load_body->builtin_inline_p = builtin_inline_p; load_body->builtin_inline_p = builtin_inline_p;
load_body->ivc_size = ivc_size; load_body->ivc_size = ivc_size;
load_body->icvarc_size = icvarc_size;
load_body->ise_size = ise_size; load_body->ise_size = ise_size;
load_body->ic_size = ic_size; load_body->ic_size = ic_size;
load_body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, ISEQ_IS_SIZE(load_body)); load_body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, ISEQ_IS_SIZE(load_body));

19
iseq.c
View file

@ -274,13 +274,11 @@ rb_iseq_each_value(const rb_iseq_t *iseq, iseq_value_itr_t * func, void *data)
union iseq_inline_storage_entry *is_entries = body->is_entries; union iseq_inline_storage_entry *is_entries = body->is_entries;
if (body->is_entries) { if (body->is_entries) {
// IVC and ICVARC entries // IVC entries
for (unsigned int i = 0; i < body->ivc_size; i++, is_entries++) { for (unsigned int i = 0; i < body->ivc_size; i++, is_entries++) {
IVC ivc = (IVC)is_entries; IVC ivc = (IVC)is_entries;
if (ivc->entry) { if (ivc->entry) {
if (RB_TYPE_P(ivc->entry->class_value, T_NONE)) { RUBY_ASSERT(!RB_TYPE_P(ivc->entry->class_value, T_NONE));
rb_bug("!! %u", ivc->entry->index);
}
VALUE nv = func(data, ivc->entry->class_value); VALUE nv = func(data, ivc->entry->class_value);
if (ivc->entry->class_value != nv) { if (ivc->entry->class_value != nv) {
@ -289,6 +287,19 @@ rb_iseq_each_value(const rb_iseq_t *iseq, iseq_value_itr_t * func, void *data)
} }
} }
// ICVARC entries
for (unsigned int i = 0; i < body->icvarc_size; i++, is_entries++) {
ICVARC icvarc = (ICVARC)is_entries;
if (icvarc->entry) {
RUBY_ASSERT(!RB_TYPE_P(icvarc->entry->class_value, T_NONE));
VALUE nv = func(data, icvarc->entry->class_value);
if (icvarc->entry->class_value != nv) {
icvarc->entry->class_value = nv;
}
}
}
// ISE entries // ISE entries
for (unsigned int i = 0; i < body->ise_size; i++, is_entries++) { for (unsigned int i = 0; i < body->ise_size; i++, is_entries++) {
union iseq_inline_storage_entry *const is = (union iseq_inline_storage_entry *)is_entries; union iseq_inline_storage_entry *const is = (union iseq_inline_storage_entry *)is_entries;

View file

@ -20,9 +20,10 @@ ISEQ_IS_ENTRY_START(const struct rb_iseq_constant_body *body, char op_type)
case TS_IC: case TS_IC:
relative_ic_offset += body->ise_size; relative_ic_offset += body->ise_size;
case TS_ISE: case TS_ISE:
relative_ic_offset += body->icvarc_size;
case TS_ICVARC:
relative_ic_offset += body->ivc_size; relative_ic_offset += body->ivc_size;
case TS_IVC: case TS_IVC:
case TS_ICVARC:
break; break;
default: default:
rb_bug("Wrong op type"); rb_bug("Wrong op type");

View file

@ -337,7 +337,7 @@ struct rb_mjit_unit;
typedef uintptr_t iseq_bits_t; typedef uintptr_t iseq_bits_t;
#define ISEQ_IS_SIZE(body) (body->ic_size + body->ivc_size + body->ise_size) #define ISEQ_IS_SIZE(body) (body->ic_size + body->ivc_size + body->ise_size + body->icvarc_size)
struct rb_iseq_constant_body { struct rb_iseq_constant_body {
enum iseq_type { enum iseq_type {
@ -448,7 +448,7 @@ struct rb_iseq_constant_body {
const struct rb_iseq_struct *parent_iseq; const struct rb_iseq_struct *parent_iseq;
struct rb_iseq_struct *local_iseq; /* local_iseq->flip_cnt can be modified */ struct rb_iseq_struct *local_iseq; /* local_iseq->flip_cnt can be modified */
union iseq_inline_storage_entry *is_entries; /* [ TS_(ICVARC|IVC) ... | TS_ISE | TS_IC ] */ union iseq_inline_storage_entry *is_entries; /* [ TS_IVC | TS_ICVARC | TS_ISE | TS_IC ] */
struct rb_call_data *call_data; //struct rb_call_data calls[ci_size]; struct rb_call_data *call_data; //struct rb_call_data calls[ci_size];
struct { struct {
@ -460,9 +460,10 @@ struct rb_iseq_constant_body {
} variable; } variable;
unsigned int local_table_size; unsigned int local_table_size;
unsigned int ic_size; // Number of IC caches unsigned int ic_size; // Number of IC caches
unsigned int ise_size; // Number of ISE caches unsigned int ise_size; // Number of ISE caches
unsigned int ivc_size; // Number of IVC and ICVARC caches unsigned int ivc_size; // Number of IVC caches
unsigned int icvarc_size; // Number of ICVARC caches
unsigned int ci_size; unsigned int ci_size;
unsigned int stack_max; /* for stack overflow check */ unsigned int stack_max; /* for stack overflow check */
union { union {