Reviewers: vogelheim,

Description:
Tweak memory management in the serializer.

[email protected]

Please review this at https://codereview.chromium.org/957703003/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+33, -25 lines):
  M src/serialize.h
  M src/serialize.cc


Index: src/serialize.cc
diff --git a/src/serialize.cc b/src/serialize.cc
index 05a54188b86cfbeef9bc010a083fcad001d9adb5..8f3888cc431f6ee753f4f4b66b3b9e91c5876e89 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -706,8 +706,8 @@ MaybeHandle<Object> Deserializer::DeserializePartial(
     return MaybeHandle<Object>();
   }

- Vector<Handle<Object> > attached_objects = Vector<Handle<Object>
::New(1);
-  attached_objects[kGlobalProxyReference] = global_proxy;
+  Handle<Object> global_proxy_object = global_proxy;
+  Vector<Handle<Object> > attached_objects(&global_proxy_object, 1);
   SetAttachedObjects(attached_objects);

   DisallowHeapAllocation no_gc;
@@ -753,7 +753,6 @@ Deserializer::~Deserializer() {
     delete external_reference_decoder_;
     external_reference_decoder_ = NULL;
   }
-  attached_objects_.Dispose();
 }


@@ -1378,6 +1377,7 @@ Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink)
 Serializer::~Serializer() {
   delete external_reference_encoder_;
   if (code_address_map_ != NULL) delete code_address_map_;
+  code_buffer_.Dispose();
 }


@@ -2044,14 +2044,16 @@ 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* original = Code::cast(object_);
+  int size = original->CodeSize();
+  Address copy = serializer_->GetCodeBuffer(size);
+  MemCopy(copy, original->address(), size);
+  Code* code = Code::cast(HeapObject::FromAddress(copy));
+  // Code age headers are not serializable.
+  code->MakeYoung(serializer_->isolate());
   int mode_mask =
       RelocInfo::kCodeTargetMask |
       RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
@@ -2062,6 +2064,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();
 }


@@ -2099,17 +2105,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
@@ -2117,7 +2113,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");
@@ -2416,8 +2411,11 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
   deserializer.SetAttachedObjects(attached_objects);

   // Deserialize.
+ MaybeHandle<SharedFunctionInfo> maybe = deserializer.DeserializeCode(isolate);
+  attached_objects.Dispose();
+
   Handle<SharedFunctionInfo> result;
-  if (!deserializer.DeserializeCode(isolate).ToHandle(&result)) {
+  if (!maybe.ToHandle(&result)) {
     // Deserializing may fail if the reservations cannot be fulfilled.
     if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n");
     return MaybeHandle<SharedFunctionInfo>();
Index: src/serialize.h
diff --git a/src/serialize.h b/src/serialize.h
index 64164c803a931c61b4808b64a025ab2c4d4e6e55..02dd07e64eb2676e44007b9b7c5af01d3c3cada7 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -572,7 +572,7 @@ class Deserializer: public SerializerDeserializer {
   void FlushICacheForNewCodeObjects();

// Pass a vector of externally-provided objects referenced by the snapshot.
-  // The ownership to its backing store is handed over as well.
+  // The ownership to its backing store is not handed over.
   void SetAttachedObjects(Vector<Handle<Object> > attached_objects) {
     attached_objects_ = attached_objects;
   }
@@ -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_;
@@ -750,6 +752,12 @@ class Serializer : public SerializerDeserializer {
   // of the serializer.  Initialize it on demand.
   void InitializeCodeAddressMap();

+  inline Address GetCodeBuffer(int size) {
+    if (size > code_buffer_.length()) code_buffer_.Dispose();
+    code_buffer_ = Vector<byte>::New(size);
+    return code_buffer_.start();
+  }
+
   inline uint32_t max_chunk_size(int space) const {
     DCHECK_LE(0, space);
     DCHECK_LT(space, kNumberOfSpaces);
@@ -784,6 +792,8 @@ class Serializer : public SerializerDeserializer {
   uint32_t large_objects_total_size_;
   uint32_t seen_large_objects_index_;

+  Vector<byte> code_buffer_;
+
   DISALLOW_COPY_AND_ASSIGN(Serializer);
 };



--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to