Chromium Code Reviews| Index: src/serialize.cc |
| diff --git a/src/serialize.cc b/src/serialize.cc |
| index 7ed36665e2fa3ea7c917f552626788cc4d4da54f..67cac884d5c7a97cba99b3590596ded3849dc540 100644 |
| --- a/src/serialize.cc |
| +++ b/src/serialize.cc |
| @@ -1776,10 +1776,43 @@ 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 WipeOutCodeHeader(Code* code) { |
| + code->set_relocation_info( |
|
Benedikt Meurer
2013/11/04 11:25:14
Nit: Can we do better here?
|
| + reinterpret_cast<ByteArray*>(Smi::FromInt(0)), SKIP_WRITE_BARRIER); |
| + code->set_handler_table( |
| + reinterpret_cast<FixedArray*>(Smi::FromInt(0)), SKIP_WRITE_BARRIER); |
| + code->set_deoptimization_data( |
| + reinterpret_cast<FixedArray*>(Smi::FromInt(0)), SKIP_WRITE_BARRIER); |
| + // Do not wipe out e.g. a minor key. |
| + if (!code->raw_type_feedback_info()->IsSmi()) { |
| + code->InitializeTypeFeedbackInfoNoWriteBarrier(Smi::FromInt(0)); |
| + } |
| +} |
| + |
| + |
| +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 +1842,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. |
| + WipeOutCodeHeader(code); |
| + 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"); |