// 10: short_data_record: [6-bit pc delta] 10 followed by
// [6-bit data delta] [2-bit data type tag]
//
-// 11: long_record [2-bit high tag][4 bit middle_tag] 11
-// followed by variable data depending on type.
+// 11: long_record [6 bit reloc mode] 11
+// followed by pc delta
+// followed by optional data depending on type.
//
// 2-bit data type tags, used in short_data_record and data_jump long_record:
// code_target_with_id: 00
// position: 01
// statement_position: 10
-// comment: 11 (not used in short_data_record)
-// deopt_reason: 11 (not used in long_data_record)
+// deopt_reason: 11
//
-// Long record format:
-// 4-bit middle_tag:
-// 0000 - 1100 : Short record for RelocInfo::Mode middle_tag + 2
-// (The middle_tag encodes rmode - RelocInfo::LAST_COMPACT_ENUM,
-// and is between 0000 and 1100)
-// The format is:
-// 00 [4 bit middle_tag] 11 followed by
-// 00 [6 bit pc delta]
-//
-// 1101: constant or veneer pool. Used only on ARM and ARM64 for now.
-// The format is: [2-bit sub-type] 1101 11
-// signed int (size of the pool).
-// The 2-bit sub-types are:
-// 00: constant pool
-// 01: veneer pool
-// 1110: long_data_record
-// The format is: [2-bit data_type_tag] 1110 11
-// signed intptr_t, lowest byte written first
-// (except data_type code_target_with_id, which
-// is followed by a signed int, not intptr_t.)
-//
-// 1111: long_pc_jump
-// The format is:
-// pc-jump: 00 1111 11,
-// 00 [6 bits pc delta]
-// or
-// pc-jump (variable length):
-// 01 1111 11,
+// If a pc delta exceeds 6 bits, it is split into a remainder that fits into
+// 6 bits and a part that does not. The latter is encoded as a long record
+// with PC_JUMP as pseudo reloc info mode. The former is encoded as part of
+// the following record in the usual way. The long pc jump record has variable
+// length:
+// pc-jump: [PC_JUMP] 11
// [7 bits data] 0
// ...
// [7 bits data] 1
const int kTagBits = 2;
const int kTagMask = (1 << kTagBits) - 1;
-const int kExtraTagBits = 4;
-const int kLocatableTypeTagBits = 2;
-const int kSmallDataBits = kBitsPerByte - kLocatableTypeTagBits;
+const int kLongTagBits = 6;
+const int kShortDataTypeTagBits = 2;
+const int kShortDataBits = kBitsPerByte - kShortDataTypeTagBits;
const int kEmbeddedObjectTag = 0;
const int kCodeTargetTag = 1;
const int kLocatableTag = 2;
const int kDefaultTag = 3;
-const int kPCJumpExtraTag = (1 << kExtraTagBits) - 1;
-
const int kSmallPCDeltaBits = kBitsPerByte - kTagBits;
const int kSmallPCDeltaMask = (1 << kSmallPCDeltaBits) - 1;
const int RelocInfo::kMaxSmallPCDelta = kSmallPCDeltaMask;
-const int kVariableLengthPCJumpTopTag = 1;
const int kChunkBits = 7;
const int kChunkMask = (1 << kChunkBits) - 1;
const int kLastChunkTagBits = 1;
const int kLastChunkTagMask = 1;
const int kLastChunkTag = 1;
-
-const int kDataJumpExtraTag = kPCJumpExtraTag - 1;
-
const int kCodeWithIdTag = 0;
const int kNonstatementPositionTag = 1;
const int kStatementPositionTag = 2;
-const int kCommentTag = 3;
-
-// Reuse the same value for deopt reason tag in short record format.
-// It is possible because we use kCommentTag only for the long record format.
const int kDeoptReasonTag = 3;
-const int kPoolExtraTag = kPCJumpExtraTag - 2;
-const int kConstPoolTag = 0;
-const int kVeneerPoolTag = 1;
-
-uint32_t RelocInfoWriter::WriteVariableLengthPCJump(uint32_t pc_delta) {
+uint32_t RelocInfoWriter::WriteLongPCJump(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
// not fit in the kSmallPCDeltaBits bits.
if (is_uintn(pc_delta, kSmallPCDeltaBits)) return pc_delta;
- WriteExtraTag(kPCJumpExtraTag, kVariableLengthPCJumpTopTag);
+ WriteMode(RelocInfo::PC_JUMP);
uint32_t pc_jump = pc_delta >> kSmallPCDeltaBits;
DCHECK(pc_jump > 0);
// Write kChunkBits size chunks of the pc_jump.
}
-void RelocInfoWriter::WriteTaggedPC(uint32_t pc_delta, int tag) {
- // Write a byte of tagged pc-delta, possibly preceded by var. length pc-jump.
- pc_delta = WriteVariableLengthPCJump(pc_delta);
+void RelocInfoWriter::WriteShortTaggedPC(uint32_t pc_delta, int tag) {
+ // Write a byte of tagged pc-delta, possibly preceded by an explicit pc-jump.
+ pc_delta = WriteLongPCJump(pc_delta);
*--pos_ = pc_delta << kTagBits | tag;
}
-void RelocInfoWriter::WriteTaggedData(intptr_t data_delta, int tag) {
- *--pos_ = static_cast<byte>(data_delta << kLocatableTypeTagBits | tag);
+void RelocInfoWriter::WriteShortTaggedData(intptr_t data_delta, int tag) {
+ *--pos_ = static_cast<byte>(data_delta << kShortDataTypeTagBits | tag);
}
-void RelocInfoWriter::WriteExtraTag(int extra_tag, int top_tag) {
- *--pos_ = static_cast<int>(top_tag << (kTagBits + kExtraTagBits) |
- extra_tag << kTagBits |
- kDefaultTag);
+void RelocInfoWriter::WriteMode(RelocInfo::Mode rmode) {
+ STATIC_ASSERT(RelocInfo::NUMBER_OF_MODES <= (1 << kLongTagBits));
+ *--pos_ = static_cast<int>((rmode << kTagBits) | kDefaultTag);
}
-void RelocInfoWriter::WriteExtraTaggedPC(uint32_t pc_delta, int extra_tag) {
+void RelocInfoWriter::WriteModeAndPC(uint32_t pc_delta, RelocInfo::Mode rmode) {
// Write two-byte tagged pc-delta, possibly preceded by var. length pc-jump.
- pc_delta = WriteVariableLengthPCJump(pc_delta);
- WriteExtraTag(extra_tag, 0);
+ pc_delta = WriteLongPCJump(pc_delta);
+ WriteMode(rmode);
*--pos_ = pc_delta;
}
-void RelocInfoWriter::WriteInt(int number) {
+void RelocInfoWriter::WriteIntData(int number) {
for (int i = 0; i < kIntSize; i++) {
*--pos_ = static_cast<byte>(number);
// Signed right shift is arithmetic shift. Tested in test-utils.cc.
}
-void RelocInfoWriter::WriteDebugBreakSlotData(int data) { WriteInt(data); }
-
-
-void RelocInfoWriter::WriteExtraTaggedIntData(int data_delta, int top_tag) {
- WriteExtraTag(kDataJumpExtraTag, top_tag);
- WriteInt(data_delta);
-}
-
-
-void RelocInfoWriter::WriteExtraTaggedPoolData(int data, int pool_type) {
- WriteExtraTag(kPoolExtraTag, pool_type);
- WriteInt(data);
-}
-
-
-void RelocInfoWriter::WriteExtraTaggedData(intptr_t data_delta, int top_tag) {
- WriteExtraTag(kDataJumpExtraTag, top_tag);
+void RelocInfoWriter::WriteData(intptr_t data_delta) {
for (int i = 0; i < kIntptrSize; i++) {
*--pos_ = static_cast<byte>(data_delta);
// Signed right shift is arithmetic shift. Tested in test-utils.cc.
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 (is_intn(pos_delta, kShortDataBits)) {
+ WriteShortTaggedPC(pc_delta, kLocatableTag);
+ WriteShortTaggedData(pos_delta, pos_type_tag);
} else {
// Otherwise, use costly encoding.
- WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
- WriteExtraTaggedIntData(pos_delta, pos_type_tag);
+ WriteModeAndPC(pc_delta, rmode);
+ WriteIntData(pos_delta);
}
}
// The two most common modes are given small tags, and usually fit in a byte.
if (rmode == RelocInfo::EMBEDDED_OBJECT) {
- WriteTaggedPC(pc_delta, kEmbeddedObjectTag);
+ WriteShortTaggedPC(pc_delta, kEmbeddedObjectTag);
} else if (rmode == RelocInfo::CODE_TARGET) {
- WriteTaggedPC(pc_delta, kCodeTargetTag);
+ WriteShortTaggedPC(pc_delta, kCodeTargetTag);
DCHECK(begin_pos - pos_ <= RelocInfo::kMaxCallSize);
} else if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
// Use signed delta-encoding for id.
DCHECK_EQ(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);
+ if (is_intn(id_delta, kShortDataBits)) {
+ WriteShortTaggedPC(pc_delta, kLocatableTag);
+ WriteShortTaggedData(id_delta, kCodeWithIdTag);
} else {
// Otherwise, use costly encoding.
- WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
- WriteExtraTaggedIntData(id_delta, kCodeWithIdTag);
+ WriteModeAndPC(pc_delta, rmode);
+ WriteIntData(id_delta);
}
last_id_ = static_cast<int>(rinfo->data());
} else if (rmode == RelocInfo::DEOPT_REASON) {
- DCHECK(rinfo->data() < (1 << kSmallDataBits));
- WriteTaggedPC(pc_delta, kLocatableTag);
- WriteTaggedData(rinfo->data(), kDeoptReasonTag);
+ DCHECK(rinfo->data() < (1 << kShortDataBits));
+ WriteShortTaggedPC(pc_delta, kLocatableTag);
+ WriteShortTaggedData(rinfo->data(), kDeoptReasonTag);
} else if (RelocInfo::IsPosition(rmode)) {
// Use signed delta-encoding for position.
DCHECK_EQ(static_cast<int>(rinfo->data()), rinfo->data());
next_position_candidate_flushed_ = false;
}
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, kPCJumpExtraTag);
- WriteExtraTaggedData(rinfo->data(), kCommentTag);
- DCHECK(begin_pos - pos_ >= RelocInfo::kMinRelocCommentSize);
- } else if (RelocInfo::IsConstPool(rmode) || RelocInfo::IsVeneerPool(rmode)) {
- WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
- WriteExtraTaggedPoolData(
- static_cast<int>(rinfo->data()),
- RelocInfo::IsConstPool(rmode) ? kConstPoolTag : kVeneerPoolTag);
} else {
- DCHECK(rmode > RelocInfo::LAST_COMPACT_ENUM);
- DCHECK(rmode <= RelocInfo::LAST_STANDARD_NONCOMPACT_ENUM);
- STATIC_ASSERT(RelocInfo::LAST_STANDARD_NONCOMPACT_ENUM -
- RelocInfo::LAST_COMPACT_ENUM <=
- kPoolExtraTag);
- int saved_mode = rmode - RelocInfo::LAST_COMPACT_ENUM - 1;
- // For all other modes we simply use the mode as the extra tag.
- // None of these modes need a data component.
- DCHECK(0 <= saved_mode && saved_mode < kPoolExtraTag);
- WriteExtraTaggedPC(pc_delta, saved_mode);
- if (RelocInfo::IsDebugBreakSlot(rmode)) {
- WriteDebugBreakSlotData(static_cast<int>(rinfo->data()));
+ WriteModeAndPC(pc_delta, rmode);
+ if (RelocInfo::IsComment(rmode)) {
+ WriteData(rinfo->data());
+ } else if (RelocInfo::IsConstPool(rmode) ||
+ RelocInfo::IsVeneerPool(rmode) ||
+ RelocInfo::IsDebugBreakSlot(rmode)) {
+ WriteIntData(static_cast<int>(rinfo->data()));
}
}
last_pc_ = rinfo->pc();
}
-inline int RelocIterator::GetExtraTag() {
- return (*pos_ >> kTagBits) & ((1 << kExtraTagBits) - 1);
+inline RelocInfo::Mode RelocIterator::GetMode() {
+ return static_cast<RelocInfo::Mode>((*pos_ >> kTagBits) &
+ ((1 << kLongTagBits) - 1));
}
-inline int RelocIterator::GetTopTag() {
- return *pos_ >> (kTagBits + kExtraTagBits);
-}
-
-
-inline void RelocIterator::ReadTaggedPC() {
+inline void RelocIterator::ReadShortTaggedPC() {
rinfo_.pc_ += *pos_ >> kTagBits;
}
}
-void RelocIterator::AdvanceReadPoolData() { AdvanceReadInt(); }
-
-
-void RelocIterator::AdvanceReadDebugBreakSlotData() { AdvanceReadInt(); }
-
-
void RelocIterator::AdvanceReadPosition() {
int x = 0;
for (int i = 0; i < kIntSize; i++) {
}
-void RelocIterator::AdvanceReadVariableLengthPCJump() {
+void RelocIterator::AdvanceReadLongPCJump() {
// Read the 32-kSmallPCDeltaBits most significant bits of the
// pc jump in kChunkBits bit chunks and shift them into place.
// Stop when the last chunk is encountered.
}
-inline int RelocIterator::GetLocatableTypeTag() {
- return *pos_ & ((1 << kLocatableTypeTagBits) - 1);
+inline int RelocIterator::GetShortDataTypeTag() {
+ return *pos_ & ((1 << kShortDataTypeTagBits) - 1);
}
-inline void RelocIterator::ReadTaggedId() {
+inline void RelocIterator::ReadShortTaggedId() {
int8_t signed_b = *pos_;
// Signed right shift is arithmetic shift. Tested in test-utils.cc.
- last_id_ += signed_b >> kLocatableTypeTagBits;
+ last_id_ += signed_b >> kShortDataTypeTagBits;
rinfo_.data_ = last_id_;
}
-inline void RelocIterator::ReadTaggedPosition() {
+inline void RelocIterator::ReadShortTaggedPosition() {
int8_t signed_b = *pos_;
// Signed right shift is arithmetic shift. Tested in test-utils.cc.
- last_position_ += signed_b >> kLocatableTypeTagBits;
+ last_position_ += signed_b >> kShortDataTypeTagBits;
rinfo_.data_ = last_position_;
}
-inline void RelocIterator::ReadTaggedData() {
+inline void RelocIterator::ReadShortTaggedData() {
uint8_t unsigned_b = *pos_;
rinfo_.data_ = unsigned_b >> kTagBits;
}
while (pos_ > end_) {
int tag = AdvanceGetTag();
if (tag == kEmbeddedObjectTag) {
- ReadTaggedPC();
+ ReadShortTaggedPC();
if (SetMode(RelocInfo::EMBEDDED_OBJECT)) return;
} else if (tag == kCodeTargetTag) {
- ReadTaggedPC();
+ ReadShortTaggedPC();
if (SetMode(RelocInfo::CODE_TARGET)) return;
} else if (tag == kLocatableTag) {
- ReadTaggedPC();
+ ReadShortTaggedPC();
Advance();
- int locatable_tag = GetLocatableTypeTag();
- if (locatable_tag == kCodeWithIdTag) {
+ int data_type_tag = GetShortDataTypeTag();
+ if (data_type_tag == kCodeWithIdTag) {
if (SetMode(RelocInfo::CODE_TARGET_WITH_ID)) {
- ReadTaggedId();
+ ReadShortTaggedId();
+ return;
+ }
+ } else if (data_type_tag == kDeoptReasonTag) {
+ if (SetMode(RelocInfo::DEOPT_REASON)) {
+ ReadShortTaggedData();
return;
}
- } else if (locatable_tag == kDeoptReasonTag) {
- ReadTaggedData();
- if (SetMode(RelocInfo::DEOPT_REASON)) return;
} else {
- DCHECK(locatable_tag == kNonstatementPositionTag ||
- locatable_tag == kStatementPositionTag);
+ DCHECK(data_type_tag == kNonstatementPositionTag ||
+ data_type_tag == kStatementPositionTag);
if (mode_mask_ & RelocInfo::kPositionMask) {
- ReadTaggedPosition();
- if (SetMode(GetPositionModeFromTag(locatable_tag))) return;
+ // Always update the position if we are interested in either
+ // statement positions or non-statement positions.
+ ReadShortTaggedPosition();
+ if (SetMode(GetPositionModeFromTag(data_type_tag))) return;
}
}
} else {
DCHECK(tag == kDefaultTag);
- int extra_tag = GetExtraTag();
- if (extra_tag == kPCJumpExtraTag) {
- if (GetTopTag() == kVariableLengthPCJumpTopTag) {
- AdvanceReadVariableLengthPCJump();
- } else {
- AdvanceReadPC();
- }
- } else if (extra_tag == kDataJumpExtraTag) {
- int locatable_tag = GetTopTag();
- if (locatable_tag == kCodeWithIdTag) {
- if (SetMode(RelocInfo::CODE_TARGET_WITH_ID)) {
+ RelocInfo::Mode rmode = GetMode();
+ if (rmode == RelocInfo::PC_JUMP) {
+ AdvanceReadLongPCJump();
+ } else {
+ AdvanceReadPC();
+ if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
+ if (SetMode(rmode)) {
AdvanceReadId();
return;
}
Advance(kIntSize);
- } else if (locatable_tag != kCommentTag) {
- DCHECK(locatable_tag == kNonstatementPositionTag ||
- locatable_tag == kStatementPositionTag);
+ } else if (RelocInfo::IsComment(rmode)) {
+ if (SetMode(rmode)) {
+ AdvanceReadData();
+ return;
+ }
+ Advance(kIntptrSize);
+ } else if (RelocInfo::IsPosition(rmode)) {
if (mode_mask_ & RelocInfo::kPositionMask) {
+ // Always update the position if we are interested in either
+ // statement positions or non-statement positions.
AdvanceReadPosition();
- if (SetMode(GetPositionModeFromTag(locatable_tag))) return;
+ if (SetMode(rmode)) return;
} else {
Advance(kIntSize);
}
- } else {
- DCHECK(locatable_tag == kCommentTag);
- if (SetMode(RelocInfo::COMMENT)) {
- AdvanceReadData();
- return;
- }
- Advance(kIntptrSize);
- }
- } else if (extra_tag == kPoolExtraTag) {
- int pool_type = GetTopTag();
- DCHECK(pool_type == kConstPoolTag || pool_type == kVeneerPoolTag);
- RelocInfo::Mode rmode = (pool_type == kConstPoolTag) ?
- RelocInfo::CONST_POOL : RelocInfo::VENEER_POOL;
- if (SetMode(rmode)) {
- AdvanceReadPoolData();
- return;
- }
- Advance(kIntSize);
- } else {
- AdvanceReadPC();
- RelocInfo::Mode rmode = static_cast<RelocInfo::Mode>(
- extra_tag + RelocInfo::LAST_COMPACT_ENUM + 1);
- if (RelocInfo::IsDebugBreakSlot(rmode)) {
+ } else if (RelocInfo::IsConstPool(rmode) ||
+ RelocInfo::IsVeneerPool(rmode) ||
+ RelocInfo::IsDebugBreakSlot(rmode)) {
if (SetMode(rmode)) {
- AdvanceReadDebugBreakSlotData();
+ AdvanceReadInt();
return;
}
Advance(kIntSize);
- } else if (SetMode(rmode)) {
+ } else if (SetMode(static_cast<RelocInfo::Mode>(rmode))) {
return;
}
}
#ifdef ENABLE_DISASSEMBLER
const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) {
switch (rmode) {
- case RelocInfo::NONE32:
+ case NONE32:
return "no reloc 32";
- case RelocInfo::NONE64:
+ case NONE64:
return "no reloc 64";
- case RelocInfo::EMBEDDED_OBJECT:
+ case EMBEDDED_OBJECT:
return "embedded object";
- case RelocInfo::CONSTRUCT_CALL:
+ case CONSTRUCT_CALL:
return "code target (js construct call)";
- case RelocInfo::DEBUG_BREAK:
+ case DEBUG_BREAK:
return "debug break";
- case RelocInfo::CODE_TARGET:
+ case CODE_TARGET:
return "code target";
- case RelocInfo::CODE_TARGET_WITH_ID:
+ case CODE_TARGET_WITH_ID:
return "code target with id";
- case RelocInfo::CELL:
+ case CELL:
return "property cell";
- case RelocInfo::RUNTIME_ENTRY:
+ case RUNTIME_ENTRY:
return "runtime entry";
- case RelocInfo::JS_RETURN:
+ case JS_RETURN:
return "js return";
- case RelocInfo::COMMENT:
+ case COMMENT:
return "comment";
- case RelocInfo::POSITION:
+ case POSITION:
return "position";
- case RelocInfo::STATEMENT_POSITION:
+ case STATEMENT_POSITION:
return "statement position";
- case RelocInfo::EXTERNAL_REFERENCE:
+ case EXTERNAL_REFERENCE:
return "external reference";
- case RelocInfo::INTERNAL_REFERENCE:
+ case INTERNAL_REFERENCE:
return "internal reference";
- case RelocInfo::INTERNAL_REFERENCE_ENCODED:
+ case INTERNAL_REFERENCE_ENCODED:
return "encoded internal reference";
- case RelocInfo::DEOPT_REASON:
+ case DEOPT_REASON:
return "deopt reason";
- case RelocInfo::CONST_POOL:
+ case CONST_POOL:
return "constant pool";
- case RelocInfo::VENEER_POOL:
+ case VENEER_POOL:
return "veneer pool";
- case RelocInfo::DEBUG_BREAK_SLOT:
+ case DEBUG_BREAK_SLOT:
return "debug break slot";
- case RelocInfo::CODE_AGE_SEQUENCE:
+ case CODE_AGE_SEQUENCE:
return "code_age_sequence";
- case RelocInfo::NUMBER_OF_MODES:
+ case NUMBER_OF_MODES:
+ case PC_JUMP:
UNREACHABLE();
return "number_of_modes";
}
case NONE64:
break;
case NUMBER_OF_MODES:
+ case PC_JUMP:
UNREACHABLE();
break;
case CODE_AGE_SEQUENCE:
// we do not normally record relocation info.
static const char* const kFillerCommentString;
- // The minimum size of a comment is equal to three bytes for the extra tagged
- // pc + the tag for the data, and kPointerSize for the actual pointer to the
- // comment.
- static const int kMinRelocCommentSize = 3 + kPointerSize;
+ // The minimum size of a comment is equal to two bytes for the extra tagged
+ // pc and kPointerSize for the actual pointer to the comment.
+ static const int kMinRelocCommentSize = 2 + kPointerSize;
// The maximum size for a call instruction including pc-jump.
static const int kMaxCallSize = 6;
CONST_POOL,
VENEER_POOL,
- DEOPT_REASON, // Deoptimization reason index.
+ DEOPT_REASON, // Deoptimization reason index.
+
+ // This is not an actual reloc mode, but used to encode a long pc jump that
+ // cannot be encoded as part of another record.
+ PC_JUMP,
- // add more as needed
// Pseudo-types
- NUMBER_OF_MODES, // There are at most 15 modes with noncompact encoding.
+ NUMBER_OF_MODES,
NONE32, // never recorded 32-bit value
NONE64, // never recorded 64-bit value
CODE_AGE_SEQUENCE, // Not stored in RelocInfo array, used explictly by
FIRST_REAL_RELOC_MODE = CODE_TARGET,
LAST_REAL_RELOC_MODE = VENEER_POOL,
- FIRST_PSEUDO_RELOC_MODE = CODE_AGE_SEQUENCE,
- LAST_PSEUDO_RELOC_MODE = CODE_AGE_SEQUENCE,
LAST_CODE_ENUM = DEBUG_BREAK,
LAST_GCED_ENUM = CELL,
- // Modes <= LAST_COMPACT_ENUM are guaranteed to have compact encoding.
- LAST_COMPACT_ENUM = CODE_TARGET_WITH_ID,
- LAST_STANDARD_NONCOMPACT_ENUM = INTERNAL_REFERENCE_ENCODED
};
RelocInfo() {}
return mode >= FIRST_REAL_RELOC_MODE &&
mode <= LAST_REAL_RELOC_MODE;
}
- static inline bool IsPseudoRelocMode(Mode mode) {
- DCHECK(!IsRealRelocMode(mode));
- return mode >= FIRST_PSEUDO_RELOC_MODE &&
- mode <= LAST_PSEUDO_RELOC_MODE;
- }
static inline bool IsConstructCall(Mode mode) {
return mode == CONSTRUCT_CALL;
}
void Finish() { FlushPosition(); }
// Max size (bytes) of a written RelocInfo. Longest encoding is
- // ExtraTag, VariableLengthPCJump, ExtraTag, pc_delta, ExtraTag, data_delta.
- // On ia32 and arm this is 1 + 4 + 1 + 1 + 1 + 4 = 12.
- // On x64 this is 1 + 4 + 1 + 1 + 1 + 8 == 16;
+ // ExtraTag, VariableLengthPCJump, ExtraTag, pc_delta, data_delta.
+ // On ia32 and arm this is 1 + 4 + 1 + 1 + 4 = 11.
+ // On x64 this is 1 + 4 + 1 + 1 + 8 == 15;
// Here we use the maximum of the two.
- static const int kMaxSize = 16;
+ static const int kMaxSize = 15;
private:
- inline uint32_t WriteVariableLengthPCJump(uint32_t pc_delta);
- inline void WriteTaggedPC(uint32_t pc_delta, int tag);
- inline void WriteExtraTaggedPC(uint32_t pc_delta, int extra_tag);
- inline void WriteInt(int number);
- inline void WriteDebugBreakSlotData(int data);
- inline void WriteExtraTaggedIntData(int data_delta, int top_tag);
- inline void WriteExtraTaggedPoolData(int data, int pool_type);
- inline void WriteExtraTaggedData(intptr_t data_delta, int top_tag);
- inline void WriteTaggedData(intptr_t data_delta, int tag);
- inline void WriteExtraTag(int extra_tag, int top_tag);
+ inline uint32_t WriteLongPCJump(uint32_t pc_delta);
+
+ inline void WriteShortTaggedPC(uint32_t pc_delta, int tag);
+ inline void WriteShortTaggedData(intptr_t data_delta, int tag);
+
+ inline void WriteMode(RelocInfo::Mode rmode);
+ inline void WriteModeAndPC(uint32_t pc_delta, RelocInfo::Mode rmode);
+ inline void WriteIntData(int data_delta);
+ inline void WriteData(intptr_t data_delta);
inline void WritePosition(int pc_delta, int pos_delta, RelocInfo::Mode rmode);
void FlushPosition();
// *Get* just reads and returns info on current byte.
void Advance(int bytes = 1) { pos_ -= bytes; }
int AdvanceGetTag();
- int GetExtraTag();
- int GetTopTag();
- void ReadTaggedPC();
+ RelocInfo::Mode GetMode();
+
+ void AdvanceReadLongPCJump();
+
+ int GetShortDataTypeTag();
+ void ReadShortTaggedPC();
+ void ReadShortTaggedId();
+ void ReadShortTaggedPosition();
+ void ReadShortTaggedData();
+
void AdvanceReadPC();
void AdvanceReadId();
void AdvanceReadInt();
- void AdvanceReadPoolData();
- void AdvanceReadDebugBreakSlotData();
void AdvanceReadPosition();
void AdvanceReadData();
- void AdvanceReadVariableLengthPCJump();
- int GetLocatableTypeTag();
- void ReadTaggedId();
- void ReadTaggedPosition();
- void ReadTaggedData();
// If the given mode is wanted, set it in rinfo_ and return true.
// Else return false. Used for efficiently skipping unwanted modes.