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}
This commit is contained in:
parent
295ab27830
commit
e87c0bac35
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user