diff options
author | Narayan Kamath <narayan@google.com> | 2014-08-15 15:57:30 +0100 |
---|---|---|
committer | Narayan Kamath <narayan@google.com> | 2014-08-21 12:50:26 +0100 |
commit | df7e1dbcd0ff712f39b8e80023228ea4eb8531c2 (patch) | |
tree | 904437411d647d595d3b55db11925e2983e3b379 | |
parent | 50e691bc0794413f7b5b13ceb7671300aed9fe81 (diff) | |
download | libcore-df7e1dbcd0ff712f39b8e80023228ea4eb8531c2.zip libcore-df7e1dbcd0ff712f39b8e80023228ea4eb8531c2.tar.gz libcore-df7e1dbcd0ff712f39b8e80023228ea4eb8531c2.tar.bz2 |
Fix abuse of Runtime.freeMemory.
Runtime.freeMemory is the largest allocation that's
possible *without a heap expansion*. That's a poor proxy
for "can i allocate this byte array" and leads to flaky
CTS tests.
bug: 17021619
Change-Id: I108138bf2402e899a40a0b3081c083f733e7c999
-rw-r--r-- | luni/src/main/java/java/math/Multiplication.java | 78 |
1 files changed, 37 insertions, 41 deletions
diff --git a/luni/src/main/java/java/math/Multiplication.java b/luni/src/main/java/java/math/Multiplication.java index 98cabee..093b1b7 100644 --- a/luni/src/main/java/java/math/Multiplication.java +++ b/luni/src/main/java/java/math/Multiplication.java @@ -125,49 +125,45 @@ class Multiplication { } else if (exp <= 50) { // To calculate: 10^exp return BigInteger.TEN.pow(intExp); - } else if (exp <= 1000) { - // To calculate: 5^exp * 2^exp - return bigFivePows[1].pow(intExp).shiftLeft(intExp); } - // "LARGE POWERS" - /* - * To check if there is free memory to allocate a BigInteger of the - * estimated size, measured in bytes: 1 + [exp / log10(2)] - */ - long byteArraySize = 1 + (long)(exp / 2.4082399653118496); - - if (byteArraySize > Runtime.getRuntime().freeMemory()) { - throw new ArithmeticException(); - } - if (exp <= Integer.MAX_VALUE) { - // To calculate: 5^exp * 2^exp - return bigFivePows[1].pow(intExp).shiftLeft(intExp); - } - /* - * "HUGE POWERS" - * - * This branch probably won't be executed since the power of ten is too - * big. - */ - // To calculate: 5^exp - BigInteger powerOfFive = bigFivePows[1].pow(Integer.MAX_VALUE); - BigInteger res = powerOfFive; - long longExp = exp - Integer.MAX_VALUE; - - intExp = (int)(exp % Integer.MAX_VALUE); - while (longExp > Integer.MAX_VALUE) { - res = res.multiply(powerOfFive); - longExp -= Integer.MAX_VALUE; - } - res = res.multiply(bigFivePows[1].pow(intExp)); - // To calculate: 5^exp << exp - res = res.shiftLeft(Integer.MAX_VALUE); - longExp = exp - Integer.MAX_VALUE; - while (longExp > Integer.MAX_VALUE) { - res = res.shiftLeft(Integer.MAX_VALUE); - longExp -= Integer.MAX_VALUE; + + BigInteger res = null; + try { + // "LARGE POWERS" + if (exp <= Integer.MAX_VALUE) { + // To calculate: 5^exp * 2^exp + res = bigFivePows[1].pow(intExp).shiftLeft(intExp); + } else { + /* + * "HUGE POWERS" + * + * This branch probably won't be executed since the power of ten is too + * big. + */ + // To calculate: 5^exp + BigInteger powerOfFive = bigFivePows[1].pow(Integer.MAX_VALUE); + res = powerOfFive; + long longExp = exp - Integer.MAX_VALUE; + + intExp = (int) (exp % Integer.MAX_VALUE); + while (longExp > Integer.MAX_VALUE) { + res = res.multiply(powerOfFive); + longExp -= Integer.MAX_VALUE; + } + res = res.multiply(bigFivePows[1].pow(intExp)); + // To calculate: 5^exp << exp + res = res.shiftLeft(Integer.MAX_VALUE); + longExp = exp - Integer.MAX_VALUE; + while (longExp > Integer.MAX_VALUE) { + res = res.shiftLeft(Integer.MAX_VALUE); + longExp -= Integer.MAX_VALUE; + } + res = res.shiftLeft(intExp); + } + } catch (OutOfMemoryError error) { + throw new ArithmeticException(error.getMessage()); } - res = res.shiftLeft(intExp); + return res; } |