@@ -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].
63516352fn 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]
1037410375type 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