Revision: 11871
Author:   erikcorry
Date:     Tue Jun 19 11:38:03 2012
Log: Snapshots: Add --extra-code flag to mksnapshot which lets you specify a file with more JS code that is loaded into the VM before writing the snapshot. Get
rid of the hard coded limit on the partial snapshot cache size.  This change
disables most of the serializer tests for the snapshot build of the VM: It's
getting too complicated to support both booting from a snapshot and then
creating a new snapshot from the same VM or loading more code with another
snapshot in the same VM.
Review URL: http://codereview.chromium.org/10574013
http://code.google.com/p/v8/source/detail?r=11871

Modified:
 /branches/bleeding_edge/src/flag-definitions.h
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/isolate.cc
 /branches/bleeding_edge/src/isolate.h
 /branches/bleeding_edge/src/mksnapshot.cc
 /branches/bleeding_edge/src/serialize.cc
 /branches/bleeding_edge/src/serialize.h
 /branches/bleeding_edge/src/snapshot-common.cc
 /branches/bleeding_edge/src/snapshot.h
 /branches/bleeding_edge/test/cctest/test-serialize.cc

=======================================
--- /branches/bleeding_edge/src/flag-definitions.h      Thu Jun 14 07:06:22 2012
+++ /branches/bleeding_edge/src/flag-definitions.h      Tue Jun 19 11:38:03 2012
@@ -451,6 +451,10 @@
               "file in which to serialize heap")
 #endif

+// mksnapshot.cc
+DEFINE_string(extra_code, NULL, "A filename with extra code to be included in"
+                  " the snapshot (mksnapshot only)")
+
 //
 // Dev shell flags
 //
@@ -610,6 +614,7 @@
 DEFINE_string(logfile, "v8.log", "Specify the name of the log file.")
 DEFINE_bool(ll_prof, false, "Enable low-level linux profiler.")

+
 //
 // Disassembler only flags
 //
=======================================
--- /branches/bleeding_edge/src/heap.cc Fri Jun 15 06:48:54 2012
+++ /branches/bleeding_edge/src/heap.cc Tue Jun 19 11:38:03 2012
@@ -2822,7 +2822,7 @@
// The idea is to have a small number string cache in the snapshot to keep // boot-time memory usage down. If we expand the number string cache already
   // while creating the snapshot then that didn't work out.
-  ASSERT(!Serializer::enabled());
+  ASSERT(!Serializer::enabled() || FLAG_extra_code != NULL);
   MaybeObject* maybe_obj =
       AllocateFixedArray(FullSizeNumberStringCacheLength(), TENURED);
   Object* new_cache;
=======================================
--- /branches/bleeding_edge/src/isolate.cc      Fri Jun 15 06:34:39 2012
+++ /branches/bleeding_edge/src/isolate.cc      Tue Jun 19 11:38:03 2012
@@ -1549,6 +1549,11 @@
   { ScopedLock lock(process_wide_mutex_);
     thread_data_table_->RemoveAllThreads(this);
   }
+
+  if (serialize_partial_snapshot_cache_ != NULL) {
+    delete[] serialize_partial_snapshot_cache_;
+    serialize_partial_snapshot_cache_ = NULL;
+  }

   if (!IsDefaultIsolate()) {
     delete this;
@@ -1596,6 +1601,26 @@
     state_ = UNINITIALIZED;
   }
 }
+
+
+void Isolate::PushToPartialSnapshotCache(Object* obj) {
+  int length = serialize_partial_snapshot_cache_length();
+  int capacity = serialize_partial_snapshot_cache_capacity();
+
+  if (length >= capacity) {
+    int new_capacity = (capacity + 10) * 1.2;
+    Object** new_array = new Object*[new_capacity];
+    for (int i = 0; i < length; i++) {
+      new_array[i] = serialize_partial_snapshot_cache()[i];
+    }
+    if (capacity != 0) delete[] serialize_partial_snapshot_cache();
+    set_serialize_partial_snapshot_cache(new_array);
+    set_serialize_partial_snapshot_cache_capacity(new_capacity);
+  }
+
+  serialize_partial_snapshot_cache()[length] = obj;
+  set_serialize_partial_snapshot_cache_length(length + 1);
+}


 void Isolate::SetIsolateThreadLocals(Isolate* isolate,
@@ -1814,6 +1839,11 @@
     V8::SetFatalError();
     return false;
   }
+
+  if (create_heap_objects) {
+    // Terminate the cache array with the sentinel so we can iterate.
+    PushToPartialSnapshotCache(heap_.undefined_value());
+  }

   InitializeThreadLocal();

