diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 1e8b7319bb3..21dddc8e63b 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -4115,6 +4115,14 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) { DumpAppCDSWithKlassId = true; } + if (!UseSparkOpt && FLAG_IS_CMDLINE(UseSparkOpt)) { + UseBigDecimalOpt = false; + } + + if (UseBigDecimalOpt) { + PropertyList_add(&_system_properties, new SystemProperty("java.math.BigDecimal.opt", "true", true)); + } + // Set object alignment values. set_object_alignment(); diff --git a/src/hotspot/share/runtime/globals_ext.hpp b/src/hotspot/share/runtime/globals_ext.hpp index 642e932dfac..fd0788c7319 100644 --- a/src/hotspot/share/runtime/globals_ext.hpp +++ b/src/hotspot/share/runtime/globals_ext.hpp @@ -90,6 +90,12 @@ product(bool, G1BarrierSimple, false, \ "Use simple G1 post barrier") \ \ + product(bool, UseSparkOpt, true, \ + "enable several optimizations for apache spark") \ + \ + product(bool, UseBigDecimalOpt, true, \ + "use binary search in zero stripping of BigDecimal") \ + \ //add new AJDK specific flags here diff --git a/src/java.base/share/classes/java/math/BigDecimal.java b/src/java.base/share/classes/java/math/BigDecimal.java index ff9a6daf47b..74a1c807773 100644 --- a/src/java.base/share/classes/java/math/BigDecimal.java +++ b/src/java.base/share/classes/java/math/BigDecimal.java @@ -368,6 +368,9 @@ protected StringBuilderHelper initialValue() { */ private static final BigDecimal ONE_HALF = valueOf(5L, 1); + // string to boolean + private static final boolean opt = Boolean.parseBoolean(System.getProperty("java.math.BigDecimal.opt")); + // Constructors /** @@ -4860,6 +4863,38 @@ private static boolean needIncrement(MutableBigInteger mdivisor, int roundingMod return commonNeedIncrement(roundingMode, qsign, cmpFracHalf, mq.isOdd()); } + /** + * Remove insignificant trailing zeros from this + * {@code BigInteger} value until the preferred scale is reached or no + * more zeros can be removed. This is a faster version of createAndStripZerosToMatchScale + * using binary search instead of linear search. + * + * @return new {@code BigDecimal} with a scale possibly reduced + * to be closed to the preferred scale. + */ + private static BigDecimal createAndStripZerosToMatchScaleFast(BigInteger intVal, int scale, long preferredScale) { + BigInteger qr[]; // quotient-remainder pair + int scaleStep; + while (intVal.compareMagnitude(BigInteger.TEN) >= 0 + && scale > preferredScale) { + scaleStep = checkScale(intVal, Math.max(((long) scale - preferredScale) / 2, 1l)); + if (intVal.getLowestSetBit() >= scaleStep) { // intVal can be divided by pow(10, scaleStep) only if intVal has more trailing zeros than scaleStep + qr = intVal.divideAndRemainder(bigTenToThe(scaleStep)); + if (qr[1].signum() == 0) { + intVal = qr[0]; + scale = checkScale(intVal, (long) scale - scaleStep); // could Overflow + continue; + } + } + if (scaleStep == 1) { + break; + } else { + preferredScale = scale - scaleStep; + } + } + return valueOf(intVal, scale, 0); + } + /** * Remove insignificant trailing zeros from this * {@code BigInteger} value until the preferred scale is reached or no @@ -4870,6 +4905,9 @@ private static boolean needIncrement(MutableBigInteger mdivisor, int roundingMod * to be closed to the preferred scale. */ private static BigDecimal createAndStripZerosToMatchScale(BigInteger intVal, int scale, long preferredScale) { + if (opt && preferredScale >= Integer.MIN_VALUE) { + return createAndStripZerosToMatchScaleFast(intVal, scale, preferredScale); + } BigInteger qr[]; // quotient-remainder pair while (intVal.compareMagnitude(BigInteger.TEN) >= 0 && scale > preferredScale) {