< prev index next >

## src/java.base/share/classes/java/math/BigInteger.java

```@@ -40,10 +40,11 @@

import jdk.internal.math.DoubleConsts;
import jdk.internal.math.FloatConsts;
import jdk.internal.HotSpotIntrinsicCandidate;
import jdk.internal.vm.annotation.Stable;
+import jdk.internal.vm.annotation.ForceInline;

/**
* Immutable arbitrary-precision integers.  All operations behave as if
* BigIntegers were represented in two's-complement notation (like Java's
* primitive integer types).  BigInteger provides analogues to all of Java's
```

```@@ -2619,30 +2620,21 @@
}
}

// shifts a up to len right n bits assumes no leading zeros, 0<n<32
static void primitiveRightShift(int[] a, int len, int n) {
-        int n2 = 32 - n;
-        for (int i=len-1, c=a[i]; i > 0; i--) {
-            int b = c;
-            c = a[i-1];
-            a[i] = (c << n2) | (b >>> n);
-        }
+        Objects.checkFromToIndex(0, len, a.length);
+        shiftRightImplWorker(a, a, 1, n, len-1);
a[0] >>>= n;
}

// shifts a up to len left n bits assumes no leading zeros, 0<=n<32
static void primitiveLeftShift(int[] a, int len, int n) {
if (len == 0 || n == 0)
return;
-
-        int n2 = 32 - n;
-        for (int i=0, c=a[i], m=i+len-1; i < m; i++) {
-            int b = c;
-            c = a[i+1];
-            a[i] = (b << n) | (c >>> n2);
-        }
+        Objects.checkFromToIndex(0, len, a.length);
+        shiftLeftImplWorker(a, a, 0, n, len-1);
a[len-1] <<= n;
}

/**
* Calculate bitlength of contents of the first len elements an int array,
```

```@@ -3351,18 +3343,29 @@
newMag = new int[magLen + nInts + 1];
newMag[i++] = highBits;
} else {
newMag = new int[magLen + nInts];
}
-            int j=0;
-            while (j < magLen-1)
-                newMag[i++] = mag[j++] << nBits | mag[j] >>> nBits2;
-            newMag[i] = mag[j] << nBits;
+            int numIter = magLen - 1;
+            Objects.checkFromToIndex(0, numIter + 1, mag.length);
+            Objects.checkFromToIndex(i, numIter + i + 1, newMag.length);
+            shiftLeftImplWorker(newMag, mag, i, nBits, numIter);
+            newMag[numIter + i] = mag[numIter] << nBits;
}
return newMag;
}

+    @ForceInline
+    @HotSpotIntrinsicCandidate
+    private static void shiftLeftImplWorker(int[] newArr, int[] oldArr, int newIdx, int shiftCount, int numIter) {
+        int shiftCountRight = 32 - shiftCount;
+        int oldIdx = 0;
+        while (oldIdx < numIter) {
+            newArr[newIdx++] = (oldArr[oldIdx++] << shiftCount) | (oldArr[oldIdx] >>> shiftCountRight);
+        }
+    }
+
/**
* Returns a BigInteger whose value is {@code (this >> n)}.  Sign
* extension is performed.  The shift distance, {@code n}, may be
* negative, in which case this method performs a left shift.
* (Computes <code>floor(this / 2<sup>n</sup>)</code>.)
```

```@@ -3413,15 +3416,14 @@
newMag = new int[magLen - nInts];
newMag[i++] = highBits;
} else {
newMag = new int[magLen - nInts -1];
}
-
-            int nBits2 = 32 - nBits;
-            int j=0;
-            while (j < magLen - nInts - 1)
-                newMag[i++] = (mag[j++] << nBits2) | (mag[j] >>> nBits);
+            int numIter = magLen - nInts - 1;
+            Objects.checkFromToIndex(0, numIter + 1, mag.length);
+            Objects.checkFromToIndex(i, numIter + i, newMag.length);
+            shiftRightImplWorker(newMag, mag, i, nBits, numIter);
}

if (signum < 0) {
// Find out whether any one-bits were shifted off the end.
boolean onesLost = false;
```

```@@ -3435,10 +3437,21 @@
}

return new BigInteger(newMag, signum);
}

+    @ForceInline
+    @HotSpotIntrinsicCandidate
+    private static void shiftRightImplWorker(int[] newArr, int[] oldArr, int newIdx, int shiftCount, int numIter) {
+        int shiftCountLeft = 32 - shiftCount;
+        int idx = numIter;
+        int nidx = (newIdx == 0) ? numIter - 1 : numIter;
+        while (nidx >= newIdx) {
+            newArr[nidx--] = (oldArr[idx--] >>> shiftCount) | (oldArr[idx] << shiftCountLeft);
+        }
+    }
+
int[] javaIncrement(int[] val) {
int lastSum = 0;
for (int i=val.length-1;  i >= 0 && lastSum == 0; i--)
lastSum = (val[i] += 1);
if (lastSum == 0) {
```
< prev index next >