summaryrefslogtreecommitdiff
path: root/compiler/driver/compiler_driver.h
diff options
context:
space:
mode:
author Treehugger Robot <treehugger-gerrit@google.com> 2017-05-03 14:13:58 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2017-05-03 14:13:59 +0000
commit29825550d6bd7f1185e16b3925c7f084078e688e (patch)
treece96bd0b74266b14d47419cd1d4dd969801198eb /compiler/driver/compiler_driver.h
parent15cb9753075bcaa5b91a6497a2d35e8bd98af1f0 (diff)
parentd01745ef88bfd25df574a885d90a1a7785db5f5b (diff)
Merge "optimizing: constructor fence redundancy elimination - remove dmb after LSE"
Diffstat (limited to 'compiler/driver/compiler_driver.h')
-rw-r--r--compiler/driver/compiler_driver.h34
1 files changed, 34 insertions, 0 deletions
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 874e35716c..fbab9dfbaf 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -179,6 +179,40 @@ class CompilerDriver {
uint16_t class_def_index,
bool requires)
REQUIRES(!requires_constructor_barrier_lock_);
+
+ // Do the <init> methods for this class require a constructor barrier (prior to the return)?
+ // The answer is "yes", if and only if this class has any instance final fields.
+ // (This must not be called for any non-<init> methods; the answer would be "no").
+ //
+ // ---
+ //
+ // JLS 17.5.1 "Semantics of final fields" mandates that all final fields are frozen at the end
+ // of the invoked constructor. The constructor barrier is a conservative implementation means of
+ // enforcing the freezes happen-before the object being constructed is observable by another
+ // thread.
+ //
+ // Note: This question only makes sense for instance constructors;
+ // static constructors (despite possibly having finals) never need
+ // a barrier.
+ //
+ // JLS 12.4.2 "Detailed Initialization Procedure" approximately describes
+ // class initialization as:
+ //
+ // lock(class.lock)
+ // class.state = initializing
+ // unlock(class.lock)
+ //
+ // invoke <clinit>
+ //
+ // lock(class.lock)
+ // class.state = initialized
+ // unlock(class.lock) <-- acts as a release
+ //
+ // The last operation in the above example acts as an atomic release
+ // for any stores in <clinit>, which ends up being stricter
+ // than what a constructor barrier needs.
+ //
+ // See also QuasiAtomic::ThreadFenceForConstructor().
bool RequiresConstructorBarrier(Thread* self,
const DexFile* dex_file,
uint16_t class_def_index)