[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/nodes.h b/compiler/optimizing/nodes.h
index 649038b..c3c35ac 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -19,6 +19,7 @@
 
 #include "base/arena_containers.h"
 #include "base/arena_object.h"
+#include "dex/compiler_enums.h"
 #include "entrypoints/quick/quick_entrypoints_enum.h"
 #include "handle.h"
 #include "handle_scope.h"
@@ -718,6 +719,7 @@
   M(LoadString, Instruction)                                            \
   M(Local, Instruction)                                                 \
   M(LongConstant, Constant)                                             \
+  M(MemoryBarrier, Instruction)                                         \
   M(MonitorOperation, Instruction)                                      \
   M(Mul, BinaryOperation)                                               \
   M(Neg, UnaryOperation)                                                \
@@ -908,6 +910,12 @@
   HUseListNode<T>* use_node_;
 };
 
+// TODO: Add better documentation to this class and maybe refactor with more suggestive names.
+// - Has(All)SideEffects suggests that all the side effects are present but only ChangesSomething
+//   flag is consider.
+// - DependsOn suggests that there is a real dependency between side effects but it only
+//   checks DependendsOnSomething flag.
+//
 // Represents the side effects an instruction may have.
 class SideEffects : public ValueObject {
  public:
@@ -3437,6 +3445,22 @@
   DISALLOW_COPY_AND_ASSIGN(HCheckCast);
 };
 
+class HMemoryBarrier : public HTemplateInstruction<0> {
+ public:
+  explicit HMemoryBarrier(MemBarrierKind barrier_kind)
+      : HTemplateInstruction(SideEffects::None()),
+        barrier_kind_(barrier_kind) {}
+
+  MemBarrierKind GetBarrierKind() { return barrier_kind_; }
+
+  DECLARE_INSTRUCTION(MemoryBarrier);
+
+ private:
+  const MemBarrierKind barrier_kind_;
+
+  DISALLOW_COPY_AND_ASSIGN(HMemoryBarrier);
+};
+
 class HMonitorOperation : public HTemplateInstruction<1> {
  public:
   enum OperationKind {