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() {
void Assembler::GetCode(CodeDesc* desc) {
reloc_info_writer.Finish();
if (!FLAG_enable_ool_constant_pool) {
// Emit constant pool if necessary.
CheckConstPool(true, false);
......
......@@ -590,6 +590,7 @@ void Assembler::Reset() {
void Assembler::GetCode(CodeDesc* desc) {
reloc_info_writer.Finish();
// Emit constant pool if necessary.
CheckConstPool(true, false);
DCHECK(constpool_.IsEmpty());
......
......@@ -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) {
RelocInfo::Mode rmode = rinfo->rmode();
if (rmode != RelocInfo::POSITION) {
FlushPosition();
}
#ifdef DEBUG
byte* begin_pos = pos_;
#endif
......@@ -425,7 +456,6 @@ void RelocInfoWriter::Write(const RelocInfo* rinfo) {
<= kMaxStandardNonCompactModes);
// Use unsigned delta-encoding for 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.
if (rmode == RelocInfo::EMBEDDED_OBJECT) {
......@@ -455,16 +485,18 @@ void RelocInfoWriter::Write(const RelocInfo* rinfo) {
// Use signed delta-encoding for position.
DCHECK(static_cast<int>(rinfo->data()) == rinfo->data());
int pos_delta = static_cast<int>(rinfo->data()) - last_position_;
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);
if (rmode == RelocInfo::STATEMENT_POSITION) {
WritePosition(pc_delta, pos_delta, rmode);
} else {
// Otherwise, use costly encoding.
WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
WriteExtraTaggedIntData(pos_delta, pos_type_tag);
DCHECK(rmode == RelocInfo::POSITION);
if (pc_delta != 0 || last_mode_ != RelocInfo::POSITION) {
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());
} else if (RelocInfo::IsComment(rmode)) {
......@@ -486,6 +518,7 @@ void RelocInfoWriter::Write(const RelocInfo* rinfo) {
WriteExtraTaggedPC(pc_delta, saved_mode);
}
last_pc_ = rinfo->pc();
last_mode_ = rmode;
#ifdef DEBUG
DCHECK(begin_pos - pos_ <= kMaxSize);
#endif
......
......@@ -647,14 +647,24 @@ class RelocInfo {
// lower addresses.
class RelocInfoWriter BASE_EMBEDDED {
public:
RelocInfoWriter() : pos_(NULL),
last_pc_(NULL),
last_id_(0),
last_position_(0) {}
RelocInfoWriter(byte* pos, byte* pc) : pos_(pos),
last_pc_(pc),
last_id_(0),
last_position_(0) {}
RelocInfoWriter()
: pos_(NULL),
last_pc_(NULL),
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) {}
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* last_pc() const { return last_pc_; }
......@@ -668,6 +678,8 @@ class RelocInfoWriter BASE_EMBEDDED {
last_pc_ = pc;
}
void Finish() { FlushPosition(); }
// Max size (bytes) of a written RelocInfo. Longest encoding is
// ExtraTag, VariableLengthPCJump, ExtraTag, pc_delta, ExtraTag, data_delta.
// On ia32 and arm this is 1 + 4 + 1 + 1 + 1 + 4 = 12.
......@@ -684,11 +696,19 @@ class RelocInfoWriter BASE_EMBEDDED {
inline void WriteExtraTaggedData(intptr_t data_delta, int top_tag);
inline void WriteTaggedData(intptr_t data_delta, int 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* last_pc_;
int last_id_;
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);
};
......
......@@ -333,6 +333,7 @@ Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
void Assembler::GetCode(CodeDesc* desc) {
// Finalize code (at this point overflow() may be true, but the gap ensures
// that we are still not overlapping instructions and relocation info).
reloc_info_writer.Finish();
DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
// Set up code descriptor.
desc->buffer = buffer_;
......
......@@ -248,6 +248,7 @@ Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
void Assembler::GetCode(CodeDesc* desc) {
reloc_info_writer.Finish();
// Set up code descriptor.
desc->buffer = buffer_;
desc->buffer_size = buffer_size_;
......
......@@ -332,6 +332,7 @@ Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
void Assembler::GetCode(CodeDesc* desc) {
// Finalize code (at this point overflow() may be true, but the gap ensures
// that we are still not overlapping instructions and relocation info).
reloc_info_writer.Finish();
DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
// Set up code descriptor.
desc->buffer = buffer_;
......
......@@ -256,6 +256,7 @@ Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
void Assembler::GetCode(CodeDesc* desc) {
// Finalize code (at this point overflow() may be true, but the gap ensures
// that we are still not overlapping instructions and relocation info).
reloc_info_writer.Finish();
DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
// Set up code descriptor.
desc->buffer = buffer_;
......
......@@ -55,10 +55,16 @@ TEST(Positions) {
for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) {
RelocInfo::Mode mode = (i % 2 == 0) ?
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);
CHECK(writer.pos() - RelocInfoWriter::kMaxSize >= relocation_info_end);
}
writer.Finish();
relocation_info_size = static_cast<int>(buffer_end - writer.pos());
CodeDesc desc = { buffer.get(), buffer_size, code_size,
relocation_info_size, NULL };
......@@ -68,6 +74,7 @@ TEST(Positions) {
RelocIterator it(desc, RelocInfo::ModeMask(RelocInfo::POSITION));
pc = buffer.get();
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::STATEMENT_POSITION : 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