Revision: 3805
Author: [email protected]
Date: Fri Feb 5 01:40:21 2010
Log: * Generate contexts involving extensions using partial snapshots.
Review URL: http://codereview.chromium.org/573018
http://code.google.com/p/v8/source/detail?r=3805
Modified:
/branches/experimental/partial_snapshots/include/v8.h
/branches/experimental/partial_snapshots/src/api.cc
/branches/experimental/partial_snapshots/src/bootstrapper.cc
/branches/experimental/partial_snapshots/src/bootstrapper.h
/branches/experimental/partial_snapshots/src/v8-counters.h
/branches/experimental/partial_snapshots/test/cctest/test-serialize.cc
=======================================
--- /branches/experimental/partial_snapshots/include/v8.h Thu Feb 4
00:02:41 2010
+++ /branches/experimental/partial_snapshots/include/v8.h Fri Feb 5
01:40:21 2010
@@ -2586,9 +2586,8 @@
void DetachGlobal();
/** Creates a new context. */
- static Persistent<Context> New();
static Persistent<Context> New(
- ExtensionConfiguration* extensions,
+ ExtensionConfiguration* extensions = NULL,
Handle<ObjectTemplate> global_template = Handle<ObjectTemplate>(),
Handle<Value> global_object = Handle<Value>());
=======================================
--- /branches/experimental/partial_snapshots/src/api.cc Thu Feb 4 00:02:41
2010
+++ /branches/experimental/partial_snapshots/src/api.cc Fri Feb 5 01:40:21
2010
@@ -2734,44 +2734,42 @@
}
-Persistent<Context> v8::Context::New() {
+Persistent<Context> v8::Context::New(
+ v8::ExtensionConfiguration* extensions,
+ v8::Handle<ObjectTemplate> global_template,
+ v8::Handle<Value> global_object) {
EnsureInitialized("v8::Context::New()");
LOG_API("Context::New");
ON_BAILOUT("v8::Context::New()", return Persistent<Context>());
- if (i::Bootstrapper::AutoExtensionsExist()) {
- return New(0);
- }
-
- // Enter V8 via an ENTER_V8 scope.
- Persistent<Context> result;
- {
- ENTER_V8;
- HandleScope scope;
+ // Handle the simple cases with partial snapshot deserialization.
+ if (global_template.IsEmpty() && global_object.IsEmpty()) {
+ // Enter V8 via an ENTER_V8 scope.
+ Persistent<Context> result;
+ {
+ ENTER_V8;
+ HandleScope scope;
#if defined(ANDROID)
- // On mobile device, full GC is expensive, leave it to the system to
- // decide when should make a full GC.
+ // On mobile device, full GC is expensive, leave it to the system to
+ // decide when should make a full GC.
#else
- // Give the heap a chance to cleanup if we've disposed contexts.
- i::Heap::CollectAllGarbageIfContextDisposed();
+ // Give the heap a chance to cleanup if we've disposed contexts.
+ i::Heap::CollectAllGarbageIfContextDisposed();
#endif
- i::Handle<i::Context> env = i::Snapshot::NewContextFromSnapshot();
- if (env.is_null()) {
- return New(0);
- }
- i::Counters::contexts_created_by_snapshot.Increment();
- return Persistent<Context>::New(Utils::ToLocal(env));
- }
-}
-
-
-Persistent<Context> v8::Context::New(
- v8::ExtensionConfiguration* extensions,
- v8::Handle<ObjectTemplate> global_template,
- v8::Handle<Value> global_object) {
- EnsureInitialized("v8::Context::New()");
- LOG_API("Context::New");
- ON_BAILOUT("v8::Context::New()", return Persistent<Context>());
+ i::Handle<i::Context> env = i::Snapshot::NewContextFromSnapshot();
+ if (!env.is_null()) {
+ if (i::Bootstrapper::InstallExtensions(env, extensions)) {
+ i::Counters::contexts_created_by_snapshot.Increment();
+ return Persistent<Context>::New(Utils::ToLocal(env));
+ } else {
+ return Persistent<Context>();
+ }
+ }
+ // If there was no snapshot built into the VM then we fall through
to the
+ // slow new context builder.
+ }
+ }
+
i::Counters::contexts_created_from_scratch.Increment();
// Enter V8 via an ENTER_V8 scope.
=======================================
--- /branches/experimental/partial_snapshots/src/bootstrapper.cc Thu Feb 4
00:02:41 2010
+++ /branches/experimental/partial_snapshots/src/bootstrapper.cc Fri Feb 5
01:40:21 2010
@@ -292,17 +292,11 @@
Genesis(Handle<Object> global_object,
v8::Handle<v8::ObjectTemplate> global_template,
v8::ExtensionConfiguration* extensions);
- ~Genesis();
+ ~Genesis() { }
Handle<Context> result() { return result_; }
Genesis* previous() { return previous_; }
- static Genesis* current() { return current_; }
-
- // Support for thread preemption.
- static int ArchiveSpacePerThread();
- static char* ArchiveState(char* to);
- static char* RestoreState(char* from);
private:
Handle<Context> global_context_;
@@ -311,7 +305,6 @@
// triggered during environment creation there may be weak handle
// processing callbacks which may create new environments.
Genesis* previous_;
- static Genesis* current_;
Handle<Context> global_context() { return global_context_; }
@@ -319,10 +312,11 @@
Handle<Object> global_object);
void InstallNativeFunctions();
bool InstallNatives();
- bool InstallExtensions(v8::ExtensionConfiguration* extensions);
- bool InstallExtension(const char* name);
- bool InstallExtension(v8::RegisteredExtension* current);
- bool InstallSpecialObjects();
+ static bool InstallExtensions(Handle<Context> global_context,
+ v8::ExtensionConfiguration* extensions);
+ static bool InstallExtension(const char* name);
+ static bool InstallExtension(v8::RegisteredExtension* current);
+ static void InstallSpecialObjects(Handle<Context> global_context);
bool ConfigureApiObject(Handle<JSObject> object,
Handle<ObjectTemplateInfo> object_template);
bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate>
global_template);
@@ -351,13 +345,14 @@
Handle<String> source,
SourceCodeCache* cache,
v8::Extension* extension,
+ Handle<Context> top_context,
bool use_runtime_context);
Handle<Context> result_;
+ BootstrapperActive active_;
+ friend class Bootstrapper;
};
-Genesis* Genesis::current_ = NULL;
-
void Bootstrapper::Iterate(ObjectVisitor* v) {
extensions_cache.Iterate(v);
@@ -372,18 +367,19 @@
void Bootstrapper::AddFixup(Code* code, MacroAssembler* masm) {
PendingFixups::Add(code, masm);
}
-
-
-bool Bootstrapper::IsActive() {
- return Genesis::current() != NULL;
-}
Handle<Context> Bootstrapper::CreateEnvironment(
Handle<Object> global_object,
v8::Handle<v8::ObjectTemplate> global_template,
v8::ExtensionConfiguration* extensions) {
+ HandleScope scope;
Genesis genesis(global_object, global_template, extensions);
+ if (!genesis.result().is_null()) {
+ if (!InstallExtensions(genesis.result(), extensions)) {
+ return Handle<Context>();
+ }
+ }
return genesis.result();
}
@@ -404,12 +400,6 @@
env->set_global_proxy(env->global());
env->global()->set_global_receiver(env->global());
}
-
-
-Genesis::~Genesis() {
- ASSERT(current_ == this);
- current_ = previous_;
-}
static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
@@ -900,8 +890,12 @@
#ifdef ENABLE_DEBUGGER_SUPPORT
Debugger::set_compiling_natives(true);
#endif
- bool result =
- CompileScriptCached(name, source, NULL, NULL, true);
+ bool result = CompileScriptCached(name,
+ source,
+ NULL,
+ NULL,
+ Handle<Context>(Top::context()),
+ true);
ASSERT(Top::has_pending_exception() != result);
if (!result) Top::clear_pending_exception();
#ifdef ENABLE_DEBUGGER_SUPPORT
@@ -915,6 +909,7 @@
Handle<String> source,
SourceCodeCache* cache,
v8::Extension* extension,
+ Handle<Context> top_context,
bool use_runtime_context) {
HandleScope scope;
Handle<JSFunction> boilerplate;
@@ -939,11 +934,11 @@
// Setup the function context. Conceptually, we should clone the
// function before overwriting the context but since we're in a
// single-threaded environment it is not strictly necessary.
- ASSERT(Top::context()->IsGlobalContext());
+ ASSERT(top_context->IsGlobalContext());
Handle<Context> context =
Handle<Context>(use_runtime_context
- ? Top::context()->runtime_context()
- : Top::context());
+ ? Handle<Context>(top_context->runtime_context())
+ : top_context);
Handle<JSFunction> fun =
Factory::NewFunctionFromBoilerplate(boilerplate, context);
@@ -951,14 +946,14 @@
// object as the receiver. Provide no parameters.
Handle<Object> receiver =
Handle<Object>(use_runtime_context
- ? Top::context()->builtins()
- : Top::context()->global());
+ ? top_context->builtins()
+ : top_context->global());
bool has_pending_exception;
Handle<Object> result =
Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
if (has_pending_exception) return false;
return PendingFixups::Process(
- Handle<JSBuiltinsObject>(Top::context()->builtins()));
+ Handle<JSBuiltinsObject>(top_context->builtins()));
}
@@ -1210,10 +1205,24 @@
}
-bool Genesis::InstallSpecialObjects() {
+int BootstrapperActive::nesting_ = 0;
+
+
+bool Bootstrapper::InstallExtensions(Handle<Context> global_context,
+ v8::ExtensionConfiguration*
extensions) {
+ BootstrapperActive active;
+ SaveContext saved_context;
+ Top::set_context(*global_context);
+ if (!Genesis::InstallExtensions(global_context, extensions)) return
false;
+ Genesis::InstallSpecialObjects(global_context);
+ return true;
+}
+
+
+void Genesis::InstallSpecialObjects(Handle<Context> global_context) {
HandleScope scope;
Handle<JSGlobalObject> js_global(
- JSGlobalObject::cast(global_context()->global()));
+ JSGlobalObject::cast(global_context->global()));
// Expose the natives in global if a name for it is specified.
if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) !=
0) {
Handle<String> natives_string =
@@ -1236,13 +1245,12 @@
if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
// If loading fails we just bail out without installing the
// debugger but without tanking the whole context.
- if (!Debug::Load())
- return true;
+ if (!Debug::Load()) return;
// Set the security token for the debugger context to the same as
// the shell global context to allow calling between these (otherwise
// exposing debug global object doesn't make much sense).
Debug::debug_context()->set_security_token(
- global_context()->security_token());
+ global_context->security_token());
Handle<String> debug_string =
Factory::LookupAsciiSymbol(FLAG_expose_debug_as);
@@ -1250,19 +1258,18 @@
Handle<Object>(Debug::debug_context()->global_proxy()), DONT_ENUM);
}
#endif
-
- return true;
}
-bool Genesis::InstallExtensions(v8::ExtensionConfiguration* extensions) {
+bool Genesis::InstallExtensions(Handle<Context> global_context,
+ v8::ExtensionConfiguration* extensions) {
// Clear coloring of extension list
v8::RegisteredExtension* current =
v8::RegisteredExtension::first_extension();
while (current != NULL) {
current->set_state(v8::UNVISITED);
current = current->next();
}
- // Install auto extensions. Coordinate with AutoExtensionsExist below.
+ // Install auto extensions.
current = v8::RegisteredExtension::first_extension();
while (current != NULL) {
if (current->extension()->auto_enable())
@@ -1326,7 +1333,9 @@
Handle<String> source_code = Factory::NewStringFromAscii(source);
bool result = CompileScriptCached(CStrVector(extension->name()),
source_code,
- &extensions_cache, extension,
+ &extensions_cache,
+ extension,
+ Handle<Context>(Top::context()),
false);
ASSERT(Top::has_pending_exception() != result);
if (!result) {
@@ -1557,11 +1566,6 @@
Genesis::Genesis(Handle<Object> global_object,
v8::Handle<v8::ObjectTemplate> global_template,
v8::ExtensionConfiguration* extensions) {
- // Link this genesis object into the stacked genesis chain. This
- // must be done before any early exits because the destructor
- // will always do unlinking.
- previous_ = current_;
- current_ = this;
result_ = Handle<Context>::null();
// If V8 isn't running and cannot be initialized, just return.
@@ -1570,7 +1574,7 @@
// Before creating the roots we must save the context and restore it
// on all function exits.
HandleScope scope;
- SaveContext context;
+ SaveContext saved_context;
CreateRoots(global_template, global_object);
@@ -1581,10 +1585,6 @@
if (!ConfigureGlobalObjects(global_template)) return;
- if (!InstallExtensions(extensions)) return;
-
- if (!InstallSpecialObjects()) return;
-
result_ = global_context_;
}
@@ -1593,59 +1593,46 @@
// Reserve space for statics needing saving and restoring.
int Bootstrapper::ArchiveSpacePerThread() {
- return Genesis::ArchiveSpacePerThread();
+ return BootstrapperActive::ArchiveSpacePerThread();
}
// Archive statics that are thread local.
char* Bootstrapper::ArchiveState(char* to) {
- return Genesis::ArchiveState(to);
+ return BootstrapperActive::ArchiveState(to);
}
// Restore statics that are thread local.
char* Bootstrapper::RestoreState(char* from) {
- return Genesis::RestoreState(from);
+ return BootstrapperActive::RestoreState(from);
}
// Called when the top-level V8 mutex is destroyed.
void Bootstrapper::FreeThreadResources() {
- ASSERT(Genesis::current() == NULL);
-}
-
-
-// Are there extensions that should be installed even if no extension was
-// specified?
-bool Bootstrapper::AutoExtensionsExist() {
- // Find auto extensions.
- v8::RegisteredExtension* current =
v8::RegisteredExtension::first_extension();
- while (current != NULL) {
- if (current->extension()->auto_enable()) return true;
- current = current->next();
- }
- return FLAG_expose_gc;
+ ASSERT(!BootstrapperActive::IsActive());
}
// Reserve space for statics needing saving and restoring.
-int Genesis::ArchiveSpacePerThread() {
- return sizeof(current_);
+int BootstrapperActive::ArchiveSpacePerThread() {
+ return sizeof(nesting_);
}
// Archive statics that are thread local.
-char* Genesis::ArchiveState(char* to) {
- *reinterpret_cast<Genesis**>(to) = current_;
- current_ = NULL;
- return to + sizeof(current_);
+char* BootstrapperActive::ArchiveState(char* to) {
+ *reinterpret_cast<int*>(to) = nesting_;
+ nesting_ = 0;
+ return to + sizeof(nesting_);
}
// Restore statics that are thread local.
-char* Genesis::RestoreState(char* from) {
- current_ = *reinterpret_cast<Genesis**>(from);
- return from + sizeof(current_);
+char* BootstrapperActive::RestoreState(char* from) {
+ nesting_ = *reinterpret_cast<int*>(from);
+ return from + sizeof(nesting_);
}
} } // namespace v8::internal
=======================================
--- /branches/experimental/partial_snapshots/src/bootstrapper.h Thu Feb 4
00:02:41 2010
+++ /branches/experimental/partial_snapshots/src/bootstrapper.h Fri Feb 5
01:40:21 2010
@@ -32,6 +32,24 @@
namespace v8 {
namespace internal {
+
+class BootstrapperActive BASE_EMBEDDED {
+ public:
+ BootstrapperActive() { nesting_++; }
+ ~BootstrapperActive() { nesting_--; }
+
+ // Support for thread preemption.
+ static int ArchiveSpacePerThread();
+ static char* ArchiveState(char* to);
+ static char* RestoreState(char* from);
+
+ private:
+ static bool IsActive() { return nesting_ != 0; }
+ static int nesting_;
+ friend class Bootstrapper;
+};
+
+
// The Boostrapper is the public interface for creating a JavaScript global
// context.
class Bootstrapper : public AllStatic {
@@ -60,7 +78,7 @@
static void AddFixup(Code* code, MacroAssembler* masm);
// Tells whether bootstrapping is active.
- static bool IsActive();
+ static bool IsActive() { return BootstrapperActive::IsActive(); }
// Encoding/decoding support for fixup flags.
class FixupFlagsUseCodeObject: public BitField<bool, 0, 1> {};
@@ -77,7 +95,8 @@
static char* AllocateAutoDeletedArray(int bytes);
// Used for new context creation.
- static bool AutoExtensionsExist();
+ static bool InstallExtensions(Handle<Context> global_context,
+ v8::ExtensionConfiguration* extensions);
};
=======================================
--- /branches/experimental/partial_snapshots/src/v8-counters.h Thu Feb 4
00:02:41 2010
+++ /branches/experimental/partial_snapshots/src/v8-counters.h Fri Feb 5
01:40:21 2010
@@ -102,7 +102,7 @@
SC(contexts_created_from_scratch, V8.ContextsCreatedFromScratch) \
/* Number of contexts created by partial snapshot. */ \
SC(contexts_created_by_snapshot, V8.ContextsCreatedBySnapshot)
-
+
#define STATS_COUNTER_LIST_2(SC) \
=======================================
--- /branches/experimental/partial_snapshots/test/cctest/test-serialize.cc
Thu Feb 4 00:02:41 2010
+++ /branches/experimental/partial_snapshots/test/cctest/test-serialize.cc
Fri Feb 5 01:40:21 2010
@@ -290,57 +290,68 @@
DEPENDENT_TEST(Deserialize, Serialize) {
- v8::HandleScope scope;
-
- Deserialize();
-
- v8::Persistent<v8::Context> env = v8::Context::New();
- env->Enter();
-
- SanityCheck();
+ // The serialize-deserialize tests only work if the VM is built without
+ // serialization. That doesn't matter. We don't need to be able to
+ // serialize a snapshot in a VM that is booted from a snapshot.
+ if (!Snapshot::IsEnabled()) {
+ v8::HandleScope scope;
+
+ Deserialize();
+
+ v8::Persistent<v8::Context> env = v8::Context::New();
+ env->Enter();
+
+ SanityCheck();
+ }
}
DEPENDENT_TEST(DeserializeFromSecondSerialization, SerializeTwice) {
- v8::HandleScope scope;
-
- Deserialize();
-
- v8::Persistent<v8::Context> env = v8::Context::New();
- env->Enter();
-
- SanityCheck();
+ if (!Snapshot::IsEnabled()) {
+ v8::HandleScope scope;
+
+ Deserialize();
+
+ v8::Persistent<v8::Context> env = v8::Context::New();
+ env->Enter();
+
+ SanityCheck();
+ }
}
DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) {
- v8::HandleScope scope;
-
- Deserialize();
-
- v8::Persistent<v8::Context> env = v8::Context::New();
- env->Enter();
-
- const char* c_source = "\"1234\".length";
- v8::Local<v8::String> source = v8::String::New(c_source);
- v8::Local<v8::Script> script = v8::Script::Compile(source);
- CHECK_EQ(4, script->Run()->Int32Value());
+ if (!Snapshot::IsEnabled()) {
+ v8::HandleScope scope;
+
+ Deserialize();
+
+ v8::Persistent<v8::Context> env = v8::Context::New();
+ env->Enter();
+
+ const char* c_source = "\"1234\".length";
+ v8::Local<v8::String> source = v8::String::New(c_source);
+ v8::Local<v8::Script> script = v8::Script::Compile(source);
+ CHECK_EQ(4, script->Run()->Int32Value());
+ }
}
DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2,
SerializeTwice) {
- v8::HandleScope scope;
-
- Deserialize();
-
- v8::Persistent<v8::Context> env = v8::Context::New();
- env->Enter();
-
- const char* c_source = "\"1234\".length";
- v8::Local<v8::String> source = v8::String::New(c_source);
- v8::Local<v8::Script> script = v8::Script::Compile(source);
- CHECK_EQ(4, script->Run()->Int32Value());
+ if (!Snapshot::IsEnabled()) {
+ v8::HandleScope scope;
+
+ Deserialize();
+
+ v8::Persistent<v8::Context> env = v8::Context::New();
+ env->Enter();
+
+ const char* c_source = "\"1234\".length";
+ v8::Local<v8::String> source = v8::String::New(c_source);
+ v8::Local<v8::Script> script = v8::Script::Compile(source);
+ CHECK_EQ(4, script->Run()->Int32Value());
+ }
}
@@ -427,35 +438,37 @@
DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
- int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
- Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
- OS::SNPrintF(startup_name, "%s.startup",
FLAG_testing_serialization_file);
-
- CHECK(Snapshot::Initialize(startup_name.start()));
-
- const char* file_name = FLAG_testing_serialization_file;
- ReserveSpaceForPartialSnapshot(file_name);
-
- int snapshot_size = 0;
- byte* snapshot = ReadBytes(file_name, &snapshot_size);
-
- Object* root;
- {
- SnapshotByteSource source(snapshot, snapshot_size);
- Deserializer deserializer(&source);
- deserializer.DeserializePartial(&root);
- CHECK(root->IsString());
- }
- v8::HandleScope handle_scope;
- Handle<Object>root_handle(root);
-
- Object* root2;
- {
- SnapshotByteSource source(snapshot, snapshot_size);
- Deserializer deserializer(&source);
- deserializer.DeserializePartial(&root2);
- CHECK(root2->IsString());
- CHECK(*root_handle == root2);
+ if (!Snapshot::IsEnabled()) {
+ int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
+ Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
+ OS::SNPrintF(startup_name, "%s.startup",
FLAG_testing_serialization_file);
+
+ CHECK(Snapshot::Initialize(startup_name.start()));
+
+ const char* file_name = FLAG_testing_serialization_file;
+ ReserveSpaceForPartialSnapshot(file_name);
+
+ int snapshot_size = 0;
+ byte* snapshot = ReadBytes(file_name, &snapshot_size);
+
+ Object* root;
+ {
+ SnapshotByteSource source(snapshot, snapshot_size);
+ Deserializer deserializer(&source);
+ deserializer.DeserializePartial(&root);
+ CHECK(root->IsString());
+ }
+ v8::HandleScope handle_scope;
+ Handle<Object>root_handle(root);
+
+ Object* root2;
+ {
+ SnapshotByteSource source(snapshot, snapshot_size);
+ Deserializer deserializer(&source);
+ deserializer.DeserializePartial(&root2);
+ CHECK(root2->IsString());
+ CHECK(*root_handle == root2);
+ }
}
}
@@ -506,35 +519,37 @@
DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
- int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
- Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
- OS::SNPrintF(startup_name, "%s.startup",
FLAG_testing_serialization_file);
-
- CHECK(Snapshot::Initialize(startup_name.start()));
-
- const char* file_name = FLAG_testing_serialization_file;
- ReserveSpaceForPartialSnapshot(file_name);
-
- int snapshot_size = 0;
- byte* snapshot = ReadBytes(file_name, &snapshot_size);
-
- Object* root;
- {
- SnapshotByteSource source(snapshot, snapshot_size);
- Deserializer deserializer(&source);
- deserializer.DeserializePartial(&root);
- CHECK(root->IsContext());
- }
- v8::HandleScope handle_scope;
- Handle<Object>root_handle(root);
-
- Object* root2;
- {
- SnapshotByteSource source(snapshot, snapshot_size);
- Deserializer deserializer(&source);
- deserializer.DeserializePartial(&root2);
- CHECK(root2->IsContext());
- CHECK(*root_handle != root2);
+ if (!Snapshot::IsEnabled()) {
+ int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
+ Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
+ OS::SNPrintF(startup_name, "%s.startup",
FLAG_testing_serialization_file);
+
+ CHECK(Snapshot::Initialize(startup_name.start()));
+
+ const char* file_name = FLAG_testing_serialization_file;
+ ReserveSpaceForPartialSnapshot(file_name);
+
+ int snapshot_size = 0;
+ byte* snapshot = ReadBytes(file_name, &snapshot_size);
+
+ Object* root;
+ {
+ SnapshotByteSource source(snapshot, snapshot_size);
+ Deserializer deserializer(&source);
+ deserializer.DeserializePartial(&root);
+ CHECK(root->IsContext());
+ }
+ v8::HandleScope handle_scope;
+ Handle<Object>root_handle(root);
+
+ Object* root2;
+ {
+ SnapshotByteSource source(snapshot, snapshot_size);
+ Deserializer deserializer(&source);
+ deserializer.DeserializePartial(&root2);
+ CHECK(root2->IsContext());
+ CHECK(*root_handle != root2);
+ }
}
}
@@ -542,6 +557,7 @@
TEST(LinearAllocation) {
v8::V8::Initialize();
int new_space_max = 512 * KB;
+
for (int size = 1000; size < 5 * MB; size += size >> 1) {
int new_space_size = (size < new_space_max) ? size : new_space_max;
Heap::ReserveSpace(
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev