Handle variable size of methods properly between 32 and 64 bit.

Bug: 19100762
Change-Id: I62358905fa882284d0201ed3c1e97e1286ccec5f
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index b234249..670b76c 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -273,13 +273,7 @@
 
 void ImageWriter::AssignImageBinSlot(mirror::Object* object) {
   DCHECK(object != nullptr);
-  size_t object_size;
-  if (object->IsArtMethod()) {
-    // Methods are sized based on the target pointer size.
-    object_size = mirror::ArtMethod::InstanceSize(target_ptr_size_);
-  } else {
-    object_size = object->SizeOf();
-  }
+  size_t object_size = object->SizeOf();
 
   // The magic happens here. We segregate objects into different bins based
   // on how likely they are to get dirty at runtime.
@@ -931,7 +925,7 @@
   if (obj->IsArtMethod()) {
     // Size without pointer fields since we don't want to overrun the buffer if target art method
     // is 32 bits but source is 64 bits.
-    n = mirror::ArtMethod::SizeWithoutPointerFields(sizeof(void*));
+    n = mirror::ArtMethod::SizeWithoutPointerFields(image_writer->target_ptr_size_);
   } else {
     n = obj->SizeOf();
   }
@@ -1016,10 +1010,6 @@
   }
   if (orig->IsArtMethod<kVerifyNone>()) {
     FixupMethod(orig->AsArtMethod<kVerifyNone>(), down_cast<ArtMethod*>(copy));
-  } else if (orig->IsClass() && orig->AsClass()->IsArtMethodClass()) {
-    // Set the right size for the target.
-    size_t size = mirror::ArtMethod::InstanceSize(target_ptr_size_);
-    down_cast<mirror::Class*>(copy)->SetObjectSizeWithoutChecks(size);
   }
 }
 
@@ -1031,7 +1021,9 @@
   // trampoline.
 
   // Quick entrypoint:
-  const uint8_t* quick_code = GetOatAddress(method->GetQuickOatCodeOffset());
+  uint32_t quick_oat_code_offset = PointerToLowMemUInt32(
+      method->GetEntryPointFromQuickCompiledCodePtrSize(target_ptr_size_));
+  const uint8_t* quick_code = GetOatAddress(quick_oat_code_offset);
   *quick_is_interpreted = false;
   if (quick_code != nullptr &&
       (!method->IsStatic() || method->IsConstructor() || method->GetDeclaringClass()->IsInitialized())) {
@@ -1082,11 +1074,12 @@
   // locations.
   // Copy all of the fields from the runtime methods to the target methods first since we did a
   // bytewise copy earlier.
-  copy->SetEntryPointFromInterpreterPtrSize<kVerifyNone>(orig->GetEntryPointFromInterpreter(),
-                                                         target_ptr_size_);
-  copy->SetEntryPointFromJniPtrSize<kVerifyNone>(orig->GetEntryPointFromJni(), target_ptr_size_);
+  copy->SetEntryPointFromInterpreterPtrSize<kVerifyNone>(
+      orig->GetEntryPointFromInterpreterPtrSize(target_ptr_size_), target_ptr_size_);
+  copy->SetEntryPointFromJniPtrSize<kVerifyNone>(
+      orig->GetEntryPointFromJniPtrSize(target_ptr_size_), target_ptr_size_);
   copy->SetEntryPointFromQuickCompiledCodePtrSize<kVerifyNone>(
-      orig->GetEntryPointFromQuickCompiledCode(), target_ptr_size_);
+      orig->GetEntryPointFromQuickCompiledCodePtrSize(target_ptr_size_), target_ptr_size_);
 
   // The resolution method has a special trampoline to call.
   Runtime* runtime = Runtime::Current();
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index 7516811..9c0157e 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -899,7 +899,8 @@
 class OatWriter::InitImageMethodVisitor : public OatDexMethodVisitor {
  public:
   InitImageMethodVisitor(OatWriter* writer, size_t offset)
-    : OatDexMethodVisitor(writer, offset) {
+    : OatDexMethodVisitor(writer, offset),
+      pointer_size_(GetInstructionSetPointerSize(writer_->compiler_driver_->GetInstructionSet())) {
   }
 
   bool VisitMethod(size_t class_def_method_index, const ClassDataItemIterator& it)
@@ -932,10 +933,14 @@
       std::string dump = exc->Dump();
       LOG(FATAL) << dump;
     }
-    method->SetQuickOatCodeOffset(offsets.code_offset_);
+    method->SetEntryPointFromQuickCompiledCodePtrSize(reinterpret_cast<void*>(offsets.code_offset_),
+                                                      pointer_size_);
 
     return true;
   }
