Tweak memory management in the serializer.

R=vogelheim@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#26947}
This commit is contained in:
yangguo 2015-03-02 11:57:39 -08:00 committed by Commit bot
parent 363dbde912
commit ea02c3339d
2 changed files with 25 additions and 20 deletions

View File

@ -2046,14 +2046,12 @@ void Serializer::ObjectSerializer::VisitExternalOneByteString(
}
static Code* CloneCodeObject(HeapObject* code) {
Address copy = new byte[code->Size()];
MemCopy(copy, code->address(), code->Size());
return Code::cast(HeapObject::FromAddress(copy));
}
static void WipeOutRelocations(Code* code) {
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 age headers are not serializable.
code->MakeYoung(serializer_->isolate());
int mode_mask =
RelocInfo::kCodeTargetMask |
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
@ -2064,6 +2062,10 @@ static void WipeOutRelocations(Code* code) {
it.rinfo()->WipeOut();
}
}
// 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();
return code->address();
}
@ -2101,17 +2103,7 @@ int Serializer::ObjectSerializer::OutputRawData(
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_);
// Code age headers are not serializable.
code->MakeYoung(serializer_->isolate());
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();
}
if (code_object_) object_start = PrepareCode();
const char* description = code_object_ ? "Code" : "Byte";
#ifdef MEMORY_SANITIZER
@ -2119,7 +2111,6 @@ int Serializer::ObjectSerializer::OutputRawData(
MSAN_MEMORY_IS_INITIALIZED(object_start + base, bytes_to_output);
#endif // MEMORY_SANITIZER
sink_->PutRaw(object_start + base, bytes_to_output, description);
if (code_object_) delete[] object_start;
}
if (to_skip != 0 && return_skip == kIgnoringReturn) {
sink_->Put(kSkip, "Skip");
@ -2178,6 +2169,14 @@ void Serializer::InitializeCodeAddressMap() {
}
Code* Serializer::CopyCode(Code* code) {
code_buffer_.Rewind(0); // Clear buffer without deleting backing store.
int size = code->CodeSize();
code_buffer_.AddAll(Vector<byte>(code->address(), size));
return Code::cast(HeapObject::FromAddress(&code_buffer_.first()));
}
ScriptData* CodeSerializer::Serialize(Isolate* isolate,
Handle<SharedFunctionInfo> info,
Handle<String> source) {

View File

@ -703,6 +703,8 @@ class Serializer : public SerializerDeserializer {
// External strings are serialized in a way to resemble sequential strings.
void SerializeExternalString();
Address PrepareCode();
Serializer* serializer_;
HeapObject* object_;
SnapshotByteSink* sink_;
@ -749,6 +751,8 @@ class Serializer : public SerializerDeserializer {
// of the serializer. Initialize it on demand.
void InitializeCodeAddressMap();
Code* CopyCode(Code* code);
inline uint32_t max_chunk_size(int space) const {
DCHECK_LE(0, space);
DCHECK_LT(space, kNumberOfSpaces);
@ -783,6 +787,8 @@ class Serializer : public SerializerDeserializer {
uint32_t large_objects_total_size_;
uint32_t seen_large_objects_index_;
List<byte> code_buffer_;
DISALLOW_COPY_AND_ASSIGN(Serializer);
};