@@ -1841,7 +1871,7 @@
 #endif

   // If we are deserializing, read the state into the now-empty heap.
-  if (des != NULL) {
+  if (!create_heap_objects) {
     des->Deserialize();
   }
   stub_cache_->Initialize();
@@ -1856,7 +1886,7 @@
   heap_.SetStackLimits();

   // Quiet the heap NaN if needed on target platform.
-  if (des != NULL) Assembler::QuietNaN(heap_.nan_value());
+  if (create_heap_objects) Assembler::QuietNaN(heap_.nan_value());

   deoptimizer_data_ = new DeoptimizerData;
   runtime_profiler_ = new RuntimeProfiler(this);
@@ -1864,7 +1894,7 @@

   // If we are deserializing, log non-function code objects and compiled
   // functions found in the snapshot.
-  if (des != NULL && (FLAG_log_code || FLAG_ll_prof)) {
+  if (create_heap_objects && (FLAG_log_code || FLAG_ll_prof)) {
     HandleScope scope;
     LOG(this, LogCodeObjects());
     LOG(this, LogCompiledFunctions());
=======================================
--- /branches/bleeding_edge/src/isolate.h       Mon Jun 11 06:18:05 2012
+++ /branches/bleeding_edge/src/isolate.h       Tue Jun 19 11:38:03 2012
@@ -307,7 +307,6 @@

#define ISOLATE_INIT_ARRAY_LIST(V) \ /* SerializerDeserializer state. */ \ - V(Object*, serialize_partial_snapshot_cache, kPartialSnapshotCacheCapacity) \ V(int, jsregexp_static_offsets_vector, kJSRegexpStaticOffsetsVectorSize) \ V(int, bad_char_shift_table, kUC16AlphabetSize) \ V(int, good_suffix_shift_table, (kBMMaxShift + 1)) \
@@ -320,6 +319,8 @@
#define ISOLATE_INIT_LIST(V) \ /* SerializerDeserializer state. */ \ V(int, serialize_partial_snapshot_cache_length, 0) \ + V(int, serialize_partial_snapshot_cache_capacity, 0) \ + V(Object**, serialize_partial_snapshot_cache, NULL) \ /* Assembler state. */ \ /* A previously allocated buffer of kMinimalBufferSize bytes, or NULL. */ \ V(byte*, assembler_spare_buffer, NULL) \
@@ -609,6 +610,9 @@
     return (exception != Failure::OutOfMemoryException()) &&
         (exception != heap()->termination_exception());
   }
+
+  // Serializer.
+  void PushToPartialSnapshotCache(Object* obj);

   // JS execution stack (see frames.h).
   static Address c_entry_fp(ThreadLocalTop* thread) {
=======================================
--- /branches/bleeding_edge/src/mksnapshot.cc   Thu May 31 05:26:36 2012
+++ /branches/bleeding_edge/src/mksnapshot.cc   Tue Jun 19 11:38:03 2012
@@ -25,6 +25,8 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+#include <errno.h>
+#include <stdio.h>
 #ifdef COMPRESS_STARTUP_DATA_BZ2
 #include <bzlib.h>
 #endif
@@ -33,6 +35,7 @@
 #include "v8.h"

 #include "bootstrapper.h"
+#include "flags.h"
 #include "natives.h"
 #include "platform.h"
 #include "serialize.h"
@@ -308,6 +311,62 @@
             "\nException thrown while compiling natives - see above.\n\n");
     exit(1);
   }
+  if (i::FLAG_extra_code != NULL) {
+    context->Enter();
+    // Capture 100 frames if anything happens.
+    V8::SetCaptureStackTraceForUncaughtExceptions(true, 100);
+    HandleScope scope;
+    const char* name = i::FLAG_extra_code;
+    FILE* file = i::OS::FOpen(name, "rb");
+    if (file == NULL) {
+      fprintf(stderr, "Failed to open '%s': errno %d\n", name, errno);
+      exit(1);
+    }
+
+    fseek(file, 0, SEEK_END);
+    int size = ftell(file);
+    rewind(file);
+
+    char* chars = new char[size + 1];
+    chars[size] = '\0';
+    for (int i = 0; i < size;) {
+      int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
+      if (read < 0) {
+        fprintf(stderr, "Failed to read '%s': errno %d\n", name, errno);
+        exit(1);
+      }
+      i += read;
+    }
+    fclose(file);
+    Local<String> source = String::New(chars);
+    TryCatch try_catch;
+    Local<Script> script = Script::Compile(source);
+    if (try_catch.HasCaught()) {
+      fprintf(stderr, "Failure compiling '%s' (see above)\n", name);
+      exit(1);
+    }
+    Handle<Value> ret = script->Run();
+    if (try_catch.HasCaught()) {
+      fprintf(stderr, "Failure running '%s'\n", name);
+      Local<Message> message = try_catch.Message();
+      Local<String> message_string = message->Get();
+      Local<String> message_line = message->GetSourceLine();
+ int len = 2 + message_string->Utf8Length() + message_line->Utf8Length();
+      char* buf = new char(len);
+      message_string->WriteUtf8(buf);
+      fprintf(stderr, "%s at line %d\n", buf, message->GetLineNumber());
+      message_line->WriteUtf8(buf);
+      fprintf(stderr, "%s\n", buf);
+      int from = message->GetStartColumn();
+      int to = message->GetEndColumn();
+      int i;
+      for (i = 0; i < from; i++) fprintf(stderr, " ");
+      for ( ; i <= to; i++) fprintf(stderr, "^");
+      fprintf(stderr, "\n");
+      exit(1);
+    }
+    context->Exit();
+  }
   // Make sure all builtin scripts are cached.
   { HandleScope scope;
     for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) {
=======================================
--- /branches/bleeding_edge/src/serialize.cc    Mon Apr 23 08:09:59 2012
+++ /branches/bleeding_edge/src/serialize.cc    Tue Jun 19 11:38:03 2012
@@ -37,6 +37,7 @@
 #include "platform.h"
 #include "runtime.h"
 #include "serialize.h"
+#include "snapshot.h"
 #include "stub-cache.h"
 #include "v8threads.h"

@@ -674,10 +675,6 @@
   ASSERT_EQ(NULL, isolate_->thread_manager()->FirstThreadStateInUse());
   // No active handles.
   ASSERT(isolate_->handle_scope_implementer()->blocks()->is_empty());
- // Make sure the entire partial snapshot cache is traversed, filling it with
-  // valid object pointers.
-  isolate_->set_serialize_partial_snapshot_cache_length(
-      Isolate::kPartialSnapshotCacheCapacity);
   ASSERT_EQ(NULL, external_reference_decoder_);
   external_reference_decoder_ = new ExternalReferenceDecoder();
   isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG);
@@ -1149,22 +1146,6 @@

 void PartialSerializer::Serialize(Object** object) {
   this->VisitPointer(object);
-  Isolate* isolate = Isolate::Current();
-
- // After we have done the partial serialization the partial snapshot cache - // will contain some references needed to decode the partial snapshot. We
-  // fill it up with undefineds so it has a predictable length so the
-  // deserialization code doesn't need to know the length.
-  for (int index = isolate->serialize_partial_snapshot_cache_length();
-       index < Isolate::kPartialSnapshotCacheCapacity;
-       index++) {
-    isolate->serialize_partial_snapshot_cache()[index] =
-        isolate->heap()->undefined_value();
-    startup_serializer_->VisitPointer(
-        &isolate->serialize_partial_snapshot_cache()[index]);
-  }
-  isolate->set_serialize_partial_snapshot_cache_length(
-      Isolate::kPartialSnapshotCacheCapacity);
 }


@@ -1194,26 +1175,29 @@

// This ensures that the partial snapshot cache keeps things alive during GC and // tracks their movement. When it is called during serialization of the startup -// snapshot the partial snapshot is empty, so nothing happens. When the partial -// (context) snapshot is created, this array is populated with the pointers that -// the partial snapshot will need. As that happens we emit serialized objects to -// the startup snapshot that correspond to the elements of this cache array. On -// deserialization we therefore need to visit the cache array. This fills it up
-// with pointers to deserialized objects.
+// snapshot nothing happens. When the partial (context) snapshot is created,
+// this array is populated with the pointers that the partial snapshot will
+// need. As that happens we emit serialized objects to the startup snapshot
+// that correspond to the elements of this cache array. On deserialization we +// therefore need to visit the cache array. This fills it up with pointers to
+// deserialized objects.
 void SerializerDeserializer::Iterate(ObjectVisitor* visitor) {
+  if (Serializer::enabled()) return;
   Isolate* isolate = Isolate::Current();
-  visitor->VisitPointers(
-      isolate->serialize_partial_snapshot_cache(),
-      &isolate->serialize_partial_snapshot_cache()[
-          isolate->serialize_partial_snapshot_cache_length()]);
-}
-
-
-// When deserializing we need to set the size of the snapshot cache. This means -// the root iteration code (above) will iterate over array elements, writing the
-// references to deserialized objects in them.
-void SerializerDeserializer::SetSnapshotCacheSize(int size) {
-  Isolate::Current()->set_serialize_partial_snapshot_cache_length(size);
+  for (int i = 0; ; i++) {
+    if (isolate->serialize_partial_snapshot_cache_length() <= i) {
+      // Extend the array ready to get a value from the visitor when
+      // deserializing.
+      isolate->PushToPartialSnapshotCache(Smi::FromInt(0));
+    }
+    Object** cache = isolate->serialize_partial_snapshot_cache();
+    visitor->VisitPointers(&cache[i], &cache[i + 1]);
+ // Sentinel is the undefined object, which is a root so it will not normally
+    // be found in the cache.
+    if (cache[i] == isolate->heap()->undefined_value()) {
+      break;
+    }
+  }
 }


@@ -1231,14 +1215,11 @@
   // then visit the pointer so that it becomes part of the startup snapshot
   // and we can refer to it from the partial snapshot.
   int length = isolate->serialize_partial_snapshot_cache_length();
-  CHECK(length < Isolate::kPartialSnapshotCacheCapacity);
-  isolate->serialize_partial_snapshot_cache()[length] = heap_object;
-  startup_serializer_->VisitPointer(
-      &isolate->serialize_partial_snapshot_cache()[length]);
+  isolate->PushToPartialSnapshotCache(heap_object);
+ startup_serializer_->VisitPointer(reinterpret_cast<Object**>(&heap_object));
   // We don't recurse from the startup snapshot generator into the partial
   // snapshot generator.
-  ASSERT(length == isolate->serialize_partial_snapshot_cache_length());
-  isolate->set_serialize_partial_snapshot_cache_length(length + 1);
+  ASSERT(length == isolate->serialize_partial_snapshot_cache_length() - 1);
   return length;
 }

