# HG changeset patch # User Doug Simon # Date 1426172677 -3600 # Node ID 853f84c7cc6f03a6b587426ce37b803f70c1e476 # Parent 97a72dcdac8d2492683c70e432c99915432ae4a2 fixed Math.pow intrinsic to make a runtime call instead of calling the original method diff -r 97a72dcdac8d -r 853f84c7cc6f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Thu Mar 12 16:03:40 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Thu Mar 12 16:04:37 2015 +0100 @@ -1444,6 +1444,7 @@ @HotSpotVMValue(expression = "SharedRuntime::dsin", get = HotSpotVMValue.Type.ADDRESS) @Stable public long arithmeticSinAddress; @HotSpotVMValue(expression = "SharedRuntime::dcos", get = HotSpotVMValue.Type.ADDRESS) @Stable public long arithmeticCosAddress; @HotSpotVMValue(expression = "SharedRuntime::dtan", get = HotSpotVMValue.Type.ADDRESS) @Stable public long arithmeticTanAddress; + @HotSpotVMValue(expression = "SharedRuntime::dpow", get = HotSpotVMValue.Type.ADDRESS) @Stable public long arithmeticPowAddress; @HotSpotVMValue(expression = "(jint) GraalCounterSize") @Stable public int graalCountersSize; diff -r 97a72dcdac8d -r 853f84c7cc6f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java Thu Mar 12 16:03:40 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java Thu Mar 12 16:04:37 2015 +0100 @@ -150,6 +150,7 @@ registerForeignCall(ARITHMETIC_SIN, c.arithmeticSinAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); registerForeignCall(ARITHMETIC_COS, c.arithmeticCosAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); registerForeignCall(ARITHMETIC_TAN, c.arithmeticTanAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); + registerForeignCall(ARITHMETIC_POW, c.arithmeticPowAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); registerForeignCall(LOAD_AND_CLEAR_EXCEPTION, c.loadAndClearExceptionAddress, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, ANY_LOCATION); registerForeignCall(EXCEPTION_HANDLER_FOR_PC, c.exceptionHandlerForPcAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); diff -r 97a72dcdac8d -r 853f84c7cc6f graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java Thu Mar 12 16:03:40 2015 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java Thu Mar 12 16:04:37 2015 +0100 @@ -54,7 +54,6 @@ test("mathSin", value); test("mathSqrt", value); test("mathTan", value); - test("mathPow", value); test("mathAll", value); } @@ -62,11 +61,26 @@ public void testMathPow() { double a = 34567.891D; double b = 4.6D; - for (int i = 0; i < 10000; i++) { - a = mathPow(a, b); - a = StrictMath.pow(a, b); - } test("mathPow", a, b); + + // Test the values directly handled by the substitution + + // If the second argument is positive or negative zero, then the result is 1.0. + test("mathPow", a, 0.0D); + test("mathPow", a, -0.0D); + // If the second argument is 1.0, then the result is the same as the first argument. + test("mathPow", a, 1.0D); + // If the second argument is NaN, then the result is NaN. + test("mathPow", a, Double.NaN); + // If the first argument is NaN and the second argument is nonzero, then the result is NaN. + test("mathPow", Double.NaN, b); + test("mathPow", Double.NaN, 0.0D); + // x**-1 = 1/x + test("mathPow", a, -1.0D); + // x**2 = x*x + test("mathPow", a, 2.0D); + // x**0.5 = sqrt(x) + test("mathPow", a, 0.5D); } public static double mathPow(double a, double b) { diff -r 97a72dcdac8d -r 853f84c7cc6f graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MathSubstitutionsX86.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MathSubstitutionsX86.java Thu Mar 12 16:03:40 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MathSubstitutionsX86.java Thu Mar 12 16:04:37 2015 +0100 @@ -46,12 +46,12 @@ @MethodSubstitution(guard = MathGuard.class) public static double pow(double x, double y) { // If the second argument is positive or negative zero, then the result is 1.0. - if (y == 0) { + if (y == 0.0D) { return 1; } // If the second argument is 1.0, then the result is the same as the first argument. - if (y == 1) { + if (y == 1.0D) { return x; } @@ -61,26 +61,25 @@ } // If the first argument is NaN and the second argument is nonzero, then the result is NaN. - if (Double.isNaN(x) && y != 0) { + if (Double.isNaN(x) && y != 0.0D) { return Double.NaN; } // x**-1 = 1/x - if (y == -1) { + if (y == -1.0D) { return 1 / x; } // x**2 = x*x - if (y == 2) { + if (y == 2.0D) { return x * x; } // x**0.5 = sqrt(x) - if (y == 0.5 && x >= 0) { + if (y == 0.5D && x >= 0.0D) { return Math.sqrt(x); } - - return pow(x, y); + return callDouble2(ARITHMETIC_POW, x, y); } // NOTE on snippets below: @@ -94,7 +93,7 @@ if (Math.abs(x) < PI_4) { return MathIntrinsicNode.compute(x, Operation.SIN); } else { - return callDouble(ARITHMETIC_SIN, x); + return callDouble1(ARITHMETIC_SIN, x); } } @@ -103,7 +102,7 @@ if (Math.abs(x) < PI_4) { return MathIntrinsicNode.compute(x, Operation.COS); } else { - return callDouble(ARITHMETIC_COS, x); + return callDouble1(ARITHMETIC_COS, x); } } @@ -112,7 +111,7 @@ if (Math.abs(x) < PI_4) { return MathIntrinsicNode.compute(x, Operation.TAN); } else { - return callDouble(ARITHMETIC_TAN, x); + return callDouble1(ARITHMETIC_TAN, x); } } @@ -127,7 +126,11 @@ public static final ForeignCallDescriptor ARITHMETIC_SIN = new ForeignCallDescriptor("arithmeticSin", double.class, double.class); public static final ForeignCallDescriptor ARITHMETIC_COS = new ForeignCallDescriptor("arithmeticCos", double.class, double.class); public static final ForeignCallDescriptor ARITHMETIC_TAN = new ForeignCallDescriptor("arithmeticTan", double.class, double.class); + public static final ForeignCallDescriptor ARITHMETIC_POW = new ForeignCallDescriptor("arithmeticPow", double.class, double.class, double.class); @NodeIntrinsic(value = ForeignCallNode.class, setStampFromReturnType = true) - public static native double callDouble(@ConstantNodeParameter ForeignCallDescriptor descriptor, double value); + private static native double callDouble1(@ConstantNodeParameter ForeignCallDescriptor descriptor, double value); + + @NodeIntrinsic(value = ForeignCallNode.class, setStampFromReturnType = true) + private static native double callDouble2(@ConstantNodeParameter ForeignCallDescriptor descriptor, double a, double b); }