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