* Remove old snapshot implementation
authorerik.corry@gmail.com <erik.corry@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 16 Nov 2009 12:08:40 +0000 (12:08 +0000)
committererik.corry@gmail.com <erik.corry@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 16 Nov 2009 12:08:40 +0000 (12:08 +0000)
Review URL: http://codereview.chromium.org/394007

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3307 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

13 files changed:
src/api.cc
src/assembler.h
src/checks.cc
src/globals.h
src/mksnapshot.cc
src/serialize.cc
src/serialize.h
src/snapshot-common.cc
src/snapshot.h
src/v8.cc
src/v8.h
test/cctest/cctest.status
test/cctest/test-serialize.cc

index 00b590f..f631bfd 100644 (file)
@@ -2636,11 +2636,7 @@ bool v8::V8::Initialize() {
   if (i::V8::IsRunning()) return true;
   ENTER_V8;
   HandleScope scope;
-  if (i::FLAG_new_snapshot) {
-    if (i::Snapshot::Initialize2()) return true;
-  } else {
-    if (i::Snapshot::Initialize()) return true;
-  }
+  if (i::Snapshot::Initialize()) return true;
   return i::V8::Initialize(NULL);
 }
 
index 434e3bc..aecd4cd 100644 (file)
@@ -471,12 +471,16 @@ class ExternalReference BASE_EMBEDDED {
 
   static void* Redirect(void* address, bool fp_return = false) {
     if (redirector_ == NULL) return address;
-    return (*redirector_)(address, fp_return);
+    void* answer = (*redirector_)(address, fp_return);
+    return answer;
   }
 
   static void* Redirect(Address address_arg, bool fp_return = false) {
     void* address = reinterpret_cast<void*>(address_arg);
-    return redirector_ == NULL ? address : (*redirector_)(address, fp_return);
+    void* answer = (redirector_ == NULL) ?
+                   address :
+                   (*redirector_)(address, fp_return);
+    return answer;
   }
 
   void* address_;
index f8a2f24..b5df316 100644 (file)
@@ -36,6 +36,8 @@ static int fatal_error_handler_nesting_depth = 0;
 
 // Contains protection against recursive calls (faults while handling faults).
 extern "C" void V8_Fatal(const char* file, int line, const char* format, ...) {
+  fflush(stdout);
+  fflush(stderr);
   fatal_error_handler_nesting_depth++;
   // First time we try to print an error message
   if (fatal_error_handler_nesting_depth < 2) {
index a1974fc..ad0539f 100644 (file)
@@ -252,7 +252,6 @@ class Variable;
 class VariableProxy;
 class RelocInfo;
 class Deserializer;
-class GenericDeserializer;  // TODO(erikcorry): Get rid of this.
 class MessageLocation;
 class ObjectGroup;
 class TickSample;
index f9dbd5c..eb743f8 100644 (file)
@@ -87,27 +87,12 @@ class CounterCollection {
 // We statically allocate a set of local counters to be used if we
 // don't want to store the stats in a memory-mapped file
 static CounterCollection local_counters;
-static CounterCollection* counters = &local_counters;
 
 
 typedef std::map<std::string, int*> CounterMap;
 typedef std::map<std::string, int*>::iterator CounterMapIterator;
 static CounterMap counter_table_;
 
-// Callback receiver when v8 has a counter to track.
-static int* counter_callback(const char* name) {
-  std::string counter = name;
-  // See if this counter name is already known.
-  if (counter_table_.find(counter) != counter_table_.end())
-    return counter_table_[counter];
-
-  Counter* ctr = counters->GetNextCounter();
-  if (ctr == NULL) return NULL;
-  int* ptr = ctr->Bind(name);
-  counter_table_[counter] = ptr;
-  return ptr;
-}
-
 
 class CppByteSink : public i::SnapshotByteSink {
  public:
@@ -151,57 +136,6 @@ class CppByteSink : public i::SnapshotByteSink {
 };
 
 
-// Write C++ code that defines Snapshot::snapshot_ to contain the snapshot
-// to the file given by filename. Only the first size chars are written.
-static int WriteInternalSnapshotToFile(const char* filename,
-                                       const v8::internal::byte* bytes,
-                                       int size) {
-  FILE* f = i::OS::FOpen(filename, "wb");
-  if (f == NULL) {
-    i::OS::PrintError("Cannot open file %s for writing.\n", filename);
-    return 0;
-  }
-  fprintf(f, "// Autogenerated snapshot file. Do not edit.\n\n");
-  fprintf(f, "#include \"v8.h\"\n");
-  fprintf(f, "#include \"platform.h\"\n\n");
-  fprintf(f, "#include \"snapshot.h\"\n\n");
-  fprintf(f, "namespace v8 {\nnamespace internal {\n\n");
-  fprintf(f, "const byte Snapshot::data_[] = {");
-  int written = 0;
-  written += fprintf(f, "0x%x", bytes[0]);
-  for (int i = 1; i < size; ++i) {
-    written += fprintf(f, ",0x%x", bytes[i]);
-    // The following is needed to keep the line length low on Visual C++:
-    if (i % 512 == 0) fprintf(f, "\n");
-  }
-  fprintf(f, "};\n\n");
-  fprintf(f, "int Snapshot::size_ = %d;\n\n", size);
-  fprintf(f, "} }  // namespace v8::internal\n");
-  fclose(f);
-  return written;
-}
-
-
-int main2(int argc, char** argv) {
-  i::Serializer::Enable();
-  Persistent<Context> context = v8::Context::New();
-  // Make sure all builtin scripts are cached.
-  { HandleScope scope;
-    for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) {
-      i::Bootstrapper::NativesSourceLookup(i);
-    }
-  }
-  context.Dispose();
-  CppByteSink sink(argv[1]);
-  i::Serializer2 ser(&sink);
-  // 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);
-  ser.Serialize();
-  return 0;
-}
-
-
 int main(int argc, char** argv) {
 #ifdef ENABLE_LOGGING_AND_PROFILING
   // By default, log code create information in the snapshot.
@@ -215,38 +149,20 @@ int main(int argc, char** argv) {
     i::FlagList::PrintHelp();
     return !i::FLAG_help;
   }
-
-  if (i::FLAG_new_snapshot) {
-    return main2(argc, argv);
-  }
-
-  v8::V8::SetCounterFunction(counter_callback);
-  v8::HandleScope scope;
-
-  const int kExtensionCount = 1;
-  const char* extension_list[kExtensionCount] = { "v8/gc" };
-  v8::ExtensionConfiguration extensions(kExtensionCount, extension_list);
-
   i::Serializer::Enable();
-  v8::Context::New(&extensions);
-
+  Persistent<Context> context = v8::Context::New();
   // Make sure all builtin scripts are cached.
   { HandleScope scope;
     for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) {
       i::Bootstrapper::NativesSourceLookup(i);
     }
   }
-  // Get rid of unreferenced scripts with a global GC.
-  i::Heap::CollectAllGarbage(false);
-  i::Serializer ser;
+  context.Dispose();
+  CppByteSink sink(argv[1]);
+  i::Serializer ser(&sink);
+  // 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);
   ser.Serialize();
-  v8::internal::byte* bytes;
-  int len;
-  ser.Finalize(&bytes, &len);
-
-  WriteInternalSnapshotToFile(argv[1], bytes, len);
-
-  i::DeleteArray(bytes);
-
   return 0;
 }
index 858f4c0..de87022 100644 (file)
 namespace v8 {
 namespace internal {
 
-// 32-bit encoding: a RelativeAddress must be able to fit in a
-// pointer: it is encoded as an Address with (from LS to MS bits):
-// - 2 bits identifying this as a HeapObject.
-// - 4 bits to encode the AllocationSpace (including special values for
-//   code and fixed arrays in LO space)
-// - 27 bits identifying a word in the space, in one of three formats:
-// - paged spaces: 16 bits of page number, 11 bits of word offset in page
-// - NEW space:    27 bits of word offset
-// - LO space:     27 bits of page number
-
-const int kSpaceShift = kHeapObjectTagSize;
-const int kSpaceBits = 4;
-const int kSpaceMask = (1 << kSpaceBits) - 1;
-
-const int kOffsetShift = kSpaceShift + kSpaceBits;
-const int kOffsetBits = 11;
-const int kOffsetMask = (1 << kOffsetBits) - 1;
-
-const int kPageShift = kOffsetShift + kOffsetBits;
-const int kPageBits = 32 - (kOffsetBits + kSpaceBits + kHeapObjectTagSize);
-const int kPageMask = (1 << kPageBits) - 1;
-
-const int kPageAndOffsetShift = kOffsetShift;
-const int kPageAndOffsetBits = kPageBits + kOffsetBits;
-const int kPageAndOffsetMask = (1 << kPageAndOffsetBits) - 1;
-
-// These values are special allocation space tags used for
-// serialization.
-// Mark the pages executable on platforms that support it.
-const int kLargeCode = LAST_SPACE + 1;
-// Allocate extra remembered-set bits.
-const int kLargeFixedArray = LAST_SPACE + 2;
-
-
-static inline AllocationSpace GetSpace(Address addr) {
-  const intptr_t encoded = reinterpret_cast<intptr_t>(addr);
-  int space_number = (static_cast<int>(encoded >> kSpaceShift) & kSpaceMask);
-  if (space_number > LAST_SPACE) space_number = LO_SPACE;
-  return static_cast<AllocationSpace>(space_number);
-}
-
-
-static inline bool IsLargeExecutableObject(Address addr) {
-  const intptr_t encoded = reinterpret_cast<intptr_t>(addr);
-  const int space_number =
-      (static_cast<int>(encoded >> kSpaceShift) & kSpaceMask);
-  return (space_number == kLargeCode);
-}
-
-
-static inline bool IsLargeFixedArray(Address addr) {
-  const intptr_t encoded = reinterpret_cast<intptr_t>(addr);
-  const int space_number =
-      (static_cast<int>(encoded >> kSpaceShift) & kSpaceMask);
-  return (space_number == kLargeFixedArray);
-}
-
-
-static inline int PageIndex(Address addr) {
-  const intptr_t encoded = reinterpret_cast<intptr_t>(addr);
-  return static_cast<int>(encoded >> kPageShift) & kPageMask;
-}
-
-
-static inline int PageOffset(Address addr) {
-  const intptr_t encoded = reinterpret_cast<intptr_t>(addr);
-  const int offset = static_cast<int>(encoded >> kOffsetShift) & kOffsetMask;
-  return offset << kObjectAlignmentBits;
-}
-
-
-static inline int NewSpaceOffset(Address addr) {
-  const intptr_t encoded = reinterpret_cast<intptr_t>(addr);
-  const int page_offset =
-      static_cast<int>(encoded >> kPageAndOffsetShift) & kPageAndOffsetMask;
-  return page_offset << kObjectAlignmentBits;
-}
-
-
-static inline int LargeObjectIndex(Address addr) {
-  const intptr_t encoded = reinterpret_cast<intptr_t>(addr);
-  return static_cast<int>(encoded >> kPageAndOffsetShift) & kPageAndOffsetMask;
-}
-
-
-// A RelativeAddress encodes a heap address that is independent of
-// the actual memory addresses in real heap. The general case (for the
-// OLD, CODE and MAP spaces) is as a (space id, page number, page offset)
-// triple. The NEW space has page number == 0, because there are no
-// pages. The LARGE_OBJECT space has page offset = 0, since there is
-// exactly one object per page.  RelativeAddresses are encodable as
-// Addresses, so that they can replace the map() pointers of
-// HeapObjects. The encoded Addresses are also encoded as HeapObjects
-// and allow for marking (is_marked() see mark(), clear_mark()...) as
-// used by the Mark-Compact collector.
-
-class RelativeAddress {
- public:
-  RelativeAddress(AllocationSpace space,
-                  int page_index,
-                  int page_offset)
-  : space_(space), page_index_(page_index), page_offset_(page_offset)  {
-    // Assert that the space encoding (plus the two pseudo-spaces for
-    // special large objects) fits in the available bits.
-    ASSERT(((LAST_SPACE + 2) & ~kSpaceMask) == 0);
-    ASSERT(space <= LAST_SPACE && space >= 0);
-  }
-
-  // Return the encoding of 'this' as an Address. Decode with constructor.
-  Address Encode() const;
-
-  AllocationSpace space() const {
-    if (space_ > LAST_SPACE) return LO_SPACE;
-    return static_cast<AllocationSpace>(space_);
-  }
-  int page_index() const { return page_index_; }
-  int page_offset() const { return page_offset_; }
-
-  bool in_paged_space() const {
-    return space_ == CODE_SPACE ||
-           space_ == OLD_POINTER_SPACE ||
-           space_ == OLD_DATA_SPACE ||
-           space_ == MAP_SPACE ||
-           space_ == CELL_SPACE;
-  }
-
-  void next_address(int offset) { page_offset_ += offset; }
-  void next_page(int init_offset = 0) {
-    page_index_++;
-    page_offset_ = init_offset;
-  }
-
-#ifdef DEBUG
-  void Verify();
-#endif
-
-  void set_to_large_code_object() {
-    ASSERT(space_ == LO_SPACE);
-    space_ = kLargeCode;
-  }
-  void set_to_large_fixed_array() {
-    ASSERT(space_ == LO_SPACE);
-    space_ = kLargeFixedArray;
-  }
-
-
- private:
-  int space_;
-  int page_index_;
-  int page_offset_;
-};
-
-
-Address RelativeAddress::Encode() const {
-  ASSERT(page_index_ >= 0);
-  int word_offset = 0;
-  int result = 0;
-  switch (space_) {
-    case MAP_SPACE:
-    case CELL_SPACE:
-    case OLD_POINTER_SPACE:
-    case OLD_DATA_SPACE:
-    case CODE_SPACE:
-      ASSERT_EQ(0, page_index_ & ~kPageMask);
-      word_offset = page_offset_ >> kObjectAlignmentBits;
-      ASSERT_EQ(0, word_offset & ~kOffsetMask);
-      result = (page_index_ << kPageShift) | (word_offset << kOffsetShift);
-      break;
-    case NEW_SPACE:
-      ASSERT_EQ(0, page_index_);
-      word_offset = page_offset_ >> kObjectAlignmentBits;
-      ASSERT_EQ(0, word_offset & ~kPageAndOffsetMask);
-      result = word_offset << kPageAndOffsetShift;
-      break;
-    case LO_SPACE:
-    case kLargeCode:
-    case kLargeFixedArray:
-      ASSERT_EQ(0, page_offset_);
-      ASSERT_EQ(0, page_index_ & ~kPageAndOffsetMask);
-      result = page_index_ << kPageAndOffsetShift;
-      break;
-  }
-  // OR in AllocationSpace and kHeapObjectTag
-  ASSERT_EQ(0, space_ & ~kSpaceMask);
-  result |= (space_ << kSpaceShift) | kHeapObjectTag;
-  return reinterpret_cast<Address>(result);
-}
-
-
-#ifdef DEBUG
-void RelativeAddress::Verify() {
-  ASSERT(page_offset_ >= 0 && page_index_ >= 0);
-  switch (space_) {
-    case MAP_SPACE:
-    case CELL_SPACE:
-    case OLD_POINTER_SPACE:
-    case OLD_DATA_SPACE:
-    case CODE_SPACE:
-      ASSERT(Page::kObjectStartOffset <= page_offset_ &&
-             page_offset_ <= Page::kPageSize);
-      break;
-    case NEW_SPACE:
-      ASSERT(page_index_ == 0);
-      break;
-    case LO_SPACE:
-    case kLargeCode:
-    case kLargeFixedArray:
-      ASSERT(page_offset_ == 0);
-      break;
-  }
-}
-#endif
-
-enum GCTreatment {
-  DataObject,     // Object that cannot contain a reference to new space.
-  PointerObject,  // Object that can contain a reference to new space.
-  CodeObject      // Object that contains executable code.
-};
-
-// A SimulatedHeapSpace simulates the allocation of objects in a page in
-// the heap. It uses linear allocation - that is, it doesn't simulate the
-// use of a free list. This simulated
-// allocation must exactly match that done by Heap.
-
-class SimulatedHeapSpace {
- public:
-  // The default constructor initializes to an invalid state.
-  SimulatedHeapSpace(): current_(LAST_SPACE, -1, -1) {}
-
-  // Sets 'this' to the first address in 'space' that would be
-  // returned by allocation in an empty heap.
-  void InitEmptyHeap(AllocationSpace space);
-
-  // Sets 'this' to the next address in 'space' that would be returned
-  // by allocation in the current heap. Intended only for testing
-  // serialization and deserialization in the current address space.
-  void InitCurrentHeap(AllocationSpace space);
-
-  // Returns the RelativeAddress where the next
-  // object of 'size' bytes will be allocated, and updates 'this' to
-  // point to the next free address beyond that object.
-  RelativeAddress Allocate(int size, GCTreatment special_gc_treatment);
-
- private:
-  RelativeAddress current_;
-};
-
-
-void SimulatedHeapSpace::InitEmptyHeap(AllocationSpace space) {
-  switch (space) {
-    case MAP_SPACE:
-    case CELL_SPACE:
-    case OLD_POINTER_SPACE:
-    case OLD_DATA_SPACE:
-    case CODE_SPACE:
-      current_ = RelativeAddress(space, 0, Page::kObjectStartOffset);
-      break;
-    case NEW_SPACE:
-    case LO_SPACE:
-      current_ = RelativeAddress(space, 0, 0);
-      break;
-  }
-}
-
-
-void SimulatedHeapSpace::InitCurrentHeap(AllocationSpace space) {
-  switch (space) {
-    case MAP_SPACE:
-    case CELL_SPACE:
-    case OLD_POINTER_SPACE:
-    case OLD_DATA_SPACE:
-    case CODE_SPACE: {
-      PagedSpace* ps;
-      if (space == MAP_SPACE) {
-        ps = Heap::map_space();
-      } else if (space == CELL_SPACE) {
-        ps = Heap::cell_space();
-      } else if (space == OLD_POINTER_SPACE) {
-        ps = Heap::old_pointer_space();
-      } else if (space == OLD_DATA_SPACE) {
-        ps = Heap::old_data_space();
-      } else {
-        ASSERT(space == CODE_SPACE);
-        ps = Heap::code_space();
-      }
-      Address top = ps->top();
-      Page* top_page = Page::FromAllocationTop(top);
-      int page_index = 0;
-      PageIterator it(ps, PageIterator::PAGES_IN_USE);
-      while (it.has_next()) {
-        if (it.next() == top_page) break;
-        page_index++;
-      }
-      current_ = RelativeAddress(space,
-                                 page_index,
-                                 top_page->Offset(top));
-      break;
-    }
-    case NEW_SPACE:
-      current_ = RelativeAddress(space,
-                                 0,
-                                 static_cast<int>(Heap::NewSpaceTop()
-                                     - Heap::NewSpaceStart()));
-      break;
-    case LO_SPACE:
-      int page_index = 0;
-      for (LargeObjectIterator it(Heap::lo_space()); it.has_next(); it.next()) {
-        page_index++;
-      }
-      current_ = RelativeAddress(space, page_index, 0);
-      break;
-  }
-}
-
-
-RelativeAddress SimulatedHeapSpace::Allocate(int size,
-                                             GCTreatment special_gc_treatment) {
-#ifdef DEBUG
-  current_.Verify();
-#endif
-  int alloc_size = OBJECT_SIZE_ALIGN(size);
-  if (current_.in_paged_space() &&
-      current_.page_offset() + alloc_size > Page::kPageSize) {
-    ASSERT(alloc_size <= Page::kMaxHeapObjectSize);
-    current_.next_page(Page::kObjectStartOffset);
-  }
-  RelativeAddress result = current_;
-  if (current_.space() == LO_SPACE) {
-    current_.next_page();
-    if (special_gc_treatment == CodeObject) {
-      result.set_to_large_code_object();
-    } else if (special_gc_treatment == PointerObject) {
-      result.set_to_large_fixed_array();
-    }
-  } else {
-    current_.next_address(alloc_size);
-  }
-#ifdef DEBUG
-  current_.Verify();
-  result.Verify();
-#endif
-  return result;
-}
-
 // -----------------------------------------------------------------------------
 // Coding of external references.
 
@@ -491,12 +147,12 @@ void ExternalReferenceTable::Add(Address address,
                                  TypeCode type,
                                  uint16_t id,
                                  const char* name) {
-  CHECK_NE(NULL, address);
+  ASSERT_NE(NULL, address);
   ExternalReferenceEntry entry;
   entry.address = address;
   entry.code = EncodeExternal(type, id);
   entry.name = name;
-  CHECK_NE(0, entry.code);
+  ASSERT_NE(0, entry.code);
   refs_.Add(entry);
   if (id > max_id_[type]) max_id_[type] = id;
 }
@@ -829,953 +485,11 @@ ExternalReferenceDecoder::~ExternalReferenceDecoder() {
 }
 
 
-//------------------------------------------------------------------------------
-// Implementation of Serializer
-
-
-// Helper class to write the bytes of the serialized heap.
-
-class SnapshotWriter {
- public:
-  SnapshotWriter() {
-    len_ = 0;
-    max_ = 8 << 10;  // 8K initial size
-    str_ = NewArray<byte>(max_);
-  }
-
-  ~SnapshotWriter() {
-    DeleteArray(str_);
-  }
-
-  void GetBytes(byte** str, int* len) {
-    *str = NewArray<byte>(len_);
-    memcpy(*str, str_, len_);
-    *len = len_;
-  }
-
-  void Reserve(int bytes, int pos);
-
-  void PutC(char c) {
-    InsertC(c, len_);
-  }
-
-  void PutInt(int i) {
-    InsertInt(i, len_);
-  }
-
-  void PutAddress(Address p) {
-    PutBytes(reinterpret_cast<byte*>(&p), sizeof(p));
-  }
-
-  void PutBytes(const byte* a, int size) {
-    InsertBytes(a, len_, size);
-  }
-
-  void PutString(const char* s) {
-    InsertString(s, len_);
-  }
-
-  int InsertC(char c, int pos) {
-    Reserve(1, pos);
-    str_[pos] = c;
-    len_++;
-    return pos + 1;
-  }
-
-  int InsertInt(int i, int pos) {
-    return InsertBytes(reinterpret_cast<byte*>(&i), pos, sizeof(i));
-  }
-
-  int InsertBytes(const byte* a, int pos, int size) {
-    Reserve(size, pos);
-    memcpy(&str_[pos], a, size);
-    len_ += size;
-    return pos + size;
-  }
-
-  int InsertString(const char* s, int pos);
-
-  int length() { return len_; }
-
-  Address position() { return reinterpret_cast<Address>(&str_[len_]); }
-
- private:
-  byte* str_;  // the snapshot
-  int len_;   // the current length of str_
-  int max_;   // the allocated size of str_
-};
-
-
-void SnapshotWriter::Reserve(int bytes, int pos) {
-  CHECK(0 <= pos && pos <= len_);
-  while (len_ + bytes >= max_) {
-    max_ *= 2;
-    byte* old = str_;
-    str_ = NewArray<byte>(max_);
-    memcpy(str_, old, len_);
-    DeleteArray(old);
-  }
-  if (pos < len_) {
-    byte* old = str_;
-    str_ = NewArray<byte>(max_);
-    memcpy(str_, old, pos);
-    memcpy(str_ + pos + bytes, old + pos, len_ - pos);
-    DeleteArray(old);
-  }
-}
-
-int SnapshotWriter::InsertString(const char* s, int pos) {
-  int size = StrLength(s);
-  pos = InsertC('[', pos);
-  pos = InsertInt(size, pos);
-  pos = InsertC(']', pos);
-  return InsertBytes(reinterpret_cast<const byte*>(s), pos, size);
-}
-
-
-class ReferenceUpdater: public ObjectVisitor {
- public:
-  ReferenceUpdater(HeapObject* obj, Serializer* serializer)
-    : obj_address_(obj->address()),
-      serializer_(serializer),
-      reference_encoder_(serializer->reference_encoder_),
-      offsets_(8),
-      addresses_(8),
-      offsets_32_bit_(0),
-      data_32_bit_(0) {
-  }
-
-  virtual void VisitPointers(Object** start, Object** end) {
-    for (Object** p = start; p < end; ++p) {
-      if ((*p)->IsHeapObject()) {
-        offsets_.Add(
-            static_cast<int>(reinterpret_cast<Address>(p) - obj_address_));
-        Address a = serializer_->GetSavedAddress(HeapObject::cast(*p));
-        addresses_.Add(a);
-      }
-    }
-  }
-
-  virtual void VisitCodeTarget(RelocInfo* rinfo) {
-    ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
-    Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
-    Address encoded_target = serializer_->GetSavedAddress(target);
-    // All calls and jumps are to code objects that encode into 32 bits.
-    offsets_32_bit_.Add(
-        static_cast<int>(rinfo->target_address_address() - obj_address_));
-    uint32_t small_target =
-        static_cast<uint32_t>(reinterpret_cast<uintptr_t>(encoded_target));
-    ASSERT(reinterpret_cast<uintptr_t>(encoded_target) == small_target);
-    data_32_bit_.Add(small_target);
-  }
-
-
-  virtual void VisitExternalReferences(Address* start, Address* end) {
-    for (Address* p = start; p < end; ++p) {
-      uint32_t code = reference_encoder_->Encode(*p);
-      CHECK(*p == NULL ? code == 0 : code != 0);
-      offsets_.Add(
-          static_cast<int>(reinterpret_cast<Address>(p) - obj_address_));
-      addresses_.Add(reinterpret_cast<Address>(code));
-    }
-  }
-
-  virtual void VisitRuntimeEntry(RelocInfo* rinfo) {
-    Address target = rinfo->target_address();
-    uint32_t encoding = reference_encoder_->Encode(target);
-    CHECK(target == NULL ? encoding == 0 : encoding != 0);
-    offsets_.Add(
-        static_cast<int>(rinfo->target_address_address() - obj_address_));
-    addresses_.Add(reinterpret_cast<Address>(encoding));
-  }
-
-  void Update(Address start_address) {
-    for (int i = 0; i < offsets_.length(); i++) {
-      memcpy(start_address + offsets_[i], &addresses_[i], sizeof(Address));
-    }
-    for (int i = 0; i < offsets_32_bit_.length(); i++) {
-      memcpy(start_address + offsets_32_bit_[i], &data_32_bit_[i],
-             sizeof(uint32_t));
-    }
-  }
-
- private:
-  Address obj_address_;
-  Serializer* serializer_;
-  ExternalReferenceEncoder* reference_encoder_;
-  List<int> offsets_;
-  List<Address> addresses_;
-  // Some updates are 32-bit even on a 64-bit platform.
-  // We keep a separate list of them on 64-bit platforms.
-  List<int> offsets_32_bit_;
-  List<uint32_t> data_32_bit_;
-};
-
-
-// Helper functions for a map of encoded heap object addresses.
-static uint32_t HeapObjectHash(HeapObject* key) {
-  uint32_t low32bits = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key));
-  return low32bits >> 2;
-}
-
-
-static bool MatchHeapObject(void* key1, void* key2) {
-  return key1 == key2;
-}
-
-
-Serializer::Serializer()
-  : global_handles_(4),
-    saved_addresses_(MatchHeapObject) {
-  root_ = true;
-  roots_ = 0;
-  objects_ = 0;
-  reference_encoder_ = NULL;
-  writer_ = new SnapshotWriter();
-  for (int i = 0; i <= LAST_SPACE; i++) {
-    allocator_[i] = new SimulatedHeapSpace();
-  }
-}
-
-
-Serializer::~Serializer() {
-  for (int i = 0; i <= LAST_SPACE; i++) {
-    delete allocator_[i];
-  }
-  if (reference_encoder_) delete reference_encoder_;
-  delete writer_;
-}
-
-
 bool Serializer::serialization_enabled_ = false;
 bool Serializer::too_late_to_enable_now_ = false;
 
 
-#ifdef DEBUG
-static const int kMaxTagLength = 32;
-
-void Serializer::Synchronize(const char* tag) {
-  if (FLAG_debug_serialization) {
-    int length = StrLength(tag);
-    ASSERT(length <= kMaxTagLength);
-    writer_->PutC('S');
-    writer_->PutInt(length);
-    writer_->PutBytes(reinterpret_cast<const byte*>(tag), length);
-  }
-}
-#endif
-
-
-void Serializer::InitializeAllocators() {
-  for (int i = 0; i <= LAST_SPACE; i++) {
-    allocator_[i]->InitEmptyHeap(static_cast<AllocationSpace>(i));
-  }
-}
-
-
-bool Serializer::IsVisited(HeapObject* obj) {
-  HashMap::Entry* entry =
-    saved_addresses_.Lookup(obj, HeapObjectHash(obj), false);
-  return entry != NULL;
-}
-
-
-Address Serializer::GetSavedAddress(HeapObject* obj) {
-  HashMap::Entry* entry =
-    saved_addresses_.Lookup(obj, HeapObjectHash(obj), false);
-  ASSERT(entry != NULL);
-  return reinterpret_cast<Address>(entry->value);
-}
-
-
-void Serializer::SaveAddress(HeapObject* obj, Address addr) {
-  HashMap::Entry* entry =
-    saved_addresses_.Lookup(obj, HeapObjectHash(obj), true);
-  entry->value = addr;
-}
-
-
-void Serializer::Serialize() {
-  // No active threads.
-  CHECK_EQ(NULL, ThreadState::FirstInUse());
-  // No active or weak handles.
-  CHECK(HandleScopeImplementer::instance()->blocks()->is_empty());
-  CHECK_EQ(0, GlobalHandles::NumberOfWeakHandles());
-  // We need a counter function during serialization to resolve the
-  // references to counters in the code on the heap.
-  CHECK(StatsTable::HasCounterFunction());
-  CHECK(enabled());
-  InitializeAllocators();
-  reference_encoder_ = new ExternalReferenceEncoder();
-  PutHeader();
-  Heap::IterateRoots(this, VISIT_ONLY_STRONG);
-  PutLog();
-  PutContextStack();
-  Disable();
-}
-
-
-void Serializer::Finalize(byte** str, int* len) {
-  writer_->GetBytes(str, len);
-}
-
-
-// Serialize objects by writing them into the stream.
-
-void Serializer::VisitPointers(Object** start, Object** end) {
-  bool root = root_;
-  root_ = false;
-  for (Object** p = start; p < end; ++p) {
-    bool serialized;
-    Address a = Encode(*p, &serialized);
-    if (root) {
-      roots_++;
-      // If the object was not just serialized,
-      // write its encoded address instead.
-      if (!serialized) PutEncodedAddress(a);
-    }
-  }
-  root_ = root;
-}
-
-
-void Serializer::VisitCodeTarget(RelocInfo* rinfo) {
-  ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
-  Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
-  bool serialized;
-  Encode(target, &serialized);
-}
-
-
-class GlobalHandlesRetriever: public ObjectVisitor {
- public:
-  explicit GlobalHandlesRetriever(List<Object**>* handles)
-  : global_handles_(handles) {}
-
-  virtual void VisitPointers(Object** start, Object** end) {
-    for (; start != end; ++start) {
-      global_handles_->Add(start);
-    }
-  }
-
- private:
-  List<Object**>* global_handles_;
-};
-
-
-void Serializer::PutFlags() {
-  writer_->PutC('F');
-  List<const char*>* argv = FlagList::argv();
-  writer_->PutInt(argv->length());
-  writer_->PutC('[');
-  for (int i = 0; i < argv->length(); i++) {
-    if (i > 0) writer_->PutC('|');
-    writer_->PutString((*argv)[i]);
-    DeleteArray((*argv)[i]);
-  }
-  writer_->PutC(']');
-  flags_end_ = writer_->length();
-  delete argv;
-}
-
-
-void Serializer::PutHeader() {
-  PutFlags();
-  writer_->PutC('D');
-#ifdef DEBUG
-  writer_->PutC(FLAG_debug_serialization ? '1' : '0');
-#else
-  writer_->PutC('0');
-#endif
-#ifdef V8_NATIVE_REGEXP
-  writer_->PutC('N');
-#else  // Interpreted regexp
-  writer_->PutC('I');
-#endif
-  // Write sizes of paged memory spaces. Allocate extra space for the old
-  // and code spaces, because objects in new space will be promoted to them.
-  writer_->PutC('S');
-  writer_->PutC('[');
-  writer_->PutInt(Heap::old_pointer_space()->Size() +
-                  Heap::new_space()->Size());
-  writer_->PutC('|');
-  writer_->PutInt(Heap::old_data_space()->Size() + Heap::new_space()->Size());
-  writer_->PutC('|');
-  writer_->PutInt(Heap::code_space()->Size() + Heap::new_space()->Size());
-  writer_->PutC('|');
-  writer_->PutInt(Heap::map_space()->Size());
-  writer_->PutC('|');
-  writer_->PutInt(Heap::cell_space()->Size());
-  writer_->PutC(']');
-  // Write global handles.
-  writer_->PutC('G');
-  writer_->PutC('[');
-  GlobalHandlesRetriever ghr(&global_handles_);
-  GlobalHandles::IterateStrongRoots(&ghr);
-  for (int i = 0; i < global_handles_.length(); i++) {
-    writer_->PutC('N');
-  }
-  writer_->PutC(']');
-}
-
-
-void Serializer::PutLog() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  if (FLAG_log_code) {
-    Logger::TearDown();
-    int pos = writer_->InsertC('L', flags_end_);
-    bool exists;
-    Vector<const char> log = ReadFile(FLAG_logfile, &exists);
-    writer_->InsertString(log.start(), pos);
-    log.Dispose();
-  }
-#endif
-}
-
-
-static int IndexOf(const List<Object**>& list, Object** element) {
-  for (int i = 0; i < list.length(); i++) {
-    if (list[i] == element) return i;
-  }
-  return -1;
-}
-
-
-void Serializer::PutGlobalHandleStack(const List<Handle<Object> >& stack) {
-  writer_->PutC('[');
-  writer_->PutInt(stack.length());
-  for (int i = stack.length() - 1; i >= 0; i--) {
-    writer_->PutC('|');
-    int gh_index = IndexOf(global_handles_, stack[i].location());
-    CHECK_GE(gh_index, 0);
-    writer_->PutInt(gh_index);
-  }
-  writer_->PutC(']');
-}
-
-
-void Serializer::PutContextStack() {
-  List<Context*> contexts(2);
-  while (HandleScopeImplementer::instance()->HasSavedContexts()) {
-    Context* context =
-      HandleScopeImplementer::instance()->RestoreContext();
-    contexts.Add(context);
-  }
-  for (int i = contexts.length() - 1; i >= 0; i--) {
-    HandleScopeImplementer::instance()->SaveContext(contexts[i]);
-  }
-  writer_->PutC('C');
-  writer_->PutC('[');
-  writer_->PutInt(contexts.length());
-  if (!contexts.is_empty()) {
-    Object** start = reinterpret_cast<Object**>(&contexts.first());
-    VisitPointers(start, start + contexts.length());
-  }
-  writer_->PutC(']');
-}
-
-void Serializer::PutEncodedAddress(Address addr) {
-  writer_->PutC('P');
-  writer_->PutAddress(addr);
-}
-
-
-Address Serializer::Encode(Object* o, bool* serialized) {
-  *serialized = false;
-  if (o->IsSmi()) {
-    return reinterpret_cast<Address>(o);
-  } else {
-    HeapObject* obj = HeapObject::cast(o);
-    if (IsVisited(obj)) {
-      return GetSavedAddress(obj);
-    } else {
-      // First visit: serialize the object.
-      *serialized = true;
-      return PutObject(obj);
-    }
-  }
-}
-
-
-Address Serializer::PutObject(HeapObject* obj) {
-  Map* map = obj->map();
-  InstanceType type = map->instance_type();
-  int size = obj->SizeFromMap(map);
-
-  // Simulate the allocation of obj to predict where it will be
-  // allocated during deserialization.
-  Address addr = Allocate(obj).Encode();
-
-  SaveAddress(obj, addr);
-
-  if (type == CODE_TYPE) {
-    LOG(CodeMoveEvent(obj->address(), addr));
-  }
-
-  // Write out the object prologue: type, size, and simulated address of obj.
-  writer_->PutC('[');
-  CHECK_EQ(0, static_cast<int>(size & kObjectAlignmentMask));
-  writer_->PutInt(type);
-  writer_->PutInt(size >> kObjectAlignmentBits);
-  PutEncodedAddress(addr);  // encodes AllocationSpace
-
-  // Visit all the pointers in the object other than the map. This
-  // will recursively serialize any as-yet-unvisited objects.
-  obj->Iterate(this);
-
-  // Mark end of recursively embedded objects, start of object body.
-  writer_->PutC('|');
-  // Write out the raw contents of the object. No compression, but
-  // fast to deserialize.
-  writer_->PutBytes(obj->address(), size);
-  // Update pointers and external references in the written object.
-  ReferenceUpdater updater(obj, this);
-  obj->Iterate(&updater);
-  updater.Update(writer_->position() - size);
-
-#ifdef DEBUG
-  if (FLAG_debug_serialization) {
-    // Write out the object epilogue to catch synchronization errors.
-    PutEncodedAddress(addr);
-    writer_->PutC(']');
-  }
-#endif
-
-  objects_++;
-  return addr;
-}
-
-
-RelativeAddress Serializer::Allocate(HeapObject* obj) {
-  // Find out which AllocationSpace 'obj' is in.
-  AllocationSpace s;
-  bool found = false;
-  for (int i = FIRST_SPACE; !found && i <= LAST_SPACE; i++) {
-    s = static_cast<AllocationSpace>(i);
-    found = Heap::InSpace(obj, s);
-  }
-  CHECK(found);
-  int size = obj->Size();
-  if (s == NEW_SPACE) {
-    if (size > Heap::MaxObjectSizeInPagedSpace()) {
-      s = LO_SPACE;
-    } else {
-      OldSpace* space = Heap::TargetSpace(obj);
-      ASSERT(space == Heap::old_pointer_space() ||
-             space == Heap::old_data_space());
-      s = (space == Heap::old_pointer_space()) ?
-          OLD_POINTER_SPACE :
-          OLD_DATA_SPACE;
-    }
-  }
-  GCTreatment gc_treatment = DataObject;
-  if (obj->IsFixedArray()) gc_treatment = PointerObject;
-  else if (obj->IsCode()) gc_treatment = CodeObject;
-  return allocator_[s]->Allocate(size, gc_treatment);
-}
-
-
-//------------------------------------------------------------------------------
-// Implementation of Deserializer
-
-
-static const int kInitArraySize = 32;
-
-
-Deserializer::Deserializer(const byte* str, int len)
-  : reader_(str, len),
-    map_pages_(kInitArraySize),
-    cell_pages_(kInitArraySize),
-    old_pointer_pages_(kInitArraySize),
-    old_data_pages_(kInitArraySize),
-    code_pages_(kInitArraySize),
-    large_objects_(kInitArraySize),
-    global_handles_(4) {
-  root_ = true;
-  roots_ = 0;
-  objects_ = 0;
-  reference_decoder_ = NULL;
-#ifdef DEBUG
-  expect_debug_information_ = false;
-#endif
-}
-
-
-Deserializer::~Deserializer() {
-  if (reference_decoder_) delete reference_decoder_;
-}
-
-
-void Deserializer::ExpectEncodedAddress(Address expected) {
-  Address a = GetEncodedAddress();
-  USE(a);
-  ASSERT(a == expected);
-}
-
-
-#ifdef DEBUG
-void Deserializer::Synchronize(const char* tag) {
-  if (expect_debug_information_) {
-    char buf[kMaxTagLength];
-    reader_.ExpectC('S');
-    int length = reader_.GetInt();
-    ASSERT(length <= kMaxTagLength);
-    reader_.GetBytes(reinterpret_cast<Address>(buf), length);
-    ASSERT_EQ(StrLength(tag), length);
-    ASSERT(strncmp(tag, buf, length) == 0);
-  }
-}
-#endif
-
-
-class NoGlobalHandlesChecker : public ObjectVisitor {
- public:
-  virtual void VisitPointers(Object** start, Object** end) {
-    ASSERT(false);
-  }
-};
-
-
-class GlobalHandleDestroyer : public ObjectVisitor {
-  void VisitPointers(Object**start, Object**end) {
-    while (start < end) {
-      GlobalHandles::Destroy(start++);
-    }
-  }
-};
-
-
-void Deserializer::Deserialize() {
-  // No global handles.
-  NoGlobalHandlesChecker checker;
-  GlobalHandles::IterateStrongRoots(&checker);
-  // No active threads.
-  ASSERT_EQ(NULL, ThreadState::FirstInUse());
-  // No active handles.
-  ASSERT(HandleScopeImplementer::instance()->blocks()->is_empty());
-  reference_decoder_ = new ExternalReferenceDecoder();
-  // By setting linear allocation only, we forbid the use of free list
-  // allocation which is not predicted by SimulatedAddress.
-  GetHeader();
-  Heap::IterateRoots(this, VISIT_ONLY_STRONG);
-  GetContextStack();
-  // Any global handles that have been set up by deserialization are leaked
-  // since noone is keeping track of them.  So we discard them now.
-  GlobalHandleDestroyer destroyer;
-  GlobalHandles::IterateStrongRoots(&destroyer);
-}
-
-
-void Deserializer::VisitPointers(Object** start, Object** end) {
-  bool root = root_;
-  root_ = false;
-  for (Object** p = start; p < end; ++p) {
-    if (root) {
-      roots_++;
-      // Read the next object or pointer from the stream
-      // pointer in the stream.
-      int c = reader_.GetC();
-      if (c == '[') {
-        *p = GetObject();  // embedded object
-      } else {
-        ASSERT(c == 'P');  // pointer to previously serialized object
-        *p = Resolve(reader_.GetAddress());
-      }
-    } else {
-      // A pointer internal to a HeapObject that we've already
-      // read: resolve it to a true address (or Smi)
-      *p = Resolve(reinterpret_cast<Address>(*p));
-    }
-  }
-  root_ = root;
-}
-
-
-void Deserializer::VisitCodeTarget(RelocInfo* rinfo) {
-  ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
-  // On all platforms, the encoded code object address is only 32 bits.
-  Address encoded_address = reinterpret_cast<Address>(Memory::uint32_at(
-      reinterpret_cast<Address>(rinfo->target_object_address())));
-  Code* target_object = reinterpret_cast<Code*>(Resolve(encoded_address));
-  rinfo->set_target_address(target_object->instruction_start());
-}
-
-
-void Deserializer::VisitExternalReferences(Address* start, Address* end) {
-  for (Address* p = start; p < end; ++p) {
-    uint32_t code = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(*p));
-    *p = reference_decoder_->Decode(code);
-  }
-}
-
-
-void Deserializer::VisitRuntimeEntry(RelocInfo* rinfo) {
-  uint32_t* pc = reinterpret_cast<uint32_t*>(rinfo->target_address_address());
-  uint32_t encoding = *pc;
-  Address target = reference_decoder_->Decode(encoding);
-  rinfo->set_target_address(target);
-}
-
-
-void Deserializer::GetFlags() {
-  reader_.ExpectC('F');
-  int argc = reader_.GetInt() + 1;
-  char** argv = NewArray<char*>(argc);
-  reader_.ExpectC('[');
-  for (int i = 1; i < argc; i++) {
-    if (i > 1) reader_.ExpectC('|');
-    argv[i] = reader_.GetString();
-  }
-  reader_.ExpectC(']');
-  has_log_ = false;
-  for (int i = 1; i < argc; i++) {
-    if (strcmp("--log_code", argv[i]) == 0) {
-      has_log_ = true;
-    } else if (strcmp("--nouse_ic", argv[i]) == 0) {
-      FLAG_use_ic = false;
-    } else if (strcmp("--debug_code", argv[i]) == 0) {
-      FLAG_debug_code = true;
-    } else if (strcmp("--nolazy", argv[i]) == 0) {
-      FLAG_lazy = false;
-    }
-    DeleteArray(argv[i]);
-  }
-
-  DeleteArray(argv);
-}
-
-
-void Deserializer::GetLog() {
-  if (has_log_) {
-    reader_.ExpectC('L');
-    char* snapshot_log = reader_.GetString();
-#ifdef ENABLE_LOGGING_AND_PROFILING
-    if (FLAG_log_code) {
-      LOG(Preamble(snapshot_log));
-    }
-#endif
-    DeleteArray(snapshot_log);
-  }
-}
-
-
-static void InitPagedSpace(PagedSpace* space,
-                           int capacity,
-                           List<Page*>* page_list) {
-  if (!space->EnsureCapacity(capacity)) {
-    V8::FatalProcessOutOfMemory("InitPagedSpace");
-  }
-  PageIterator it(space, PageIterator::ALL_PAGES);
-  while (it.has_next()) page_list->Add(it.next());
-}
-
-
-void Deserializer::GetHeader() {
-  reader_.ExpectC('D');
-#ifdef DEBUG
-  expect_debug_information_ = reader_.GetC() == '1';
-#else
-  // In release mode, don't attempt to read a snapshot containing
-  // synchronization tags.
-  if (reader_.GetC() != '0') FATAL("Snapshot contains synchronization tags.");
-#endif
-#ifdef V8_NATIVE_REGEXP
-  reader_.ExpectC('N');
-#else  // Interpreted regexp.
-  reader_.ExpectC('I');
-#endif
-  // Ensure sufficient capacity in paged memory spaces to avoid growth
-  // during deserialization.
-  reader_.ExpectC('S');
-  reader_.ExpectC('[');
-  InitPagedSpace(Heap::old_pointer_space(),
-                 reader_.GetInt(),
-                 &old_pointer_pages_);
-  reader_.ExpectC('|');
-  InitPagedSpace(Heap::old_data_space(), reader_.GetInt(), &old_data_pages_);
-  reader_.ExpectC('|');
-  InitPagedSpace(Heap::code_space(), reader_.GetInt(), &code_pages_);
-  reader_.ExpectC('|');
-  InitPagedSpace(Heap::map_space(), reader_.GetInt(), &map_pages_);
-  reader_.ExpectC('|');
-  InitPagedSpace(Heap::cell_space(), reader_.GetInt(), &cell_pages_);
-  reader_.ExpectC(']');
-  // Create placeholders for global handles later to be fill during
-  // IterateRoots.
-  reader_.ExpectC('G');
-  reader_.ExpectC('[');
-  int c = reader_.GetC();
-  while (c != ']') {
-    ASSERT(c == 'N');
-    global_handles_.Add(GlobalHandles::Create(NULL).location());
-    c = reader_.GetC();
-  }
-}
-
-
-void Deserializer::GetGlobalHandleStack(List<Handle<Object> >* stack) {
-  reader_.ExpectC('[');
-  int length = reader_.GetInt();
-  for (int i = 0; i < length; i++) {
-    reader_.ExpectC('|');
-    int gh_index = reader_.GetInt();
-    stack->Add(global_handles_[gh_index]);
-  }
-  reader_.ExpectC(']');
-}
-
-
-void Deserializer::GetContextStack() {
-  reader_.ExpectC('C');
-  CHECK_EQ(reader_.GetC(), '[');
-  int count = reader_.GetInt();
-  List<Context*> entered_contexts(count);
-  if (count > 0) {
-    Object** start = reinterpret_cast<Object**>(&entered_contexts.first());
-    VisitPointers(start, start + count);
-  }
-  reader_.ExpectC(']');
-  for (int i = 0; i < count; i++) {
-    HandleScopeImplementer::instance()->SaveContext(entered_contexts[i]);
-  }
-}
-
-
-Address Deserializer::GetEncodedAddress() {
-  reader_.ExpectC('P');
-  return reader_.GetAddress();
-}
-
-
-Object* Deserializer::GetObject() {
-  // Read the prologue: type, size and encoded address.
-  InstanceType type = static_cast<InstanceType>(reader_.GetInt());
-  int size = reader_.GetInt() << kObjectAlignmentBits;
-  Address a = GetEncodedAddress();
-
-  // Get a raw object of the right size in the right space.
-  AllocationSpace space = GetSpace(a);
-  Object* o;
-  if (IsLargeExecutableObject(a)) {
-    o = Heap::lo_space()->AllocateRawCode(size);
-  } else if (IsLargeFixedArray(a)) {
-    o = Heap::lo_space()->AllocateRawFixedArray(size);
-  } else {
-    AllocationSpace retry_space = (space == NEW_SPACE)
-        ? Heap::TargetSpaceId(type)
-        : space;
-    o = Heap::AllocateRaw(size, space, retry_space);
-  }
-  ASSERT(!o->IsFailure());
-  // Check that the simulation of heap allocation was correct.
-  ASSERT(o == Resolve(a));
-
-  // Read any recursively embedded objects.
-  int c = reader_.GetC();
-  while (c == '[') {
-    GetObject();
-    c = reader_.GetC();
-  }
-  ASSERT(c == '|');
-
-  HeapObject* obj = reinterpret_cast<HeapObject*>(o);
-  // Read the uninterpreted contents of the object after the map
-  reader_.GetBytes(obj->address(), size);
-#ifdef DEBUG
-  if (expect_debug_information_) {
-    // Read in the epilogue to check that we're still synchronized
-    ExpectEncodedAddress(a);
-    reader_.ExpectC(']');
-  }
-#endif
-
-  // Resolve the encoded pointers we just read in.
-  // Same as obj->Iterate(this), but doesn't rely on the map pointer being set.
-  VisitPointer(reinterpret_cast<Object**>(obj->address()));
-  obj->IterateBody(type, size, this);
-
-  if (type == CODE_TYPE) {
-    LOG(CodeMoveEvent(a, obj->address()));
-  }
-  objects_++;
-  return o;
-}
-
-
-static inline Object* ResolvePaged(int page_index,
-                                   int page_offset,
-                                   PagedSpace* space,
-                                   List<Page*>* page_list) {
-  ASSERT(page_index < page_list->length());
-  Address address = (*page_list)[page_index]->OffsetToAddress(page_offset);
-  return HeapObject::FromAddress(address);
-}
-
-
-template<typename T>
-void ConcatReversed(List<T>* target, const List<T>& source) {
-  for (int i = source.length() - 1; i >= 0; i--) {
-    target->Add(source[i]);
-  }
-}
-
-
-Object* Deserializer::Resolve(Address encoded) {
-  Object* o = reinterpret_cast<Object*>(encoded);
-  if (o->IsSmi()) return o;
-
-  // Encoded addresses of HeapObjects always have 'HeapObject' tags.
-  ASSERT(o->IsHeapObject());
-  switch (GetSpace(encoded)) {
-    // For Map space and Old space, we cache the known Pages in map_pages,
-    // old_pointer_pages and old_data_pages. Even though MapSpace keeps a list
-    // of page addresses, we don't rely on it since GetObject uses AllocateRaw,
-    // and that appears not to update the page list.
-    case MAP_SPACE:
-      return ResolvePaged(PageIndex(encoded), PageOffset(encoded),
-                          Heap::map_space(), &map_pages_);
-    case CELL_SPACE:
-      return ResolvePaged(PageIndex(encoded), PageOffset(encoded),
-                          Heap::cell_space(), &cell_pages_);
-    case OLD_POINTER_SPACE:
-      return ResolvePaged(PageIndex(encoded), PageOffset(encoded),
-                          Heap::old_pointer_space(), &old_pointer_pages_);
-    case OLD_DATA_SPACE:
-      return ResolvePaged(PageIndex(encoded), PageOffset(encoded),
-                          Heap::old_data_space(), &old_data_pages_);
-    case CODE_SPACE:
-      return ResolvePaged(PageIndex(encoded), PageOffset(encoded),
-                          Heap::code_space(), &code_pages_);
-    case NEW_SPACE:
-      return HeapObject::FromAddress(Heap::NewSpaceStart() +
-                                     NewSpaceOffset(encoded));
-    case LO_SPACE:
-      // Cache the known large_objects, allocated one per 'page'
-      int index = LargeObjectIndex(encoded);
-      if (index >= large_objects_.length()) {
-        int new_object_count =
-          Heap::lo_space()->PageCount() - large_objects_.length();
-        List<Object*> new_objects(new_object_count);
-        LargeObjectIterator it(Heap::lo_space());
-        for (int i = 0; i < new_object_count; i++) {
-          new_objects.Add(it.next());
-        }
-#ifdef DEBUG
-        for (int i = large_objects_.length() - 1; i >= 0; i--) {
-          ASSERT(it.next() == large_objects_[i]);
-        }
-#endif
-        ConcatReversed(&large_objects_, new_objects);
-        ASSERT(index < large_objects_.length());
-      }
-      return large_objects_[index];  // s.page_offset() is ignored.
-  }
-  UNREACHABLE();
-  return NULL;
-}
-
-
-Deserializer2::Deserializer2(SnapshotByteSource* source)
+Deserializer::Deserializer(SnapshotByteSource* source)
     : source_(source),
       external_reference_decoder_(NULL) {
 }
@@ -1784,7 +498,7 @@ Deserializer2::Deserializer2(SnapshotByteSource* source)
 // This routine both allocates a new object, and also keeps
 // track of where objects have been allocated so that we can
 // fix back references when deserializing.
-Address Deserializer2::Allocate(int space_index, Space* space, int size) {
+Address Deserializer::Allocate(int space_index, Space* space, int size) {
   Address address;
   if (!SpaceIsLarge(space_index)) {
     ASSERT(!SpaceIsPaged(space_index) ||
@@ -1809,7 +523,7 @@ Address Deserializer2::Allocate(int space_index, Space* space, int size) {
     } else if (space_index == kLargeFixedArray) {
       new_allocation = lo_space->AllocateRawFixedArray(size);
     } else {
-      ASSERT(space_index == kLargeCode);
+      ASSERT_EQ(kLargeCode, space_index);
       new_allocation = lo_space->AllocateRawCode(size);
     }
     ASSERT(!new_allocation->IsFailure());
@@ -1825,7 +539,7 @@ Address Deserializer2::Allocate(int space_index, Space* space, int size) {
 
 // This returns the address of an object that has been described in the
 // snapshot as being offset bytes back in a particular space.
-HeapObject* Deserializer2::GetAddressFromEnd(int space) {
+HeapObject* Deserializer::GetAddressFromEnd(int space) {
   int offset = source_->GetInt();
   ASSERT(!SpaceIsLarge(space));
   offset <<= kObjectAlignmentBits;
@@ -1835,7 +549,7 @@ HeapObject* Deserializer2::GetAddressFromEnd(int space) {
 
 // This returns the address of an object that has been described in the
 // snapshot as being offset bytes into a particular space.
-HeapObject* Deserializer2::GetAddressFromStart(int space) {
+HeapObject* Deserializer::GetAddressFromStart(int space) {
   int offset = source_->GetInt();
   if (SpaceIsLarge(space)) {
     // Large spaces have one object per 'page'.
@@ -1854,7 +568,7 @@ HeapObject* Deserializer2::GetAddressFromStart(int space) {
 }
 
 
-void Deserializer2::Deserialize() {
+void Deserializer::Deserialize() {
   // Don't GC while deserializing - just expand the heap.
   AlwaysAllocateScope always_allocate;
   // Don't use the free lists while deserializing.
@@ -1863,7 +577,7 @@ void Deserializer2::Deserialize() {
   ASSERT_EQ(NULL, ThreadState::FirstInUse());
   // No active handles.
   ASSERT(HandleScopeImplementer::instance()->blocks()->is_empty());
-  ASSERT(external_reference_decoder_ == NULL);
+  ASSERT_EQ(NULL, external_reference_decoder_);
   external_reference_decoder_ = new ExternalReferenceDecoder();
   Heap::IterateRoots(this, VISIT_ONLY_STRONG);
   ASSERT(source_->AtEOF());
@@ -1874,7 +588,7 @@ void Deserializer2::Deserialize() {
 
 // This is called on the roots.  It is the driver of the deserialization
 // process.  It is also called on the body of each function.
-void Deserializer2::VisitPointers(Object** start, Object** end) {
+void Deserializer::VisitPointers(Object** start, Object** end) {
   // The space must be new space.  Any other space would cause ReadChunk to try
   // to update the remembered using NULL as the address.
   ReadChunk(start, end, NEW_SPACE, NULL);
@@ -1887,9 +601,9 @@ void Deserializer2::VisitPointers(Object** start, Object** end) {
 // written very late, which means the ByteArray map is not set up by the
 // time we need to use it to mark the space at the end of a page free (by
 // making it into a byte array).
-void Deserializer2::ReadObject(int space_number,
-                               Space* space,
-                               Object** write_back) {
+void Deserializer::ReadObject(int space_number,
+                              Space* space,
+                              Object** write_back) {
   int size = source_->GetInt() << kObjectAlignmentBits;
   Address address = Allocate(space_number, space, size);
   *write_back = HeapObject::FromAddress(address);
@@ -1911,10 +625,10 @@ void Deserializer2::ReadObject(int space_number,
   case (base_tag) + kLargeFixedArray:  /* NOLINT */
 
 
-void Deserializer2::ReadChunk(Object** current,
-                              Object** limit,
-                              int space,
-                              Address address) {
+void Deserializer::ReadChunk(Object** current,
+                             Object** limit,
+                             int space,
+                             Address address) {
   while (current < limit) {
     int data = source_->Get();
     switch (data) {
@@ -2085,7 +799,7 @@ void Deserializer2::ReadChunk(Object** current,
         UNREACHABLE();
     }
   }
-  ASSERT(current == limit);
+  ASSERT_EQ(current, limit);
 }
 
 
@@ -2101,11 +815,11 @@ void SnapshotByteSink::PutInt(uintptr_t integer, const char* description) {
 
 #ifdef DEBUG
 
-void Deserializer2::Synchronize(const char* tag) {
+void Deserializer::Synchronize(const char* tag) {
   int data = source_->Get();
   // If this assert fails then that indicates that you have a mismatch between
   // the number of GC roots when serializing and deserializing.
-  ASSERT(data == SYNCHRONIZE);
+  ASSERT_EQ(SYNCHRONIZE, data);
   do {
     int character = source_->Get();
     if (character == 0) break;
@@ -2119,7 +833,7 @@ void Deserializer2::Synchronize(const char* tag) {
 }
 
 
-void Serializer2::Synchronize(const char* tag) {
+void Serializer::Synchronize(const char* tag) {
   sink_->Put(SYNCHRONIZE, tag);
   int character;
   do {
@@ -2130,7 +844,7 @@ void Serializer2::Synchronize(const char* tag) {
 
 #endif
 
-Serializer2::Serializer2(SnapshotByteSink* sink)
+Serializer::Serializer(SnapshotByteSink* sink)
     : sink_(sink),
       current_root_index_(0),
       external_reference_encoder_(NULL) {
@@ -2140,13 +854,19 @@ Serializer2::Serializer2(SnapshotByteSink* sink)
 }
 
 
-void Serializer2::Serialize() {
+void Serializer::Serialize() {
   // No active threads.
   CHECK_EQ(NULL, ThreadState::FirstInUse());
   // No active or weak handles.
   CHECK(HandleScopeImplementer::instance()->blocks()->is_empty());
   CHECK_EQ(0, GlobalHandles::NumberOfWeakHandles());
-  ASSERT(external_reference_encoder_ == NULL);
+  CHECK_EQ(NULL, external_reference_encoder_);
+  // We don't support serializing installed extensions.
+  for (RegisteredExtension* ext = RegisteredExtension::first_extension();
+       ext != NULL;
+       ext = ext->next()) {
+    CHECK_NE(v8::INSTALLED, ext->state());
+  }
   external_reference_encoder_ = new ExternalReferenceEncoder();
   Heap::IterateRoots(this, VISIT_ONLY_STRONG);
   delete external_reference_encoder_;
@@ -2154,7 +874,7 @@ void Serializer2::Serialize() {
 }
 
 
-void Serializer2::VisitPointers(Object** start, Object** end) {
+void Serializer::VisitPointers(Object** start, Object** end) {
   for (Object** current = start; current < end; current++) {
     if ((*current)->IsSmi()) {
       sink_->Put(RAW_DATA_SERIALIZATION, "RawData");
@@ -2169,10 +889,10 @@ void Serializer2::VisitPointers(Object** start, Object** end) {
 }
 
 
-void Serializer2::SerializeObject(
+void Serializer::SerializeObject(
     Object* o,
     ReferenceRepresentation reference_representation) {
-  ASSERT(o->IsHeapObject());
+  CHECK(o->IsHeapObject());
   HeapObject* heap_object = HeapObject::cast(o);
   MapWord map_word = heap_object->map_word();
   if (map_word.IsSerializationAddress()) {
@@ -2204,7 +924,7 @@ void Serializer2::SerializeObject(
         sink_->PutInt(address, "address");
       }
     } else {
-      ASSERT(reference_representation == TAGGED_REPRESENTATION);
+      CHECK_EQ(TAGGED_REPRESENTATION, reference_representation);
       if (from_start) {
 #define COMMON_REFS_CASE(tag, common_space, common_offset)                 \
         if (space == common_space && address == common_offset) {           \
@@ -2233,14 +953,14 @@ void Serializer2::SerializeObject(
 
 
 
-void Serializer2::ObjectSerializer::Serialize() {
-  int space = Serializer2::SpaceOfObject(object_);
+void Serializer::ObjectSerializer::Serialize() {
+  int space = Serializer::SpaceOfObject(object_);
   int size = object_->Size();
 
   if (reference_representation_ == TAGGED_REPRESENTATION) {
     sink_->Put(OBJECT_SERIALIZATION + space, "ObjectSerialization");
   } else {
-    ASSERT(reference_representation_ == CODE_TARGET_REPRESENTATION);
+    CHECK_EQ(CODE_TARGET_REPRESENTATION, reference_representation_);
     sink_->Put(CODE_OBJECT_SERIALIZATION + space, "ObjectSerialization");
   }
   sink_->PutInt(size >> kObjectAlignmentBits, "Size in words");
@@ -2260,15 +980,15 @@ void Serializer2::ObjectSerializer::Serialize() {
   serializer_->SerializeObject(map, TAGGED_REPRESENTATION);
 
   // Serialize the rest of the object.
-  ASSERT(bytes_processed_so_far_ == 0);
+  CHECK_EQ(0, bytes_processed_so_far_);
   bytes_processed_so_far_ = kPointerSize;
   object_->IterateBody(map->instance_type(), size, this);
   OutputRawData(object_->address() + size);
 }
 
 
-void Serializer2::ObjectSerializer::VisitPointers(Object** start,
-                                                  Object** end) {
+void Serializer::ObjectSerializer::VisitPointers(Object** start,
+                                                 Object** end) {
   Object** current = start;
   while (current < end) {
     while (current < end && (*current)->IsSmi()) current++;
@@ -2283,8 +1003,8 @@ void Serializer2::ObjectSerializer::VisitPointers(Object** start,
 }
 
 
-void Serializer2::ObjectSerializer::VisitExternalReferences(Address* start,
-                                                            Address* end) {
+void Serializer::ObjectSerializer::VisitExternalReferences(Address* start,
+                                                           Address* end) {
   Address references_start = reinterpret_cast<Address>(start);
   OutputRawData(references_start);
 
@@ -2297,7 +1017,7 @@ void Serializer2::ObjectSerializer::VisitExternalReferences(Address* start,
 }
 
 
-void Serializer2::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) {
+void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) {
   Address target_start = rinfo->target_address_address();
   OutputRawData(target_start);
   Address target = rinfo->target_address();
@@ -2309,8 +1029,8 @@ void Serializer2::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) {
 }
 
 
-void Serializer2::ObjectSerializer::VisitCodeTarget(RelocInfo* rinfo) {
-  ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
+void Serializer::ObjectSerializer::VisitCodeTarget(RelocInfo* rinfo) {
+  CHECK(RelocInfo::IsCodeTarget(rinfo->rmode()));
   Address target_start = rinfo->target_address_address();
   OutputRawData(target_start);
   Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
@@ -2319,7 +1039,7 @@ void Serializer2::ObjectSerializer::VisitCodeTarget(RelocInfo* rinfo) {
 }
 
 
-void Serializer2::ObjectSerializer::VisitExternalAsciiString(
+void Serializer::ObjectSerializer::VisitExternalAsciiString(
     v8::String::ExternalAsciiStringResource** resource_pointer) {
   Address references_start = reinterpret_cast<Address>(resource_pointer);
   OutputRawData(references_start);
@@ -2346,7 +1066,7 @@ void Serializer2::ObjectSerializer::VisitExternalAsciiString(
 }
 
 
-void Serializer2::ObjectSerializer::OutputRawData(Address up_to) {
+void Serializer::ObjectSerializer::OutputRawData(Address up_to) {
   Address object_start = object_->address();
   int up_to_offset = static_cast<int>(up_to - object_start);
   int skipped = up_to_offset - bytes_processed_so_far_;
@@ -2374,7 +1094,7 @@ void Serializer2::ObjectSerializer::OutputRawData(Address up_to) {
 }
 
 
-int Serializer2::SpaceOfObject(HeapObject* object) {
+int Serializer::SpaceOfObject(HeapObject* object) {
   for (int i = FIRST_SPACE; i <= LAST_SPACE; i++) {
     AllocationSpace s = static_cast<AllocationSpace>(i);
     if (Heap::InSpace(object, s)) {
@@ -2395,7 +1115,7 @@ int Serializer2::SpaceOfObject(HeapObject* object) {
 }
 
 
-int Serializer2::SpaceOfAlreadySerializedObject(HeapObject* object) {
+int Serializer::SpaceOfAlreadySerializedObject(HeapObject* object) {
   for (int i = FIRST_SPACE; i <= LAST_SPACE; i++) {
     AllocationSpace s = static_cast<AllocationSpace>(i);
     if (Heap::InSpace(object, s)) {
@@ -2407,8 +1127,8 @@ int Serializer2::SpaceOfAlreadySerializedObject(HeapObject* object) {
 }
 
 
-int Serializer2::Allocate(int space, int size, bool* new_page) {
-  ASSERT(space >= 0 && space < kNumberOfSpaces);
+int Serializer::Allocate(int space, int size, bool* new_page) {
+  CHECK(space >= 0 && space < kNumberOfSpaces);
   if (SpaceIsLarge(space)) {
     // In large object space we merely number the objects instead of trying to
     // determine some sort of address.
@@ -2426,9 +1146,9 @@ int Serializer2::Allocate(int space, int size, bool* new_page) {
     // and allocation does not start at offset 0 in the page, but this scheme
     // means the deserializer can get the page number quickly by shifting the
     // serialized address.
-    ASSERT(IsPowerOf2(Page::kPageSize));
+    CHECK(IsPowerOf2(Page::kPageSize));
     int used_in_this_page = (fullness_[space] & (Page::kPageSize - 1));
-    ASSERT(size <= Page::kObjectAreaSize);
+    CHECK(size <= Page::kObjectAreaSize);
     if (used_in_this_page + size > Page::kObjectAreaSize) {
       *new_page = true;
       fullness_[space] = RoundUp(fullness_[space], Page::kPageSize);
index 1205561..96bd751 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2006-2009 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:
@@ -108,260 +108,6 @@ class ExternalReferenceDecoder {
 };
 
 
-// A Serializer recursively visits objects to construct a serialized
-// representation of the Heap stored in a string. Serialization is
-// destructive. We use a similar mechanism to the GC to ensure that
-// each object is visited once, namely, we modify the map pointer of
-// each visited object to contain the relative address in the
-// appropriate space where that object will be allocated when the heap
-// is deserialized.
-
-
-// Helper classes defined in serialize.cc.
-class RelativeAddress;
-class SimulatedHeapSpace;
-class SnapshotWriter;
-class ReferenceUpdater;
-
-
-class Serializer: public ObjectVisitor {
- public:
-  Serializer();
-
-  virtual ~Serializer();
-
-  // Serialize the current state of the heap. This operation destroys the
-  // heap contents and the contents of the roots into the heap.
-  void Serialize();
-
-  // Returns the serialized buffer. Ownership is transferred to the
-  // caller. Only the destructor and getters may be called after this call.
-  void Finalize(byte** str, int* len);
-
-  int roots() { return roots_; }
-  int objects() { return objects_; }
-
-#ifdef DEBUG
-  // insert "tag" into the serialized stream
-  virtual void Synchronize(const char* tag);
-#endif
-
-  static bool enabled() { return serialization_enabled_; }
-
-  static void Enable() {
-    if (!serialization_enabled_) {
-      ASSERT(!too_late_to_enable_now_);
-    }
-    serialization_enabled_ = true;
-  }
-
-  static void Disable() { serialization_enabled_ = false; }
-  // Call this when you have made use of the fact that there is no serialization
-  // going on.
-  static void TooLateToEnableNow() { too_late_to_enable_now_ = true; }
-
- private:
-  friend class ReferenceUpdater;
-
-  virtual void VisitPointers(Object** start, Object** end);
-  virtual void VisitCodeTarget(RelocInfo* rinfo);
-  bool IsVisited(HeapObject* obj);
-
-  Address GetSavedAddress(HeapObject* obj);
-
-  void SaveAddress(HeapObject* obj, Address addr);
-
-  void PutEncodedAddress(Address addr);
-  // Write the global flags into the file.
-  void PutFlags();
-  // Write global information into the header of the file.
-  void PutHeader();
-  // Write the contents of the log into the file.
-  void PutLog();
-  // Serialize 'obj', and return its encoded RelativeAddress.
-  Address PutObject(HeapObject* obj);
-  // Write a stack of handles to the file bottom first.
-  void PutGlobalHandleStack(const List<Handle<Object> >& stack);
-  // Write the context stack into the file.
-  void PutContextStack();
-
-  // Return the encoded RelativeAddress where this object will be
-  // allocated on deserialization. On the first visit of 'o',
-  // serialize its contents. On return, *serialized will be true iff
-  // 'o' has just been serialized.
-  Address Encode(Object* o, bool* serialized);
-
-  // Simulate the allocation of 'obj', returning the address where it will
-  // be allocated on deserialization
-  RelativeAddress Allocate(HeapObject* obj);
-
-  void InitializeAllocators();
-
-  SnapshotWriter* writer_;
-  bool root_;  // serializing a root?
-  int roots_;  // number of roots visited
-  int objects_;  // number of objects serialized
-
-  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 flags_end_;  // The position right after the flags.
-
-  // An array of per-space SimulatedHeapSpaces used as memory allocators.
-  SimulatedHeapSpace* allocator_[LAST_SPACE+1];
-  // A list of global handles at serialization time.
-  List<Object**> global_handles_;
-
-  ExternalReferenceEncoder* reference_encoder_;
-
-  HashMap saved_addresses_;
-
-  DISALLOW_COPY_AND_ASSIGN(Serializer);
-};
-
-// Helper class to read the bytes of the serialized heap.
-
-class SnapshotReader {
- public:
-  SnapshotReader(const byte* str, int len): str_(str), end_(str + len) {}
-
-  void ExpectC(char expected) {
-    int c = GetC();
-    USE(c);
-    ASSERT(c == expected);
-  }
-
-  int GetC() {
-    if (str_ >= end_) return EOF;
-    return *str_++;
-  }
-
-  int GetInt() {
-    int result;
-    GetBytes(reinterpret_cast<Address>(&result), sizeof(result));
-    return result;
-  }
-
-  Address GetAddress() {
-    Address result;
-    GetBytes(reinterpret_cast<Address>(&result), sizeof(result));
-    return result;
-  }
-
-  void GetBytes(Address a, int size) {
-    ASSERT(str_ + size <= end_);
-    memcpy(a, str_, size);
-    str_ += size;
-  }
-
-  char* GetString() {
-    ExpectC('[');
-    int size = GetInt();
-    ExpectC(']');
-    char* s = NewArray<char>(size + 1);
-    GetBytes(reinterpret_cast<Address>(s), size);
-    s[size] = 0;
-    return s;
-  }
-
- private:
-  const byte* str_;
-  const byte* end_;
-};
-
-
-// A Deserializer reads a snapshot and reconstructs the Object graph it defines.
-
-
-// TODO(erikcorry): Get rid of this superclass when we are using the new
-// snapshot code exclusively.
-class GenericDeserializer: public ObjectVisitor {
- public:
-  virtual void GetLog() = 0;
-  virtual void Deserialize() = 0;
-};
-
-
-// TODO(erikcorry): Get rid of this class.
-class Deserializer: public GenericDeserializer {
- public:
-  // Create a deserializer. The snapshot is held in str and has size len.
-  Deserializer(const byte* str, int len);
-
-  virtual ~Deserializer();
-
-  // Read the flags from the header of the file, and set those that
-  // should be inherited from the snapshot.
-  void GetFlags();
-
-  // Read saved profiling information from the file and log it if required.
-  void GetLog();
-
-  // Deserialize the snapshot into an empty heap.
-  void Deserialize();
-
-  int roots() { return roots_; }
-  int objects() { return objects_; }
-
-#ifdef DEBUG
-  // Check for the presence of "tag" in the serialized stream
-  virtual void Synchronize(const char* tag);
-#endif
-
- private:
-  virtual void VisitPointers(Object** start, Object** end);
-  virtual void VisitCodeTarget(RelocInfo* rinfo);
-  virtual void VisitExternalReferences(Address* start, Address* end);
-  virtual void VisitRuntimeEntry(RelocInfo* rinfo);
-
-  Address GetEncodedAddress();
-
-  // Read other global information (except flags) from the header of the file.
-  void GetHeader();
-  // Read a stack of handles from the file bottom first.
-  void GetGlobalHandleStack(List<Handle<Object> >* stack);
-  // Read the context stack from the file.
-  void GetContextStack();
-
-  Object* GetObject();
-
-  // Get the encoded address. In debug mode we make sure
-  // it matches the given expectations.
-  void ExpectEncodedAddress(Address expected);
-
-  // Given an encoded address (the result of
-  // RelativeAddress::Encode), return the object to which it points,
-  // which will be either an Smi or a HeapObject in the current heap.
-  Object* Resolve(Address encoded_address);
-
-  SnapshotReader reader_;
-  bool root_;  // Deserializing a root?
-  int roots_;  // number of roots visited
-  int objects_;  // number of objects serialized
-
-  bool has_log_;  // The file has log information.
-
-  // Resolve caches the following:
-  List<Page*> map_pages_;  // All pages in the map space.
-  List<Page*> cell_pages_;  // All pages in the cell space.
-  List<Page*> old_pointer_pages_;  // All pages in the old pointer space.
-  List<Page*> old_data_pages_;  // All pages in the old data space.
-  List<Page*> code_pages_;  // All pages in the code space.
-  List<Object*> large_objects_;    // All known large objects.
-  // A list of global handles at deserialization time.
-  List<Object**> global_handles_;
-
-  ExternalReferenceDecoder* reference_decoder_;
-
-#ifdef DEBUG
-  bool expect_debug_information_;
-#endif
-
-  DISALLOW_COPY_AND_ASSIGN(Deserializer);
-};
-
-
 class SnapshotByteSource {
  public:
   SnapshotByteSource(const byte* array, int length)
@@ -407,6 +153,7 @@ class SnapshotByteSource {
   int position_;
 };
 
+
 // It is very common to have a reference to the object at word 10 in space 2,
 // the object at word 5 in space 2 and the object at word 28 in space 4.  This
 // only works for objects in the first page of a space.
@@ -436,10 +183,9 @@ class SnapshotByteSource {
   f(14, 32) \
   f(15, 36)
 
-// The SerDes class is a common superclass for Serializer2 and Deserializer2
+// The SerDes class is a common superclass for Serializer and Deserializer
 // which is used to store common constants and methods used by both.
-// TODO(erikcorry): This should inherit from ObjectVisitor.
-class SerDes: public GenericDeserializer {
+class SerDes: public ObjectVisitor {
  protected:
   enum DataType {
     RAW_DATA_SERIALIZATION = 0,
@@ -483,16 +229,15 @@ class SerDes: public GenericDeserializer {
 
 
 // A Deserializer reads a snapshot and reconstructs the Object graph it defines.
-class Deserializer2: public SerDes {
+class Deserializer: public SerDes {
  public:
   // Create a deserializer from a snapshot byte source.
-  explicit Deserializer2(SnapshotByteSource* source);
+  explicit Deserializer(SnapshotByteSource* source);
 
-  virtual ~Deserializer2() { }
+  virtual ~Deserializer() { }
 
   // Deserialize the snapshot into an empty heap.
   void Deserialize();
-  void GetLog() { }   // TODO(erikcorry): Get rid of this.
 #ifdef DEBUG
   virtual void Synchronize(const char* tag);
 #endif
@@ -530,7 +275,7 @@ class Deserializer2: public SerDes {
   // START_NEW_PAGE_SERIALIZATION tag.
   Address last_object_address_;
 
-  DISALLOW_COPY_AND_ASSIGN(Deserializer2);
+  DISALLOW_COPY_AND_ASSIGN(Deserializer);
 };
 
 
@@ -545,15 +290,26 @@ class SnapshotByteSink {
 };
 
 
-class Serializer2 : public SerDes {
+class Serializer : public SerDes {
  public:
-  explicit Serializer2(SnapshotByteSink* sink);
+  explicit Serializer(SnapshotByteSink* sink);
   // Serialize the current state of the heap. This operation destroys the
   // heap contents.
   void Serialize();
   void VisitPointers(Object** start, Object** end);
-  void GetLog() { }       // TODO(erikcorry): Get rid of this.
-  void Deserialize() { }  // TODO(erikcorry): Get rid of this.
+
+  static void Enable() {
+    if (!serialization_enabled_) {
+      ASSERT(!too_late_to_enable_now_);
+    }
+    serialization_enabled_ = true;
+  }
+
+  static void Disable() { serialization_enabled_ = false; }
+  // Call this when you have made use of the fact that there is no serialization
+  // going on.
+  static void TooLateToEnableNow() { too_late_to_enable_now_ = true; }
+  static bool enabled() { return serialization_enabled_; }
 #ifdef DEBUG
   virtual void Synchronize(const char* tag);
 #endif
@@ -565,7 +321,7 @@ class Serializer2 : public SerDes {
   };
   class ObjectSerializer : public ObjectVisitor {
    public:
-    ObjectSerializer(Serializer2* serializer,
+    ObjectSerializer(Serializer* serializer,
                      Object* o,
                      SnapshotByteSink* sink,
                      ReferenceRepresentation representation)
@@ -591,7 +347,7 @@ class Serializer2 : public SerDes {
    private:
     void OutputRawData(Address up_to);
 
-    Serializer2* serializer_;
+    Serializer* serializer_;
     HeapObject* object_;
     SnapshotByteSink* sink_;
     ReferenceRepresentation reference_representation_;
@@ -626,11 +382,14 @@ class Serializer2 : public SerDes {
   SnapshotByteSink* sink_;
   int current_root_index_;
   ExternalReferenceEncoder* external_reference_encoder_;
+  static bool serialization_enabled_;
+  // Did we already make use of the fact that serialization was not enabled?
+  static bool too_late_to_enable_now_;
 
   friend class ObjectSerializer;
-  friend class Deserializer2;
+  friend class Deserializer;
 
-  DISALLOW_COPY_AND_ASSIGN(Serializer2);
+  DISALLOW_COPY_AND_ASSIGN(Serializer);
 };
 
 } }  // namespace v8::internal
index 875cc96..c01baad 100644 (file)
@@ -38,15 +38,8 @@ namespace v8 {
 namespace internal {
 
 bool Snapshot::Deserialize(const byte* content, int len) {
-  Deserializer des(content, len);
-  des.GetFlags();
-  return V8::Initialize(&des);
-}
-
-
-bool Snapshot::Deserialize2(const byte* content, int len) {
   SnapshotByteSource source(content, len);
-  Deserializer2 deserializer(&source);
+  Deserializer deserializer(&source);
   return V8::Initialize(&deserializer);
 }
 
@@ -56,46 +49,17 @@ bool Snapshot::Initialize(const char* snapshot_file) {
     int len;
     byte* str = ReadBytes(snapshot_file, &len);
     if (!str) return false;
-    bool result = Deserialize(str, len);
-    DeleteArray(str);
-    return result;
-  } else if (size_ > 0) {
-    return Deserialize(data_, size_);
-  }
-  return false;
-}
-
-
-bool Snapshot::Initialize2(const char* snapshot_file) {
-  if (snapshot_file) {
-    int len;
-    byte* str = ReadBytes(snapshot_file, &len);
-    if (!str) return false;
-    Deserialize2(str, len);
+    Deserialize(str, len);
     DeleteArray(str);
     return true;
   } else if (size_ > 0) {
-    Deserialize2(data_, size_);
+    Deserialize(data_, size_);
     return true;
   }
   return false;
 }
 
 
-bool Snapshot::WriteToFile(const char* snapshot_file) {
-  Serializer ser;
-  ser.Serialize();
-  byte* str;
-  int len;
-  ser.Finalize(&str, &len);
-
-  int written = WriteBytes(snapshot_file, str, len);
-
-  DeleteArray(str);
-  return written == len;
-}
-
-
 class FileByteSink : public SnapshotByteSink {
  public:
   explicit FileByteSink(const char* snapshot_file) {
@@ -121,9 +85,9 @@ class FileByteSink : public SnapshotByteSink {
 };
 
 
-bool Snapshot::WriteToFile2(const char* snapshot_file) {
+bool Snapshot::WriteToFile(const char* snapshot_file) {
   FileByteSink file(snapshot_file);
-  Serializer2 ser(&file);
+  Serializer ser(&file);
   ser.Serialize();
   return true;
 }
index a3a3867..88ba8db 100644 (file)
@@ -37,7 +37,6 @@ class Snapshot {
   // NULL, use the internal snapshot instead. Returns false if no snapshot
   // could be found.
   static bool Initialize(const char* snapshot_file = NULL);
-  static bool Initialize2(const char* snapshot_file = NULL);
 
   // Returns whether or not the snapshot is enabled.
   static bool IsEnabled() { return size_ != 0; }
@@ -45,14 +44,12 @@ class Snapshot {
   // Write snapshot to the given file. Returns true if snapshot was written
   // successfully.
   static bool WriteToFile(const char* snapshot_file);
-  static bool WriteToFile2(const char* snapshot_file);
 
  private:
   static const byte data_[];
   static int size_;
 
   static bool Deserialize(const byte* content, int len);
-  static bool Deserialize2(const byte* content, int len);
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(Snapshot);
 };
index 93a116d..d172742 100644 (file)
--- a/src/v8.cc
+++ b/src/v8.cc
@@ -43,7 +43,7 @@ bool V8::has_been_setup_ = false;
 bool V8::has_been_disposed_ = false;
 bool V8::has_fatal_error_ = false;
 
-bool V8::Initialize(GenericDeserializer *des) {
+bool V8::Initialize(Deserializer *des) {
   bool create_heap_objects = des == NULL;
   if (has_been_disposed_ || has_fatal_error_) return false;
   if (IsRunning()) return true;
@@ -59,7 +59,6 @@ bool V8::Initialize(GenericDeserializer *des) {
 
   // Enable logging before setting up the heap
   Logger::Setup();
-  if (des) des->GetLog();
 
   // Setup the platform OS support.
   OS::Setup();
index 6c5546c..b3624c5 100644 (file)
--- a/src/v8.h
+++ b/src/v8.h
@@ -72,6 +72,8 @@
 namespace v8 {
 namespace internal {
 
+class Deserializer;
+
 class V8 : public AllStatic {
  public:
   // Global actions.
@@ -80,7 +82,7 @@ class V8 : public AllStatic {
   // created from scratch. If a non-null Deserializer is given, the
   // initial state is created by reading the deserialized data into an
   // empty heap.
-  static bool Initialize(GenericDeserializer* des);
+  static bool Initialize(Deserializer* des);
   static void TearDown();
   static bool IsRunning() { return is_running_; }
   // To be dead you have to have lived
index 35361b4..a143cbd 100644 (file)
@@ -33,12 +33,6 @@ test-debug/DebuggerAgent: PASS, (PASS || FAIL) if $system == linux
 # BUG(382): Weird test. Can't guarantee that it never times out.
 test-api/ApplyInterruption: PASS || TIMEOUT
 
-# This is about to go away anyway since new snapshot code is on the way.
-test-serialize/Deserialize: FAIL
-test-serialize/DeserializeAndRunScript: FAIL || CRASH
-test-serialize/DeserializeNatives: FAIL || CRASH
-test-serialize/DeserializeExtensions: FAIL || CRASH
-
 # These tests always fail.  They are here to test test.py.  If
 # they don't fail then test.py has failed.
 test-serialize/TestThatAlwaysFails: FAIL
index ee8ef51..9ed4874 100644 (file)
@@ -174,83 +174,32 @@ TEST(ExternalReferenceDecoder) {
 
 
 static void Serialize() {
-#ifdef DEBUG
-  FLAG_debug_serialization = true;
-#endif
-  StatsTable::SetCounterFunction(counter_function);
-
-  v8::HandleScope scope;
-  const int kExtensionCount = 1;
-  const char* extension_list[kExtensionCount] = { "v8/gc" };
-  v8::ExtensionConfiguration extensions(kExtensionCount, extension_list);
-  Serializer::Enable();
-  v8::Persistent<v8::Context> env = v8::Context::New(&extensions);
-  env->Enter();
-
-  Snapshot::WriteToFile(FLAG_testing_serialization_file);
-}
-
-
-static void Serialize2() {
   // We have to create one context.  One reason for this is so that the builtins
   // can be loaded from v8natives.js and their addresses can be processed.  This
   // will clear the pending fixups array, which would otherwise contain GC roots
   // that would confuse the serialization/deserialization process.
   v8::Persistent<v8::Context> env = v8::Context::New();
   env.Dispose();
-  Snapshot::WriteToFile2(FLAG_testing_serialization_file);
-}
-
-
-// Test that the whole heap can be serialized when running from a
-// bootstrapped heap.
-// (Smoke test.)
-TEST(Serialize) {
-  if (Snapshot::IsEnabled()) return;
-  Serialize();
+  Snapshot::WriteToFile(FLAG_testing_serialization_file);
 }
 
 
 // Test that the whole heap can be serialized.
-TEST(Serialize2) {
+TEST(Serialize) {
   Serializer::Enable();
   v8::V8::Initialize();
-  Serialize2();
+  Serialize();
 }
 
 
-// Test that the heap isn't destroyed after a serialization.
-TEST(SerializeNondestructive) {
-  if (Snapshot::IsEnabled()) return;
-  StatsTable::SetCounterFunction(counter_function);
-  v8::HandleScope scope;
-  Serializer::Enable();
-  v8::Persistent<v8::Context> env = v8::Context::New();
-  v8::Context::Scope context_scope(env);
-  Serializer().Serialize();
-  const char* c_source = "\"abcd\".charAt(2) == 'c'";
-  v8::Local<v8::String> source = v8::String::New(c_source);
-  v8::Local<v8::Script> script = v8::Script::Compile(source);
-  v8::Local<v8::Value> value = script->Run();
-  CHECK(value->BooleanValue());
-}
-
 //----------------------------------------------------------------------------
 // Tests that the heap can be deserialized.
 
 static void Deserialize() {
-#ifdef DEBUG
-  FLAG_debug_serialization = true;
-#endif
   CHECK(Snapshot::Initialize(FLAG_testing_serialization_file));
 }
 
 
-static void Deserialize2() {
-  CHECK(Snapshot::Initialize2(FLAG_testing_serialization_file));
-}
-
-
 static void SanityCheck() {
   v8::HandleScope scope;
 #ifdef DEBUG
@@ -269,15 +218,6 @@ DEPENDENT_TEST(Deserialize, Serialize) {
 
   Deserialize();
 
-  SanityCheck();
-}
-
-
-DEPENDENT_TEST(Deserialize2, Serialize2) {
-  v8::HandleScope scope;
-
-  Deserialize2();
-
   fflush(stdout);
 
   v8::Persistent<v8::Context> env = v8::Context::New();
@@ -287,23 +227,11 @@ DEPENDENT_TEST(Deserialize2, Serialize2) {
 }
 
 
-DEPENDENT_TEST(DeserializeAndRunScript, Serialize) {
+DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) {
   v8::HandleScope scope;
 
   Deserialize();
 
-  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(DeserializeAndRunScript2, Serialize2) {
-  v8::HandleScope scope;
-
-  Deserialize2();
-
   v8::Persistent<v8::Context> env = v8::Context::New();
   env->Enter();
 
@@ -314,31 +242,6 @@ DEPENDENT_TEST(DeserializeAndRunScript2, Serialize2) {
 }
 
 
-DEPENDENT_TEST(DeserializeNatives, Serialize) {
-  v8::HandleScope scope;
-
-  Deserialize();
-
-  const char* c_source = "\"abcd\".charAt(2) == 'c'";
-  v8::Local<v8::String> source = v8::String::New(c_source);
-  v8::Local<v8::Script> script = v8::Script::Compile(source);
-  v8::Local<v8::Value> value = script->Run();
-  CHECK(value->BooleanValue());
-}
-
-
-DEPENDENT_TEST(DeserializeExtensions, Serialize) {
-  v8::HandleScope scope;
-
-  Deserialize();
-  const char* c_source = "gc();";
-  v8::Local<v8::String> source = v8::String::New(c_source);
-  v8::Local<v8::Script> script = v8::Script::Compile(source);
-  v8::Local<v8::Value> value = script->Run();
-  CHECK(value->IsUndefined());
-}
-
-
 TEST(TestThatAlwaysSucceeds) {
 }