Implement monitorenter/monitorexit.

Pretty simple as they just invoke the runtime.

Change-Id: I5fcb2c783deac27e55e28d8b3da3e68ea4b77363
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 0c75e41..1545b0a 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -508,6 +508,7 @@
   M(LoadString, Instruction)                                            \
   M(Local, Instruction)                                                 \
   M(LongConstant, Constant)                                             \
+  M(MonitorOperation, Instruction)                                      \
   M(Mul, BinaryOperation)                                               \
   M(Neg, UnaryOperation)                                                \
   M(NewArray, Instruction)                                              \
@@ -2431,6 +2432,36 @@
   DISALLOW_COPY_AND_ASSIGN(HCheckCast);
 };
 
+class HMonitorOperation : public HTemplateInstruction<1> {
+ public:
+  enum OperationKind {
+    kEnter,
+    kExit,
+  };
+
+  HMonitorOperation(HInstruction* object, OperationKind kind, uint32_t dex_pc)
+    : HTemplateInstruction(SideEffects::None()), kind_(kind), dex_pc_(dex_pc) {
+    SetRawInputAt(0, object);
+  }
+
+  // Instruction may throw a Java exception, so we need an environment.
+  bool NeedsEnvironment() const OVERRIDE { return true; }
+  bool CanThrow() const OVERRIDE { return true; }
+
+  uint32_t GetDexPc() const { return dex_pc_; }
+
+  bool IsEnter() const { return kind_ == kEnter; }
+
+  DECLARE_INSTRUCTION(MonitorOperation);
+
+ protected:
+  const OperationKind kind_;
+  const uint32_t dex_pc_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(HMonitorOperation);
+};
+
 
 class MoveOperands : public ArenaObject<kArenaAllocMisc> {
  public: