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

Reply via email to