Revert "Revert "Optimizing: Better invoke-static/-direct dispatch.""

Fixed kCallArtMethod to use correct callee location for
kRecursive. This combination is used when compiling with
debuggable flag set.

This reverts commit b2c431e80e92eb6437788cc544cee6c88c3156df.

Change-Id: Idee0f2a794199ebdf24892c60f8a5dcf057db01c
diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h
index 2582444..938369b 100644
--- a/compiler/optimizing/code_generator.h
+++ b/compiler/optimizing/code_generator.h
@@ -48,6 +48,7 @@
 class Assembler;
 class CodeGenerator;
 class DexCompilationUnit;
+class LinkerPatch;
 class ParallelMoveResolver;
 class SrcMapElem;
 template <class Alloc>
@@ -160,6 +161,7 @@
 
   virtual void Initialize() = 0;
   virtual void Finalize(CodeAllocator* allocator);
+  virtual void EmitLinkerPatches(ArenaVector<LinkerPatch>* linker_patches);
   virtual void GenerateFrameEntry() = 0;
   virtual void GenerateFrameExit() = 0;
   virtual void Bind(HBasicBlock* block) = 0;
@@ -356,6 +358,17 @@
   DisassemblyInformation* GetDisassemblyInformation() const { return disasm_info_; }
 
  protected:
+  // Method patch info used for recording locations of required linker patches and
+  // target methods. The target method can be used for various purposes, whether for
+  // patching the address of the method or the code pointer or a PC-relative call.
+  template <typename LabelType>
+  struct MethodPatchInfo {
+    explicit MethodPatchInfo(MethodReference m) : target_method(m), label() { }
+
+    MethodReference target_method;
+    LabelType label;
+  };
+
   CodeGenerator(HGraph* graph,
                 size_t number_of_core_registers,
                 size_t number_of_fpu_registers,
@@ -427,8 +440,8 @@
 
   // Arm64 has its own type for a label, so we need to templatize this method
   // to share the logic.
-  template <typename T>
-  T* CommonGetLabelOf(T* raw_pointer_to_labels_array, HBasicBlock* block) const {
+  template <typename LabelType>
+  LabelType* CommonGetLabelOf(LabelType* raw_pointer_to_labels_array, HBasicBlock* block) const {
     block = FirstNonEmptyBlock(block);
     return raw_pointer_to_labels_array + block->GetBlockId();
   }