Revision: 3792
Author: [email protected]
Date: Thu Feb  4 00:02:41 2010
Log: * Add the partial context snapshot to the VM executable if
running with snapshots.
* Create contexts from partial snapshot if they contain no
extensions or global object templates.  Add counters to track
when this happens.
* Remove debugging (logging code).
* Some lint fixes.
Review URL: http://codereview.chromium.org/565047
http://code.google.com/p/v8/source/detail?r=3792

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/frames.cc
 /branches/experimental/partial_snapshots/src/heap.h
 /branches/experimental/partial_snapshots/src/mksnapshot.cc
 /branches/experimental/partial_snapshots/src/serialize.cc
 /branches/experimental/partial_snapshots/src/serialize.h
 /branches/experimental/partial_snapshots/src/snapshot-common.cc
 /branches/experimental/partial_snapshots/src/snapshot-empty.cc
 /branches/experimental/partial_snapshots/src/snapshot.h
 /branches/experimental/partial_snapshots/src/v8-counters.h
 /branches/experimental/partial_snapshots/src/v8threads.cc
 /branches/experimental/partial_snapshots/test/cctest/test-serialize.cc

=======================================
--- /branches/experimental/partial_snapshots/include/v8.h Mon Jan 11 04:13:24 2010 +++ /branches/experimental/partial_snapshots/include/v8.h Thu Feb 4 00:02:41 2010
@@ -2586,8 +2586,9 @@
   void DetachGlobal();

   /** Creates a new context. */
+  static Persistent<Context> New();
   static Persistent<Context> New(
-      ExtensionConfiguration* extensions = 0,
+      ExtensionConfiguration* extensions,
       Handle<ObjectTemplate> global_template = Handle<ObjectTemplate>(),
       Handle<Value> global_object = Handle<Value>());

=======================================
--- /branches/experimental/partial_snapshots/src/api.cc Wed Feb 3 02:52:22 2010 +++ /branches/experimental/partial_snapshots/src/api.cc Thu Feb 4 00:02:41 2010
@@ -2732,6 +2732,37 @@
   return i::Handle<i::FunctionTemplateInfo>(
     i::FunctionTemplateInfo::cast(templ->constructor()));
 }
+
+
+Persistent<Context> v8::Context::New() {
+  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;
+#if defined(ANDROID)
+    // 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();
+#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(
@@ -2741,6 +2772,7 @@
   EnsureInitialized("v8::Context::New()");
   LOG_API("Context::New");
   ON_BAILOUT("v8::Context::New()", return Persistent<Context>());
+  i::Counters::contexts_created_from_scratch.Increment();

   // Enter V8 via an ENTER_V8 scope.
   i::Handle<i::Context> env;
=======================================
--- /branches/experimental/partial_snapshots/src/bootstrapper.cc Wed Feb 3 02:52:22 2010 +++ /branches/experimental/partial_snapshots/src/bootstrapper.cc Thu Feb 4 00:02:41 2010
@@ -1262,7 +1262,7 @@
     current->set_state(v8::UNVISITED);
     current = current->next();
   }
-  // Install auto extensions
+  // Install auto extensions.  Coordinate with AutoExtensionsExist below.
   current = v8::RegisteredExtension::first_extension();
   while (current != NULL) {
     if (current->extension()->auto_enable())
@@ -1613,6 +1613,19 @@
 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;
+}


 // Reserve space for statics needing saving and restoring.
=======================================
--- /branches/experimental/partial_snapshots/src/bootstrapper.h Wed Feb 3 02:52:22 2010 +++ /branches/experimental/partial_snapshots/src/bootstrapper.h Thu Feb 4 00:02:41 2010
@@ -75,6 +75,9 @@
   // This will allocate a char array that is deleted when V8 is shut down.
   // It should only be used for strictly finite allocations.
   static char* AllocateAutoDeletedArray(int bytes);
+
+  // Used for new context creation.
+  static bool AutoExtensionsExist();
 };


=======================================
--- /branches/experimental/partial_snapshots/src/frames.cc Wed Feb 3 02:52:22 2010 +++ /branches/experimental/partial_snapshots/src/frames.cc Thu Feb 4 00:02:41 2010
@@ -359,7 +359,6 @@
for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
     it.handler()->Cook(code);
   }
