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.