Revert of MIPS: Fix 'Assembler support for internal references.' (patchset #1 id:1 of https://codereview.chromium.org/922043005/)
Reason for revert: Breaks http://build.chromium.org/p/chromium.fyi/builders/Android%20MIPS%20Builder%20(dbg) Original issue's description: > MIPS: Fix 'Assembler support for internal references.' > > Added new INTERNAL_REFERENCE_ENCODED RelocInfo type to differentiate MIPS existing use of internal references in instructions from the new raw pointer reference needed for dd(Label*). > > BUG= > TEST=cctest/test-assembler-mips/jump_tables1, cctest/test-assembler-mips/jump_tables2, cctest/test-assembler-mips/jump_tables3, cctest/test-run-machops/RunSwitch1 > > Committed: https://crrev.com/244ac6de8316259bc5878480e05348a369c08e2f > Cr-Commit-Position: refs/heads/master@{#26651} TBR=danno@chromium.org,bmeurer@chromium.org,jkummerow@chromium.org,paul.lind@imgtec.com,gergely.kis@imgtec.com,akos.palfi@imgtec.com,dusan.milosavljevic@imgtec.com,balazs.kilvady@imgtec.com NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG= Review URL: https://codereview.chromium.org/934623003 Cr-Commit-Position: refs/heads/master@{#26675}
This commit is contained in:
parent
90734ca186
commit
4fdac75d9f
@ -393,11 +393,6 @@ class RelocInfo {
|
||||
NONE64, // never recorded 64-bit value
|
||||
CODE_AGE_SEQUENCE, // Not stored in RelocInfo array, used explictly by
|
||||
// code aging.
|
||||
|
||||
// Encoded internal reference, used only on MIPS and MIPS64.
|
||||
// Re-uses previous ARM-only encoding, to fit in RealRelocMode space.
|
||||
INTERNAL_REFERENCE_ENCODED = CONST_POOL,
|
||||
|
||||
FIRST_REAL_RELOC_MODE = CODE_TARGET,
|
||||
LAST_REAL_RELOC_MODE = VENEER_POOL,
|
||||
FIRST_PSEUDO_RELOC_MODE = CODE_AGE_SEQUENCE,
|
||||
@ -470,9 +465,6 @@ class RelocInfo {
|
||||
static inline bool IsInternalReference(Mode mode) {
|
||||
return mode == INTERNAL_REFERENCE;
|
||||
}
|
||||
static inline bool IsInternalReferenceEncoded(Mode mode) {
|
||||
return mode == INTERNAL_REFERENCE_ENCODED;
|
||||
}
|
||||
static inline bool IsDebugBreakSlot(Mode mode) {
|
||||
return mode == DEBUG_BREAK_SLOT;
|
||||
}
|
||||
|
@ -126,10 +126,10 @@ void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) {
|
||||
Assembler::JumpLabelToJumpRegister(pc_);
|
||||
}
|
||||
}
|
||||
if (IsInternalReference(rmode_) || IsInternalReferenceEncoded(rmode_)) {
|
||||
if (IsInternalReference(rmode_)) {
|
||||
// Absolute code pointer inside code object moves with the code object.
|
||||
byte* p = reinterpret_cast<byte*>(pc_);
|
||||
int count = Assembler::RelocateInternalReference(rmode_, p, delta);
|
||||
int count = Assembler::RelocateInternalReference(p, delta);
|
||||
CpuFeatures::FlushICache(p, count * sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
|
@ -197,8 +197,7 @@ Register ToRegister(int num) {
|
||||
// Implementation of RelocInfo.
|
||||
|
||||
const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
|
||||
1 << RelocInfo::INTERNAL_REFERENCE |
|
||||
1 << RelocInfo::INTERNAL_REFERENCE_ENCODED;
|
||||
1 << RelocInfo::INTERNAL_REFERENCE;
|
||||
|
||||
|
||||
bool RelocInfo::IsCodedSpecially() {
|
||||
@ -663,18 +662,8 @@ bool Assembler::IsAndImmediate(Instr instr) {
|
||||
}
|
||||
|
||||
|
||||
int Assembler::target_at(int32_t pos, bool is_internal) {
|
||||
int Assembler::target_at(int32_t pos) {
|
||||
Instr instr = instr_at(pos);
|
||||
if (is_internal) {
|
||||
if (instr == 0) {
|
||||
return kEndOfChain;
|
||||
} else {
|
||||
int32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos);
|
||||
int32_t delta = instr_address - instr;
|
||||
DCHECK(pos > delta);
|
||||
return pos - delta;
|
||||
}
|
||||
}
|
||||
if ((instr & ~kImm16Mask) == 0) {
|
||||
// Emitted label constant, not part of a branch.
|
||||
if (instr == 0) {
|
||||
@ -723,22 +712,20 @@ int Assembler::target_at(int32_t pos, bool is_internal) {
|
||||
DCHECK(pos > delta);
|
||||
return pos - delta;
|
||||
}
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
} else { // IsLabel(instr)
|
||||
int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
|
||||
if (imm28 == kEndOfJumpChain) {
|
||||
// EndOfChain sentinel is returned directly, not relative to pc or pos.
|
||||
return kEndOfChain;
|
||||
} else {
|
||||
return pos + imm28;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Assembler::target_at_put(int32_t pos, int32_t target_pos,
|
||||
bool is_internal) {
|
||||
void Assembler::target_at_put(int32_t pos, int32_t target_pos) {
|
||||
Instr instr = instr_at(pos);
|
||||
|
||||
if (is_internal) {
|
||||
uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos;
|
||||
instr_at_put(pos, imm);
|
||||
return;
|
||||
}
|
||||
if ((instr & ~kImm16Mask) == 0) {
|
||||
DCHECK(target_pos == kEndOfChain || target_pos >= 0);
|
||||
// Emitted label constant, not part of a branch.
|
||||
@ -781,7 +768,8 @@ void Assembler::target_at_put(int32_t pos, int32_t target_pos,
|
||||
|
||||
instr_at_put(pos, instr | (imm26 & kImm26Mask));
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos;
|
||||
instr_at_put(pos, imm);
|
||||
}
|
||||
}
|
||||
|
||||
@ -802,8 +790,7 @@ void Assembler::print(Label* L) {
|
||||
} else {
|
||||
PrintF("%d\n", instr);
|
||||
}
|
||||
next(&l, internal_reference_positions_.find(l.pos()) !=
|
||||
internal_reference_positions_.end());
|
||||
next(&l);
|
||||
}
|
||||
} else {
|
||||
PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
|
||||
@ -814,7 +801,6 @@ void Assembler::print(Label* L) {
|
||||
void Assembler::bind_to(Label* L, int pos) {
|
||||
DCHECK(0 <= pos && pos <= pc_offset()); // Must have valid binding position.
|
||||
int32_t trampoline_pos = kInvalidSlotPos;
|
||||
bool is_internal = false;
|
||||
if (L->is_linked() && !trampoline_emitted_) {
|
||||
unbound_labels_count_--;
|
||||
next_buffer_check_ += kTrampolineSlotsSize;
|
||||
@ -823,27 +809,22 @@ void Assembler::bind_to(Label* L, int pos) {
|
||||
while (L->is_linked()) {
|
||||
int32_t fixup_pos = L->pos();
|
||||
int32_t dist = pos - fixup_pos;
|
||||
is_internal = internal_reference_positions_.find(fixup_pos) !=
|
||||
internal_reference_positions_.end();
|
||||
next(L, is_internal); // Call next before overwriting link with target at
|
||||
// fixup_pos.
|
||||
next(L); // Call next before overwriting link with target at fixup_pos.
|
||||
Instr instr = instr_at(fixup_pos);
|
||||
if (is_internal) {
|
||||
target_at_put(fixup_pos, pos, is_internal);
|
||||
} else if (!is_internal && IsBranch(instr)) {
|
||||
if (IsBranch(instr)) {
|
||||
if (dist > kMaxBranchOffset) {
|
||||
if (trampoline_pos == kInvalidSlotPos) {
|
||||
trampoline_pos = get_trampoline_entry(fixup_pos);
|
||||
CHECK(trampoline_pos != kInvalidSlotPos);
|
||||
}
|
||||
DCHECK((trampoline_pos - fixup_pos) <= kMaxBranchOffset);
|
||||
target_at_put(fixup_pos, trampoline_pos, false);
|
||||
target_at_put(fixup_pos, trampoline_pos);
|
||||
fixup_pos = trampoline_pos;
|
||||
dist = pos - fixup_pos;
|
||||
}
|
||||
target_at_put(fixup_pos, pos, false);
|
||||
target_at_put(fixup_pos, pos);
|
||||
} else {
|
||||
target_at_put(fixup_pos, pos, false);
|
||||
target_at_put(fixup_pos, pos);
|
||||
}
|
||||
}
|
||||
L->bind_to(pos);
|
||||
@ -861,9 +842,9 @@ void Assembler::bind(Label* L) {
|
||||
}
|
||||
|
||||
|
||||
void Assembler::next(Label* L, bool is_internal) {
|
||||
void Assembler::next(Label* L) {
|
||||
DCHECK(L->is_linked());
|
||||
int link = target_at(L->pos(), is_internal);
|
||||
int link = target_at(L->pos());
|
||||
if (link == kEndOfChain) {
|
||||
L->Unuse();
|
||||
} else {
|
||||
@ -2351,58 +2332,51 @@ void Assembler::bc1t(int16_t offset, uint16_t cc) {
|
||||
|
||||
|
||||
// Debugging.
|
||||
int Assembler::RelocateInternalReference(RelocInfo::Mode rmode, byte* pc,
|
||||
intptr_t pc_delta) {
|
||||
int Assembler::RelocateInternalReference(byte* pc, intptr_t pc_delta) {
|
||||
Instr instr = instr_at(pc);
|
||||
if (IsLui(instr)) {
|
||||
Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize);
|
||||
Instr instr_ori = instr_at(pc + 1 * Assembler::kInstrSize);
|
||||
DCHECK(IsOri(instr_ori));
|
||||
int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift;
|
||||
imm |= (instr_ori & static_cast<int32_t>(kImm16Mask));
|
||||
if (imm == kEndOfJumpChain) {
|
||||
return 0; // Number of instructions patched.
|
||||
}
|
||||
imm += pc_delta;
|
||||
DCHECK((imm & 3) == 0);
|
||||
|
||||
if (RelocInfo::IsInternalReference(rmode)) {
|
||||
instr_lui &= ~kImm16Mask;
|
||||
instr_ori &= ~kImm16Mask;
|
||||
|
||||
instr_at_put(pc + 0 * Assembler::kInstrSize,
|
||||
instr_lui | ((imm >> kLuiShift) & kImm16Mask));
|
||||
instr_at_put(pc + 1 * Assembler::kInstrSize,
|
||||
instr_ori | (imm & kImm16Mask));
|
||||
return 2; // Number of instructions patched.
|
||||
} else if (IsJ(instr)) {
|
||||
uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
|
||||
if (static_cast<int32_t>(imm28) == kEndOfJumpChain) {
|
||||
return 0; // Number of instructions patched.
|
||||
}
|
||||
imm28 += pc_delta;
|
||||
imm28 &= kImm28Mask;
|
||||
DCHECK((imm28 & 3) == 0);
|
||||
|
||||
instr &= ~kImm26Mask;
|
||||
uint32_t imm26 = imm28 >> 2;
|
||||
DCHECK(is_uint26(imm26));
|
||||
|
||||
instr_at_put(pc, instr | (imm26 & kImm26Mask));
|
||||
return 1; // Number of instructions patched.
|
||||
} else { // IsLabel(instr)
|
||||
int32_t* p = reinterpret_cast<int32_t*>(pc);
|
||||
if (*p == 0) {
|
||||
uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
|
||||
if (static_cast<int32_t>(imm28) == kEndOfJumpChain) {
|
||||
return 0; // Number of instructions patched.
|
||||
}
|
||||
*p += pc_delta;
|
||||
return 1; // Number of instructions patched.
|
||||
} else {
|
||||
DCHECK(RelocInfo::IsInternalReferenceEncoded(rmode));
|
||||
if (IsLui(instr)) {
|
||||
Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize);
|
||||
Instr instr_ori = instr_at(pc + 1 * Assembler::kInstrSize);
|
||||
DCHECK(IsOri(instr_ori));
|
||||
int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift;
|
||||
imm |= (instr_ori & static_cast<int32_t>(kImm16Mask));
|
||||
if (imm == kEndOfJumpChain) {
|
||||
return 0; // Number of instructions patched.
|
||||
}
|
||||
imm += pc_delta;
|
||||
DCHECK((imm & 3) == 0);
|
||||
|
||||
instr_lui &= ~kImm16Mask;
|
||||
instr_ori &= ~kImm16Mask;
|
||||
|
||||
instr_at_put(pc + 0 * Assembler::kInstrSize,
|
||||
instr_lui | ((imm >> kLuiShift) & kImm16Mask));
|
||||
instr_at_put(pc + 1 * Assembler::kInstrSize,
|
||||
instr_ori | (imm & kImm16Mask));
|
||||
return 2; // Number of instructions patched.
|
||||
} else if (IsJ(instr)) {
|
||||
uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
|
||||
if (static_cast<int32_t>(imm28) == kEndOfJumpChain) {
|
||||
return 0; // Number of instructions patched.
|
||||
}
|
||||
imm28 += pc_delta;
|
||||
imm28 &= kImm28Mask;
|
||||
DCHECK((imm28 & 3) == 0);
|
||||
|
||||
instr &= ~kImm26Mask;
|
||||
uint32_t imm26 = imm28 >> 2;
|
||||
DCHECK(is_uint26(imm26));
|
||||
|
||||
instr_at_put(pc, instr | (imm26 & kImm26Mask));
|
||||
return 1; // Number of instructions patched.
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2443,12 +2417,12 @@ void Assembler::GrowBuffer() {
|
||||
// Relocate runtime entries.
|
||||
for (RelocIterator it(desc); !it.done(); it.next()) {
|
||||
RelocInfo::Mode rmode = it.rinfo()->rmode();
|
||||
if (rmode == RelocInfo::INTERNAL_REFERENCE_ENCODED ||
|
||||
rmode == RelocInfo::INTERNAL_REFERENCE) {
|
||||
if (rmode == RelocInfo::INTERNAL_REFERENCE) {
|
||||
byte* p = reinterpret_cast<byte*>(it.rinfo()->pc());
|
||||
RelocateInternalReference(rmode, p, pc_delta);
|
||||
RelocateInternalReference(p, pc_delta);
|
||||
}
|
||||
}
|
||||
|
||||
DCHECK(!overflow());
|
||||
}
|
||||
|
||||
@ -2475,9 +2449,23 @@ void Assembler::dd(Label* label) {
|
||||
*reinterpret_cast<uint32_t*>(pc_) = data;
|
||||
pc_ += sizeof(uint32_t);
|
||||
} else {
|
||||
uint32_t target_pos = jump_address(label);
|
||||
emit(target_pos);
|
||||
internal_reference_positions_.insert(label->pos());
|
||||
int target_pos;
|
||||
if (label->is_linked()) {
|
||||
// Point to previous instruction that uses the link.
|
||||
target_pos = label->pos();
|
||||
} else {
|
||||
// First entry of the link chain points to itself.
|
||||
target_pos = pc_offset();
|
||||
}
|
||||
label->link_to(pc_offset());
|
||||
// Encode internal reference to unbound label. We set the least significant
|
||||
// bit to distinguish unbound internal references in GrowBuffer() below.
|
||||
int diff = target_pos - pc_offset();
|
||||
DCHECK_EQ(0, diff & 3);
|
||||
int imm26 = diff >> 2;
|
||||
DCHECK(is_int26(imm26));
|
||||
// Emit special LABEL instruction.
|
||||
emit(LABEL | (imm26 & kImm26Mask));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2562,7 +2550,7 @@ void Assembler::CheckTrampolinePool() {
|
||||
// Buffer growth (and relocation) must be blocked for internal
|
||||
// references until associated instructions are emitted and available
|
||||
// to be patched.
|
||||
RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
|
||||
RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
|
||||
lui(at, (imm32 & kHiMask) >> kLuiShift);
|
||||
ori(at, at, (imm32 & kImm16Mask));
|
||||
}
|
||||
|
@ -38,8 +38,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <tr1/unordered_set>
|
||||
|
||||
#include "src/assembler.h"
|
||||
#include "src/mips/constants-mips.h"
|
||||
#include "src/serialize.h"
|
||||
@ -1023,8 +1021,7 @@ class Assembler : public AssemblerBase {
|
||||
void RecordDeoptReason(const int reason, const int raw_position);
|
||||
|
||||
|
||||
static int RelocateInternalReference(RelocInfo::Mode rmode, byte* pc,
|
||||
intptr_t pc_delta);
|
||||
static int RelocateInternalReference(byte* pc, intptr_t pc_delta);
|
||||
|
||||
// Writes a single byte or word of data in the code stream. Used for
|
||||
// inline tables, e.g., jump-tables.
|
||||
@ -1129,10 +1126,10 @@ class Assembler : public AssemblerBase {
|
||||
int32_t buffer_space() const { return reloc_info_writer.pos() - pc_; }
|
||||
|
||||
// Decode branch instruction at pos and return branch target pos.
|
||||
int target_at(int32_t pos, bool is_internal);
|
||||
int target_at(int32_t pos);
|
||||
|
||||
// Patch branch instruction at pos to branch to given branch target pos.
|
||||
void target_at_put(int32_t pos, int32_t target_pos, bool is_internal);
|
||||
void target_at_put(int32_t pos, int32_t target_pos);
|
||||
|
||||
// Say if we need to relocate with this mode.
|
||||
bool MustUseReg(RelocInfo::Mode rmode);
|
||||
@ -1301,7 +1298,7 @@ class Assembler : public AssemblerBase {
|
||||
// Labels.
|
||||
void print(Label* L);
|
||||
void bind_to(Label* L, int pos);
|
||||
void next(Label* L, bool is_internal);
|
||||
void next(Label* L);
|
||||
|
||||
// One trampoline consists of:
|
||||
// - space for trampoline slots,
|
||||
@ -1366,10 +1363,6 @@ class Assembler : public AssemblerBase {
|
||||
static const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
|
||||
static const int kInvalidSlotPos = -1;
|
||||
|
||||
// Internal reference positions, required for unbounded internal reference
|
||||
// labels.
|
||||
std::tr1::unordered_set<int> internal_reference_positions_;
|
||||
|
||||
Trampoline trampoline_;
|
||||
bool internal_trampoline_exception_;
|
||||
|
||||
|
@ -339,6 +339,7 @@ enum Opcode {
|
||||
|
||||
DADDI = ((3 << 3) + 0) << kOpcodeShift, // This is also BNEC.
|
||||
SPECIAL2 = ((3 << 3) + 4) << kOpcodeShift,
|
||||
LABEL = ((3 << 3) + 5) << kOpcodeShift,
|
||||
SPECIAL3 = ((3 << 3) + 7) << kOpcodeShift,
|
||||
|
||||
LB = ((4 << 3) + 0) << kOpcodeShift,
|
||||
|
@ -3087,7 +3087,7 @@ void MacroAssembler::J(Label* L, BranchDelaySlot bdslot) {
|
||||
{ BlockGrowBufferScope block_buf_growth(this);
|
||||
// Buffer growth (and relocation) must be blocked for internal references
|
||||
// until associated instructions are emitted and available to be patched.
|
||||
RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
|
||||
RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
|
||||
j(imm28);
|
||||
}
|
||||
// Emit a nop in the branch delay slot if required.
|
||||
@ -3104,7 +3104,7 @@ void MacroAssembler::Jr(Label* L, BranchDelaySlot bdslot) {
|
||||
{ BlockGrowBufferScope block_buf_growth(this);
|
||||
// Buffer growth (and relocation) must be blocked for internal references
|
||||
// until associated instructions are emitted and available to be patched.
|
||||
RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
|
||||
RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
|
||||
lui(at, (imm32 & kHiMask) >> kLuiShift);
|
||||
ori(at, at, (imm32 & kImm16Mask));
|
||||
}
|
||||
@ -3124,7 +3124,7 @@ void MacroAssembler::Jalr(Label* L, BranchDelaySlot bdslot) {
|
||||
{ BlockGrowBufferScope block_buf_growth(this);
|
||||
// Buffer growth (and relocation) must be blocked for internal references
|
||||
// until associated instructions are emitted and available to be patched.
|
||||
RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
|
||||
RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
|
||||
lui(at, (imm32 & kHiMask) >> kLuiShift);
|
||||
ori(at, at, (imm32 & kImm16Mask));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user