diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java index ec84baa9ed60d1161117164700bfa7e8d2c38e46..271ee97b99d22e51b74496ab0eebaf935ad0e9fc 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java @@ -47,6 +47,7 @@ import com.oracle.truffle.r.runtime.RContext.ConsoleHandler; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.RPromise.Closure; import com.oracle.truffle.r.runtime.data.RPromise.PromiseProfile; +import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.env.*; import com.oracle.truffle.r.runtime.env.REnvironment.PutException; import com.oracle.truffle.r.runtime.ffi.*; @@ -364,6 +365,7 @@ public final class REngine implements RContext.Engine { } catch (ControlFlowException cfe) { throw RError.error(RError.Message.NO_LOOP_FOR_BREAK_NEXT); } + assert !FastROptions.CheckResultCompleteness.getValue() || checkResult(result); if (printResult) { printResult(result); } @@ -382,6 +384,13 @@ public final class REngine implements RContext.Engine { return result; } + private static boolean checkResult(Object result) { + if (result instanceof RAbstractVector && ((RAbstractVector) result).isComplete()) { + assert ((RAbstractVector) result).checkCompleteness() : "vector: " + result + " is not complete, but isComplete flag is true"; + } + return true; + } + private static final PromiseProfile globalPromiseProfile = new PromiseProfile(); @TruffleBoundary diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ColSums.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ColSums.java index 48503680bc4be5267a436f767ac0866e9a3b02bc..ea99c9c48723e574c9df4b35f3df07c1211e9bc5 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ColSums.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ColSums.java @@ -63,10 +63,12 @@ public abstract class ColSums extends RBuiltinNode { boolean isComplete = true; final boolean rna = removeNA.profile(naRm == RRuntime.LOGICAL_TRUE); na.enable(x); + double[] data = x.getDataWithoutCopying(); + int pos = 0; nextCol: for (int c = 0; c < colNum; ++c) { double sum = 0; for (int i = 0; i < rowNum; ++i) { - double el = x.getDataAt(c * rowNum + i); + double el = data[pos++]; if (rna) { if (!na.check(el) && !Double.isNaN(el)) { sum = add.op(sum, el); @@ -74,11 +76,13 @@ public abstract class ColSums extends RBuiltinNode { } else { if (na.check(el)) { result[c] = RRuntime.DOUBLE_NA; + pos += rowNum - i - 1; continue nextCol; } if (Double.isNaN(el)) { result[c] = Double.NaN; isComplete = false; + pos += rowNum - i - 1; continue nextCol; } sum = add.op(sum, el); @@ -95,10 +99,12 @@ public abstract class ColSums extends RBuiltinNode { double[] result = new double[colNum]; final boolean rna = removeNA.profile(naRm == RRuntime.LOGICAL_TRUE); na.enable(x); + byte[] data = x.getDataWithoutCopying(); + int pos = 0; nextCol: for (int c = 0; c < colNum; ++c) { double sum = 0; for (int i = 0; i < rowNum; ++i) { - byte el = x.getDataAt(c * rowNum + i); + byte el = data[pos++]; if (rna) { if (!na.check(el)) { sum = add.op(sum, el); @@ -106,6 +112,7 @@ public abstract class ColSums extends RBuiltinNode { } else { if (na.check(el)) { result[c] = RRuntime.DOUBLE_NA; + pos += rowNum - i - 1; continue nextCol; } sum = add.op(sum, el); @@ -122,10 +129,12 @@ public abstract class ColSums extends RBuiltinNode { double[] result = new double[colNum]; final boolean rna = removeNA.profile(naRm == RRuntime.LOGICAL_TRUE); na.enable(x); + int[] data = x.getDataWithoutCopying(); + int pos = 0; nextCol: for (int c = 0; c < colNum; ++c) { double sum = 0; for (int i = 0; i < rowNum; ++i) { - int el = x.getDataAt(c * rowNum + i); + int el = data[pos++]; if (rna) { if (!na.check(el)) { sum = add.op(sum, el); @@ -133,6 +142,7 @@ public abstract class ColSums extends RBuiltinNode { } else { if (na.check(el)) { result[c] = RRuntime.DOUBLE_NA; + pos += rowNum - i - 1; continue nextCol; } sum = add.op(sum, el); @@ -149,5 +159,4 @@ public abstract class ColSums extends RBuiltinNode { controlVisibility(); throw RError.error(getEncapsulatingSourceSection(), RError.Message.X_NUMERIC); } - } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDiag.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDiag.java index 1eaa5b17eff11588dc2b2b99bc81272719d85b50..9db416a6efd4a91baaae1971763b4fd6ab7f01a3 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDiag.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDiag.java @@ -90,7 +90,7 @@ public abstract class UpdateDiag extends RInvisibleBuiltinNode { int nrow = resultVector.getDimensions()[0]; int size = Math.min(nrow, resultVector.getDimensions()[1]); int pos = 0; - naCheck.enable(!resultVector.isComplete()); + naCheck.enable(resultVector); for (int i = 0; i < size; i++) { resultVector.updateDataAt(pos, valueVector.getDataAt(i % valueVector.getLength()), naCheck); pos += nrow + 1; @@ -110,7 +110,7 @@ public abstract class UpdateDiag extends RInvisibleBuiltinNode { int size = Math.min(resultVector.getDimensions()[0], resultVector.getDimensions()[1]); int nrow = resultVector.getDimensions()[0]; int pos = 0; - naCheck.enable(!resultVector.isComplete()); + naCheck.enable(resultVector); for (int i = 0; i < size; i++) { resultVector.updateDataAt(pos, valueVector.getDataAt(i % valueVector.getLength()), naCheck); pos += nrow + 1; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/ArrayPositionCast.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/ArrayPositionCast.java index 6904958bc30fe97849d25f79d2d0768fdd266bd2..a9a70f2a664cbdb82df2582c83a0129092096996 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/ArrayPositionCast.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/ArrayPositionCast.java @@ -659,7 +659,7 @@ public abstract class ArrayPositionCast extends ArrayPositionsCastBase { int logicalVectorLength = operand.getLength(); int logicalVectorInd = 0; int[] data = new int[resultLength]; - naCheck.enable(!operand.isComplete()); + naCheck.enable(operand); int timesSeenFalse = 0; int timesSeenNA = 0; int i = 0; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/read/AccessArrayNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/read/AccessArrayNode.java index 42cc3f0d73727ff0f766e5231a30dc66ca76f5c1..c39914478c57d7c429408e0d5dd6b0ac2215f5e8 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/read/AccessArrayNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/read/AccessArrayNode.java @@ -368,7 +368,7 @@ public abstract class AccessArrayNode extends RNode { int accSrcDimensions = vector.getLength() / srcDimSize; int accDstDimensions = resLength / p.getLength(); - elementNACheck.enable(!p.isComplete()); + elementNACheck.enable(p); for (int i = 0; i < p.getLength(); i++) { int dstArrayBase = accDstDimensions * i; int pos = p.getDataAt(i); @@ -1352,7 +1352,7 @@ public abstract class AccessArrayNode extends RNode { int accSrcDimensions = vector.getLength() / srcDimSize; int accDstDimensions = resLength / p.getLength(); - elementNACheck.enable(!p.isComplete()); + elementNACheck.enable(p); for (int i = 0; i < p.getLength(); i++) { int dstArrayBase = accDstDimensions * i; int pos = p.getDataAt(i); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java index ca31defef717cb4c7268e3c49f94a3b39e86a222..67602fb83ed29fc39cf02ccea30d332485c790b4 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java @@ -750,8 +750,8 @@ public abstract class BinaryArithmeticNode extends RBuiltinNode { if (emptyVector.profile(length == 0)) { return RDataFactory.createEmptyDoubleVector(); } - leftNACheck.enable(!left.isComplete()); - rightNACheck.enable(!right.isComplete()); + leftNACheck.enable(left); + rightNACheck.enable(right); double[] result = new double[length]; for (int i = 0; i < length; ++i) { double leftValue = left.getDataAt(i); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java index 40bec6926fa771ed92988b51ca2b2782a1a1ffd0..4ed662fbd44f94187b2f67b8686cc4d5ef46d775 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java @@ -28,6 +28,7 @@ import com.oracle.truffle.api.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.nodes.builtin.*; +import com.oracle.truffle.r.nodes.unary.CastLogicalNode.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.closures.*; @@ -46,6 +47,8 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { private final NACheck leftNACheck = NACheck.create(); private final NACheck rightNACheck = NACheck.create(); + private final NAProfile resultNAProfile = NAProfile.create(); + public BinaryBooleanNode(BooleanOperationFactory factory) { this.factory = factory; this.logic = factory.create(); @@ -1483,44 +1486,58 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { // int vector and scalar implementation + private RLogicalVector createResult(RAbstractVector left, byte[] result, boolean naResult) { + RLogicalVector ret = RDataFactory.createLogicalVector(result, !naResult && leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.getDimensions()); + ret.copyNamesFrom(left); + return ret; + } + private RLogicalVector performIntVectorOp(RAbstractIntVector left, double rightValue, boolean reverse) { int length = left.getLength(); byte[] result = new byte[length]; - leftNACheck.enable(!left.isComplete()); + leftNACheck.enable(left); rightNACheck.enable(rightValue); + boolean naResult = false; for (int i = 0; i < length; ++i) { int leftValue = left.getDataAt(i); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : (!reverse ? logic.op(leftValue, rightValue) : logic.op(rightValue, leftValue)); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.getDimensions()); - ret.copyNamesFrom(left); - return ret; + return createResult(left, result, naResult); } private RLogicalVector performIntVectorOp(RAbstractIntVector left, String rightValue, boolean reverse) { int length = left.getLength(); byte[] result = new byte[length]; - leftNACheck.enable(!left.isComplete()); + leftNACheck.enable(left); rightNACheck.enable(rightValue); + boolean naResult = false; for (int i = 0; i < length; ++i) { String leftValue = RRuntime.intToString(left.getDataAt(i), false); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : (!reverse ? logic.op(leftValue, rightValue) : logic.op(rightValue, leftValue)); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.getDimensions()); - ret.copyNamesFrom(left); - return ret; + return createResult(left, result, naResult); } private RLogicalVector performIntVectorOp(RAbstractIntVector left, RComplex rightValue, boolean reverse) { int length = left.getLength(); byte[] result = new byte[length]; - leftNACheck.enable(!left.isComplete()); + leftNACheck.enable(left); rightNACheck.enable(rightValue); + boolean naResult = false; for (int i = 0; i < length; ++i) { RComplex leftValue = RRuntime.int2complex(left.getDataAt(i)); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : (!reverse ? logic.op(leftValue, rightValue) : logic.op(rightValue, leftValue)); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.getDimensions()); @@ -1533,41 +1550,49 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { private RLogicalVector performDoubleVectorOp(RAbstractDoubleVector left, double rightValue, boolean reverse) { int length = left.getLength(); byte[] result = new byte[length]; - leftNACheck.enable(!left.isComplete()); + leftNACheck.enable(left); rightNACheck.enable(rightValue); + boolean naResult = false; for (int i = 0; i < length; ++i) { double leftValue = left.getDataAt(i); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : (!reverse ? logic.op(leftValue, rightValue) : logic.op(rightValue, leftValue)); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.getDimensions()); - ret.copyNamesFrom(left); - return ret; + return createResult(left, result, naResult); } private RLogicalVector performDoubleVectorOp(RAbstractDoubleVector left, String rightValue, boolean reverse) { int length = left.getLength(); byte[] result = new byte[length]; - leftNACheck.enable(!left.isComplete()); + leftNACheck.enable(left); rightNACheck.enable(rightValue); + boolean naResult = false; for (int i = 0; i < length; ++i) { String leftValue = RRuntime.doubleToString(left.getDataAt(i)); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : (!reverse ? logic.op(leftValue, rightValue) : logic.op(rightValue, leftValue)); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.getDimensions()); - ret.copyNamesFrom(left); - return ret; + return createResult(left, result, naResult); } private RLogicalVector performDoubleVectorOp(RAbstractDoubleVector left, RComplex rightValue, boolean reverse) { int length = left.getLength(); byte[] result = new byte[length]; - leftNACheck.enable(!left.isComplete()); + leftNACheck.enable(left); rightNACheck.enable(rightValue); + boolean naResult = false; for (int i = 0; i < length; ++i) { RComplex leftValue = RRuntime.double2complex(left.getDataAt(i)); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : (!reverse ? logic.op(leftValue, rightValue) : logic.op(rightValue, leftValue)); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.getDimensions()); @@ -1580,26 +1605,32 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { private RLogicalVector performLogicalVectorOp(RAbstractLogicalVector left, double rightValue, boolean reverse) { int length = left.getLength(); byte[] result = new byte[length]; - leftNACheck.enable(!left.isComplete()); + leftNACheck.enable(left); rightNACheck.enable(rightValue); + boolean naResult = false; for (int i = 0; i < length; ++i) { byte leftValue = left.getDataAt(i); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : (!reverse ? logic.op(leftValue, rightValue) : logic.op(rightValue, leftValue)); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.getDimensions()); - ret.copyNamesFrom(left); - return ret; + return createResult(left, result, naResult); } private RLogicalVector performLogicalVectorOp(RAbstractLogicalVector left, String rightValue, boolean reverse) { int length = left.getLength(); byte[] result = new byte[length]; - leftNACheck.enable(!left.isComplete()); + leftNACheck.enable(left); rightNACheck.enable(rightValue); + boolean naResult = false; for (int i = 0; i < length; ++i) { String leftValue = RRuntime.logicalToString(left.getDataAt(i)); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : (!reverse ? logic.op(leftValue, rightValue) : logic.op(rightValue, leftValue)); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.getDimensions()); @@ -1610,16 +1641,18 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { private RLogicalVector performLogicalVectorOp(RAbstractLogicalVector left, RComplex rightValue, boolean reverse) { int length = left.getLength(); byte[] result = new byte[length]; - leftNACheck.enable(!left.isComplete()); + leftNACheck.enable(left); rightNACheck.enable(rightValue); + boolean naResult = false; for (int i = 0; i < length; ++i) { RComplex leftValue = RRuntime.logical2complex(left.getDataAt(i)); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : (!reverse ? logic.op(leftValue, rightValue) : logic.op(rightValue, leftValue)); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.getDimensions()); - ret.copyNamesFrom(left); - return ret; + return createResult(left, result, naResult); } // string vector and scalar implementation @@ -1627,16 +1660,18 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { private RLogicalVector performStringVectorOp(RAbstractStringVector left, String rightValue, boolean reverse) { int length = left.getLength(); byte[] result = new byte[length]; - leftNACheck.enable(!left.isComplete()); + leftNACheck.enable(left); rightNACheck.enable(rightValue); + boolean naResult = false; for (int i = 0; i < length; ++i) { String leftValue = left.getDataAt(i); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : (!reverse ? logic.op(leftValue, rightValue) : logic.op(rightValue, leftValue)); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.getDimensions()); - ret.copyNamesFrom(left); - return ret; + return createResult(left, result, naResult); } // complex vector and scalar implementation @@ -1644,76 +1679,86 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { private RLogicalVector performComplexVectorOp(RAbstractComplexVector left, RComplex rightValue, boolean reverse) { int length = left.getLength(); byte[] result = new byte[length]; - leftNACheck.enable(!left.isComplete()); + leftNACheck.enable(left); rightNACheck.enable(rightValue); + boolean naResult = false; for (int i = 0; i < length; ++i) { RComplex leftValue = left.getDataAt(i); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : (!reverse ? logic.op(leftValue, rightValue) : logic.op(rightValue, leftValue)); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.getDimensions()); - ret.copyNamesFrom(left); - return ret; + return createResult(left, result, naResult); } private RLogicalVector performComplexVectorOp(RAbstractComplexVector left, String rightValue, boolean reverse) { int length = left.getLength(); byte[] result = new byte[length]; - leftNACheck.enable(!left.isComplete()); + leftNACheck.enable(left); rightNACheck.enable(rightValue); + boolean naResult = false; for (int i = 0; i < length; ++i) { String leftValue = RRuntime.complexToString(left.getDataAt(i)); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : (!reverse ? logic.op(leftValue, rightValue) : logic.op(rightValue, leftValue)); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.getDimensions()); - ret.copyNamesFrom(left); - return ret; + return createResult(left, result, naResult); } private RLogicalVector performRawVectorOp(RAbstractRawVector left, double rightValue, boolean reverse) { int length = left.getLength(); byte[] result = new byte[length]; - leftNACheck.enable(!left.isComplete()); + leftNACheck.enable(left); rightNACheck.enable(rightValue); + boolean naResult = false; for (int i = 0; i < length; ++i) { double leftValue = RRuntime.raw2double(left.getDataAt(i)); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : (!reverse ? logic.op(leftValue, rightValue) : logic.op(rightValue, leftValue)); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.getDimensions()); - ret.copyNamesFrom(left); - return ret; + return createResult(left, result, naResult); } private RLogicalVector performRawVectorOp(RAbstractRawVector left, String rightValue, boolean reverse) { int length = left.getLength(); byte[] result = new byte[length]; - leftNACheck.enable(!left.isComplete()); + leftNACheck.enable(left); rightNACheck.enable(rightValue); + boolean naResult = false; for (int i = 0; i < length; ++i) { String leftValue = RRuntime.rawToString(left.getDataAt(i)); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : (!reverse ? logic.op(leftValue, rightValue) : logic.op(rightValue, leftValue)); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.getDimensions()); - ret.copyNamesFrom(left); - return ret; + return createResult(left, result, naResult); } private RLogicalVector performRawVectorOp(RAbstractRawVector left, RComplex rightValue, boolean reverse) { int length = left.getLength(); byte[] result = new byte[length]; - leftNACheck.enable(!left.isComplete()); + leftNACheck.enable(left); rightNACheck.enable(rightValue); + boolean naResult = false; for (int i = 0; i < length; ++i) { RComplex leftValue = RRuntime.raw2complex(left.getDataAt(i)); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : (!reverse ? logic.op(leftValue, rightValue) : logic.op(rightValue, leftValue)); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.getDimensions()); - ret.copyNamesFrom(left); - return ret; + return createResult(left, result, naResult); } private RRawVector performRawVectorOp(RAbstractRawVector left, RRaw rightValue, boolean reverse) { @@ -1735,15 +1780,20 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { assert areSameLength(left, right); int length = left.getLength(); byte[] result = new byte[length]; - leftNACheck.enable(!left.isComplete()); - rightNACheck.enable(!right.isComplete()); + leftNACheck.enable(left); + rightNACheck.enable(right); + boolean naResult = false; for (int i = 0; i < length; ++i) { int leftValue = left.getDataAt(i); int rightValue = right.getDataAt(i); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : logic.op(leftValue, rightValue); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.hasDimensions() ? left.getDimensions() : right.getDimensions()); + RLogicalVector ret = RDataFactory.createLogicalVector(result, !naResult && leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), + left.hasDimensions() ? left.getDimensions() : right.getDimensions()); ret.copyNamesFrom(left.getNames() != null && left.getNames() != RNull.instance ? left : right); return ret; } @@ -1754,21 +1804,25 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { int rightLength = right.getLength(); int resultLength = Math.max(leftLength, rightLength); byte[] result = new byte[resultLength]; - leftNACheck.enable(!left.isComplete()); - rightNACheck.enable(!right.isComplete()); + leftNACheck.enable(left); + rightNACheck.enable(right); int l = 0; int r = 0; + boolean naResult = false; for (int i = 0; i < resultLength; ++i, l = Utils.incMod(l, leftLength), r = Utils.incMod(r, rightLength)) { int leftValue = left.getDataAt(l); int rightValue = right.getDataAt(r); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : logic.op(leftValue, rightValue); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } boolean notMultiple = l != 0 || r != 0; if (notMultiple) { RError.warning(RError.Message.LENGTH_NOT_MULTI); } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA()); + RLogicalVector ret = RDataFactory.createLogicalVector(result, !naResult && leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA()); ret.setDimensions(left.hasDimensions() ? left.getDimensions() : right.getDimensions(), this.getSourceSection()); ret.copyNamesFrom(leftLength == resultLength ? left : right); return ret; @@ -1780,15 +1834,20 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { assert areSameLength(left, right); int length = left.getLength(); byte[] result = new byte[length]; - leftNACheck.enable(!left.isComplete()); - rightNACheck.enable(!right.isComplete()); + leftNACheck.enable(left); + rightNACheck.enable(right); + boolean naResult = false; for (int i = 0; i < length; ++i) { double leftValue = left.getDataAt(i); double rightValue = right.getDataAt(i); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : logic.op(leftValue, rightValue); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.hasDimensions() ? left.getDimensions() : right.getDimensions()); + RLogicalVector ret = RDataFactory.createLogicalVector(result, !naResult && leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), + left.hasDimensions() ? left.getDimensions() : right.getDimensions()); ret.copyNamesFrom(left.getNames() != null && left.getNames() != RNull.instance ? left : right); return ret; } @@ -1799,21 +1858,25 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { int rightLength = right.getLength(); int resultLength = Math.max(leftLength, rightLength); byte[] result = new byte[resultLength]; - leftNACheck.enable(!left.isComplete()); - rightNACheck.enable(!right.isComplete()); + leftNACheck.enable(left); + rightNACheck.enable(right); int l = 0; int r = 0; + boolean naResult = false; for (int i = 0; i < resultLength; ++i, l = Utils.incMod(l, leftLength), r = Utils.incMod(r, rightLength)) { double leftValue = left.getDataAt(l); double rightValue = right.getDataAt(r); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : logic.op(leftValue, rightValue); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } boolean notMultiple = l != 0 || r != 0; if (notMultiple) { RError.warning(RError.Message.LENGTH_NOT_MULTI); } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA()); + RLogicalVector ret = RDataFactory.createLogicalVector(result, !naResult && leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA()); ret.setDimensions(left.hasDimensions() ? left.getDimensions() : right.getDimensions(), this.getSourceSection()); ret.copyNamesFrom(leftLength == resultLength ? left : right); return ret; @@ -1825,15 +1888,20 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { assert areSameLength(left, right); int length = left.getLength(); byte[] result = new byte[length]; - leftNACheck.enable(!left.isComplete()); - rightNACheck.enable(!right.isComplete()); + leftNACheck.enable(left); + rightNACheck.enable(right); + boolean naResult = false; for (int i = 0; i < length; ++i) { String leftValue = left.getDataAt(i); String rightValue = right.getDataAt(i); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : logic.op(leftValue, rightValue); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.hasDimensions() ? left.getDimensions() : right.getDimensions()); + RLogicalVector ret = RDataFactory.createLogicalVector(result, !naResult && leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), + left.hasDimensions() ? left.getDimensions() : right.getDimensions()); ret.copyNamesFrom(left.getNames() != null && left.getNames() != RNull.instance ? left : right); return ret; } @@ -1844,21 +1912,25 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { int rightLength = right.getLength(); int resultLength = Math.max(leftLength, rightLength); byte[] result = new byte[resultLength]; - leftNACheck.enable(!left.isComplete()); - rightNACheck.enable(!right.isComplete()); + leftNACheck.enable(left); + rightNACheck.enable(right); int l = 0; int r = 0; + boolean naResult = false; for (int i = 0; i < resultLength; ++i, l = Utils.incMod(l, leftLength), r = Utils.incMod(r, rightLength)) { String leftValue = left.getDataAt(l); String rightValue = right.getDataAt(r); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : logic.op(leftValue, rightValue); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } boolean notMultiple = l != 0 || r != 0; if (notMultiple) { RError.warning(RError.Message.LENGTH_NOT_MULTI); } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA()); + RLogicalVector ret = RDataFactory.createLogicalVector(result, !naResult && leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA()); ret.setDimensions(left.hasDimensions() ? left.getDimensions() : right.getDimensions(), this.getSourceSection()); ret.copyNamesFrom(leftLength == resultLength ? left : right); return ret; @@ -1870,15 +1942,20 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { assert areSameLength(left, right); int length = left.getLength(); byte[] result = new byte[length]; - leftNACheck.enable(!left.isComplete()); - rightNACheck.enable(!right.isComplete()); + leftNACheck.enable(left); + rightNACheck.enable(right); + boolean naResult = false; for (int i = 0; i < length; ++i) { RComplex leftValue = left.getDataAt(i); RComplex rightValue = right.getDataAt(i); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : logic.op(leftValue, rightValue); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), left.hasDimensions() ? left.getDimensions() : right.getDimensions()); + RLogicalVector ret = RDataFactory.createLogicalVector(result, !naResult && leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA(), + left.hasDimensions() ? left.getDimensions() : right.getDimensions()); ret.copyNamesFrom(left.getNames() != null && left.getNames() != RNull.instance ? left : right); return ret; } @@ -1889,21 +1966,25 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { int rightLength = right.getLength(); int resultLength = Math.max(leftLength, rightLength); byte[] result = new byte[resultLength]; - leftNACheck.enable(!left.isComplete()); - rightNACheck.enable(!right.isComplete()); + leftNACheck.enable(left); + rightNACheck.enable(right); int l = 0; int r = 0; + boolean naResult = false; for (int i = 0; i < resultLength; ++i, l = Utils.incMod(l, leftLength), r = Utils.incMod(r, rightLength)) { RComplex leftValue = left.getDataAt(l); RComplex rightValue = right.getDataAt(r); byte resultValue = leftNACheck.check(leftValue) || rightNACheck.check(rightValue) ? RRuntime.LOGICAL_NA : logic.op(leftValue, rightValue); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } boolean notMultiple = l != 0 || r != 0; if (notMultiple) { RError.warning(RError.Message.LENGTH_NOT_MULTI); } - RLogicalVector ret = RDataFactory.createLogicalVector(result, leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA()); + RLogicalVector ret = RDataFactory.createLogicalVector(result, !naResult && leftNACheck.neverSeenNA() && rightNACheck.neverSeenNA()); ret.setDimensions(left.hasDimensions() ? left.getDimensions() : right.getDimensions(), this.getSourceSection()); ret.copyNamesFrom(leftLength == resultLength ? left : right); return ret; @@ -1915,10 +1996,14 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { assert areSameLength(left, right); int length = left.getLength(); byte[] result = new byte[length]; + boolean naResult = false; for (int i = 0; i < length; ++i) { RRaw leftValue = left.getDataAt(i); RRaw rightValue = right.getDataAt(i); byte resultValue = logic.op(leftValue, rightValue).getValue(); + if (resultNAProfile.isNA(resultValue)) { + naResult = true; + } result[i] = resultValue; } RRawVector ret = RDataFactory.createRawVector(result, left.hasDimensions() ? left.getDimensions() : right.getDimensions()); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/CombineBinaryNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/CombineBinaryNode.java index 9f6f63829b619000eb2bbfb0628951d4529ec63d..cb95bbc879f74aa6fc59ae700e01c2d25f24502b 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/CombineBinaryNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/CombineBinaryNode.java @@ -47,7 +47,7 @@ public abstract class CombineBinaryNode extends BinaryNode { namesData[i++] = RRuntime.NAMES_ATTR_EMPTY_VALUE; to++; } - naCheck.enable(!orgNames.isComplete()); + naCheck.enable(orgNames); for (int j = 0; i < to; i++, j++) { namesData[i] = orgNames.getDataAt(j); naCheck.check(namesData[i]); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java index 4717be1f29d280a3beb9f5f8312abfa54ac99bbc..0f66f70bf44cba1c939992caa69760b3531ce819 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java @@ -79,7 +79,7 @@ public abstract class CastStringNode extends CastNode { for (int i = 0; i < operand.getLength(); i++) { sdata[i] = elementFunction.apply(i); } - RStringVector ret = RDataFactory.createStringVector(sdata, RDataFactory.COMPLETE_VECTOR, isPreserveDimensions() ? operand.getDimensions() : null, isPreserveNames() ? operand.getNames() : null); + RStringVector ret = RDataFactory.createStringVector(sdata, operand.isComplete(), isPreserveDimensions() ? operand.getDimensions() : null, isPreserveNames() ? operand.getNames() : null); if (isAttrPreservation()) { ret.copyRegAttributesFrom(operand); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java index bc46cceb0891e71932cfdcde91384bc64e36663b..3caa924bf46ae9949f857ce71ff1701b605083ec 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticReduceNode.java @@ -188,8 +188,9 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode { int result = semantics.getIntStart(); na.enable(operand); int opCount = 0; + int[] data = operand.getDataWithoutCopying(); for (int i = 0; i < operand.getLength(); i++) { - int d = operand.getDataAt(i); + int d = data[i]; if (na.check(d)) { if (profiledNaRm) { continue; @@ -213,8 +214,9 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode { double result = semantics.getDoubleStart(); na.enable(operand); int opCount = 0; + double[] data = operand.getDataWithoutCopying(); for (int i = 0; i < operand.getLength(); i++) { - double d = operand.getDataAt(i); + double d = data[i]; if (na.check(d)) { if (profiledNaRm) { continue; @@ -238,8 +240,9 @@ public abstract class UnaryArithmeticReduceNode extends UnaryNode { int result = semantics.getIntStart(); na.enable(operand); int opCount = 0; + byte[] data = operand.getDataWithoutCopying(); for (int i = 0; i < operand.getLength(); i++) { - byte d = operand.getDataAt(i); + byte d = data[i]; if (na.check(d)) { if (profiledNaRm) { continue; diff --git a/com.oracle.truffle.r.options/src/com/oracle/truffle/r/options/FastROptions.java b/com.oracle.truffle.r.options/src/com/oracle/truffle/r/options/FastROptions.java index d0f669c5918b76e8ae103f9795796f50c1e238f2..aac24c0f60c7e11bf34cfb60aa6971395fd63487 100644 --- a/com.oracle.truffle.r.options/src/com/oracle/truffle/r/options/FastROptions.java +++ b/com.oracle.truffle.r.options/src/com/oracle/truffle/r/options/FastROptions.java @@ -45,6 +45,8 @@ public class FastROptions { public static final OptionValue<Boolean> DisableGroupGenerics = new OptionValue<>(false); @Option(help = "Prints Java and R stack traces for all R errors") public static final OptionValue<Boolean> PrintErrorStacktraces = new OptionValue<>(false); + @Option(help = "Check completeness of results vectors after evaluating unit tests and R shell commands") + public static final OptionValue<Boolean> CheckResultCompleteness = new OptionValue<>(false); @Option(help = "Turn on debugging output") public static final OptionValue<Boolean> Debug = new OptionValue<>(false); //@formatter:on diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RComplexVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RComplexVector.java index 142faa3d20115284bda225ce5cc0b50a8203ec59..b783eead375f9cc9f38b016495942860c45492c1 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RComplexVector.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RComplexVector.java @@ -58,7 +58,15 @@ public final class RComplexVector extends RVector implements RAbstractComplexVec @Override @TruffleBoundary public String toString() { - return Arrays.toString(data); + StringBuilder str = new StringBuilder(); + str.append('['); + for (int i = 0; i < getLength(); i++) { + if (i > 0) { + str.append(", "); + } + str.append(RRuntime.complexToString(getDataAt(i))); + } + return str.append(']').toString(); } @Override diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDoubleVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDoubleVector.java index 7fedee60cd8f6318d01cbfe4de1badbab478fdd8..e85b400ca1541f7116df80ee432799edbf5bb68b 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDoubleVector.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDoubleVector.java @@ -76,7 +76,7 @@ public final class RDoubleVector extends RVector implements RAbstractDoubleVecto @Override @TruffleBoundary public String toString() { - return Arrays.toString(data); + return Arrays.toString(Arrays.stream(data).mapToObj(v -> RRuntime.doubleToString(v)).toArray(String[]::new)); } public RIntVector trimToIntVector() { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RIntVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RIntVector.java index ec171ebbb0b01f2170e7815391ba56a3103267fa..057da30c232174dc72385ded460c8ab48c30e2a7 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RIntVector.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RIntVector.java @@ -80,7 +80,7 @@ public final class RIntVector extends RVector implements RAbstractIntVector { @Override @TruffleBoundary public String toString() { - return Arrays.toString(data); + return Arrays.toString(Arrays.stream(data).mapToObj(v -> RRuntime.intToString(v, false)).toArray(String[]::new)); } @Override diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java index 951e1100c4ca0604a74a32fb865c6eac0477b166..22d760d56d3a49a013595a91ddfad5fefa517d05 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java @@ -228,4 +228,8 @@ public final class RList extends RVector implements RAbstractVector { protected RStringVector getImplicitClassHr() { return getClassHierarchyHelper(new String[]{RType.List.getName()}, implicitClassHrDyn); } + + public boolean checkCompleteness() { + return true; + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractComplexVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractComplexVector.java index 79a4b7e6288aa6b28271eaa1b5a94047837f03b6..1c082f82108c668cf516334aec7125a03a6ab33b 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractComplexVector.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractComplexVector.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.runtime.data.model; +import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; public interface RAbstractComplexVector extends RAbstractVector { @@ -29,4 +30,13 @@ public interface RAbstractComplexVector extends RAbstractVector { RComplex getDataAt(int index); RComplexVector materialize(); + + default boolean checkCompleteness() { + for (int i = 0; i < getLength(); i++) { + if (RRuntime.isNA(getDataAt(i))) { + return false; + } + } + return true; + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractDoubleVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractDoubleVector.java index 127b31863315e0c3f7bb20f9ed2bed1ddb3a6a46..e6c33808488210230aa557ed2a11b9ded8b71f39 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractDoubleVector.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractDoubleVector.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.runtime.data.model; +import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; public interface RAbstractDoubleVector extends RAbstractVector { @@ -29,4 +30,13 @@ public interface RAbstractDoubleVector extends RAbstractVector { double getDataAt(int index); RDoubleVector materialize(); + + default boolean checkCompleteness() { + for (int i = 0; i < getLength(); i++) { + if (RRuntime.isNA(getDataAt(i))) { + return false; + } + } + return true; + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractIntVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractIntVector.java index 8343c3eedf76427b6e70260fec6d7fd50fdf08c8..8816c9b84a6a207db09df43cc5ebc5df7755152d 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractIntVector.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractIntVector.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.runtime.data.model; +import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; public interface RAbstractIntVector extends RAbstractVector { @@ -29,4 +30,13 @@ public interface RAbstractIntVector extends RAbstractVector { int getDataAt(int index); RIntVector materialize(); + + default boolean checkCompleteness() { + for (int i = 0; i < getLength(); i++) { + if (RRuntime.isNA(getDataAt(i))) { + return false; + } + } + return true; + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractLogicalVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractLogicalVector.java index 488a05343342413772b612ac3b76f1926dff0e90..4006121efda1dd2531926610f83e871cb3f9b3f7 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractLogicalVector.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractLogicalVector.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.runtime.data.model; +import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; public interface RAbstractLogicalVector extends RAbstractVector { @@ -29,4 +30,13 @@ public interface RAbstractLogicalVector extends RAbstractVector { byte getDataAt(int index); RLogicalVector materialize(); + + default boolean checkCompleteness() { + for (int i = 0; i < getLength(); i++) { + if (RRuntime.isNA(getDataAt(i))) { + return false; + } + } + return true; + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractRawVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractRawVector.java index 117fe94b4191c86858be2b963c44017041626707..a7a57b11f18438fa4dd7b868df747c49c6d599a8 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractRawVector.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractRawVector.java @@ -29,4 +29,8 @@ public interface RAbstractRawVector extends RAbstractVector { RRaw getDataAt(int index); RRawVector materialize(); + + default boolean checkCompleteness() { + return true; + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractStringVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractStringVector.java index 15c8c146f5174b1aa59c2ac2964c88247470571f..afa2918e9fab45b679d7ffb79cb66f13c76aa749 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractStringVector.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractStringVector.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.runtime.data.model; +import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; public interface RAbstractStringVector extends RAbstractVector { @@ -29,4 +30,13 @@ public interface RAbstractStringVector extends RAbstractVector { String getDataAt(int index); RStringVector materialize(); + + default boolean checkCompleteness() { + for (int i = 0; i < getLength(); i++) { + if (RRuntime.isNA(getDataAt(i))) { + return false; + } + } + return true; + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractVector.java index c1323361647f70cbc6746bd335e5b9434b9a8cd8..be75a9dfbea297a5d3b7bdb05981f63e80e1f61c 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractVector.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractVector.java @@ -65,4 +65,6 @@ public interface RAbstractVector extends RAbstractContainer { boolean isMatrix(); boolean isArray(); + + boolean checkCompleteness(); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java index bc37448c2807ca0676a435d9682e58efc4baffbd..e1d0e1e5631a15d31028ea6d862303d411842ee1 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java @@ -56,74 +56,15 @@ public abstract class BinaryArithmetic extends Operation { public static class PowBuiltin { } - public static final BinaryArithmeticFactory ADD = new BinaryArithmeticFactory() { - - @Override - public BinaryArithmetic create() { - return new Add(); - } - }; - public static final BinaryArithmeticFactory SUBTRACT = new BinaryArithmeticFactory() { - - @Override - public BinaryArithmetic create() { - return new Subtract(); - } - }; - public static final BinaryArithmeticFactory MULTIPLY = new BinaryArithmeticFactory() { - - @Override - public BinaryArithmetic create() { - return new Multiply(); - } - }; - public static final BinaryArithmeticFactory INTEGER_DIV = new BinaryArithmeticFactory() { - - @Override - public BinaryArithmetic create() { - return new IntegerDiv(); - } - }; - - public static final BinaryArithmeticFactory DIV = new BinaryArithmeticFactory() { - - @Override - public BinaryArithmetic create() { - return new Div(); - } - }; - - public static final BinaryArithmeticFactory MOD = new BinaryArithmeticFactory() { - - @Override - public BinaryArithmetic create() { - return new Mod(); - } - }; - - public static final BinaryArithmeticFactory POW = new BinaryArithmeticFactory() { - - @Override - public BinaryArithmetic create() { - return new Pow(); - } - }; - - public static final BinaryArithmeticFactory MAX = new BinaryArithmeticFactory() { - - @Override - public BinaryArithmetic create() { - return new Max(); - } - }; - - public static final BinaryArithmeticFactory MIN = new BinaryArithmeticFactory() { - - @Override - public BinaryArithmetic create() { - return new Min(); - } - }; + public static final BinaryArithmeticFactory ADD = Add::new; + public static final BinaryArithmeticFactory SUBTRACT = Subtract::new; + public static final BinaryArithmeticFactory MULTIPLY = Multiply::new; + public static final BinaryArithmeticFactory INTEGER_DIV = IntegerDiv::new; + public static final BinaryArithmeticFactory DIV = Div::new; + public static final BinaryArithmeticFactory MOD = Mod::new; + public static final BinaryArithmeticFactory POW = Pow::new; + public static final BinaryArithmeticFactory MAX = Max::new; + public static final BinaryArithmeticFactory MIN = Min::new; private final boolean supportsIntResult; @@ -317,12 +258,10 @@ public abstract class BinaryArithmetic extends Operation { double[] res = new double[2]; double[] interm = new double[4]; complexMult(leftReal, leftImag, rightReal, rightImag, res, interm); - if (Double.isNaN(res[0]) && Double.isNaN(res[1])) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - MultiplyNaN multNaN = new MultiplyNaN(); - replace(multNaN); - return multNaN.handleNaN(leftReal, leftImag, rightReal, rightImag, res, interm); - } + /* + * LStadler: removed the special code for handling NaNs in the result, since it works + * fine (and the tests are broken either way). to revive it, get it from the history. + */ return RDataFactory.createComplex(res[0], res[1]); } @@ -356,59 +295,6 @@ public abstract class BinaryArithmetic extends Operation { } - private static final class MultiplyNaN extends Multiply { - - private final ConditionProfile inf1 = ConditionProfile.createBinaryProfile(); - private final ConditionProfile inf2 = ConditionProfile.createBinaryProfile(); - private final ConditionProfile inf3 = ConditionProfile.createBinaryProfile(); - - @Override - public RComplex op(double leftReal, double leftImag, double rightReal, double rightImag) { - double[] res = new double[2]; - double[] interm = new double[4]; - complexMult(leftReal, leftImag, rightReal, rightImag, res, interm); - if (Double.isNaN(res[0]) && Double.isNaN(res[1])) { - return handleNaN(leftReal, leftImag, rightReal, rightImag, res, interm); - } - return RDataFactory.createComplex(res[0], res[1]); - } - - protected RComplex handleNaN(double leftReal, double leftImag, double rightReal, double rightImag, double[] res, double[] interm) { - boolean recalc = false; - double ra = leftReal; - double rb = leftImag; - double rc = rightReal; - double rd = rightImag; - if (inf1.profile(Double.isInfinite(ra) || Double.isInfinite(rb))) { - ra = convertInf(ra); - rb = convertInf(rb); - rc = convertNaN(rc); - rd = convertNaN(rd); - recalc = true; - } - if (inf2.profile(Double.isInfinite(rc) || Double.isInfinite(rd))) { - rc = convertInf(rc); - rd = convertInf(rd); - ra = convertNaN(ra); - rb = convertNaN(rb); - recalc = true; - } - if (inf3.profile(!recalc && (Double.isInfinite(interm[0]) || Double.isInfinite(interm[1]) || Double.isInfinite(interm[2]) || Double.isInfinite(interm[3])))) { - ra = convertNaN(ra); - rb = convertNaN(rb); - rc = convertNaN(rc); - rd = convertNaN(rd); - recalc = true; - } - if (recalc) { - res[0] = Double.POSITIVE_INFINITY * (ra * rc - rb * rd); - res[1] = Double.POSITIVE_INFINITY * (ra * rd + rb * rc); - } - return RDataFactory.createComplex(res[0], res[1]); - } - - } - private static class Div extends BinaryArithmetic { public Div() { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmeticFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmeticFactory.java index 9caa9b4a99b2bdcb8e5b3dc2ed20b64b77a1bbe3..9f50120d8538d7397ddd1df55fde8a5c0fa17c3c 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmeticFactory.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmeticFactory.java @@ -22,8 +22,8 @@ */ package com.oracle.truffle.r.runtime.ops; -public abstract class BinaryArithmeticFactory extends OperationFactory { +@FunctionalInterface +public interface BinaryArithmeticFactory extends OperationFactory { - @Override - public abstract BinaryArithmetic create(); + BinaryArithmetic create(); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryCompare.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryCompare.java index 0a614dc224f5f5cafc84402517093fa10a96b075..51cdb19edf48abf7f758ab631bea9fc27e096362 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryCompare.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryCompare.java @@ -52,49 +52,12 @@ public abstract class BinaryCompare extends BooleanOperation { public static class LessBuiltin { } - public static final BooleanOperationFactory NOT_EQUAL = new BooleanOperationFactory() { - - @Override - public BooleanOperation create() { - return new NotEqual(); - } - }; - - public static final BooleanOperationFactory EQUAL = new BooleanOperationFactory() { - - @Override - public BooleanOperation create() { - return new Equal(); - } - }; - public static final BooleanOperationFactory GREATER_EQUAL = new BooleanOperationFactory() { - - @Override - public BooleanOperation create() { - return new GreaterEqual(); - } - }; - public static final BooleanOperationFactory GREATER_THAN = new BooleanOperationFactory() { - - @Override - public BooleanOperation create() { - return new GreaterThan(); - } - }; - public static final BooleanOperationFactory LESS_EQUAL = new BooleanOperationFactory() { - - @Override - public BooleanOperation create() { - return new LessEqual(); - } - }; - public static final BooleanOperationFactory LESS_THAN = new BooleanOperationFactory() { - - @Override - public BooleanOperation create() { - return new LessThan(); - } - }; + public static final BooleanOperationFactory NOT_EQUAL = NotEqual::new; + public static final BooleanOperationFactory EQUAL = Equal::new; + public static final BooleanOperationFactory GREATER_EQUAL = GreaterEqual::new; + public static final BooleanOperationFactory GREATER_THAN = GreaterThan::new; + public static final BooleanOperationFactory LESS_EQUAL = LessEqual::new; + public static final BooleanOperationFactory LESS_THAN = LessThan::new; public BinaryCompare(boolean commutative) { super(commutative, false); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryLogic.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryLogic.java index 42927099a3de6bf569d405f045840cb42418b2dc..94c72adc0dcbc11335e660fd73e30ada409e4b1a 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryLogic.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryLogic.java @@ -45,37 +45,10 @@ public abstract class BinaryLogic extends BooleanOperation { public static class OrBuiltin { } - public static final BooleanOperationFactory NON_VECTOR_AND = new BooleanOperationFactory() { - - @Override - public BooleanOperation create() { - return new NonVectorAnd(); - } - }; - - public static final BooleanOperationFactory NON_VECTOR_OR = new BooleanOperationFactory() { - - @Override - public BooleanOperation create() { - return new NonVectorOr(); - } - }; - - public static final BooleanOperationFactory AND = new BooleanOperationFactory() { - - @Override - public BooleanOperation create() { - return new And(); - } - }; - - public static final BooleanOperationFactory OR = new BooleanOperationFactory() { - - @Override - public BooleanOperation create() { - return new Or(); - } - }; + public static final BooleanOperationFactory NON_VECTOR_AND = NonVectorAnd::new; + public static final BooleanOperationFactory NON_VECTOR_OR = NonVectorOr::new; + public static final BooleanOperationFactory AND = And::new; + public static final BooleanOperationFactory OR = Or::new; public BinaryLogic() { super(true, true); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BooleanOperationFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BooleanOperationFactory.java index 01745f511a9dd2ac7a23f3746dc1adb2af969618..fd6384e5912b01dd4b76e6abdb683116a81e335c 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BooleanOperationFactory.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BooleanOperationFactory.java @@ -22,8 +22,8 @@ */ package com.oracle.truffle.r.runtime.ops; -public abstract class BooleanOperationFactory extends OperationFactory { +@FunctionalInterface +public interface BooleanOperationFactory extends OperationFactory { - @Override - public abstract BooleanOperation create(); + BooleanOperation create(); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/OperationFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/OperationFactory.java index f16147f68a116e347044b91123675486063fd6ec..1b92f75b313a6b2eb46db509df55f9a3fb452dec 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/OperationFactory.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/OperationFactory.java @@ -22,8 +22,9 @@ */ package com.oracle.truffle.r.runtime.ops; -public abstract class OperationFactory { +@FunctionalInterface +public interface OperationFactory { - public abstract Operation create(); + Operation create(); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/UnaryArithmetic.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/UnaryArithmetic.java index b270f54a42a09c62d795a98dd5f84324af1c8b49..e141953c1740070644f3da42550cfe81c90b2b61 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/UnaryArithmetic.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/UnaryArithmetic.java @@ -20,37 +20,10 @@ import com.oracle.truffle.r.runtime.data.*; public abstract class UnaryArithmetic extends Operation { - public static final UnaryArithmeticFactory NEGATE = new UnaryArithmeticFactory() { - - @Override - public UnaryArithmetic create() { - return new Negate(); - } - }; - - public static final UnaryArithmeticFactory ROUND = new UnaryArithmeticFactory() { - - @Override - public UnaryArithmetic create() { - return new Round(); - } - }; - - public static final UnaryArithmeticFactory FLOOR = new UnaryArithmeticFactory() { - - @Override - public UnaryArithmetic create() { - return new Floor(); - } - }; - - public static final UnaryArithmeticFactory CEILING = new UnaryArithmeticFactory() { - - @Override - public UnaryArithmetic create() { - return new Ceiling(); - } - }; + public static final UnaryArithmeticFactory NEGATE = Negate::new; + public static final UnaryArithmeticFactory ROUND = Round::new; + public static final UnaryArithmeticFactory FLOOR = Floor::new; + public static final UnaryArithmeticFactory CEILING = Ceiling::new; public UnaryArithmetic() { super(false, false); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/UnaryArithmeticFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/UnaryArithmeticFactory.java index 19ef9e17c4952e0bdf3b3b932257589b5efd6670..07a19b5d3891d4e2fd8e6a194766c5efd3cc6dea 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/UnaryArithmeticFactory.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/UnaryArithmeticFactory.java @@ -22,8 +22,8 @@ */ package com.oracle.truffle.r.runtime.ops; -public abstract class UnaryArithmeticFactory extends OperationFactory { +@FunctionalInterface +public interface UnaryArithmeticFactory extends OperationFactory { - @Override - public abstract UnaryArithmetic create(); + UnaryArithmetic create(); }