Skip to content

Commit 78ce485

Browse files
committed
Introduce TS_ISE operand
The `once` instruction uses an "inline storage entry". This commit introduces an inline storage entry specific operand. Adding this operand allows us to remove conditionals based on instruction type.
1 parent fcb7054 commit 78ce485

File tree

6 files changed

+24
-9
lines changed

6 files changed

+24
-9
lines changed

compile.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2052,9 +2052,17 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
20522052
rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d", ic_index, iseq->body->is_size);
20532053
}
20542054
generated_iseq[code_index + 1 + j] = (VALUE)ic;
2055-
if (BIN(once) == insn || BIN(trace_once) == insn) {
2056-
FL_SET(iseq, ISEQ_MARKABLE_ISEQ);
2055+
break;
2056+
}
2057+
case TS_ISE: /* inline storage entry */
2058+
{
2059+
unsigned int ic_index = FIX2UINT(operands[j]);
2060+
IC ic = (IC)&iseq->body->is_entries[ic_index];
2061+
if (UNLIKELY(ic_index >= iseq->body->is_size)) {
2062+
rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d", ic_index, iseq->body->is_size);
20572063
}
2064+
generated_iseq[code_index + 1 + j] = (VALUE)ic;
2065+
FL_SET(iseq, ISEQ_MARKABLE_ISEQ);
20582066
break;
20592067
}
20602068
case TS_CALLINFO: /* call info */
@@ -7280,6 +7288,7 @@ insn_data_to_s_detail(INSN *iobj)
72807288
break;
72817289
}
72827290
case TS_IC: /* inline cache */
7291+
case TS_ISE: /* inline storage entry */
72837292
rb_str_catf(str, "<ic:%d>", FIX2INT(OPERAND_AT(iobj, j)));
72847293
break;
72857294
case TS_CALLINFO: /* call info */
@@ -7665,6 +7674,7 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor,
76657674
argv[j] = (VALUE)rb_global_entry(SYM2ID(op));
76667675
break;
76677676
case TS_IC:
7677+
case TS_ISE:
76687678
argv[j] = op;
76697679
if (NUM2UINT(op) >= iseq->body->is_size) {
76707680
iseq->body->is_size = NUM2INT(op) + 1;
@@ -8270,6 +8280,7 @@ ibf_dump_code(struct ibf_dump *dump, const rb_iseq_t *iseq)
82708280
code[code_index] = (VALUE)ibf_dump_iseq(dump, (const rb_iseq_t *)op);
82718281
break;
82728282
case TS_IC:
8283+
case TS_ISE:
82738284
{
82748285
unsigned int i;
82758286
for (i=0; i<iseq->body->is_size; i++) {
@@ -8335,6 +8346,7 @@ ibf_load_code(const struct ibf_load *load, const rb_iseq_t *iseq, const struct r
83358346
code[code_index] = (VALUE)ibf_load_iseq(load, (const rb_iseq_t *)op);
83368347
break;
83378348
case TS_IC:
8349+
case TS_ISE:
83388350
code[code_index] = (VALUE)&is_entries[(int)op];
83398351
break;
83408352
case TS_CALLINFO:

insns.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -972,11 +972,11 @@ setinlinecache
972972
/* run iseq only once */
973973
DEFINE_INSN
974974
once
975-
(ISEQ iseq, IC ic)
975+
(ISEQ iseq, ISE ise)
976976
()
977977
(VALUE val)
978978
{
979-
val = vm_once_dispatch(ec, iseq, ic);
979+
val = vm_once_dispatch(ec, iseq, ise);
980980
}
981981

982982
/* case dispatcher, jump by table if possible */

iseq.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,14 +159,14 @@ iseq_extract_values(const VALUE *code, size_t pos, iseq_value_itr_t * func, void
159159
}
160160
break;
161161
}
162-
case TS_IC:
163-
if (BIN(once) == insn || BIN(trace_once) == insn) {
162+
case TS_ISE:
163+
{
164164
union iseq_inline_storage_entry *const is = (union iseq_inline_storage_entry *)code[pos + op_no + 1];
165165
if (is->once.value) {
166166
func(data, is->once.value);
167167
}
168+
break;
168169
}
169-
break;
170170
default:
171171
break;
172172
}
@@ -1715,6 +1715,7 @@ rb_insn_operand_intern(const rb_iseq_t *iseq,
17151715
break;
17161716

17171717
case TS_IC:
1718+
case TS_ISE:
17181719
ret = rb_sprintf("<is:%"PRIdPTRDIFF">", (union iseq_inline_storage_entry *)op - iseq->body->is_entries);
17191720
break;
17201721

@@ -2458,6 +2459,7 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
24582459
}
24592460
break;
24602461
case TS_IC:
2462+
case TS_ISE:
24612463
{
24622464
union iseq_inline_storage_entry *is = (union iseq_inline_storage_entry *)*seq;
24632465
rb_ary_push(ary, INT2FIX(is - iseq->body->is_entries));

tool/ruby_vm/models/typemap.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"GENTRY" => %w[G TS_GENTRY],
1919
"IC" => %w[K TS_IC],
2020
"ID" => %w[I TS_ID],
21+
"ISE" => %w[T TS_ISE],
2122
"ISEQ" => %w[S TS_ISEQ],
2223
"OFFSET" => %w[O TS_OFFSET],
2324
"VALUE" => %w[V TS_VALUE],

vm_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,7 @@ enum vm_svar_index {
10021002

10031003
/* inline cache */
10041004
typedef struct iseq_inline_cache_entry *IC;
1005+
typedef union iseq_inline_storage_entry *ISE;
10051006
typedef struct rb_call_info *CALL_INFO;
10061007
typedef struct rb_call_cache *CALL_CACHE;
10071008

vm_insnhelper.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3281,11 +3281,10 @@ vm_ic_update(IC ic, VALUE val, const VALUE *reg_ep)
32813281
}
32823282

32833283
static VALUE
3284-
vm_once_dispatch(rb_execution_context_t *ec, ISEQ iseq, IC ic)
3284+
vm_once_dispatch(rb_execution_context_t *ec, ISEQ iseq, ISE is)
32853285
{
32863286
rb_thread_t *th = rb_ec_thread_ptr(ec);
32873287
rb_thread_t *const RUNNING_THREAD_ONCE_DONE = (rb_thread_t *)(0x1);
3288-
union iseq_inline_storage_entry *const is = (union iseq_inline_storage_entry *)ic;
32893288

32903289
again:
32913290
if (is->once.running_thread == RUNNING_THREAD_ONCE_DONE) {

0 commit comments

Comments
 (0)