Do not deduplicate code if --debuggable is set.
This ensures that the correct method is displayed in backtrace, and it
makes it possible to reliably set native breakpoints in the methods.
I assume this will also be needed for java debugging as soon as the
ArtMethod* is removed from the stackframe.
Change-Id: I289e85461c231fde2d45473bb19aff9ad5fb496d
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index 73d7210..5abd204 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -350,8 +350,9 @@
class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor {
public:
InitCodeMethodVisitor(OatWriter* writer, size_t offset)
- : OatDexMethodVisitor(writer, offset) {
- text_absolute_patch_locations_ = writer->GetAbsolutePatchLocationsFor(".text");
+ : OatDexMethodVisitor(writer, offset),
+ text_absolute_patch_locations_(writer->GetAbsolutePatchLocationsFor(".text")),
+ debuggable_(writer->GetCompilerDriver()->GetCompilerOptions().GetDebuggable()) {
text_absolute_patch_locations_->reserve(
writer_->compiler_driver_->GetNonRelativeLinkerPatchCount());
}
@@ -379,20 +380,19 @@
CHECK_NE(code_size, 0U);
uint32_t thumb_offset = compiled_method->CodeDelta();
- // Deduplicate code arrays.
+ // Deduplicate code arrays if we are not producing debuggable code.
bool deduped = false;
- auto lb = dedupe_map_.lower_bound(compiled_method);
- if (lb != dedupe_map_.end() && !dedupe_map_.key_comp()(compiled_method, lb->first)) {
- quick_code_offset = lb->second;
- deduped = true;
+ if (debuggable_) {
+ quick_code_offset = NewQuickCodeOffset(compiled_method, it, thumb_offset);
} else {
- offset_ = writer_->relative_patcher_->ReserveSpace(
- offset_, compiled_method, MethodReference(dex_file_, it.GetMemberIndex()));
- offset_ = compiled_method->AlignCode(offset_);
- DCHECK_ALIGNED_PARAM(offset_,
- GetInstructionSetAlignment(compiled_method->GetInstructionSet()));
- quick_code_offset = offset_ + sizeof(OatQuickMethodHeader) + thumb_offset;
- dedupe_map_.PutBefore(lb, compiled_method, quick_code_offset);
+ auto lb = dedupe_map_.lower_bound(compiled_method);
+ if (lb != dedupe_map_.end() && !dedupe_map_.key_comp()(compiled_method, lb->first)) {
+ quick_code_offset = lb->second;
+ deduped = true;
+ } else {
+ quick_code_offset = NewQuickCodeOffset(compiled_method, it, thumb_offset);
+ dedupe_map_.PutBefore(lb, compiled_method, quick_code_offset);
+ }
}
MethodReference method_ref(dex_file_, it.GetMemberIndex());
@@ -532,12 +532,26 @@
}
};
+ uint32_t NewQuickCodeOffset(CompiledMethod* compiled_method,
+ const ClassDataItemIterator& it,
+ uint32_t thumb_offset) {
+ offset_ = writer_->relative_patcher_->ReserveSpace(
+ offset_, compiled_method, MethodReference(dex_file_, it.GetMemberIndex()));
+ offset_ = compiled_method->AlignCode(offset_);
+ DCHECK_ALIGNED_PARAM(offset_,
+ GetInstructionSetAlignment(compiled_method->GetInstructionSet()));
+ return offset_ + sizeof(OatQuickMethodHeader) + thumb_offset;
+ }
+
// Deduplication is already done on a pointer basis by the compiler driver,
// so we can simply compare the pointers to find out if things are duplicated.
SafeMap<const CompiledMethod*, uint32_t, CodeOffsetsKeyComparator> dedupe_map_;
// Patch locations for the .text section.
- std::vector<uintptr_t>* text_absolute_patch_locations_;
+ std::vector<uintptr_t>* const text_absolute_patch_locations_;
+
+ // Cache of compiler's --debuggable option.
+ const bool debuggable_;
};
template <typename DataAccess>