Share DWARF .debug_abbrev sections.
Restructure the code so that all compilation units share the same
.debug_abbrev sections. This deduplicates many of the abbrevs.
Change-Id: I7da07a8c850871786df52674183c16d574684729
diff --git a/compiler/dwarf/debug_info_entry_writer.h b/compiler/dwarf/debug_info_entry_writer.h
index 5e3d2c8..1e29859 100644
--- a/compiler/dwarf/debug_info_entry_writer.h
+++ b/compiler/dwarf/debug_info_entry_writer.h
@@ -21,6 +21,7 @@
#include <unordered_map>
#include "base/casts.h"
+#include "dwarf/debug_abbrev_writer.h"
#include "dwarf/dwarf_constants.h"
#include "dwarf/expression.h"
#include "dwarf/writer.h"
@@ -29,24 +30,8 @@
namespace art {
namespace dwarf {
-// 32-bit FNV-1a hash function which we use to find duplicate abbreviations.
-// See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
-template <typename Vector>
-struct FNVHash {
- static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
-
- size_t operator()(const Vector& v) const {
- uint32_t hash = 2166136261u;
- for (size_t i = 0; i < v.size(); i++) {
- hash = (hash ^ v[i]) * 16777619u;
- }
- return hash;
- }
-};
-
/*
* Writer for debug information entries (DIE).
- * It also handles generation of abbreviations.
*
* Usage:
* StartTag(DW_TAG_compile_unit);
@@ -69,13 +54,13 @@
if (inside_entry_) {
// Write abbrev code for the previous entry.
// Parent entry is finalized before any children are written.
- this->UpdateUleb128(abbrev_code_offset_, EndAbbrev(DW_CHILDREN_yes));
+ this->UpdateUleb128(abbrev_code_offset_, debug_abbrev_->EndAbbrev(DW_CHILDREN_yes));
inside_entry_ = false;
}
- StartAbbrev(tag);
+ debug_abbrev_->StartAbbrev(tag);
// Abbrev code placeholder of sufficient size.
abbrev_code_offset_ = this->data()->size();
- this->PushUleb128(NextAbbrevCode());
+ this->PushUleb128(debug_abbrev_->NextAbbrevCode());
depth_++;
inside_entry_ = true;
return abbrev_code_offset_ + kCompilationUnitHeaderSize;
@@ -86,7 +71,7 @@
DCHECK_GT(depth_, 0);
if (inside_entry_) {
// Write abbrev code for this entry.
- this->UpdateUleb128(abbrev_code_offset_, EndAbbrev(DW_CHILDREN_no));
+ this->UpdateUleb128(abbrev_code_offset_, debug_abbrev_->EndAbbrev(DW_CHILDREN_no));
inside_entry_ = false;
// This entry has no children and so there is no terminator.
} else {
@@ -98,7 +83,7 @@
}
void WriteAddr(Attribute attrib, uint64_t value) {
- AddAbbrevAttribute(attrib, DW_FORM_addr);
+ debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_addr);
patch_locations_.push_back(this->data()->size());
if (is64bit_) {
this->PushUint64(value);
@@ -108,89 +93,89 @@
}
void WriteBlock(Attribute attrib, const uint8_t* ptr, size_t num_bytes) {
- AddAbbrevAttribute(attrib, DW_FORM_block);
+ debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_block);
this->PushUleb128(num_bytes);
this->PushData(ptr, num_bytes);
}
void WriteExprLoc(Attribute attrib, const Expression& expr) {
- AddAbbrevAttribute(attrib, DW_FORM_exprloc);
+ debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_exprloc);
this->PushUleb128(dchecked_integral_cast<uint32_t>(expr.size()));
this->PushData(expr.data());
}
void WriteData1(Attribute attrib, uint8_t value) {
- AddAbbrevAttribute(attrib, DW_FORM_data1);
+ debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_data1);
this->PushUint8(value);
}
void WriteData2(Attribute attrib, uint16_t value) {
- AddAbbrevAttribute(attrib, DW_FORM_data2);
+ debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_data2);
this->PushUint16(value);
}
void WriteData4(Attribute attrib, uint32_t value) {
- AddAbbrevAttribute(attrib, DW_FORM_data4);
+ debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_data4);
this->PushUint32(value);
}
void WriteData8(Attribute attrib, uint64_t value) {
- AddAbbrevAttribute(attrib, DW_FORM_data8);
+ debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_data8);
this->PushUint64(value);
}
void WriteSecOffset(Attribute attrib, uint32_t offset) {
- AddAbbrevAttribute(attrib, DW_FORM_sec_offset);
+ debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_sec_offset);
this->PushUint32(offset);
}
void WriteSdata(Attribute attrib, int value) {
- AddAbbrevAttribute(attrib, DW_FORM_sdata);
+ debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_sdata);
this->PushSleb128(value);
}
void WriteUdata(Attribute attrib, int value) {
- AddAbbrevAttribute(attrib, DW_FORM_udata);
+ debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_udata);
this->PushUleb128(value);
}
void WriteUdata(Attribute attrib, uint32_t value) {
- AddAbbrevAttribute(attrib, DW_FORM_udata);
+ debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_udata);
this->PushUleb128(value);
}
void WriteFlag(Attribute attrib, bool value) {
- AddAbbrevAttribute(attrib, DW_FORM_flag);
+ debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_flag);
this->PushUint8(value ? 1 : 0);
}
void WriteFlagPresent(Attribute attrib) {
- AddAbbrevAttribute(attrib, DW_FORM_flag_present);
+ debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_flag_present);
}
void WriteRef4(Attribute attrib, uint32_t cu_offset) {
- AddAbbrevAttribute(attrib, DW_FORM_ref4);
+ debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_ref4);
this->PushUint32(cu_offset);
}
void WriteRef(Attribute attrib, uint32_t cu_offset) {
- AddAbbrevAttribute(attrib, DW_FORM_ref_udata);
+ debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_ref_udata);
this->PushUleb128(cu_offset);
}
void WriteString(Attribute attrib, const char* value) {
- AddAbbrevAttribute(attrib, DW_FORM_string);
+ debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_string);
this->PushString(value);
}
void WriteStrp(Attribute attrib, size_t debug_str_offset) {
- AddAbbrevAttribute(attrib, DW_FORM_strp);
+ debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_strp);
this->PushUint32(dchecked_integral_cast<uint32_t>(debug_str_offset));
}
void WriteStrp(Attribute attrib, const char* str, size_t len,
std::vector<uint8_t>* debug_str) {
- AddAbbrevAttribute(attrib, DW_FORM_strp);
+ debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_strp);
this->PushUint32(debug_str->size());
debug_str->insert(debug_str->end(), str, str + len);
debug_str->push_back(0);
@@ -213,16 +198,13 @@
using Writer<Vector>::UpdateUint32;
DebugInfoEntryWriter(bool is64bitArch,
- Vector* debug_abbrev,
+ DebugAbbrevWriter<Vector>* debug_abbrev,
const typename Vector::allocator_type& alloc =
typename Vector::allocator_type())
: Writer<Vector>(&entries_),
debug_abbrev_(debug_abbrev),
- current_abbrev_(alloc),
- abbrev_codes_(alloc),
entries_(alloc),
is64bit_(is64bitArch) {
- debug_abbrev_.PushUint8(0); // Add abbrev table terminator.
}
~DebugInfoEntryWriter() {
@@ -231,53 +213,7 @@
}
private:
- // Start abbreviation declaration.
- void StartAbbrev(Tag tag) {
- current_abbrev_.clear();
- EncodeUnsignedLeb128(¤t_abbrev_, tag);
- has_children_offset_ = current_abbrev_.size();
- current_abbrev_.push_back(0); // Place-holder for DW_CHILDREN.
- }
-
- // Add attribute specification.
- void AddAbbrevAttribute(Attribute name, Form type) {
- DCHECK(inside_entry_) << "Call StartTag before adding attributes.";
- EncodeUnsignedLeb128(¤t_abbrev_, name);
- EncodeUnsignedLeb128(¤t_abbrev_, type);
- }
-
- int NextAbbrevCode() {
- return 1 + abbrev_codes_.size();
- }
-
- // End abbreviation declaration and return its code.
- int EndAbbrev(Children has_children) {
- DCHECK(!current_abbrev_.empty());
- current_abbrev_[has_children_offset_] = has_children;
- auto it = abbrev_codes_.insert(std::make_pair(std::move(current_abbrev_),
- NextAbbrevCode()));
- int abbrev_code = it.first->second;
- if (UNLIKELY(it.second)) { // Inserted new entry.
- const Vector& abbrev = it.first->first;
- debug_abbrev_.Pop(); // Remove abbrev table terminator.
- debug_abbrev_.PushUleb128(abbrev_code);
- debug_abbrev_.PushData(abbrev.data(), abbrev.size());
- debug_abbrev_.PushUint8(0); // Attribute list end.
- debug_abbrev_.PushUint8(0); // Attribute list end.
- debug_abbrev_.PushUint8(0); // Add abbrev table terminator.
- }
- return abbrev_code;
- }
-
- private:
- // Fields for writing and deduplication of abbrevs.
- Writer<Vector> debug_abbrev_;
- Vector current_abbrev_;
- size_t has_children_offset_ = 0;
- std::unordered_map<Vector, int,
- FNVHash<Vector> > abbrev_codes_;
-
- // Fields for writing of debugging information entries.
+ DebugAbbrevWriter<Vector>* debug_abbrev_;
Vector entries_;
bool is64bit_;
int depth_ = 0;