Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: f9bc67d1c70d
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 3c67f599427b
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Jun 9, 2016

  1. [Truffle] Rewrite Fixnum#/ on division by 0.

    * loop { begin; 1/0; rescue; $!; end } optimizes nicely now.
    * Get rid of methods trying to avoid boxing as it's boxed right after in interpreter.
    eregon committed Jun 9, 2016
    Copy the full SHA
    fd17285 View commit details
  2. Copy the full SHA
    3c67f59 View commit details
Original file line number Diff line number Diff line change
@@ -249,8 +249,10 @@ public abstract static class DivNode extends CoreMethodArrayArgumentsNode {
private final BranchProfile bMinusOneANotMinimum = BranchProfile.create();
private final BranchProfile finalCase = BranchProfile.create();

@Specialization(rewriteOn = UnexpectedResultException.class)
public int div(int a, int b) throws UnexpectedResultException {
// int

@Specialization(rewriteOn = ArithmeticException.class)
public Object divInt(int a, int b) {
if (b > 0) {
bGreaterZero.enter();
if (a >= 0) {
@@ -267,7 +269,7 @@ public int div(int a, int b) throws UnexpectedResultException {
bMinusOne.enter();
if (a == Integer.MIN_VALUE) {
bMinusOneAMinimum.enter();
throw new UnexpectedResultException(BigInteger.valueOf(a).negate());
return BigInteger.valueOf(a).negate();
} else {
bMinusOneANotMinimum.enter();
return -a;
@@ -279,31 +281,12 @@ public int div(int a, int b) throws UnexpectedResultException {
}

@Specialization
public Object divEdgeCase(int a, int b) {
if (b > 0) {
bGreaterZero.enter();
if (a >= 0) {
bGreaterZeroAGreaterEqualZero.enter();
return a / b;
} else {
bGreaterZeroALessZero.enter();
return (a + 1) / b - 1;
}
} else if (a > 0) {
aGreaterZero.enter();
return (a - 1) / b - 1;
} else if (b == -1) {
bMinusOne.enter();
if (a == Integer.MIN_VALUE) {
bMinusOneAMinimum.enter();
return BigInteger.valueOf(a).negate();
} else {
bMinusOneANotMinimum.enter();
return -a;
}
public Object divIntFallback(int a, int b,
@Cached("createBinaryProfile()") ConditionProfile zeroProfile) {
if (zeroProfile.profile(b == 0)) {
throw new RaiseException(coreExceptions().zeroDivisionError(this));
} else {
finalCase.enter();
return a / b;
return divInt(a, b);
}
}

@@ -316,8 +299,10 @@ public Object divCoerced(
return snippetNode.execute(frame, "redo_coerced :/, b", "b", b);
}

@Specialization(rewriteOn = UnexpectedResultException.class)
public long div(long a, long b) throws UnexpectedResultException {
// long

@Specialization(rewriteOn = ArithmeticException.class)
public Object divLong(long a, long b) {
if (b > 0) {
bGreaterZero.enter();
if (a >= 0) {
@@ -334,7 +319,7 @@ public long div(long a, long b) throws UnexpectedResultException {
bMinusOne.enter();
if (a == Long.MIN_VALUE) {
bMinusOneAMinimum.enter();
throw new UnexpectedResultException(BigInteger.valueOf(a).negate());
return BigInteger.valueOf(a).negate();
} else {
bMinusOneANotMinimum.enter();
return -a;
@@ -346,31 +331,12 @@ public long div(long a, long b) throws UnexpectedResultException {
}

@Specialization
public Object divEdgeCase(long a, long b) {
if (b > 0) {
bGreaterZero.enter();
if (a >= 0) {
bGreaterZeroAGreaterEqualZero.enter();
return a / b;
} else {
bGreaterZeroALessZero.enter();
return (a + 1) / b - 1;
}
} else if (a > 0) {
aGreaterZero.enter();
return (a - 1) / b - 1;
} else if (b == -1) {
bMinusOne.enter();
if (a == Long.MIN_VALUE) {
bMinusOneAMinimum.enter();
return BigInteger.valueOf(a).negate();
} else {
bMinusOneANotMinimum.enter();
return -a;
}
public Object divLongFallback(long a, long b,
@Cached("createBinaryProfile()") ConditionProfile zeroProfile) {
if (zeroProfile.profile(b == 0)) {
throw new RaiseException(coreExceptions().zeroDivisionError(this));
} else {
finalCase.enter();
return a / b;
return divLong(a, b);
}
}

@@ -379,14 +345,14 @@ public double div(long a, double b) {
return a / b;
}

@Specialization(guards = {"!isLongMinValue(a)", "isRubyBignum(b)"})
public int div(long a, DynamicObject b) {
@Specialization(guards = { "isRubyBignum(b)", "!isLongMinValue(a)" })
public int divBignum(long a, DynamicObject b) {
return 0;
}

@Specialization(guards = {"isLongMinValue(a)", "isRubyBignum(b)"})
public int divEdgeCase(long a, DynamicObject b) {
return -(Layouts.BIGNUM.getValue(b).signum());
@Specialization(guards = { "isRubyBignum(b)", "isLongMinValue(a)" })
public int divBignumEdgeCase(long a, DynamicObject b) {
return -Layouts.BIGNUM.getValue(b).signum();
}

@Specialization(guards = "!isRubyBignum(b)")
@@ -398,7 +364,7 @@ public Object divCoerced(
return snippetNode.execute(frame, "redo_coerced :/, b", "b", b);
}

public static boolean isLongMinValue(long a) {
protected static boolean isLongMinValue(long a) {
return a == Long.MIN_VALUE;
}

Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@
*/
package org.jruby.truffle.language.exceptions;

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.RubyContext;
@@ -19,12 +20,10 @@ public class DisablingBacktracesNode extends RubyNode {
@Child private RubyNode child;

private static final ThreadLocal<Boolean> BACTRACES_DISABLED = new ThreadLocal<Boolean>() {

@Override
protected Boolean initialValue() {
return false;
}

};

public DisablingBacktracesNode(RubyContext context, SourceSection sourceSection, RubyNode child) {
@@ -34,17 +33,27 @@ public DisablingBacktracesNode(RubyContext context, SourceSection sourceSection,

@Override
public Object execute(VirtualFrame frame) {
final boolean backtracesPreviouslyDisabled = BACTRACES_DISABLED.get();
final boolean backtracesPreviouslyDisabled = getBacktracesDisabled();
try {
BACTRACES_DISABLED.set(true);
setBacktracesDisabled(true);
return child.execute(frame);
} finally {
BACTRACES_DISABLED.set(backtracesPreviouslyDisabled);
setBacktracesDisabled(backtracesPreviouslyDisabled);
}
}

public static boolean areBacktracesDisabled() {
@TruffleBoundary
private static Boolean getBacktracesDisabled() {
return BACTRACES_DISABLED.get();
}

@TruffleBoundary
private void setBacktracesDisabled(boolean value) {
BACTRACES_DISABLED.set(value);
}

public static boolean areBacktracesDisabled() {
return getBacktracesDisabled();
}

}