@@ -1361,7 +1361,7 @@ fn gen_newarray(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb:
13611361 // Save the PC and SP because we are allocating
13621362 jit_prepare_routine_call(jit, ctx, REG0);
13631363
1364- x86opnd_t values_ptr = ctx_sp_opnd(ctx, -(sizeof(VALUE) * (uint32_t)n));
1364+ x86opnd_t values_ptr = ctx_sp_opnd(ctx, -(SIZEOF_VALUE * (uint32_t)n));
13651365
13661366 // call rb_ec_ary_new_from_values(struct rb_execution_context_struct *ec, long n, const VALUE *elts);
13671367 mov(cb, C_ARG_REGS[0], REG_EC);
@@ -1650,6 +1650,91 @@ fn gen_getlocal_wc1(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, o
16501650 gen_getlocal_generic ( ctx, cb, idx. as_u32 ( ) , 1 )
16511651}
16521652
1653+ fn gen_setlocal_wc0 ( jit : & mut JITState , ctx : & mut Context , cb : & mut CodeBlock , ocb : & mut OutlinedCb ) -> CodegenStatus
1654+ {
1655+ /*
1656+ vm_env_write(const VALUE *ep, int index, VALUE v)
1657+ {
1658+ VALUE flags = ep[VM_ENV_DATA_INDEX_FLAGS];
1659+ if (LIKELY((flags & VM_ENV_FLAG_WB_REQUIRED) == 0)) {
1660+ VM_STACK_ENV_WRITE(ep, index, v);
1661+ }
1662+ else {
1663+ vm_env_write_slowpath(ep, index, v);
1664+ }
1665+ }
1666+ */
1667+
1668+ let slot_idx = jit_get_arg ( jit, 0 ) . as_i32 ( ) ;
1669+ let local_idx = slot_to_local_idx ( jit. get_iseq ( ) , slot_idx) as usize ;
1670+
1671+ // Load environment pointer EP (level 0) from CFP
1672+ gen_get_ep ( cb, REG0 , 0 ) ;
1673+
1674+ // flags & VM_ENV_FLAG_WB_REQUIRED
1675+ let flags_opnd = mem_opnd ( 64 , REG0 , SIZEOF_VALUE as i32 * VM_ENV_DATA_INDEX_FLAGS as i32 ) ;
1676+ test ( cb, flags_opnd, imm_opnd ( VM_ENV_FLAG_WB_REQUIRED as i64 ) ) ;
1677+
1678+ // Create a side-exit to fall back to the interpreter
1679+ let side_exit = get_side_exit ( jit, ocb, ctx) ;
1680+
1681+ // if (flags & VM_ENV_FLAG_WB_REQUIRED) != 0
1682+ jnz_ptr ( cb, side_exit) ;
1683+
1684+ // Set the type of the local variable in the context
1685+ let temp_type = ctx. get_opnd_type ( InsnOpnd :: StackOpnd ( 0 ) ) ;
1686+ ctx. set_local_type ( local_idx, temp_type) ;
1687+
1688+ // Pop the value to write from the stack
1689+ let stack_top = ctx. stack_pop ( 1 ) ;
1690+ mov ( cb, REG1 , stack_top) ;
1691+
1692+ // Write the value at the environment pointer
1693+ let offs: i32 = -8 * slot_idx;
1694+ mov ( cb, mem_opnd ( 64 , REG0 , offs) , REG1 ) ;
1695+
1696+ KeepCompiling
1697+ }
1698+
1699+ fn gen_setlocal_generic ( jit : & mut JITState , ctx : & mut Context , cb : & mut CodeBlock , ocb : & mut OutlinedCb , local_idx : i32 , level : u32 ) -> CodegenStatus
1700+ {
1701+ // Load environment pointer EP at level
1702+ gen_get_ep ( cb, REG0 , level) ;
1703+
1704+ // flags & VM_ENV_FLAG_WB_REQUIRED
1705+ let flags_opnd = mem_opnd ( 64 , REG0 , SIZEOF_VALUE as i32 * VM_ENV_DATA_INDEX_FLAGS as i32 ) ;
1706+ test ( cb, flags_opnd, imm_opnd ( VM_ENV_FLAG_WB_REQUIRED as i64 ) ) ;
1707+
1708+ // Create a side-exit to fall back to the interpreter
1709+ let side_exit = get_side_exit ( jit, ocb, ctx) ;
1710+
1711+ // if (flags & VM_ENV_FLAG_WB_REQUIRED) != 0
1712+ jnz_ptr ( cb, side_exit) ;
1713+
1714+ // Pop the value to write from the stack
1715+ let stack_top = ctx. stack_pop ( 1 ) ;
1716+ mov ( cb, REG1 , stack_top) ;
1717+
1718+ // Write the value at the environment pointer
1719+ let offs = -( SIZEOF_VALUE as i32 * local_idx) ;
1720+ mov ( cb, mem_opnd ( 64 , REG0 , offs) , REG1 ) ;
1721+
1722+ KeepCompiling
1723+ }
1724+
1725+ fn gen_setlocal ( jit : & mut JITState , ctx : & mut Context , cb : & mut CodeBlock , ocb : & mut OutlinedCb ) -> CodegenStatus
1726+ {
1727+ let idx = jit_get_arg ( jit, 0 ) . as_i32 ( ) ;
1728+ let level = jit_get_arg ( jit, 1 ) . as_u32 ( ) ;
1729+ gen_setlocal_generic ( jit, ctx, cb, ocb, idx, level)
1730+ }
1731+
1732+ fn gen_setlocal_wc1 ( jit : & mut JITState , ctx : & mut Context , cb : & mut CodeBlock , ocb : & mut OutlinedCb ) -> CodegenStatus
1733+ {
1734+ let idx = jit_get_arg ( jit, 0 ) . as_i32 ( ) ;
1735+ gen_setlocal_generic ( jit, ctx, cb, ocb, idx, 1 )
1736+ }
1737+
16531738/*
16541739// new hash initialized from top N values
16551740fn gen_newhash(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb: &mut OutlinedCb) -> CodegenStatus
@@ -1709,68 +1794,6 @@ fn gen_putstring(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb:
17091794 return YJIT_KEEP_COMPILING;
17101795}
17111796
1712- // Get EP at level from CFP
1713- static void
1714- gen_get_ep(codeblock_t *cb, x86opnd_t reg, uint32_t level)
1715- {
1716- // Load environment pointer EP from CFP
1717- mov(cb, reg, member_opnd(REG_CFP, rb_control_frame_t, ep));
1718-
1719- while (level--) {
1720- // Get the previous EP from the current EP
1721- // See GET_PREV_EP(ep) macro
1722- // VALUE *prev_ep = ((VALUE *)((ep)[VM_ENV_DATA_INDEX_SPECVAL] & ~0x03))
1723- mov(cb, reg, mem_opnd(64, REG0, SIZEOF_VALUE * VM_ENV_DATA_INDEX_SPECVAL));
1724- and(cb, reg, imm_opnd(~0x03));
1725- }
1726- }
1727-
1728- fn gen_setlocal_wc0(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb: &mut OutlinedCb) -> CodegenStatus
1729- {
1730- /*
1731- vm_env_write(const VALUE *ep, int index, VALUE v)
1732- {
1733- VALUE flags = ep[VM_ENV_DATA_INDEX_FLAGS];
1734- if (LIKELY((flags & VM_ENV_FLAG_WB_REQUIRED) == 0)) {
1735- VM_STACK_ENV_WRITE(ep, index, v);
1736- }
1737- else {
1738- vm_env_write_slowpath(ep, index, v);
1739- }
1740- }
1741- */
1742-
1743- int32_t slot_idx = (int32_t)jit_get_arg(jit, 0);
1744- uint32_t local_idx = slot_to_local_idx(jit->iseq, slot_idx);
1745-
1746- // Load environment pointer EP (level 0) from CFP
1747- gen_get_ep(cb, REG0, 0);
1748-
1749- // flags & VM_ENV_FLAG_WB_REQUIRED
1750- x86opnd_t flags_opnd = mem_opnd(64, REG0, sizeof(VALUE) * VM_ENV_DATA_INDEX_FLAGS);
1751- test(cb, flags_opnd, imm_opnd(VM_ENV_FLAG_WB_REQUIRED));
1752-
1753- // Create a side-exit to fall back to the interpreter
1754- uint8_t *side_exit = get_side_exit(jit, ocb, ctx);
1755-
1756- // if (flags & VM_ENV_FLAG_WB_REQUIRED) != 0
1757- jnz_ptr(cb, side_exit);
1758-
1759- // Set the type of the local variable in the context
1760- val_type_t temp_type = ctx_get_opnd_type(ctx, OPND_STACK(0));
1761- ctx_set_local_type(ctx, local_idx, temp_type);
1762-
1763- // Pop the value to write from the stack
1764- x86opnd_t stack_top = ctx_stack_pop(ctx, 1);
1765- mov(cb, REG1, stack_top);
1766-
1767- // Write the value at the environment pointer
1768- const int32_t offs = -8 * slot_idx;
1769- mov(cb, mem_opnd(64, REG0, offs), REG1);
1770-
1771- return YJIT_KEEP_COMPILING;
1772- }
1773-
17741797// Push Qtrue or Qfalse depending on whether the given keyword was supplied by
17751798// the caller
17761799fn gen_checkkeyword(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb: &mut OutlinedCb) -> CodegenStatus
@@ -1791,7 +1814,7 @@ fn gen_checkkeyword(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, o
17911814 gen_get_ep(cb, REG0, 0);
17921815
17931816 // VALUE kw_bits = *(ep - bits);
1794- x86opnd_t bits_opnd = mem_opnd(64, REG0, sizeof(VALUE) * -bits_offset);
1817+ x86opnd_t bits_opnd = mem_opnd(64, REG0, SIZEOF_VALUE * -bits_offset);
17951818
17961819 // unsigned int b = (unsigned int)FIX2ULONG(kw_bits);
17971820 // if ((b & (0x01 << idx))) {
@@ -1809,45 +1832,6 @@ fn gen_checkkeyword(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, o
18091832 return YJIT_KEEP_COMPILING;
18101833}
18111834
1812- fn gen_setlocal_generic(jitstate_t *jit, ctx_t *ctx, uint32_t local_idx, uint32_t level)
1813- {
1814- // Load environment pointer EP at level
1815- gen_get_ep(cb, REG0, level);
1816-
1817- // flags & VM_ENV_FLAG_WB_REQUIRED
1818- x86opnd_t flags_opnd = mem_opnd(64, REG0, sizeof(VALUE) * VM_ENV_DATA_INDEX_FLAGS);
1819- test(cb, flags_opnd, imm_opnd(VM_ENV_FLAG_WB_REQUIRED));
1820-
1821- // Create a side-exit to fall back to the interpreter
1822- uint8_t *side_exit = get_side_exit(jit, ocb, ctx);
1823-
1824- // if (flags & VM_ENV_FLAG_WB_REQUIRED) != 0
1825- jnz_ptr(cb, side_exit);
1826-
1827- // Pop the value to write from the stack
1828- x86opnd_t stack_top = ctx_stack_pop(ctx, 1);
1829- mov(cb, REG1, stack_top);
1830-
1831- // Write the value at the environment pointer
1832- const int32_t offs = -(SIZEOF_VALUE * local_idx);
1833- mov(cb, mem_opnd(64, REG0, offs), REG1);
1834-
1835- return YJIT_KEEP_COMPILING;
1836- }
1837-
1838- fn gen_setlocal(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb: &mut OutlinedCb) -> CodegenStatus
1839- {
1840- int32_t idx = (int32_t)jit_get_arg(jit, 0);
1841- int32_t level = (int32_t)jit_get_arg(jit, 1);
1842- return gen_setlocal_generic(jit, ctx, idx, level);
1843- }
1844-
1845- fn gen_setlocal_wc1(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb: &mut OutlinedCb) -> CodegenStatus
1846- {
1847- int32_t idx = (int32_t)jit_get_arg(jit, 0);
1848- return gen_setlocal_generic(jit, ctx, idx, 1);
1849- }
1850-
18511835static void
18521836gen_jnz_to_target0(codeblock_t *cb, uint8_t *target0, uint8_t *target1, uint8_t shape)
18531837{
@@ -2098,7 +2082,7 @@ fn gen_get_ivar(jitstate_t *jit, ctx_t *ctx, const int max_chain_depth, VALUE co
20982082 mov(cb, REG0, tbl_opnd);
20992083
21002084 // Read the ivar from the extended table
2101- x86opnd_t ivar_opnd = mem_opnd(64, REG0, sizeof(VALUE) * ivar_index);
2085+ x86opnd_t ivar_opnd = mem_opnd(64, REG0, SIZEOF_VALUE * ivar_index);
21022086 mov(cb, REG0, ivar_opnd);
21032087
21042088 // Check that the ivar is not Qundef
@@ -2271,7 +2255,7 @@ fn gen_concatstrings(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock,
22712255 // Save the PC and SP because we are allocating
22722256 jit_prepare_routine_call(jit, ctx, REG0);
22732257
2274- x86opnd_t values_ptr = ctx_sp_opnd(ctx, -(sizeof(VALUE) * (uint32_t)n));
2258+ x86opnd_t values_ptr = ctx_sp_opnd(ctx, SIZEOF_VALUE * (uint32_t)n));
22752259
22762260 // call rb_str_concat_literals(long n, const VALUE *strings);
22772261 mov(cb, C_ARG_REGS[0], imm_opnd(n));
@@ -3586,8 +3570,8 @@ fn gen_send_cfunc(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, con
35863570
35873571 // Stack overflow check
35883572 // #define CHECK_VM_STACK_OVERFLOW0(cfp, sp, margin)
3589- // REG_CFP <= REG_SP + 4 * sizeof(VALUE) + sizeof(rb_control_frame_t)
3590- lea(cb, REG0, ctx_sp_opnd(ctx, sizeof(VALUE) * 4 + 2 * sizeof(rb_control_frame_t)));
3573+ // REG_CFP <= REG_SP + 4 * SIZEOF_VALUE + sizeof(rb_control_frame_t)
3574+ lea(cb, REG0, ctx_sp_opnd(ctx, SIZEOF_VALUE * 4 + 2 * sizeof(rb_control_frame_t)));
35913575 cmp(cb, REG_CFP, REG0);
35923576 jle_ptr(cb, counted_exit!(ocb, side_exit, send_se_cf_overflow));
35933577
@@ -3607,7 +3591,7 @@ fn gen_send_cfunc(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, con
36073591
36083592 // Increment the stack pointer by 3 (in the callee)
36093593 // sp += 3
3610- lea(cb, REG0, ctx_sp_opnd(ctx, sizeof(VALUE) * 3));
3594+ lea(cb, REG0, ctx_sp_opnd(ctx, SIZEOF_VALUE * 3));
36113595
36123596 // Write method entry at sp[-3]
36133597 // sp[-3] = me;
@@ -3656,7 +3640,7 @@ fn gen_send_cfunc(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, con
36563640 mov(cb, member_opnd(REG1, rb_control_frame_t, iseq), imm_opnd(0));
36573641 mov(cb, member_opnd(REG1, rb_control_frame_t, block_code), imm_opnd(0));
36583642 mov(cb, member_opnd(REG1, rb_control_frame_t, __bp__), REG0);
3659- sub(cb, REG0, imm_opnd(sizeof(VALUE) ));
3643+ sub(cb, REG0, imm_opnd(SIZEOF_VALUE ));
36603644 mov(cb, member_opnd(REG1, rb_control_frame_t, ep), REG0);
36613645 mov(cb, REG0, recv);
36623646 mov(cb, member_opnd(REG1, rb_control_frame_t, self), REG0);
@@ -3986,7 +3970,7 @@ fn gen_send_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, cons
39863970 // Note that vm_push_frame checks it against a decremented cfp, hence the multiply by 2.
39873971 // #define CHECK_VM_STACK_OVERFLOW0(cfp, sp, margin)
39883972 add_comment(cb, "stack overflow check");
3989- lea(cb, REG0, ctx_sp_opnd(ctx, sizeof(VALUE) * (num_locals + iseq->body->stack_max) + 2 * sizeof(rb_control_frame_t)));
3973+ lea(cb, REG0, ctx_sp_opnd(ctx, SIZEOF_VALUE * (num_locals + iseq->body->stack_max) + 2 * sizeof(rb_control_frame_t)));
39903974 cmp(cb, REG_CFP, REG0);
39913975 jle_ptr(cb, counted_exit!(ocb, side_exit, send_se_cf_overflow));
39923976
@@ -4106,7 +4090,7 @@ fn gen_send_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, cons
41064090
41074091 // Store the updated SP on the current frame (pop arguments and receiver)
41084092 add_comment(cb, "store caller sp");
4109- lea(cb, REG0, ctx_sp_opnd(ctx, sizeof(VALUE) * -(argc + 1)));
4093+ lea(cb, REG0, ctx_sp_opnd(ctx, SIZEOF_VALUE * -(argc + 1)));
41104094 mov(cb, member_opnd(REG_CFP, rb_control_frame_t, sp), REG0);
41114095
41124096 // Store the next PC in the current frame
@@ -4121,11 +4105,11 @@ fn gen_send_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, cons
41214105 }
41224106
41234107 // Adjust the callee's stack pointer
4124- lea(cb, REG0, ctx_sp_opnd(ctx, sizeof(VALUE) * (3 + num_locals + doing_kw_call)));
4108+ lea(cb, REG0, ctx_sp_opnd(ctx, SIZEOF_VALUE * (3 + num_locals + doing_kw_call)));
41254109
41264110 // Initialize local variables to Qnil
41274111 for (int i = 0; i < num_locals; i++) {
4128- mov(cb, mem_opnd(64, REG0, sizeof(VALUE) * (i - num_locals - 3)), imm_opnd(Qnil));
4112+ mov(cb, mem_opnd(64, REG0, SIZEOF_VALUE * (i - num_locals - 3)), imm_opnd(Qnil));
41294113 }
41304114
41314115 add_comment(cb, "push env");
@@ -4173,7 +4157,7 @@ fn gen_send_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, cons
41734157 mov(cb, REG_SP, REG0); // Switch to the callee's REG_SP
41744158 mov(cb, member_opnd(REG_CFP, rb_control_frame_t, sp), REG0);
41754159 mov(cb, member_opnd(REG_CFP, rb_control_frame_t, __bp__), REG0);
4176- sub(cb, REG0, imm_opnd(sizeof(VALUE) ));
4160+ sub(cb, REG0, imm_opnd(SIZEOF_VALUE ));
41774161 mov(cb, member_opnd(REG_CFP, rb_control_frame_t, ep), REG0);
41784162 jit_mov_gc_ptr(jit, cb, REG0, (VALUE)iseq);
41794163 mov(cb, member_opnd(REG_CFP, rb_control_frame_t, iseq), REG0);
@@ -4778,7 +4762,7 @@ fn gen_toregexp(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb:
47784762 // raise an exception.
47794763 jit_prepare_routine_call(jit, ctx, REG0);
47804764
4781- x86opnd_t values_ptr = ctx_sp_opnd(ctx, -(sizeof(VALUE) * (uint32_t)cnt));
4765+ x86opnd_t values_ptr = ctx_sp_opnd(ctx, -(SIZEOF_VALUE * (uint32_t)cnt));
47824766 ctx_stack_pop(ctx, cnt);
47834767
47844768 mov(cb, C_ARG_REGS[0], imm_opnd(0));
@@ -5238,6 +5222,9 @@ fn get_gen_fn(opcode: VALUE) -> Option<CodeGenFn>
52385222 OP_GETLOCAL => Some ( gen_getlocal) ,
52395223 OP_GETLOCAL_WC_0 => Some ( gen_getlocal_wc0) ,
52405224 OP_GETLOCAL_WC_1 => Some ( gen_getlocal_wc1) ,
5225+ OP_SETLOCAL => Some ( gen_setlocal) ,
5226+ OP_SETLOCAL_WC_0 => Some ( gen_setlocal_wc0) ,
5227+ OP_SETLOCAL_WC_1 => Some ( gen_setlocal_wc1) ,
52415228
52425229 /*
52435230 yjit_reg_op(BIN(newarray), gen_newarray);
@@ -5249,9 +5236,6 @@ fn get_gen_fn(opcode: VALUE) -> Option<CodeGenFn>
52495236 yjit_reg_op(BIN(newrange), gen_newrange);
52505237 yjit_reg_op(BIN(concatstrings), gen_concatstrings);
52515238 yjit_reg_op(BIN(putstring), gen_putstring);
5252- yjit_reg_op(BIN(setlocal), gen_setlocal);
5253- yjit_reg_op(BIN(setlocal_WC_0), gen_setlocal_wc0);
5254- yjit_reg_op(BIN(setlocal_WC_1), gen_setlocal_wc1);
52555239 yjit_reg_op(BIN(getinstancevariable), gen_getinstancevariable);
52565240 yjit_reg_op(BIN(setinstancevariable), gen_setinstancevariable);
52575241 yjit_reg_op(BIN(defined), gen_defined);
0 commit comments