5 ms·
AFAIU the JIT-compiler (or the CPU) could reorder the code: String x = allocate String; // allocate memory only (no initialization) initialize string x
by readittwice 9y ago
AFAIU the JIT-compiler (or the CPU) could reorder the code:
String x = allocate String; // allocate memory only (no initialization)
initialize string x // constructor
publish x // e.g. store in some global
reordered to
String x = allocate String;
publish x // after publishing some other thread could read unintialized object
initialize string x
- alkonaut 9y agoIt could, but as far as I know it then isn't a compliant JIT any more. That is, it's either a bug or a deliberate deviation from the specification.
- readittwice 9y agoWhy is the JIT not allowed to do this? (Assuming publishing isn't volatile) The reordering could also be caused by the CPU, not only by the JIT. If the JIT isn't allowed to reorder, we also need to prevent the CPU from reordering. Otherwise it doesn't make sense to restrict the JIT from reordering if the CPU could still reorder later. We would need to emit memory barriers for non-volatile loads & stores to prevent reordering on architectures like ARM. This sounds quite expensive. This doesn't make sense to me. Am I thinking wrong? Can you point me to documentation/reference that states that the JIT isn't allowed to do this?
- andars 9y agoSee section 17.5, "final Field Semantics" in http://docs.oracle.com/javase/specs/jls/se8/jls8.pdf http://docs.oracle.com/javase/specs/jls/se8/jls8.pdf. Note that a String's value field is final.
- alkonaut 9y agoExactly. Relevant passage from ^ An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields.
- readittwice 9y agoThanks, that explains it! Didn't know that final fields have this special rule and that the value field in the String class is final. So to recap: this shouldn't be possible for Strings, since the value field in the String class is final and therefore has a memory barrier. But it could happen for other classes with non-final fields.
- sanxiyn 9y agoYes, Java requires memory barriers for final fields. Yes, it is expensive on ARM, but if you don't do it you are not implementing Java.
- juancn 9y agoIt cannot do that, value is final, so value has to be fully initialized before publishing. The only way that could happen is if the String constructor unsafely published the string (which is not the case)