I see a lot of posts that discuss why Java's current implementation of the hashCode() method of String is correct:
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i]; // (*)
}
hash = h; // (**)
}
return h;
}
However, the aforementioned explanations focus on reading the value of the hash field and how instruction reordering may cause problems if we don't use a local variable h.
My question is: what in the Java Memory Model forbids the compiler or JVM to write a temporary result to hash before line (**)?
For example, a hypothetical compiler/JVM might decide to "save local variables" and do the computation (*) not in the local variable h but directly in hash – what forbids this?