Skip to content

Commit 577fc43

Browse files
author
Noah Gibbs
authored
Port gen_branch and propagate cb and ocb params appropriately (ruby#222)
1 parent 535c145 commit 577fc43

File tree

2 files changed

+52
-38
lines changed

2 files changed

+52
-38
lines changed

yjit/src/codegen.rs

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1919,7 +1919,7 @@ fn gen_jbe_to_target0(cb: &mut CodeBlock, target0: CodePtr, target1: Option<Code
19191919

19201920
// Generate a jump to a stub that recompiles the current YARV instruction on failure.
19211921
// When depth_limitk is exceeded, generate a jump to a side exit.
1922-
fn jit_chain_guard(jcc:JCCKinds, jit: &JITState, ctx: &Context, cb: &mut CodeBlock, depth_limit: i32, side_exit: CodePtr)
1922+
fn jit_chain_guard(jcc:JCCKinds, jit: &JITState, ctx: &Context, cb: &mut CodeBlock, ocb: &mut OutlinedCb, depth_limit: i32, side_exit: CodePtr)
19231923
{
19241924
let target0_gen_fn = match jcc {
19251925
JCC_JNE | JCC_JNZ => gen_jnz_to_target0,
@@ -1935,11 +1935,13 @@ fn jit_chain_guard(jcc:JCCKinds, jit: &JITState, ctx: &Context, cb: &mut CodeBlo
19351935
gen_branch(
19361936
jit,
19371937
ctx,
1938+
cb,
1939+
ocb,
19381940
bid,
19391941
&deeper,
19401942
None,
19411943
None,
1942-
target0_gen_fn
1944+
target0_gen_fn,
19431945
);
19441946
}
19451947
else {
@@ -2043,7 +2045,7 @@ fn gen_get_ivar(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb:
20432045
mov(cb, REG1, member_opnd(REG0, struct RBasic, flags));
20442046
and(cb, REG1, imm_opnd(RUBY_T_MASK));
20452047
cmp(cb, REG1, imm_opnd(T_OBJECT));
2046-
jit_chain_guard(JCC_JNE, jit, &starting_context, cb, max_chain_depth, side_exit);
2048+
jit_chain_guard(JCC_JNE, jit, &starting_context, cb, ocb, max_chain_depth, side_exit);
20472049
*/
20482050

20492051
// FIXME: Mapping the index could fail when there is too many ivar names. If we're
@@ -2066,7 +2068,8 @@ fn gen_get_ivar(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb:
20662068
add_comment(cb, "guard embedded getivar");
20672069
let flags_opnd = mem_opnd(64, REG0, RUBY_OFFSET_RBASIC_FLAGS);
20682070
test(cb, flags_opnd, uimm_opnd(ROBJECT_EMBED as u64));
2069-
jit_chain_guard(JCC_JZ, jit, &starting_context, cb, max_chain_depth, counted_exit!(ocb, side_exit, getivar_megamorphic));
2071+
let side_exit = counted_exit!(ocb, side_exit, getivar_megamorphic);
2072+
jit_chain_guard(JCC_JZ, jit, &starting_context, cb, ocb, max_chain_depth, side_exit);
20702073

20712074
// Load the variable
20722075
let offs = RUBY_OFFSET_ROBJECT_AS_ARY + (ivar_index * SIZEOF_VALUE) as i32;
@@ -2090,7 +2093,8 @@ fn gen_get_ivar(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb:
20902093
add_comment(cb, "guard extended getivar");
20912094
let flags_opnd = mem_opnd(64, REG0, RUBY_OFFSET_RBASIC_FLAGS);
20922095
test(cb, flags_opnd, uimm_opnd(ROBJECT_EMBED as u64));
2093-
jit_chain_guard(JCC_JNZ, jit, &starting_context, cb, max_chain_depth, counted_exit!(ocb, side_exit, getivar_megamorphic));
2096+
let side_exit = counted_exit!(ocb, side_exit, getivar_megamorphic);
2097+
jit_chain_guard(JCC_JNZ, jit, &starting_context, cb, ocb, max_chain_depth, side_exit);
20942098

20952099
// check that the extended table is big enough
20962100
if ivar_index >= ROBJECT_EMBED_LEN_MAX + 1 {
@@ -2142,7 +2146,7 @@ fn gen_getinstancevariable(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeB
21422146
// Guard that the receiver has the same class as the one from compile time.
21432147
mov(cb, REG0, mem_opnd(64, REG_CFP, RUBY_OFFSET_CFP_SELF));
21442148

2145-
jit_guard_known_klass(jit, ctx, cb, comptime_val_klass, InsnOpnd::SelfOpnd, comptime_val, GET_IVAR_MAX_DEPTH, side_exit);
2149+
jit_guard_known_klass(jit, ctx, cb, ocb, comptime_val_klass, InsnOpnd::SelfOpnd, comptime_val, GET_IVAR_MAX_DEPTH, side_exit);
21462150

21472151
gen_get_ivar(jit, ctx, cb, ocb, GET_IVAR_MAX_DEPTH, comptime_val, ivar_name, InsnOpnd::SelfOpnd, side_exit)
21482152
}
@@ -2452,7 +2456,7 @@ fn gen_equality_specialized(jit: &mut JITState, ctx: &mut Context, cb: &mut Code
24522456
mov(cb, REG0, C_ARG_REGS[0]);
24532457
unsafe {
24542458
// Use of rb_cString here requires an unsafe block
2455-
jit_guard_known_klass(jit, ctx, cb, rb_cString, StackOpnd(1), comptime_a, SEND_MAX_DEPTH, side_exit);
2459+
jit_guard_known_klass(jit, ctx, cb, ocb, rb_cString, StackOpnd(1), comptime_a, SEND_MAX_DEPTH, side_exit);
24562460
}
24572461

24582462
let ret = cb.new_label("ret".to_string());
@@ -2468,7 +2472,7 @@ fn gen_equality_specialized(jit: &mut JITState, ctx: &mut Context, cb: &mut Code
24682472
// Note: any T_STRING is valid here, but we check for a ::String for simplicity
24692473
// To pass a mutable static variable (rb_cString) requires an unsafe block
24702474
unsafe {
2471-
jit_guard_known_klass(jit, ctx, cb, rb_cString, StackOpnd(0), comptime_b, SEND_MAX_DEPTH, side_exit);
2475+
jit_guard_known_klass(jit, ctx, cb, ocb, rb_cString, StackOpnd(0), comptime_b, SEND_MAX_DEPTH, side_exit);
24722476
}
24732477
}
24742478

@@ -2570,7 +2574,7 @@ fn gen_opt_aref(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb:
25702574
mov(cb, REG1, mem_opnd(64, REG0, RUBY_OFFSET_RBASIC_KLASS));
25712575
mov(cb, REG0, uimm_opnd(unsafe { rb_cArray }.into()));
25722576
cmp(cb, REG0, REG1);
2573-
jit_chain_guard(JCC_JNE, jit, &starting_context, cb, OPT_AREF_MAX_CHAIN_DEPTH, side_exit);
2577+
jit_chain_guard(JCC_JNE, jit, &starting_context, cb, ocb, OPT_AREF_MAX_CHAIN_DEPTH, side_exit);
25742578

25752579
// Bail if idx is not a FIXNUM
25762580
mov(cb, REG1, idx_opnd);
@@ -2606,7 +2610,7 @@ fn gen_opt_aref(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb:
26062610

26072611
// Guard that the receiver is a hash
26082612
mov(cb, REG0, recv_opnd);
2609-
jit_guard_known_klass(jit, ctx, cb, unsafe { rb_cHash }, StackOpnd(1), comptime_recv, OPT_AREF_MAX_CHAIN_DEPTH, side_exit);
2613+
jit_guard_known_klass(jit, ctx, cb, ocb, unsafe { rb_cHash }, StackOpnd(1), comptime_recv, OPT_AREF_MAX_CHAIN_DEPTH, side_exit);
26102614

26112615
// Setup arguments for rb_hash_aref().
26122616
mov(cb, C_ARG_REGS[0], REG0);
@@ -2655,11 +2659,11 @@ fn gen_opt_aset(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb:
26552659

26562660
// Guard receiver is an Array
26572661
mov(cb, REG0, recv);
2658-
jit_guard_known_klass(jit, ctx, cb, unsafe { rb_cArray }, StackOpnd(2), comptime_recv, SEND_MAX_DEPTH, side_exit);
2662+
jit_guard_known_klass(jit, ctx, cb, ocb, unsafe { rb_cArray }, StackOpnd(2), comptime_recv, SEND_MAX_DEPTH, side_exit);
26592663

26602664
// Guard key is a fixnum
26612665
mov(cb, REG0, key);
2662-
jit_guard_known_klass(jit, ctx, cb, unsafe { rb_cInteger }, StackOpnd(1), comptime_key, SEND_MAX_DEPTH, side_exit);
2666+
jit_guard_known_klass(jit, ctx, cb, ocb, unsafe { rb_cInteger }, StackOpnd(1), comptime_key, SEND_MAX_DEPTH, side_exit);
26632667

26642668
// Call rb_ary_store
26652669
mov(cb, C_ARG_REGS[0], recv);
@@ -2689,7 +2693,7 @@ fn gen_opt_aset(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb:
26892693

26902694
// Guard receiver is a Hash
26912695
mov(cb, REG0, recv);
2692-
jit_guard_known_klass(jit, ctx, cb, unsafe { rb_cHash }, StackOpnd(2), comptime_recv, SEND_MAX_DEPTH, side_exit);
2696+
jit_guard_known_klass(jit, ctx, cb, ocb, unsafe { rb_cHash }, StackOpnd(2), comptime_recv, SEND_MAX_DEPTH, side_exit);
26932697

26942698
// Call rb_hash_aset
26952699
mov(cb, C_ARG_REGS[0], recv);
@@ -3017,6 +3021,8 @@ fn gen_branchif(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb:
30173021
gen_branch(
30183022
jit,
30193023
ctx,
3024+
cb,
3025+
ocb,
30203026
jump_block,
30213027
ctx,
30223028
Some(next_block),
@@ -3065,6 +3071,8 @@ fn gen_branchunless(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, o
30653071
gen_branch(
30663072
jit,
30673073
ctx,
3074+
cb,
3075+
ocb,
30683076
jump_block,
30693077
ctx,
30703078
Some(next_block),
@@ -3112,6 +3120,8 @@ fn gen_branchnil(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb:
31123120
gen_branch(
31133121
jit,
31143122
ctx,
3123+
cb,
3124+
ocb,
31153125
jump_block,
31163126
ctx,
31173127
Some(next_block),
@@ -3154,7 +3164,7 @@ fn gen_jump(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb: &mut
31543164
///
31553165
/// Recompile as contingency if possible, or take side exit a last resort.
31563166
3157-
fn jit_guard_known_klass(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, known_klass: VALUE, insn_opnd: InsnOpnd, sample_instance: VALUE, max_chain_depth: i32, side_exit: CodePtr) -> bool
3167+
fn jit_guard_known_klass(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb: &mut OutlinedCb, known_klass: VALUE, insn_opnd: InsnOpnd, sample_instance: VALUE, max_chain_depth: i32, side_exit: CodePtr) -> bool
31583168
{
31593169
let val_type = ctx.get_opnd_type(insn_opnd);
31603170

@@ -3165,7 +3175,7 @@ fn jit_guard_known_klass(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlo
31653175

31663176
add_comment(cb, "guard object is nil");
31673177
cmp(cb, REG0, imm_opnd(Qnil.into()));
3168-
jit_chain_guard(JCC_JNE, jit, ctx, cb, max_chain_depth, side_exit);
3178+
jit_chain_guard(JCC_JNE, jit, ctx, cb, ocb, max_chain_depth, side_exit);
31693179

31703180
ctx.upgrade_opnd_type(insn_opnd, Type::Nil);
31713181
}
@@ -3177,7 +3187,7 @@ fn jit_guard_known_klass(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlo
31773187

31783188
add_comment(cb, "guard object is true");
31793189
cmp(cb, REG0, imm_opnd(Qtrue.into()));
3180-
jit_chain_guard(JCC_JNE, jit, ctx, cb, max_chain_depth, side_exit);
3190+
jit_chain_guard(JCC_JNE, jit, ctx, cb, ocb, max_chain_depth, side_exit);
31813191

31823192
ctx.upgrade_opnd_type(insn_opnd, Type::True);
31833193
}
@@ -3190,7 +3200,7 @@ fn jit_guard_known_klass(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlo
31903200
add_comment(cb, "guard object is false");
31913201
assert!(Qfalse.as_i32() == 0);
31923202
test(cb, REG0, REG0);
3193-
jit_chain_guard(JCC_JNZ, jit, ctx, cb, max_chain_depth, side_exit);
3203+
jit_chain_guard(JCC_JNZ, jit, ctx, cb, ocb, max_chain_depth, side_exit);
31943204

31953205
ctx.upgrade_opnd_type(insn_opnd, Type::False);
31963206
}
@@ -3204,7 +3214,7 @@ fn jit_guard_known_klass(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlo
32043214

32053215
add_comment(cb, "guard object is fixnum");
32063216
test(cb, REG0, imm_opnd(RUBY_FIXNUM_FLAG as i64));
3207-
jit_chain_guard(JCC_JZ, jit, ctx, cb, max_chain_depth, side_exit);
3217+
jit_chain_guard(JCC_JZ, jit, ctx, cb, ocb, max_chain_depth, side_exit);
32083218
ctx.upgrade_opnd_type(insn_opnd, Type::Fixnum);
32093219
}
32103220
}
@@ -3218,7 +3228,7 @@ fn jit_guard_known_klass(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlo
32183228
add_comment(cb, "guard object is static symbol");
32193229
assert!(RUBY_SPECIAL_SHIFT == 8);
32203230
cmp(cb, REG0_8, uimm_opnd(RUBY_SYMBOL_FLAG as u64));
3221-
jit_chain_guard(JCC_JNE, jit, ctx, cb, max_chain_depth, side_exit);
3231+
jit_chain_guard(JCC_JNE, jit, ctx, cb, ocb, max_chain_depth, side_exit);
32223232
ctx.upgrade_opnd_type(insn_opnd, Type::ImmSymbol);
32233233
}
32243234
}
@@ -3232,7 +3242,7 @@ fn jit_guard_known_klass(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlo
32323242
mov(cb, REG1, REG0);
32333243
and(cb, REG1, uimm_opnd(RUBY_FLONUM_MASK as u64));
32343244
cmp(cb, REG1, uimm_opnd(RUBY_FLONUM_FLAG as u64));
3235-
jit_chain_guard(JCC_JNE, jit, ctx, cb, max_chain_depth, side_exit);
3245+
jit_chain_guard(JCC_JNE, jit, ctx, cb, ocb, max_chain_depth, side_exit);
32363246
ctx.upgrade_opnd_type(insn_opnd, Type::Flonum);
32373247
}
32383248
}
@@ -3252,7 +3262,7 @@ fn jit_guard_known_klass(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlo
32523262
// TODO: jit_mov_gc_ptr keeps a strong reference, which leaks the object.
32533263
jit_mov_gc_ptr(jit, cb, REG1, sample_instance);
32543264
cmp(cb, REG0, REG1);
3255-
jit_chain_guard(JCC_JNE, jit, ctx, cb, max_chain_depth, side_exit);
3265+
jit_chain_guard(JCC_JNE, jit, ctx, cb, ocb, max_chain_depth, side_exit);
32563266
}
32573267
else {
32583268
assert!(!val_type.is_imm());
@@ -3263,9 +3273,9 @@ fn jit_guard_known_klass(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlo
32633273
add_comment(cb, "guard not immediate");
32643274
assert!(Qfalse.as_i32() < Qnil.as_i32());
32653275
test(cb, REG0, imm_opnd(RUBY_IMMEDIATE_MASK as i64));
3266-
jit_chain_guard(JCC_JNZ, jit, ctx, cb, max_chain_depth, side_exit);
3276+
jit_chain_guard(JCC_JNZ, jit, ctx, cb, ocb, max_chain_depth, side_exit);
32673277
cmp(cb, REG0, imm_opnd(Qnil.into()));
3268-
jit_chain_guard(JCC_JBE, jit, ctx, cb, max_chain_depth, side_exit);
3278+
jit_chain_guard(JCC_JBE, jit, ctx, cb, ocb, max_chain_depth, side_exit);
32693279

32703280
ctx.upgrade_opnd_type(insn_opnd, Type::UnknownHeap);
32713281
}
@@ -3277,7 +3287,7 @@ fn jit_guard_known_klass(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlo
32773287
add_comment(cb, "guard known class");
32783288
jit_mov_gc_ptr(jit, cb, REG1, known_klass);
32793289
cmp(cb, klass_opnd, REG1);
3280-
jit_chain_guard(JCC_JNE, jit, ctx, cb, max_chain_depth, side_exit);
3290+
jit_chain_guard(JCC_JNE, jit, ctx, cb, ocb, max_chain_depth, side_exit);
32813291
}
32823292

32833293
true
@@ -4161,6 +4171,8 @@ fn gen_send_iseq(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, ocb:
41614171
gen_branch(
41624172
jit,
41634173
ctx,
4174+
cb,
4175+
ocb,
41644176
return_block,
41654177
&return_ctx,
41664178
Some(return_block),
@@ -4311,7 +4323,7 @@ fn gen_send_general(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, o
43114323
let recv = ctx.stack_opnd(argc);
43124324
let recv_opnd = StackOpnd(argc.try_into().unwrap());
43134325
mov(cb, REG0, recv);
4314-
if !jit_guard_known_klass(jit, ctx, cb, comptime_recv_klass, recv_opnd, comptime_recv, SEND_MAX_DEPTH, side_exit) {
4326+
if !jit_guard_known_klass(jit, ctx, cb, ocb, comptime_recv_klass, recv_opnd, comptime_recv, SEND_MAX_DEPTH, side_exit) {
43154327
return CantCompile;
43164328
}
43174329

@@ -4725,7 +4737,7 @@ fn gen_objtostring(jit: &mut JITState, ctx: &mut Context, cb: &mut CodeBlock, oc
47254737
let side_exit = get_side_exit(jit, ocb, ctx);
47264738

47274739
mov(cb, REG0, recv);
4728-
jit_guard_known_klass(jit, ctx, cb, comptime_recv.class_of(), StackOpnd(0), comptime_recv, SEND_MAX_DEPTH, side_exit);
4740+
jit_guard_known_klass(jit, ctx, cb, ocb, comptime_recv.class_of(), StackOpnd(0), comptime_recv, SEND_MAX_DEPTH, side_exit);
47294741
// No work needed. The string value is already on the top of the stack.
47304742
KeepCompiling
47314743
}

yjit/src/core.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,6 +1408,8 @@ fn get_branch_target(
14081408
pub fn gen_branch(
14091409
jit: &JITState,
14101410
src_ctx: &Context,
1411+
cb: &mut CodeBlock,
1412+
ocb: &mut OutlinedCb,
14111413
target0: BlockId,
14121414
ctx0: &Context,
14131415
target1: Option<BlockId>,
@@ -1417,23 +1419,23 @@ pub fn gen_branch(
14171419
{
14181420
//assert!(target0 != BLOCKID_NULL);
14191421

1420-
todo!("gen_branch() unimplemented");
1422+
let branchref = make_branch_entry(jit.get_block(), src_ctx, gen_jump_branch);
1423+
let mut branch = branchref.borrow_mut();
14211424

1422-
/*
1423-
branch_t *branch = make_branch_entry(jit->block, src_ctx, gen_fn);
1424-
branch->targets[0] = target0;
1425-
branch->targets[1] = target1;
1426-
branch->target_ctxs[0] = *ctx0;
1427-
branch->target_ctxs[1] = ctx1? *ctx1:DEFAULT_CTX;
1425+
branch.targets[0] = target0;
1426+
if target1.is_some() {
1427+
branch.targets[1] = target1.unwrap();
1428+
}
1429+
branch.target_ctxs[0] = *ctx0;
1430+
branch.target_ctxs[1] = if ctx1.is_some() { *ctx1.unwrap() } else { Context::default() };
14281431

14291432
// Get the branch targets or stubs
1430-
branch->dst_addrs[0] = get_branch_target(target0, ctx0, branch, 0);
1431-
branch->dst_addrs[1] = ctx1? get_branch_target(target1, ctx1, branch, 1):NULL;
1433+
branch.dst_addrs[0] = Some(get_branch_target(target0, ctx0, &branchref, 0, ocb));
1434+
branch.dst_addrs[1] = if ctx1.is_some() { Some(get_branch_target(target1.unwrap(), ctx1.unwrap(), &branchref, 1, ocb)) } else { None };
14321435

14331436
// Call the branch generation function
1434-
branch->start_addr = cb.get_write_ptr();
1435-
regenerate_branch(cb, branch);
1436-
*/
1437+
branch.start_addr = Some(cb.get_write_ptr());
1438+
regenerate_branch(cb, &mut branch);
14371439
}
14381440

14391441
fn gen_jump_branch(cb: &mut CodeBlock, target0: CodePtr, target1: Option<CodePtr>, shape: BranchShape)

0 commit comments

Comments
 (0)