Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(246)

Side by Side Diff: src/serialize.h

Issue 982773003: Serializer: simplify external reference encoding. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/disassembler.cc ('k') | src/serialize.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_SERIALIZE_H_ 5 #ifndef V8_SERIALIZE_H_
6 #define V8_SERIALIZE_H_ 6 #define V8_SERIALIZE_H_
7 7
8 #include "src/hashmap.h" 8 #include "src/hashmap.h"
9 #include "src/heap-profiler.h" 9 #include "src/heap-profiler.h"
10 #include "src/isolate.h" 10 #include "src/isolate.h"
11 #include "src/snapshot-source-sink.h" 11 #include "src/snapshot-source-sink.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 15
16 class ScriptData; 16 class ScriptData;
17 17
18 // A TypeCode is used to distinguish different kinds of external reference. 18 static const int kDeoptTableSerializeEntryCount = 64;
19 // It is a single bit to make testing for types easy.
20 enum TypeCode {
21 UNCLASSIFIED, // One-of-a-kind references.
22 C_BUILTIN,
23 BUILTIN,
24 RUNTIME_FUNCTION,
25 IC_UTILITY,
26 STATS_COUNTER,
27 TOP_ADDRESS,
28 ACCESSOR_CODE,
29 STUB_CACHE_TABLE,
30 RUNTIME_ENTRY,
31 LAZY_DEOPTIMIZATION
32 };
33
34 const int kTypeCodeCount = LAZY_DEOPTIMIZATION + 1;
35 const int kFirstTypeCode = UNCLASSIFIED;
36
37 const int kReferenceIdBits = 16;
38 const int kReferenceIdMask = (1 << kReferenceIdBits) - 1;
39 const int kReferenceTypeShift = kReferenceIdBits;
40
41 const int kDeoptTableSerializeEntryCount = 64;
42 19
43 // ExternalReferenceTable is a helper class that defines the relationship 20 // ExternalReferenceTable is a helper class that defines the relationship
44 // between external references and their encodings. It is used to build 21 // between external references and their encodings. It is used to build
45 // hashmaps in ExternalReferenceEncoder and ExternalReferenceDecoder. 22 // hashmaps in ExternalReferenceEncoder and ExternalReferenceDecoder.
46 class ExternalReferenceTable { 23 class ExternalReferenceTable {
47 public: 24 public:
48 static ExternalReferenceTable* instance(Isolate* isolate); 25 static ExternalReferenceTable* instance(Isolate* isolate);
49 26
50 ~ExternalReferenceTable() { }
51
52 int size() const { return refs_.length(); } 27 int size() const { return refs_.length(); }
53
54 Address address(int i) { return refs_[i].address; } 28 Address address(int i) { return refs_[i].address; }
55
56 uint32_t code(int i) { return refs_[i].code; }
57
58 const char* name(int i) { return refs_[i].name; } 29 const char* name(int i) { return refs_[i].name; }
59 30
60 int max_id(int code) { return max_id_[code]; } 31 inline static Address NotAvailable() { return NULL; }
61 32
62 private: 33 private:
63 explicit ExternalReferenceTable(Isolate* isolate) : refs_(64) {
64 PopulateTable(isolate);
65 }
66
67 struct ExternalReferenceEntry { 34 struct ExternalReferenceEntry {
68 Address address; 35 Address address;
69 uint32_t code;
70 const char* name; 36 const char* name;
71 }; 37 };
72 38
73 void PopulateTable(Isolate* isolate); 39 explicit ExternalReferenceTable(Isolate* isolate);
74
75 // For a few types of references, we can get their address from their id.
76 void AddFromId(TypeCode type,
77 uint16_t id,
78 const char* name,
79 Isolate* isolate);
80
81 // For other types of references, the caller will figure out the address.
82 void Add(Address address, TypeCode type, uint16_t id, const char* name);
83 40
84 void Add(Address address, const char* name) { 41 void Add(Address address, const char* name) {
85 Add(address, UNCLASSIFIED, ++max_id_[UNCLASSIFIED], name); 42 ExternalReferenceEntry entry = {address, name};
43 refs_.Add(entry);
86 } 44 }
87 45
88 List<ExternalReferenceEntry> refs_; 46 List<ExternalReferenceEntry> refs_;
89 uint16_t max_id_[kTypeCodeCount]; 47
48 DISALLOW_COPY_AND_ASSIGN(ExternalReferenceTable);
90 }; 49 };
91 50
92 51
93 class ExternalReferenceEncoder { 52 class ExternalReferenceEncoder {
94 public: 53 public:
95 explicit ExternalReferenceEncoder(Isolate* isolate); 54 explicit ExternalReferenceEncoder(Isolate* isolate);
96 55
97 uint32_t Encode(Address key) const; 56 uint32_t Encode(Address key) const;
98 57
99 const char* NameOfAddress(Address key) const; 58 const char* NameOfAddress(Isolate* isolate, Address address) const;
100 59
101 private: 60 private:
102 HashMap encodings_;
103 static uint32_t Hash(Address key) { 61 static uint32_t Hash(Address key) {
104 return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key) >> 2); 62 return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key) >>
63 kPointerSizeLog2);
105 } 64 }
106 65
107 int IndexOf(Address key) const; 66 HashMap map_;
108 67
109 void Put(Address key, int index); 68 DISALLOW_COPY_AND_ASSIGN(ExternalReferenceEncoder);
110
111 Isolate* isolate_;
112 }; 69 };
113 70
114 71
115 class ExternalReferenceDecoder {
116 public:
117 explicit ExternalReferenceDecoder(Isolate* isolate);
118 ~ExternalReferenceDecoder();
119
120 Address Decode(uint32_t key) const {
121 if (key == 0) return NULL;
122 return *Lookup(key);
123 }
124
125 private:
126 Address** encodings_;
127
128 Address* Lookup(uint32_t key) const {
129 int type = key >> kReferenceTypeShift;
130 DCHECK(kFirstTypeCode <= type && type < kTypeCodeCount);
131 int id = key & kReferenceIdMask;
132 return &encodings_[type][id];
133 }
134
135 void Put(uint32_t key, Address value) {
136 *Lookup(key) = value;
137 }
138
139 Isolate* isolate_;
140 };
141
142
143 class AddressMapBase { 72 class AddressMapBase {
144 protected: 73 protected:
145 static void SetValue(HashMap::Entry* entry, uint32_t v) { 74 static void SetValue(HashMap::Entry* entry, uint32_t v) {
146 entry->value = reinterpret_cast<void*>(v); 75 entry->value = reinterpret_cast<void*>(v);
147 } 76 }
148 77
149 static uint32_t GetValue(HashMap::Entry* entry) { 78 static uint32_t GetValue(HashMap::Entry* entry) {
150 return static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value)); 79 return static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value));
151 } 80 }
152 81
(...skipping 10 matching lines...) Expand all
163 static void* Key(HeapObject* obj) { 92 static void* Key(HeapObject* obj) {
164 return reinterpret_cast<void*>(obj->address()); 93 return reinterpret_cast<void*>(obj->address());
165 } 94 }
166 }; 95 };
167 96
168 97
169 class RootIndexMap : public AddressMapBase { 98 class RootIndexMap : public AddressMapBase {
170 public: 99 public:
171 explicit RootIndexMap(Isolate* isolate); 100 explicit RootIndexMap(Isolate* isolate);
172 101
173 ~RootIndexMap() { delete map_; } 102 static const int kInvalidRootIndex = -1;
174 103
175 static const int kInvalidRootIndex = -1;
176 int Lookup(HeapObject* obj) { 104 int Lookup(HeapObject* obj) {
177 HashMap::Entry* entry = LookupEntry(map_, obj, false); 105 HashMap::Entry* entry = LookupEntry(&map_, obj, false);
178 if (entry) return GetValue(entry); 106 if (entry) return GetValue(entry);
179 return kInvalidRootIndex; 107 return kInvalidRootIndex;
180 } 108 }
181 109
182 private: 110 private:
183 HashMap* map_; 111 HashMap map_;
184 112
185 DISALLOW_COPY_AND_ASSIGN(RootIndexMap); 113 DISALLOW_COPY_AND_ASSIGN(RootIndexMap);
186 }; 114 };
187 115
188 116
189 class PartialCacheIndexMap : public AddressMapBase { 117 class PartialCacheIndexMap : public AddressMapBase {
190 public: 118 public:
191 PartialCacheIndexMap() : map_(HashMap::PointersMatch) {} 119 PartialCacheIndexMap() : map_(HashMap::PointersMatch) {}
192 120
193 static const int kInvalidIndex = -1; 121 static const int kInvalidIndex = -1;
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 }; 440 };
513 441
514 SerializedData(byte* data, int size) 442 SerializedData(byte* data, int size)
515 : data_(data), size_(size), owns_data_(false) {} 443 : data_(data), size_(size), owns_data_(false) {}
516 SerializedData() : data_(NULL), size_(0), owns_data_(false) {} 444 SerializedData() : data_(NULL), size_(0), owns_data_(false) {}
517 445
518 ~SerializedData() { 446 ~SerializedData() {
519 if (owns_data_) DeleteArray<byte>(data_); 447 if (owns_data_) DeleteArray<byte>(data_);
520 } 448 }
521 449
450 uint32_t GetMagicNumber() const { return GetHeaderValue(kMagicNumberOffset); }
451
522 class ChunkSizeBits : public BitField<uint32_t, 0, 31> {}; 452 class ChunkSizeBits : public BitField<uint32_t, 0, 31> {};
523 class IsLastChunkBits : public BitField<bool, 31, 1> {}; 453 class IsLastChunkBits : public BitField<bool, 31, 1> {};
524 454
455 static uint32_t ComputeMagicNumber(ExternalReferenceTable* table) {
456 uint32_t external_refs = table->size();
457 return 0xC0DE0000 ^ external_refs;
458 }
459
525 protected: 460 protected:
526 void SetHeaderValue(int offset, uint32_t value) { 461 void SetHeaderValue(int offset, uint32_t value) {
527 uint32_t* address = reinterpret_cast<uint32_t*>(data_ + offset); 462 uint32_t* address = reinterpret_cast<uint32_t*>(data_ + offset);
528 memcpy(reinterpret_cast<uint32_t*>(address), &value, sizeof(value)); 463 memcpy(reinterpret_cast<uint32_t*>(address), &value, sizeof(value));
529 } 464 }
530 465
531 uint32_t GetHeaderValue(int offset) const { 466 uint32_t GetHeaderValue(int offset) const {
532 uint32_t value; 467 uint32_t value;
533 memcpy(&value, reinterpret_cast<int*>(data_ + offset), sizeof(value)); 468 memcpy(&value, reinterpret_cast<int*>(data_ + offset), sizeof(value));
534 return value; 469 return value;
535 } 470 }
536 471
537 void AllocateData(int size); 472 void AllocateData(int size);
538 473
474 static uint32_t ComputeMagicNumber(Isolate* isolate) {
475 return ComputeMagicNumber(ExternalReferenceTable::instance(isolate));
476 }
477
478 void SetMagicNumber(Isolate* isolate) {
479 SetHeaderValue(kMagicNumberOffset, ComputeMagicNumber(isolate));
480 }
481
482 static const int kMagicNumberOffset = 0;
483
539 byte* data_; 484 byte* data_;
540 int size_; 485 int size_;
541 bool owns_data_; 486 bool owns_data_;
542 }; 487 };
543 488
544 489
545 // A Deserializer reads a snapshot and reconstructs the Object graph it defines. 490 // A Deserializer reads a snapshot and reconstructs the Object graph it defines.
546 class Deserializer: public SerializerDeserializer { 491 class Deserializer: public SerializerDeserializer {
547 public: 492 public:
548 // Create a deserializer from a snapshot byte source. 493 // Create a deserializer from a snapshot byte source.
549 template <class Data> 494 template <class Data>
550 explicit Deserializer(Data* data) 495 explicit Deserializer(Data* data)
551 : isolate_(NULL), 496 : isolate_(NULL),
552 source_(data->Payload()), 497 source_(data->Payload()),
553 external_reference_decoder_(NULL), 498 magic_number_(data->GetMagicNumber()),
499 external_reference_table_(NULL),
554 deserialized_large_objects_(0), 500 deserialized_large_objects_(0),
555 deserializing_user_code_(false) { 501 deserializing_user_code_(false) {
556 DecodeReservation(data->Reservations()); 502 DecodeReservation(data->Reservations());
557 } 503 }
558 504
559 virtual ~Deserializer(); 505 virtual ~Deserializer();
560 506
561 // Deserialize the snapshot into an empty heap. 507 // Deserialize the snapshot into an empty heap.
562 void Deserialize(Isolate* isolate); 508 void Deserialize(Isolate* isolate);
563 509
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 // snapshot by chunk index and offset. 563 // snapshot by chunk index and offset.
618 HeapObject* GetBackReferencedObject(int space); 564 HeapObject* GetBackReferencedObject(int space);
619 565
620 // Cached current isolate. 566 // Cached current isolate.
621 Isolate* isolate_; 567 Isolate* isolate_;
622 568
623 // Objects from the attached object descriptions in the serialized user code. 569 // Objects from the attached object descriptions in the serialized user code.
624 Vector<Handle<Object> > attached_objects_; 570 Vector<Handle<Object> > attached_objects_;
625 571
626 SnapshotByteSource source_; 572 SnapshotByteSource source_;
573 uint32_t magic_number_;
574
627 // The address of the next object that will be allocated in each space. 575 // The address of the next object that will be allocated in each space.
628 // Each space has a number of chunks reserved by the GC, with each chunk 576 // Each space has a number of chunks reserved by the GC, with each chunk
629 // fitting into a page. Deserialized objects are allocated into the 577 // fitting into a page. Deserialized objects are allocated into the
630 // current chunk of the target space by bumping up high water mark. 578 // current chunk of the target space by bumping up high water mark.
631 Heap::Reservation reservations_[kNumberOfSpaces]; 579 Heap::Reservation reservations_[kNumberOfSpaces];
632 uint32_t current_chunk_[kNumberOfPreallocatedSpaces]; 580 uint32_t current_chunk_[kNumberOfPreallocatedSpaces];
633 Address high_water_[kNumberOfPreallocatedSpaces]; 581 Address high_water_[kNumberOfPreallocatedSpaces];
634 582
635 ExternalReferenceDecoder* external_reference_decoder_; 583 ExternalReferenceTable* external_reference_table_;
636 584
637 List<HeapObject*> deserialized_large_objects_; 585 List<HeapObject*> deserialized_large_objects_;
638 586
639 bool deserializing_user_code_; 587 bool deserializing_user_code_;
640 588
641 DISALLOW_COPY_AND_ASSIGN(Deserializer); 589 DISALLOW_COPY_AND_ASSIGN(Deserializer);
642 }; 590 };
643 591
644 592
645 class CodeAddressMap; 593 class CodeAddressMap;
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
938 886
939 Vector<const Reservation> Reservations() const; 887 Vector<const Reservation> Reservations() const;
940 Vector<const byte> Payload() const; 888 Vector<const byte> Payload() const;
941 889
942 Vector<const byte> RawData() const { 890 Vector<const byte> RawData() const {
943 return Vector<const byte>(data_, size_); 891 return Vector<const byte>(data_, size_);
944 } 892 }
945 893
946 private: 894 private:
947 bool IsSane(); 895 bool IsSane();
896
948 // The data header consists of uint32_t-sized entries: 897 // The data header consists of uint32_t-sized entries:
949 // [0] version hash 898 // [0] magic number and external reference count
950 // [1] number of reservation size entries 899 // [1] version hash
951 // [2] payload length 900 // [2] number of reservation size entries
901 // [3] payload length
952 // ... reservations 902 // ... reservations
953 // ... serialized payload 903 // ... serialized payload
954 static const int kCheckSumOffset = 0; 904 static const int kCheckSumOffset = kMagicNumberOffset + kInt32Size;
955 static const int kNumReservationsOffset = kCheckSumOffset + kInt32Size; 905 static const int kNumReservationsOffset = kCheckSumOffset + kInt32Size;
956 static const int kPayloadLengthOffset = kNumReservationsOffset + kInt32Size; 906 static const int kPayloadLengthOffset = kNumReservationsOffset + kInt32Size;
957 static const int kHeaderSize = kPayloadLengthOffset + kInt32Size; 907 static const int kHeaderSize = kPayloadLengthOffset + kInt32Size;
958 }; 908 };
959 909
960 910
961 // Wrapper around ScriptData to provide code-serializer-specific functionality. 911 // Wrapper around ScriptData to provide code-serializer-specific functionality.
962 class SerializedCodeData : public SerializedData { 912 class SerializedCodeData : public SerializedData {
963 public: 913 public:
964 // Used when consuming. 914 // Used when consuming.
965 static SerializedCodeData* FromCachedData(ScriptData* cached_data, 915 static SerializedCodeData* FromCachedData(Isolate* isolate,
916 ScriptData* cached_data,
966 String* source); 917 String* source);
967 918
968 // Used when producing. 919 // Used when producing.
969 SerializedCodeData(const List<byte>& payload, const CodeSerializer& cs); 920 SerializedCodeData(const List<byte>& payload, const CodeSerializer& cs);
970 921
971 // Return ScriptData object and relinquish ownership over it to the caller. 922 // Return ScriptData object and relinquish ownership over it to the caller.
972 ScriptData* GetScriptData(); 923 ScriptData* GetScriptData();
973 924
974 Vector<const Reservation> Reservations() const; 925 Vector<const Reservation> Reservations() const;
975 Vector<const byte> Payload() const; 926 Vector<const byte> Payload() const;
976 927
977 int NumInternalizedStrings() const; 928 int NumInternalizedStrings() const;
978 Vector<const uint32_t> CodeStubKeys() const; 929 Vector<const uint32_t> CodeStubKeys() const;
979 930
980 private: 931 private:
981 explicit SerializedCodeData(ScriptData* data); 932 explicit SerializedCodeData(ScriptData* data);
982 933
983 enum SanityCheckResult { 934 enum SanityCheckResult {
984 CHECK_SUCCESS = 0, 935 CHECK_SUCCESS = 0,
985 MAGIC_NUMBER_MISMATCH = 1, 936 MAGIC_NUMBER_MISMATCH = 1,
986 VERSION_MISMATCH = 2, 937 VERSION_MISMATCH = 2,
987 SOURCE_MISMATCH = 3, 938 SOURCE_MISMATCH = 3,
988 CPU_FEATURES_MISMATCH = 4, 939 CPU_FEATURES_MISMATCH = 4,
989 FLAGS_MISMATCH = 5, 940 FLAGS_MISMATCH = 5,
990 CHECKSUM_MISMATCH = 6 941 CHECKSUM_MISMATCH = 6
991 }; 942 };
992 943
993 SanityCheckResult SanityCheck(String* source) const; 944 SanityCheckResult SanityCheck(Isolate* isolate, String* source) const;
994 945
995 uint32_t SourceHash(String* source) const { return source->length(); } 946 uint32_t SourceHash(String* source) const { return source->length(); }
996 947
997 static const uint32_t kMagicNumber = 0xC0D1F1ED;
998
999 // The data header consists of uint32_t-sized entries: 948 // The data header consists of uint32_t-sized entries:
1000 // [ 0] magic number 949 // [ 0] magic number and external reference count
1001 // [ 1] version hash 950 // [ 1] version hash
1002 // [ 2] source hash 951 // [ 2] source hash
1003 // [ 3] cpu features 952 // [ 3] cpu features
1004 // [ 4] flag hash 953 // [ 4] flag hash
1005 // [ 5] number of internalized strings 954 // [ 5] number of internalized strings
1006 // [ 6] number of code stub keys 955 // [ 6] number of code stub keys
1007 // [ 7] number of reservation size entries 956 // [ 7] number of reservation size entries
1008 // [ 8] payload length 957 // [ 8] payload length
1009 // [ 9] payload checksum part 1 958 // [ 9] payload checksum part 1
1010 // [10] payload checksum part 2 959 // [10] payload checksum part 2
1011 // ... reservations 960 // ... reservations
1012 // ... code stub keys 961 // ... code stub keys
1013 // ... serialized payload 962 // ... serialized payload
1014 static const int kMagicNumberOffset = 0;
1015 static const int kVersionHashOffset = kMagicNumberOffset + kInt32Size; 963 static const int kVersionHashOffset = kMagicNumberOffset + kInt32Size;
1016 static const int kSourceHashOffset = kVersionHashOffset + kInt32Size; 964 static const int kSourceHashOffset = kVersionHashOffset + kInt32Size;
1017 static const int kCpuFeaturesOffset = kSourceHashOffset + kInt32Size; 965 static const int kCpuFeaturesOffset = kSourceHashOffset + kInt32Size;
1018 static const int kFlagHashOffset = kCpuFeaturesOffset + kInt32Size; 966 static const int kFlagHashOffset = kCpuFeaturesOffset + kInt32Size;
1019 static const int kNumInternalizedStringsOffset = kFlagHashOffset + kInt32Size; 967 static const int kNumInternalizedStringsOffset = kFlagHashOffset + kInt32Size;
1020 static const int kNumReservationsOffset = 968 static const int kNumReservationsOffset =
1021 kNumInternalizedStringsOffset + kInt32Size; 969 kNumInternalizedStringsOffset + kInt32Size;
1022 static const int kNumCodeStubKeysOffset = kNumReservationsOffset + kInt32Size; 970 static const int kNumCodeStubKeysOffset = kNumReservationsOffset + kInt32Size;
1023 static const int kPayloadLengthOffset = kNumCodeStubKeysOffset + kInt32Size; 971 static const int kPayloadLengthOffset = kNumCodeStubKeysOffset + kInt32Size;
1024 static const int kChecksum1Offset = kPayloadLengthOffset + kInt32Size; 972 static const int kChecksum1Offset = kPayloadLengthOffset + kInt32Size;
1025 static const int kChecksum2Offset = kChecksum1Offset + kInt32Size; 973 static const int kChecksum2Offset = kChecksum1Offset + kInt32Size;
1026 static const int kHeaderSize = kChecksum2Offset + kInt32Size; 974 static const int kHeaderSize = kChecksum2Offset + kInt32Size;
1027 }; 975 };
1028 } } // namespace v8::internal 976 } } // namespace v8::internal
1029 977
1030 #endif // V8_SERIALIZE_H_ 978 #endif // V8_SERIALIZE_H_
OLDNEW
« no previous file with comments | « src/disassembler.cc ('k') | src/serialize.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698