Revision: 24391
Author:   yang...@chromium.org
Date:     Thu Oct  2 09:39:13 2014 UTC
Log: Serialize all external strings except for native source code strings.

R=mvstan...@chromium.org

Review URL: https://codereview.chromium.org/604373008
https://code.google.com/p/v8/source/detail?r=24391

Modified:
 /branches/bleeding_edge/include/v8.h
 /branches/bleeding_edge/src/bootstrapper.cc
 /branches/bleeding_edge/src/heap/heap.cc
 /branches/bleeding_edge/src/heap/heap.h
 /branches/bleeding_edge/src/serialize.cc
 /branches/bleeding_edge/test/cctest/test-serialize.cc

=======================================
--- /branches/bleeding_edge/include/v8.h        Thu Oct  2 08:28:04 2014 UTC
+++ /branches/bleeding_edge/include/v8.h        Thu Oct  2 09:39:13 2014 UTC
@@ -5912,7 +5912,7 @@
   static const int kNullValueRootIndex = 7;
   static const int kTrueValueRootIndex = 8;
   static const int kFalseValueRootIndex = 9;
-  static const int kEmptyStringRootIndex = 152;
+  static const int kEmptyStringRootIndex = 153;

// The external allocation limit should be below 256 MB on all architectures
   // to avoid that resource-constrained embedders run low on memory.
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Tue Sep 30 15:40:08 2014 UTC
+++ /branches/bleeding_edge/src/bootstrapper.cc Thu Oct  2 09:39:13 2014 UTC
@@ -57,6 +57,8 @@
     Handle<String> source_code = isolate_->factory()
->NewExternalStringFromOneByte(resource)
                                      .ToHandleChecked();
+    // Mark this external string with a special map.
+    source_code->set_map(isolate_->heap()->native_source_string_map());
     heap->natives_source_cache()->set(index, *source_code);
   }
   Handle<Object> cached_source(heap->natives_source_cache()->get(index),
=======================================
--- /branches/bleeding_edge/src/heap/heap.cc    Thu Oct  2 07:21:53 2014 UTC
+++ /branches/bleeding_edge/src/heap/heap.cc    Thu Oct  2 09:39:13 2014 UTC
@@ -2521,6 +2521,13 @@
       if (StringShape(entry.type).IsCons()) map->mark_unstable();
       roots_[entry.index] = map;
     }
+
+ { // Create a separate external one byte string map for native sources. + AllocationResult allocation = AllocateMap(EXTERNAL_ONE_BYTE_STRING_TYPE, + ExternalOneByteString::kSize);
+      if (!allocation.To(&obj)) return false;
+      set_native_source_string_map(Map::cast(obj));
+    }

     ALLOCATE_VARSIZE_MAP(STRING_TYPE, undetectable_string)
     undetectable_string_map()->set_is_undetectable();