-  printf("Cook %p (%d)\n", (void*)(pc()), code->kind());
   ASSERT(code->contains(pc()));
   set_pc(AddressFrom<Address>(pc() - code->instruction_start()));
 }
@@ -372,7 +371,6 @@
     it.handler()->Uncook(code);
   }
   set_pc(code->instruction_start() + OffsetFrom(pc()));
-  printf("Uncook %p (%d)\n", (void*)(pc()), code->kind());
   ASSERT(code->contains(pc()));
 }

=======================================
--- /branches/experimental/partial_snapshots/src/heap.h Wed Feb 3 02:52:22 2010 +++ /branches/experimental/partial_snapshots/src/heap.h Thu Feb 4 00:02:41 2010
@@ -1477,12 +1477,10 @@
  public:
   AssertNoAllocation() {
     old_state_ = Heap::allow_allocation(false);
-    //printf("No allocation\n");
   }

   ~AssertNoAllocation() {
     Heap::allow_allocation(old_state_);
-    //printf("Allocation\n");
   }

  private:
=======================================
--- /branches/experimental/partial_snapshots/src/mksnapshot.cc Wed Feb 3 02:52:22 2010 +++ /branches/experimental/partial_snapshots/src/mksnapshot.cc Thu Feb 4 00:02:41 2010
@@ -35,6 +35,7 @@
 #include "natives.h"
 #include "platform.h"
 #include "serialize.h"
+#include "list.h"

 // use explicit namespace to avoid clashing with types in namespace v8
 namespace i = v8::internal;
