diff --git a/src/mksnapshot.cc b/src/mksnapshot.cc
index d1620bf..b4a4018 100644
--- a/src/mksnapshot.cc
+++ b/src/mksnapshot.cc
@@ -1,227 +1,236 @@
 // Copyright 2006-2008 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:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
+#include <errno.h>
+#include <stdio.h>
 #ifdef COMPRESS_STARTUP_DATA_BZ2
 #include <bzlib.h>
 #endif
 #include <signal.h>
 
-#include "v8.h"
+#include "src/v8.h"
 
-#include "bootstrapper.h"
-#include "natives.h"
-#include "platform.h"
-#include "serialize.h"
-#include "list.h"
+#include "include/libplatform/libplatform.h"
+#include "src/assembler.h"
+#include "src/base/platform/platform.h"
+#include "src/bootstrapper.h"
+#include "src/flags.h"
+#include "src/list.h"
+#include "src/natives.h"
+#include "src/serialize.h"
+
 
 using namespace v8;
 
-static const unsigned int kMaxCounters = 256;
-
-// A single counter in a counter collection.
-class Counter {
- public:
-  static const int kMaxNameSize = 64;
-  int32_t* Bind(const char* name) {
-    int i;
-    for (i = 0; i < kMaxNameSize - 1 && name[i]; i++) {
-      name_[i] = name[i];
-    }
-    name_[i] = '\0';
-    return &counter_;
-  }
- private:
-  int32_t counter_;
-  uint8_t name_[kMaxNameSize];
-};
-
-
-// A set of counters and associated information.  An instance of this
-// class is stored directly in the memory-mapped counters file if
-// the --save-counters options is used
-class CounterCollection {
- public:
-  CounterCollection() {
-    magic_number_ = 0xDEADFACE;
-    max_counters_ = kMaxCounters;
-    max_name_size_ = Counter::kMaxNameSize;
-    counters_in_use_ = 0;
-  }
-  Counter* GetNextCounter() {
-    if (counters_in_use_ == kMaxCounters) return NULL;
-    return &counters_[counters_in_use_++];
-  }
- private:
-  uint32_t magic_number_;
-  uint32_t max_counters_;
-  uint32_t max_name_size_;
-  uint32_t counters_in_use_;
-  Counter counters_[kMaxCounters];
-};
-
 
 class Compressor {
  public:
   virtual ~Compressor() {}
-  virtual bool Compress(i::Vector<char> input) = 0;
-  virtual i::Vector<char>* output() = 0;
+  virtual bool Compress(i::Vector<i::byte> input) = 0;
+  virtual i::Vector<i::byte>* output() = 0;
 };
 
 
