--- jsr166/src/main/java/util/Vector.java 2016/11/13 19:58:47 1.34 +++ jsr166/src/main/java/util/Vector.java 2016/11/14 22:46:22 1.36 @@ -585,6 +585,7 @@ public class Vector modCount++; elementCount--; elementData[elementCount] = null; /* to let gc do its work */ + // checkInvariants(); } /** @@ -675,10 +676,7 @@ public class Vector * method (which is part of the {@link List} interface). */ public synchronized void removeAllElements() { - // Let gc do its work - for (int i = 0; i < elementCount; i++) - elementData[i] = null; - + Arrays.fill(elementData, 0, elementCount, null); modCount++; elementCount = 0; } @@ -810,6 +808,7 @@ public class Vector elementData = grow(); elementData[s] = e; elementCount = s + 1; + // checkInvariants(); } /** @@ -878,6 +877,7 @@ public class Vector numMoved); elementData[--elementCount] = null; // Let gc do its work + // checkInvariants(); return oldValue; } @@ -933,6 +933,7 @@ public class Vector elementData = grow(s + numNew); System.arraycopy(a, 0, elementData, s, numNew); elementCount = s + numNew; + // checkInvariants(); return true; } } @@ -1005,7 +1006,6 @@ public class Vector int expectedModCount = modCount; final Object[] es = elementData; final int end = elementCount; - final boolean modified; int i; // Optimize for initial run of survivors for (i = 0; i < end && !filter.test(elementAt(es, i)); i++) @@ -1013,24 +1013,30 @@ public class Vector // Tolerate predicates that reentrantly access the collection for // read (but writers still get CME), so traverse once to find // elements to delete, a second pass to physically expunge. - if (modified = (i < end)) { - expectedModCount++; - modCount++; + if (i < end) { final int beg = i; final long[] deathRow = nBits(end - beg); deathRow[0] = 1L; // set bit 0 for (i = beg + 1; i < end; i++) if (filter.test(elementAt(es, i))) setBit(deathRow, i - beg); + if (modCount != expectedModCount) + throw new ConcurrentModificationException(); + expectedModCount++; + modCount++; int w = beg; for (i = beg; i < end; i++) if (isClear(deathRow, i - beg)) es[w++] = es[i]; Arrays.fill(es, elementCount = w, end, null); + // checkInvariants(); + return true; + } else { + if (modCount != expectedModCount) + throw new ConcurrentModificationException(); + // checkInvariants(); + return false; } - if (modCount != expectedModCount) - throw new ConcurrentModificationException(); - return modified; } /** @@ -1071,6 +1077,7 @@ public class Vector numMoved); System.arraycopy(a, 0, elementData, index, numNew); elementCount = s + numNew; + // checkInvariants(); return true; } @@ -1152,15 +1159,13 @@ public class Vector * (If {@code toIndex==fromIndex}, this operation has no effect.) */ protected synchronized void removeRange(int fromIndex, int toIndex) { - int numMoved = elementCount - toIndex; - System.arraycopy(elementData, toIndex, elementData, fromIndex, - numMoved); - - // Let gc do its work - modCount++; - int newElementCount = elementCount - (toIndex-fromIndex); - while (elementCount != newElementCount) - elementData[--elementCount] = null; + final Object[] es = elementData; + final int oldSize = elementCount; + System.arraycopy(es, toIndex, es, fromIndex, oldSize - toIndex); + + modCount++; + Arrays.fill(es, elementCount -= (toIndex - fromIndex), oldSize, null); + // checkInvariants(); } /** @@ -1350,6 +1355,7 @@ public class Vector action.accept(elementAt(es, i)); if (modCount != expectedModCount) throw new ConcurrentModificationException(); + // checkInvariants(); } @Override @@ -1363,6 +1369,7 @@ public class Vector if (modCount != expectedModCount) throw new ConcurrentModificationException(); modCount++; + // checkInvariants(); } @SuppressWarnings("unchecked") @@ -1370,10 +1377,10 @@ public class Vector public synchronized void sort(Comparator c) { final int expectedModCount = modCount; Arrays.sort((E[]) elementData, 0, elementCount, c); - if (modCount != expectedModCount) { + if (modCount != expectedModCount) throw new ConcurrentModificationException(); - } modCount++; + // checkInvariants(); } /** @@ -1480,4 +1487,9 @@ public class Vector return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED; } } + + void checkInvariants() { + // assert elementCount >= 0; + // assert elementCount == elementData.length || elementData[elementCount] == null; + } }