serialize.h revision b0fe1620dcb4135ac3ab2d66ff93072373911299
1d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Copyright 2006-2009 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 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_SERIALIZE_H_ 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_SERIALIZE_H_ 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "hashmap.h" 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A TypeCode is used to distinguish different kinds of external reference. 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// It is a single bit to make testing for types easy. 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum TypeCode { 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UNCLASSIFIED, // One-of-a-kind references. 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block BUILTIN, 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RUNTIME_FUNCTION, 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block IC_UTILITY, 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DEBUG_ADDRESS, 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block STATS_COUNTER, 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TOP_ADDRESS, 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block C_BUILTIN, 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EXTENSION, 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ACCESSOR, 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RUNTIME_ENTRY, 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block STUB_CACHE_TABLE 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst int kTypeCodeCount = STUB_CACHE_TABLE + 1; 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst int kFirstTypeCode = UNCLASSIFIED; 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst int kReferenceIdBits = 16; 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst int kReferenceIdMask = (1 << kReferenceIdBits) - 1; 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst int kReferenceTypeShift = kReferenceIdBits; 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst int kDebugRegisterBits = 4; 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst int kDebugIdShift = kDebugRegisterBits; 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ExternalReferenceEncoder { 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExternalReferenceEncoder(); 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t Encode(Address key) const; 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* NameOfAddress(Address key) const; 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HashMap encodings_; 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static uint32_t Hash(Address key) { 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key) >> 2); 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int IndexOf(Address key) const; 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static bool Match(void* key1, void* key2) { return key1 == key2; } 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Put(Address key, int index); 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ExternalReferenceDecoder { 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExternalReferenceDecoder(); 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~ExternalReferenceDecoder(); 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address Decode(uint32_t key) const { 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (key == 0) return NULL; 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return *Lookup(key); 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address** encodings_; 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address* Lookup(uint32_t key) const { 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int type = key >> kReferenceTypeShift; 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(kFirstTypeCode <= type && type < kTypeCodeCount); 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int id = key & kReferenceIdMask; 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return &encodings_[type][id]; 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Put(uint32_t key, Address value) { 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *Lookup(key) = value; 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 111d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockclass SnapshotByteSource { 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 113d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block SnapshotByteSource(const byte* array, int length) 114d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block : data_(array), length_(length), position_(0) { } 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 116d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block bool HasMore() { return position_ < length_; } 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 118d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block int Get() { 119d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(position_ < length_); 120d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return data_[position_++]; 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu inline void CopyRaw(byte* to, int number_of_bytes); 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu inline int GetInt(); 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 127d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block bool AtEOF() { 128d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return position_ == length_; 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 131d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int position() { return position_; } 132e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 134d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block const byte* data_; 135d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block int length_; 136d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block int position_; 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 140f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke// It is very common to have a reference to objects at certain offsets in the 141f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke// heap. These offsets have been determined experimentally. We code 142f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke// references to such objects in a single byte that encodes the way the pointer 143f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke// is written (only plain pointers allowed), the space number and the offset. 144f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke// This only works for objects in the first page of a space. Don't use this for 145f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke// things in newspace since it bypasses the write barrier. 146f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 147f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkestatic const int k64 = (sizeof(uintptr_t) - 4) / 4; 148f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 149f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#define COMMON_REFERENCE_PATTERNS(f) \ 150f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke f(kNumberOfSpaces, 2, (11 - k64)) \ 151f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke f((kNumberOfSpaces + 1), 2, 0) \ 152f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke f((kNumberOfSpaces + 2), 2, (142 - 16 * k64)) \ 153f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke f((kNumberOfSpaces + 3), 2, (74 - 15 * k64)) \ 154f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke f((kNumberOfSpaces + 4), 2, 5) \ 155f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke f((kNumberOfSpaces + 5), 1, 135) \ 156f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke f((kNumberOfSpaces + 6), 2, (228 - 39 * k64)) 157d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 158d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define COMMON_RAW_LENGTHS(f) \ 159d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block f(1, 1) \ 160d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block f(2, 2) \ 161d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block f(3, 3) \ 162d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block f(4, 4) \ 163d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block f(5, 5) \ 164d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block f(6, 6) \ 165d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block f(7, 7) \ 166d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block f(8, 8) \ 167d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block f(9, 12) \ 168d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block f(10, 16) \ 169d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block f(11, 20) \ 170d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block f(12, 24) \ 171d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block f(13, 28) \ 172d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block f(14, 32) \ 173d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block f(15, 36) 174d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 175d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// The Serializer/Deserializer class is a common superclass for Serializer and 176d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// Deserializer which is used to store common constants and methods used by 177d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// both. 178d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeclass SerializerDeserializer: public ObjectVisitor { 179d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke public: 180d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke static void Iterate(ObjectVisitor* visitor); 181d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke static void SetSnapshotCacheSize(int size); 182d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 183d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block protected: 184f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Where the pointed-to object can be found: 185f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke enum Where { 186f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke kNewObject = 0, // Object is next in snapshot. 187f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // 1-8 One per space. 188f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke kRootArray = 0x9, // Object is found in root array. 189f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke kPartialSnapshotCache = 0xa, // Object is in the cache. 190f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke kExternalReference = 0xb, // Pointer to an external reference. 191f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // 0xc-0xf Free. 192f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke kBackref = 0x10, // Object is described relative to end. 193f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // 0x11-0x18 One per space. 194f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // 0x19-0x1f Common backref offsets. 195f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke kFromStart = 0x20, // Object is described relative to start. 196f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // 0x21-0x28 One per space. 197f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // 0x29-0x2f Free. 198f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // 0x30-0x3f Used by misc tags below. 199f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke kPointedToMask = 0x3f 200d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block }; 201f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 202f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // How to code the pointer to the object. 203f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke enum HowToCode { 204f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke kPlain = 0, // Straight pointer. 205f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // What this means depends on the architecture: 206f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke kFromCode = 0x40, // A pointer inlined in code. 207f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke kHowToCodeMask = 0x40 208f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke }; 209f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 210f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Where to point within the object. 211f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke enum WhereToPoint { 212f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke kStartOfObject = 0, 213f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke kFirstInstruction = 0x80, 214f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke kWhereToPointMask = 0x80 215f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke }; 216f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 217f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Misc. 218f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Raw data to be copied from the snapshot. 219f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke static const int kRawData = 0x30; 220f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Some common raw lengths: 0x31-0x3f 221f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // A tag emitted at strategic points in the snapshot to delineate sections. 222f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // If the deserializer does not find these at the expected moments then it 223f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // is an indication that the snapshot and the VM do not fit together. 224f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Examine the build process for architecture, version or configuration 225f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // mismatches. 226f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke static const int kSynchronize = 0x70; 227f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Used for the source code of the natives, which is in the executable, but 228f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // is referred to from external strings in the snapshot. 229f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke static const int kNativesStringResource = 0x71; 230f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke static const int kNewPage = 0x72; 231f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // 0x73-0x7f Free. 232f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // 0xb0-0xbf Free. 233f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // 0xf0-0xff Free. 234f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 235f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 236d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static const int kLargeData = LAST_SPACE; 237d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static const int kLargeCode = kLargeData + 1; 238d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static const int kLargeFixedArray = kLargeCode + 1; 239d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static const int kNumberOfSpaces = kLargeFixedArray + 1; 240f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke static const int kAnyOldSpace = -1; 241d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 242d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // A bitmask for getting the space out of an instruction. 243d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static const int kSpaceMask = 15; 244d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 245d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static inline bool SpaceIsLarge(int space) { return space >= kLargeData; } 246d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static inline bool SpaceIsPaged(int space) { 247d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return space >= FIRST_PAGED_SPACE && space <= LAST_PAGED_SPACE; 248d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 249d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 250d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke static int partial_snapshot_cache_length_; 251756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick static const int kPartialSnapshotCacheCapacity = 1400; 252d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke static Object* partial_snapshot_cache_[]; 253d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}; 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuint SnapshotByteSource::GetInt() { 2573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // A little unwind to catch the really small ints. 2583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int snapshot_byte = Get(); 2593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if ((snapshot_byte & 0x80) == 0) { 2603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return snapshot_byte; 2613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 2623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu int accumulator = (snapshot_byte & 0x7f) << 7; 2633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu while (true) { 2643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu snapshot_byte = Get(); 2653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if ((snapshot_byte & 0x80) == 0) { 2663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return accumulator | snapshot_byte; 2673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 2683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu accumulator = (accumulator | (snapshot_byte & 0x7f)) << 7; 2693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 2703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu UNREACHABLE(); 2713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return accumulator; 2723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 2733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid SnapshotByteSource::CopyRaw(byte* to, int number_of_bytes) { 2763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu memcpy(to, data_ + position_, number_of_bytes); 2773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu position_ += number_of_bytes; 2783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 2793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 281d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// A Deserializer reads a snapshot and reconstructs the Object graph it defines. 282d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeclass Deserializer: public SerializerDeserializer { 283d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block public: 284d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Create a deserializer from a snapshot byte source. 285d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block explicit Deserializer(SnapshotByteSource* source); 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 287d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke virtual ~Deserializer(); 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Deserialize the snapshot into an empty heap. 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Deserialize(); 291e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 292e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Deserialize a single object and the objects reachable from it. 293e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void DeserializePartial(Object** root); 294e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Synchronize(const char* tag); 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void VisitPointers(Object** start, Object** end); 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 302d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block virtual void VisitExternalReferences(Address* start, Address* end) { 303d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block UNREACHABLE(); 304d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 306d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block virtual void VisitRuntimeEntry(RelocInfo* rinfo) { 307d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block UNREACHABLE(); 308d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 310d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void ReadChunk(Object** start, Object** end, int space, Address address); 311d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block HeapObject* GetAddressFromStart(int space); 312d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block inline HeapObject* GetAddressFromEnd(int space); 313d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Address Allocate(int space_number, Space* space, int size); 314d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void ReadObject(int space_number, Space* space, Object** write_back); 315d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 316d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Keep track of the pages in the paged spaces. 317d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // (In large object space we are keeping track of individual objects 318d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // rather than pages.) In new space we just need the address of the 319d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // first object and the others will flow from that. 320d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke List<Address> pages_[SerializerDeserializer::kNumberOfSpaces]; 321d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 322d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block SnapshotByteSource* source_; 323e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke static ExternalReferenceDecoder* external_reference_decoder_; 324d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // This is the address of the next object that will be allocated in each 325d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // space. It is used to calculate the addresses of back-references. 326d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Address high_water_[LAST_SPACE + 1]; 327d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // This is the address of the most recent object that was allocated. It 328d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // is used to set the location of the new page when we encounter a 329d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // START_NEW_PAGE_SERIALIZATION tag. 330d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Address last_object_address_; 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 332d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block DISALLOW_COPY_AND_ASSIGN(Deserializer); 333d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}; 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 336d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockclass SnapshotByteSink { 337d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block public: 338d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block virtual ~SnapshotByteSink() { } 339d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block virtual void Put(int byte, const char* description) = 0; 340d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block virtual void PutSection(int byte, const char* description) { 341d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Put(byte, description); 342d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 343d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void PutInt(uintptr_t integer, const char* description); 344e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke virtual int Position() = 0; 345d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}; 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 348d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// Mapping objects to their location after deserialization. 349d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// This is used during building, but not at runtime by V8. 350d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeclass SerializationAddressMapper { 351d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke public: 352d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SerializationAddressMapper() 353d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke : serialization_map_(new HashMap(&SerializationMatchFun)), 354d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke no_allocation_(new AssertNoAllocation()) { } 355d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 356d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ~SerializationAddressMapper() { 357d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke delete serialization_map_; 358d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke delete no_allocation_; 359d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 360d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 361d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke bool IsMapped(HeapObject* obj) { 362d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return serialization_map_->Lookup(Key(obj), Hash(obj), false) != NULL; 363d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 364d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 365d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int MappedTo(HeapObject* obj) { 366d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(IsMapped(obj)); 367d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return static_cast<int>(reinterpret_cast<intptr_t>( 368d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke serialization_map_->Lookup(Key(obj), Hash(obj), false)->value)); 369d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 370d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 371d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void AddMapping(HeapObject* obj, int to) { 372d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(!IsMapped(obj)); 373d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke HashMap::Entry* entry = 374d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke serialization_map_->Lookup(Key(obj), Hash(obj), true); 375d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke entry->value = Value(to); 376d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 377d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 378d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke private: 379d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke static bool SerializationMatchFun(void* key1, void* key2) { 380d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return key1 == key2; 381d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 382d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 383d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke static uint32_t Hash(HeapObject* obj) { 384d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return static_cast<int32_t>(reinterpret_cast<intptr_t>(obj->address())); 385d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 386d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 387d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke static void* Key(HeapObject* obj) { 388d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return reinterpret_cast<void*>(obj->address()); 389d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 390d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 391d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke static void* Value(int v) { 392d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return reinterpret_cast<void*>(v); 393d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 394d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 395d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke HashMap* serialization_map_; 396d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke AssertNoAllocation* no_allocation_; 397d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke DISALLOW_COPY_AND_ASSIGN(SerializationAddressMapper); 398d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}; 399d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 400d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 401d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeclass Serializer : public SerializerDeserializer { 402d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block public: 403d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block explicit Serializer(SnapshotByteSink* sink); 4043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ~Serializer(); 405d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void VisitPointers(Object** start, Object** end); 406e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // You can call this after serialization to find out how much space was used 407e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // in each space. 408e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int CurrentAllocationAddress(int space) { 409e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (SpaceIsLarge(space)) return large_object_total_; 410e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return fullness_[space]; 411e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 413d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static void Enable() { 414d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (!serialization_enabled_) { 415d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(!too_late_to_enable_now_); 416d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 417d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block serialization_enabled_ = true; 418d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 420d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static void Disable() { serialization_enabled_ = false; } 421d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Call this when you have made use of the fact that there is no serialization 422d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // going on. 423d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static void TooLateToEnableNow() { too_late_to_enable_now_ = true; } 424d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static bool enabled() { return serialization_enabled_; } 425d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SerializationAddressMapper* address_mapper() { return &address_mapper_; } 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 427d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block virtual void Synchronize(const char* tag); 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 430d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke protected: 431d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke static const int kInvalidRootIndex = -1; 432d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke virtual int RootIndex(HeapObject* heap_object) = 0; 433d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) = 0; 434d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 435d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block class ObjectSerializer : public ObjectVisitor { 436d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block public: 437d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ObjectSerializer(Serializer* serializer, 438d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Object* o, 439d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block SnapshotByteSink* sink, 440f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke HowToCode how_to_code, 441f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke WhereToPoint where_to_point) 442d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block : serializer_(serializer), 443d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block object_(HeapObject::cast(o)), 444d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block sink_(sink), 445f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke reference_representation_(how_to_code + where_to_point), 446d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block bytes_processed_so_far_(0) { } 447d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void Serialize(); 448d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void VisitPointers(Object** start, Object** end); 449d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void VisitExternalReferences(Address* start, Address* end); 450d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void VisitCodeTarget(RelocInfo* target); 451791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block void VisitCodeEntry(Address entry_address); 452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void VisitGlobalPropertyCell(RelocInfo* rinfo); 453d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void VisitRuntimeEntry(RelocInfo* reloc); 454d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Used for seralizing the external strings that hold the natives source. 455d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void VisitExternalAsciiString( 456d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::String::ExternalAsciiStringResource** resource); 457d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // We can't serialize a heap with external two byte strings. 458d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void VisitExternalTwoByteString( 459d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::String::ExternalStringResource** resource) { 460d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block UNREACHABLE(); 461d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 462d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 463d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block private: 464d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void OutputRawData(Address up_to); 465d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 466d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Serializer* serializer_; 467d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block HeapObject* object_; 468d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block SnapshotByteSink* sink_; 469f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke int reference_representation_; 470d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block int bytes_processed_so_far_; 471d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block }; 472d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 473d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke virtual void SerializeObject(Object* o, 474f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke HowToCode how_to_code, 475f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke WhereToPoint where_to_point) = 0; 476d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void SerializeReferenceToPreviousObject( 477d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int space, 478d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int address, 479f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke HowToCode how_to_code, 480f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke WhereToPoint where_to_point); 481d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void InitializeAllocators(); 482d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // This will return the space for an object. If the object is in large 483d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // object space it may return kLargeCode or kLargeFixedArray in order 484d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // to indicate to the deserializer what kind of large object allocation 485d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // to make. 486d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static int SpaceOfObject(HeapObject* object); 487d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // This just returns the space of the object. It will return LO_SPACE 488d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // for all large objects since you can't check the type of the object 489d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // once the map has been used for the serialization address. 490d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static int SpaceOfAlreadySerializedObject(HeapObject* object); 491d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block int Allocate(int space, int size, bool* new_page_started); 492d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block int EncodeExternalReference(Address addr) { 493d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return external_reference_encoder_->Encode(addr); 494d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 495d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 496d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Keep track of the fullness of each space in order to generate 497d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // relative addresses for back references. Large objects are 498d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // just numbered sequentially since relative addresses make no 499d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // sense in large object space. 500d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block int fullness_[LAST_SPACE + 1]; 501d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block SnapshotByteSink* sink_; 502d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block int current_root_index_; 503d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ExternalReferenceEncoder* external_reference_encoder_; 504d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static bool serialization_enabled_; 505d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Did we already make use of the fact that serialization was not enabled? 506d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block static bool too_late_to_enable_now_; 507e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int large_object_total_; 508d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SerializationAddressMapper address_mapper_; 509d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 510d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block friend class ObjectSerializer; 511d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block friend class Deserializer; 512d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 513d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block DISALLOW_COPY_AND_ASSIGN(Serializer); 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 516d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 517d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeclass PartialSerializer : public Serializer { 518d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke public: 519d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke PartialSerializer(Serializer* startup_snapshot_serializer, 520d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SnapshotByteSink* sink) 521d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke : Serializer(sink), 522d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke startup_serializer_(startup_snapshot_serializer) { 523d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 524d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 525d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Serialize the objects reachable from a single object pointer. 526d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke virtual void Serialize(Object** o); 527d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke virtual void SerializeObject(Object* o, 528f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke HowToCode how_to_code, 529f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke WhereToPoint where_to_point); 530d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 531d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke protected: 532d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke virtual int RootIndex(HeapObject* o); 533d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke virtual int PartialSnapshotCacheIndex(HeapObject* o); 534d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) { 5353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // Scripts should be referred only through shared function infos. We can't 5363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // allow them to be part of the partial snapshot because they contain a 5373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // unique ID, and deserializing several partial snapshots containing script 5383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu // would cause dupes. 5393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(!o->IsScript()); 5406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return o->IsString() || o->IsSharedFunctionInfo() || 541756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick o->IsHeapNumber() || o->IsCode() || 542756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick o->map() == Heap::fixed_cow_array_map(); 543d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 544d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 545d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke private: 546d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Serializer* startup_serializer_; 547d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke DISALLOW_COPY_AND_ASSIGN(PartialSerializer); 548d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}; 549d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 550d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 551d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeclass StartupSerializer : public Serializer { 552d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke public: 553d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke explicit StartupSerializer(SnapshotByteSink* sink) : Serializer(sink) { 554d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Clear the cache of objects used by the partial snapshot. After the 555d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // strong roots have been serialized we can create a partial snapshot 556d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // which will repopulate the cache with objects neede by that partial 557d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // snapshot. 558d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke partial_snapshot_cache_length_ = 0; 559d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 560d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Serialize the current state of the heap. The order is: 561d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 1) Strong references. 562d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 2) Partial snapshot cache. 563d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 3) Weak references (eg the symbol table). 564d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke virtual void SerializeStrongReferences(); 565d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke virtual void SerializeObject(Object* o, 566f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke HowToCode how_to_code, 567f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke WhereToPoint where_to_point); 568d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void SerializeWeakReferences(); 569d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke void Serialize() { 570d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SerializeStrongReferences(); 571d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SerializeWeakReferences(); 572d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 573d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 574d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke private: 575d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke virtual int RootIndex(HeapObject* o) { return kInvalidRootIndex; } 576d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) { 577d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return false; 578d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 579d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}; 580d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 5813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_SERIALIZE_H_ 585