Revision: 3619
Author: [email protected]
Date: Fri Jan 15 06:20:31 2010
Log: Implement enough of the partial snapshots that we can deserialize
a single string.
Review URL: http://codereview.chromium.org/536077
http://code.google.com/p/v8/source/detail?r=3619

Modified:
 /branches/bleeding_edge/src/serialize.cc
 /branches/bleeding_edge/src/serialize.h
 /branches/bleeding_edge/src/v8.cc
 /branches/bleeding_edge/test/cctest/test-serialize.cc

=======================================
--- /branches/bleeding_edge/src/serialize.cc    Fri Jan 15 04:25:24 2010
+++ /branches/bleeding_edge/src/serialize.cc    Fri Jan 15 06:20:31 2010
@@ -554,11 +554,10 @@

 bool Serializer::serialization_enabled_ = false;
 bool Serializer::too_late_to_enable_now_ = false;
+ExternalReferenceDecoder* Deserializer::external_reference_decoder_ = NULL;


-Deserializer::Deserializer(SnapshotByteSource* source)
-    : source_(source),
-      external_reference_decoder_(NULL) {
+Deserializer::Deserializer(SnapshotByteSource* source) : source_(source) {
 }


@@ -648,8 +647,26 @@
   external_reference_decoder_ = new ExternalReferenceDecoder();
   Heap::IterateRoots(this, VISIT_ONLY_STRONG);
   ASSERT(source_->AtEOF());
-  delete external_reference_decoder_;
-  external_reference_decoder_ = NULL;
+}
+
+
+void Deserializer::DeserializePartial(Object** root) {
+  // Don't GC while deserializing - just expand the heap.
+  AlwaysAllocateScope always_allocate;
+  // Don't use the free lists while deserializing.
+  LinearAllocationScope allocate_linearly;
+  if (external_reference_decoder_ == NULL) {
+    external_reference_decoder_ = new ExternalReferenceDecoder();
+  }
+  VisitPointer(root);
+}
+
+
+void Deserializer::TearDown() {
+  if (external_reference_decoder_ != NULL) {
+    delete external_reference_decoder_;
+    external_reference_decoder_ = NULL;
+  }
 }


@@ -862,6 +879,11 @@
         *current++ = reinterpret_cast<Object*>(resource);
         break;
       }
+      case ROOT_SERIALIZATION: {
+        int root_id = source_->GetInt();
+        *current++ = Heap::roots_address()[root_id];
+        break;
+      }
       default:
         UNREACHABLE();
     }
@@ -915,7 +937,8 @@
     : sink_(sink),
       current_root_index_(0),
       external_reference_encoder_(NULL),
