| 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
|
|
|