+
+ protected:
+  const size_t pointer_size_;
 };
 
 class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor {
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index e0df6db..da1c3c0 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -377,7 +377,8 @@
   Handle<mirror::Class> java_lang_reflect_ArtMethod(hs.NewHandle(
     AllocClass(self, java_lang_Class.Get(), mirror::ArtMethod::ClassSize())));
   CHECK(java_lang_reflect_ArtMethod.Get() != nullptr);
-  java_lang_reflect_ArtMethod->SetObjectSize(mirror::ArtMethod::InstanceSize(sizeof(void*)));
+  size_t pointer_size = GetInstructionSetPointerSize(Runtime::Current()->GetInstructionSet());
+  java_lang_reflect_ArtMethod->SetObjectSize(mirror::ArtMethod::InstanceSize(pointer_size));
   SetClassRoot(kJavaLangReflectArtMethod, java_lang_reflect_ArtMethod.Get());
   java_lang_reflect_ArtMethod->SetStatus(mirror::Class::kStatusResolved, self);
   mirror::ArtMethod::SetClass(java_lang_reflect_ArtMethod.Get());
@@ -5481,7 +5482,8 @@
     klass->SetNumReferenceInstanceFields(num_reference_fields);
     if (!klass->IsVariableSize()) {
       if (klass->DescriptorEquals("Ljava/lang/reflect/ArtMethod;")) {
-        klass->SetObjectSize(mirror::ArtMethod::InstanceSize(sizeof(void*)));
+        size_t pointer_size = GetInstructionSetPointerSize(Runtime::Current()->GetInstructionSet());
+        klass->SetObjectSize(mirror::ArtMethod::InstanceSize(pointer_size));
       } else {
         std::string temp;
         DCHECK_GE(size, sizeof(mirror::Object)) << klass->GetDescriptor(&temp);
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 43f3a2e..f795768 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -899,10 +899,11 @@
                  dex_locations,
                  runtime_options.GetOrDefault(Opt::Image),
                  &boot_class_path);
+    instruction_set_ = runtime_options.GetOrDefault(Opt::ImageInstructionSet);
     class_linker_->InitWithoutImage(std::move(boot_class_path));
 
     // TODO: Should we move the following to InitWithoutImage?
-    SetInstructionSet(kRuntimeISA);
+    SetInstructionSet(instruction_set_);
     for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
       Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
       if (!HasCalleeSaveMethod(type)) {
@@ -1322,7 +1323,8 @@
   method->SetDexMethodIndex(DexFile::kDexNoIndex);
   // When compiling, the code pointer will get set later when the image is loaded.
   if (runtime->IsCompiler()) {
-    method->SetEntryPointFromQuickCompiledCode(nullptr);
+    size_t pointer_size = GetInstructionSetPointerSize(instruction_set_);
+    method->SetEntryPointFromQuickCompiledCodePtrSize(nullptr, pointer_size);
   } else {
     method->SetEntryPointFromQuickCompiledCode(GetQuickImtConflictStub());
   }
@@ -1340,7 +1342,8 @@
   method->SetDexMethodIndex(DexFile::kDexNoIndex);
   // When compiling, the code pointer will get set later when the image is loaded.
   if (runtime->IsCompiler()) {
-    method->SetEntryPointFromQuickCompiledCode(nullptr);
+    size_t pointer_size = GetInstructionSetPointerSize(instruction_set_);
+    method->SetEntryPointFromQuickCompiledCodePtrSize(nullptr, pointer_size);
   } else {
     method->SetEntryPointFromQuickCompiledCode(GetQuickResolutionStub());
   }
@@ -1356,7 +1359,8 @@
   method->SetDeclaringClass(mirror::ArtMethod::GetJavaLangReflectArtMethod());
   // TODO: use a special method for callee saves
   method->SetDexMethodIndex(DexFile::kDexNoIndex);
-  method->SetEntryPointFromQuickCompiledCode(nullptr);
+  size_t pointer_size = GetInstructionSetPointerSize(instruction_set_);
+  method->SetEntryPointFromQuickCompiledCodePtrSize(nullptr, pointer_size);
   DCHECK_NE(instruction_set_, kNone);
   return method.Get();
 }
diff --git a/runtime/stack.cc b/runtime/stack.cc
index b771aa7..b39aebf 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -134,7 +134,8 @@
     } else {
       return cur_shadow_frame_->GetVRegReference(0);
     }
-  } else if (m->IsOptimized(sizeof(void*))) {
+  } else if (m->IsOptimized(GetInstructionSetPointerSize(
+      Runtime::Current()->GetInstructionSet()))) {
     // TODO: Implement, currently only used for exceptions when jdwp is enabled.
     UNIMPLEMENTED(WARNING)
         << "StackVisitor::GetThisObject is unimplemented with the optimizing compiler";