On 2009-12-11 4:30, Boris (JIRA) wrote:
possible data-reordering in some hashCode-methods (e.g. String or URL)
----------------------------------------------------------------------

                  Key: HARMONY-6404
                  URL: https://issues.apache.org/jira/browse/HARMONY-6404
              Project: Harmony
           Issue Type: Bug
             Reporter: Boris


First I have to say that I don't know if the Java Memory Model is relevant for 
Harmony, so please reject the bug if this is not the case.

The current implementation of several of Harmony's classes that try to cache 
hashCode in an optimized way are affected by a reordering-bug that can occur 
because of the way the hashCode is cached and retrieved.
The problem is that the method contains no memory barriers, so that the VM may 
reorder the data-reads at its own will. With an unlucky reordering the method 
could return 0 although the actual hashCode is NOT 0.

Or to speak in code: This actual code:
         if (hashCode == 0) {
             // calculate hash
             hashCode = hash;
         }
         return hashCode;
could be reordered to something like
         return hashCode;
         if (hashCode == 0) {
             // calculate hash
             hashCode = hash;
         }
(which is of course no valid Java-code, but that is what the VM might do 
internally).

One common solution is to assign the field but then return the temp-value (in this case 
the variable "hash") and NOT the field itself. So that the read can not be 
reordered. (This way might be even faster because it may be one memory-read less)
Another solution would be to make hashCode volatile or to not cache the 
hashCode, but these have a performance cost.

I'll attach a patch I wrote. I could not get harmony to compile, so these are 
untested.
BTW: This fix also fixes a more likely bug in BigInteger and BigDecimal: 
Callers of hashCode might have seen half-constructed hashCodes there.

(This bug was found via the entry LANG-481 see there for some more details)


It's interesting topic. In my understand, re-order would be a issue only if hashCode is object reference. Because when "retrun hasCode" the value of "hasCode" pushed to stack, if hasCode is primitive type I don't think vm would to such re-order - the return value would be always 0, that's incorrect.

--
Best Regards,
Regis.

Reply via email to