| Index: src/serialize.cc
|
| diff --git a/src/serialize.cc b/src/serialize.cc
|
| index 7ed36665e2fa3ea7c917f552626788cc4d4da54f..fdb00ad270f35346795dbc4dd5a5361d82c22bab 100644
|
| --- a/src/serialize.cc
|
| +++ b/src/serialize.cc
|
| @@ -1776,10 +1776,29 @@ void Serializer::ObjectSerializer::VisitExternalAsciiString(
|
| }
|
|
|
|
|
| +static Code* CloneCodeObject(HeapObject* code) {
|
| + Address copy = new byte[code->Size()];
|
| + OS::MemCopy(copy, code->address(), code->Size());
|
| + return Code::cast(HeapObject::FromAddress(copy));
|
| +}
|
| +
|
| +
|
| +static void WipeOutRelocations(Code* code) {
|
| + int mode_mask =
|
| + RelocInfo::kCodeTargetMask |
|
| + RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
|
| + RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
|
| + RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
|
| + for (RelocIterator it(code, mode_mask); !it.done(); it.next()) {
|
| + it.rinfo()->WipeOut();
|
| + }
|
| +}
|
| +
|
| +
|
| int Serializer::ObjectSerializer::OutputRawData(
|
| Address up_to, Serializer::ObjectSerializer::ReturnSkip return_skip) {
|
| Address object_start = object_->address();
|
| - Address base = object_start + bytes_processed_so_far_;
|
| + int base = bytes_processed_so_far_;
|
| int up_to_offset = static_cast<int>(up_to - object_start);
|
| int to_skip = up_to_offset - bytes_processed_so_far_;
|
| int bytes_to_output = to_skip;
|
| @@ -1809,10 +1828,22 @@ int Serializer::ObjectSerializer::OutputRawData(
|
| sink_->Put(kRawData, "RawData");
|
| sink_->PutInt(bytes_to_output, "length");
|
| }
|
| +
|
| + // To make snapshots reproducible, we need to wipe out all pointers in code.
|
| + if (code_object_) {
|
| + Code* code = CloneCodeObject(object_);
|
| + WipeOutRelocations(code);
|
| + // We need to wipe out the header fields *after* wiping out the
|
| + // relocations, because some of these fields are needed for the latter.
|
| + code->WipeOutHeader();
|
| + object_start = code->address();
|
| + }
|
| +
|
| + const char* description = code_object_ ? "Code" : "Byte";
|
| for (int i = 0; i < bytes_to_output; i++) {
|
| - unsigned int data = base[i];
|
| - sink_->PutSection(data, "Byte");
|
| + sink_->PutSection(object_start[base + i], description);
|
| }
|
| + if (code_object_) delete[] object_start;
|
| }
|
| if (to_skip != 0 && return_skip == kIgnoringReturn) {
|
| sink_->Put(kSkip, "Skip");
|
|
|