[optimizing] Add memory barriers in constructors when needed

If a class has final fields we must add a memory barrier before
returning from constructor. This makes sure the fields are visible to
other threads.

Bug: 19851497
Change-Id: If8c485092fc512efb9636cd568cb0543fb27688e
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 8a64d81..fff2906 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -520,8 +520,19 @@
   UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction());
 }
 
+static bool RequiresConstructorBarrier(const DexCompilationUnit& cu, const CompilerDriver& driver) {
+  Thread* self = Thread::Current();
+  return cu.IsConstructor()
+      && driver.RequiresConstructorBarrier(self, cu.GetDexFile(), cu.GetClassDefIndex());
+}
+
 void HGraphBuilder::BuildReturn(const Instruction& instruction, Primitive::Type type) {
   if (type == Primitive::kPrimVoid) {
+    // Note that we might insert redundant barriers when inlining `super` calls.
+    // TODO: add a data flow analysis to get rid of duplicate barriers.
+    if (RequiresConstructorBarrier(*dex_compilation_unit_, *compiler_driver_)) {
+      current_block_->AddInstruction(new (arena_) HMemoryBarrier(kStoreStore));
+    }
     current_block_->AddInstruction(new (arena_) HReturnVoid());
   } else {
     HInstruction* value = LoadLocal(instruction.VRegA(), type);