-class PartialSnapshotSink : public i::SnapshotByteSink {
+class SnapshotWriter {
  public:
-  PartialSnapshotSink() : data_(), raw_size_(-1) { }
-  virtual ~PartialSnapshotSink() { data_.Free(); }
-  virtual void Put(int byte, const char* description) {
-    data_.Add(byte);
+  explicit SnapshotWriter(const char* snapshot_file)
+      : fp_(GetFileDescriptorOrDie(snapshot_file))
+      , raw_file_(NULL)
+      , raw_context_file_(NULL)
+      , startup_blob_file_(NULL)
+      , compressor_(NULL) {
   }
-  virtual int Position() { return data_.length(); }
-  void Print(FILE* fp) {
-    int length = Position();
-    for (int j = 0; j < length; j++) {
-      if ((j & 0x1f) == 0x1f) {
-        fprintf(fp, "\n");
-      }
-      if (j != 0) {
-        fprintf(fp, ",");
-      }
-      fprintf(fp, "%u", static_cast<unsigned char>(at(j)));
-    }
+
+  ~SnapshotWriter() {
+    fclose(fp_);
+    if (raw_file_) fclose(raw_file_);
+    if (raw_context_file_) fclose(raw_context_file_);
+    if (startup_blob_file_) fclose(startup_blob_file_);
   }
-  char at(int i) { return data_[i]; }
-  bool Compress(Compressor* compressor) {
-    ASSERT_EQ(-1, raw_size_);
-    raw_size_ = data_.length();
-    if (!compressor->Compress(data_.ToVector())) return false;
-    data_.Clear();
-    data_.AddAll(*compressor->output());
-    return true;
+
+  void SetCompressor(Compressor* compressor) {
+    compressor_ = compressor;
   }
-  int raw_size() { return raw_size_; }
+
+  void SetRawFiles(const char* raw_file, const char* raw_context_file) {
+    raw_file_ = GetFileDescriptorOrDie(raw_file);
+    raw_context_file_ = GetFileDescriptorOrDie(raw_context_file);
+  }
+
+  void SetStartupBlobFile(const char* startup_blob_file) {
+    if (startup_blob_file != NULL)
+      startup_blob_file_ = GetFileDescriptorOrDie(startup_blob_file);
+  }
+
+  void WriteSnapshot(const i::List<i::byte>& snapshot_data,
+                     const i::Serializer& serializer,
+                     const i::List<i::byte>& context_snapshot_data,
+                     const i::Serializer& context_serializer) const {
+    WriteSnapshotFile(snapshot_data, serializer,
+                      context_snapshot_data, context_serializer);
+    MaybeWriteStartupBlob(snapshot_data, serializer,
+                          context_snapshot_data, context_serializer);
+  }
 
  private:
-  i::List<char> data_;
-  int raw_size_;
-};
+  void MaybeWriteStartupBlob(const i::List<i::byte>& snapshot_data,
+                             const i::Serializer& serializer,
+                             const i::List<i::byte>& context_snapshot_data,
+                             const i::Serializer& context_serializer) const {
+    if (!startup_blob_file_)
+      return;
 
+    i::List<i::byte> startup_blob;
+    i::ListSnapshotSink sink(&startup_blob);
 
-class CppByteSink : public PartialSnapshotSink {
- public:
-  explicit CppByteSink(const char* snapshot_file) {
-    fp_ = i::OS::FOpen(snapshot_file, "wb");
-    if (fp_ == NULL) {
-      i::PrintF("Unable to write to snapshot file \"%s\"\n", snapshot_file);
+    int spaces[] = {
+        i::NEW_SPACE, i::OLD_POINTER_SPACE, i::OLD_DATA_SPACE, i::CODE_SPACE,
+        i::MAP_SPACE, i::CELL_SPACE,  i::PROPERTY_CELL_SPACE
+    };
+
+    i::byte* snapshot_bytes = snapshot_data.begin();
+    sink.PutBlob(snapshot_bytes, snapshot_data.length(), "snapshot");
+    for (size_t i = 0; i < arraysize(spaces); ++i)
+      sink.PutInt(serializer.CurrentAllocationAddress(spaces[i]), "spaces");
+
+    i::byte* context_bytes = context_snapshot_data.begin();
+    sink.PutBlob(context_bytes, context_snapshot_data.length(), "context");
+    for (size_t i = 0; i < arraysize(spaces); ++i)
+      sink.PutInt(context_serializer.CurrentAllocationAddress(spaces[i]),
+                  "spaces");
+
+    size_t written = fwrite(startup_blob.begin(), 1, startup_blob.length(),
+                            startup_blob_file_);
+    if (written != (size_t)startup_blob.length()) {
+      i::PrintF("Writing snapshot file failed.. Aborting.\n");
       exit(1);
     }
+  }
+
+  void WriteSnapshotFile(const i::List<i::byte>& snapshot_data,
+                         const i::Serializer& serializer,
+                         const i::List<i::byte>& context_snapshot_data,
+                         const i::Serializer& context_serializer) const {
+    WriteFilePrefix();
+    WriteData("", snapshot_data, raw_file_);
+    WriteData("context_", context_snapshot_data, raw_context_file_);
+    WriteMeta("context_", context_serializer);
+    WriteMeta("", serializer);
+    WriteFileSuffix();
+  }
+
+  void WriteFilePrefix() const {
     fprintf(fp_, "// Autogenerated snapshot file. Do not edit.\n\n");
-    fprintf(fp_, "#include \"v8.h\"\n");
-    fprintf(fp_, "#include \"platform.h\"\n\n");
-    fprintf(fp_, "#include \"snapshot.h\"\n\n");
-    fprintf(fp_, "namespace v8 {\nnamespace internal {\n\n");
-    fprintf(fp_, "const byte Snapshot::data_[] = {");
+    fprintf(fp_, "#include \"src/v8.h\"\n");
+    fprintf(fp_, "#include \"src/base/platform/platform.h\"\n\n");
+    fprintf(fp_, "#include \"src/snapshot.h\"\n\n");
+    fprintf(fp_, "namespace v8 {\n");
+    fprintf(fp_, "namespace internal {\n\n");
   }
 
-  virtual ~CppByteSink() {
-    fprintf(fp_, "const int Snapshot::size_ = %d;\n", Position());
-#ifdef COMPRESS_STARTUP_DATA_BZ2
-    fprintf(fp_, "const byte* Snapshot::raw_data_ = NULL;\n");
-    fprintf(fp_,
-            "const int Snapshot::raw_size_ = %d;\n\n",
-            raw_size());
-#else
-    fprintf(fp_,
-            "const byte* Snapshot::raw_data_ = Snapshot::data_;\n");
-    fprintf(fp_,
-            "const int Snapshot::raw_size_ = Snapshot::size_;\n\n");
-#endif
-    fprintf(fp_, "} }  // namespace v8::internal\n");
-    fclose(fp_);
+  void WriteFileSuffix() const {
+    fprintf(fp_, "}  // namespace internal\n");
+    fprintf(fp_, "}  // namespace v8\n");
   }
 
-  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_, "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 WriteData(const char* prefix, const i::List<i::byte>& source_data,
+                 FILE* raw_file) const {
+    const i::List<i::byte>* data_to_be_written = NULL;
+    i::List<i::byte> compressed_data;
+    if (!compressor_) {
+      data_to_be_written = &source_data;
+    } else if (compressor_->Compress(source_data.ToVector())) {
+      compressed_data.AddAll(*compressor_->output());
+      data_to_be_written = &compressed_data;
+    } else {
+      i::PrintF("Compression failed. Aborting.\n");
+      exit(1);
+    }
+
+    DCHECK(data_to_be_written);
+    MaybeWriteRawFile(data_to_be_written, raw_file);
+    WriteData(prefix, source_data, data_to_be_written);
   }
 
-  void WritePartialSnapshot() {
-    int length = partial_sink_.Position();
-    fprintf(fp_, "};\n\n");
-    fprintf(fp_, "const int Snapshot::context_size_ = %d;\n",  length);
-#ifdef COMPRESS_STARTUP_DATA_BZ2
-    fprintf(fp_,
-            "const int Snapshot::context_raw_size_ = %d;\n",
-            partial_sink_.raw_size());
-#else
-    fprintf(fp_,
-            "const int Snapshot::context_raw_size_ = "
-            "Snapshot::context_size_;\n");
-#endif
-    fprintf(fp_, "const byte Snapshot::context_data_[] = {\n");
-    partial_sink_.Print(fp_);
-    fprintf(fp_, "};\n\n");
-#ifdef COMPRESS_STARTUP_DATA_BZ2
-    fprintf(fp_, "const byte* Snapshot::context_raw_data_ = NULL;\n");
-#else
-    fprintf(fp_, "const byte* Snapshot::context_raw_data_ ="
-            " Snapshot::context_data_;\n");
-#endif
+  void MaybeWriteRawFile(const i::List<i::byte>* data, FILE* raw_file) const {
+    if (!data || !raw_file)
+      return;
+
+    // Sanity check, whether i::List iterators truly return pointers to an
+    // internal array.
+    DCHECK(data->end() - data->begin() == data->length());
+
+    size_t written = fwrite(data->begin(), 1, data->length(), raw_file);
+    if (written != (size_t)data->length()) {
+      i::PrintF("Writing raw file failed.. Aborting.\n");
+      exit(1);
+    }
   }
 
-  void WriteSnapshot() {
-    Print(fp_);
+  void WriteData(const char* prefix, const i::List<i::byte>& source_data,
+                 const i::List<i::byte>* data_to_be_written) const {
+    fprintf(fp_, "const byte Snapshot::%sdata_[] = {\n", prefix);
+    WriteSnapshotData(data_to_be_written);
+    fprintf(fp_, "};\n");
+    fprintf(fp_, "const int Snapshot::%ssize_ = %d;\n", prefix,
+            data_to_be_written->length());
+
+    if (data_to_be_written == &source_data) {
+      fprintf(fp_, "const byte* Snapshot::%sraw_data_ = Snapshot::%sdata_;\n",
+              prefix, prefix);
+      fprintf(fp_, "const int Snapshot::%sraw_size_ = Snapshot::%ssize_;\n",
+              prefix, prefix);
+    } else {
+      fprintf(fp_, "const byte* Snapshot::%sraw_data_ = NULL;\n", prefix);
+      fprintf(fp_, "const int Snapshot::%sraw_size_ = %d;\n",
+              prefix, source_data.length());
+    }
+    fprintf(fp_, "\n");
   }
 
-  PartialSnapshotSink* partial_sink() { return &partial_sink_; }
+  void WriteMeta(const char* prefix, const i::Serializer& ser) const {
+    WriteSizeVar(ser, prefix, "new", i::NEW_SPACE);
+    WriteSizeVar(ser, prefix, "pointer", i::OLD_POINTER_SPACE);
+    WriteSizeVar(ser, prefix, "data", i::OLD_DATA_SPACE);
+    WriteSizeVar(ser, prefix, "code", i::CODE_SPACE);
+    WriteSizeVar(ser, prefix, "map", i::MAP_SPACE);
+    WriteSizeVar(ser, prefix, "cell", i::CELL_SPACE);
+    WriteSizeVar(ser, prefix, "property_cell", i::PROPERTY_CELL_SPACE);
+    fprintf(fp_, "\n");
+  }
 
- private:
+  void WriteSizeVar(const i::Serializer& ser, const char* prefix,
+                    const char* name, int space) const {
+    fprintf(fp_, "const int Snapshot::%s%s_space_used_ = %d;\n",
+            prefix, name, ser.CurrentAllocationAddress(space));
+  }
+
+  void WriteSnapshotData(const i::List<i::byte>* data) const {
+    for (int i = 0; i < data->length(); i++) {
+      if ((i & 0x1f) == 0x1f)
+        fprintf(fp_, "\n");
+      if (i > 0)
+        fprintf(fp_, ",");
+      fprintf(fp_, "%u", static_cast<unsigned char>(data->at(i)));
+    }
+    fprintf(fp_, "\n");
+  }
+
+  FILE* GetFileDescriptorOrDie(const char* filename) {
+    FILE* fp = base::OS::FOpen(filename, "wb");
+    if (fp == NULL) {
+      i::PrintF("Unable to open file \"%s\" for writing.\n", filename);
+      exit(1);
+    }
+    return fp;
+  }
+
   FILE* fp_;
-  PartialSnapshotSink partial_sink_;
+  FILE* raw_file_;
+  FILE* raw_context_file_;
+  FILE* startup_blob_file_;
+  Compressor* compressor_;
 };
 
 
@@ -263,7 +272,7 @@
                              int* raw_data_size,
                              const char* compressed_data,
                              int compressed_data_size) {
-    ASSERT_EQ(StartupData::kBZip2,
+    DCHECK_EQ(StartupData::kBZip2,
               V8::GetCompressedStartupDataAlgorithm());
     unsigned int decompressed_size = *raw_data_size;
     int result =
@@ -281,6 +290,18 @@
 #endif
 
 
+void DumpException(Handle<Message> message) {
+  String::Utf8Value message_string(message->Get());
+  String::Utf8Value message_line(message->GetSourceLine());
+  fprintf(stderr, "%s at line %d\n", *message_string, message->GetLineNumber());
+  fprintf(stderr, "%s\n", *message_line);
+  for (int i = 0; i <= message->GetEndColumn(); ++i) {
+    fprintf(stderr, "%c", i < message->GetStartColumn() ? ' ' : '^');
+  }
+  fprintf(stderr, "\n");
+}
+
+
 int main(int argc, char** argv) {
   // By default, log code create information in the snapshot.
   i::FLAG_log_code = true;
@@ -293,6 +314,13 @@
     i::FlagList::PrintHelp();
     return !i::FLAG_help;
   }
+
+  i::CpuFeatures::Probe(true);
+  V8::InitializeICU();
+  v8::Platform* platform = v8::platform::CreateDefaultPlatform();
+  v8::V8::InitializePlatform(platform);
+  v8::V8::Initialize();
+
 #ifdef COMPRESS_STARTUP_DATA_BZ2
   BZip2Decompressor natives_decompressor;
   int bz2_result = natives_decompressor.Decompress();
@@ -301,48 +329,110 @@
     exit(1);
   }
 #endif
-  i::Serializer::Enable();
-  Persistent<Context> context = v8::Context::New();
-  ASSERT(!context.IsEmpty());
-  // Make sure all builtin scripts are cached.
-  { HandleScope scope;
-    for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) {
-      i::Isolate::Current()->bootstrapper()->NativesSourceLookup(i);
+  i::FLAG_logfile_per_isolate = false;
+
+  Isolate::CreateParams params;
+  params.enable_serializer = true;
+  Isolate* isolate = v8::Isolate::New(params);
+  { Isolate::Scope isolate_scope(isolate);
+    i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
+
+    Persistent<Context> context;
+    {
+      HandleScope handle_scope(isolate);
+      context.Reset(isolate, Context::New(isolate));
+    }
+
+    if (context.IsEmpty()) {
+      fprintf(stderr,
+              "\nException thrown while compiling natives - see above.\n\n");
+      exit(1);
+    }
+    if (i::FLAG_extra_code != NULL) {
+      // Capture 100 frames if anything happens.
+      V8::SetCaptureStackTraceForUncaughtExceptions(true, 100);
+      HandleScope scope(isolate);
+      v8::Context::Scope cscope(v8::Local<v8::Context>::New(isolate, context));
+      const char* name = i::FLAG_extra_code;
+      FILE* file = base::OS::FOpen(name, "rb");
+      if (file == NULL) {
+        fprintf(stderr, "Failed to open '%s': errno %d\n", name, errno);
+        exit(1);
+      }
+
+      fseek(file, 0, SEEK_END);
+      int size = ftell(file);
+      rewind(file);
+
+      char* chars = new char[size + 1];
+      chars[size] = '\0';
+      for (int i = 0; i < size;) {
+        int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
+        if (read < 0) {
+          fprintf(stderr, "Failed to read '%s': errno %d\n", name, errno);
+          exit(1);
+        }
+        i += read;
+      }
+      fclose(file);
+      Local<String> source = String::NewFromUtf8(isolate, chars);
+      TryCatch try_catch;
+      Local<Script> script = Script::Compile(source);
+      if (try_catch.HasCaught()) {
+        fprintf(stderr, "Failure compiling '%s'\n", name);
+        DumpException(try_catch.Message());
+        exit(1);
+      }
+      script->Run();
+      if (try_catch.HasCaught()) {
+        fprintf(stderr, "Failure running '%s'\n", name);
+        DumpException(try_catch.Message());
+        exit(1);
+      }
+    }
+    // Make sure all builtin scripts are cached.
+    { HandleScope scope(isolate);
+      for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) {
+        internal_isolate->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.
+    internal_isolate->heap()->CollectAllGarbage(
+        i::Heap::kNoGCFlags, "mksnapshot");
+    i::Object* raw_context = *v8::Utils::OpenPersistent(context);
+    context.Reset();
+
+    // This results in a somewhat smaller snapshot, probably because it gets
+    // rid of some things that are cached between garbage collections.
+    i::List<i::byte> snapshot_data;
+    i::ListSnapshotSink snapshot_sink(&snapshot_data);
+    i::StartupSerializer ser(internal_isolate, &snapshot_sink);
+    ser.SerializeStrongReferences();
+
+    i::List<i::byte> context_data;
+    i::ListSnapshotSink contex_sink(&context_data);
+    i::PartialSerializer context_ser(internal_isolate, &ser, &contex_sink);
+    context_ser.Serialize(&raw_context);
+    ser.SerializeWeakReferences();
+
+    {
+      SnapshotWriter writer(argv[1]);
+      if (i::FLAG_raw_file && i::FLAG_raw_context_file)
+        writer.SetRawFiles(i::FLAG_raw_file, i::FLAG_raw_context_file);
+      if (i::FLAG_startup_blob)
+        writer.SetStartupBlobFile(i::FLAG_startup_blob);
+  #ifdef COMPRESS_STARTUP_DATA_BZ2
+      BZip2Compressor bzip2;
+      writer.SetCompressor(&bzip2);
+  #endif
+      writer.WriteSnapshot(snapshot_data, ser, context_data, context_ser);
     }
   }
-  // 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.
-  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags, "mksnapshot");
-  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::StartupSerializer ser(&sink);
-  ser.SerializeStrongReferences();
 
-  i::PartialSerializer partial_ser(&ser, sink.partial_sink());
-  partial_ser.Serialize(&raw_context);
-
-  ser.SerializeWeakReferences();
-
-#ifdef COMPRESS_STARTUP_DATA_BZ2
-  BZip2Compressor compressor;
-  if (!sink.Compress(&compressor))
-    return 1;
-  if (!sink.partial_sink()->Compress(&compressor))
-    return 1;
-#endif
-  sink.WriteSnapshot();
-  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));
+  isolate->Dispose();
+  V8::Dispose();
+  V8::ShutdownPlatform();
+  delete platform;
   return 0;
 }
