Add DCHECKs to ArenaVector and ScopedArenaVector.
Implement dchecked_vector<> template that DCHECK()s element
access and insert()/emplace()/erase() positions. Change the
ArenaVector<> and ScopedArenaVector<> aliases to use the new
template instead of std::vector<>. Remove DCHECK()s that
have now become unnecessary from the Optimizing compiler.
Change-Id: Ib8506bd30d223f68f52bd4476c76d9991acacadc
diff --git a/compiler/dwarf/debug_frame_opcode_writer.h b/compiler/dwarf/debug_frame_opcode_writer.h
index d8077d5..60241f7 100644
--- a/compiler/dwarf/debug_frame_opcode_writer.h
+++ b/compiler/dwarf/debug_frame_opcode_writer.h
@@ -31,8 +31,10 @@
// * Choose the most compact encoding of a given opcode.
// * Keep track of current state and convert absolute values to deltas.
// * Divide by header-defined factors as appropriate.
-template<typename Allocator = std::allocator<uint8_t> >
-class DebugFrameOpCodeWriter : private Writer<Allocator> {
+template<typename Vector = std::vector<uint8_t> >
+class DebugFrameOpCodeWriter : private Writer<Vector> {
+ static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
+
public:
// To save space, DWARF divides most offsets by header-defined factors.
// They are used in integer divisions, so we make them constants.
@@ -288,11 +290,12 @@
void SetCurrentCFAOffset(int offset) { current_cfa_offset_ = offset; }
- using Writer<Allocator>::data;
+ using Writer<Vector>::data;
DebugFrameOpCodeWriter(bool enabled = true,
- const Allocator& alloc = Allocator())
- : Writer<Allocator>(&opcodes_),
+ const typename Vector::allocator_type& alloc =
+ typename Vector::allocator_type())
+ : Writer<Vector>(&opcodes_),
enabled_(enabled),
opcodes_(alloc),
current_cfa_offset_(0),
@@ -318,7 +321,7 @@
}
bool enabled_; // If disabled all writes are no-ops.
- std::vector<uint8_t, Allocator> opcodes_;
+ Vector opcodes_;
int current_cfa_offset_;
int current_pc_;
bool uses_dwarf3_features_;
diff --git a/compiler/dwarf/debug_info_entry_writer.h b/compiler/dwarf/debug_info_entry_writer.h
index f5b9ca5..d9b367b 100644
--- a/compiler/dwarf/debug_info_entry_writer.h
+++ b/compiler/dwarf/debug_info_entry_writer.h
@@ -29,9 +29,11 @@
// 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 Allocator >
+template <typename Vector>
struct FNVHash {
- size_t operator()(const std::vector<uint8_t, Allocator>& v) const {
+ 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;
@@ -52,8 +54,10 @@
* EndTag();
* EndTag();
*/
-template< typename Allocator = std::allocator<uint8_t> >
-class DebugInfoEntryWriter FINAL : private Writer<Allocator> {
+template <typename Vector = std::vector<uint8_t>>
+class DebugInfoEntryWriter FINAL : private Writer<Vector> {
+ static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
+
public:
// Start debugging information entry.
void StartTag(Tag tag, Children children) {
@@ -176,12 +180,13 @@
return patch_locations_;
}
- using Writer<Allocator>::data;
+ using Writer<Vector>::data;
DebugInfoEntryWriter(bool is64bitArch,
- std::vector<uint8_t, Allocator>* debug_abbrev,
- const Allocator& alloc = Allocator())
- : Writer<Allocator>(&entries_),
+ 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),
@@ -221,7 +226,7 @@
NextAbbrevCode()));
int abbrev_code = it.first->second;
if (UNLIKELY(it.second)) { // Inserted new entry.
- const std::vector<uint8_t, Allocator>& abbrev = it.first->first;
+ 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());
@@ -234,13 +239,13 @@
private:
// Fields for writing and deduplication of abbrevs.
- Writer<Allocator> debug_abbrev_;
- std::vector<uint8_t, Allocator> current_abbrev_;
- std::unordered_map<std::vector<uint8_t, Allocator>, int,
- FNVHash<Allocator> > abbrev_codes_;
+ Writer<Vector> debug_abbrev_;
+ Vector current_abbrev_;
+ std::unordered_map<Vector, int,
+ FNVHash<Vector> > abbrev_codes_;
// Fields for writing of debugging information entries.
- std::vector<uint8_t, Allocator> entries_;
+ Vector entries_;
bool is64bit_;
int depth_ = 0;
size_t abbrev_code_offset_ = 0; // Location to patch once we know the code.
diff --git a/compiler/dwarf/debug_line_opcode_writer.h b/compiler/dwarf/debug_line_opcode_writer.h
index bdc25e4..201f0b4 100644
--- a/compiler/dwarf/debug_line_opcode_writer.h
+++ b/compiler/dwarf/debug_line_opcode_writer.h
@@ -30,8 +30,10 @@
// * Choose the most compact encoding of a given opcode.
// * Keep track of current state and convert absolute values to deltas.
// * Divide by header-defined factors as appropriate.
-template<typename Allocator = std::allocator<uint8_t>>
-class DebugLineOpCodeWriter FINAL : private Writer<Allocator> {
+template<typename Vector = std::vector<uint8_t>>
+class DebugLineOpCodeWriter FINAL : private Writer<Vector> {
+ static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
+
public:
static constexpr int kOpcodeBase = 13;
static constexpr bool kDefaultIsStmt = true;
@@ -212,12 +214,13 @@
return patch_locations_;
}
- using Writer<Allocator>::data;
+ using Writer<Vector>::data;
DebugLineOpCodeWriter(bool use64bitAddress,
int codeFactorBits,
- const Allocator& alloc = Allocator())
- : Writer<Allocator>(&opcodes_),
+ const typename Vector::allocator_type& alloc =
+ typename Vector::allocator_type())
+ : Writer<Vector>(&opcodes_),
opcodes_(alloc),
uses_dwarf3_features_(false),
use_64bit_address_(use64bitAddress),
@@ -234,7 +237,7 @@
return offset >> code_factor_bits_;
}
- std::vector<uint8_t, Allocator> opcodes_;
+ Vector opcodes_;
bool uses_dwarf3_features_;
bool use_64bit_address_;
int code_factor_bits_;
diff --git a/compiler/dwarf/headers.h b/compiler/dwarf/headers.h
index ae57755..b7eff19 100644
--- a/compiler/dwarf/headers.h
+++ b/compiler/dwarf/headers.h
@@ -36,21 +36,23 @@
// In particular, it is not related to machine architecture.
// Write common information entry (CIE) to .debug_frame or .eh_frame section.
-template<typename Allocator>
+template<typename Vector>
void WriteDebugFrameCIE(bool is64bit,
ExceptionHeaderValueApplication address_type,
Reg return_address_register,
- const DebugFrameOpCodeWriter<Allocator>& opcodes,
+ const DebugFrameOpCodeWriter<Vector>& opcodes,
CFIFormat format,
std::vector<uint8_t>* debug_frame) {
+ static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
+
Writer<> writer(debug_frame);
size_t cie_header_start_ = writer.data()->size();
writer.PushUint32(0); // Length placeholder.
writer.PushUint32((format == DW_EH_FRAME_FORMAT) ? 0 : 0xFFFFFFFF); // CIE id.
writer.PushUint8(1); // Version.
writer.PushString("zR");
- writer.PushUleb128(DebugFrameOpCodeWriter<Allocator>::kCodeAlignmentFactor);
- writer.PushSleb128(DebugFrameOpCodeWriter<Allocator>::kDataAlignmentFactor);
+ writer.PushUleb128(DebugFrameOpCodeWriter<Vector>::kCodeAlignmentFactor);
+ writer.PushSleb128(DebugFrameOpCodeWriter<Vector>::kDataAlignmentFactor);
writer.PushUleb128(return_address_register.num()); // ubyte in DWARF2.
writer.PushUleb128(1); // z: Augmentation data size.
if (is64bit) {
@@ -74,13 +76,15 @@
}
// Write frame description entry (FDE) to .debug_frame or .eh_frame section.
-template<typename Allocator>
+template<typename Vector>
void WriteDebugFrameFDE(bool is64bit, size_t cie_offset,
uint64_t initial_address, uint64_t address_range,
- const std::vector<uint8_t, Allocator>* opcodes,
+ const Vector* opcodes,
CFIFormat format,
std::vector<uint8_t>* debug_frame,
std::vector<uintptr_t>* debug_frame_patches) {
+ static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
+
Writer<> writer(debug_frame);
size_t fde_header_start = writer.data()->size();
writer.PushUint32(0); // Length placeholder.
@@ -107,11 +111,13 @@
}
// Write compilation unit (CU) to .debug_info section.
-template<typename Allocator>
+template<typename Vector>
void WriteDebugInfoCU(uint32_t debug_abbrev_offset,
- const DebugInfoEntryWriter<Allocator>& entries,
+ const DebugInfoEntryWriter<Vector>& entries,
std::vector<uint8_t>* debug_info,
std::vector<uintptr_t>* debug_info_patches) {
+ static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
+
Writer<> writer(debug_info);
size_t start = writer.data()->size();
writer.PushUint32(0); // Length placeholder.
@@ -135,12 +141,14 @@
};
// Write line table to .debug_line section.
-template<typename Allocator>
+template<typename Vector>
void WriteDebugLineTable(const std::vector<std::string>& include_directories,
const std::vector<FileEntry>& files,
- const DebugLineOpCodeWriter<Allocator>& opcodes,
+ const DebugLineOpCodeWriter<Vector>& opcodes,
std::vector<uint8_t>* debug_line,
std::vector<uintptr_t>* debug_line_patches) {
+ static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
+
Writer<> writer(debug_line);
size_t header_start = writer.data()->size();
writer.PushUint32(0); // Section-length placeholder.
@@ -151,13 +159,13 @@
size_t header_length_pos = writer.data()->size();
writer.PushUint32(0); // Header-length placeholder.
writer.PushUint8(1 << opcodes.GetCodeFactorBits());
- writer.PushUint8(DebugLineOpCodeWriter<Allocator>::kDefaultIsStmt ? 1 : 0);
- writer.PushInt8(DebugLineOpCodeWriter<Allocator>::kLineBase);
- writer.PushUint8(DebugLineOpCodeWriter<Allocator>::kLineRange);
- writer.PushUint8(DebugLineOpCodeWriter<Allocator>::kOpcodeBase);
- static const int opcode_lengths[DebugLineOpCodeWriter<Allocator>::kOpcodeBase] = {
+ writer.PushUint8(DebugLineOpCodeWriter<Vector>::kDefaultIsStmt ? 1 : 0);
+ writer.PushInt8(DebugLineOpCodeWriter<Vector>::kLineBase);
+ writer.PushUint8(DebugLineOpCodeWriter<Vector>::kLineRange);
+ writer.PushUint8(DebugLineOpCodeWriter<Vector>::kOpcodeBase);
+ static const int opcode_lengths[DebugLineOpCodeWriter<Vector>::kOpcodeBase] = {
0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 };
- for (int i = 1; i < DebugLineOpCodeWriter<Allocator>::kOpcodeBase; i++) {
+ for (int i = 1; i < DebugLineOpCodeWriter<Vector>::kOpcodeBase; i++) {
writer.PushUint8(opcode_lengths[i]);
}
for (const std::string& directory : include_directories) {
diff --git a/compiler/dwarf/writer.h b/compiler/dwarf/writer.h
index e703aee..42c32c4 100644
--- a/compiler/dwarf/writer.h
+++ b/compiler/dwarf/writer.h
@@ -26,8 +26,10 @@
namespace dwarf {
// The base class for all DWARF writers.
-template<typename Allocator = std::allocator<uint8_t>>
+template <typename Vector = std::vector<uint8_t>>
class Writer {
+ static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
+
public:
void PushUint8(int value) {
DCHECK_GE(value, 0);
@@ -116,8 +118,9 @@
data_->insert(data_->end(), p, p + size);
}
- template<typename Allocator2>
- void PushData(const std::vector<uint8_t, Allocator2>* buffer) {
+ template<typename Vector2>
+ void PushData(const Vector2* buffer) {
+ static_assert(std::is_same<typename Vector2::value_type, uint8_t>::value, "Invalid value type");
data_->insert(data_->end(), buffer->begin(), buffer->end());
}
@@ -155,14 +158,14 @@
data_->resize(RoundUp(data_->size(), alignment), 0);
}
- const std::vector<uint8_t, Allocator>* data() const {
+ const Vector* data() const {
return data_;
}
- explicit Writer(std::vector<uint8_t, Allocator>* buffer) : data_(buffer) { }
+ explicit Writer(Vector* buffer) : data_(buffer) { }
private:
- std::vector<uint8_t, Allocator>* data_;
+ Vector* const data_;
DISALLOW_COPY_AND_ASSIGN(Writer);
};