Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d6ca1ce

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 6649dc4 commit d6ca1ce

File tree

6 files changed

+24
-9
lines changed

6 files changed

+24
-9
lines changed

compile.c

+14-2
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 */
@@ -7299,6 +7307,7 @@ insn_data_to_s_detail(INSN *iobj)
72997307
break;
73007308
}
73017309
case TS_IC: /* inline cache */
7310+
case TS_ISE: /* inline storage entry */
73027311
rb_str_catf(str, "<ic:%d>", FIX2INT(OPERAND_AT(iobj, j)));
73037312
break;
73047313
case TS_CALLINFO: /* call info */
@@ -7684,6 +7693,7 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor,
76847693
argv[j] = (VALUE)rb_global_entry(SYM2ID(op));
76857694
break;
76867695
case TS_IC:
7696+
case TS_ISE:
76877697
argv[j] = op;
76887698
if (NUM2UINT(op) >= iseq->body->is_size) {
76897699
iseq->body->is_size = NUM2INT(op) + 1;
@@ -8289,6 +8299,7 @@ ibf_dump_code(struct ibf_dump *dump, const rb_iseq_t *iseq)
82898299
code[code_index] = (VALUE)ibf_dump_iseq(dump, (const rb_iseq_t *)op);
82908300
break;
82918301
case TS_IC:
8302+
case TS_ISE:
82928303
{
82938304
unsigned int i;
82948305
for (i=0; i<iseq->body->is_size; i++) {
@@ -8354,6 +8365,7 @@ ibf_load_code(const struct ibf_load *load, const rb_iseq_t *iseq, const struct r
83548365
code[code_index] = (VALUE)ibf_load_iseq(load, (const rb_iseq_t *)op);
83558366
break;
83568367
case TS_IC:
8368+
case TS_ISE:
83578369
code[code_index] = (VALUE)&is_entries[(int)op];
83588370
break;
83598371
case TS_CALLINFO:

insns.def

+2-2
Original file line numberDiff line numberDiff line change
@@ -971,11 +971,11 @@ setinlinecache
971971
/* run iseq only once */
972972
DEFINE_INSN
973973
once
974-
(ISEQ iseq, IC ic)
974+
(ISEQ iseq, ISE ise)
975975
()
976976
(VALUE val)
977977
{
978-
val = vm_once_dispatch(ec, iseq, ic);
978+
val = vm_once_dispatch(ec, iseq, ise);
979979
}
980980

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

iseq.c

+5-3
Original file line numberDiff line numberDiff line change
@@ -161,14 +161,14 @@ iseq_extract_values(const VALUE *code, size_t pos, iseq_value_itr_t * func, void
161161
}
162162
break;
163163
}
164-
case TS_IC:
165-
if (BIN(once) == insn || BIN(trace_once) == insn) {
164+
case TS_ISE:
165+
{
166166
union iseq_inline_storage_entry *const is = (union iseq_inline_storage_entry *)code[pos + op_no + 1];
167167
if (is->once.value) {
168168
func(data, is->once.value);
169169
}
170+
break;
170171
}
171-
break;
172172
default:
173173
break;
174174
}
@@ -1717,6 +1717,7 @@ rb_insn_operand_intern(const rb_iseq_t *iseq,
17171717
break;
17181718

17191719
case TS_IC:
1720+
case TS_ISE:
17201721
ret = rb_sprintf("<is:%"PRIdPTRDIFF">", (union iseq_inline_storage_entry *)op - iseq->body->is_entries);
17211722
break;
17221723

@@ -2460,6 +2461,7 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
24602461
}
24612462
break;
24622463
case TS_IC:
2464+
case TS_ISE:
24632465
{
24642466
union iseq_inline_storage_entry *is = (union iseq_inline_storage_entry *)*seq;
24652467
rb_ary_push(ary, INT2FIX(is - iseq->body->is_entries));

tool/ruby_vm/models/typemap.rb

+1
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

+1
Original file line numberDiff line numberDiff line change
@@ -1013,6 +1013,7 @@ enum vm_svar_index {
10131013

10141014
/* inline cache */
10151015
typedef struct iseq_inline_cache_entry *IC;
1016+
typedef union iseq_inline_storage_entry *ISE;
10161017
typedef struct rb_call_info *CALL_INFO;
10171018
typedef struct rb_call_cache *CALL_CACHE;
10181019

vm_insnhelper.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -3285,11 +3285,10 @@ vm_ic_update(IC ic, VALUE val, const VALUE *reg_ep)
32853285
}
32863286

32873287
static VALUE
3288-
vm_once_dispatch(rb_execution_context_t *ec, ISEQ iseq, IC ic)
3288+
vm_once_dispatch(rb_execution_context_t *ec, ISEQ iseq, ISE is)
32893289
{
32903290
rb_thread_t *th = rb_ec_thread_ptr(ec);
32913291
rb_thread_t *const RUNNING_THREAD_ONCE_DONE = (rb_thread_t *)(0x1);
3292-
union iseq_inline_storage_entry *const is = (union iseq_inline_storage_entry *)ic;
32933292

32943293
again:
32953294
if (is->once.running_thread == RUNNING_THREAD_ONCE_DONE) {

0 commit comments

Comments
 (0)