Mercurial > hg > openjdk > jdk6 > jdk
changeset 1769:5bce64ab3f5f
8189284: More refactoring for deserialization cases
Reviewed-by: rriggs, igerasim, rhalade, skoivu
author | igerasim |
---|---|
date | Tue, 28 Nov 2017 14:10:28 -0800 |
parents | d4387e13f0f4 |
children | 67e0c158c9f8 |
files | src/share/classes/java/util/concurrent/ArrayBlockingQueue.java |
diffstat | 1 files changed, 121 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java Sun Nov 05 22:53:42 2017 -0800 +++ b/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java Tue Nov 28 14:10:28 2017 -0800 @@ -712,6 +712,127 @@ } /** + * Deserializes this queue and then checks some invariants. + * + * @param s the input stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.InvalidObjectException if invariants are violated + * @throws java.io.IOException if an I/O error occurs + */ + private void readObject(java.io.ObjectInputStream s) + throws java.io.IOException, ClassNotFoundException { + + // Read in items array and various fields + s.defaultReadObject(); + + // Check invariants over count and index fields. Note that + // if putIndex==takeIndex, count can be either 0 or items.length. + if (items.length == 0 || + takeIndex < 0 || takeIndex >= items.length || + putIndex < 0 || putIndex >= items.length || + count < 0 || count > items.length || + floorMod(putIndex - takeIndex, items.length) != + floorMod(count, items.length)) { + throw new java.io.InvalidObjectException("invariants violated"); + } + } + + /* Taken from java.lang.Math in OpenJDK 8 */ + + /** + * Returns the floor modulus of the {@code int} arguments. + * <p> + * The floor modulus is {@code x - (floorDiv(x, y) * y)}, + * has the same sign as the divisor {@code y}, and + * is in the range of {@code -abs(y) < r < +abs(y)}. + * + * <p> + * The relationship between {@code floorDiv} and {@code floorMod} is such that: + * <ul> + * <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x} + * </ul> + * <p> + * The difference in values between {@code floorMod} and + * the {@code %} operator is due to the difference between + * {@code floorDiv} that returns the integer less than or equal to the quotient + * and the {@code /} operator that returns the integer closest to zero. + * <p> + * Examples: + * <ul> + * <li>If the signs of the arguments are the same, the results + * of {@code floorMod} and the {@code %} operator are the same. <br> + * <ul> + * <li>{@code floorMod(4, 3) == 1}; and {@code (4 % 3) == 1}</li> + * </ul> + * <li>If the signs of the arguments are different, the results differ from the {@code %} operator.<br> + * <ul> + * <li>{@code floorMod(+4, -3) == -2}; and {@code (+4 % -3) == +1} </li> + * <li>{@code floorMod(-4, +3) == +2}; and {@code (-4 % +3) == -1} </li> + * <li>{@code floorMod(-4, -3) == -1}; and {@code (-4 % -3) == -1 } </li> + * </ul> + * </li> + * </ul> + * <p> + * If the signs of arguments are unknown and a positive modulus + * is needed it can be computed as {@code (floorMod(x, y) + abs(y)) % abs(y)}. + * + * @param x the dividend + * @param y the divisor + * @return the floor modulus {@code x - (floorDiv(x, y) * y)} + * @throws ArithmeticException if the divisor {@code y} is zero + * @see #floorDiv(int, int) + * @since 1.8 + */ + static int floorMod(int x, int y) { + int r = x - floorDiv(x, y) * y; + return r; + } + + /** + * Returns the largest (closest to positive infinity) + * {@code int} value that is less than or equal to the algebraic quotient. + * There is one special case, if the dividend is the + * {@linkplain Integer#MIN_VALUE Integer.MIN_VALUE} and the divisor is {@code -1}, + * then integer overflow occurs and + * the result is equal to the {@code Integer.MIN_VALUE}. + * <p> + * Normal integer division operates under the round to zero rounding mode + * (truncation). This operation instead acts under the round toward + * negative infinity (floor) rounding mode. + * The floor rounding mode gives different results than truncation + * when the exact result is negative. + * <ul> + * <li>If the signs of the arguments are the same, the results of + * {@code floorDiv} and the {@code /} operator are the same. <br> + * For example, {@code floorDiv(4, 3) == 1} and {@code (4 / 3) == 1}.</li> + * <li>If the signs of the arguments are different, the quotient is negative and + * {@code floorDiv} returns the integer less than or equal to the quotient + * and the {@code /} operator returns the integer closest to zero.<br> + * For example, {@code floorDiv(-4, 3) == -2}, + * whereas {@code (-4 / 3) == -1}. + * </li> + * </ul> + * <p> + * + * @param x the dividend + * @param y the divisor + * @return the largest (closest to positive infinity) + * {@code int} value that is less than or equal to the algebraic quotient. + * @throws ArithmeticException if the divisor {@code y} is zero + * @see #floorMod(int, int) + * @see #floor(double) + * @since 1.8 + */ + static int floorDiv(int x, int y) { + int r = x / y; + // if the signs are different and modulo not zero, round down + if ((x ^ y) < 0 && (r * y != x)) { + r--; + } + return r; + } + /** * Iterator for ArrayBlockingQueue */ private class Itr implements Iterator<E> {