105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifndef V8_SERIALIZE_H_ 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define V8_SERIALIZE_H_ 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org#include "src/compiler.h" 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hashmap.h" 10975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org#include "src/heap-profiler.h" 11975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org#include "src/isolate.h" 12975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org#include "src/snapshot-source-sink.h" 1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 1571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A TypeCode is used to distinguish different kinds of external reference. 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// It is a single bit to make testing for types easy. 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenenum TypeCode { 209d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org UNCLASSIFIED, // One-of-a-kind references. 219d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org C_BUILTIN, 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BUILTIN, 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen RUNTIME_FUNCTION, 2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IC_UTILITY, 2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen STATS_COUNTER, 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TOP_ADDRESS, 2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ACCESSOR, 28a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org STUB_CACHE_TABLE, 299d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org RUNTIME_ENTRY, 30a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org LAZY_DEOPTIMIZATION 3143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 3243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 33a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgconst int kTypeCodeCount = LAZY_DEOPTIMIZATION + 1; 3443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenconst int kFirstTypeCode = UNCLASSIFIED; 3543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenconst int kReferenceIdBits = 16; 3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenconst int kReferenceIdMask = (1 << kReferenceIdBits) - 1; 3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenconst int kReferenceTypeShift = kReferenceIdBits; 3943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 401845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgconst int kDeoptTableSerializeEntryCount = 64; 4143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 42b645116853c677aca8a316381b87441ba6004f67danno@chromium.org// ExternalReferenceTable is a helper class that defines the relationship 43b645116853c677aca8a316381b87441ba6004f67danno@chromium.org// between external references and their encodings. It is used to build 44b645116853c677aca8a316381b87441ba6004f67danno@chromium.org// hashmaps in ExternalReferenceEncoder and ExternalReferenceDecoder. 45b645116853c677aca8a316381b87441ba6004f67danno@chromium.orgclass ExternalReferenceTable { 46b645116853c677aca8a316381b87441ba6004f67danno@chromium.org public: 47b645116853c677aca8a316381b87441ba6004f67danno@chromium.org static ExternalReferenceTable* instance(Isolate* isolate); 48b645116853c677aca8a316381b87441ba6004f67danno@chromium.org 49b645116853c677aca8a316381b87441ba6004f67danno@chromium.org ~ExternalReferenceTable() { } 50b645116853c677aca8a316381b87441ba6004f67danno@chromium.org 51b645116853c677aca8a316381b87441ba6004f67danno@chromium.org int size() const { return refs_.length(); } 52b645116853c677aca8a316381b87441ba6004f67danno@chromium.org 53b645116853c677aca8a316381b87441ba6004f67danno@chromium.org Address address(int i) { return refs_[i].address; } 54b645116853c677aca8a316381b87441ba6004f67danno@chromium.org 55b645116853c677aca8a316381b87441ba6004f67danno@chromium.org uint32_t code(int i) { return refs_[i].code; } 56b645116853c677aca8a316381b87441ba6004f67danno@chromium.org 57b645116853c677aca8a316381b87441ba6004f67danno@chromium.org const char* name(int i) { return refs_[i].name; } 58b645116853c677aca8a316381b87441ba6004f67danno@chromium.org 59b645116853c677aca8a316381b87441ba6004f67danno@chromium.org int max_id(int code) { return max_id_[code]; } 60b645116853c677aca8a316381b87441ba6004f67danno@chromium.org 61b645116853c677aca8a316381b87441ba6004f67danno@chromium.org private: 62b645116853c677aca8a316381b87441ba6004f67danno@chromium.org explicit ExternalReferenceTable(Isolate* isolate) : refs_(64) { 63fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org PopulateTable(isolate); 64b645116853c677aca8a316381b87441ba6004f67danno@chromium.org } 65b645116853c677aca8a316381b87441ba6004f67danno@chromium.org 66b645116853c677aca8a316381b87441ba6004f67danno@chromium.org struct ExternalReferenceEntry { 67b645116853c677aca8a316381b87441ba6004f67danno@chromium.org Address address; 68b645116853c677aca8a316381b87441ba6004f67danno@chromium.org uint32_t code; 69b645116853c677aca8a316381b87441ba6004f67danno@chromium.org const char* name; 70b645116853c677aca8a316381b87441ba6004f67danno@chromium.org }; 71b645116853c677aca8a316381b87441ba6004f67danno@chromium.org 72b645116853c677aca8a316381b87441ba6004f67danno@chromium.org void PopulateTable(Isolate* isolate); 73b645116853c677aca8a316381b87441ba6004f67danno@chromium.org 74b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // For a few types of references, we can get their address from their id. 75b645116853c677aca8a316381b87441ba6004f67danno@chromium.org void AddFromId(TypeCode type, 76b645116853c677aca8a316381b87441ba6004f67danno@chromium.org uint16_t id, 77b645116853c677aca8a316381b87441ba6004f67danno@chromium.org const char* name, 78b645116853c677aca8a316381b87441ba6004f67danno@chromium.org Isolate* isolate); 79b645116853c677aca8a316381b87441ba6004f67danno@chromium.org 80b645116853c677aca8a316381b87441ba6004f67danno@chromium.org // For other types of references, the caller will figure out the address. 81b645116853c677aca8a316381b87441ba6004f67danno@chromium.org void Add(Address address, TypeCode type, uint16_t id, const char* name); 82b645116853c677aca8a316381b87441ba6004f67danno@chromium.org 839d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org void Add(Address address, const char* name) { 849d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org Add(address, UNCLASSIFIED, ++max_id_[UNCLASSIFIED], name); 859d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org } 869d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 87b645116853c677aca8a316381b87441ba6004f67danno@chromium.org List<ExternalReferenceEntry> refs_; 889d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org uint16_t max_id_[kTypeCodeCount]; 89b645116853c677aca8a316381b87441ba6004f67danno@chromium.org}; 90b645116853c677aca8a316381b87441ba6004f67danno@chromium.org 91b645116853c677aca8a316381b87441ba6004f67danno@chromium.org 9243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass ExternalReferenceEncoder { 9343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 943d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org explicit ExternalReferenceEncoder(Isolate* isolate); 9543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 9643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen uint32_t Encode(Address key) const; 9743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 9843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char* NameOfAddress(Address key) const; 9943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 10043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 10143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HashMap encodings_; 10243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static uint32_t Hash(Address key) { 1039085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key) >> 2); 10443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 10543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 10643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int IndexOf(Address key) const; 10743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 10843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void Put(Address key, int index); 109ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 110ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Isolate* isolate_; 11143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 11243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 11343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 11443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass ExternalReferenceDecoder { 11543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 1163d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org explicit ExternalReferenceDecoder(Isolate* isolate); 11743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ~ExternalReferenceDecoder(); 11843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 11943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Address Decode(uint32_t key) const { 12043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (key == 0) return NULL; 12143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return *Lookup(key); 12243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 12343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 12543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Address** encodings_; 12643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Address* Lookup(uint32_t key) const { 12843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int type = key >> kReferenceTypeShift; 129e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kFirstTypeCode <= type && type < kTypeCodeCount); 13043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int id = key & kReferenceIdMask; 13143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return &encodings_[type][id]; 13243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 13343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 13443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void Put(uint32_t key, Address value) { 13543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *Lookup(key) = value; 13643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 137ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 138ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Isolate* isolate_; 13943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 14043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 14143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 142b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// The Serializer/Deserializer class is a common superclass for Serializer and 143b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Deserializer which is used to store common constants and methods used by 144b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// both. 145b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgclass SerializerDeserializer: public ObjectVisitor { 146b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org public: 1473d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org static void Iterate(Isolate* isolate, ObjectVisitor* visitor); 148b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 14956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org static int nop() { return kNop; } 15056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org 1513811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org protected: 1529dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Where the pointed-to object can be found: 1539dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com enum Where { 1549bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org kNewObject = 0, // Object is next in snapshot. 15556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // 1-6 One per space. 1569bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org kRootArray = 0x9, // Object is found in root array. 1579bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org kPartialSnapshotCache = 0xa, // Object is in the cache. 1589bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org kExternalReference = 0xb, // Pointer to an external reference. 1599bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org kSkip = 0xc, // Skip n bytes. 1609bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org kBuiltin = 0xd, // Builtin code object. 161d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org kAttachedReference = 0xe, // Object is described in an attached list. 162d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org kNop = 0xf, // Does nothing, used to pad. 163d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org kBackref = 0x10, // Object is described relative to end. 16456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // 0x11-0x16 One per space. 1659bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org kBackrefWithSkip = 0x18, // Object is described relative to end. 16656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // 0x19-0x1e One per space. 16756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // 0x20-0x3f Used by misc. tags below. 1689dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com kPointedToMask = 0x3f 1693811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org }; 1709dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 1719dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // How to code the pointer to the object. 1729dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com enum HowToCode { 1739dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com kPlain = 0, // Straight pointer. 1749dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // What this means depends on the architecture: 1759dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com kFromCode = 0x40, // A pointer inlined in code. 1769dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com kHowToCodeMask = 0x40 1779dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com }; 1789dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 17956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // For kRootArrayConstants 18056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org enum WithSkip { 18156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org kNoSkipDistance = 0, 18256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org kHasSkipDistance = 0x40, 18356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org kWithSkipMask = 0x40 18456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org }; 18556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org 1869dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Where to point within the object. 1879dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com enum WhereToPoint { 1889dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com kStartOfObject = 0, 189000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org kInnerPointer = 0x80, // First insn in code object or payload of cell. 1909dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com kWhereToPointMask = 0x80 1919dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com }; 1929dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 1939dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Misc. 19456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // Raw data to be copied from the snapshot. This byte code does not advance 19556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // the current pointer, which is used for code objects, where we write the 19656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // entire code in one memcpy, then fix up stuff with kSkip and other byte 19756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // codes that overwrite data. 19856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org static const int kRawData = 0x20; 19956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // Some common raw lengths: 0x21-0x3f. These autoadvance the current pointer. 2009dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // A tag emitted at strategic points in the snapshot to delineate sections. 2019dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // If the deserializer does not find these at the expected moments then it 2029dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // is an indication that the snapshot and the VM do not fit together. 2039dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Examine the build process for architecture, version or configuration 2049dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // mismatches. 20540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org static const int kSynchronize = 0x70; 2069dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Used for the source code of the natives, which is in the executable, but 2079dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // is referred to from external strings in the snapshot. 20840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org static const int kNativesStringResource = 0x71; 20956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org static const int kRepeat = 0x72; 21056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org static const int kConstantRepeat = 0x73; 21156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // 0x73-0x7f Repeat last word (subtract 0x72 to get the count). 21256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org static const int kMaxRepeats = 0x7f - 0x72; 213394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com static int CodeForRepeats(int repeats) { 214e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(repeats >= 1 && repeats <= kMaxRepeats); 21556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org return 0x72 + repeats; 216394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 217394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com static int RepeatsForCode(int byte_code) { 218e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(byte_code >= kConstantRepeat && byte_code <= 0x7f); 21956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org return byte_code - 0x72; 220394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 22156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org static const int kRootArrayConstants = 0xa0; 22256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // 0xa0-0xbf Things from the first 32 elements of the root array. 223394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com static const int kRootArrayNumberOfConstantEncodings = 0x20; 224394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com static int RootArrayConstantFromByteCode(int byte_code) { 22556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org return byte_code & 0x1f; 226394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 2279dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 22856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org static const int kNumberOfSpaces = LO_SPACE; 22940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org static const int kAnyOldSpace = -1; 2303811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 231c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org // A bitmask for getting the space out of an instruction. 23256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org static const int kSpaceMask = 7; 2333811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}; 2343811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 2353811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 2363811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org// A Deserializer reads a snapshot and reconstructs the Object graph it defines. 237b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgclass Deserializer: public SerializerDeserializer { 2383811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org public: 2393811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Create a deserializer from a snapshot byte source. 240c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org explicit Deserializer(SnapshotByteSource* source); 2413811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 242b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org virtual ~Deserializer(); 2433811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 2443811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Deserialize the snapshot into an empty heap. 2453d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org void Deserialize(Isolate* isolate); 246b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 247b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Deserialize a single object and the objects reachable from it. 2483d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org void DeserializePartial(Isolate* isolate, Object** root); 249b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 25056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org void set_reservation(int space_number, int reservation) { 251e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(space_number >= 0); 252e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(space_number <= LAST_SPACE); 25356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org reservations_[space_number] = reservation; 25456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org } 25556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org 2565366bfdf41c98cd70820c1633b031dc290ec1cd6machenbach@chromium.org void FlushICacheForNewCodeObjects(); 2575366bfdf41c98cd70820c1633b031dc290ec1cd6machenbach@chromium.org 258d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org // Serialized user code reference certain objects that are provided in a list 259d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org // By calling this method, we assume that we are deserializing user code. 260a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void SetAttachedObjects(Vector<Handle<Object> >* attached_objects) { 261d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org attached_objects_ = attached_objects; 262d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org } 263d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org 264d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org bool deserializing_user_code() { return attached_objects_ != NULL; } 265d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org 2663811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org private: 2673811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org virtual void VisitPointers(Object** start, Object** end); 2683811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 2693811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org virtual void VisitRuntimeEntry(RelocInfo* rinfo) { 2703811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org UNREACHABLE(); 2713811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 2723811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 273ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Allocation sites are present in the snapshot, and must be linked into 274ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // a list at deserialization time. 275ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org void RelinkAllocationSite(AllocationSite* site); 276ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 277394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Fills in some heap data in an area from start to end (non-inclusive). The 278394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // space id is used for the write barrier. The object_address is the address 279394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // of the object we are writing into, or NULL if we are not writing into an 2802efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // object, i.e. if we are writing a series of tagged values that are not on 2812efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // the heap. 282394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com void ReadChunk( 283394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Object** start, Object** end, int space, Address object_address); 28456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org void ReadObject(int space_number, Object** write_back); 28556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org 2867c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org // Special handling for serialized code like hooking up internalized strings. 2877c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj); 2887c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org Object* ProcessBackRefInSerializedCode(Object* obj); 289d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org 29056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // This routine both allocates a new object, and also keeps 29156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // track of where objects have been allocated so that we can 29256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // fix back references when deserializing. 29356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Address Allocate(int space_index, int size) { 29456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Address address = high_water_[space_index]; 29556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org high_water_[space_index] = address + size; 29656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org return address; 29756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org } 29856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org 29956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // This returns the address of an object that has been described in the 30056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // snapshot as being offset bytes back in a particular space. 30156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org HeapObject* GetAddressFromEnd(int space) { 30256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org int offset = source_->GetInt(); 30356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org offset <<= kObjectAlignmentBits; 30456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org return HeapObject::FromAddress(high_water_[space] - offset); 30556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org } 30656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org 307ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Cached current isolate. 308ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Isolate* isolate_; 309ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 310d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org // Objects from the attached object descriptions in the serialized user code. 311a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Vector<Handle<Object> >* attached_objects_; 312d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org 3133811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org SnapshotByteSource* source_; 314c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org // This is the address of the next object that will be allocated in each 315c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org // space. It is used to calculate the addresses of back-references. 316c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org Address high_water_[LAST_SPACE + 1]; 31756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org 31856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org int reservations_[LAST_SPACE + 1]; 31956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org static const intptr_t kUninitializedReservation = -1; 3203811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 321ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReferenceDecoder* external_reference_decoder_; 322ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 323c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org DISALLOW_COPY_AND_ASSIGN(Deserializer); 3243811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}; 3253811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 3263811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 327b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Mapping objects to their location after deserialization. 328b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// This is used during building, but not at runtime by V8. 329b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgclass SerializationAddressMapper { 330b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org public: 331b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org SerializationAddressMapper() 33279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org : no_allocation_(), 333731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org serialization_map_(new HashMap(HashMap::PointersMatch)) { } 334b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 335b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ~SerializationAddressMapper() { 336b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org delete serialization_map_; 337b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 338b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 339b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org bool IsMapped(HeapObject* obj) { 340b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return serialization_map_->Lookup(Key(obj), Hash(obj), false) != NULL; 341b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 342b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 343b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int MappedTo(HeapObject* obj) { 344e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsMapped(obj)); 345b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return static_cast<int>(reinterpret_cast<intptr_t>( 346b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org serialization_map_->Lookup(Key(obj), Hash(obj), false)->value)); 347b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 348b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 349b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void AddMapping(HeapObject* obj, int to) { 350e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!IsMapped(obj)); 351b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org HashMap::Entry* entry = 352b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org serialization_map_->Lookup(Key(obj), Hash(obj), true); 353b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org entry->value = Value(to); 354b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 355b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 356b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org private: 35740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org static uint32_t Hash(HeapObject* obj) { 358b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return static_cast<int32_t>(reinterpret_cast<intptr_t>(obj->address())); 359b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 360b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 36140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org static void* Key(HeapObject* obj) { 362b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return reinterpret_cast<void*>(obj->address()); 363b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 364b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 36540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org static void* Value(int v) { 366b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return reinterpret_cast<void*>(v); 367b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 368b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 36979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_allocation_; 370b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org HashMap* serialization_map_; 371b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org DISALLOW_COPY_AND_ASSIGN(SerializationAddressMapper); 372b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}; 373b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 374b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 375d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgclass CodeAddressMap; 376d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 377ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org// There can be only one serializer per V8 process. 37840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgclass Serializer : public SerializerDeserializer { 3793811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org public: 3803d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org Serializer(Isolate* isolate, SnapshotByteSink* sink); 3815d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org ~Serializer(); 3823811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void VisitPointers(Object** start, Object** end); 3830c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // You can call this after serialization to find out how much space was used 3840c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // in each space. 385f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org int CurrentAllocationAddress(int space) const { 386e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(space < kNumberOfSpaces); 3870c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org return fullness_[space]; 3880c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 389c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 3903d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org Isolate* isolate() const { return isolate_; } 391fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org 392b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org SerializationAddressMapper* address_mapper() { return &address_mapper_; } 39356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org void PutRoot(int index, 39456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org HeapObject* object, 39556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org HowToCode how, 39656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org WhereToPoint where, 39756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org int skip); 3983811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 399b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org protected: 40040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org static const int kInvalidRootIndex = -1; 401394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 40288aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org int RootIndex(HeapObject* heap_object, HowToCode from); 403394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com intptr_t root_index_wave_front() { return root_index_wave_front_; } 404394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com void set_root_index_wave_front(intptr_t value) { 405e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(value >= root_index_wave_front_); 406394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com root_index_wave_front_ = value; 407394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 408b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4093811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org class ObjectSerializer : public ObjectVisitor { 4103811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org public: 411c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org ObjectSerializer(Serializer* serializer, 4123811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Object* o, 4133811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org SnapshotByteSink* sink, 4149dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com HowToCode how_to_code, 4159dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com WhereToPoint where_to_point) 4163811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org : serializer_(serializer), 4173811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org object_(HeapObject::cast(o)), 4183811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org sink_(sink), 4199dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com reference_representation_(how_to_code + where_to_point), 42056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org bytes_processed_so_far_(0), 42156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org code_object_(o->IsCode()), 42256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org code_has_been_output_(false) { } 4233811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void Serialize(); 4243811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void VisitPointers(Object** start, Object** end); 42504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org void VisitEmbeddedPointer(RelocInfo* target); 426c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org void VisitExternalReference(Address* p); 42704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org void VisitExternalReference(RelocInfo* rinfo); 4283811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void VisitCodeTarget(RelocInfo* target); 429145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com void VisitCodeEntry(Address entry_address); 43041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org void VisitCell(RelocInfo* rinfo); 431c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org void VisitRuntimeEntry(RelocInfo* reloc); 432c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org // Used for seralizing the external strings that hold the natives source. 4332c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void VisitExternalOneByteString( 4342c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org v8::String::ExternalOneByteStringResource** resource); 435c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org // We can't serialize a heap with external two byte strings. 436c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org void VisitExternalTwoByteString( 437c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org v8::String::ExternalStringResource** resource) { 438c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org UNREACHABLE(); 439c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org } 4403811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 4413811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org private: 44256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org enum ReturnSkip { kCanReturnSkipInsteadOfSkipping, kIgnoringReturn }; 44356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // This function outputs or skips the raw data between the last pointer and 44456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // up to the current position. It optionally can just return the number of 44556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // bytes to skip instead of performing a skip instruction, in case the skip 44656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // can be merged into the next instruction. 44756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org int OutputRawData(Address up_to, ReturnSkip return_skip = kIgnoringReturn); 4483811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 449c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org Serializer* serializer_; 4503811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org HeapObject* object_; 4513811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org SnapshotByteSink* sink_; 4529dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com int reference_representation_; 4533811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org int bytes_processed_so_far_; 45456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org bool code_object_; 45556c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org bool code_has_been_output_; 4563811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org }; 4573811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 458b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org virtual void SerializeObject(Object* o, 4599dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com HowToCode how_to_code, 46056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org WhereToPoint where_to_point, 46156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org int skip) = 0; 462a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void SerializeReferenceToPreviousObject(HeapObject* heap_object, 463a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org HowToCode how_to_code, 464a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org WhereToPoint where_to_point, 465a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org int skip); 4663811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void InitializeAllocators(); 46756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // This will return the space for an object. 46840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org static int SpaceOfObject(HeapObject* object); 46956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org int Allocate(int space, int size); 4703811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org int EncodeExternalReference(Address addr) { 4713811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org return external_reference_encoder_->Encode(addr); 4723811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 4733811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 474ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org int SpaceAreaSize(int space); 475ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org 476db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org // Some roots should not be serialized, because their actual value depends on 477db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org // absolute addresses and they are reset after deserialization, anyway. 478db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org bool ShouldBeSkipped(Object** current); 479db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org 480ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org Isolate* isolate_; 4813811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Keep track of the fullness of each space in order to generate 48256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // relative addresses for back references. 4833811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org int fullness_[LAST_SPACE + 1]; 4843811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org SnapshotByteSink* sink_; 4853811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ExternalReferenceEncoder* external_reference_encoder_; 4864ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org 487b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org SerializationAddressMapper address_mapper_; 488394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com intptr_t root_index_wave_front_; 48956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org void Pad(); 4903811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 4913811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org friend class ObjectSerializer; 492c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org friend class Deserializer; 4933811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 494fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org // We may not need the code address map for logging for every instance 495fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org // of the serializer. Initialize it on demand. 496fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org void InitializeCodeAddressMap(); 497fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org 49805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org private: 499fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org CodeAddressMap* code_address_map_; 500c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org DISALLOW_COPY_AND_ASSIGN(Serializer); 5013811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}; 5023811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 503b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 504b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgclass PartialSerializer : public Serializer { 505b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org public: 5063d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org PartialSerializer(Isolate* isolate, 5073d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org Serializer* startup_snapshot_serializer, 508b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org SnapshotByteSink* sink) 5093d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org : Serializer(isolate, sink), 510b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org startup_serializer_(startup_snapshot_serializer) { 511394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com set_root_index_wave_front(Heap::kStrongRootListLength); 512fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org InitializeCodeAddressMap(); 513b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 514b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 515b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Serialize the objects reachable from a single object pointer. 5163ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org void Serialize(Object** o); 517b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org virtual void SerializeObject(Object* o, 5189dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com HowToCode how_to_code, 51956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org WhereToPoint where_to_point, 52056c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org int skip); 521b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 5223ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org private: 5233ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org int PartialSnapshotCacheIndex(HeapObject* o); 5243ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org bool ShouldBeInThePartialSnapshotCache(HeapObject* o) { 5255d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org // Scripts should be referred only through shared function infos. We can't 5265d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org // allow them to be part of the partial snapshot because they contain a 5275d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org // unique ID, and deserializing several partial snapshots containing script 5285d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org // would cause dupes. 529e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!o->IsScript()); 5301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return o->IsName() || o->IsSharedFunctionInfo() || 5310b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org o->IsHeapNumber() || o->IsCode() || 532c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org o->IsScopeInfo() || 533c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org o->map() == 534c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org startup_serializer_->isolate()->heap()->fixed_cow_array_map(); 535b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 536b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 5373ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 538b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Serializer* startup_serializer_; 539b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org DISALLOW_COPY_AND_ASSIGN(PartialSerializer); 540b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}; 541b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 542b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 543b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgclass StartupSerializer : public Serializer { 544b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org public: 5453d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org StartupSerializer(Isolate* isolate, SnapshotByteSink* sink) 5463d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org : Serializer(isolate, sink) { 547b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Clear the cache of objects used by the partial snapshot. After the 548b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // strong roots have been serialized we can create a partial snapshot 549394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // which will repopulate the cache with objects needed by that partial 550b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // snapshot. 5513d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org isolate->set_serialize_partial_snapshot_cache_length(0); 552fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org InitializeCodeAddressMap(); 553b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 554b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Serialize the current state of the heap. The order is: 555b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // 1) Strong references. 556b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // 2) Partial snapshot cache. 5574a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // 3) Weak references (e.g. the string table). 558b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org virtual void SerializeStrongReferences(); 559b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org virtual void SerializeObject(Object* o, 5609dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com HowToCode how_to_code, 56156c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org WhereToPoint where_to_point, 56256c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org int skip); 563b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void SerializeWeakReferences(); 564b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void Serialize() { 565b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org SerializeStrongReferences(); 566b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org SerializeWeakReferences(); 56756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org Pad(); 568b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 569d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org 570d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org private: 571d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org DISALLOW_COPY_AND_ASSIGN(StartupSerializer); 572b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}; 573b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 5745d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org 575f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.orgclass CodeSerializer : public Serializer { 576f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org public: 577d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org CodeSerializer(Isolate* isolate, SnapshotByteSink* sink, String* source) 578d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org : Serializer(isolate, sink), source_(source) { 579f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org set_root_index_wave_front(Heap::kStrongRootListLength); 580f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org InitializeCodeAddressMap(); 581f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org } 582f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org 583d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org static ScriptData* Serialize(Isolate* isolate, 584d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org Handle<SharedFunctionInfo> info, 585d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org Handle<String> source); 586d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org 587f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org virtual void SerializeObject(Object* o, HowToCode how_to_code, 588f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org WhereToPoint where_to_point, int skip); 589f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org 590d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org static Handle<SharedFunctionInfo> Deserialize(Isolate* isolate, 591d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org ScriptData* data, 592d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org Handle<String> source); 593d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org 594d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org static const int kSourceObjectIndex = 0; 595a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org static const int kCodeStubsBaseIndex = 1; 596f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org 5974c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org String* source() { 598e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!AllowHeapAllocation::IsAllowed()); 5994c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org return source_; 6004c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org } 6014c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 602a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org List<uint32_t>* stub_keys() { return &stub_keys_; } 603a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 6049bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org private: 6059bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org void SerializeBuiltin(Code* builtin, HowToCode how_to_code, 6069bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org WhereToPoint where_to_point, int skip); 607a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void SerializeCodeStub(Code* code, HowToCode how_to_code, 608a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org WhereToPoint where_to_point, int skip); 609d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org void SerializeSourceObject(HowToCode how_to_code, WhereToPoint where_to_point, 610d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org int skip); 611a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void SerializeHeapObject(HeapObject* heap_object, HowToCode how_to_code, 612a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org WhereToPoint where_to_point, int skip); 613a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org int AddCodeStubKey(uint32_t stub_key); 614d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org 615d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org DisallowHeapAllocation no_gc_; 616d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org String* source_; 617a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org List<uint32_t> stub_keys_; 618d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org DISALLOW_COPY_AND_ASSIGN(CodeSerializer); 619f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org}; 62070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org 62170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org 62270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org// Wrapper around ScriptData to provide code-serializer-specific functionality. 62370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgclass SerializedCodeData { 62470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org public: 62570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org // Used by when consuming. 6264c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org explicit SerializedCodeData(ScriptData* data, String* source) 62770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org : script_data_(data), owns_script_data_(false) { 6284c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org DisallowHeapAllocation no_gc; 6294c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org CHECK(IsSane(source)); 63070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org } 63170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org 63270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org // Used when producing. 63370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org SerializedCodeData(List<byte>* payload, CodeSerializer* cs); 63470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org 63570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org ~SerializedCodeData() { 63670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org if (owns_script_data_) delete script_data_; 63770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org } 63870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org 63970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org // Return ScriptData object and relinquish ownership over it to the caller. 64070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org ScriptData* GetScriptData() { 64170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org ScriptData* result = script_data_; 64270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org script_data_ = NULL; 643e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(owns_script_data_); 64470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org owns_script_data_ = false; 64570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org return result; 64670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org } 64770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org 648a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Vector<const uint32_t> CodeStubKeys() const { 649a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org return Vector<const uint32_t>( 650a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org reinterpret_cast<const uint32_t*>(script_data_->data() + kHeaderSize), 651a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org GetHeaderValue(kNumCodeStubKeysOffset)); 652a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org } 653a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 65470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org const byte* Payload() const { 655a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org int code_stubs_size = GetHeaderValue(kNumCodeStubKeysOffset) * kInt32Size; 656a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org return script_data_->data() + kHeaderSize + code_stubs_size; 65770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org } 65870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org 65970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org int PayloadLength() const { 660a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org int payload_length = GetHeaderValue(kPayloadLengthOffset); 661a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org DCHECK_EQ(script_data_->data() + script_data_->length(), 662a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Payload() + payload_length); 663a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org return payload_length; 66470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org } 66570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org 66670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org int GetReservation(int space) const { 66770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org return GetHeaderValue(kReservationsOffset + space); 66870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org } 66970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org 67070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org private: 67170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org void SetHeaderValue(int offset, int value) { 67270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org reinterpret_cast<int*>(const_cast<byte*>(script_data_->data()))[offset] = 67370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org value; 67470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org } 67570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org 67670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org int GetHeaderValue(int offset) const { 67770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org return reinterpret_cast<const int*>(script_data_->data())[offset]; 67870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org } 67970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org 6804c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org bool IsSane(String* source); 6814c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org 6824c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org int CheckSum(String* source); 68370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org 68470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org // The data header consists of int-sized entries: 68570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org // [0] version hash 686a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // [1] number of code stub keys 687a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // [2] payload length 688a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // [3..9] reservation sizes for spaces from NEW_SPACE to PROPERTY_CELL_SPACE. 6894c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org static const int kCheckSumOffset = 0; 690a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org static const int kNumCodeStubKeysOffset = 1; 691a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org static const int kPayloadLengthOffset = 2; 692a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org static const int kReservationsOffset = 3; 693a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 694a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org static const int kNumSpaces = PROPERTY_CELL_SPACE - NEW_SPACE + 1; 695a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org static const int kHeaderEntries = kReservationsOffset + kNumSpaces; 696a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org static const int kHeaderSize = kHeaderEntries * kIntSize; 697a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 698a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // Following the header, we store, in sequential order 699a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // - code stub keys 700a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // - serialization payload 70170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org 70270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org ScriptData* script_data_; 70370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org bool owns_script_data_; 70470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org}; 70543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 70643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 70743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif // V8_SERIALIZE_H_ 708