| Index: src/assembler.cc
|
| ===================================================================
|
| --- src/assembler.cc (revision 11811)
|
| +++ src/assembler.cc (working copy)
|
| @@ -141,7 +141,7 @@
|
| // an iteration.
|
| //
|
| // The encoding relies on the fact that there are fewer than 14
|
| -// different non-compactly encoded relocation modes.
|
| +// different relocation modes using standard non-compact encoding.
|
| //
|
| // The first byte of a relocation record has a tag in its low 2 bits:
|
| // Here are the record schemes, depending on the low tag and optional higher
|
| @@ -173,7 +173,9 @@
|
| // 00 [4 bit middle_tag] 11 followed by
|
| // 00 [6 bit pc delta]
|
| //
|
| -// 1101: not used (would allow one more relocation mode to be added)
|
| +// 1101: constant pool. Used on ARM only for now.
|
| +// The format is: 11 1101 11
|
| +// signed int (size of the constant pool).
|
| // 1110: long_data_record
|
| // The format is: [2-bit data_type_tag] 1110 11
|
| // signed intptr_t, lowest byte written first
|
| @@ -194,7 +196,7 @@
|
| // dropped, and last non-zero chunk tagged with 1.)
|
|
|
|
|
| -const int kMaxRelocModes = 14;
|
| +const int kMaxStandardNonCompactModes = 14;
|
|
|
| const int kTagBits = 2;
|
| const int kTagMask = (1 << kTagBits) - 1;
|
| @@ -228,7 +230,10 @@
|
| const int kStatementPositionTag = 2;
|
| const int kCommentTag = 3;
|
|
|
| +const int kConstPoolExtraTag = kPCJumpExtraTag - 2;
|
| +const int kConstPoolTag = 3;
|
|
|
| +
|
| uint32_t RelocInfoWriter::WriteVariableLengthPCJump(uint32_t pc_delta) {
|
| // Return if the pc_delta can fit in kSmallPCDeltaBits bits.
|
| // Otherwise write a variable length PC jump for the bits that do
|
| @@ -285,6 +290,15 @@
|
| }
|
| }
|
|
|
| +void RelocInfoWriter::WriteExtraTaggedConstPoolData(int data) {
|
| + WriteExtraTag(kConstPoolExtraTag, kConstPoolTag);
|
| + for (int i = 0; i < kIntSize; i++) {
|
| + *--pos_ = static_cast<byte>(data);
|
| + // Signed right shift is arithmetic shift. Tested in test-utils.cc.
|
| + data = data >> kBitsPerByte;
|
| + }
|
| +}
|
| +
|
| void RelocInfoWriter::WriteExtraTaggedData(intptr_t data_delta, int top_tag) {
|
| WriteExtraTag(kDataJumpExtraTag, top_tag);
|
| for (int i = 0; i < kIntptrSize; i++) {
|
| @@ -300,8 +314,8 @@
|
| byte* begin_pos = pos_;
|
| #endif
|
| ASSERT(rinfo->pc() - last_pc_ >= 0);
|
| - ASSERT(RelocInfo::NUMBER_OF_MODES - RelocInfo::LAST_COMPACT_ENUM <=
|
| - kMaxRelocModes);
|
| + ASSERT(RelocInfo::LAST_STANDARD_NONCOMPACT_ENUM - RelocInfo::LAST_COMPACT_ENUM
|
| + <= kMaxStandardNonCompactModes);
|
| // Use unsigned delta-encoding for pc.
|
| uint32_t pc_delta = static_cast<uint32_t>(rinfo->pc() - last_pc_);
|
| RelocInfo::Mode rmode = rinfo->rmode();
|
| @@ -347,6 +361,9 @@
|
| WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
|
| WriteExtraTaggedData(rinfo->data(), kCommentTag);
|
| ASSERT(begin_pos - pos_ >= RelocInfo::kMinRelocCommentSize);
|
| + } else if (RelocInfo::IsConstPool(rmode)) {
|
| + WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
|
| + WriteExtraTaggedConstPoolData(rinfo->data());
|
| } else {
|
| ASSERT(rmode > RelocInfo::LAST_COMPACT_ENUM);
|
| int saved_mode = rmode - RelocInfo::LAST_COMPACT_ENUM;
|
| @@ -397,6 +414,15 @@
|
| }
|
|
|
|
|
| +void RelocIterator::AdvanceReadConstPoolData() {
|
| + int x = 0;
|
| + for (int i = 0; i < kIntSize; i++) {
|
| + x |= static_cast<int>(*--pos_) << i * kBitsPerByte;
|
| + }
|
| + rinfo_.data_ = x;
|
| +}
|
| +
|
| +
|
| void RelocIterator::AdvanceReadPosition() {
|
| int x = 0;
|
| for (int i = 0; i < kIntSize; i++) {
|
| @@ -500,8 +526,7 @@
|
| ASSERT(tag == kDefaultTag);
|
| int extra_tag = GetExtraTag();
|
| if (extra_tag == kPCJumpExtraTag) {
|
| - int top_tag = GetTopTag();
|
| - if (top_tag == kVariableLengthPCJumpTopTag) {
|
| + if (GetTopTag() == kVariableLengthPCJumpTopTag) {
|
| AdvanceReadVariableLengthPCJump();
|
| } else {
|
| AdvanceReadPC();
|
| @@ -531,6 +556,13 @@
|
| }
|
| Advance(kIntptrSize);
|
| }
|
| + } else if ((extra_tag == kConstPoolExtraTag) &&
|
| + (GetTopTag() == kConstPoolTag)) {
|
| + if (SetMode(RelocInfo::CONST_POOL)) {
|
| + AdvanceReadConstPoolData();
|
| + return;
|
| + }
|
| + Advance(kIntSize);
|
| } else {
|
| AdvanceReadPC();
|
| int rmode = extra_tag + RelocInfo::LAST_COMPACT_ENUM;
|
| @@ -613,6 +645,8 @@
|
| return "external reference";
|
| case RelocInfo::INTERNAL_REFERENCE:
|
| return "internal reference";
|
| + case RelocInfo::CONST_POOL:
|
| + return "constant pool";
|
| case RelocInfo::DEBUG_BREAK_SLOT:
|
| #ifndef ENABLE_DEBUGGER_SUPPORT
|
| UNREACHABLE();
|
| @@ -698,6 +732,7 @@
|
| case STATEMENT_POSITION:
|
| case EXTERNAL_REFERENCE:
|
| case INTERNAL_REFERENCE:
|
| + case CONST_POOL:
|
| case DEBUG_BREAK_SLOT:
|
| case NONE:
|
| break;
|
|
|