@@ -1337,12 +1318,14 @@


 void StartupSerializer::SerializeWeakReferences() {
- for (int i = Isolate::Current()->serialize_partial_snapshot_cache_length();
-       i < Isolate::kPartialSnapshotCacheCapacity;
-       i++) {
-    sink_->Put(kRootArray + kPlain + kStartOfObject, "RootSerialization");
-    sink_->PutInt(Heap::kUndefinedValueRootIndex, "root_index");
-  }
+ // This phase comes right after the partial serialization (of the snapshot). + // After we have done the partial serialization the partial snapshot cache + // will contain some references needed to decode the partial snapshot. We + // add one entry with 'undefined' which is the sentinel that the deserializer
+  // uses to know it is done deserializing the array.
+  Isolate* isolate = Isolate::Current();
+  Object* undefined = isolate->heap()->undefined_value();
+  VisitPointer(&undefined);
   HEAP->IterateWeakRoots(this, VISIT_ALL);
 }

=======================================
--- /branches/bleeding_edge/src/serialize.h     Wed Mar 21 07:29:14 2012
+++ /branches/bleeding_edge/src/serialize.h     Tue Jun 19 11:38:03 2012
@@ -210,7 +210,6 @@
 class SerializerDeserializer: public ObjectVisitor {
  public:
   static void Iterate(ObjectVisitor* visitor);
-  static void SetSnapshotCacheSize(int size);

  protected:
   // Where the pointed-to object can be found:
=======================================
--- /branches/bleeding_edge/src/snapshot-common.cc      Fri Apr 29 05:08:33 2011
+++ /branches/bleeding_edge/src/snapshot-common.cc      Tue Jun 19 11:38:03 2012
@@ -58,6 +58,11 @@
   }
   return false;
 }
+
+
+bool Snapshot::HaveASnapshotToStartFrom() {
+  return size_ != 0;
+}


 Handle<Context> Snapshot::NewContextFromSnapshot() {
=======================================
--- /branches/bleeding_edge/src/snapshot.h      Tue Jan 31 05:33:44 2012
+++ /branches/bleeding_edge/src/snapshot.h      Tue Jun 19 11:38:03 2012
@@ -40,6 +40,8 @@
   // could be found.
   static bool Initialize(const char* snapshot_file = NULL);

+  static bool HaveASnapshotToStartFrom();
+
   // Create a new context using the internal partial snapshot.
   static Handle<Context> NewContextFromSnapshot();

=======================================
--- /branches/bleeding_edge/test/cctest/test-serialize.cc Thu Feb 23 04:11:24 2012 +++ /branches/bleeding_edge/test/cctest/test-serialize.cc Tue Jun 19 11:38:03 2012
@@ -250,18 +250,22 @@

 // Test that the whole heap can be serialized.
 TEST(Serialize) {
-  Serializer::Enable();
-  v8::V8::Initialize();
-  Serialize();
+  if (!Snapshot::HaveASnapshotToStartFrom()) {
+    Serializer::Enable();
+    v8::V8::Initialize();
+    Serialize();
+  }
 }


 // Test that heap serialization is non-destructive.
 TEST(SerializeTwice) {
-  Serializer::Enable();
-  v8::V8::Initialize();
-  Serialize();
-  Serialize();
+  if (!Snapshot::HaveASnapshotToStartFrom()) {
+    Serializer::Enable();
+    v8::V8::Initialize();
+    Serialize();
+    Serialize();
+  }
 }


@@ -289,7 +293,7 @@
   // 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()) {
+  if (!Snapshot::HaveASnapshotToStartFrom()) {
     v8::HandleScope scope;
     Deserialize();

@@ -302,7 +306,7 @@


 DEPENDENT_TEST(DeserializeFromSecondSerialization, SerializeTwice) {
-  if (!Snapshot::IsEnabled()) {
+  if (!Snapshot::HaveASnapshotToStartFrom()) {
     v8::HandleScope scope;
     Deserialize();

@@ -315,7 +319,7 @@


 DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) {
-  if (!Snapshot::IsEnabled()) {
+  if (!Snapshot::HaveASnapshotToStartFrom()) {
     v8::HandleScope scope;
     Deserialize();

@@ -332,7 +336,7 @@

 DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2,
                SerializeTwice) {
-  if (!Snapshot::IsEnabled()) {
+  if (!Snapshot::HaveASnapshotToStartFrom()) {
     v8::HandleScope scope;
     Deserialize();

@@ -348,52 +352,55 @@


 TEST(PartialSerialization) {
-  Serializer::Enable();
-  v8::V8::Initialize();
-
-  v8::Persistent<v8::Context> env = v8::Context::New();
-  ASSERT(!env.IsEmpty());
-  env->Enter();
-  // Make sure all builtin scripts are cached.
-  { HandleScope scope;
-    for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
-      Isolate::Current()->bootstrapper()->NativesSourceLookup(i);
-    }
-  }
-  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
-  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
-
-  Object* raw_foo;
-  {
-    v8::HandleScope handle_scope;
-    v8::Local<v8::String> foo = v8::String::New("foo");
-    ASSERT(!foo.IsEmpty());
-    raw_foo = *(v8::Utils::OpenHandle(*foo));
-  }
-
-  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);
-
-  env->Exit();
-  env.Dispose();
-
-  FileByteSink startup_sink(startup_name.start());
-  startup_name.Dispose();
-  StartupSerializer startup_serializer(&startup_sink);
-  startup_serializer.SerializeStrongReferences();
-
-  FileByteSink partial_sink(FLAG_testing_serialization_file);
-  PartialSerializer p_ser(&startup_serializer, &partial_sink);
-  p_ser.Serialize(&raw_foo);
-  startup_serializer.SerializeWeakReferences();
-  partial_sink.WriteSpaceUsed(p_ser.CurrentAllocationAddress(NEW_SPACE),
- p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE), - p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
-                              p_ser.CurrentAllocationAddress(CODE_SPACE),
-                              p_ser.CurrentAllocationAddress(MAP_SPACE),
-                              p_ser.CurrentAllocationAddress(CELL_SPACE),
-                              p_ser.CurrentAllocationAddress(LO_SPACE));
+  if (!Snapshot::HaveASnapshotToStartFrom()) {
+    Serializer::Enable();
+    v8::V8::Initialize();
+
+    v8::Persistent<v8::Context> env = v8::Context::New();
+    ASSERT(!env.IsEmpty());
+    env->Enter();
+    // Make sure all builtin scripts are cached.
+    { HandleScope scope;
+      for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
+        Isolate::Current()->bootstrapper()->NativesSourceLookup(i);
+      }
+    }
+    HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+    HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+
+    Object* raw_foo;
+    {
+      v8::HandleScope handle_scope;
+      v8::Local<v8::String> foo = v8::String::New("foo");
+      ASSERT(!foo.IsEmpty());
+      raw_foo = *(v8::Utils::OpenHandle(*foo));
+    }
+
+    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);
+
+    env->Exit();
+    env.Dispose();
+
+    FileByteSink startup_sink(startup_name.start());
+    startup_name.Dispose();
+    StartupSerializer startup_serializer(&startup_sink);
+    startup_serializer.SerializeStrongReferences();
+
+    FileByteSink partial_sink(FLAG_testing_serialization_file);
+    PartialSerializer p_ser(&startup_serializer, &partial_sink);
+    p_ser.Serialize(&raw_foo);
+    startup_serializer.SerializeWeakReferences();
+    partial_sink.WriteSpaceUsed(
+        p_ser.CurrentAllocationAddress(NEW_SPACE),
+        p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
+        p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
+        p_ser.CurrentAllocationAddress(CODE_SPACE),
+        p_ser.CurrentAllocationAddress(MAP_SPACE),
+        p_ser.CurrentAllocationAddress(CELL_SPACE),
+        p_ser.CurrentAllocationAddress(LO_SPACE));
+  }
 }


@@ -471,53 +478,56 @@


 TEST(ContextSerialization) {
-  Serializer::Enable();
-  v8::V8::Initialize();
-
-  v8::Persistent<v8::Context> env = v8::Context::New();
-  ASSERT(!env.IsEmpty());
-  env->Enter();
-  // Make sure all builtin scripts are cached.
-  { HandleScope scope;
-    for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
-      Isolate::Current()->bootstrapper()->NativesSourceLookup(i);
-    }
-  }
-  // If we don't do this then we end up with a stray root pointing at the
-  // context even after we have disposed of env.
-  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
-
-  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);
-
-  env->Exit();
-
-  Object* raw_context = *(v8::Utils::OpenHandle(*env));
-
-  env.Dispose();
-
-  FileByteSink startup_sink(startup_name.start());
-  startup_name.Dispose();
-  StartupSerializer startup_serializer(&startup_sink);
-  startup_serializer.SerializeStrongReferences();
-
-  FileByteSink partial_sink(FLAG_testing_serialization_file);
-  PartialSerializer p_ser(&startup_serializer, &partial_sink);
-  p_ser.Serialize(&raw_context);
-  startup_serializer.SerializeWeakReferences();
-  partial_sink.WriteSpaceUsed(p_ser.CurrentAllocationAddress(NEW_SPACE),
- p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE), - p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
-                              p_ser.CurrentAllocationAddress(CODE_SPACE),
-                              p_ser.CurrentAllocationAddress(MAP_SPACE),
-                              p_ser.CurrentAllocationAddress(CELL_SPACE),
-                              p_ser.CurrentAllocationAddress(LO_SPACE));
+  if (!Snapshot::HaveASnapshotToStartFrom()) {
+    Serializer::Enable();
+    v8::V8::Initialize();
+
+    v8::Persistent<v8::Context> env = v8::Context::New();
+    ASSERT(!env.IsEmpty());
+    env->Enter();
+    // Make sure all builtin scripts are cached.
+    { HandleScope scope;
+      for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
+        Isolate::Current()->bootstrapper()->NativesSourceLookup(i);
+      }
+    }
+    // If we don't do this then we end up with a stray root pointing at the
+    // context even after we have disposed of env.
+    HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+
+    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);
+
+    env->Exit();
+
+    Object* raw_context = *(v8::Utils::OpenHandle(*env));
+
+    env.Dispose();
+
+    FileByteSink startup_sink(startup_name.start());
+    startup_name.Dispose();
+    StartupSerializer startup_serializer(&startup_sink);
+    startup_serializer.SerializeStrongReferences();
+
+    FileByteSink partial_sink(FLAG_testing_serialization_file);
+    PartialSerializer p_ser(&startup_serializer, &partial_sink);
+    p_ser.Serialize(&raw_context);
+    startup_serializer.SerializeWeakReferences();
+    partial_sink.WriteSpaceUsed(
+        p_ser.CurrentAllocationAddress(NEW_SPACE),
+        p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
+        p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
+        p_ser.CurrentAllocationAddress(CODE_SPACE),
+        p_ser.CurrentAllocationAddress(MAP_SPACE),
+        p_ser.CurrentAllocationAddress(CELL_SPACE),
+        p_ser.CurrentAllocationAddress(LO_SPACE));
+  }
 }


 DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
-  if (!Snapshot::IsEnabled()) {
+  if (!Snapshot::HaveASnapshotToStartFrom()) {
     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);

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to