# HG changeset patch # User bpb # Date 1392843267 28800 # Node ID 534f9ebe390f652aeb55f249afd7683586a1043b # Parent c766ec3e4877f1dbb213c8f59f150c39b6ff7850 8035279: Clean up internal deprecations in BigInteger Summary: Modify lazily intialized values to use different marker values. Reviewed-by: TBD diff --git a/src/share/classes/java/math/BigInteger.java b/src/share/classes/java/math/BigInteger.java --- a/src/share/classes/java/math/BigInteger.java +++ b/src/share/classes/java/math/BigInteger.java @@ -146,51 +146,42 @@ // values, and cached the first time they are needed (or never, if they // aren't needed). - /** - * One plus the bitCount of this BigInteger. Zeros means unitialized. + /** + * The bitCount of this BigInteger. {@code Integer.MIN_VALUE} means + * uninitialized. * * @serial * @see #bitCount - * @deprecated Deprecated since logical value is offset from stored - * value and correction factor is applied in accessor method. */ - @Deprecated - private int bitCount; + private volatile int bitCount = Integer.MIN_VALUE; /** - * One plus the bitLength of this BigInteger. Zeros means unitialized. - * (either value is acceptable). + * The bitLength of this BigInteger. {@code Integer.MIN_VALUE} means + * uninitialized. * * @serial * @see #bitLength() - * @deprecated Deprecated since logical value is offset from stored - * value and correction factor is applied in accessor method. */ - @Deprecated - private int bitLength; + private volatile int bitLength = Integer.MIN_VALUE; /** - * Two plus the lowest set bit of this BigInteger, as returned by - * getLowestSetBit(). + * The lowest set bit of this BigInteger, as returned by + * getLowestSetBit(). {@code Integer.MIN_VALUE} means uninitialized, + * and {@code -1} that this BigInteger contains no one bits. * * @serial * @see #getLowestSetBit - * @deprecated Deprecated since logical value is offset from stored - * value and correction factor is applied in accessor method. */ - @Deprecated - private int lowestSetBit; + private volatile int lowestSetBit = Integer.MIN_VALUE; /** - * Two plus the index of the lowest-order int in the magnitude of this - * BigInteger that contains a nonzero int, or -2 (either value is acceptable). + * The index of the lowest-order int in the magnitude of this + * BigInteger that contains a nonzero int, or {@code Integer.MIN_VALUE} to + * indicate uninitialized (either value is acceptable). * The least significant int has int-number 0, the next int in order of * increasing significance has int-number 1, and so forth. - * @deprecated Deprecated since logical value is offset from stored - * value and correction factor is applied in accessor method. */ - @Deprecated - private int firstNonzeroIntNum; + private volatile int firstNonzeroIntNum = Integer.MIN_VALUE; /** * This mask is used to obtain the value of an int as if it were unsigned. @@ -3240,9 +3231,9 @@ * @return index of the rightmost one bit in this BigInteger. */ public int getLowestSetBit() { - @SuppressWarnings("deprecation") int lsb = lowestSetBit - 2; - if (lsb == -2) { // lowestSetBit not initialized yet - lsb = 0; + // This computation has a known, acceptable non-critical race condition. + if (lowestSetBit == Integer.MIN_VALUE) { // lowestSetBit not initialized yet + int lsb = 0; if (signum == 0) { lsb -= 1; } else { @@ -3252,9 +3243,9 @@ ; lsb += (i << 5) + Integer.numberOfTrailingZeros(b); } - lowestSetBit = lsb + 2; + lowestSetBit = lsb; } - return lsb; + return lowestSetBit; } @@ -3271,29 +3262,29 @@ * representation of this BigInteger, excluding a sign bit. */ public int bitLength() { - @SuppressWarnings("deprecation") int n = bitLength - 1; - if (n == -1) { // bitLength not initialized yet + // This computation has a known, acceptable non-critical race condition. + if (bitLength == Integer.MIN_VALUE) { // bitLength not initialized yet int[] m = mag; int len = m.length; - if (len == 0) { - n = 0; // offset by one to initialize - } else { + int n = 0; + if (len != 0) { // Calculate the bit length of the magnitude int magBitLength = ((len - 1) << 5) + bitLengthForInt(mag[0]); - if (signum < 0) { - // Check if magnitude is a power of two - boolean pow2 = (Integer.bitCount(mag[0]) == 1); - for (int i=1; i< len && pow2; i++) - pow2 = (mag[i] == 0); - - n = (pow2 ? magBitLength -1 : magBitLength); - } else { - n = magBitLength; - } + if (signum < 0) { + // Check if magnitude is a power of two + boolean pow2 = (Integer.bitCount(mag[0]) == 1); + for (int i = 1; i < len && pow2; i++) { + pow2 = (mag[i] == 0); + } + + n = (pow2 ? magBitLength - 1 : magBitLength); + } else { + n = magBitLength; + } } - bitLength = n + 1; + bitLength = n; } - return n; + return bitLength; } /** @@ -3305,9 +3296,9 @@ * of this BigInteger that differ from its sign bit. */ public int bitCount() { - @SuppressWarnings("deprecation") int bc = bitCount - 1; - if (bc == -1) { // bitCount not initialized yet - bc = 0; // offset by one to initialize + // This computation has a known, acceptable non-critical race condition. + if (bitCount == Integer.MIN_VALUE) { // bitCount not initialized yet + int bc = 0; // Count the bits in the magnitude for (int i=0; i < mag.length; i++) bc += Integer.bitCount(mag[i]); @@ -3319,9 +3310,9 @@ magTrailingZeroCount += Integer.numberOfTrailingZeros(mag[j]); bc += magTrailingZeroCount - 1; } - bitCount = bc + 1; + bitCount = bc; } - return bc; + return bitCount; } // Primality Testing @@ -4190,9 +4181,9 @@ * least significant). If the magnitude is zero, return value is undefined. */ private int firstNonzeroIntNum() { - int fn = firstNonzeroIntNum - 2; - if (fn == -2) { // firstNonzeroIntNum not initialized yet - fn = 0; + // This computation has a known, acceptable non-critical race condition. + if (firstNonzeroIntNum == Integer.MIN_VALUE) { // firstNonzeroIntNum not initialized yet + int fn = 0; // Search for the first nonzero int int i; @@ -4200,9 +4191,9 @@ for (i = mlen - 1; i >= 0 && mag[i] == 0; i--) ; fn = mlen - i - 1; - firstNonzeroIntNum = fn + 2; // offset by two to initialize + firstNonzeroIntNum = fn; } - return fn; + return firstNonzeroIntNum; } /** use serialVersionUID from JDK 1.1. for interoperability */ @@ -4238,11 +4229,10 @@ * for historical reasons, but it is converted to an array of ints * and the byte array is discarded. * Note: - * The current convention is to initialize the cache fields, bitCount, - * bitLength and lowestSetBit, to 0 rather than some other marker value. - * Therefore, no explicit action to set these fields needs to be taken in - * readObject because those fields already have a 0 value be default since - * defaultReadObject is not being used. + * The current convention is explicitly to initialize the cache fields + * bitCount, bitLength, firstNonzeroIntNum, and lowestSetBit to + * Integer.MIN_VALUE. This serves to indicate that the actual values need + * to be calculated when accessed. */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { @@ -4288,6 +4278,12 @@ throw new java.io.StreamCorruptedException("BigInteger: Out of the supported range"); } } + + // Initialize cached fields to indicate not computed yet. + bitCount = Integer.MIN_VALUE; + bitLength = Integer.MIN_VALUE; + lowestSetBit = Integer.MIN_VALUE; + firstNonzeroIntNum = Integer.MIN_VALUE; } // Support for resetting final fields while deserializing