I have created an issue for fixing the introduced regression and created a 
regression test that would have caught the error (fix a bug, write a test...).

8008785: IdentityHashMap.values().toArray(V[]) broken by JDK-8008167

http://cr.openjdk.java.net/~mduigou/JDK-8008785/0/webrev

Mike

On Feb 24 2013, at 12:27 , Peter Levart wrote:

> Hi Mike,
> 
> I thought I saw that too when you commited the change, but then re-examinig 
> the whole source in detail, I couldn't spot it again. I must have stared at 
> the wrong third of change...
> 
> Regards, Peter
> 
> On 02/24/2013 07:53 PM, Mike Duigou wrote:
>> Ouch, this would have been introduced by me.
>> 
>> I will check to see how this could have passed the pre-commit regression 
>> testing. I suspect that a regression test needs to be improved.
>> 
>> Mike
>> 
>> On Feb 24 2013, at 10:48 , Alan Bateman wrote:
>> 
>>> On 24/02/2013 15:49, Peter Levart wrote:
>>>> Hi Alan,
>>>> 
>>>> I checked and it seems all 3 IHM views [keySet|values|entrySet] have a 
>>>> fail-fast iterator implementation 
>>>> (IdentityHashMap.IdentityHashMapIterator) and all 3 are (were) using the 
>>>> iterator for .toArray implementations. So this patch tries to preserve the 
>>>> behavior when there is a concurrent modification (which is only possible 
>>>> from other thread and is illegal usage anyway since IHM is not 
>>>> thread-safe) while executing the toArray methods on the views...
>>>> 
>>>> Do you see something I don't see?
>>> My apologies, I see it does check the modification count in 
>>> IdentityHashMapIterator.nextIndex.
>>> 
>>> However, as this forced me to looks at the changes-set again then the copy 
>>> loop in Values.toArray has caught by eye:
>>> 
>>>             for (int si = 0; si < tab.length; si += 2) {
>>>                 if (tab[si++] != null) { // key present ?
>>>                     // more elements than expected -> concurrent 
>>> modification from other thread
>>>                     if (ti >= size) {
>>>                         throw new ConcurrentModificationException();
>>>                     }
>>>                     a[ti++] = (T) tab[si]; // copy value
>>>                 }
>>>             }
>>> 
>>> Looks like si is incrementing by 3 rather than 2 (which ironically will 
>>> cause a CME later because there will be fewer elements copied than 
>>> expected). 
>>> 
>>> Do you concur? If so then we can create a bug to change this to test 
>>> tab[si] and copy in tab[si+1].
>>> 
>>> -Alan
> 

Reply via email to