Skip to content

Commit

Permalink
YJIT: Implement specialization for no-op {Kernel,Numeric}#dup
Browse files Browse the repository at this point in the history
Type information in the context for no additional work!

This is the `if (special_object_p(obj)) return obj;` path in
rb_obj_dup() and for Numeric#dup, it's always the identity function.
  • Loading branch information
XrXr committed Oct 21, 2024
1 parent 5131fb5 commit a6d9b88
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 0 deletions.
1 change: 1 addition & 0 deletions yjit/bindgen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ fn main() {
.allowlist_var("rb_cIO")
.allowlist_var("rb_cSymbol")
.allowlist_var("rb_cFloat")
.allowlist_var("rb_cNumeric")
.allowlist_var("rb_cString")
.allowlist_var("rb_cThread")
.allowlist_var("rb_cArray")
Expand Down
39 changes: 39 additions & 0 deletions yjit/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6347,6 +6347,42 @@ fn jit_thread_s_current(
true
}

fn jit_numeric_dup(
_jit: &mut JITState,
_asm: &mut Assembler,
_ci: *const rb_callinfo,
_cme: *const rb_callable_method_entry_t,
_block: Option<BlockHandler>,
_argc: i32,
_known_recv_class: Option<VALUE>,
) -> bool {
// Numeric#dup has arity=0 and is the identity function.
// Our caller already did argument count check, so this is
// no-op to return the receiver that is already on the stack.
true
}

/// Specialization for rb_obj_dup() (Kernel#dup)
fn jit_rb_obj_dup(
_jit: &mut JITState,
asm: &mut Assembler,
_ci: *const rb_callinfo,
_cme: *const rb_callable_method_entry_t,
_block: Option<BlockHandler>,
_argc: i32,
_known_recv_class: Option<VALUE>,
) -> bool {
// Kernel#dup has arity=0, and caller already did argument count check.
let self_type = asm.ctx.get_opnd_type(StackOpnd(0));

if self_type.is_imm() {
// Method is no-op when receiver is an immediate value.
true
} else {
false
}
}

/// Check if we know how to codegen for a particular cfunc method
/// See also: [reg_method_codegen].
fn lookup_cfunc_codegen(def: *const rb_method_definition_t) -> Option<MethodGenFn> {
Expand Down Expand Up @@ -10424,6 +10460,8 @@ pub fn yjit_reg_method_codegen_fns() {
reg_method_codegen(rb_cFloat, "*", jit_rb_float_mul);
reg_method_codegen(rb_cFloat, "/", jit_rb_float_div);

reg_method_codegen(rb_cNumeric, "dup", jit_numeric_dup);

reg_method_codegen(rb_cString, "empty?", jit_rb_str_empty_p);
reg_method_codegen(rb_cString, "to_s", jit_rb_str_to_s);
reg_method_codegen(rb_cString, "to_str", jit_rb_str_to_s);
Expand All @@ -10449,6 +10487,7 @@ pub fn yjit_reg_method_codegen_fns() {

reg_method_codegen(rb_mKernel, "respond_to?", jit_obj_respond_to);
reg_method_codegen(rb_mKernel, "block_given?", jit_rb_f_block_given_p);
reg_method_codegen(rb_mKernel, "dup", jit_rb_obj_dup);

reg_method_codegen(rb_cClass, "superclass", jit_rb_class_superclass);

Expand Down
1 change: 1 addition & 0 deletions yjit/src/cruby_bindings.inc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,7 @@ extern "C" {
pub static mut rb_cInteger: VALUE;
pub static mut rb_cModule: VALUE;
pub static mut rb_cNilClass: VALUE;
pub static mut rb_cNumeric: VALUE;
pub static mut rb_cString: VALUE;
pub static mut rb_cSymbol: VALUE;
pub static mut rb_cThread: VALUE;
Expand Down

0 comments on commit a6d9b88

Please sign in to comment.