Allow patching between dex files in the boot classpath.

Change-Id: I53f219a5382d0fcd580e96e50025fdad4fc399df
diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc
index 083fccb..0c83731 100644
--- a/compiler/dex/quick/x86/target_x86.cc
+++ b/compiler/dex/quick/x86/target_x86.cc
@@ -832,19 +832,22 @@
   Mir2Lir::Materialize();
 }
 
-void X86Mir2Lir::LoadMethodAddress(int dex_method_index, InvokeType type,
+void X86Mir2Lir::LoadMethodAddress(const MethodReference& target_method, InvokeType type,
                                    SpecialTargetRegister symbolic_reg) {
   /*
    * For x86, just generate a 32 bit move immediate instruction, that will be filled
    * in at 'link time'.  For now, put a unique value based on target to ensure that
    * code deduplication works.
    */
-  const DexFile::MethodId& id = cu_->dex_file->GetMethodId(dex_method_index);
-  uintptr_t ptr = reinterpret_cast<uintptr_t>(&id);
+  int target_method_idx = target_method.dex_method_index;
+  const DexFile* target_dex_file = target_method.dex_file;
+  const DexFile::MethodId& target_method_id = target_dex_file->GetMethodId(target_method_idx);
+  uintptr_t target_method_id_ptr = reinterpret_cast<uintptr_t>(&target_method_id);
 
-  // Generate the move instruction with the unique pointer and save index and type.
+  // Generate the move instruction with the unique pointer and save index, dex_file, and type.
   LIR *move = RawLIR(current_dalvik_offset_, kX86Mov32RI, TargetReg(symbolic_reg),
-                     static_cast<int>(ptr), dex_method_index, type);
+                     static_cast<int>(target_method_id_ptr), target_method_idx,
+                     WrapPointer(const_cast<DexFile*>(target_dex_file)), type);
   AppendLIR(move);
   method_address_insns_.Insert(move);
 }
@@ -865,18 +868,20 @@
   class_type_address_insns_.Insert(move);
 }
 
-LIR *X86Mir2Lir::CallWithLinkerFixup(int dex_method_index, InvokeType type) {
+LIR *X86Mir2Lir::CallWithLinkerFixup(const MethodReference& target_method, InvokeType type) {
   /*
    * For x86, just generate a 32 bit call relative instruction, that will be filled
    * in at 'link time'.  For now, put a unique value based on target to ensure that
    * code deduplication works.
    */
-  const DexFile::MethodId& id = cu_->dex_file->GetMethodId(dex_method_index);
-  uintptr_t ptr = reinterpret_cast<uintptr_t>(&id);
+  int target_method_idx = target_method.dex_method_index;
+  const DexFile* target_dex_file = target_method.dex_file;
+  const DexFile::MethodId& target_method_id = target_dex_file->GetMethodId(target_method_idx);
+  uintptr_t target_method_id_ptr = reinterpret_cast<uintptr_t>(&target_method_id);
 
-  // Generate the call instruction with the unique pointer and save index and type.
-  LIR *call = RawLIR(current_dalvik_offset_, kX86CallI, static_cast<int>(ptr), dex_method_index,
-                     type);
+  // Generate the call instruction with the unique pointer and save index, dex_file, and type.
+  LIR *call = RawLIR(current_dalvik_offset_, kX86CallI, static_cast<int>(target_method_id_ptr),
+                     target_method_idx, WrapPointer(const_cast<DexFile*>(target_dex_file)), type);
   AppendLIR(call);
   call_method_insns_.Insert(call);
   return call;
@@ -892,13 +897,16 @@
   for (uint32_t i = 0; i < method_address_insns_.Size(); i++) {
       LIR* p = method_address_insns_.Get(i);
       DCHECK_EQ(p->opcode, kX86Mov32RI);
-      uint32_t target = p->operands[2];
+      uint32_t target_method_idx = p->operands[2];
+      const DexFile* target_dex_file =
+          reinterpret_cast<const DexFile*>(UnwrapPointer(p->operands[3]));
 
       // The offset to patch is the last 4 bytes of the instruction.
       int patch_offset = p->offset + p->flags.size - 4;
       cu_->compiler_driver->AddMethodPatch(cu_->dex_file, cu_->class_def_idx,
                                            cu_->method_idx, cu_->invoke_type,
-                                           target, static_cast<InvokeType>(p->operands[3]),
+                                           target_method_idx, target_dex_file,
+                                           static_cast<InvokeType>(p->operands[4]),
                                            patch_offset);
   }
 
@@ -906,25 +914,28 @@
   for (uint32_t i = 0; i < class_type_address_insns_.Size(); i++) {
       LIR* p = class_type_address_insns_.Get(i);
       DCHECK_EQ(p->opcode, kX86Mov32RI);
-      uint32_t target = p->operands[2];
+      uint32_t target_method_idx = p->operands[2];
 
       // The offset to patch is the last 4 bytes of the instruction.
       int patch_offset = p->offset + p->flags.size - 4;
       cu_->compiler_driver->AddClassPatch(cu_->dex_file, cu_->class_def_idx,
-                                          cu_->method_idx, target, patch_offset);
+                                          cu_->method_idx, target_method_idx, patch_offset);
   }
 
   // And now the PC-relative calls to methods.
   for (uint32_t i = 0; i < call_method_insns_.Size(); i++) {
       LIR* p = call_method_insns_.Get(i);
       DCHECK_EQ(p->opcode, kX86CallI);
-      uint32_t target = p->operands[1];
+      uint32_t target_method_idx = p->operands[1];
+      const DexFile* target_dex_file =
+          reinterpret_cast<const DexFile*>(UnwrapPointer(p->operands[2]));
 
       // The offset to patch is the last 4 bytes of the instruction.
       int patch_offset = p->offset + p->flags.size - 4;
       cu_->compiler_driver->AddRelativeCodePatch(cu_->dex_file, cu_->class_def_idx,
-                                                 cu_->method_idx, cu_->invoke_type, target,
-                                                 static_cast<InvokeType>(p->operands[2]),
+                                                 cu_->method_idx, cu_->invoke_type,
+                                                 target_method_idx, target_dex_file,
+                                                 static_cast<InvokeType>(p->operands[3]),
                                                  patch_offset, -4 /* offset */);
   }