Commit cff4fb97 authored by michael_dawson's avatar michael_dawson Committed by Commit bot

PPC: Serializer: serialize internal references via object visitor.

Port 7c149afb

Original commit message:

R=mbrandy@us.ibm.com, svenpanne@chromium.org, danno@chromium.org, jkummerow@chromium.org

BUG=

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

Cr-Commit-Position: refs/heads/master@{#27388}
parent 0fe88cb0
......@@ -78,15 +78,9 @@ Address RelocInfo::target_internal_reference() {
}
void RelocInfo::set_target_internal_reference(Address target) {
if (IsInternalReference(rmode_)) {
// Jump table entry
Memory::Address_at(pc_) = target;
} else {
// mov sequence
DCHECK(IsInternalReferenceEncoded(rmode_));
Assembler::set_target_address_at(pc_, host_, target, SKIP_ICACHE_FLUSH);
}
Address RelocInfo::target_internal_reference_address() {
DCHECK(IsInternalReference(rmode_) || IsInternalReferenceEncoded(rmode_));
return reinterpret_cast<Address>(pc_);
}
......@@ -308,8 +302,18 @@ Object** RelocInfo::call_object_address() {
void RelocInfo::WipeOut() {
DCHECK(IsEmbeddedObject(rmode_) || IsCodeTarget(rmode_) ||
IsRuntimeEntry(rmode_) || IsExternalReference(rmode_));
Assembler::set_target_address_at(pc_, host_, NULL);
IsRuntimeEntry(rmode_) || IsExternalReference(rmode_) ||
IsInternalReference(rmode_) || IsInternalReferenceEncoded(rmode_));
if (IsInternalReference(rmode_)) {
// Jump table entry
Memory::Address_at(pc_) = NULL;
} else if (IsInternalReferenceEncoded(rmode_)) {
// mov sequence
// Currently used only by deserializer, no need to flush.
Assembler::set_target_address_at(pc_, host_, NULL, SKIP_ICACHE_FLUSH);
} else {
Assembler::set_target_address_at(pc_, host_, NULL);
}
}
......@@ -356,6 +360,9 @@ void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
visitor->VisitCell(this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
visitor->VisitExternalReference(this);
} else if (mode == RelocInfo::INTERNAL_REFERENCE ||
mode == RelocInfo::INTERNAL_REFERENCE_ENCODED) {
visitor->VisitInternalReference(this);
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
visitor->VisitCodeAgeSequence(this);
} else if (((RelocInfo::IsJSReturn(mode) && IsPatchedReturnSequence()) ||
......@@ -380,6 +387,9 @@ void RelocInfo::Visit(Heap* heap) {
StaticVisitor::VisitCell(heap, this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
StaticVisitor::VisitExternalReference(this);
} else if (mode == RelocInfo::INTERNAL_REFERENCE ||
mode == RelocInfo::INTERNAL_REFERENCE_ENCODED) {
StaticVisitor::VisitInternalReference(this);
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
StaticVisitor::VisitCodeAgeSequence(heap, this);
} else if (heap->isolate()->debug()->has_break_points() &&
......@@ -474,6 +484,18 @@ void Assembler::deserialization_set_special_target_at(
set_target_address_at(instruction_payload, code, target);
}
void Assembler::deserialization_set_target_internal_reference_at(
Address pc, Address target) {
if (IsLis(instr_at(pc)) && IsOri(instr_at(pc + kInstrSize))) {
Code* code = NULL;
set_target_address_at(pc, code, target, SKIP_ICACHE_FLUSH);
} else {
Memory::Address_at(pc) = target;
}
}
// This code assumes the FIXED_SEQUENCE of lis/ori
void Assembler::set_target_address_at(Address pc,
ConstantPoolArray* constant_pool,
......
......@@ -2303,14 +2303,19 @@ void Assembler::EmitRelocations() {
for (std::vector<DeferredRelocInfo>::iterator it = relocations_.begin();
it != relocations_.end(); it++) {
RelocInfo::Mode rmode = it->rmode();
RelocInfo rinfo(buffer_ + it->position(), rmode, it->data(), NULL);
Address pc = buffer_ + it->position();
Code* code = NULL;
RelocInfo rinfo(pc, rmode, it->data(), code);
// Fix up internal references now that they are guaranteed to be bound.
if (RelocInfo::IsInternalReference(rmode) ||
RelocInfo::IsInternalReferenceEncoded(rmode)) {
intptr_t pos =
reinterpret_cast<intptr_t>(rinfo.target_internal_reference());
rinfo.set_target_internal_reference(buffer_ + pos);
if (RelocInfo::IsInternalReference(rmode)) {
// Jump table entry
intptr_t pos = reinterpret_cast<intptr_t>(Memory::Address_at(pc));
Memory::Address_at(pc) = buffer_ + pos;
} else if (RelocInfo::IsInternalReferenceEncoded(rmode)) {
// mov sequence
intptr_t pos = reinterpret_cast<intptr_t>(target_address_at(pc, code));
set_target_address_at(pc, code, buffer_ + pos, SKIP_ICACHE_FLUSH);
}
reloc_info_writer.Write(&rinfo);
......
......@@ -629,6 +629,10 @@ class Assembler : public AssemblerBase {
inline static void deserialization_set_special_target_at(
Address instruction_payload, Code* code, Address target);
// This sets the internal reference at the pc.
inline static void deserialization_set_target_internal_reference_at(
Address pc, Address target);
// Size of an instruction.
static const int kInstrSize = sizeof(Instr);
......
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