Commit e87c0bac authored by danno's avatar danno Committed by Commit bot

Remove redundant source position information in RelocInfo

Previously, emitting two more more unique source positions at the same pc would
generate two or more RelocInfo entries. Now, only the last emitted source
position for any pc is added to the RelocInfo.

Review URL: https://codereview.chromium.org/908443002

Cr-Commit-Position: refs/heads/master@{#26608}
parent 295ab278
...@@ -492,6 +492,7 @@ Assembler::~Assembler() { ...@@ -492,6 +492,7 @@ Assembler::~Assembler() {
void Assembler::GetCode(CodeDesc* desc) { void Assembler::GetCode(CodeDesc* desc) {
reloc_info_writer.Finish();
if (!FLAG_enable_ool_constant_pool) { if (!FLAG_enable_ool_constant_pool) {
// Emit constant pool if necessary. // Emit constant pool if necessary.
CheckConstPool(true, false); CheckConstPool(true, false);
......
...@@ -590,6 +590,7 @@ void Assembler::Reset() { ...@@ -590,6 +590,7 @@ void Assembler::Reset() {
void Assembler::GetCode(CodeDesc* desc) { void Assembler::GetCode(CodeDesc* desc) {
reloc_info_writer.Finish();
// Emit constant pool if necessary. // Emit constant pool if necessary.
CheckConstPool(true, false); CheckConstPool(true, false);
DCHECK(constpool_.IsEmpty()); DCHECK(constpool_.IsEmpty());
......
...@@ -415,7 +415,38 @@ void RelocInfoWriter::WriteExtraTaggedData(intptr_t data_delta, int top_tag) { ...@@ -415,7 +415,38 @@ void RelocInfoWriter::WriteExtraTaggedData(intptr_t data_delta, int top_tag) {
} }
void RelocInfoWriter::WritePosition(int pc_delta, int pos_delta,
RelocInfo::Mode rmode) {
int pos_type_tag = (rmode == RelocInfo::POSITION) ? kNonstatementPositionTag
: kStatementPositionTag;
// Check if delta is small enough to fit in a tagged byte.
if (is_intn(pos_delta, kSmallDataBits)) {
WriteTaggedPC(pc_delta, kLocatableTag);
WriteTaggedData(pos_delta, pos_type_tag);
} else {
// Otherwise, use costly encoding.
WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
WriteExtraTaggedIntData(pos_delta, pos_type_tag);
}
}
void RelocInfoWriter::FlushPosition() {
if (!next_position_candidate_flushed_) {
WritePosition(next_position_candidate_pc_delta_,
next_position_candidate_pos_delta_, RelocInfo::POSITION);
next_position_candidate_pos_delta_ = 0;
next_position_candidate_pc_delta_ = 0;
next_position_candidate_flushed_ = true;
}
}
void RelocInfoWriter::Write(const RelocInfo* rinfo) { void RelocInfoWriter::Write(const RelocInfo* rinfo) {
RelocInfo::Mode rmode = rinfo->rmode();
if (rmode != RelocInfo::POSITION) {
FlushPosition();
}
#ifdef DEBUG #ifdef DEBUG
byte* begin_pos = pos_; byte* begin_pos = pos_;
#endif #endif
...@@ -425,7 +456,6 @@ void RelocInfoWriter::Write(const RelocInfo* rinfo) { ...@@ -425,7 +456,6 @@ void RelocInfoWriter::Write(const RelocInfo* rinfo) {
<= kMaxStandardNonCompactModes); <= kMaxStandardNonCompactModes);
// Use unsigned delta-encoding for pc. // Use unsigned delta-encoding for pc.
uint32_t pc_delta = static_cast<uint32_t>(rinfo->pc() - last_pc_); uint32_t pc_delta = static_cast<uint32_t>(rinfo->pc() - last_pc_);
RelocInfo::Mode rmode = rinfo->rmode();
// The two most common modes are given small tags, and usually fit in a byte. // The two most common modes are given small tags, and usually fit in a byte.
if (rmode == RelocInfo::EMBEDDED_OBJECT) { if (rmode == RelocInfo::EMBEDDED_OBJECT) {
...@@ -455,16 +485,18 @@ void RelocInfoWriter::Write(const RelocInfo* rinfo) { ...@@ -455,16 +485,18 @@ void RelocInfoWriter::Write(const RelocInfo* rinfo) {
// Use signed delta-encoding for position. // Use signed delta-encoding for position.
DCHECK(static_cast<int>(rinfo->data()) == rinfo->data()); DCHECK(static_cast<int>(rinfo->data()) == rinfo->data());
int pos_delta = static_cast<int>(rinfo->data()) - last_position_; int pos_delta = static_cast<int>(rinfo->data()) - last_position_;
int pos_type_tag = (rmode == RelocInfo::POSITION) ? kNonstatementPositionTag if (rmode == RelocInfo::STATEMENT_POSITION) {
: kStatementPositionTag; WritePosition(pc_delta, pos_delta, rmode);
// Check if delta is small enough to fit in a tagged byte.
if (is_intn(pos_delta, kSmallDataBits)) {
WriteTaggedPC(pc_delta, kLocatableTag);
WriteTaggedData(pos_delta, pos_type_tag);
} else { } else {
// Otherwise, use costly encoding. DCHECK(rmode == RelocInfo::POSITION);
WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag); if (pc_delta != 0 || last_mode_ != RelocInfo::POSITION) {
WriteExtraTaggedIntData(pos_delta, pos_type_tag); FlushPosition();
next_position_candidate_pc_delta_ = pc_delta;
next_position_candidate_pos_delta_ = pos_delta;
} else {
next_position_candidate_pos_delta_ += pos_delta;
}
next_position_candidate_flushed_ = false;
} }
last_position_ = static_cast<int>(rinfo->data()); last_position_ = static_cast<int>(rinfo->data());
} else if (RelocInfo::IsComment(rmode)) { } else if (RelocInfo::IsComment(rmode)) {
...@@ -486,6 +518,7 @@ void RelocInfoWriter::Write(const RelocInfo* rinfo) { ...@@ -486,6 +518,7 @@ void RelocInfoWriter::Write(const RelocInfo* rinfo) {
WriteExtraTaggedPC(pc_delta, saved_mode); WriteExtraTaggedPC(pc_delta, saved_mode);
} }
last_pc_ = rinfo->pc(); last_pc_ = rinfo->pc();
last_mode_ = rmode;
#ifdef DEBUG #ifdef DEBUG
DCHECK(begin_pos - pos_ <= kMaxSize); DCHECK(begin_pos - pos_ <= kMaxSize);
#endif #endif
......
...@@ -647,14 +647,24 @@ class RelocInfo { ...@@ -647,14 +647,24 @@ class RelocInfo {
// lower addresses. // lower addresses.
class RelocInfoWriter BASE_EMBEDDED { class RelocInfoWriter BASE_EMBEDDED {
public: public:
RelocInfoWriter() : pos_(NULL), RelocInfoWriter()
last_pc_(NULL), : pos_(NULL),
last_id_(0), last_pc_(NULL),
last_position_(0) {} last_id_(0),
RelocInfoWriter(byte* pos, byte* pc) : pos_(pos), last_position_(0),
last_pc_(pc), last_mode_(RelocInfo::NUMBER_OF_MODES),
last_id_(0), next_position_candidate_pos_delta_(0),
last_position_(0) {} next_position_candidate_pc_delta_(0),
next_position_candidate_flushed_(true) {}
RelocInfoWriter(byte* pos, byte* pc)
: pos_(pos),
last_pc_(pc),
last_id_(0),
last_position_(0),
last_mode_(RelocInfo::NUMBER_OF_MODES),
next_position_candidate_pos_delta_(0),
next_position_candidate_pc_delta_(0),
next_position_candidate_flushed_(true) {}
byte* pos() const { return pos_; } byte* pos() const { return pos_; }
byte* last_pc() const { return last_pc_; } byte* last_pc() const { return last_pc_; }
...@@ -668,6 +678,8 @@ class RelocInfoWriter BASE_EMBEDDED { ...@@ -668,6 +678,8 @@ class RelocInfoWriter BASE_EMBEDDED {
last_pc_ = pc; last_pc_ = pc;
} }
void Finish() { FlushPosition(); }
// Max size (bytes) of a written RelocInfo. Longest encoding is // Max size (bytes) of a written RelocInfo. Longest encoding is
// ExtraTag, VariableLengthPCJump, ExtraTag, pc_delta, ExtraTag, data_delta. // ExtraTag, VariableLengthPCJump, ExtraTag, pc_delta, ExtraTag, data_delta.
// On ia32 and arm this is 1 + 4 + 1 + 1 + 1 + 4 = 12. // On ia32 and arm this is 1 + 4 + 1 + 1 + 1 + 4 = 12.
...@@ -684,11 +696,19 @@ class RelocInfoWriter BASE_EMBEDDED { ...@@ -684,11 +696,19 @@ class RelocInfoWriter BASE_EMBEDDED {
inline void WriteExtraTaggedData(intptr_t data_delta, int top_tag); inline void WriteExtraTaggedData(intptr_t data_delta, int top_tag);
inline void WriteTaggedData(intptr_t data_delta, int tag); inline void WriteTaggedData(intptr_t data_delta, int tag);
inline void WriteExtraTag(int extra_tag, int top_tag); inline void WriteExtraTag(int extra_tag, int top_tag);
inline void WritePosition(int pc_delta, int pos_delta, RelocInfo::Mode rmode);
void FlushPosition();
byte* pos_; byte* pos_;
byte* last_pc_; byte* last_pc_;
int last_id_; int last_id_;
int last_position_; int last_position_;
RelocInfo::Mode last_mode_;
int next_position_candidate_pos_delta_;
uint32_t next_position_candidate_pc_delta_;
bool next_position_candidate_flushed_;
DISALLOW_COPY_AND_ASSIGN(RelocInfoWriter); DISALLOW_COPY_AND_ASSIGN(RelocInfoWriter);
}; };
......
...@@ -333,6 +333,7 @@ Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) ...@@ -333,6 +333,7 @@ Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
void Assembler::GetCode(CodeDesc* desc) { void Assembler::GetCode(CodeDesc* desc) {
// Finalize code (at this point overflow() may be true, but the gap ensures // Finalize code (at this point overflow() may be true, but the gap ensures
// that we are still not overlapping instructions and relocation info). // that we are still not overlapping instructions and relocation info).
reloc_info_writer.Finish();
DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap. DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
// Set up code descriptor. // Set up code descriptor.
desc->buffer = buffer_; desc->buffer = buffer_;
......
...@@ -248,6 +248,7 @@ Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) ...@@ -248,6 +248,7 @@ Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
void Assembler::GetCode(CodeDesc* desc) { void Assembler::GetCode(CodeDesc* desc) {
reloc_info_writer.Finish();
// Set up code descriptor. // Set up code descriptor.
desc->buffer = buffer_; desc->buffer = buffer_;
desc->buffer_size = buffer_size_; desc->buffer_size = buffer_size_;
......
...@@ -332,6 +332,7 @@ Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) ...@@ -332,6 +332,7 @@ Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
void Assembler::GetCode(CodeDesc* desc) { void Assembler::GetCode(CodeDesc* desc) {
// Finalize code (at this point overflow() may be true, but the gap ensures // Finalize code (at this point overflow() may be true, but the gap ensures
// that we are still not overlapping instructions and relocation info). // that we are still not overlapping instructions and relocation info).
reloc_info_writer.Finish();
DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap. DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
// Set up code descriptor. // Set up code descriptor.
desc->buffer = buffer_; desc->buffer = buffer_;
......
...@@ -256,6 +256,7 @@ Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) ...@@ -256,6 +256,7 @@ Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
void Assembler::GetCode(CodeDesc* desc) { void Assembler::GetCode(CodeDesc* desc) {
// Finalize code (at this point overflow() may be true, but the gap ensures // Finalize code (at this point overflow() may be true, but the gap ensures
// that we are still not overlapping instructions and relocation info). // that we are still not overlapping instructions and relocation info).
reloc_info_writer.Finish();
DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap. DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
// Set up code descriptor. // Set up code descriptor.
desc->buffer = buffer_; desc->buffer = buffer_;
......
...@@ -55,10 +55,16 @@ TEST(Positions) { ...@@ -55,10 +55,16 @@ TEST(Positions) {
for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) { for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) {
RelocInfo::Mode mode = (i % 2 == 0) ? RelocInfo::Mode mode = (i % 2 == 0) ?
RelocInfo::STATEMENT_POSITION : RelocInfo::POSITION; RelocInfo::STATEMENT_POSITION : RelocInfo::POSITION;
if (mode == RelocInfo::STATEMENT_POSITION) {
printf("TEST WRITING STATEMENT %p %d\n", pc, pos);
} else {
printf("TEST WRITING POSITION %p %d\n", pc, pos);
}
WriteRinfo(&writer, pc, mode, pos); WriteRinfo(&writer, pc, mode, pos);
CHECK(writer.pos() - RelocInfoWriter::kMaxSize >= relocation_info_end); CHECK(writer.pos() - RelocInfoWriter::kMaxSize >= relocation_info_end);
} }
writer.Finish();
relocation_info_size = static_cast<int>(buffer_end - writer.pos()); relocation_info_size = static_cast<int>(buffer_end - writer.pos());
CodeDesc desc = { buffer.get(), buffer_size, code_size, CodeDesc desc = { buffer.get(), buffer_size, code_size,
relocation_info_size, NULL }; relocation_info_size, NULL };
...@@ -68,6 +74,7 @@ TEST(Positions) { ...@@ -68,6 +74,7 @@ TEST(Positions) {
RelocIterator it(desc, RelocInfo::ModeMask(RelocInfo::POSITION)); RelocIterator it(desc, RelocInfo::ModeMask(RelocInfo::POSITION));
pc = buffer.get(); pc = buffer.get();
for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) { for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) {
printf("TESTING 1: %d\n", i);
RelocInfo::Mode mode = (i % 2 == 0) ? RelocInfo::Mode mode = (i % 2 == 0) ?
RelocInfo::STATEMENT_POSITION : RelocInfo::POSITION; RelocInfo::STATEMENT_POSITION : RelocInfo::POSITION;
if (mode == RelocInfo::POSITION) { if (mode == RelocInfo::POSITION) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment