Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
import org.jruby.management.InlineStats;
import org.jruby.parser.ParserManager;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.Builtins;
import org.jruby.runtime.JavaSites;
import org.jruby.runtime.TraceEventManager;
import org.jruby.runtime.backtrace.RubyStackTraceElement;
Expand Down Expand Up @@ -4792,6 +4793,18 @@ void addProfiledMethod(final String id, final DynamicMethod method) {
getProfilingService().addProfiledMethod(id, method);
}

void invalidateBuiltin(RubyModule module, String method) {
if (!isBootingCore()) {
Builtins.invalidateBuiltin(builtinBits, module.classIndex, method);
}
}

private final short[] builtinBits = Builtins.allocate();

public short[] getBuiltinBits() {
return builtinBits;
}

/**
* Increment the count of exceptions generated by code in this runtime.
*/
Expand Down
5 changes: 3 additions & 2 deletions core/src/main/java/org/jruby/RubyArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
import org.jruby.javasupport.JavaUtil;
import org.jruby.runtime.Arity;
import org.jruby.runtime.Block;
import org.jruby.runtime.Builtins;
import org.jruby.runtime.CallSite;
import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.Helpers;
Expand Down Expand Up @@ -4045,8 +4046,8 @@ public DefaultComparator(ThreadContext context) {
DefaultComparator(ThreadContext context, final boolean honorOverride) {
this.context = context;
if ( honorOverride && context != null ) {
this.fixnumBypass = !honorOverride || fixnumClass(context).isMethodBuiltin("<=>");
this.stringBypass = !honorOverride || stringClass(context).isMethodBuiltin("<=>");
this.fixnumBypass = !honorOverride || Builtins.checkIntegerCmp(context);
this.stringBypass = !honorOverride || Builtins.checkStringCmp(context);
}
else { // no-opt
this.fixnumBypass = false;
Expand Down
11 changes: 5 additions & 6 deletions core/src/main/java/org/jruby/RubyBignum.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.jruby.api.Convert;
import org.jruby.api.Create;
import org.jruby.api.JRubyAPI;
import org.jruby.runtime.Builtins;
import org.jruby.runtime.CallSite;
import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.Helpers;
Expand Down Expand Up @@ -1281,20 +1282,18 @@ public IRubyObject fdivFloat(ThreadContext context, RubyFloat y) {

@Override
public IRubyObject isNegative(ThreadContext context) {
CachingCallSite op_lt_site = sites(context).basic_op_lt;
if (op_lt_site.isBuiltin(metaClass)) {
if (Builtins.checkIntegerLt(context)) {
return asBoolean(context, value.signum() < 0);
}
return op_lt_site.call(context, this, this, zero(context.runtime));
return sites(context).basic_op_lt.call(context, this, this, zero(context.runtime));
}

@Override
public IRubyObject isPositive(ThreadContext context) {
CachingCallSite op_gt_site = sites(context).basic_op_gt;
if (op_gt_site.isBuiltin(metaClass)) {
if (Builtins.checkIntegerGt(context)) {
return asBoolean(context, value.signum() > 0);
}
return op_gt_site.call(context, this, this, zero(context.runtime));
return sites(context).basic_op_gt.call(context, this, this, zero(context.runtime));
}

@Override
Expand Down
11 changes: 5 additions & 6 deletions core/src/main/java/org/jruby/RubyFixnum.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.jruby.api.JRubyAPI;
import org.jruby.compiler.Constantizable;
import org.jruby.runtime.Block;
import org.jruby.runtime.Builtins;
import org.jruby.runtime.CallSite;
import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.Helpers;
Expand Down Expand Up @@ -1561,20 +1562,18 @@ public IRubyObject fdivDouble(ThreadContext context, IRubyObject y) {

@Override
public IRubyObject isNegative(ThreadContext context) {
CachingCallSite op_lt_site = sites(context).basic_op_lt;
if (op_lt_site.isBuiltin(metaClass)) {
if (Builtins.checkIntegerLt(context)) {
return asBoolean(context, getValue() < 0);
}
return op_lt_site.call(context, this, this, asFixnum(context, 0));
return sites(context).basic_op_lt.call(context, this, this, asFixnum(context, 0));
}

@Override
public IRubyObject isPositive(ThreadContext context) {
CachingCallSite op_gt_site = sites(context).basic_op_gt;
if (op_gt_site.isBuiltin(metaClass)) {
if (Builtins.checkIntegerGt(context)) {
return asBoolean(context, getValue() > 0);
}
return op_gt_site.call(context, this, this, asFixnum(context, 0));
return sites(context).basic_op_gt.call(context, this, this, asFixnum(context, 0));
}

@Override
Expand Down
5 changes: 4 additions & 1 deletion core/src/main/java/org/jruby/RubyHash.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import org.jruby.javasupport.JavaUtil;
import org.jruby.runtime.Arity;
import org.jruby.runtime.Block;
import org.jruby.runtime.Builtins;
import org.jruby.runtime.CallBlock19;
import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.Helpers;
Expand Down Expand Up @@ -2009,7 +2010,9 @@ public IRubyObject shift(ThreadContext context) {


CachingCallSite self_default = sites(context).self_default;
if (self_default.isBuiltin(this)) return default_value_get(context, context.nil);
if (metaClass == context.runtime.getHash() && Builtins.checkHashDefault(context)) {
return default_value_get(context, context.nil);
}

return self_default.call(context, this, this, context.nil);
}
Expand Down
1 change: 1 addition & 0 deletions core/src/main/java/org/jruby/RubyInteger.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.jruby.ast.util.ArgsUtil;
import org.jruby.runtime.Arity;
import org.jruby.runtime.Block;
import org.jruby.runtime.Builtins;
import org.jruby.runtime.CallSite;
import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.JavaSites;
Expand Down
2 changes: 2 additions & 0 deletions core/src/main/java/org/jruby/RubyModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,8 @@ public DynamicMethod putMethod(ThreadContext context, String id, DynamicMethod m
}

context.runtime.addProfiledMethod(id, method);
context.runtime.invalidateBuiltin(methodLocation, id);

return method;
}

Expand Down
25 changes: 6 additions & 19 deletions core/src/main/java/org/jruby/RubyNumeric.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.jruby.javasupport.JavaUtil;
import org.jruby.runtime.Arity;
import org.jruby.runtime.Block;
import org.jruby.runtime.Builtins;
import org.jruby.runtime.CallSite;
import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.Helpers;
Expand Down Expand Up @@ -936,15 +937,8 @@ public IRubyObject numRemainder(ThreadContext context, IRubyObject y) {
public static boolean positiveInt(ThreadContext context, IRubyObject num) {
JavaSites.CheckedSites gt = sites(context).op_gt_checked;

if (num instanceof RubyFixnum) {
if (gt.site.retrieveCache(num).method.isBuiltin()) {
return ((RubyFixnum) num).signum(context) == 1;
}
}
else if (num instanceof RubyBignum) {
if (gt.site.retrieveCache(num).method.isBuiltin()) {
return ((RubyBignum) num).signum() == 1;
}
if (num instanceof RubyInteger integer && Builtins.checkIntegerGt(context)) {
return integer.signum(context) == 1;
}
return compareNumberWithZero(context, num, gt).isTrue();
}
Expand All @@ -953,15 +947,8 @@ else if (num instanceof RubyBignum) {
public static boolean negativeInt(ThreadContext context, IRubyObject num) {
JavaSites.CheckedSites lt = sites(context).op_lt_checked;

if (num instanceof RubyFixnum) {
if (lt.site.retrieveCache(num).method.isBuiltin()) {
return ((RubyFixnum) num).signum(context) == -1;
}
}
else if (num instanceof RubyBignum) {
if (lt.site.retrieveCache(num).method.isBuiltin()) {
return ((RubyBignum) num).signum() == -1;
}
if (num instanceof RubyInteger integer && Builtins.checkIntegerLt(context)) {
return integer.signum(context) == -1;
}
return compareNumberWithZero(context, num, lt).isTrue();
}
Expand Down Expand Up @@ -1192,7 +1179,7 @@ private boolean scanStepArgs(ThreadContext context, IRubyObject[] args, IRubyObj

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

RubyFixnum zero = asFixnum(context, 0);
IRubyObject r = getMetaClass(num).finvokeChecked(context, num, sites(context).op_gt_checked, zero);
Expand Down
44 changes: 24 additions & 20 deletions core/src/main/java/org/jruby/RubyObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

import org.jruby.anno.JRubyClass;
import org.jruby.runtime.Block;
import org.jruby.runtime.Builtins;
import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.JavaSites.ObjectSites;
import org.jruby.runtime.ObjectAllocator;
Expand Down Expand Up @@ -410,16 +411,16 @@ public static boolean equalInternal(final ThreadContext context, final IRubyObje
}

private static boolean fastNumEqualInternal(final ThreadContext context, final IRubyObject a, final IRubyObject b) {
if (a instanceof RubyFixnum) {
if (b instanceof RubyFixnum) {
if (!context.sites.Fixnum.op_eqq.isBuiltin(a)) {
if (a instanceof RubyFixnum fixnumA) {
if (b instanceof RubyFixnum fixnumB) {
if (!Builtins.checkIntegerEquals(context)) {
return context.sites.Fixnum.op_eqq.call(context, a, a, b).isTrue();
}
return ((RubyFixnum) a).fastEqual((RubyFixnum) b);
return fixnumA.fastEqual(fixnumB);
}
} else if (a instanceof RubyFloat) {
if (b instanceof RubyFloat) {
if (!context.sites.Float.op_equal.isBuiltin(a)) {
if (!Builtins.checkFloatEquals(context)) {
return context.sites.Float.op_equal.call(context, a, a, b).isTrue();
}
return ((RubyFloat) a).fastEqual((RubyFloat) b);
Expand Down Expand Up @@ -484,11 +485,12 @@ public static IRubyObject dig(ThreadContext context, IRubyObject obj, IRubyObjec
for (; idx < args.length; idx++) {
if ( obj.isNil() ) break;
IRubyObject arg = args[idx];
if (isArrayDig(obj, sites)) {
RubyClass metaClass = obj.getMetaClass();
if (isArrayDig(context, metaClass)) {
obj = ((RubyArray) obj).dig(context, arg);
} else if (isHashDig(obj, sites)) {
} else if (isHashDig(context, metaClass)) {
obj = ((RubyHash) obj).dig(context, arg);
} else if (isStructDig(obj, sites)) {
} else if (isStructDig(context, metaClass)) {
obj = ((RubyStruct) obj).dig(context, arg);
} else if (sites.respond_to_dig.respondsTo(context, obj, obj, true) ) {
final int len = args.length - idx;
Expand Down Expand Up @@ -517,10 +519,11 @@ public static IRubyObject dig1(ThreadContext context, IRubyObject obj, IRubyObje
if ( obj.isNil() ) return context.nil;

ObjectSites sites = sites(context);
RubyClass metaClass = obj.getMetaClass();

if (isArrayDig(obj, sites)) return ((RubyArray) obj).dig(context, arg1);
if (isHashDig(obj, sites)) return ((RubyHash) obj).dig(context, arg1);
if (isStructDig(obj, sites)) return ((RubyStruct) obj).dig(context, arg1);
if (isArrayDig(context, metaClass)) return ((RubyArray) obj).dig(context, arg1);
if (isHashDig(context, metaClass)) return ((RubyHash) obj).dig(context, arg1);
if (isStructDig(context, metaClass)) return ((RubyStruct) obj).dig(context, arg1);

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

RubyClass metaClass = obj.getMetaClass();
ObjectSites sites = sites(context);

if (isArrayDig(obj, sites)) return ((RubyArray) obj).dig(context, arg1, arg2);
if (isHashDig(obj, sites)) return ((RubyHash) obj).dig(context, arg1, arg2);
if (isStructDig(obj, sites)) return ((RubyStruct) obj).dig(context, arg1, arg2);
if (isArrayDig(context, metaClass)) return ((RubyArray) obj).dig(context, arg1, arg2);
if (isHashDig(context, metaClass)) return ((RubyHash) obj).dig(context, arg1, arg2);
if (isStructDig(context, metaClass)) return ((RubyStruct) obj).dig(context, arg1, arg2);

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

private static boolean isStructDig(IRubyObject obj, ObjectSites sites) {
return obj instanceof RubyStruct && sites.dig_struct.isBuiltin(obj.getMetaClass());
private static boolean isStructDig(ThreadContext context, RubyClass metaClass) {
return metaClass == context.runtime.getStructClass() && Builtins.checkStructDig(context);
}

private static boolean isHashDig(IRubyObject obj, ObjectSites sites) {
return obj instanceof RubyHash && sites.dig_hash.isBuiltin(obj.getMetaClass());
private static boolean isHashDig(ThreadContext context, RubyClass metaClass) {
return metaClass == context.runtime.getHash() && Builtins.checkHashDig(context);
}

private static boolean isArrayDig(IRubyObject obj, ObjectSites sites) {
return obj instanceof RubyArray && sites.dig_array.isBuiltin(obj.getMetaClass());
private static boolean isArrayDig(ThreadContext context, RubyClass metaClass) {
return metaClass == context.runtime.getArray() && Builtins.checkArrayDig(context);
}

/**
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/java/org/jruby/RubyString.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
import org.jruby.runtime.Arity;
import org.jruby.runtime.Block;
import org.jruby.runtime.BlockCallback;
import org.jruby.runtime.Builtins;
import org.jruby.runtime.CallBlock19;
import org.jruby.runtime.CallSite;
import org.jruby.runtime.ClassIndex;
Expand Down Expand Up @@ -2089,7 +2090,7 @@ public IRubyObject op_lt(ThreadContext context, IRubyObject other) {
}

private boolean cmpIsBuiltin(ThreadContext context) {
return sites(context).cmp.isBuiltin(this);
return metaClass == context.runtime.getString() && Builtins.checkStringHash(context);
}

@Deprecated(since = "10.0.0.0")
Expand Down
6 changes: 3 additions & 3 deletions core/src/main/java/org/jruby/RubyTime.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import org.jruby.java.proxies.JavaProxy;
import org.jruby.runtime.Arity;
import org.jruby.runtime.Block;
import org.jruby.runtime.Builtins;
import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.JavaSites.TimeSites;
Expand Down Expand Up @@ -808,11 +809,10 @@ public IRubyObject op_equal(ThreadContext context, IRubyObject other) {

private static int safeCmp(ThreadContext context, RubyTime self, IRubyObject other) {
int cmpResult;
CachingCallSite cmp = sites(context).cmp;
if (cmp.isBuiltin(self)) {
if (self.metaClass == context.runtime.getTime() && Builtins.checkTimeCmp(context)) {
cmpResult = self.cmp((RubyTime) other);
} else {
cmpResult = toInt(context, cmp.call(context, self, self, other));
cmpResult = toInt(context, sites(context).cmp.call(context, self, self, other));
}
return cmpResult;
}
Expand Down
6 changes: 3 additions & 3 deletions core/src/main/java/org/jruby/api/Convert.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.jruby.RubyRational;
import org.jruby.RubyString;
import org.jruby.RubySymbol;
import org.jruby.runtime.Builtins;
import org.jruby.runtime.JavaSites;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
Expand Down Expand Up @@ -513,9 +514,8 @@ public static double toDouble(ThreadContext context, IRubyObject arg) {
var sites = context.sites;
return switch (arg) {
case RubyFloat flote -> flote.getValue();
case RubyFixnum fixnum when sites.Fixnum.to_f.isBuiltin(fixnum) -> fixnum.asDouble(context);
case RubyBignum bignum when sites.Bignum.to_f.isBuiltin(bignum) -> bignum.asDouble(context);
case RubyRational rational when sites.Rational.to_f.isBuiltin(rational) -> rational.asDouble(context);
case RubyInteger integer when Builtins.checkIntegerToF(context) -> integer.asDouble(context);
case RubyRational rational when Builtins.checkRationalToF(context) -> rational.asDouble(context);
case RubyString a -> throw typeError(context, "no implicit conversion to float from string");
case RubyNil a -> throw typeError(context, "no implicit conversion to float from nil");
case RubyBoolean a -> throw typeError(context, "no implicit conversion to float from " + (arg.isTrue() ? "true" : "false"));
Expand Down
Loading
Loading