Index: src/assembler.cc |
diff --git a/src/assembler.cc b/src/assembler.cc |
index 4c5eda198106e5c9ef9bac136788e5188dad9b84..56578ca563b4b027b4ce9227f1f7f4a09445fde6 100644 |
--- a/src/assembler.cc |
+++ b/src/assembler.cc |
@@ -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 |