YJIT: Get rid of Type::TProc (#10287)

This commit is contained in:
Takashi Kokubun 2024-03-20 08:29:27 -07:00 committed by GitHub
parent e07441f05f
commit 4238615432
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 21 additions and 19 deletions

View File

@ -7095,15 +7095,15 @@ fn gen_send_iseq(
} }
match block_arg_type { match block_arg_type {
Some(Type::Nil) => { Some(BlockArg::Nil) => {
// We have a nil block arg, so let's pop it off the args // We have a nil block arg, so let's pop it off the args
asm.stack_pop(1); asm.stack_pop(1);
} }
Some(Type::BlockParamProxy) => { Some(BlockArg::BlockParamProxy) => {
// We don't need the actual stack value // We don't need the actual stack value
asm.stack_pop(1); asm.stack_pop(1);
} }
Some(Type::TProc) => { Some(BlockArg::TProc) => {
// Place the proc as the block handler. We do this early because // Place the proc as the block handler. We do this early because
// the block arg being at the top of the stack gets in the way of // the block arg being at the top of the stack gets in the way of
// rest param handling later. Also, since there are C calls that // rest param handling later. Also, since there are C calls that
@ -7136,7 +7136,6 @@ fn gen_send_iseq(
None => { None => {
// Nothing to do // Nothing to do
} }
_ => unreachable!(),
} }
if kw_splat { if kw_splat {
@ -7396,9 +7395,9 @@ fn gen_send_iseq(
} else if let Some(captured_opnd) = captured_opnd { } else if let Some(captured_opnd) = captured_opnd {
let ep_opnd = asm.load(Opnd::mem(64, captured_opnd, SIZEOF_VALUE_I32)); // captured->ep let ep_opnd = asm.load(Opnd::mem(64, captured_opnd, SIZEOF_VALUE_I32)); // captured->ep
SpecVal::PrevEPOpnd(ep_opnd) SpecVal::PrevEPOpnd(ep_opnd)
} else if let Some(Type::TProc) = block_arg_type { } else if let Some(BlockArg::TProc) = block_arg_type {
SpecVal::BlockHandler(Some(BlockHandler::AlreadySet)) SpecVal::BlockHandler(Some(BlockHandler::AlreadySet))
} else if let Some(Type::BlockParamProxy) = block_arg_type { } else if let Some(BlockArg::BlockParamProxy) = block_arg_type {
SpecVal::BlockHandler(Some(BlockHandler::BlockParamProxy)) SpecVal::BlockHandler(Some(BlockHandler::BlockParamProxy))
} else { } else {
SpecVal::BlockHandler(block) SpecVal::BlockHandler(block)
@ -7942,12 +7941,22 @@ fn exit_if_has_rest_and_optional_and_block(asm: &mut Assembler, iseq_has_rest: b
) )
} }
#[derive(Clone, Copy)]
enum BlockArg {
Nil,
/// A special sentinel value indicating the block parameter should be read from
/// the current surrounding cfp
BlockParamProxy,
/// A proc object. Could be an instance of a subclass of ::rb_cProc
TProc,
}
#[must_use] #[must_use]
fn exit_if_unsupported_block_arg_type( fn exit_if_unsupported_block_arg_type(
jit: &mut JITState, jit: &mut JITState,
asm: &mut Assembler, asm: &mut Assembler,
supplying_block_arg: bool supplying_block_arg: bool
) -> Option<Option<Type>> { ) -> Option<Option<BlockArg>> {
let block_arg_type = if supplying_block_arg { let block_arg_type = if supplying_block_arg {
asm.ctx.get_opnd_type(StackOpnd(0)) asm.ctx.get_opnd_type(StackOpnd(0))
} else { } else {
@ -7956,16 +7965,15 @@ fn exit_if_unsupported_block_arg_type(
}; };
match block_arg_type { match block_arg_type {
Type::Nil | Type::BlockParamProxy => { // We'll handle Nil and BlockParamProxy later
// We'll handle this later Type::Nil => Some(Some(BlockArg::Nil)),
Some(Some(block_arg_type)) Type::BlockParamProxy => Some(Some(BlockArg::BlockParamProxy)),
}
_ if { _ if {
let sample_block_arg = jit.peek_at_stack(&asm.ctx, 0); let sample_block_arg = jit.peek_at_stack(&asm.ctx, 0);
unsafe { rb_obj_is_proc(sample_block_arg) }.test() unsafe { rb_obj_is_proc(sample_block_arg) }.test()
} => { } => {
// Speculate that we'll have a proc as the block arg // Speculate that we'll have a proc as the block arg
Some(Some(Type::TProc)) Some(Some(BlockArg::TProc))
} }
_ => { _ => {
gen_counter_incr(asm, Counter::send_iseq_block_arg_type); gen_counter_incr(asm, Counter::send_iseq_block_arg_type);

View File

@ -60,13 +60,11 @@ pub enum Type {
TArray, // An object with the T_ARRAY flag set, possibly an rb_cArray TArray, // An object with the T_ARRAY flag set, possibly an rb_cArray
THash, // An object with the T_HASH flag set, possibly an rb_cHash THash, // An object with the T_HASH flag set, possibly an rb_cHash
TProc, // A proc object. Could be an instance of a subclass of ::rb_cProc
BlockParamProxy, // A special sentinel value indicating the block parameter should be read from BlockParamProxy, // A special sentinel value indicating the block parameter should be read from
// the current surrounding cfp // the current surrounding cfp
// The context currently relies on types taking at most 4 bits (max value 15) // The context currently relies on types taking at most 4 bits (max value 15)
// to encode, so if we add any more, we will need to refactor the context, // to encode, so if we add two more, we will need to refactor the context,
// or we could remove HeapSymbol, which is currently unused. // or we could remove HeapSymbol, which is currently unused.
} }
@ -113,8 +111,6 @@ impl Type {
RUBY_T_ARRAY => Type::TArray, RUBY_T_ARRAY => Type::TArray,
RUBY_T_HASH => Type::THash, RUBY_T_HASH => Type::THash,
RUBY_T_STRING => Type::TString, RUBY_T_STRING => Type::TString,
#[cfg(not(test))]
RUBY_T_DATA if unsafe { rb_obj_is_proc(val).test() } => Type::TProc,
_ => Type::UnknownHeap, _ => Type::UnknownHeap,
} }
} }
@ -159,7 +155,6 @@ impl Type {
Type::TString => true, Type::TString => true,
Type::CString => true, Type::CString => true,
Type::BlockParamProxy => true, Type::BlockParamProxy => true,
Type::TProc => true,
_ => false, _ => false,
} }
} }
@ -195,7 +190,6 @@ impl Type {
Type::THash => Some(RUBY_T_HASH), Type::THash => Some(RUBY_T_HASH),
Type::ImmSymbol | Type::HeapSymbol => Some(RUBY_T_SYMBOL), Type::ImmSymbol | Type::HeapSymbol => Some(RUBY_T_SYMBOL),
Type::TString | Type::CString => Some(RUBY_T_STRING), Type::TString | Type::CString => Some(RUBY_T_STRING),
Type::TProc => Some(RUBY_T_DATA),
Type::Unknown | Type::UnknownImm | Type::UnknownHeap => None, Type::Unknown | Type::UnknownImm | Type::UnknownHeap => None,
Type::BlockParamProxy => None, Type::BlockParamProxy => None,
} }