summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2022-06-27 14:31:15 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2022-06-29 16:21:48 -0700
commite3ab525f699b5191db70ef095b3d110890441940 (patch)
treeb2dcd5f5dcbaaecc03d18c5fa403469abb96a3f7
parent66eb58d6bd50dd3ad8691fcc8eb72ad4d45bc04c (diff)
Fix ISeq dump / load in array cases
We need to dump relative offsets for inline storage entries so that loading iseqs as an array works as well. This commit also has some minor refactoring to make computing relative ISE information easier. This should fix the iseq dump / load as array tests we're seeing fail in CI. Co-Authored-By: John Hawthorn <john@hawthorn.email>
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/6069
-rw-r--r--compile.c22
-rw-r--r--iseq.c26
-rw-r--r--iseq.h1
3 files changed, 32 insertions, 17 deletions
diff --git a/compile.c b/compile.c
index 7b649b9d34..8872d6f7e8 100644
--- a/compile.c
+++ b/compile.c
@@ -2371,7 +2371,6 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
len = insn_len(insn);
for (j = 0; types[j]; j++) {
- unsigned int ic_index = 0;
char type = types[j];
/* printf("--> [%c - (%d-%d)]\n", type, k, j); */
@@ -2421,14 +2420,12 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
}
/* [ TS_(ICVARC|IVC) ... | TS_ISE | TS_IC ] */
case TS_IC: /* inline cache: constants */
- ic_index += body->ise_size;
case TS_ISE: /* inline storage entry: `once` insn */
- ic_index += body->ivc_size;
case TS_ICVARC: /* inline cvar cache */
case TS_IVC: /* inline ivar cache */
{
- ic_index += FIX2UINT(operands[j]);
- IC ic = (IC)&body->is_entries[ic_index];
+ unsigned int ic_index = FIX2UINT(operands[j]);
+ IC ic = &ISEQ_IS_ENTRY_START(body, type)[ic_index].ic_cache;
if (UNLIKELY(ic_index >= ISEQ_IS_SIZE(body))) {
BADINSN_DUMP(anchor, &iobj->link, 0);
COMPILE_ERROR(iseq, iobj->insn_info.line_no,
@@ -11169,13 +11166,8 @@ ibf_dump_code(struct ibf_dump *dump, const rb_iseq_t *iseq)
case TS_IVC:
case TS_ICVARC:
{
- unsigned int i;
- for (i=0; i<ISEQ_IS_SIZE(body); i++) {
- if (op == (VALUE)&body->is_entries[i]) {
- break;
- }
- }
- wv = (VALUE)i;
+ union iseq_inline_storage_entry *is = (union iseq_inline_storage_entry *)op;
+ wv = is - ISEQ_IS_ENTRY_START(body, types[op_index]);
}
break;
case TS_CALLDATA:
@@ -11214,7 +11206,6 @@ ibf_load_code(const struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t bytecod
struct rb_iseq_constant_body *load_body = ISEQ_BODY(iseq);
struct rb_call_data *cd_entries = load_body->call_data;
- union iseq_inline_storage_entry *is_entries = load_body->is_entries;
iseq_bits_t * mark_offset_bits;
@@ -11295,12 +11286,13 @@ ibf_load_code(const struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t bytecod
{
unsigned int op = (unsigned int)ibf_load_small_value(load, &reading_pos);
- code[code_index] = (VALUE)&is_entries[op];
+ ISE ic = ISEQ_IS_ENTRY_START(load_body, operand_type) + op;
+ code[code_index] = (VALUE)ic;
if (insn == BIN(opt_getinlinecache) && operand_type == TS_IC) {
// Store the instruction index for opt_getinlinecache on the IC for
// YJIT to invalidate code when opt_setinlinecache runs.
- is_entries[op].ic_cache.get_insn_idx = insn_index;
+ ic->ic_cache.get_insn_idx = insn_index;
}
}
FL_SET(iseqv, ISEQ_MARKABLE_ISEQ);
diff --git a/iseq.c b/iseq.c
index 7f02e1b9e5..0ac67f62bc 100644
--- a/iseq.c
+++ b/iseq.c
@@ -2943,6 +2943,26 @@ iseq_type_id(enum iseq_type type)
rb_bug("unsupported iseq type: %d", (int)type);
}
+union iseq_inline_storage_entry *
+ISEQ_IS_ENTRY_START(const struct rb_iseq_constant_body *body, char op_type)
+{
+ unsigned int relative_ic_offset = 0;
+
+ switch(op_type) {
+ case TS_IC:
+ relative_ic_offset += body->ise_size;
+ case TS_ISE:
+ relative_ic_offset += body->ivc_size;
+ case TS_IVC:
+ case TS_ICVARC:
+ break;
+ default:
+ rb_bug("Wrong op type");
+ }
+
+ return &body->is_entries[relative_ic_offset];
+}
+
static VALUE
iseq_data_to_ary(const rb_iseq_t *iseq)
{
@@ -3048,7 +3068,9 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
rb_ary_push(ary, ID2SYM(insn_syms[insn%numberof(insn_syms)]));
for (j=0; j<len-1; j++, seq++) {
- switch (insn_op_type(insn, j)) {
+ enum ruby_insn_type_chars op_type = insn_op_type(insn, j);
+
+ switch (op_type) {
case TS_OFFSET: {
unsigned long idx = nseq - iseq_original + *seq;
rb_ary_push(ary, register_label(labels_table, idx));
@@ -3079,7 +3101,7 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
case TS_ISE:
{
union iseq_inline_storage_entry *is = (union iseq_inline_storage_entry *)*seq;
- rb_ary_push(ary, INT2FIX(is - iseq_body->is_entries));
+ rb_ary_push(ary, INT2FIX(is - ISEQ_IS_ENTRY_START(ISEQ_BODY(iseq), op_type)));
}
break;
case TS_CALLDATA:
diff --git a/iseq.h b/iseq.h
index 46a8b1b010..afec0bae20 100644
--- a/iseq.h
+++ b/iseq.h
@@ -169,6 +169,7 @@ void rb_iseq_init_trace(rb_iseq_t *iseq);
int rb_iseq_add_local_tracepoint_recursively(const rb_iseq_t *iseq, rb_event_flag_t turnon_events, VALUE tpval, unsigned int target_line, bool target_bmethod);
int rb_iseq_remove_local_tracepoint_recursively(const rb_iseq_t *iseq, VALUE tpval);
const rb_iseq_t *rb_iseq_load_iseq(VALUE fname);
+union iseq_inline_storage_entry *ISEQ_IS_ENTRY_START(const struct rb_iseq_constant_body *body, char op_type);
#if VM_INSN_INFO_TABLE_IMPL == 2
unsigned int *rb_iseq_insns_info_decode_positions(const struct rb_iseq_constant_body *body);