summaryrefslogtreecommitdiff
path: root/yjit
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2023-08-23 19:07:30 -0400
committerAlan Wu <XrXr@users.noreply.github.com>2023-08-24 17:35:10 -0400
commitf61e620c4d68abeef1a220d7414d741bf3f981a8 (patch)
tree7eacbe885fa5404c1ad5dc190ee3a23d33bb409c /yjit
parent0e3dc5a056abf51363070ad94de4a8097bc80197 (diff)
YJIT: Move block handler SpecVal variants into BlockHandler
A refactor so that the variants correspond to branches in vm_caller_setup_arg_block().
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/8271
Diffstat (limited to 'yjit')
-rw-r--r--yjit/src/codegen.rs52
1 files changed, 27 insertions, 25 deletions
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index 7e44a05f00..e20734d7b5 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -5063,23 +5063,25 @@ unsafe extern "C" fn build_kwhash(ci: *const rb_callinfo, sp: *const VALUE) -> V
// at sp[-2]. Depending on the frame type, it can serve different purposes,
// which are covered here by enum variants.
enum SpecVal {
- None,
BlockHandler(BlockHandler),
- BlockParamProxy,
PrevEP(*const VALUE),
PrevEPOpnd(Opnd),
- // To avoid holding values across C calls for complex calls,
- // we might need to set the SpecVal earlier in the call sequence
- AlreadySet,
}
// Each variant represents a branch in vm_caller_setup_arg_block.
#[derive(Clone, Copy)]
pub enum BlockHandler {
+ // passing no block
+ None,
// send, invokesuper: blockiseq operand
BlockISeq(IseqPtr),
// invokesuper: GET_BLOCK_HANDLER() (GET_LEP()[VM_ENV_DATA_INDEX_SPECVAL])
LEPSpecVal,
+ // part of the allocate-free block forwarding scheme
+ BlockParamProxy,
+ // To avoid holding the block arg (e.g. proc and symbol) across C calls,
+ // we might need to set the block handler early in the call sequence
+ AlreadySet,
}
struct ControlFrame {
@@ -5127,11 +5129,11 @@ fn gen_push_frame(
// the outer environment depending on the frame type.
// sp[-2] = specval;
let specval: Opnd = match frame.specval {
- SpecVal::None => {
- VM_BLOCK_HANDLER_NONE.into()
- }
SpecVal::BlockHandler(block_handler) => {
match block_handler {
+ BlockHandler::None => {
+ VM_BLOCK_HANDLER_NONE.into()
+ }
BlockHandler::BlockISeq(block_iseq) => {
// Change cfp->block_code in the current frame. See vm_caller_setup_arg_block().
// VM_CFP_TO_CAPTURED_BLOCK does &cfp->self, rb_captured_block->code.iseq aliases
@@ -5145,17 +5147,18 @@ fn gen_push_frame(
let lep_opnd = gen_get_lep(jit, asm);
asm.load(Opnd::mem(64, lep_opnd, SIZEOF_VALUE_I32 * VM_ENV_DATA_INDEX_SPECVAL))
}
- }
- }
- SpecVal::BlockParamProxy => {
- let ep_opnd = gen_get_lep(jit, asm);
- let block_handler = asm.load(
- Opnd::mem(64, ep_opnd, SIZEOF_VALUE_I32 * VM_ENV_DATA_INDEX_SPECVAL)
- );
+ BlockHandler::BlockParamProxy => {
+ let ep_opnd = gen_get_lep(jit, asm);
+ let block_handler = asm.load(
+ Opnd::mem(64, ep_opnd, SIZEOF_VALUE_I32 * VM_ENV_DATA_INDEX_SPECVAL)
+ );
- asm.store(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_BLOCK_CODE), block_handler);
+ asm.store(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_BLOCK_CODE), block_handler);
- block_handler
+ block_handler
+ }
+ BlockHandler::AlreadySet => 0.into(), // unused
+ }
}
SpecVal::PrevEP(prev_ep) => {
let tagged_prev_ep = (prev_ep as usize) | 1;
@@ -5164,9 +5167,8 @@ fn gen_push_frame(
SpecVal::PrevEPOpnd(ep_opnd) => {
asm.or(ep_opnd, 1.into())
}
- SpecVal::AlreadySet => 0.into(), // unused
};
- if let SpecVal::AlreadySet = frame.specval {
+ if let SpecVal::BlockHandler(BlockHandler::AlreadySet) = frame.specval {
asm.comment("specval should have been set");
} else {
asm.store(Opnd::mem(64, sp, SIZEOF_VALUE_I32 * -2), specval);
@@ -5414,11 +5416,11 @@ fn gen_send_cfunc(
let sp = asm.lea(asm.ctx.sp_opnd((SIZEOF_VALUE as isize) * 3));
let specval = if block_arg_type == Some(Type::BlockParamProxy) {
- SpecVal::BlockParamProxy
+ SpecVal::BlockHandler(BlockHandler::BlockParamProxy)
} else if let Some(block_handler) = block {
SpecVal::BlockHandler(block_handler)
} else {
- SpecVal::None
+ SpecVal::BlockHandler(BlockHandler::None)
};
let mut frame_type = VM_FRAME_MAGIC_CFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL;
@@ -6457,14 +6459,14 @@ fn gen_send_iseq(
} else if let Some(captured_opnd) = captured_opnd {
let ep_opnd = asm.load(Opnd::mem(64, captured_opnd, SIZEOF_VALUE_I32)); // captured->ep
SpecVal::PrevEPOpnd(ep_opnd)
- } else if block_arg_type == Some(Type::BlockParamProxy) {
- SpecVal::BlockParamProxy
} else if let Some(Type::TProc) = block_arg_type {
- SpecVal::AlreadySet
+ SpecVal::BlockHandler(BlockHandler::AlreadySet)
+ } else if let Some(Type::BlockParamProxy) = block_arg_type {
+ SpecVal::BlockHandler(BlockHandler::BlockParamProxy)
} else if let Some(block_handler) = block {
SpecVal::BlockHandler(block_handler)
} else {
- SpecVal::None
+ SpecVal::BlockHandler(BlockHandler::None)
};
// Setup the new frame