}
-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_);
}
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);
+ }
}
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()) ||
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() &&
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,
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);