1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2008 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef COMPRESS_STARTUP_DATA_BZ2 29257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include <bzlib.h> 30257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <signal.h> 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "bootstrapper.h" 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "natives.h" 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "platform.h" 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "serialize.h" 393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#include "list.h" 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing namespace v8; 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const unsigned int kMaxCounters = 256; 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A single counter in a counter collection. 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Counter { 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kMaxNameSize = 64; 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t* Bind(const char* name) { 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int i; 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (i = 0; i < kMaxNameSize - 1 && name[i]; i++) { 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block name_[i] = name[i]; 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block name_[i] = '\0'; 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return &counter_; 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t counter_; 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint8_t name_[kMaxNameSize]; 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A set of counters and associated information. An instance of this 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// class is stored directly in the memory-mapped counters file if 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the --save-counters options is used 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CounterCollection { 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CounterCollection() { 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block magic_number_ = 0xDEADFACE; 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block max_counters_ = kMaxCounters; 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block max_name_size_ = Counter::kMaxNameSize; 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block counters_in_use_ = 0; 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counter* GetNextCounter() { 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (counters_in_use_ == kMaxCounters) return NULL; 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return &counters_[counters_in_use_++]; 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t magic_number_; 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t max_counters_; 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t max_name_size_; 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t counters_in_use_; 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Counter counters_[kMaxCounters]; 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 87257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass Compressor { 88257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 89257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual ~Compressor() {} 90257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual bool Compress(i::Vector<char> input) = 0; 91257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual i::Vector<char>* output() = 0; 92257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 93257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 94257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 95257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass PartialSnapshotSink : public i::SnapshotByteSink { 96257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 97257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch PartialSnapshotSink() : data_(), raw_size_(-1) { } 98257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual ~PartialSnapshotSink() { data_.Free(); } 99257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual void Put(int byte, const char* description) { 100257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch data_.Add(byte); 101257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 102257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual int Position() { return data_.length(); } 103257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void Print(FILE* fp) { 104257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int length = Position(); 105257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch for (int j = 0; j < length; j++) { 106257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if ((j & 0x1f) == 0x1f) { 107257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch fprintf(fp, "\n"); 108257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 109257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (j != 0) { 110257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch fprintf(fp, ","); 111257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch fprintf(fp, "%u", static_cast<unsigned char>(at(j))); 113257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 114257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 115257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch char at(int i) { return data_[i]; } 116257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool Compress(Compressor* compressor) { 117257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ASSERT_EQ(-1, raw_size_); 118257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch raw_size_ = data_.length(); 119257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!compressor->Compress(data_.ToVector())) return false; 120257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch data_.Clear(); 121257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch data_.AddAll(*compressor->output()); 122257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return true; 123257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 124257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int raw_size() { return raw_size_; } 1253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 126257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private: 127257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch i::List<char> data_; 128257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int raw_size_; 129257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 130257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 131257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 132257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass CppByteSink : public PartialSnapshotSink { 133d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block public: 134257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch explicit CppByteSink(const char* snapshot_file) { 135d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block fp_ = i::OS::FOpen(snapshot_file, "wb"); 136d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (fp_ == NULL) { 137d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block i::PrintF("Unable to write to snapshot file \"%s\"\n", snapshot_file); 138d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block exit(1); 139d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 140d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block fprintf(fp_, "// Autogenerated snapshot file. Do not edit.\n\n"); 141d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block fprintf(fp_, "#include \"v8.h\"\n"); 142d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block fprintf(fp_, "#include \"platform.h\"\n\n"); 143d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block fprintf(fp_, "#include \"snapshot.h\"\n\n"); 144d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block fprintf(fp_, "namespace v8 {\nnamespace internal {\n\n"); 145d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block fprintf(fp_, "const byte Snapshot::data_[] = {"); 146d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 148d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block virtual ~CppByteSink() { 149257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch fprintf(fp_, "const int Snapshot::size_ = %d;\n", Position()); 150257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef COMPRESS_STARTUP_DATA_BZ2 151257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch fprintf(fp_, "const byte* Snapshot::raw_data_ = NULL;\n"); 152257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch fprintf(fp_, 153257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch "const int Snapshot::raw_size_ = %d;\n\n", 154257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch raw_size()); 155257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#else 156257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch fprintf(fp_, 157257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch "const byte* Snapshot::raw_data_ = Snapshot::data_;\n"); 158257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch fprintf(fp_, 159257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch "const int Snapshot::raw_size_ = Snapshot::size_;\n\n"); 160257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif 1613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu fprintf(fp_, "} } // namespace v8::internal\n"); 1623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu fclose(fp_); 1633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 1643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void WriteSpaceUsed( 1663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int new_space_used, 1673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int pointer_space_used, 1683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int data_space_used, 1693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int code_space_used, 1703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int map_space_used, 1713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int cell_space_used, 1723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int large_space_used) { 1733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu fprintf(fp_, "const int Snapshot::new_space_used_ = %d;\n", new_space_used); 1743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu fprintf(fp_, 1753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu "const int Snapshot::pointer_space_used_ = %d;\n", 1763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu pointer_space_used); 1773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu fprintf(fp_, 1783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu "const int Snapshot::data_space_used_ = %d;\n", 1793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu data_space_used); 1803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu fprintf(fp_, 1813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu "const int Snapshot::code_space_used_ = %d;\n", 1823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu code_space_used); 1833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu fprintf(fp_, "const int Snapshot::map_space_used_ = %d;\n", map_space_used); 1843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu fprintf(fp_, 1853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu "const int Snapshot::cell_space_used_ = %d;\n", 1863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu cell_space_used); 1873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu fprintf(fp_, 1883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu "const int Snapshot::large_space_used_ = %d;\n", 1893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu large_space_used); 1903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 1913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu void WritePartialSnapshot() { 1933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int length = partial_sink_.Position(); 1943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu fprintf(fp_, "};\n\n"); 1953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu fprintf(fp_, "const int Snapshot::context_size_ = %d;\n", length); 196257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef COMPRESS_STARTUP_DATA_BZ2 197257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch fprintf(fp_, 198257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch "const int Snapshot::context_raw_size_ = %d;\n", 199257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch partial_sink_.raw_size()); 200257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#else 201257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch fprintf(fp_, 202257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch "const int Snapshot::context_raw_size_ = " 203257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch "Snapshot::context_size_;\n"); 204257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif 2053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu fprintf(fp_, "const byte Snapshot::context_data_[] = {\n"); 206257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch partial_sink_.Print(fp_); 207257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch fprintf(fp_, "};\n\n"); 208257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef COMPRESS_STARTUP_DATA_BZ2 209257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch fprintf(fp_, "const byte* Snapshot::context_raw_data_ = NULL;\n"); 210257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#else 211257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch fprintf(fp_, "const byte* Snapshot::context_raw_data_ =" 212257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch " Snapshot::context_data_;\n"); 213257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 215d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 216257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void WriteSnapshot() { 217257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Print(fp_); 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 219d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 220257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch PartialSnapshotSink* partial_sink() { return &partial_sink_; } 221257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 222257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private: 223257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch FILE* fp_; 224257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch PartialSnapshotSink partial_sink_; 225257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 226e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 228257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef COMPRESS_STARTUP_DATA_BZ2 229257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass BZip2Compressor : public Compressor { 230257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 231257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BZip2Compressor() : output_(NULL) {} 232257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual ~BZip2Compressor() { 233257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch delete output_; 234257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 235257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual bool Compress(i::Vector<char> input) { 236257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch delete output_; 237257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch output_ = new i::ScopedVector<char>((input.length() * 101) / 100 + 1000); 238257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch unsigned int output_length_ = output_->length(); 239257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int result = BZ2_bzBuffToBuffCompress(output_->start(), &output_length_, 240257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch input.start(), input.length(), 241257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9, 1, 0); 242257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (result == BZ_OK) { 243257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch output_->Truncate(output_length_); 244257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return true; 245257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 246257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch fprintf(stderr, "bzlib error code: %d\n", result); 247257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return false; 2483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 249257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 250257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual i::Vector<char>* output() { return output_; } 2513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 252d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block private: 253257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch i::ScopedVector<char>* output_; 254d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}; 2553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass BZip2Decompressor : public StartupDataDecompressor { 2583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public: 2593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual ~BZip2Decompressor() { } 2603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch protected: 2623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual int DecompressData(char* raw_data, 2633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int* raw_data_size, 2643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const char* compressed_data, 2653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int compressed_data_size) { 2663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT_EQ(StartupData::kBZip2, 2673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch V8::GetCompressedStartupDataAlgorithm()); 2683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch unsigned int decompressed_size = *raw_data_size; 2693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int result = 2703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch BZ2_bzBuffToBuffDecompress(raw_data, 2713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch &decompressed_size, 2723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const_cast<char*>(compressed_data), 2733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch compressed_data_size, 2743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 0, 1); 2753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (result == BZ_OK) { 2763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch *raw_data_size = decompressed_size; 2773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return result; 2793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}; 281257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint main(int argc, char** argv) { 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // By default, log code create information in the snapshot. 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::FLAG_log_code = true; 2873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Print the usage if an error occurs when parsing the command line 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // flags or if the help flag is set. 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int result = i::FlagList::SetFlagsFromCommandLine(&argc, argv, true); 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result > 0 || argc != 2 || i::FLAG_help) { 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("Usage: %s [flag] ... outfile\n", argv[0]); 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::FlagList::PrintHelp(); 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return !i::FLAG_help; 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef COMPRESS_STARTUP_DATA_BZ2 2973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch BZip2Decompressor natives_decompressor; 2983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int bz2_result = natives_decompressor.Decompress(); 2993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (bz2_result != BZ_OK) { 3003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch fprintf(stderr, "bzip error code: %d\n", bz2_result); 3013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch exit(1); 3023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Serializer::Enable(); 305d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Persistent<Context> context = v8::Context::New(); 306e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(!context.IsEmpty()); 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure all builtin scripts are cached. 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { HandleScope scope; 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) { 31044f0eee88ff00398ff7f715fab053374d808c90dSteve Block i::Isolate::Current()->bootstrapper()->NativesSourceLookup(i); 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // If we don't do this then we end up with a stray root pointing at the 3143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // context even after we have disposed of the context. 3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(i::Heap::kNoGCFlags, "mksnapshot"); 3163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu i::Object* raw_context = *(v8::Utils::OpenHandle(*context)); 317d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block context.Dispose(); 318d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CppByteSink sink(argv[1]); 319d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // This results in a somewhat smaller snapshot, probably because it gets rid 320d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // of some things that are cached between garbage collections. 321d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke i::StartupSerializer ser(&sink); 3223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ser.SerializeStrongReferences(); 3233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu i::PartialSerializer partial_ser(&ser, sink.partial_sink()); 3253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu partial_ser.Serialize(&raw_context); 3263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ser.SerializeWeakReferences(); 3283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 329257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef COMPRESS_STARTUP_DATA_BZ2 330257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BZip2Compressor compressor; 331257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!sink.Compress(&compressor)) 332257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return 1; 333257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!sink.partial_sink()->Compress(&compressor)) 334257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return 1; 335257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif 336257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch sink.WriteSnapshot(); 3373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu sink.WritePartialSnapshot(); 3383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu sink.WriteSpaceUsed( 3403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu partial_ser.CurrentAllocationAddress(i::NEW_SPACE), 3413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu partial_ser.CurrentAllocationAddress(i::OLD_POINTER_SPACE), 3423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu partial_ser.CurrentAllocationAddress(i::OLD_DATA_SPACE), 3433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu partial_ser.CurrentAllocationAddress(i::CODE_SPACE), 3443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu partial_ser.CurrentAllocationAddress(i::MAP_SPACE), 3453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu partial_ser.CurrentAllocationAddress(i::CELL_SPACE), 3463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu partial_ser.CurrentAllocationAddress(i::LO_SPACE)); 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 0; 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 349