From c934e483ceabbd589422beea1fa35f5182ecfa99 Mon Sep 17 00:00:00 2001 From: Mathieu Chartier Date: Thu, 20 Nov 2014 17:08:58 -0800 Subject: [PATCH] Fix oatdump to use OatHeader pointer size Bug: 18473190 Change-Id: If505b4f62105899f4f1257d3bccda3e6eb0dcd7c --- oatdump/oatdump.cc | 35 +++++++++++++------ .../quick/quick_instrumentation_entrypoints.cc | 2 +- runtime/fault_handler.cc | 3 +- runtime/instrumentation.cc | 4 +-- runtime/instrumentation.h | 2 +- runtime/mirror/art_method-inl.h | 39 +++++++++++----------- runtime/mirror/art_method.cc | 12 +++---- runtime/mirror/art_method.h | 16 +++++---- runtime/stack.cc | 16 ++++----- runtime/thread.cc | 4 +-- 10 files changed, 76 insertions(+), 57 deletions(-) diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 8f93a66ca..d638b297b 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -143,7 +143,8 @@ class OatDumper { : oat_file_(oat_file), oat_dex_files_(oat_file.GetOatDexFiles()), options_(options), - disassembler_(Disassembler::Create(oat_file_.GetOatHeader().GetInstructionSet(), + instruction_set_(oat_file_.GetOatHeader().GetInstructionSet()), + disassembler_(Disassembler::Create(instruction_set_, new DisassemblerOptions(options_->absolute_addresses_, oat_file.Begin()))) { AddAllOffsets(); @@ -154,6 +155,10 @@ class OatDumper { delete disassembler_; } + InstructionSet GetInstructionSet() { + return instruction_set_; + } + bool Dump(std::ostream& os) { bool success = true; const OatHeader& oat_header = oat_file_.GetOatHeader(); @@ -265,7 +270,7 @@ class OatDumper { return end_offset - begin_offset; } - InstructionSet GetInstructionSet() { + InstructionSet GetOatInstructionSet() { return oat_file_.GetOatHeader().GetInstructionSet(); } @@ -951,6 +956,7 @@ class OatDumper { const OatFile& oat_file_; const std::vector oat_dex_files_; const OatDumperOptions* options_; + InstructionSet instruction_set_; std::set offsets_; Disassembler* disassembler_; }; @@ -1201,7 +1207,8 @@ class ImageDumper { const void* GetQuickOatCodeBegin(mirror::ArtMethod* m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - const void* quick_code = m->GetEntryPointFromQuickCompiledCode(); + const void* quick_code = m->GetEntryPointFromQuickCompiledCodePtrSize( + InstructionSetPointerSize(oat_dumper_->GetOatInstructionSet())); if (quick_code == Runtime::Current()->GetClassLinker()->GetQuickResolutionTrampoline()) { quick_code = oat_dumper_->GetQuickOatCode(m); } @@ -1302,11 +1309,14 @@ class ImageDumper { } } } else if (obj->IsArtMethod()) { + const size_t image_pointer_size = InstructionSetPointerSize( + state->oat_dumper_->GetOatInstructionSet()); mirror::ArtMethod* method = obj->AsArtMethod(); if (method->IsNative()) { // TODO: portable dumping. - DCHECK(method->GetNativeGcMap() == nullptr) << PrettyMethod(method); - DCHECK(method->GetMappingTable() == nullptr) << PrettyMethod(method); + DCHECK(method->GetNativeGcMapPtrSize(image_pointer_size) == nullptr) + << PrettyMethod(method); + DCHECK(method->GetMappingTable(image_pointer_size) == nullptr) << PrettyMethod(method); bool first_occurrence; const void* quick_oat_code = state->GetQuickOatCodeBegin(method); uint32_t quick_oat_code_size = state->GetQuickOatCodeSize(method); @@ -1314,33 +1324,36 @@ class ImageDumper { if (first_occurrence) { state->stats_.native_to_managed_code_bytes += quick_oat_code_size; } - if (quick_oat_code != method->GetEntryPointFromQuickCompiledCode()) { + if (quick_oat_code != method->GetEntryPointFromQuickCompiledCodePtrSize( + image_pointer_size)) { indent_os << StringPrintf("OAT CODE: %p\n", quick_oat_code); } } else if (method->IsAbstract() || method->IsCalleeSaveMethod() || method->IsResolutionMethod() || method->IsImtConflictMethod() || method->IsImtUnimplementedMethod() || method->IsClassInitializer()) { - DCHECK(method->GetNativeGcMap() == nullptr) << PrettyMethod(method); - DCHECK(method->GetMappingTable() == nullptr) << PrettyMethod(method); + DCHECK(method->GetNativeGcMapPtrSize(image_pointer_size) == nullptr) + << PrettyMethod(method); + DCHECK(method->GetMappingTable(image_pointer_size) == nullptr) << PrettyMethod(method); } else { const DexFile::CodeItem* code_item = method->GetCodeItem(); size_t dex_instruction_bytes = code_item->insns_size_in_code_units_ * 2; state->stats_.dex_instruction_bytes += dex_instruction_bytes; bool first_occurrence; - size_t gc_map_bytes = state->ComputeOatSize(method->GetNativeGcMap(), &first_occurrence); + size_t gc_map_bytes = state->ComputeOatSize( + method->GetNativeGcMapPtrSize(image_pointer_size), &first_occurrence); if (first_occurrence) { state->stats_.gc_map_bytes += gc_map_bytes; } size_t pc_mapping_table_bytes = - state->ComputeOatSize(method->GetMappingTable(), &first_occurrence); + state->ComputeOatSize(method->GetMappingTable(image_pointer_size), &first_occurrence); if (first_occurrence) { state->stats_.pc_mapping_table_bytes += pc_mapping_table_bytes; } size_t vmap_table_bytes = - state->ComputeOatSize(method->GetVmapTable(), &first_occurrence); + state->ComputeOatSize(method->GetVmapTable(image_pointer_size), &first_occurrence); if (first_occurrence) { state->stats_.vmap_table_bytes += vmap_table_bytes; } diff --git a/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc b/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc index 49df62db4..771a280ac 100644 --- a/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc @@ -36,7 +36,7 @@ extern "C" const void* artInstrumentationMethodEntryFromCode(mirror::ArtMethod* if (instrumentation->IsDeoptimized(method)) { result = GetQuickToInterpreterBridge(); } else { - result = instrumentation->GetQuickCodeFor(method); + result = instrumentation->GetQuickCodeFor(method, sizeof(void*)); } DCHECK((result != Runtime::Current()->GetClassLinker()->GetQuickToInterpreterBridgeTrampoline()) || !Runtime::Current()->GetHeap()->HasImageSpace()); diff --git a/runtime/fault_handler.cc b/runtime/fault_handler.cc index 56d709ad2..63eef51e8 100644 --- a/runtime/fault_handler.cc +++ b/runtime/fault_handler.cc @@ -268,7 +268,8 @@ bool FaultManager::IsInGeneratedCode(siginfo_t* siginfo, void* context, bool che // at the return PC address. if (true || kIsDebugBuild) { VLOG(signals) << "looking for dex pc for return pc " << std::hex << return_pc; - const void* code = Runtime::Current()->GetInstrumentation()->GetQuickCodeFor(method_obj); + const void* code = Runtime::Current()->GetInstrumentation()->GetQuickCodeFor(method_obj, + sizeof(void*)); uint32_t sought_offset = return_pc - reinterpret_cast(code); VLOG(signals) << "pc offset: " << std::hex << sought_offset; } diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc index 652d29bf0..a698c9efd 100644 --- a/runtime/instrumentation.cc +++ b/runtime/instrumentation.cc @@ -918,10 +918,10 @@ void Instrumentation::DisableMethodTracing() { ConfigureStubs(false, false); } -const void* Instrumentation::GetQuickCodeFor(mirror::ArtMethod* method) const { +const void* Instrumentation::GetQuickCodeFor(mirror::ArtMethod* method, size_t pointer_size) const { Runtime* runtime = Runtime::Current(); if (LIKELY(!instrumentation_stubs_installed_)) { - const void* code = method->GetEntryPointFromQuickCompiledCode(); + const void* code = method->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size); DCHECK(code != nullptr); ClassLinker* class_linker = runtime->GetClassLinker(); if (LIKELY(code != class_linker->GetQuickResolutionTrampoline()) && diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h index 3017bf6a3..c261a1a67 100644 --- a/runtime/instrumentation.h +++ b/runtime/instrumentation.h @@ -200,7 +200,7 @@ class Instrumentation { // Get the quick code for the given method. More efficient than asking the class linker as it // will short-cut to GetCode if instrumentation and static method resolution stubs aren't // installed. - const void* GetQuickCodeFor(mirror::ArtMethod* method) const + const void* GetQuickCodeFor(mirror::ArtMethod* method, size_t pointer_size) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void ForceInterpretOnly() { diff --git a/runtime/mirror/art_method-inl.h b/runtime/mirror/art_method-inl.h index 33dd19f74..8844f1c52 100644 --- a/runtime/mirror/art_method-inl.h +++ b/runtime/mirror/art_method-inl.h @@ -231,16 +231,16 @@ inline void ArtMethod::SetPortableOatCodeOffset(uint32_t code_offset) { } #endif -inline const void* ArtMethod::GetQuickOatEntryPoint() { +inline const void* ArtMethod::GetQuickOatEntryPoint(size_t pointer_size) { if (IsPortableCompiled() || IsAbstract() || IsRuntimeMethod() || IsProxyMethod()) { return nullptr; } Runtime* runtime = Runtime::Current(); - const void* entry_point = runtime->GetInstrumentation()->GetQuickCodeFor(this); + const void* entry_point = runtime->GetInstrumentation()->GetQuickCodeFor(this, pointer_size); // On failure, instead of nullptr we get the quick-generic-jni-trampoline for native method // indicating the generic JNI, or the quick-to-interpreter-bridge (but not the trampoline) // for non-native methods. - DCHECK(entry_point != runtime->GetClassLinker()->GetQuickToInterpreterBridgeTrampoline()); + DCHECK_NE(entry_point, runtime->GetClassLinker()->GetQuickToInterpreterBridgeTrampoline()); if (UNLIKELY(entry_point == GetQuickToInterpreterBridge()) || UNLIKELY(entry_point == runtime->GetClassLinker()->GetQuickGenericJniTrampoline())) { return nullptr; @@ -248,21 +248,21 @@ inline const void* ArtMethod::GetQuickOatEntryPoint() { return entry_point; } -inline const void* ArtMethod::GetQuickOatCodePointer() { - return EntryPointToCodePointer(GetQuickOatEntryPoint()); +inline const void* ArtMethod::GetQuickOatCodePointer(size_t pointer_size) { + return EntryPointToCodePointer(GetQuickOatEntryPoint(pointer_size)); } -inline const uint8_t* ArtMethod::GetMappingTable() { - const void* code_pointer = GetQuickOatCodePointer(); +inline const uint8_t* ArtMethod::GetMappingTable(size_t pointer_size) { + const void* code_pointer = GetQuickOatCodePointer(pointer_size); if (code_pointer == nullptr) { return nullptr; } - return GetMappingTable(code_pointer); + return GetMappingTable(code_pointer, pointer_size); } -inline const uint8_t* ArtMethod::GetMappingTable(const void* code_pointer) { +inline const uint8_t* ArtMethod::GetMappingTable(const void* code_pointer, size_t pointer_size) { DCHECK(code_pointer != nullptr); - DCHECK(code_pointer == GetQuickOatCodePointer()); + DCHECK_EQ(code_pointer, GetQuickOatCodePointer(pointer_size)); uint32_t offset = reinterpret_cast(code_pointer)[-1].mapping_table_offset_; if (UNLIKELY(offset == 0u)) { @@ -271,17 +271,17 @@ inline const uint8_t* ArtMethod::GetMappingTable(const void* code_pointer) { return reinterpret_cast(code_pointer) - offset; } -inline const uint8_t* ArtMethod::GetVmapTable() { - const void* code_pointer = GetQuickOatCodePointer(); +inline const uint8_t* ArtMethod::GetVmapTable(size_t pointer_size) { + const void* code_pointer = GetQuickOatCodePointer(pointer_size); if (code_pointer == nullptr) { return nullptr; } - return GetVmapTable(code_pointer); + return GetVmapTable(code_pointer, pointer_size); } -inline const uint8_t* ArtMethod::GetVmapTable(const void* code_pointer) { +inline const uint8_t* ArtMethod::GetVmapTable(const void* code_pointer, size_t pointer_size) { DCHECK(code_pointer != nullptr); - DCHECK(code_pointer == GetQuickOatCodePointer()); + DCHECK_EQ(code_pointer, GetQuickOatCodePointer(pointer_size)); uint32_t offset = reinterpret_cast(code_pointer)[-1].vmap_table_offset_; if (UNLIKELY(offset == 0u)) { @@ -342,13 +342,14 @@ inline bool ArtMethod::IsImtUnimplementedMethod() { } inline uintptr_t ArtMethod::NativePcOffset(const uintptr_t pc) { - const void* code = Runtime::Current()->GetInstrumentation()->GetQuickCodeFor(this); + const void* code = Runtime::Current()->GetInstrumentation()->GetQuickCodeFor(this, sizeof(void*)); return pc - reinterpret_cast(code); } inline uintptr_t ArtMethod::NativePcOffset(const uintptr_t pc, const void* quick_entry_point) { DCHECK(quick_entry_point != GetQuickToInterpreterBridge()); - DCHECK(quick_entry_point == Runtime::Current()->GetInstrumentation()->GetQuickCodeFor(this)); + DCHECK_EQ(quick_entry_point, + Runtime::Current()->GetInstrumentation()->GetQuickCodeFor(this, sizeof(void*))); return pc - reinterpret_cast(quick_entry_point); } @@ -369,7 +370,7 @@ inline QuickMethodFrameInfo ArtMethod::GetQuickFrameInfo() { return runtime->GetRuntimeMethodFrameInfo(this); } - const void* entry_point = runtime->GetInstrumentation()->GetQuickCodeFor(this); + const void* entry_point = runtime->GetInstrumentation()->GetQuickCodeFor(this, sizeof(void*)); // On failure, instead of nullptr we get the quick-generic-jni-trampoline for native method // indicating the generic JNI, or the quick-to-interpreter-bridge (but not the trampoline) // for non-native methods. And we really shouldn't see a failure for non-native methods here. @@ -400,7 +401,7 @@ inline QuickMethodFrameInfo ArtMethod::GetQuickFrameInfo() { inline QuickMethodFrameInfo ArtMethod::GetQuickFrameInfo(const void* code_pointer) { DCHECK(code_pointer != nullptr); - DCHECK_EQ(code_pointer, GetQuickOatCodePointer()); + DCHECK_EQ(code_pointer, GetQuickOatCodePointer(sizeof(void*))); return reinterpret_cast(code_pointer)[-1].frame_info_; } diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc index 5ed7f2ead..9bd5e7d9b 100644 --- a/runtime/mirror/art_method.cc +++ b/runtime/mirror/art_method.cc @@ -152,9 +152,9 @@ uint32_t ArtMethod::ToDexPc(const uintptr_t pc, bool abort_on_failure) { // Portable doesn't use the machine pc, we just use dex pc instead. return static_cast(pc); } - const void* entry_point = GetQuickOatEntryPoint(); - MappingTable table( - entry_point != nullptr ? GetMappingTable(EntryPointToCodePointer(entry_point)) : nullptr); + const void* entry_point = GetQuickOatEntryPoint(sizeof(void*)); + MappingTable table(entry_point != nullptr ? + GetMappingTable(EntryPointToCodePointer(entry_point), sizeof(void*)) : nullptr); if (table.TotalSize() == 0) { // NOTE: Special methods (see Mir2Lir::GenSpecialCase()) have an empty mapping // but they have no suspend checks and, consequently, we never call ToDexPc() for them. @@ -185,9 +185,9 @@ uint32_t ArtMethod::ToDexPc(const uintptr_t pc, bool abort_on_failure) { } uintptr_t ArtMethod::ToNativePc(const uint32_t dex_pc) { - const void* entry_point = GetQuickOatEntryPoint(); - MappingTable table( - entry_point != nullptr ? GetMappingTable(EntryPointToCodePointer(entry_point)) : nullptr); + const void* entry_point = GetQuickOatEntryPoint(sizeof(void*)); + MappingTable table(entry_point != nullptr ? + GetMappingTable(EntryPointToCodePointer(entry_point), sizeof(void*)) : nullptr); if (table.TotalSize() == 0) { DCHECK_EQ(dex_pc, 0U); return 0; // Special no mapping/pc == 0 case diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h index 894c3ce49..0c07448c0 100644 --- a/runtime/mirror/art_method.h +++ b/runtime/mirror/art_method.h @@ -366,18 +366,22 @@ class MANAGED ArtMethod FINAL : public Object { } // Actual entry point pointer to compiled oat code or nullptr. - const void* GetQuickOatEntryPoint() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const void* GetQuickOatEntryPoint(size_t pointer_size) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Actual pointer to compiled oat code or nullptr. - const void* GetQuickOatCodePointer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const void* GetQuickOatCodePointer(size_t pointer_size) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Callers should wrap the uint8_t* in a MappingTable instance for convenient access. - const uint8_t* GetMappingTable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - const uint8_t* GetMappingTable(const void* code_pointer) + const uint8_t* GetMappingTable(size_t pointer_size) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const uint8_t* GetMappingTable(const void* code_pointer, size_t pointer_size) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Callers should wrap the uint8_t* in a VmapTable instance for convenient access. - const uint8_t* GetVmapTable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - const uint8_t* GetVmapTable(const void* code_pointer) + const uint8_t* GetVmapTable(size_t pointer_size) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const uint8_t* GetVmapTable(const void* code_pointer, size_t pointer_size) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); const uint8_t* GetNativeGcMap() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { diff --git a/runtime/stack.cc b/runtime/stack.cc index 2d0060eb6..56bfff7c3 100644 --- a/runtime/stack.cc +++ b/runtime/stack.cc @@ -147,9 +147,9 @@ bool StackVisitor::GetVReg(mirror::ArtMethod* m, uint16_t vreg, VRegKind kind, if (cur_quick_frame_ != nullptr) { DCHECK(context_ != nullptr); // You can't reliably read registers without a context. DCHECK(m == GetMethod()); - const void* code_pointer = m->GetQuickOatCodePointer(); + const void* code_pointer = m->GetQuickOatCodePointer(sizeof(void*)); DCHECK(code_pointer != nullptr); - const VmapTable vmap_table(m->GetVmapTable(code_pointer)); + const VmapTable vmap_table(m->GetVmapTable(code_pointer, sizeof(void*))); QuickMethodFrameInfo frame_info = m->GetQuickFrameInfo(code_pointer); uint32_t vmap_offset; // TODO: IsInContext stops before spotting floating point registers. @@ -201,9 +201,9 @@ bool StackVisitor::GetVRegPair(mirror::ArtMethod* m, uint16_t vreg, VRegKind kin if (cur_quick_frame_ != nullptr) { DCHECK(context_ != nullptr); // You can't reliably read registers without a context. DCHECK(m == GetMethod()); - const void* code_pointer = m->GetQuickOatCodePointer(); + const void* code_pointer = m->GetQuickOatCodePointer(sizeof(void*)); DCHECK(code_pointer != nullptr); - const VmapTable vmap_table(m->GetVmapTable(code_pointer)); + const VmapTable vmap_table(m->GetVmapTable(code_pointer, sizeof(void*))); QuickMethodFrameInfo frame_info = m->GetQuickFrameInfo(code_pointer); uint32_t vmap_offset_lo, vmap_offset_hi; // TODO: IsInContext stops before spotting floating point registers. @@ -248,9 +248,9 @@ bool StackVisitor::SetVReg(mirror::ArtMethod* m, uint16_t vreg, uint32_t new_val if (cur_quick_frame_ != nullptr) { DCHECK(context_ != nullptr); // You can't reliably write registers without a context. DCHECK(m == GetMethod()); - const void* code_pointer = m->GetQuickOatCodePointer(); + const void* code_pointer = m->GetQuickOatCodePointer(sizeof(void*)); DCHECK(code_pointer != nullptr); - const VmapTable vmap_table(m->GetVmapTable(code_pointer)); + const VmapTable vmap_table(m->GetVmapTable(code_pointer, sizeof(void*))); QuickMethodFrameInfo frame_info = m->GetQuickFrameInfo(code_pointer); uint32_t vmap_offset; // TODO: IsInContext stops before spotting floating point registers. @@ -312,9 +312,9 @@ bool StackVisitor::SetVRegPair(mirror::ArtMethod* m, uint16_t vreg, uint64_t new if (cur_quick_frame_ != nullptr) { DCHECK(context_ != nullptr); // You can't reliably write registers without a context. DCHECK(m == GetMethod()); - const void* code_pointer = m->GetQuickOatCodePointer(); + const void* code_pointer = m->GetQuickOatCodePointer(sizeof(void*)); DCHECK(code_pointer != nullptr); - const VmapTable vmap_table(m->GetVmapTable(code_pointer)); + const VmapTable vmap_table(m->GetVmapTable(code_pointer, sizeof(void*))); QuickMethodFrameInfo frame_info = m->GetQuickFrameInfo(code_pointer); uint32_t vmap_offset_lo, vmap_offset_hi; // TODO: IsInContext stops before spotting floating point registers. diff --git a/runtime/thread.cc b/runtime/thread.cc index bc2d5ff1b..74119bb9a 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -2117,12 +2117,12 @@ class ReferenceMapVisitor : public StackVisitor { static_cast(code_item->registers_size_)); if (num_regs > 0) { Runtime* runtime = Runtime::Current(); - const void* entry_point = runtime->GetInstrumentation()->GetQuickCodeFor(m); + const void* entry_point = runtime->GetInstrumentation()->GetQuickCodeFor(m, sizeof(void*)); uintptr_t native_pc_offset = m->NativePcOffset(GetCurrentQuickFramePc(), entry_point); const uint8_t* reg_bitmap = map.FindBitMap(native_pc_offset); DCHECK(reg_bitmap != nullptr); const void* code_pointer = mirror::ArtMethod::EntryPointToCodePointer(entry_point); - const VmapTable vmap_table(m->GetVmapTable(code_pointer)); + const VmapTable vmap_table(m->GetVmapTable(code_pointer, sizeof(void*))); QuickMethodFrameInfo frame_info = m->GetQuickFrameInfo(code_pointer); // For all dex registers in the bitmap StackReference* cur_quick_frame = GetCurrentQuickFrame(); -- 2.11.0