@@ -96,7 +97,9 @@

 class CppByteSink : public i::SnapshotByteSink {
  public:
-  explicit CppByteSink(const char* snapshot_file) : bytes_written_(0) {
+  explicit CppByteSink(const char* snapshot_file)
+      : bytes_written_(0),
+        partial_sink_(this) {
     fp_ = i::OS::FOpen(snapshot_file, "wb");
     if (fp_ == NULL) {
i::PrintF("Unable to write to snapshot file \"%s\"\n", snapshot_file);
@@ -111,22 +114,63 @@
   }

   virtual ~CppByteSink() {
-    if (fp_ != NULL) {
-      fprintf(fp_, "};\n\n");
-      fprintf(fp_, "int Snapshot::size_ = %d;\n\n", bytes_written_);
-      fprintf(fp_, "} }  // namespace v8::internal\n");
-      fclose(fp_);
+    fprintf(fp_, "const int Snapshot::size_ = %d;\n\n", bytes_written_);
+    fprintf(fp_, "} }  // namespace v8::internal\n");
+    fclose(fp_);
+  }
+
+  void WriteSpaceUsed(
+      int new_space_used,
+      int pointer_space_used,
+      int data_space_used,
+      int code_space_used,
+      int map_space_used,
+      int cell_space_used,
+      int large_space_used) {
+    fprintf(fp_, "};\n\n");
+ fprintf(fp_, "const int Snapshot::new_space_used_ = %d;\n", new_space_used);
+    fprintf(fp_,
+            "const int Snapshot::pointer_space_used_ = %d;\n",
+            pointer_space_used);
+    fprintf(fp_,
+            "const int Snapshot::data_space_used_ = %d;\n",
+            data_space_used);
+    fprintf(fp_,
+            "const int Snapshot::code_space_used_ = %d;\n",
+            code_space_used);
+ fprintf(fp_, "const int Snapshot::map_space_used_ = %d;\n", map_space_used);
+    fprintf(fp_,
+            "const int Snapshot::cell_space_used_ = %d;\n",
+            cell_space_used);
+    fprintf(fp_,
+            "const int Snapshot::large_space_used_ = %d;\n",
+            large_space_used);
+  }
+
+  void WritePartialSnapshot() {
+    int length = partial_sink_.Position();
+    fprintf(fp_, "};\n\n");
+    fprintf(fp_, "const int Snapshot::context_size_ = %d;\n",  length);
+    fprintf(fp_, "const byte Snapshot::context_data_[] = {\n");
+    for (int j = 0; j < length; j++) {
+      if ((j & 0x1f) == 0x1f) {
+        fprintf(fp_, "\n");
+      }
+      char byte = partial_sink_.at(j);
+      if (j != 0) {
+        fprintf(fp_, ",");
+      }
+      fprintf(fp_, "%d", byte);
     }
   }

   virtual void Put(int byte, const char* description) {
-    i::SerializerDeserializer::Trace("Put %s: %d\n", description, byte);
     if (bytes_written_ != 0) {
       fprintf(fp_, ",");
     }
     fprintf(fp_, "%d", byte);
     bytes_written_++;
-    if ((bytes_written_ & 0x3f) == 0) {
+    if ((bytes_written_ & 0x1f) == 0) {
       fprintf(fp_, "\n");
     }
   }
@@ -134,10 +178,29 @@
   virtual int Position() {
     return bytes_written_;
   }
+
+  i::SnapshotByteSink* partial_sink() { return &partial_sink_; }
+
+  class PartialSnapshotSink : public i::SnapshotByteSink {
+   public:
+    explicit PartialSnapshotSink(CppByteSink* parent)
+        : parent_(parent),
+          data_() { }
+    virtual ~PartialSnapshotSink() { data_.Free(); }
+    virtual void Put(int byte, const char* description) {
+      data_.Add(byte);
+    }
+    virtual int Position() { return data_.length(); }
+    char at(int i) { return data_[i]; }
+   private:
+    CppByteSink* parent_;
+    i::List<char> data_;
+  };

  private:
   FILE* fp_;
   int bytes_written_;
+  PartialSnapshotSink partial_sink_;
 };


@@ -163,12 +226,32 @@
       i::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 the context.
+  i::Heap::CollectAllGarbage(true);
+  i::AssertNoAllocation we_have_raw_pointers_here;
+  i::Object* raw_context = *(v8::Utils::OpenHandle(*context));
   context.Dispose();
   CppByteSink sink(argv[1]);
// This results in a somewhat smaller snapshot, probably because it gets rid
   // of some things that are cached between garbage collections.
-  i::Heap::CollectAllGarbage(true);
   i::StartupSerializer ser(&sink);
-  ser.Serialize();
+  ser.SerializeStrongReferences();
+
+  i::PartialSerializer partial_ser(&ser, sink.partial_sink());
+  partial_ser.Serialize(&raw_context);
+
+  ser.SerializeWeakReferences();
+
+  sink.WritePartialSnapshot();
+
+  sink.WriteSpaceUsed(
+      partial_ser.CurrentAllocationAddress(i::NEW_SPACE),
+      partial_ser.CurrentAllocationAddress(i::OLD_POINTER_SPACE),
+      partial_ser.CurrentAllocationAddress(i::OLD_DATA_SPACE),
+      partial_ser.CurrentAllocationAddress(i::CODE_SPACE),
+      partial_ser.CurrentAllocationAddress(i::MAP_SPACE),
+      partial_ser.CurrentAllocationAddress(i::CELL_SPACE),
+      partial_ser.CurrentAllocationAddress(i::LO_SPACE));
   return 0;
 }
=======================================
--- /branches/experimental/partial_snapshots/src/serialize.cc Wed Feb 3 04:58:31 2010 +++ /branches/experimental/partial_snapshots/src/serialize.cc Thu Feb 4 00:02:41 2010
@@ -665,7 +665,6 @@
                              Address address) {
   while (current < limit) {
     int data = source_->Get();
-    Trace("Tag", data);
     switch (data) {
 #define RAW_CASE(index, size)                                      \
       case RAW_DATA_SERIALIZATION + index: {                       \
@@ -1358,8 +1357,6 @@
   fullness_[space] = allocation_address + size;
   return allocation_address;
 }
-
-bool SerializerDeserializer::tracing_;


 } }  // namespace v8::internal
=======================================
--- /branches/experimental/partial_snapshots/src/serialize.h Wed Feb 3 04:58:31 2010 +++ /branches/experimental/partial_snapshots/src/serialize.h Thu Feb 4 00:02:41 2010
@@ -173,21 +173,6 @@
  public:
   static void Iterate(ObjectVisitor* visitor);
   static void SetSnapshotCacheSize(int size);
-#ifdef DEBUG
-  static void StartTracing() { tracing_ = true; }
-  static void StopTracing() { tracing_ = false; }
- static void Trace(const char *msg, int arg) { if (tracing_) printf("%s %d\n", msg, arg); } - static void Trace(const char *msg, const char* arg) { if (tracing_) printf("%s %s\n", msg, arg); } - static void Trace(const char *msg, const char* arg1, int arg2) { if (tracing_) printf("%s %s %d\n", msg, arg1, arg2); }
-  static bool tracing() { return tracing_; }
-#else
-  static void StartTracing() { }
-  static void StopTracing() { }
-  static void Trace(const char *msg, int arg) { }
-  static void Trace(const char *msg, const char* arg) { }
-  static void Trace(const char *msg, const char* arg1, int arg2) { }
-  static bool tracing() { return false; }
-#endif

  protected:
   enum DataType {
@@ -233,7 +218,6 @@
   static int partial_snapshot_cache_length_;
   static const int kPartialSnapshotCacheCapacity = 1300;
   static Object* partial_snapshot_cache_[];
-  static bool tracing_;
 };


@@ -241,18 +225,14 @@
   // A little unwind to catch the really small ints.
   int snapshot_byte = Get();
   if ((snapshot_byte & 0x80) == 0) {
-    SerializerDeserializer::Trace("Tag IntLastPart", snapshot_byte);
     return snapshot_byte;
   }
-  SerializerDeserializer::Trace("Tag IntPart", snapshot_byte);
   int accumulator = (snapshot_byte & 0x7f) << 7;
   while (true) {
     snapshot_byte = Get();
     if ((snapshot_byte & 0x80) == 0) {
-      SerializerDeserializer::Trace("Tag IntLastPart", snapshot_byte);
       return accumulator | snapshot_byte;
     }
-    SerializerDeserializer::Trace("Tag IntPart", snapshot_byte);
     accumulator = (accumulator | (snapshot_byte & 0x7f)) << 7;
   }
   UNREACHABLE();
@@ -261,11 +241,6 @@


 void SnapshotByteSource::CopyRaw(byte* to, int number_of_bytes) {
-  if (SerializerDeserializer::tracing()) {
-    for (int i = 0; i < number_of_bytes; i++) {
-      SerializerDeserializer::Trace("Tag Byte", data_[position_ + i]);
-    }
-  }
   memcpy(to, data_ + position_, number_of_bytes);
   position_ += number_of_bytes;
 }
=======================================
--- /branches/experimental/partial_snapshots/src/snapshot-common.cc Wed Jan 27 00:25:48 2010 +++ /branches/experimental/partial_snapshots/src/snapshot-common.cc Thu Feb 4 00:02:41 2010
@@ -58,5 +58,25 @@
   }
   return false;
 }
+
+
+Handle<Context> Snapshot::NewContextFromSnapshot() {
+  if (context_size_ == 0) {
+    return Handle<Context>();
+  }
+  Heap::ReserveSpace(new_space_used_,
+                     pointer_space_used_,
+                     data_space_used_,
+                     code_space_used_,
+                     map_space_used_,
+                     cell_space_used_,
+                     large_space_used_);
+  SnapshotByteSource source(context_data_, context_size_);
+  Deserializer deserializer(&source);
+  Object* root;
+  deserializer.DeserializePartial(&root);
+  CHECK(root->IsContext());
+  return Handle<Context>(Context::cast(root));
+}

 } }  // namespace v8::internal