-      partial_(false) {
+      partial_(false),
+      large_object_total_(0) {
   for (int i = 0; i <= LAST_SPACE; i++) {
     fullness_[i] = 0;
   }
@@ -1226,6 +1249,7 @@
// In large object space we merely number the objects instead of trying to
     // determine some sort of address.
     *new_page = true;
+    large_object_total_ += size;
     return fullness_[LO_SPACE]++;
   }
   *new_page = false;
=======================================
--- /branches/bleeding_edge/src/serialize.h     Tue Jan 12 07:16:23 2010
+++ /branches/bleeding_edge/src/serialize.h     Fri Jan 15 06:20:31 2010
@@ -239,10 +239,16 @@

   // Deserialize the snapshot into an empty heap.
   void Deserialize();
+
+  // Deserialize a single object and the objects reachable from it.
+  void DeserializePartial(Object** root);
+
 #ifdef DEBUG
   virtual void Synchronize(const char* tag);
 #endif

+  static void TearDown();
+
  private:
   virtual void VisitPointers(Object** start, Object** end);

@@ -267,7 +273,7 @@
   List<Address> pages_[SerDes::kNumberOfSpaces];

   SnapshotByteSource* source_;
-  ExternalReferenceDecoder* external_reference_decoder_;
+  static ExternalReferenceDecoder* external_reference_decoder_;
   // This is the address of the next object that will be allocated in each
   // space.  It is used to calculate the addresses of back-references.
   Address high_water_[LAST_SPACE + 1];
@@ -302,7 +308,7 @@
// You can call this after serialization to find out how much space was used
   // in each space.
   int CurrentAllocationAddress(int space) {
-    if (SpaceIsLarge(space)) space = LO_SPACE;
+    if (SpaceIsLarge(space)) return large_object_total_;
     return fullness_[space];
   }

@@ -392,6 +398,7 @@
   static bool serialization_enabled_;
// Did we already make use of the fact that serialization was not enabled?
   static bool too_late_to_enable_now_;
+  int large_object_total_;

   friend class ObjectSerializer;
   friend class Deserializer;
=======================================
--- /branches/bleeding_edge/src/v8.cc   Fri Nov 20 04:38:59 2009
+++ /branches/bleeding_edge/src/v8.cc   Fri Jan 15 06:20:31 2010
@@ -146,6 +146,7 @@

   Heap::TearDown();
   Logger::TearDown();
+  Deserializer::TearDown();

   is_running_ = false;
   has_been_disposed_ = true;
=======================================
--- /branches/bleeding_edge/test/cctest/test-serialize.cc Fri Jan 15 04:25:24 2010 +++ /branches/bleeding_edge/test/cctest/test-serialize.cc Fri Jan 15 06:20:31 2010
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 the V8 project authors. All rights reserved.
+// Copyright 2007-2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -277,6 +277,7 @@
  public:
   explicit FileByteSink(const char* snapshot_file) {
     fp_ = OS::FOpen(snapshot_file, "wb");
+    file_name_ = snapshot_file;
     if (fp_ == NULL) {
       PrintF("Unable to write to snapshot file \"%s\"\n", snapshot_file);
       exit(1);
@@ -292,10 +293,42 @@
       fputc(byte, 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);

  private:
   FILE* fp_;
+  const char* file_name_;
 };
+
+
+void FileByteSink::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) {
+  int file_name_length = strlen(file_name_) + 10;
+  Vector<char> name = Vector<char>::New(file_name_length + 1);
+  OS::SNPrintF(name, "%s.size", file_name_);
+  FILE* fp = OS::FOpen(name.start(), "wa");
+  fprintf(fp, "new %d\n", new_space_used);
+  fprintf(fp, "pointer %d\n", pointer_space_used);
+  fprintf(fp, "data %d\n", data_space_used);
+  fprintf(fp, "code %d\n", code_space_used);
+  fprintf(fp, "map %d\n", map_space_used);
+  fprintf(fp, "cell %d\n", cell_space_used);
+  fprintf(fp, "large %d\n", large_space_used);
+  fclose(fp);
+}


 TEST(PartialSerialization) {
@@ -312,6 +345,47 @@
   i::Handle<i::String> internal_foo = v8::Utils::OpenHandle(*foo);
   Object* raw_foo = *internal_foo;
   ser.SerializePartial(&raw_foo);
+  file.WriteSpaceUsed(ser.CurrentAllocationAddress(NEW_SPACE),
+                      ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
+                      ser.CurrentAllocationAddress(OLD_DATA_SPACE),
+                      ser.CurrentAllocationAddress(CODE_SPACE),
+                      ser.CurrentAllocationAddress(MAP_SPACE),
+                      ser.CurrentAllocationAddress(CELL_SPACE),
+                      ser.CurrentAllocationAddress(LO_SPACE));
+}
+
+
+DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
+  v8::V8::Initialize();
+  const char* file_name = FLAG_testing_serialization_file;
+  int file_name_length = strlen(file_name) + 10;
+  Vector<char> name = Vector<char>::New(file_name_length + 1);
+  OS::SNPrintF(name, "%s.size", file_name);
+  FILE* fp = OS::FOpen(name.start(), "ra");
+  int new_size, pointer_size, data_size, code_size, map_size, cell_size;
+  int large_size;
+  CHECK_EQ(1, fscanf(fp, "new %d\n", &new_size));
+  CHECK_EQ(1, fscanf(fp, "pointer %d\n", &pointer_size));
+  CHECK_EQ(1, fscanf(fp, "data %d\n", &data_size));
+  CHECK_EQ(1, fscanf(fp, "code %d\n", &code_size));
+  CHECK_EQ(1, fscanf(fp, "map %d\n", &map_size));
+  CHECK_EQ(1, fscanf(fp, "cell %d\n", &cell_size));
+  CHECK_EQ(1, fscanf(fp, "large %d\n", &large_size));
+  fclose(fp);
+  Heap::ReserveSpace(new_size,
+                     pointer_size,
+                     data_size,
+                     code_size,
+                     map_size,
+                     cell_size,
+                     large_size);
+  int snapshot_size = 0;
+  byte* snapshot = ReadBytes(file_name, &snapshot_size);
+  SnapshotByteSource source(snapshot, snapshot_size);
+  Deserializer deserializer(&source);
+  Object* root;
+  deserializer.DeserializePartial(&root);
+  CHECK(root->IsString());
 }


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

Reply via email to