=======================================
--- /branches/bleeding_edge/src/heap/heap.h     Wed Oct  1 11:53:29 2014 UTC
+++ /branches/bleeding_edge/src/heap/heap.h     Thu Oct  2 09:39:13 2014 UTC
@@ -83,6 +83,7 @@
V(Map, external_string_with_one_byte_data_map, \ ExternalStringWithOneByteDataMap) \ V(Map, external_one_byte_string_map, ExternalOneByteStringMap) \ + V(Map, native_source_string_map, NativeSourceStringMap) \ V(Map, short_external_string_map, ShortExternalStringMap) \ V(Map, short_external_string_with_one_byte_data_map, \ ShortExternalStringWithOneByteDataMap) \
=======================================
--- /branches/bleeding_edge/src/serialize.cc    Thu Oct  2 07:12:46 2014 UTC
+++ /branches/bleeding_edge/src/serialize.cc    Thu Oct  2 09:39:13 2014 UTC
@@ -1552,8 +1552,9 @@
 void Serializer::ObjectSerializer::SerializeExternalString() {
   // Instead of serializing this as an external string, we serialize
   // an imaginary sequential string with the same content.
-  DCHECK(object_->IsExternalString() && object_->IsInternalizedString());
   Isolate* isolate = serializer_->isolate();
+  DCHECK(object_->IsExternalString());
+  DCHECK(object_->map() != isolate->heap()->native_source_string_map());
   ExternalString* string = ExternalString::cast(object_);
   int length = string->length();
   Map* map;
@@ -1600,24 +1601,30 @@


 void Serializer::ObjectSerializer::Serialize() {
-  if (object_->IsExternalString() && object_->IsInternalizedString()) {
-    // Native source code strings are not internalized and are handled in
-    // VisitExternalOneByteString.  We deal with embedded external strings
-    // by serializing them as sequential strings on the heap.
-    // This can only happen with CodeSerializer.
-    SerializeExternalString();
-  } else {
-    int size = object_->Size();
-    Map* map = object_->map();
-    SerializePrologue(Serializer::SpaceOfObject(object_), size, map);
+  if (object_->IsExternalString()) {
+    Heap* heap = serializer_->isolate()->heap();
+    if (object_->map() != heap->native_source_string_map()) {
+      // Usually we cannot recreate resources for external strings. To work
+      // around this, external strings are serialized to look like ordinary
+      // sequential strings.
+ // The exception are native source code strings, since we can recreate
+      // their resources. In that case we fall through and leave it to
+      // VisitExternalOneByteString further down.
+      SerializeExternalString();
+      return;
+    }
+  }
+
+  int size = object_->Size();
+  Map* map = object_->map();
+  SerializePrologue(Serializer::SpaceOfObject(object_), size, map);

-    // Serialize the rest of the object.
-    CHECK_EQ(0, bytes_processed_so_far_);
-    bytes_processed_so_far_ = kPointerSize;
+  // Serialize the rest of the object.
+  CHECK_EQ(0, bytes_processed_so_far_);
+  bytes_processed_so_far_ = kPointerSize;

-    object_->IterateBody(map->instance_type(), size, this);
-    OutputRawData(object_->address() + size);
-  }
+  object_->IterateBody(map->instance_type(), size, this);
+  OutputRawData(object_->address() + size);
 }


=======================================
--- /branches/bleeding_edge/test/cctest/test-serialize.cc Thu Oct 2 08:18:03 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-serialize.cc Thu Oct 2 09:39:13 2014 UTC
@@ -1046,8 +1046,7 @@
   CHECK_NE(*orig, *copy);

   Handle<JSFunction> copy_fun =
-      isolate->factory()->NewFunctionFromSharedFunctionInfo(
-          copy, isolate->native_context());
+ f->NewFunctionFromSharedFunctionInfo(copy, isolate->native_context());

   Handle<Object> copy_result =
Execution::Call(isolate, copy_fun, global, 0, NULL).ToHandleChecked();
@@ -1057,6 +1056,59 @@
   delete cache;
   string.Dispose();
 }
+
+
+TEST(SerializeToplevelExternalScriptName) {
+  FLAG_serialize_toplevel = true;
+  LocalContext context;
+  Isolate* isolate = CcTest::i_isolate();
+ isolate->compilation_cache()->Disable(); // Disable same-isolate code cache.
+
+  Factory* f = isolate->factory();
+
+  v8::HandleScope scope(CcTest::isolate());
+
+  const char* source =
+      "var a = [1, 2, 3, 4];"
+      "a.reduce(function(x, y) { return x + y }, 0)";
+
+  Handle<String> source_string =
+      f->NewStringFromUtf8(CStrVector(source)).ToHandleChecked();
+
+  const SerializerOneByteResource one_byte_resource("one_byte", 8);
+  Handle<String> name =
+ f->NewExternalStringFromOneByte(&one_byte_resource).ToHandleChecked();
+  CHECK(name->IsExternalOneByteString());
+  CHECK(!name->IsInternalizedString());
+
+  Handle<JSObject> global(isolate->context()->global_object());
+  ScriptData* cache = NULL;
+
+  Handle<SharedFunctionInfo> orig = Compiler::CompileScript(
+      source_string, name, 0, 0, false,
+      Handle<Context>(isolate->native_context()), NULL, &cache,
+      v8::ScriptCompiler::kProduceCodeCache, NOT_NATIVES_CODE);
+
+  Handle<SharedFunctionInfo> copy;
+  {
+    DisallowCompilation no_compile_expected(isolate);
+    copy = Compiler::CompileScript(
+        source_string, name, 0, 0, false,
+        Handle<Context>(isolate->native_context()), NULL, &cache,
+        v8::ScriptCompiler::kConsumeCodeCache, NOT_NATIVES_CODE);
+  }
+  CHECK_NE(*orig, *copy);
+
+  Handle<JSFunction> copy_fun =
+ f->NewFunctionFromSharedFunctionInfo(copy, isolate->native_context());
+
+  Handle<Object> copy_result =
+ Execution::Call(isolate, copy_fun, global, 0, NULL).ToHandleChecked();
+
+  CHECK_EQ(10.0f, copy_result->Number());
+
+  delete cache;
+}


 TEST(SerializeToplevelIsolates) {

--
--
v8-dev mailing list
v8-dev@googlegroups.com
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 v8-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to