Chromium Code Reviews| Index: src/assembler.cc |
| diff --git a/src/assembler.cc b/src/assembler.cc |
| index 3b44efa9c02fd1140a834e9d868c3c6dfa905d7b..27b983a34c2f0a289a284efe8413a247f362038b 100644 |
| --- a/src/assembler.cc |
| +++ b/src/assembler.cc |
| @@ -96,11 +96,14 @@ int Label::pos() const { |
| // |
| // code_taget: [6 bits pc delta] 01 |
|
fschneider
2011/02/11 11:28:18
--> code_target
|
| // |
| +// code_taget_with_id: [6 bits pc delta] 10, |
|
fschneider
2011/02/11 11:28:18
--> code_target
|
| +// [6 bits signed data delta] 00 |
| +// |
| // position: [6 bits pc delta] 10, |
| -// [7 bits signed data delta] 0 |
| +// [6 bits signed data delta] 01 |
| // |
| // statement_position: [6 bits pc delta] 10, |
| -// [7 bits signed data delta] 1 |
| +// [6 bits signed data delta] 10 |
| // |
| // any nondata mode: 00 [4 bits rmode] 11, // rmode: 0..13 only |
| // 00 [6 bits pc delta] |
| @@ -112,13 +115,16 @@ int Label::pos() const { |
| // (variable length) 7 - 26 bit pc delta, written in chunks of 7 |
| // bits, the lowest 7 bits written first. |
| // |
| -// data-jump + pos: 00 1110 11, |
| +// data-jump + c.id: 00 1110 11, |
| +// signed intptr_t, lowest byte written first |
| +// |
| +// data-jump + pos: 01 1110 11, |
| // signed intptr_t, lowest byte written first |
| // |
| -// data-jump + st.pos: 01 1110 11, |
| +// data-jump + st.pos: 10 1110 11, |
| // signed intptr_t, lowest byte written first |
| // |
| -// data-jump + comm.: 10 1110 11, |
| +// data-jump + comm.: 11 1110 11, |
| // signed intptr_t, lowest byte written first |
| // |
| const int kMaxRelocModes = 14; |
| @@ -126,12 +132,12 @@ const int kMaxRelocModes = 14; |
| const int kTagBits = 2; |
| const int kTagMask = (1 << kTagBits) - 1; |
| const int kExtraTagBits = 4; |
| -const int kPositionTypeTagBits = 1; |
| -const int kSmallDataBits = kBitsPerByte - kPositionTypeTagBits; |
| +const int kLocatableTypeTagBits = 2; |
| +const int kSmallDataBits = kBitsPerByte - kLocatableTypeTagBits; |
| const int kEmbeddedObjectTag = 0; |
| const int kCodeTargetTag = 1; |
| -const int kPositionTag = 2; |
| +const int kLocatableTag = 2; |
| const int kDefaultTag = 3; |
| const int kPCJumpTag = (1 << kExtraTagBits) - 1; |
| @@ -149,9 +155,10 @@ const int kLastChunkTag = 1; |
| const int kDataJumpTag = kPCJumpTag - 1; |
| -const int kNonstatementPositionTag = 0; |
| -const int kStatementPositionTag = 1; |
| -const int kCommentTag = 2; |
| +const int kCodeWithIdTag = 0; |
| +const int kNonstatementPositionTag = 1; |
| +const int kStatementPositionTag = 2; |
| +const int kCommentTag = 3; |
| uint32_t RelocInfoWriter::WriteVariableLengthPCJump(uint32_t pc_delta) { |
| @@ -182,7 +189,7 @@ void RelocInfoWriter::WriteTaggedPC(uint32_t pc_delta, int tag) { |
| void RelocInfoWriter::WriteTaggedData(intptr_t data_delta, int tag) { |
| - *--pos_ = static_cast<byte>(data_delta << kPositionTypeTagBits | tag); |
| + *--pos_ = static_cast<byte>(data_delta << kLocatableTypeTagBits | tag); |
| } |
| @@ -201,11 +208,21 @@ void RelocInfoWriter::WriteExtraTaggedPC(uint32_t pc_delta, int extra_tag) { |
| } |
| +void RelocInfoWriter::WriteExtraTaggedIntData(int data_delta, int top_tag) { |
| + WriteExtraTag(kDataJumpTag, top_tag); |
| + for (int i = 0; i < kIntSize; i++) { |
| + *--pos_ = static_cast<byte>(data_delta); |
| + // Signed right shift is arithmetic shift. Tested in test-utils.cc. |
| + data_delta = data_delta >> kBitsPerByte; |
| + } |
| +} |
| + |
| + |
| void RelocInfoWriter::WriteExtraTaggedData(intptr_t data_delta, int top_tag) { |
| WriteExtraTag(kDataJumpTag, top_tag); |
| for (int i = 0; i < kIntptrSize; i++) { |
| *--pos_ = static_cast<byte>(data_delta); |
| - // Signed right shift is arithmetic shift. Tested in test-utils.cc. |
| + // Signed right shift is arithmetic shift. Tested in test-utils.cc. |
| data_delta = data_delta >> kBitsPerByte; |
| } |
| } |
| @@ -217,7 +234,8 @@ void RelocInfoWriter::Write(const RelocInfo* rinfo) { |
| #endif |
| Counters::reloc_info_count.Increment(); |
| ASSERT(rinfo->pc() - last_pc_ >= 0); |
| - ASSERT(RelocInfo::NUMBER_OF_MODES <= kMaxRelocModes); |
| + ASSERT(RelocInfo::NUMBER_OF_MODES - RelocInfo::LAST_CODE_ENUM <= |
| + kMaxRelocModes); |
| // Use unsigned delta-encoding for pc. |
| uint32_t pc_delta = static_cast<uint32_t>(rinfo->pc() - last_pc_); |
| RelocInfo::Mode rmode = rinfo->rmode(); |
| @@ -227,34 +245,47 @@ void RelocInfoWriter::Write(const RelocInfo* rinfo) { |
| WriteTaggedPC(pc_delta, kEmbeddedObjectTag); |
| } else if (rmode == RelocInfo::CODE_TARGET) { |
| WriteTaggedPC(pc_delta, kCodeTargetTag); |
| + } else if (rmode == RelocInfo::CODE_TARGET_WITH_ID) { |
| + // Use signed delta-encoding for id. |
| + ASSERT(static_cast<int>(rinfo->data()) == rinfo->data()); |
| + int id_delta = static_cast<int>(rinfo->data()) - last_id_; |
| + // Check if delta is small enough to fit in a tagged byte. |
| + if (is_intn(id_delta, kSmallDataBits)) { |
| + WriteTaggedPC(pc_delta, kLocatableTag); |
| + WriteTaggedData(id_delta, kCodeWithIdTag); |
| + } else { |
| + // Otherwise, use costly encoding. |
| + WriteExtraTaggedPC(pc_delta, kPCJumpTag); |
| + WriteExtraTaggedIntData(id_delta, kCodeWithIdTag); |
| + } |
| + last_id_ = static_cast<int>(rinfo->data()); |
| } else if (RelocInfo::IsPosition(rmode)) { |
| - // Use signed delta-encoding for data. |
| - intptr_t data_delta = rinfo->data() - last_data_; |
| - int pos_type_tag = rmode == RelocInfo::POSITION ? kNonstatementPositionTag |
| - : kStatementPositionTag; |
| - // Check if data is small enough to fit in a tagged byte. |
| - // We cannot use is_intn because data_delta is not an int32_t. |
| - if (data_delta >= -(1 << (kSmallDataBits-1)) && |
| - data_delta < 1 << (kSmallDataBits-1)) { |
| - WriteTaggedPC(pc_delta, kPositionTag); |
| - WriteTaggedData(data_delta, pos_type_tag); |
| - last_data_ = rinfo->data(); |
| + // Use signed delta-encoding for position. |
| + ASSERT(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); |
| } else { |
| // Otherwise, use costly encoding. |
| WriteExtraTaggedPC(pc_delta, kPCJumpTag); |
| - WriteExtraTaggedData(data_delta, pos_type_tag); |
| - last_data_ = rinfo->data(); |
| + WriteExtraTaggedIntData(pos_delta, pos_type_tag); |
| } |
| + last_position_ = static_cast<int>(rinfo->data()); |
| } else if (RelocInfo::IsComment(rmode)) { |
| // Comments are normally not generated, so we use the costly encoding. |
| WriteExtraTaggedPC(pc_delta, kPCJumpTag); |
| - WriteExtraTaggedData(rinfo->data() - last_data_, kCommentTag); |
| - last_data_ = rinfo->data(); |
| + WriteExtraTaggedData(rinfo->data(), kCommentTag); |
| } else { |
| + ASSERT(rmode > RelocInfo::LAST_COMPACT_ENUM); |
| + int saved_mode = rmode - RelocInfo::LAST_COMPACT_ENUM; |
| // For all other modes we simply use the mode as the extra tag. |
| // None of these modes need a data component. |
| - ASSERT(rmode < kPCJumpTag && rmode < kDataJumpTag); |
| - WriteExtraTaggedPC(pc_delta, rmode); |
| + ASSERT(saved_mode < kPCJumpTag && saved_mode < kDataJumpTag); |
| + WriteExtraTaggedPC(pc_delta, saved_mode); |
| } |
| last_pc_ = rinfo->pc(); |
| #ifdef DEBUG |
| @@ -288,12 +319,32 @@ inline void RelocIterator::AdvanceReadPC() { |
| } |
| +void RelocIterator::AdvanceReadId() { |
| + int x = 0; |
| + for (int i = 0; i < kIntSize; i++) { |
| + x |= static_cast<int>(*--pos_) << i * kBitsPerByte; |
| + } |
| + last_id_ += x; |
| + rinfo_.data_ = last_id_; |
| +} |
| + |
| + |
| +void RelocIterator::AdvanceReadPosition() { |
| + int x = 0; |
| + for (int i = 0; i < kIntSize; i++) { |
| + x |= static_cast<int>(*--pos_) << i * kBitsPerByte; |
| + } |
| + last_position_ += x; |
| + rinfo_.data_ = last_position_; |
| +} |
| + |
| + |
| void RelocIterator::AdvanceReadData() { |
| intptr_t x = 0; |
| for (int i = 0; i < kIntptrSize; i++) { |
| x |= static_cast<intptr_t>(*--pos_) << i * kBitsPerByte; |
| } |
| - rinfo_.data_ += x; |
| + rinfo_.data_ = x; |
| } |
| @@ -313,27 +364,32 @@ void RelocIterator::AdvanceReadVariableLengthPCJump() { |
| } |
| -inline int RelocIterator::GetPositionTypeTag() { |
| - return *pos_ & ((1 << kPositionTypeTagBits) - 1); |
| +inline int RelocIterator::GetLocatableTypeTag() { |
| + return *pos_ & ((1 << kLocatableTypeTagBits) - 1); |
| } |
| -inline void RelocIterator::ReadTaggedData() { |
| +inline void RelocIterator::ReadTaggedId() { |
| int8_t signed_b = *pos_; |
| // Signed right shift is arithmetic shift. Tested in test-utils.cc. |
| - rinfo_.data_ += signed_b >> kPositionTypeTagBits; |
| + last_id_ += signed_b >> kLocatableTypeTagBits; |
| + rinfo_.data_ = last_id_; |
| } |
| -inline RelocInfo::Mode RelocIterator::DebugInfoModeFromTag(int tag) { |
| - if (tag == kStatementPositionTag) { |
| - return RelocInfo::STATEMENT_POSITION; |
| - } else if (tag == kNonstatementPositionTag) { |
| - return RelocInfo::POSITION; |
| - } else { |
| - ASSERT(tag == kCommentTag); |
| - return RelocInfo::COMMENT; |
| - } |
| +inline void RelocIterator::ReadTaggedPosition() { |
| + int8_t signed_b = *pos_; |
| + // Signed right shift is arithmetic shift. Tested in test-utils.cc. |
| + last_position_ += signed_b >> kLocatableTypeTagBits; |
| + rinfo_.data_ = last_position_; |
| +} |
| + |
| + |
| +static inline RelocInfo::Mode GetPositionModeFromTag(int tag) { |
| + ASSERT(tag == kNonstatementPositionTag || |
| + tag == kStatementPositionTag); |
| + return (tag == kNonstatementPositionTag) |
| + ? RelocInfo::POSITION : RelocInfo::STATEMENT_POSITION; |
| } |
| @@ -352,13 +408,24 @@ void RelocIterator::next() { |
| } else if (tag == kCodeTargetTag) { |
| ReadTaggedPC(); |
| if (SetMode(RelocInfo::CODE_TARGET)) return; |
| - } else if (tag == kPositionTag) { |
| + } else if (tag == kLocatableTag) { |
| ReadTaggedPC(); |
| Advance(); |
| - // Check if we want source positions. |
| - if (mode_mask_ & RelocInfo::kPositionMask) { |
| - ReadTaggedData(); |
| - if (SetMode(DebugInfoModeFromTag(GetPositionTypeTag()))) return; |
| + int locatable_tag = GetLocatableTypeTag(); |
| + if (locatable_tag == kCodeWithIdTag) { |
| + if (SetMode(RelocInfo::CODE_TARGET_WITH_ID)) { |
| + ReadTaggedId(); |
| + return; |
| + } |
| + } else { |
| + // Compact encoding is never used for comments, |
| + // so it must be a position. |
| + ASSERT(locatable_tag == kNonstatementPositionTag || |
| + locatable_tag == kStatementPositionTag); |
| + if (mode_mask_ & RelocInfo::kPositionMask) { |
| + ReadTaggedPosition(); |
| + if (SetMode(GetPositionModeFromTag(locatable_tag))) return; |
| + } |
| } |
| } else { |
| ASSERT(tag == kDefaultTag); |
| @@ -371,18 +438,34 @@ void RelocIterator::next() { |
| AdvanceReadPC(); |
| } |
| } else if (extra_tag == kDataJumpTag) { |
| - // Check if we want debug modes (the only ones with data). |
| - if (mode_mask_ & RelocInfo::kDebugMask) { |
| - int top_tag = GetTopTag(); |
| - AdvanceReadData(); |
| - if (SetMode(DebugInfoModeFromTag(top_tag))) return; |
| + int locatable_tag = GetTopTag(); |
| + if (locatable_tag == kCodeWithIdTag) { |
| + if (SetMode(RelocInfo::CODE_TARGET_WITH_ID)) { |
| + AdvanceReadId(); |
| + return; |
| + } |
| + Advance(kIntSize); |
| + } else if (locatable_tag != kCommentTag) { |
| + ASSERT(locatable_tag == kNonstatementPositionTag || |
| + locatable_tag == kStatementPositionTag); |
| + if (mode_mask_ & RelocInfo::kPositionMask) { |
| + AdvanceReadPosition(); |
| + if (SetMode(GetPositionModeFromTag(locatable_tag))) return; |
| + } else { |
| + Advance(kIntSize); |
| + } |
| } else { |
| - // Otherwise, just skip over the data. |
| + ASSERT(locatable_tag == kCommentTag); |
| + if (SetMode(RelocInfo::COMMENT)) { |
| + AdvanceReadData(); |
| + return; |
| + } |
| Advance(kIntptrSize); |
| } |
| } else { |
| AdvanceReadPC(); |
| - if (SetMode(static_cast<RelocInfo::Mode>(extra_tag))) return; |
| + int rmode = extra_tag + RelocInfo::LAST_COMPACT_ENUM; |
| + if (SetMode(static_cast<RelocInfo::Mode>(rmode))) return; |
| } |
| } |
| } |
| @@ -398,6 +481,8 @@ RelocIterator::RelocIterator(Code* code, int mode_mask) { |
| end_ = code->relocation_start(); |
| done_ = false; |
| mode_mask_ = mode_mask; |
| + last_id_ = 0; |
| + last_position_ = 0; |
| if (mode_mask_ == 0) pos_ = end_; |
| next(); |
| } |
| @@ -411,6 +496,8 @@ RelocIterator::RelocIterator(const CodeDesc& desc, int mode_mask) { |
| end_ = pos_ - desc.reloc_size; |
| done_ = false; |
| mode_mask_ = mode_mask; |
| + last_id_ = 0; |
| + last_position_ = 0; |
| if (mode_mask_ == 0) pos_ = end_; |
| next(); |
| } |
| @@ -438,6 +525,8 @@ const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) { |
| return "debug break"; |
| case RelocInfo::CODE_TARGET: |
| return "code target"; |
| + case RelocInfo::CODE_TARGET_WITH_ID: |
| + return "code target with id"; |
| case RelocInfo::GLOBAL_PROPERTY_CELL: |
| return "global property cell"; |
| case RelocInfo::RUNTIME_ENTRY: |
| @@ -483,6 +572,9 @@ void RelocInfo::Print() { |
| } else if (IsCodeTarget(rmode_)) { |
| Code* code = Code::GetCodeFromTargetAddress(target_address()); |
| PrintF(" (%s) (%p)", Code::Kind2String(code->kind()), target_address()); |
| + if (rmode_ == CODE_TARGET_WITH_ID) { |
| + PrintF(" (id=%d)", static_cast<int>(data_)); |
| + } |
| } else if (IsPosition(rmode_)) { |
| PrintF(" (%" V8_PTR_PREFIX "d)", data()); |
| } else if (rmode_ == RelocInfo::RUNTIME_ENTRY) { |
| @@ -515,6 +607,7 @@ void RelocInfo::Verify() { |
| #endif |
| case CONSTRUCT_CALL: |
| case CODE_TARGET_CONTEXT: |
| + case CODE_TARGET_WITH_ID: |
| case CODE_TARGET: { |
| // convert inline target address to code object |
| Address addr = target_address(); |