Skip to content

Commit a322ab5

Browse files
committed
Expand Builtins to more types and methods
This includes all the methods and classes in CRuby's version of the builtin checks, with a few additional classes and methods. I have generated all combinations here, though class+method combinations that don't make sense should be removed eventually. This commit also replaces most fast-path uses of `isBuiltin` methods throughout JRuby with the equivalent builtin check, but there are many that have been added to CRuby in recent years. Future commits will add those additional fast paths. Based off work by @CufeHaco in jruby#9174 merged with my extensions and integration from jruby#9123. See jruby#9116 and jruby#9119
1 parent bb0b3af commit a322ab5

13 files changed

Lines changed: 202 additions & 142 deletions

File tree

core/src/main/java/org/jruby/RubyArray.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
import org.jruby.javasupport.JavaUtil;
6565
import org.jruby.runtime.Arity;
6666
import org.jruby.runtime.Block;
67+
import org.jruby.runtime.Builtins;
6768
import org.jruby.runtime.CallSite;
6869
import org.jruby.runtime.ClassIndex;
6970
import org.jruby.runtime.Helpers;
@@ -4045,8 +4046,8 @@ public DefaultComparator(ThreadContext context) {
40454046
DefaultComparator(ThreadContext context, final boolean honorOverride) {
40464047
this.context = context;
40474048
if ( honorOverride && context != null ) {
4048-
this.fixnumBypass = !honorOverride || fixnumClass(context).isMethodBuiltin("<=>");
4049-
this.stringBypass = !honorOverride || stringClass(context).isMethodBuiltin("<=>");
4049+
this.fixnumBypass = !honorOverride || Builtins.checkIntegerCmp(context);
4050+
this.stringBypass = !honorOverride || Builtins.checkStringCmp(context);
40504051
}
40514052
else { // no-opt
40524053
this.fixnumBypass = false;

core/src/main/java/org/jruby/RubyBignum.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.jruby.api.Convert;
4343
import org.jruby.api.Create;
4444
import org.jruby.api.JRubyAPI;
45+
import org.jruby.runtime.Builtins;
4546
import org.jruby.runtime.CallSite;
4647
import org.jruby.runtime.ClassIndex;
4748
import org.jruby.runtime.Helpers;
@@ -1289,20 +1290,18 @@ public IRubyObject fdivFloat(ThreadContext context, RubyFloat y) {
12891290

12901291
@Override
12911292
public IRubyObject isNegative(ThreadContext context) {
1292-
CachingCallSite op_lt_site = sites(context).basic_op_lt;
1293-
if (op_lt_site.isBuiltin(metaClass)) {
1293+
if (Builtins.checkIntegerLt(context)) {
12941294
return asBoolean(context, value.signum() < 0);
12951295
}
1296-
return op_lt_site.call(context, this, this, zero(context.runtime));
1296+
return sites(context).basic_op_lt.call(context, this, this, zero(context.runtime));
12971297
}
12981298

12991299
@Override
13001300
public IRubyObject isPositive(ThreadContext context) {
1301-
CachingCallSite op_gt_site = sites(context).basic_op_gt;
1302-
if (op_gt_site.isBuiltin(metaClass)) {
1301+
if (Builtins.checkIntegerGt(context)) {
13031302
return asBoolean(context, value.signum() > 0);
13041303
}
1305-
return op_gt_site.call(context, this, this, zero(context.runtime));
1304+
return sites(context).basic_op_gt.call(context, this, this, zero(context.runtime));
13061305
}
13071306

13081307
@Override

core/src/main/java/org/jruby/RubyFixnum.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.jruby.api.JRubyAPI;
4646
import org.jruby.compiler.Constantizable;
4747
import org.jruby.runtime.Block;
48+
import org.jruby.runtime.Builtins;
4849
import org.jruby.runtime.CallSite;
4950
import org.jruby.runtime.ClassIndex;
5051
import org.jruby.runtime.Helpers;
@@ -1563,20 +1564,18 @@ public IRubyObject fdivDouble(ThreadContext context, IRubyObject y) {
15631564

15641565
@Override
15651566
public IRubyObject isNegative(ThreadContext context) {
1566-
CachingCallSite op_lt_site = sites(context).basic_op_lt;
1567-
if (op_lt_site.isBuiltin(metaClass)) {
1567+
if (Builtins.checkIntegerLt(context)) {
15681568
return asBoolean(context, getValue() < 0);
15691569
}
1570-
return op_lt_site.call(context, this, this, asFixnum(context, 0));
1570+
return sites(context).basic_op_lt.call(context, this, this, asFixnum(context, 0));
15711571
}
15721572

15731573
@Override
15741574
public IRubyObject isPositive(ThreadContext context) {
1575-
CachingCallSite op_gt_site = sites(context).basic_op_gt;
1576-
if (op_gt_site.isBuiltin(metaClass)) {
1575+
if (Builtins.checkIntegerGt(context)) {
15771576
return asBoolean(context, getValue() > 0);
15781577
}
1579-
return op_gt_site.call(context, this, this, asFixnum(context, 0));
1578+
return sites(context).basic_op_gt.call(context, this, this, asFixnum(context, 0));
15801579
}
15811580

15821581
@Override

core/src/main/java/org/jruby/RubyHash.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import org.jruby.javasupport.JavaUtil;
5252
import org.jruby.runtime.Arity;
5353
import org.jruby.runtime.Block;
54+
import org.jruby.runtime.Builtins;
5455
import org.jruby.runtime.CallBlock19;
5556
import org.jruby.runtime.ClassIndex;
5657
import org.jruby.runtime.Helpers;
@@ -2009,7 +2010,9 @@ public IRubyObject shift(ThreadContext context) {
20092010

20102011

20112012
CachingCallSite self_default = sites(context).self_default;
2012-
if (self_default.isBuiltin(this)) return default_value_get(context, context.nil);
2013+
if (metaClass == context.runtime.getHash() && Builtins.checkHashDefault(context)) {
2014+
return default_value_get(context, context.nil);
2015+
}
20132016

20142017
return self_default.call(context, this, this, context.nil);
20152018
}

core/src/main/java/org/jruby/RubyInteger.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import org.jruby.ast.util.ArgsUtil;
4747
import org.jruby.runtime.Arity;
4848
import org.jruby.runtime.Block;
49+
import org.jruby.runtime.Builtins;
4950
import org.jruby.runtime.CallSite;
5051
import org.jruby.runtime.ClassIndex;
5152
import org.jruby.runtime.JavaSites;

core/src/main/java/org/jruby/RubyNumeric.java

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import org.jruby.javasupport.JavaUtil;
4545
import org.jruby.runtime.Arity;
4646
import org.jruby.runtime.Block;
47+
import org.jruby.runtime.Builtins;
4748
import org.jruby.runtime.CallSite;
4849
import org.jruby.runtime.ClassIndex;
4950
import org.jruby.runtime.Helpers;
@@ -936,15 +937,8 @@ public IRubyObject numRemainder(ThreadContext context, IRubyObject y) {
936937
public static boolean positiveInt(ThreadContext context, IRubyObject num) {
937938
JavaSites.CheckedSites gt = sites(context).op_gt_checked;
938939

939-
if (num instanceof RubyFixnum) {
940-
if (gt.site.retrieveCache(num).method.isBuiltin()) {
941-
return ((RubyFixnum) num).signum(context) == 1;
942-
}
943-
}
944-
else if (num instanceof RubyBignum) {
945-
if (gt.site.retrieveCache(num).method.isBuiltin()) {
946-
return ((RubyBignum) num).signum() == 1;
947-
}
940+
if (num instanceof RubyInteger integer && Builtins.checkIntegerGt(context)) {
941+
return integer.signum(context) == 1;
948942
}
949943
return compareNumberWithZero(context, num, gt).isTrue();
950944
}
@@ -953,15 +947,8 @@ else if (num instanceof RubyBignum) {
953947
public static boolean negativeInt(ThreadContext context, IRubyObject num) {
954948
JavaSites.CheckedSites lt = sites(context).op_lt_checked;
955949

956-
if (num instanceof RubyFixnum) {
957-
if (lt.site.retrieveCache(num).method.isBuiltin()) {
958-
return ((RubyFixnum) num).signum(context) == -1;
959-
}
960-
}
961-
else if (num instanceof RubyBignum) {
962-
if (lt.site.retrieveCache(num).method.isBuiltin()) {
963-
return ((RubyBignum) num).signum() == -1;
964-
}
950+
if (num instanceof RubyInteger integer && Builtins.checkIntegerLt(context)) {
951+
return integer.signum(context) == -1;
965952
}
966953
return compareNumberWithZero(context, num, lt).isTrue();
967954
}
@@ -1192,7 +1179,7 @@ private boolean scanStepArgs(ThreadContext context, IRubyObject[] args, IRubyObj
11921179

11931180
// MRI: num_step_negative_p
11941181
private static boolean numStepNegative(ThreadContext context, IRubyObject num) {
1195-
if (num instanceof RubyInteger in && context.sites.Integer.op_lt.isBuiltin(num)) return in.isNegativeNumber(context);
1182+
if (num instanceof RubyInteger in && Builtins.checkIntegerLt(context)) return in.isNegativeNumber(context);
11961183

11971184
RubyFixnum zero = asFixnum(context, 0);
11981185
IRubyObject r = getMetaClass(num).finvokeChecked(context, num, sites(context).op_gt_checked, zero);

core/src/main/java/org/jruby/RubyObject.java

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848

4949
import org.jruby.anno.JRubyClass;
5050
import org.jruby.runtime.Block;
51+
import org.jruby.runtime.Builtins;
5152
import org.jruby.runtime.ClassIndex;
5253
import org.jruby.runtime.JavaSites.ObjectSites;
5354
import org.jruby.runtime.ObjectAllocator;
@@ -419,7 +420,7 @@ private static boolean fastNumEqualInternal(final ThreadContext context, final I
419420
}
420421
} else if (a instanceof RubyFloat) {
421422
if (b instanceof RubyFloat) {
422-
if (!context.sites.Float.op_equal.isBuiltin(a)) {
423+
if (!Builtins.checkFloatEquals(context)) {
423424
return context.sites.Float.op_equal.call(context, a, a, b).isTrue();
424425
}
425426
return ((RubyFloat) a).fastEqual((RubyFloat) b);
@@ -484,11 +485,12 @@ public static IRubyObject dig(ThreadContext context, IRubyObject obj, IRubyObjec
484485
for (; idx < args.length; idx++) {
485486
if ( obj.isNil() ) break;
486487
IRubyObject arg = args[idx];
487-
if (isArrayDig(obj, sites)) {
488+
RubyClass metaClass = obj.getMetaClass();
489+
if (isArrayDig(context, metaClass)) {
488490
obj = ((RubyArray) obj).dig(context, arg);
489-
} else if (isHashDig(obj, sites)) {
491+
} else if (isHashDig(context, metaClass)) {
490492
obj = ((RubyHash) obj).dig(context, arg);
491-
} else if (isStructDig(obj, sites)) {
493+
} else if (isStructDig(context, metaClass)) {
492494
obj = ((RubyStruct) obj).dig(context, arg);
493495
} else if (sites.respond_to_dig.respondsTo(context, obj, obj, true) ) {
494496
final int len = args.length - idx;
@@ -517,10 +519,11 @@ public static IRubyObject dig1(ThreadContext context, IRubyObject obj, IRubyObje
517519
if ( obj.isNil() ) return context.nil;
518520

519521
ObjectSites sites = sites(context);
522+
RubyClass metaClass = obj.getMetaClass();
520523

521-
if (isArrayDig(obj, sites)) return ((RubyArray) obj).dig(context, arg1);
522-
if (isHashDig(obj, sites)) return ((RubyHash) obj).dig(context, arg1);
523-
if (isStructDig(obj, sites)) return ((RubyStruct) obj).dig(context, arg1);
524+
if (isArrayDig(context, metaClass)) return ((RubyArray) obj).dig(context, arg1);
525+
if (isHashDig(context, metaClass)) return ((RubyHash) obj).dig(context, arg1);
526+
if (isStructDig(context, metaClass)) return ((RubyStruct) obj).dig(context, arg1);
524527

525528
if (!sites.respond_to_dig.respondsTo(context, obj, obj, true)) throw typeError(context, "", obj," does not have #dig method");
526529
return sites.dig_misc.call(context, obj, obj, arg1);
@@ -529,26 +532,27 @@ public static IRubyObject dig1(ThreadContext context, IRubyObject obj, IRubyObje
529532
public static IRubyObject dig2(ThreadContext context, IRubyObject obj, IRubyObject arg1, IRubyObject arg2) {
530533
if ( obj.isNil() ) return context.nil;
531534

535+
RubyClass metaClass = obj.getMetaClass();
532536
ObjectSites sites = sites(context);
533537

534-
if (isArrayDig(obj, sites)) return ((RubyArray) obj).dig(context, arg1, arg2);
535-
if (isHashDig(obj, sites)) return ((RubyHash) obj).dig(context, arg1, arg2);
536-
if (isStructDig(obj, sites)) return ((RubyStruct) obj).dig(context, arg1, arg2);
538+
if (isArrayDig(context, metaClass)) return ((RubyArray) obj).dig(context, arg1, arg2);
539+
if (isHashDig(context, metaClass)) return ((RubyHash) obj).dig(context, arg1, arg2);
540+
if (isStructDig(context, metaClass)) return ((RubyStruct) obj).dig(context, arg1, arg2);
537541

538542
if (!sites.respond_to_dig.respondsTo(context, obj, obj, true)) throw typeError(context, "", obj," does not have #dig method");
539543
return sites.dig_misc.call(context, obj, obj, arg1, arg2);
540544
}
541545

542-
private static boolean isStructDig(IRubyObject obj, ObjectSites sites) {
543-
return obj instanceof RubyStruct && sites.dig_struct.isBuiltin(obj.getMetaClass());
546+
private static boolean isStructDig(ThreadContext context, RubyClass metaClass) {
547+
return metaClass == context.runtime.getStructClass() && Builtins.checkStructDig(context);
544548
}
545549

546-
private static boolean isHashDig(IRubyObject obj, ObjectSites sites) {
547-
return obj instanceof RubyHash && sites.dig_hash.isBuiltin(obj.getMetaClass());
550+
private static boolean isHashDig(ThreadContext context, RubyClass metaClass) {
551+
return metaClass == context.runtime.getHash() && Builtins.checkHashDig(context);
548552
}
549553

550-
private static boolean isArrayDig(IRubyObject obj, ObjectSites sites) {
551-
return obj instanceof RubyArray && sites.dig_array.isBuiltin(obj.getMetaClass());
554+
private static boolean isArrayDig(ThreadContext context, RubyClass metaClass) {
555+
return metaClass == context.runtime.getArray() && Builtins.checkArrayDig(context);
552556
}
553557

554558
/**

core/src/main/java/org/jruby/RubyString.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
import org.jruby.runtime.Arity;
6969
import org.jruby.runtime.Block;
7070
import org.jruby.runtime.BlockCallback;
71+
import org.jruby.runtime.Builtins;
7172
import org.jruby.runtime.CallBlock19;
7273
import org.jruby.runtime.CallSite;
7374
import org.jruby.runtime.ClassIndex;
@@ -2101,7 +2102,7 @@ public IRubyObject op_lt(ThreadContext context, IRubyObject other) {
21012102
}
21022103

21032104
private boolean cmpIsBuiltin(ThreadContext context) {
2104-
return sites(context).cmp.isBuiltin(this);
2105+
return metaClass == context.runtime.getString() && Builtins.checkStringHash(context);
21052106
}
21062107

21072108
@Deprecated(since = "10.0.0.0")

core/src/main/java/org/jruby/RubyTime.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import org.jruby.java.proxies.JavaProxy;
5454
import org.jruby.runtime.Arity;
5555
import org.jruby.runtime.Block;
56+
import org.jruby.runtime.Builtins;
5657
import org.jruby.runtime.ClassIndex;
5758
import org.jruby.runtime.Helpers;
5859
import org.jruby.runtime.JavaSites.TimeSites;
@@ -808,11 +809,10 @@ public IRubyObject op_equal(ThreadContext context, IRubyObject other) {
808809

809810
private static int safeCmp(ThreadContext context, RubyTime self, IRubyObject other) {
810811
int cmpResult;
811-
CachingCallSite cmp = sites(context).cmp;
812-
if (cmp.isBuiltin(self)) {
812+
if (self.metaClass == context.runtime.getTime() && Builtins.checkTimeCmp(context)) {
813813
cmpResult = self.cmp((RubyTime) other);
814814
} else {
815-
cmpResult = toInt(context, cmp.call(context, self, self, other));
815+
cmpResult = toInt(context, sites(context).cmp.call(context, self, self, other));
816816
}
817817
return cmpResult;
818818
}

core/src/main/java/org/jruby/api/Convert.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.jruby.RubyRational;
2222
import org.jruby.RubyString;
2323
import org.jruby.RubySymbol;
24+
import org.jruby.runtime.Builtins;
2425
import org.jruby.runtime.JavaSites;
2526
import org.jruby.runtime.ThreadContext;
2627
import org.jruby.runtime.builtin.IRubyObject;
@@ -510,12 +511,10 @@ public static byte toByte(ThreadContext context, IRubyObject arg) {
510511
* @return the value
511512
*/
512513
public static double toDouble(ThreadContext context, IRubyObject arg) {
513-
var sites = context.sites;
514514
return switch (arg) {
515515
case RubyFloat flote -> flote.getValue();
516-
case RubyFixnum fixnum when sites.Fixnum.to_f.isBuiltin(fixnum) -> fixnum.asDouble(context);
517-
case RubyBignum bignum when sites.Bignum.to_f.isBuiltin(bignum) -> bignum.asDouble(context);
518-
case RubyRational rational when sites.Rational.to_f.isBuiltin(rational) -> rational.asDouble(context);
516+
case RubyInteger integer when Builtins.checkIntegerToF(context) -> integer.asDouble(context);
517+
case RubyRational rational when Builtins.checkRationalToF(context) -> rational.asDouble(context);
519518
case RubyString a -> throw typeError(context, "no implicit conversion to float from string");
520519
case RubyNil a -> throw typeError(context, "no implicit conversion to float from nil");
521520
case RubyBoolean a -> throw typeError(context, "no implicit conversion to float from " + (arg.isTrue() ? "true" : "false"));

0 commit comments

Comments
 (0)