=======================================
--- /branches/experimental/partial_snapshots/src/snapshot-empty.cc Mon May 25 03:05:56 2009 +++ /branches/experimental/partial_snapshots/src/snapshot-empty.cc Thu Feb 4 00:02:41 2010
@@ -35,6 +35,16 @@
 namespace internal {

 const byte Snapshot::data_[] = { 0 };
-int Snapshot::size_ = 0;
+const int Snapshot::size_ = 0;
+const byte Snapshot::context_data_[] = { 0 };
+const int Snapshot::context_size_ = 0;
+
+const int Snapshot::new_space_used_ = 0;
+const int Snapshot::pointer_space_used_ = 0;
+const int Snapshot::data_space_used_ = 0;
+const int Snapshot::code_space_used_ = 0;
+const int Snapshot::map_space_used_ = 0;
+const int Snapshot::cell_space_used_ = 0;
+const int Snapshot::large_space_used_ = 0;

 } }  // namespace v8::internal
=======================================
--- /branches/experimental/partial_snapshots/src/snapshot.h Mon Nov 16 04:08:40 2009 +++ /branches/experimental/partial_snapshots/src/snapshot.h Thu Feb 4 00:02:41 2010
@@ -38,6 +38,9 @@
   // could be found.
   static bool Initialize(const char* snapshot_file = NULL);

