Skip to content

Commit 20c5a3e

Browse files
authored
YJIT: Rename method substitution functions and improve docs (+1) (ruby#11919)
* YJIT: Fill in commented-out assertion * YJIT: Rename yjit_reg_method() and add links in docs
1 parent 6588bbf commit 20c5a3e

File tree

1 file changed

+81
-78
lines changed

1 file changed

+81
-78
lines changed

yjit/src/codegen.rs

Lines changed: 81 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -6347,7 +6347,8 @@ fn jit_thread_s_current(
63476347
true
63486348
}
63496349

6350-
// Check if we know how to codegen for a particular cfunc method
6350+
/// Check if we know how to codegen for a particular cfunc method
6351+
/// See also: [reg_method_codegen].
63516352
fn lookup_cfunc_codegen(def: *const rb_method_definition_t) -> Option<MethodGenFn> {
63526353
let method_serial = unsafe { get_def_method_serial(def) };
63536354
let table = unsafe { METHOD_CODEGEN_TABLE.as_ref().unwrap() };
@@ -10368,9 +10369,9 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> {
1036810369
}
1036910370
}
1037010371

10371-
// Return true when the codegen function generates code.
10372-
// known_recv_class has Some value when the caller has used jit_guard_known_klass().
10373-
// See yjit_reg_method().
10372+
/// Return true when the codegen function generates code.
10373+
/// known_recv_class has Some value when the caller has used jit_guard_known_klass().
10374+
/// See [reg_method_codegen]
1037410375
type MethodGenFn = fn(
1037510376
jit: &mut JITState,
1037610377
asm: &mut Assembler,
@@ -10390,77 +10391,80 @@ pub fn yjit_reg_method_codegen_fns() {
1039010391
assert!(METHOD_CODEGEN_TABLE.is_none());
1039110392
METHOD_CODEGEN_TABLE = Some(HashMap::default());
1039210393

10393-
// Specialization for C methods. See yjit_reg_method() for details.
10394-
yjit_reg_method(rb_cBasicObject, "!", jit_rb_obj_not);
10395-
10396-
yjit_reg_method(rb_cNilClass, "nil?", jit_rb_true);
10397-
yjit_reg_method(rb_mKernel, "nil?", jit_rb_false);
10398-
yjit_reg_method(rb_mKernel, "is_a?", jit_rb_kernel_is_a);
10399-
yjit_reg_method(rb_mKernel, "kind_of?", jit_rb_kernel_is_a);
10400-
yjit_reg_method(rb_mKernel, "instance_of?", jit_rb_kernel_instance_of);
10401-
10402-
yjit_reg_method(rb_cBasicObject, "==", jit_rb_obj_equal);
10403-
yjit_reg_method(rb_cBasicObject, "equal?", jit_rb_obj_equal);
10404-
yjit_reg_method(rb_cBasicObject, "!=", jit_rb_obj_not_equal);
10405-
yjit_reg_method(rb_mKernel, "eql?", jit_rb_obj_equal);
10406-
yjit_reg_method(rb_cModule, "==", jit_rb_obj_equal);
10407-
yjit_reg_method(rb_cModule, "===", jit_rb_mod_eqq);
10408-
yjit_reg_method(rb_cModule, "name", jit_rb_mod_name);
10409-
yjit_reg_method(rb_cSymbol, "==", jit_rb_obj_equal);
10410-
yjit_reg_method(rb_cSymbol, "===", jit_rb_obj_equal);
10411-
yjit_reg_method(rb_cInteger, "==", jit_rb_int_equal);
10412-
yjit_reg_method(rb_cInteger, "===", jit_rb_int_equal);
10413-
10414-
yjit_reg_method(rb_cInteger, "succ", jit_rb_int_succ);
10415-
yjit_reg_method(rb_cInteger, "/", jit_rb_int_div);
10416-
yjit_reg_method(rb_cInteger, "<<", jit_rb_int_lshift);
10417-
yjit_reg_method(rb_cInteger, ">>", jit_rb_int_rshift);
10418-
yjit_reg_method(rb_cInteger, "^", jit_rb_int_xor);
10419-
yjit_reg_method(rb_cInteger, "[]", jit_rb_int_aref);
10420-
10421-
yjit_reg_method(rb_cFloat, "+", jit_rb_float_plus);
10422-
yjit_reg_method(rb_cFloat, "-", jit_rb_float_minus);
10423-
yjit_reg_method(rb_cFloat, "*", jit_rb_float_mul);
10424-
yjit_reg_method(rb_cFloat, "/", jit_rb_float_div);
10425-
10426-
yjit_reg_method(rb_cString, "empty?", jit_rb_str_empty_p);
10427-
yjit_reg_method(rb_cString, "to_s", jit_rb_str_to_s);
10428-
yjit_reg_method(rb_cString, "to_str", jit_rb_str_to_s);
10429-
yjit_reg_method(rb_cString, "length", jit_rb_str_length);
10430-
yjit_reg_method(rb_cString, "size", jit_rb_str_length);
10431-
yjit_reg_method(rb_cString, "bytesize", jit_rb_str_bytesize);
10432-
yjit_reg_method(rb_cString, "getbyte", jit_rb_str_getbyte);
10433-
yjit_reg_method(rb_cString, "setbyte", jit_rb_str_setbyte);
10434-
yjit_reg_method(rb_cString, "byteslice", jit_rb_str_byteslice);
10435-
yjit_reg_method(rb_cString, "<<", jit_rb_str_concat);
10436-
yjit_reg_method(rb_cString, "+@", jit_rb_str_uplus);
10437-
10438-
yjit_reg_method(rb_cNilClass, "===", jit_rb_case_equal);
10439-
yjit_reg_method(rb_cTrueClass, "===", jit_rb_case_equal);
10440-
yjit_reg_method(rb_cFalseClass, "===", jit_rb_case_equal);
10441-
10442-
yjit_reg_method(rb_cArray, "empty?", jit_rb_ary_empty_p);
10443-
yjit_reg_method(rb_cArray, "length", jit_rb_ary_length);
10444-
yjit_reg_method(rb_cArray, "size", jit_rb_ary_length);
10445-
yjit_reg_method(rb_cArray, "<<", jit_rb_ary_push);
10446-
10447-
yjit_reg_method(rb_cHash, "empty?", jit_rb_hash_empty_p);
10448-
10449-
yjit_reg_method(rb_mKernel, "respond_to?", jit_obj_respond_to);
10450-
yjit_reg_method(rb_mKernel, "block_given?", jit_rb_f_block_given_p);
10451-
10452-
yjit_reg_method(rb_cClass, "superclass", jit_rb_class_superclass);
10453-
10454-
yjit_reg_method(rb_singleton_class(rb_cThread), "current", jit_thread_s_current);
10455-
}
10456-
}
10457-
10458-
// Register a specialized codegen function for a particular method. Note that
10459-
// if the function returns true, the code it generates runs without a
10460-
// control frame and without interrupt checks. To avoid creating observable
10461-
// behavior changes, the codegen function should only target simple code paths
10462-
// that do not allocate and do not make method calls.
10463-
fn yjit_reg_method(klass: VALUE, mid_str: &str, gen_fn: MethodGenFn) {
10394+
// Specialization for C methods. See the function's docs for details.
10395+
reg_method_codegen(rb_cBasicObject, "!", jit_rb_obj_not);
10396+
10397+
reg_method_codegen(rb_cNilClass, "nil?", jit_rb_true);
10398+
reg_method_codegen(rb_mKernel, "nil?", jit_rb_false);
10399+
reg_method_codegen(rb_mKernel, "is_a?", jit_rb_kernel_is_a);
10400+
reg_method_codegen(rb_mKernel, "kind_of?", jit_rb_kernel_is_a);
10401+
reg_method_codegen(rb_mKernel, "instance_of?", jit_rb_kernel_instance_of);
10402+
10403+
reg_method_codegen(rb_cBasicObject, "==", jit_rb_obj_equal);
10404+
reg_method_codegen(rb_cBasicObject, "equal?", jit_rb_obj_equal);
10405+
reg_method_codegen(rb_cBasicObject, "!=", jit_rb_obj_not_equal);
10406+
reg_method_codegen(rb_mKernel, "eql?", jit_rb_obj_equal);
10407+
reg_method_codegen(rb_cModule, "==", jit_rb_obj_equal);
10408+
reg_method_codegen(rb_cModule, "===", jit_rb_mod_eqq);
10409+
reg_method_codegen(rb_cModule, "name", jit_rb_mod_name);
10410+
reg_method_codegen(rb_cSymbol, "==", jit_rb_obj_equal);
10411+
reg_method_codegen(rb_cSymbol, "===", jit_rb_obj_equal);
10412+
reg_method_codegen(rb_cInteger, "==", jit_rb_int_equal);
10413+
reg_method_codegen(rb_cInteger, "===", jit_rb_int_equal);
10414+
10415+
reg_method_codegen(rb_cInteger, "succ", jit_rb_int_succ);
10416+
reg_method_codegen(rb_cInteger, "/", jit_rb_int_div);
10417+
reg_method_codegen(rb_cInteger, "<<", jit_rb_int_lshift);
10418+
reg_method_codegen(rb_cInteger, ">>", jit_rb_int_rshift);
10419+
reg_method_codegen(rb_cInteger, "^", jit_rb_int_xor);
10420+
reg_method_codegen(rb_cInteger, "[]", jit_rb_int_aref);
10421+
10422+
reg_method_codegen(rb_cFloat, "+", jit_rb_float_plus);
10423+
reg_method_codegen(rb_cFloat, "-", jit_rb_float_minus);
10424+
reg_method_codegen(rb_cFloat, "*", jit_rb_float_mul);
10425+
reg_method_codegen(rb_cFloat, "/", jit_rb_float_div);
10426+
10427+
reg_method_codegen(rb_cString, "empty?", jit_rb_str_empty_p);
10428+
reg_method_codegen(rb_cString, "to_s", jit_rb_str_to_s);
10429+
reg_method_codegen(rb_cString, "to_str", jit_rb_str_to_s);
10430+
reg_method_codegen(rb_cString, "length", jit_rb_str_length);
10431+
reg_method_codegen(rb_cString, "size", jit_rb_str_length);
10432+
reg_method_codegen(rb_cString, "bytesize", jit_rb_str_bytesize);
10433+
reg_method_codegen(rb_cString, "getbyte", jit_rb_str_getbyte);
10434+
reg_method_codegen(rb_cString, "setbyte", jit_rb_str_setbyte);
10435+
reg_method_codegen(rb_cString, "byteslice", jit_rb_str_byteslice);
10436+
reg_method_codegen(rb_cString, "<<", jit_rb_str_concat);
10437+
reg_method_codegen(rb_cString, "+@", jit_rb_str_uplus);
10438+
10439+
reg_method_codegen(rb_cNilClass, "===", jit_rb_case_equal);
10440+
reg_method_codegen(rb_cTrueClass, "===", jit_rb_case_equal);
10441+
reg_method_codegen(rb_cFalseClass, "===", jit_rb_case_equal);
10442+
10443+
reg_method_codegen(rb_cArray, "empty?", jit_rb_ary_empty_p);
10444+
reg_method_codegen(rb_cArray, "length", jit_rb_ary_length);
10445+
reg_method_codegen(rb_cArray, "size", jit_rb_ary_length);
10446+
reg_method_codegen(rb_cArray, "<<", jit_rb_ary_push);
10447+
10448+
reg_method_codegen(rb_cHash, "empty?", jit_rb_hash_empty_p);
10449+
10450+
reg_method_codegen(rb_mKernel, "respond_to?", jit_obj_respond_to);
10451+
reg_method_codegen(rb_mKernel, "block_given?", jit_rb_f_block_given_p);
10452+
10453+
reg_method_codegen(rb_cClass, "superclass", jit_rb_class_superclass);
10454+
10455+
reg_method_codegen(rb_singleton_class(rb_cThread), "current", jit_thread_s_current);
10456+
}
10457+
}
10458+
10459+
/// Register a specialized codegen function for a particular method. Note that
10460+
/// if the function returns true, the code it generates runs without a
10461+
/// control frame and without interrupt checks, completely substituting the
10462+
/// original implementation of the method. To avoid creating observable
10463+
/// behavior changes, prefer targeting simple code paths that do not allocate
10464+
/// and do not make method calls.
10465+
///
10466+
/// See also: [lookup_cfunc_codegen].
10467+
fn reg_method_codegen(klass: VALUE, mid_str: &str, gen_fn: MethodGenFn) {
1046410468
let id_string = std::ffi::CString::new(mid_str).expect("couldn't convert to CString!");
1046510469
let mid = unsafe { rb_intern(id_string.as_ptr()) };
1046610470
let me = unsafe { rb_method_entry_at(klass, mid) };
@@ -10469,9 +10473,8 @@ fn yjit_reg_method(klass: VALUE, mid_str: &str, gen_fn: MethodGenFn) {
1046910473
panic!("undefined optimized method!: {mid_str}");
1047010474
}
1047110475

10472-
// For now, only cfuncs are supported
10473-
//RUBY_ASSERT(me && me->def);
10474-
//RUBY_ASSERT(me->def->type == VM_METHOD_TYPE_CFUNC);
10476+
// For now, only cfuncs are supported (me->cme cast fine since it's just me->def->type).
10477+
debug_assert_eq!(VM_METHOD_TYPE_CFUNC, unsafe { get_cme_def_type(me.cast()) });
1047510478

1047610479
let method_serial = unsafe {
1047710480
let def = (*me).def;

0 commit comments

Comments
 (0)