Index: src/serialize.cc |
diff --git a/src/serialize.cc b/src/serialize.cc |
index d5d06a0677f51daa36381a3181ff073d94886d44..49257d45fb92088931333a46c6430a0de9c81f21 100644 |
--- a/src/serialize.cc |
+++ b/src/serialize.cc |
@@ -900,23 +900,20 @@ void Deserializer::ReadObject(int space_number, Object** write_back) { |
DCHECK(space_number != CODE_SPACE); |
} |
#endif |
-#if V8_TARGET_ARCH_PPC |
- // If we're on a platform that uses function descriptors |
- // these jump tables make use of RelocInfo::INTERNAL_REFERENCE. |
- // As the V8 serialization code doesn't handle that relocation type |
- // we use this to fix up code that has function descriptors. |
- if (space_number == CODE_SPACE) { |
- Code* code = reinterpret_cast<Code*>(HeapObject::FromAddress(address)); |
- for (RelocIterator it(code); !it.done(); it.next()) { |
- RelocInfo::Mode rmode = it.rinfo()->rmode(); |
- if (RelocInfo::IsInternalReference(rmode) || |
- RelocInfo::IsInternalReferenceEncoded(rmode)) { |
- Assembler::RelocateInternalReference(it.rinfo()->pc(), 0, |
- code->instruction_start(), rmode); |
- } |
+ |
+ if (obj->IsCode()) { |
+ // Turn internal references encoded as offsets back to absolute addresses. |
+ Code* code = Code::cast(obj); |
+ Address entry = code->entry(); |
+ int mode_mask = RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE); |
+ for (RelocIterator it(code, mode_mask); !it.done(); it.next()) { |
+ RelocInfo* rinfo = it.rinfo(); |
+ intptr_t offset = |
+ reinterpret_cast<intptr_t>(rinfo->target_internal_reference()); |
+ DCHECK(0 <= offset && offset <= code->instruction_size()); |
+ rinfo->set_target_internal_reference(entry + offset); |
} |
} |
-#endif |
} |
@@ -1972,7 +1969,7 @@ void Serializer::ObjectSerializer::VisitExternalReference(RelocInfo* rinfo) { |
HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; |
sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); |
sink_->PutInt(skip, "SkipB4ExternalRef"); |
- Address target = rinfo->target_reference(); |
+ Address target = rinfo->target_external_reference(); |
sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); |
bytes_processed_so_far_ += rinfo->target_address_size(); |
} |
@@ -2049,17 +2046,26 @@ void Serializer::ObjectSerializer::VisitExternalOneByteString( |
Address Serializer::ObjectSerializer::PrepareCode() { |
// To make snapshots reproducible, we make a copy of the code object |
// and wipe all pointers in the copy, which we then serialize. |
- Code* code = serializer_->CopyCode(Code::cast(object_)); |
+ Code* original = Code::cast(object_); |
+ Code* code = serializer_->CopyCode(original); |
// Code age headers are not serializable. |
code->MakeYoung(serializer_->isolate()); |
- int mode_mask = |
- RelocInfo::kCodeTargetMask | |
- RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | |
- RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | |
- RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY); |
+ Address entry = original->entry(); |
+ int mode_mask = RelocInfo::kCodeTargetMask | |
+ RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | |
+ RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | |
+ RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) | |
+ RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE); |
for (RelocIterator it(code, mode_mask); !it.done(); it.next()) { |
- if (!(FLAG_enable_ool_constant_pool && it.rinfo()->IsInConstantPool())) { |
- it.rinfo()->WipeOut(); |
+ RelocInfo* rinfo = it.rinfo(); |
+ if (RelocInfo::IsInternalReference(rinfo->rmode())) { |
+ // Convert internal references to relative offsets. |
+ Address target = rinfo->target_internal_reference(); |
+ intptr_t offset = target - entry; |
+ DCHECK(0 <= offset && offset <= original->instruction_size()); |
+ rinfo->set_target_internal_reference(reinterpret_cast<Address>(offset)); |
+ } else if (!(FLAG_enable_ool_constant_pool && rinfo->IsInConstantPool())) { |
+ rinfo->WipeOut(); |
} |
} |
// We need to wipe out the header fields *after* wiping out the |