+  // Create a new context using the internal partial snapshot.
+  static Handle<Context> NewContextFromSnapshot();
+
   // Returns whether or not the snapshot is enabled.
   static bool IsEnabled() { return size_ != 0; }

@@ -47,7 +50,16 @@

  private:
   static const byte data_[];
-  static int size_;
+  static const byte context_data_[];
+  static const int new_space_used_;
+  static const int pointer_space_used_;
+  static const int data_space_used_;
+  static const int code_space_used_;
+  static const int map_space_used_;
+  static const int cell_space_used_;
+  static const int large_space_used_;
+  static const int size_;
+  static const int context_size_;

   static bool Deserialize(const byte* content, int len);

=======================================
--- /branches/experimental/partial_snapshots/src/v8-counters.h Wed Jan 27 03:08:32 2010 +++ /branches/experimental/partial_snapshots/src/v8-counters.h Thu Feb 4 00:02:41 2010
@@ -97,7 +97,12 @@
   /* Amount of source code compiled with the old codegen. */          \
   SC(total_old_codegen_source_size, V8.TotalOldCodegenSourceSize)     \
   /* Amount of source code compiled with the full codegen. */         \
-  SC(total_full_codegen_source_size, V8.TotalFullCodegenSourceSize)
+  SC(total_full_codegen_source_size, V8.TotalFullCodegenSourceSize)   \
+  /* Number of contexts created from scratch. */                      \
+  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/src/v8threads.cc Wed Feb 3 02:52:22 2010 +++ /branches/experimental/partial_snapshots/src/v8threads.cc Thu Feb 4 00:02:41 2010
@@ -156,7 +156,6 @@
     return false;
   }
   char* from = state->data();
-  printf("Restore from %p\n", (void*)state->data());
   from = HandleScopeImplementer::RestoreThread(from);
   from = Top::RestoreThread(from);
   from = Relocatable::RestoreState(from);
@@ -285,7 +284,6 @@
 void ThreadManager::EagerlyArchiveThread() {
   ThreadState* state = lazily_archived_thread_state_;
   state->LinkInto(ThreadState::IN_USE_LIST);
-  printf("Archive into %p\n", (void*)state->data());
   char* to = state->data();
// Ensure that data containing GC roots are archived first, and handle them
   // in ThreadManager::Iterate(ObjectVisitor*).
@@ -326,7 +324,6 @@
        state != NULL;
        state = state->Next()) {
     char* data = state->data();
-    printf("Iterate over %p\n", (void*)state->data());
     data = HandleScopeImplementer::Iterate(v, data);
     data = Top::Iterate(v, data);
     data = Relocatable::Iterate(v, data);
@@ -339,7 +336,6 @@
        state != NULL;
        state = state->Next()) {
     char* data = state->data();
-    printf("Mark compact prologue %p\n", (void*)state->data());
     data += HandleScopeImplementer::ArchiveSpacePerThread();
     Top::MarkCompactPrologue(is_compacting, data);
   }
@@ -351,7 +347,6 @@
        state != NULL;
        state = state->Next()) {
     char* data = state->data();
-    printf("Mark compact epilogue %p\n", (void*)state->data());
     data += HandleScopeImplementer::ArchiveSpacePerThread();
     Top::MarkCompactEpilogue(is_compacting, data);
   }
=======================================
--- /branches/experimental/partial_snapshots/test/cctest/test-serialize.cc Wed Feb 3 04:58:31 2010 +++ /branches/experimental/partial_snapshots/test/cctest/test-serialize.cc Thu Feb 4 00:02:41 2010
@@ -187,7 +187,6 @@
     }
   }
   virtual void Put(int byte, const char* description) {
-    SerializerDeserializer::Trace("Tag", description, byte);
     if (fp_ != NULL) {
       fputc(byte, fp_);
     }

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

Reply via email to