0

As far as I can remember, "synchronized" essentially flushes all cached values on exit, and ensures reading all values from their main location on entry. But I wonder how that can be accomplished? I mean, when the block only contains reading some locals, it's easy to know that only those locals are used in the block. However what about { x.f(); } - who knows what things it reads? The call even might be polymorphic, making JIT unable to guess what method will be called, or it might involve reflection. Then who knows if the method reads from some cached location rather than the main memory?

So, how can JVM know which values to flush/refresh when entering/exiting "synchronized" block? Or know which HB relationships need to be established, anyway? (i.e. know what data is accessed by those blocks?)

I only see one way of achieving the required behavior without disabling caching altogether: any method must read from main location on its entry (and can only cache values local to its body), this way no special processing is necessary for any method calls from synchronized block to make sure those calls don't read from caches.

I'd like to know if that is how it's implemented in some specific JVM (say Azul's) or maybe they use some other approach that I am somehow missing.

UPDATE. I already know that's not quite how Zulu works: in my test, f(x) does not seem to be re-read from main memory on every call to it. I tested it w/o "synchronized" and the external changes weren't visible to the method. But I believe it's because the method was actually inlined not called, or maybe because my code was so simple that JIT was able to deduce that it does not request any HB for any data accessed in that method. So maybe my guess is still correct - but only unless such optimizations are used.

Maksim Gumerov
  • 642
  • 8
  • 23
  • 1
    Does this answer your question? [Synchronized keyword internal implementation](https://stackoverflow.com/questions/25949145/synchronized-keyword-internal-implementation) – Joachim Sauer Jul 16 '23 at 12:12
  • There's also [this question](https://stackoverflow.com/questions/6584355/how-does-the-synchronize-functionality-work-in-java) and [this question](https://stackoverflow.com/questions/34675937/how-synchronized-keyword-works-internally). While none of these questions are specifically about Azul, the vagueness of the question suggests that these very detailed high-level overviews should already help you a lot. Different JVMs have more commonality than differences in this area. – Joachim Sauer Jul 16 '23 at 12:14
  • Well I did not expect non-vendor-specific answers to be of any help because that's implementation specific matter and hardly someone can say "this works this way" because it depends:) And surely enough those answers really don't help. Also my question is not vague but quite specific: how JVM guarantees avoiding caches in nested calls. – Maksim Gumerov Jul 16 '23 at 17:16
  • Just look at the most useful answer I found in your links Joachim: " And again, because flushing is an implementation detail, you don't even know whether it will actually flush something or do something entirely different (or doesn't do anything at all because the implementation and the specific situation already somehow guarantee that it will work)." - but that's exactly what I am asking :))) – Maksim Gumerov Jul 16 '23 at 17:16
  • Also sadly my question is not about locks. Locks by themselves would not enforce HB, it's JVM that enforces the "everything before releasing a monitor happens-before acquring of the same monitor" guarantee. And I'd like to know how it does it. – Maksim Gumerov Jul 16 '23 at 17:24
  • x86 is a [cache-coherent](https://en.wikipedia.org/wiki/Cache_coherence) architecture, so there is not much for the JVM to do. – Boann Jul 16 '23 at 17:34
  • Well not everyone uses x86 :) Also, caching comes in many flavors, like copying a value into CPU register or just copying it to a local variable in a method for example to avoid multiple reading of that value via "this" in a loop - and that's only from the top of my head. – Maksim Gumerov Jul 16 '23 at 17:38

0 Answers0