< prev index next >
src/hotspot/share/c1/c1_Runtime1.cpp
Print this page
rev 51185 : 8210972: Add comment text to C1 patching code
reviewed-by: jrose
*** 843,854 ****
--- 843,878 ----
// fully_initialized, the intializing_thread of the class becomes
// NULL, so the next thread to execute this code will fail the test,
// call into patch_code and complete the patching process by copying
// the patch body back into the main part of the nmethod and resume
// executing.
+
+ // NB:
+ //
+ // Patchable instruction sequences inherently exhibit race conditions,
+ // where thread A is patching an instruction at the same time thread B
+ // is executing it. The algorithms we use ensure that any observation
+ // that B can make on any intermediate states during A's patching will
+ // always end up with a correct outcome. This is easiest if there are
+ // few or no intermediate states. (Some inline caches have two
+ // related instructions that must be patched in tandem. For those,
+ // intermediate states seem to be unavoidable, but we will get the
+ // right answer from all possible observation orders.)
//
+ // When patching the entry instruction at the head of a method, or a
+ // linkable call instruction inside of a method, we try very hard to
+ // use a patch sequence which executes as a single memory transaction.
+ // This means, in practice, that when thread A patches an instruction,
+ // it should patch a 32-bit or 64-bit word that somehow overlaps the
+ // instruction or is contained in it. We believe that memory hardware
+ // will never break up such a word write, if it is naturally aligned
+ // for the word being written. We also know that some CPUs work very
+ // hard to create atomic updates even of naturally unaligned words,
+ // but we don't want to bet the farm on this always working.
//
+ // Therefore, if there is any chance of a race condition, we try to
+ // patch only naturally aligned words, as single, full-word writes.
JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_id ))
NOT_PRODUCT(_patch_code_slowcase_cnt++;)
ResourceMark rm(thread);
*** 903,913 ****
// If we are patching a field which should be atomic, then
// the generated code is not correct either, force deoptimizing.
// We need to only cover T_LONG and T_DOUBLE fields, as we can
// break access atomicity only for them.
! // Strictly speaking, the deoptimizaation on 64-bit platforms
// is unnecessary, and T_LONG stores on 32-bit platforms need
// to be handled by special patching code when AlwaysAtomicAccesses
// becomes product feature. At this point, we are still going
// for the deoptimization for consistency against volatile
// accesses.
--- 927,937 ----
// If we are patching a field which should be atomic, then
// the generated code is not correct either, force deoptimizing.
// We need to only cover T_LONG and T_DOUBLE fields, as we can
// break access atomicity only for them.
! // Strictly speaking, the deoptimization on 64-bit platforms
// is unnecessary, and T_LONG stores on 32-bit platforms need
// to be handled by special patching code when AlwaysAtomicAccesses
// becomes product feature. At this point, we are still going
// for the deoptimization for consistency against volatile
// accesses.
< prev index next >