Commit 56d2ee03 authored by balazs.kilvady's avatar balazs.kilvady Committed by Commit bot

MIPS: Fix 'MIPS: Serializer: serialize internal references via object visitor.'

BUG=

Review URL: https://codereview.chromium.org/1025453003

Cr-Commit-Position: refs/heads/master@{#27351}
parent 8554fbf6
......@@ -554,7 +554,7 @@ void Assembler::deserialization_set_special_target_at(
void Assembler::deserialization_set_target_internal_reference_at(
Address pc, Address target) {
Address pc, Address target, RelocInfo::Mode mode) {
Memory::Address_at(pc) = target;
}
......
......@@ -797,7 +797,8 @@ class Assembler : public AssemblerBase {
// This sets the internal reference at the pc.
inline static void deserialization_set_target_internal_reference_at(
Address pc, Address target);
Address pc, Address target,
RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
// Here we are patching the address in the constant pool, not the actual call
// instruction. The address in the constant pool is the same size as a
......
......@@ -660,7 +660,7 @@ void Assembler::deserialization_set_special_target_at(
void Assembler::deserialization_set_target_internal_reference_at(
Address pc, Address target) {
Address pc, Address target, RelocInfo::Mode mode) {
Memory::Address_at(pc) = target;
}
......
......@@ -904,7 +904,8 @@ class Assembler : public AssemblerBase {
// This sets the internal reference at the pc.
inline static void deserialization_set_target_internal_reference_at(
Address pc, Address target);
Address pc, Address target,
RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
// All addresses in the constant pool are the same size as pointers.
static const int kSpecialTargetSize = kPointerSize;
......
......@@ -532,7 +532,7 @@ void Assembler::emit_near_disp(Label* L) {
void Assembler::deserialization_set_target_internal_reference_at(
Address pc, Address target) {
Address pc, Address target, RelocInfo::Mode mode) {
Memory::Address_at(pc) = target;
}
......
......@@ -549,7 +549,8 @@ class Assembler : public AssemblerBase {
// This sets the internal reference at the pc.
inline static void deserialization_set_target_internal_reference_at(
Address pc, Address target);
Address pc, Address target,
RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
static const int kSpecialTargetSize = kPointerSize;
......
......@@ -200,23 +200,34 @@ Address Assembler::break_address_from_return_address(Address pc) {
}
void Assembler::set_target_internal_reference_encoded_at(Address pc,
Address target) {
// Encoded internal references are lui/ori load of 32-bit abolute address.
Instr instr_lui = Assembler::instr_at(pc + 0 * Assembler::kInstrSize);
Instr instr_ori = Assembler::instr_at(pc + 1 * Assembler::kInstrSize);
DCHECK(Assembler::IsLui(instr_lui));
DCHECK(Assembler::IsOri(instr_ori));
instr_lui &= ~kImm16Mask;
instr_ori &= ~kImm16Mask;
int32_t imm = reinterpret_cast<int32_t>(target);
DCHECK((imm & 3) == 0);
Assembler::instr_at_put(pc + 0 * Assembler::kInstrSize,
instr_lui | ((imm >> kLuiShift) & kImm16Mask));
Assembler::instr_at_put(pc + 1 * Assembler::kInstrSize,
instr_ori | (imm & kImm16Mask));
// Currently used only by deserializer, and all code will be flushed
// after complete deserialization, no need to flush on each reference.
}
void Assembler::deserialization_set_target_internal_reference_at(
Address pc, Address target) {
if (IsLui(instr_at(pc))) {
// Encoded internal references are lui/ori load of 32-bit abolute address.
Instr instr_lui = Assembler::instr_at(pc + 0 * Assembler::kInstrSize);
Instr instr_ori = Assembler::instr_at(pc + 1 * Assembler::kInstrSize);
DCHECK(Assembler::IsLui(instr_lui));
DCHECK(Assembler::IsOri(instr_ori));
instr_lui &= ~kImm16Mask;
instr_ori &= ~kImm16Mask;
int32_t imm = reinterpret_cast<int32_t>(target);
DCHECK((imm & 3) == 0);
Assembler::instr_at_put(pc + 0 * Assembler::kInstrSize,
instr_lui | ((imm >> kLuiShift) & kImm16Mask));
Assembler::instr_at_put(pc + 1 * Assembler::kInstrSize,
instr_ori | (imm & kImm16Mask));
Address pc, Address target, RelocInfo::Mode mode) {
if (mode == RelocInfo::INTERNAL_REFERENCE_ENCODED) {
DCHECK(IsLui(instr_at(pc)));
set_target_internal_reference_encoded_at(pc, target);
} else {
DCHECK(mode == RelocInfo::INTERNAL_REFERENCE);
Memory::Address_at(pc) = target;
}
}
......@@ -397,19 +408,7 @@ void RelocInfo::WipeOut() {
if (IsInternalReference(rmode_)) {
Memory::Address_at(pc_) = NULL;
} else if (IsInternalReferenceEncoded(rmode_)) {
Instr instr_lui = Assembler::instr_at(pc_ + 0 * Assembler::kInstrSize);
Instr instr_ori = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize);
DCHECK(Assembler::IsLui(instr_lui));
DCHECK(Assembler::IsOri(instr_ori));
instr_lui &= ~kImm16Mask;
instr_ori &= ~kImm16Mask;
int32_t imm = 0;
Assembler::instr_at_put(pc_ + 0 * Assembler::kInstrSize,
instr_lui | ((imm >> kLuiShift) & kImm16Mask));
Assembler::instr_at_put(pc_ + 1 * Assembler::kInstrSize,
instr_ori | (imm & kImm16Mask));
// Currently used only by deserializer, and all code will be flushed
// after complete deserialization, no need to flush on each reference.
Assembler::set_target_internal_reference_encoded_at(pc_, nullptr);
} else {
Assembler::set_target_address_at(pc_, host_, NULL);
}
......
......@@ -549,7 +549,8 @@ class Assembler : public AssemblerBase {
// This sets the internal reference at the pc.
inline static void deserialization_set_target_internal_reference_at(
Address pc, Address target);
Address pc, Address target,
RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
// Size of an instruction.
static const int kInstrSize = sizeof(Instr);
......@@ -1191,6 +1192,9 @@ class Assembler : public AssemblerBase {
}
private:
inline static void set_target_internal_reference_encoded_at(Address pc,
Address target);
// Buffer size and constant pool distance are checked together at regular
// intervals of kBufferCheckInterval emitted bytes.
static const int kBufferCheckInterval = 1*KB/2;
......
......@@ -194,30 +194,38 @@ Address Assembler::break_address_from_return_address(Address pc) {
}
void Assembler::set_target_internal_reference_encoded_at(Address pc,
Address target) {
// Encoded internal references are lui/ori load of 48-bit absolute address.
Instr instr_lui = Assembler::instr_at(pc + 0 * Assembler::kInstrSize);
Instr instr_ori = Assembler::instr_at(pc + 1 * Assembler::kInstrSize);
Instr instr_ori2 = Assembler::instr_at(pc + 3 * Assembler::kInstrSize);
DCHECK(Assembler::IsLui(instr_lui));
DCHECK(Assembler::IsOri(instr_ori));
DCHECK(Assembler::IsOri(instr_ori2));
instr_lui &= ~kImm16Mask;
instr_ori &= ~kImm16Mask;
instr_ori2 &= ~kImm16Mask;
int64_t imm = reinterpret_cast<int64_t>(target);
DCHECK((imm & 3) == 0);
Assembler::instr_at_put(pc + 0 * Assembler::kInstrSize,
instr_lui | ((imm >> 32) & kImm16Mask));
Assembler::instr_at_put(pc + 1 * Assembler::kInstrSize,
instr_ori | ((imm >> 16) & kImm16Mask));
Assembler::instr_at_put(pc + 3 * Assembler::kInstrSize,
instr_ori | (imm & kImm16Mask));
// Currently used only by deserializer, and all code will be flushed
// after complete deserialization, no need to flush on each reference.
}
void Assembler::deserialization_set_target_internal_reference_at(
Address pc, Address target) {
if (IsLui(instr_at(pc))) {
// Encoded internal references are lui/ori load of 48-bit abolute address.
Instr instr_lui = Assembler::instr_at(pc + 0 * Assembler::kInstrSize);
Instr instr_ori = Assembler::instr_at(pc + 1 * Assembler::kInstrSize);
Instr instr_ori2 = Assembler::instr_at(pc + 3 * Assembler::kInstrSize);
DCHECK(Assembler::IsLui(instr_lui));
DCHECK(Assembler::IsOri(instr_ori));
DCHECK(Assembler::IsOri(instr_ori2));
instr_lui &= ~kImm16Mask;
instr_ori &= ~kImm16Mask;
instr_ori2 &= ~kImm16Mask;
int64_t imm = reinterpret_cast<int64_t>(target);
DCHECK((imm & 3) == 0);
Assembler::instr_at_put(pc + 0 * Assembler::kInstrSize,
instr_lui | ((imm >> 32) & kImm16Mask));
Assembler::instr_at_put(pc + 1 * Assembler::kInstrSize,
instr_ori | ((imm >> 16) & kImm16Mask));
Assembler::instr_at_put(pc + 3 * Assembler::kInstrSize,
instr_ori | (imm & kImm16Mask));
// Currently used only by deserializer, and all code will be flushed
// after complete deserialization, no need to flush on each reference.
Address pc, Address target, RelocInfo::Mode mode) {
if (mode == RelocInfo::INTERNAL_REFERENCE_ENCODED) {
DCHECK(IsLui(instr_at(pc)));
set_target_internal_reference_encoded_at(pc, target);
} else {
DCHECK(mode == RelocInfo::INTERNAL_REFERENCE);
Memory::Address_at(pc) = target;
}
}
......@@ -262,7 +270,7 @@ Address RelocInfo::target_internal_reference() {
if (rmode_ == INTERNAL_REFERENCE) {
return Memory::Address_at(pc_);
} else {
// Encoded internal references are lui/ori load of 48-bit abolute address.
// Encoded internal references are lui/ori load of 48-bit absolute address.
DCHECK(rmode_ == INTERNAL_REFERENCE_ENCODED);
Instr instr_lui = Assembler::instr_at(pc_ + 0 * Assembler::kInstrSize);
Instr instr_ori = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize);
......@@ -401,24 +409,7 @@ void RelocInfo::WipeOut() {
if (IsInternalReference(rmode_)) {
Memory::Address_at(pc_) = NULL;
} else if (IsInternalReferenceEncoded(rmode_)) {
Instr instr_lui = Assembler::instr_at(pc_ + 0 * Assembler::kInstrSize);
Instr instr_ori = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize);
Instr instr_ori2 = Assembler::instr_at(pc_ + 3 * Assembler::kInstrSize);
DCHECK(Assembler::IsLui(instr_lui));
DCHECK(Assembler::IsOri(instr_ori));
DCHECK(Assembler::IsOri(instr_ori2));
instr_lui &= ~kImm16Mask;
instr_ori &= ~kImm16Mask;
instr_ori2 &= ~kImm16Mask;
int64_t imm = 0;
Assembler::instr_at_put(pc_ + 0 * Assembler::kInstrSize,
instr_lui | ((imm >> 32) & kImm16Mask));
Assembler::instr_at_put(pc_ + 1 * Assembler::kInstrSize,
instr_ori | ((imm >> 16) & kImm16Mask));
Assembler::instr_at_put(pc_ + 3 * Assembler::kInstrSize,
instr_ori | (imm & kImm16Mask));
// Currently used only by deserializer, and all code will be flushed
// after complete deserialization, no need to flush on each reference.
Assembler::set_target_internal_reference_encoded_at(pc_, nullptr);
} else {
Assembler::set_target_address_at(pc_, host_, NULL);
}
......
......@@ -542,7 +542,8 @@ class Assembler : public AssemblerBase {
// This sets the internal reference at the pc.
inline static void deserialization_set_target_internal_reference_at(
Address pc, Address target);
Address pc, Address target,
RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
// Size of an instruction.
static const int kInstrSize = sizeof(Instr);
......@@ -1172,6 +1173,9 @@ class Assembler : public AssemblerBase {
// the relocation info.
TypeFeedbackId recorded_ast_id_;
inline static void set_target_internal_reference_encoded_at(Address pc,
Address target);
int64_t buffer_space() const { return reloc_info_writer.pos() - pc_; }
// Decode branch instruction at pos and return branch target pos.
......
......@@ -1065,6 +1065,7 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
break;
}
case kInternalReferenceEncoded:
case kInternalReference: {
// Internal reference address is not encoded via skip, but by offset
// from code entry.
......@@ -1076,7 +1077,10 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
DCHECK(0 <= target_offset && target_offset <= code->instruction_size());
Address pc = code->entry() + pc_offset;
Address target = code->entry() + target_offset;
Assembler::deserialization_set_target_internal_reference_at(pc, target);
Assembler::deserialization_set_target_internal_reference_at(
pc, target, data == kInternalReference
? RelocInfo::INTERNAL_REFERENCE
: RelocInfo::INTERNAL_REFERENCE_ENCODED);
break;
}
......@@ -1843,7 +1847,10 @@ void Serializer::ObjectSerializer::VisitInternalReference(RelocInfo* rinfo) {
pc_offset <= Code::cast(object_)->instruction_size());
DCHECK(0 <= target_offset &&
target_offset <= Code::cast(object_)->instruction_size());
sink_->Put(kInternalReference, "InternalRef");
sink_->Put(rinfo->rmode() == RelocInfo::INTERNAL_REFERENCE
? kInternalReference
: kInternalReferenceEncoded,
"InternalRef");
sink_->PutInt(static_cast<uintptr_t>(pc_offset), "internal ref address");
sink_->PutInt(static_cast<uintptr_t>(target_offset), "internal ref value");
}
......
......@@ -329,8 +329,7 @@ class SerializerDeserializer: public ObjectVisitor {
kAttachedReference = 0x1b,
// 0x1c Builtin code referenced by index.
kBuiltin = 0x1c
// 0x1d..0x1e Misc (including 0x3d..0x3f, 0x5d..0x5f, 0x7d..0x7f)
// 0x1f Unused (including 0x3f, 0x5f, 0x7f).
// 0x1d..0x1f Misc (including 0x3d..0x3f, 0x5d..0x5f, 0x7d..0x7f)
};
static const int kWhereMask = 0x1f;
......@@ -362,6 +361,7 @@ class SerializerDeserializer: public ObjectVisitor {
static const int kSkip = 0x1d;
// Internal reference encoded as offsets of pc and target from code entry.
static const int kInternalReference = 0x1e;
static const int kInternalReferenceEncoded = 0x1f;
// Do nothing, used for padding.
static const int kNop = 0x3d;
// Move to next reserved chunk.
......
......@@ -266,7 +266,7 @@ void Assembler::set_target_address_at(Address pc,
void Assembler::deserialization_set_target_internal_reference_at(
Address pc, Address target) {
Address pc, Address target, RelocInfo::Mode mode) {
Memory::Address_at(pc) = target;
}
......
......@@ -572,7 +572,8 @@ class Assembler : public AssemblerBase {
// This sets the internal reference at the pc.
inline static void deserialization_set_target_internal_reference_at(
Address instruction, Address target);
Address pc, Address target,
RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
static inline RelocInfo::Mode RelocInfoNone() {
if (kPointerSize == kInt64Size) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment