Add a HCurrentMethod node.

This enables register allocation for the current method, so
that users of it don't always load it from the stack.

Currently only used by HLoadClass. Will make follow-up
CLs for the other users.

Change-Id: If73324d85643102faba47fabbbd2755eb258c59c
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 01870c3..d542e59 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -35,6 +35,7 @@
 
 class GraphChecker;
 class HBasicBlock;
+class HCurrentMethod;
 class HDoubleConstant;
 class HEnvironment;
 class HFloatConstant;
@@ -147,7 +148,8 @@
         cached_int_constants_(std::less<int32_t>(), arena->Adapter()),
         cached_float_constants_(std::less<int32_t>(), arena->Adapter()),
         cached_long_constants_(std::less<int64_t>(), arena->Adapter()),
-        cached_double_constants_(std::less<int64_t>(), arena->Adapter()) {}
+        cached_double_constants_(std::less<int64_t>(), arena->Adapter()),
+        cached_current_method_(nullptr) {}
 
   ArenaAllocator* GetArena() const { return arena_; }
   const GrowableArray<HBasicBlock*>& GetBlocks() const { return blocks_; }
@@ -278,6 +280,8 @@
     return CreateConstant(bit_cast<int64_t, double>(value), &cached_double_constants_);
   }
 
+  HCurrentMethod* GetCurrentMethod();
+
   HBasicBlock* FindCommonDominator(HBasicBlock* first, HBasicBlock* second) const;
 
   const DexFile& GetDexFile() const {
@@ -386,6 +390,8 @@
   ArenaSafeMap<int64_t, HLongConstant*> cached_long_constants_;
   ArenaSafeMap<int64_t, HDoubleConstant*> cached_double_constants_;
 
+  HCurrentMethod* cached_current_method_;
+
   friend class SsaBuilder;           // For caching constants.
   friend class SsaLivenessAnalysis;  // For the linear order.
   ART_FRIEND_TEST(GraphTest, IfSuccessorSimpleJoinBlock1);
@@ -811,6 +817,7 @@
   M(ClinitCheck, Instruction)                                           \
   M(Compare, BinaryOperation)                                           \
   M(Condition, BinaryOperation)                                         \
+  M(CurrentMethod, Instruction)                                         \
   M(Deoptimize, Instruction)                                            \
   M(Div, BinaryOperation)                                               \
   M(DivZeroCheck, Instruction)                                          \
@@ -1824,6 +1831,19 @@
   DISALLOW_COPY_AND_ASSIGN(HDeoptimize);
 };
 
+// Represents the ArtMethod that was passed as a first argument to
+// the method. It is used by instructions that depend on it, like
+// instructions that work with the dex cache.
+class HCurrentMethod : public HExpression<0> {
+ public:
+  HCurrentMethod() : HExpression(Primitive::kPrimNot, SideEffects::None()) {}
+
+  DECLARE_INSTRUCTION(CurrentMethod);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(HCurrentMethod);
+};
+
 class HUnaryOperation : public HExpression<1> {
  public:
   HUnaryOperation(Primitive::Type result_type, HInstruction* input)
@@ -3433,9 +3453,10 @@
 /**
  * Instruction to load a Class object.
  */
-class HLoadClass : public HExpression<0> {
+class HLoadClass : public HExpression<1> {
  public:
-  HLoadClass(uint16_t type_index,
+  HLoadClass(HCurrentMethod* current_method,
+             uint16_t type_index,
              const DexFile& dex_file,
              bool is_referrers_class,
              uint32_t dex_pc)
@@ -3445,7 +3466,9 @@
         is_referrers_class_(is_referrers_class),
         dex_pc_(dex_pc),
         generate_clinit_check_(false),
-        loaded_class_rti_(ReferenceTypeInfo::CreateTop(/* is_exact */ false)) {}
+        loaded_class_rti_(ReferenceTypeInfo::CreateTop(/* is_exact */ false)) {
+    SetRawInputAt(0, current_method);
+  }
 
   bool CanBeMoved() const OVERRIDE { return true; }