@@ -1854,6 +1854,7 @@ check_cfunc(const rb_callable_method_entry_t *me, VALUE (*func)())
18541854static inline int
18551855vm_method_cfunc_is (const rb_iseq_t * iseq , CALL_DATA cd , VALUE recv , VALUE (* func )())
18561856{
1857+ VM_ASSERT (iseq != NULL );
18571858 const struct rb_callcache * cc = vm_search_method ((VALUE )iseq , cd , recv );
18581859 return check_cfunc (vm_cc_cme (cc ), func );
18591860}
@@ -1890,7 +1891,7 @@ FLONUM_2_P(VALUE a, VALUE b)
18901891}
18911892
18921893static VALUE
1893- opt_equality ( const rb_iseq_t * cd_owner , VALUE recv , VALUE obj , CALL_DATA cd )
1894+ opt_equality_specialized ( VALUE recv , VALUE obj )
18941895{
18951896 if (FIXNUM_2_P (recv , obj ) && EQ_UNREDEFINED_P (INTEGER )) {
18961897 goto compare_by_identity ;
@@ -1902,7 +1903,7 @@ opt_equality(const rb_iseq_t *cd_owner, VALUE recv, VALUE obj, CALL_DATA cd)
19021903 goto compare_by_identity ;
19031904 }
19041905 else if (SPECIAL_CONST_P (recv )) {
1905- goto compare_by_funcall ;
1906+ //
19061907 }
19071908 else if (RBASIC_CLASS (recv ) == rb_cFloat && RB_FLOAT_TYPE_P (obj ) && EQ_UNREDEFINED_P (FLOAT )) {
19081909 double a = RFLOAT_VALUE (recv );
@@ -1932,11 +1933,7 @@ opt_equality(const rb_iseq_t *cd_owner, VALUE recv, VALUE obj, CALL_DATA cd)
19321933 return rb_str_eql_internal (obj , recv );
19331934 }
19341935 }
1935-
1936- compare_by_funcall :
1937- if (! vm_method_cfunc_is (cd_owner , cd , recv , rb_obj_equal )) {
1938- return Qundef ;
1939- }
1936+ return Qundef ;
19401937
19411938 compare_by_identity :
19421939 if (recv == obj ) {
@@ -1947,47 +1944,77 @@ opt_equality(const rb_iseq_t *cd_owner, VALUE recv, VALUE obj, CALL_DATA cd)
19471944 }
19481945}
19491946
1947+ static VALUE
1948+ opt_equality (const rb_iseq_t * cd_owner , VALUE recv , VALUE obj , CALL_DATA cd )
1949+ {
1950+ VM_ASSERT (cd_owner != NULL );
1951+
1952+ VALUE val = opt_equality_specialized (recv , obj );
1953+ if (val != Qundef ) return val ;
1954+
1955+ if (!vm_method_cfunc_is (cd_owner , cd , recv , rb_obj_equal )) {
1956+ return Qundef ;
1957+ }
1958+ else {
1959+ if (recv == obj ) {
1960+ return Qtrue ;
1961+ }
1962+ else {
1963+ return Qfalse ;
1964+ }
1965+ }
1966+ }
1967+
19501968#undef EQ_UNREDEFINED_P
19511969
19521970#ifndef MJIT_HEADER
1953- VALUE
1954- rb_equal_opt (VALUE obj1 , VALUE obj2 )
1971+
1972+ static inline const struct rb_callcache * gccct_method_search (rb_execution_context_t * ec , VALUE recv , ID mid , int argc ); // vm_eval.c
1973+ NOINLINE (static VALUE opt_equality_by_mid_slowpath (VALUE recv , VALUE obj , ID mid ));
1974+
1975+ static VALUE
1976+ opt_equality_by_mid_slowpath (VALUE recv , VALUE obj , ID mid )
19551977{
1956- STATIC_ASSERT ( idEq_is_embeddable , VM_CI_EMBEDDABLE_P ( idEq , 0 , 1 , 0 ) );
1978+ const struct rb_callcache * cc = gccct_method_search ( GET_EC (), recv , mid , 1 );
19571979
1958- #if USE_EMBED_CI
1959- static struct rb_call_data cd = {
1960- .ci = vm_ci_new_id (idEq , 0 , 1 , 0 ),
1961- };
1962- #else
1963- struct rb_call_data cd = {
1964- .ci = & VM_CI_ON_STACK (idEq , 0 , 1 , 0 ),
1965- };
1966- #endif
1980+ if (cc && check_cfunc (vm_cc_cme (cc ), rb_obj_equal )) {
1981+ if (recv == obj ) {
1982+ return Qtrue ;
1983+ }
1984+ else {
1985+ return Qfalse ;
1986+ }
1987+ }
1988+ else {
1989+ return Qundef ;
1990+ }
1991+ }
19671992
1968- cd .cc = & vm_empty_cc ;
1969- return opt_equality (NULL , obj1 , obj2 , & cd );
1993+ static VALUE
1994+ opt_equality_by_mid (VALUE recv , VALUE obj , ID mid )
1995+ {
1996+ VALUE val = opt_equality_specialized (recv , obj );
1997+ if (val != Qundef ) {
1998+ return val ;
1999+ }
2000+ else {
2001+ return opt_equality_by_mid_slowpath (recv , obj , mid );
2002+ }
19702003}
19712004
19722005VALUE
1973- rb_eql_opt (VALUE obj1 , VALUE obj2 )
2006+ rb_equal_opt (VALUE obj1 , VALUE obj2 )
19742007{
1975- STATIC_ASSERT (idEqlP_is_embeddable , VM_CI_EMBEDDABLE_P (idEqlP , 0 , 1 , 0 ));
1976-
1977- #if USE_EMBED_CI
1978- static struct rb_call_data cd = {
1979- .ci = vm_ci_new_id (idEqlP , 0 , 1 , 0 ),
1980- };
1981- #else
1982- struct rb_call_data cd = {
1983- .ci = & VM_CI_ON_STACK (idEqlP , 0 , 1 , 0 ),
1984- };
1985- #endif
2008+ return opt_equality_by_mid (obj1 , obj2 , idEq );
2009+ }
19862010
1987- cd .cc = & vm_empty_cc ;
1988- return opt_equality (NULL , obj1 , obj2 , & cd );
2011+ VALUE
2012+ rb_eql_opt (VALUE obj1 , VALUE obj2 )
2013+ {
2014+ return opt_equality_by_mid (obj1 , obj2 , idEqlP );
19892015}
1990- #endif
2016+
2017+ #endif // MJIT_HEADER
19912018
19922019extern VALUE rb_vm_call0 (rb_execution_context_t * ec , VALUE , ID , int , const VALUE * , const rb_callable_method_entry_t * , int kw_splat );
19932020
0 commit comments