Do not dump user source code in the code serializer.
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 15 Jul 2014 10:17:22 +0000 (10:17 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 15 Jul 2014 10:17:22 +0000 (10:17 +0000)
R=mvstanton@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22403 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/assembler.h
src/compiler.cc
src/serialize.cc
src/serialize.h
test/cctest/test-serialize.cc

index c92ef1e..6d9be82 100644 (file)
@@ -974,17 +974,6 @@ class ExternalReference BASE_EMBEDDED {
       : address_(address) {}
 
   static void* Redirect(Isolate* isolate,
-                        void* address,
-                        Type type = ExternalReference::BUILTIN_CALL) {
-    ExternalReferenceRedirector* redirector =
-        reinterpret_cast<ExternalReferenceRedirector*>(
-            isolate->external_reference_redirector());
-    if (redirector == NULL) return address;
-    void* answer = (*redirector)(address, type);
-    return answer;
-  }
-
-  static void* Redirect(Isolate* isolate,
                         Address address_arg,
                         Type type = ExternalReference::BUILTIN_CALL) {
     ExternalReferenceRedirector* redirector =
index 117b4c6..e95ed26 100644 (file)
@@ -967,8 +967,7 @@ Handle<SharedFunctionInfo> Compiler::CompileScript(
         is_shared_cross_origin, context);
     if (maybe_result.is_null() && FLAG_serialize_toplevel &&
         cached_data_mode == CONSUME_CACHED_DATA) {
-      Object* des = CodeSerializer::Deserialize(isolate, *cached_data);
-      return handle(SharedFunctionInfo::cast(des), isolate);
+      return CodeSerializer::Deserialize(isolate, *cached_data, source);
     }
   }
 
@@ -1002,7 +1001,7 @@ Handle<SharedFunctionInfo> Compiler::CompileScript(
     if (extension == NULL && !result.is_null() && !result->dont_cache()) {
       compilation_cache->PutScript(source, context, result);
       if (FLAG_serialize_toplevel && cached_data_mode == PRODUCE_CACHED_DATA) {
-        *cached_data = CodeSerializer::Serialize(result);
+        *cached_data = CodeSerializer::Serialize(isolate, result, source);
       }
     }
     if (result.is_null()) isolate->ReportPendingMessages();
index fe84894..5e75ee5 100644 (file)
@@ -718,7 +718,7 @@ class CodeAddressMap: public CodeEventLogger {
 
 Deserializer::Deserializer(SnapshotByteSource* source)
     : isolate_(NULL),
-      deserialize_code_(false),
+      attached_objects_(NULL),
       source_(source),
       external_reference_decoder_(NULL) {
   for (int i = 0; i < LAST_SPACE + 1; i++) {
@@ -905,7 +905,7 @@ void Deserializer::ReadObject(int space_number,
   if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj));
 
   // Fix up strings from serialized user code.
-  if (deserialize_code_) obj = ProcessObjectFromSerializedCode(obj);
+  if (deserializing_user_code()) obj = ProcessObjectFromSerializedCode(obj);
 
   *write_back = obj;
 #ifdef DEBUG
@@ -971,13 +971,18 @@ void Deserializer::ReadChunk(Object** current,
         emit_write_barrier = (space_number == NEW_SPACE);                      \
         new_object = GetAddressFromEnd(data & kSpaceMask);                     \
       } else if (where == kBuiltin) {                                          \
-        ASSERT(deserialize_code_);                                             \
+        ASSERT(deserializing_user_code());                                     \
         int builtin_id = source_->GetInt();                                    \
         ASSERT_LE(0, builtin_id);                                              \
         ASSERT_LT(builtin_id, Builtins::builtin_count);                        \
         Builtins::Name name = static_cast<Builtins::Name>(builtin_id);         \
         new_object = isolate->builtins()->builtin(name);                       \
         emit_write_barrier = false;                                            \
+      } else if (where == kAttachedReference) {                                \
+        ASSERT(deserializing_user_code());                                     \
+        int index = source_->GetInt();                                         \
+        new_object = attached_objects_->at(index);                             \
+        emit_write_barrier = isolate->heap()->InNewSpace(new_object);          \
       } else {                                                                 \
         ASSERT(where == kBackrefWithSkip);                                     \
         int skip = source_->GetInt();                                          \
@@ -1222,6 +1227,10 @@ void Deserializer::ReadChunk(Object** current,
       // Find a builtin and write a pointer to it in the current code object.
       CASE_STATEMENT(kBuiltin, kFromCode, kInnerPointer, 0)
       CASE_BODY(kBuiltin, kFromCode, kInnerPointer, 0)
+      // Find an object in the attached references and write a pointer to it to
+      // the current object.
+      CASE_STATEMENT(kAttachedReference, kPlain, kStartOfObject, 0)
+      CASE_BODY(kAttachedReference, kPlain, kStartOfObject, 0)
 
 #undef CASE_STATEMENT
 #undef CASE_BODY
@@ -1875,12 +1884,13 @@ void Serializer::InitializeCodeAddressMap() {
 }
 
 
-ScriptData* CodeSerializer::Serialize(Handle<SharedFunctionInfo> info) {
+ScriptData* CodeSerializer::Serialize(Isolate* isolate,
+                                      Handle<SharedFunctionInfo> info,
+                                      Handle<String> source) {
   // Serialize code object.
   List<byte> payload;
   ListSnapshotSink list_sink(&payload);
-  CodeSerializer cs(info->GetIsolate(), &list_sink);
-  DisallowHeapAllocation no_gc;
+  CodeSerializer cs(isolate, &list_sink, *source);
   Object** location = Handle<Object>::cast(info).location();
   cs.VisitPointer(location);
   cs.Pad();
@@ -1908,10 +1918,18 @@ void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code,
   }
 
   // TODO(yangguo) wire up stubs from stub cache.
-  // TODO(yangguo) wire up script source.
+  // TODO(yangguo) wire up global object.
   // TODO(yangguo) We cannot deal with different hash seeds yet.
   ASSERT(!heap_object->IsHashTable());
 
+  if (address_mapper_.IsMapped(heap_object)) {
+    int space = SpaceOfObject(heap_object);
+    int address = address_mapper_.MappedTo(heap_object);
+    SerializeReferenceToPreviousObject(space, address, how_to_code,
+                                       where_to_point, skip);
+    return;
+  }
+
   if (heap_object->IsCode()) {
     Code* code_object = Code::cast(heap_object);
     if (code_object->kind() == Code::BUILTIN) {
@@ -1920,11 +1938,8 @@ void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code,
     }
   }
 
-  if (address_mapper_.IsMapped(heap_object)) {
-    int space = SpaceOfObject(heap_object);
-    int address = address_mapper_.MappedTo(heap_object);
-    SerializeReferenceToPreviousObject(space, address, how_to_code,
-                                       where_to_point, skip);
+  if (heap_object == source_) {
+    SerializeSourceObject(how_to_code, where_to_point, skip);
     return;
   }
 
@@ -1960,21 +1975,42 @@ void CodeSerializer::SerializeBuiltin(Code* builtin, HowToCode how_to_code,
 }
 
 
-Object* CodeSerializer::Deserialize(Isolate* isolate, ScriptData* data) {
+void CodeSerializer::SerializeSourceObject(HowToCode how_to_code,
+                                           WhereToPoint where_to_point,
+                                           int skip) {
+  if (skip != 0) {
+    sink_->Put(kSkip, "SkipFromSerializeSourceObject");
+    sink_->PutInt(skip, "SkipDistanceFromSerializeSourceObject");
+  }
+
+  ASSERT(how_to_code == kPlain && where_to_point == kStartOfObject);
+  sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source");
+  sink_->PutInt(kSourceObjectIndex, "kSourceObjectIndex");
+}
+
+
+Handle<SharedFunctionInfo> CodeSerializer::Deserialize(Isolate* isolate,
+                                                       ScriptData* data,
+                                                       Handle<String> source) {
   SerializedCodeData scd(data);
   SnapshotByteSource payload(scd.Payload(), scd.PayloadLength());
   Deserializer deserializer(&payload);
-  deserializer.ExpectSerializedCode();
   STATIC_ASSERT(NEW_SPACE == 0);
   // TODO(yangguo) what happens if remaining new space is too small?
   for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) {
     deserializer.set_reservation(i, scd.GetReservation(i));
   }
+  DisallowHeapAllocation no_gc;
+
+  // Prepare and register list of attached objects.
+  List<Object*> attached_objects(1);
+  attached_objects.Set(kSourceObjectIndex, *source);
+  deserializer.SetAttachedObjects(&attached_objects);
+
   Object* root;
   deserializer.DeserializePartial(isolate, &root);
   deserializer.FlushICacheForNewCodeObjects();
-  ASSERT(root->IsSharedFunctionInfo());
-  return root;
+  return Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(root), isolate);
 }
 
 
index 78be9d2..558cb57 100644 (file)
@@ -155,9 +155,9 @@ class SerializerDeserializer: public ObjectVisitor {
     kExternalReference = 0xb,     // Pointer to an external reference.
     kSkip = 0xc,                  // Skip n bytes.
     kBuiltin = 0xd,               // Builtin code object.
-    // 0xe                             Free.
-    kNop = 0xf,       // Does nothing, used to pad.
-    kBackref = 0x10,  // Object is described relative to end.
+    kAttachedReference = 0xe,     // Object is described in an attached list.
+    kNop = 0xf,                   // Does nothing, used to pad.
+    kBackref = 0x10,              // Object is described relative to end.
     // 0x11-0x16                       One per space.
     kBackrefWithSkip = 0x18,  // Object is described relative to end.
     // 0x19-0x1e                       One per space.
@@ -252,9 +252,13 @@ class Deserializer: public SerializerDeserializer {
 
   void FlushICacheForNewCodeObjects();
 
-  // Call this to indicate that the serialized data represents user code.
-  // There are some more wiring up required in this case.
-  void ExpectSerializedCode() { deserialize_code_ = true; }
+  // Serialized user code reference certain objects that are provided in a list
+  // By calling this method, we assume that we are deserializing user code.
+  void SetAttachedObjects(List<Object*>* attached_objects) {
+    attached_objects_ = attached_objects;
+  }
+
+  bool deserializing_user_code() { return attached_objects_ != NULL; }
 
  private:
   virtual void VisitPointers(Object** start, Object** end);
@@ -297,7 +301,9 @@ class Deserializer: public SerializerDeserializer {
 
   // Cached current isolate.
   Isolate* isolate_;
-  bool deserialize_code_;
+
+  // Objects from the attached object descriptions in the serialized user code.
+  List<Object*>* attached_objects_;
 
   SnapshotByteSource* source_;
   // This is the address of the next object that will be allocated in each
@@ -557,26 +563,42 @@ class StartupSerializer : public Serializer {
     SerializeWeakReferences();
     Pad();
   }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(StartupSerializer);
 };
 
 
 class CodeSerializer : public Serializer {
  public:
-  CodeSerializer(Isolate* isolate, SnapshotByteSink* sink)
-      : Serializer(isolate, sink) {
+  CodeSerializer(Isolate* isolate, SnapshotByteSink* sink, String* source)
+      : Serializer(isolate, sink), source_(source) {
     set_root_index_wave_front(Heap::kStrongRootListLength);
     InitializeCodeAddressMap();
   }
 
-  static ScriptData* Serialize(Handle<SharedFunctionInfo> info);
+  static ScriptData* Serialize(Isolate* isolate,
+                               Handle<SharedFunctionInfo> info,
+                               Handle<String> source);
+
   virtual void SerializeObject(Object* o, HowToCode how_to_code,
                                WhereToPoint where_to_point, int skip);
 
-  static Object* Deserialize(Isolate* isolate, ScriptData* data);
+  static Handle<SharedFunctionInfo> Deserialize(Isolate* isolate,
+                                                ScriptData* data,
+                                                Handle<String> source);
+
+  static const int kSourceObjectIndex = 0;
 
  private:
   void SerializeBuiltin(Code* builtin, HowToCode how_to_code,
                         WhereToPoint where_to_point, int skip);
+  void SerializeSourceObject(HowToCode how_to_code, WhereToPoint where_to_point,
+                             int skip);
+
+  DisallowHeapAllocation no_gc_;
+  String* source_;
+  DISALLOW_COPY_AND_ASSIGN(CodeSerializer);
 };
 
 
index 7d228ca..f025d8f 100644 (file)
@@ -707,6 +707,8 @@ TEST(SerializeToplevelOnePlusOne) {
                               &cache, CONSUME_CACHED_DATA, NOT_NATIVES_CODE);
 
   CHECK_NE(*orig, *copy);
+  CHECK(Script::cast(copy->script())->source() == *source2_string);
+
   Handle<JSFunction> copy_fun =
       isolate->factory()->NewFunctionFromSharedFunctionInfo(
           copy, isolate->native_context());
@@ -758,6 +760,8 @@ TEST(SerializeToplevelInternalizedString) {
                               Handle<Context>(isolate->native_context()), NULL,
                               &cache, CONSUME_CACHED_DATA, NOT_NATIVES_CODE);
   CHECK_NE(*orig, *copy);
+  CHECK(Script::cast(copy->script())->source() == *source2_string);
+
   Handle<JSFunction> copy_fun =
       isolate->factory()->NewFunctionFromSharedFunctionInfo(
           copy, isolate->native_context());