OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 26 matching lines...) Expand all Loading... |
37 #include "runtime.h" | 37 #include "runtime.h" |
38 #include "serialize.h" | 38 #include "serialize.h" |
39 #include "stub-cache.h" | 39 #include "stub-cache.h" |
40 #include "v8threads.h" | 40 #include "v8threads.h" |
41 #include "top.h" | 41 #include "top.h" |
42 #include "bootstrapper.h" | 42 #include "bootstrapper.h" |
43 | 43 |
44 namespace v8 { | 44 namespace v8 { |
45 namespace internal { | 45 namespace internal { |
46 | 46 |
| 47 class ExternalReferenceTable; |
| 48 |
| 49 class SerializerPrivateData { |
| 50 public: |
| 51 ExternalReferenceTable* external_reference_table_; |
| 52 HashMap* serialization_map_; |
| 53 SerializerPrivateData() |
| 54 :serialization_map_(NULL), |
| 55 external_reference_table_(NULL) { |
| 56 } |
| 57 }; |
| 58 |
| 59 SerializerData::SerializerData() |
| 60 :private_data_(*new SerializerPrivateData()), |
| 61 serialization_enabled_(false), |
| 62 too_late_to_enable_now_(false) { |
| 63 } |
| 64 |
| 65 SerializerData::~SerializerData() { |
| 66 delete &private_data_; |
| 67 } |
| 68 |
47 // Mapping objects to their location after deserialization. | 69 // Mapping objects to their location after deserialization. |
48 // This is used during building, but not at runtime by V8. | 70 // This is used during building, but not at runtime by V8. |
49 class SerializationAddressMapper { | 71 class SerializationAddressMapper { |
50 public: | 72 public: |
51 static bool IsMapped(HeapObject* obj) { | 73 static bool IsMapped(HeapObject* obj) { |
52 EnsureMapExists(); | 74 EnsureMapExists(); |
53 return serialization_map_->Lookup(Key(obj), Hash(obj), false) != NULL; | 75 return v8_context()->serializer_data_.private_data_. |
| 76 serialization_map_->Lookup(Key(obj), Hash(obj), false) != NULL; |
54 } | 77 } |
55 | 78 |
56 static int MappedTo(HeapObject* obj) { | 79 static int MappedTo(HeapObject* obj) { |
57 ASSERT(IsMapped(obj)); | 80 ASSERT(IsMapped(obj)); |
58 return reinterpret_cast<intptr_t>(serialization_map_->Lookup(Key(obj), | 81 return reinterpret_cast<intptr_t>(v8_context()->serializer_data_. |
59 Hash(obj), | 82 private_data_.serialization_map_->Lookup( |
60 false)->value); | 83 Key(obj), |
| 84 Hash(obj), |
| 85 false)->value); |
61 } | 86 } |
62 | 87 |
63 static void Map(HeapObject* obj, int to) { | 88 static void Map(HeapObject* obj, int to) { |
64 EnsureMapExists(); | 89 EnsureMapExists(); |
65 ASSERT(!IsMapped(obj)); | 90 ASSERT(!IsMapped(obj)); |
66 HashMap::Entry* entry = | 91 HashMap::Entry* entry = v8_context()->serializer_data_.private_data_. |
67 serialization_map_->Lookup(Key(obj), Hash(obj), true); | 92 serialization_map_->Lookup(Key(obj), Hash(obj), true); |
68 entry->value = Value(to); | 93 entry->value = Value(to); |
69 } | 94 } |
70 | 95 |
71 static void Zap() { | 96 static void Zap() { |
72 if (serialization_map_ != NULL) { | 97 HashMap*& serialization_map = v8_context()->serializer_data_. |
73 delete serialization_map_; | 98 private_data_.serialization_map_; |
| 99 if (serialization_map != NULL) { |
| 100 delete serialization_map; |
74 } | 101 } |
75 serialization_map_ = NULL; | 102 serialization_map = NULL; |
76 } | 103 } |
77 | 104 |
78 private: | 105 private: |
79 static bool SerializationMatchFun(void* key1, void* key2) { | 106 static bool SerializationMatchFun(void* key1, void* key2) { |
80 return key1 == key2; | 107 return key1 == key2; |
81 } | 108 } |
82 | 109 |
83 static uint32_t Hash(HeapObject* obj) { | 110 static uint32_t Hash(HeapObject* obj) { |
84 return reinterpret_cast<intptr_t>(obj->address()); | 111 return reinterpret_cast<intptr_t>(obj->address()); |
85 } | 112 } |
86 | 113 |
87 static void* Key(HeapObject* obj) { | 114 static void* Key(HeapObject* obj) { |
88 return reinterpret_cast<void*>(obj->address()); | 115 return reinterpret_cast<void*>(obj->address()); |
89 } | 116 } |
90 | 117 |
91 static void* Value(int v) { | 118 static void* Value(int v) { |
92 return reinterpret_cast<void*>(v); | 119 return reinterpret_cast<void*>(v); |
93 } | 120 } |
94 | 121 |
95 static void EnsureMapExists() { | 122 static void EnsureMapExists() { |
96 if (serialization_map_ == NULL) { | 123 HashMap*& serialization_map = v8_context()->serializer_data_. |
97 serialization_map_ = new HashMap(&SerializationMatchFun); | 124 private_data_.serialization_map_; |
| 125 if (serialization_map == NULL) { |
| 126 serialization_map = new HashMap(&SerializationMatchFun); |
98 } | 127 } |
99 } | 128 } |
100 | |
101 static HashMap* serialization_map_; | |
102 }; | 129 }; |
103 | 130 |
104 | 131 |
105 HashMap* SerializationAddressMapper::serialization_map_ = NULL; | |
106 | 132 |
107 | 133 |
108 | 134 |
109 | 135 |
110 // ----------------------------------------------------------------------------- | 136 // ----------------------------------------------------------------------------- |
111 // Coding of external references. | 137 // Coding of external references. |
112 | 138 |
113 // The encoding of an external reference. The type is in the high word. | 139 // The encoding of an external reference. The type is in the high word. |
114 // The id is in the low word. | 140 // The id is in the low word. |
115 static uint32_t EncodeExternal(TypeCode type, uint16_t id) { | 141 static uint32_t EncodeExternal(TypeCode type, uint16_t id) { |
116 return static_cast<uint32_t>(type) << 16 | id; | 142 return static_cast<uint32_t>(type) << 16 | id; |
117 } | 143 } |
118 | 144 |
119 | 145 |
120 static int* GetInternalPointer(StatsCounter* counter) { | 146 static int* GetInternalPointer(StatsCounter* counter) { |
121 // All counters refer to dummy_counter, if deserializing happens without | 147 // All counters refer to dummy_counter, if deserializing happens without |
122 // setting up counters. | 148 // setting up counters. |
123 static int dummy_counter = 0; | 149 static int dummy_counter = 0; |
124 return counter->Enabled() ? counter->GetInternalPointer() : &dummy_counter; | 150 return counter->Enabled() ? counter->GetInternalPointer() : &dummy_counter; |
125 } | 151 } |
126 | 152 |
127 | 153 |
128 // ExternalReferenceTable is a helper class that defines the relationship | 154 // ExternalReferenceTable is a helper class that defines the relationship |
129 // between external references and their encodings. It is used to build | 155 // between external references and their encodings. It is used to build |
130 // hashmaps in ExternalReferenceEncoder and ExternalReferenceDecoder. | 156 // hashmaps in ExternalReferenceEncoder and ExternalReferenceDecoder. |
131 class ExternalReferenceTable { | 157 class ExternalReferenceTable { |
132 public: | 158 public: |
133 static ExternalReferenceTable* instance() { | 159 static ExternalReferenceTable* instance() { |
134 if (!instance_) instance_ = new ExternalReferenceTable(); | 160 ExternalReferenceTable*& instance = v8_context()->serializer_data_. |
135 return instance_; | 161 private_data_.external_reference_table_; |
| 162 if (!instance) instance = new ExternalReferenceTable(); |
| 163 return instance; |
136 } | 164 } |
137 | 165 |
138 int size() const { return refs_.length(); } | 166 int size() const { return refs_.length(); } |
139 | 167 |
140 Address address(int i) { return refs_[i].address; } | 168 Address address(int i) { return refs_[i].address; } |
141 | 169 |
142 uint32_t code(int i) { return refs_[i].code; } | 170 uint32_t code(int i) { return refs_[i].code; } |
143 | 171 |
144 const char* name(int i) { return refs_[i].name; } | 172 const char* name(int i) { return refs_[i].name; } |
145 | 173 |
146 int max_id(int code) { return max_id_[code]; } | 174 int max_id(int code) { return max_id_[code]; } |
147 | 175 |
148 private: | 176 private: |
149 static ExternalReferenceTable* instance_; | |
150 | 177 |
151 ExternalReferenceTable() : refs_(64) { PopulateTable(); } | 178 ExternalReferenceTable() : refs_(64) { PopulateTable(); } |
152 ~ExternalReferenceTable() { } | 179 ~ExternalReferenceTable() { } |
153 | 180 |
154 struct ExternalReferenceEntry { | 181 struct ExternalReferenceEntry { |
155 Address address; | 182 Address address; |
156 uint32_t code; | 183 uint32_t code; |
157 const char* name; | 184 const char* name; |
158 }; | 185 }; |
159 | 186 |
160 void PopulateTable(); | 187 void PopulateTable(); |
161 | 188 |
162 // For a few types of references, we can get their address from their id. | 189 // For a few types of references, we can get their address from their id. |
163 void AddFromId(TypeCode type, uint16_t id, const char* name); | 190 void AddFromId(TypeCode type, uint16_t id, const char* name); |
164 | 191 |
165 // For other types of references, the caller will figure out the address. | 192 // For other types of references, the caller will figure out the address. |
166 void Add(Address address, TypeCode type, uint16_t id, const char* name); | 193 void Add(Address address, TypeCode type, uint16_t id, const char* name); |
167 | 194 |
168 List<ExternalReferenceEntry> refs_; | 195 List<ExternalReferenceEntry> refs_; |
169 int max_id_[kTypeCodeCount]; | 196 int max_id_[kTypeCodeCount]; |
170 }; | 197 }; |
171 | 198 |
172 | 199 |
173 ExternalReferenceTable* ExternalReferenceTable::instance_ = NULL; | |
174 | 200 |
175 | 201 |
176 void ExternalReferenceTable::AddFromId(TypeCode type, | 202 void ExternalReferenceTable::AddFromId(TypeCode type, |
177 uint16_t id, | 203 uint16_t id, |
178 const char* name) { | 204 const char* name) { |
179 Address address; | 205 Address address; |
180 switch (type) { | 206 switch (type) { |
181 case C_BUILTIN: { | 207 case C_BUILTIN: { |
182 ExternalReference ref(static_cast<Builtins::CFunctionId>(id)); | 208 ExternalReference ref(static_cast<Builtins::CFunctionId>(id)); |
183 address = ref.address(); | 209 address = ref.address(); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 | 335 |
310 // Stat counters | 336 // Stat counters |
311 struct StatsRefTableEntry { | 337 struct StatsRefTableEntry { |
312 StatsCounter* counter; | 338 StatsCounter* counter; |
313 uint16_t id; | 339 uint16_t id; |
314 const char* name; | 340 const char* name; |
315 }; | 341 }; |
316 | 342 |
317 static const StatsRefTableEntry stats_ref_table[] = { | 343 static const StatsRefTableEntry stats_ref_table[] = { |
318 #define COUNTER_ENTRY(name, caption) \ | 344 #define COUNTER_ENTRY(name, caption) \ |
319 { &Counters::name, \ | 345 { &COUNTER(name), \ |
320 Counters::k_##name, \ | 346 Counters::k_##name, \ |
321 "Counters::" #name }, | 347 "Counters::" #name }, |
322 | 348 |
323 STATS_COUNTER_LIST_1(COUNTER_ENTRY) | 349 STATS_COUNTER_LIST_1(COUNTER_ENTRY) |
324 STATS_COUNTER_LIST_2(COUNTER_ENTRY) | 350 STATS_COUNTER_LIST_2(COUNTER_ENTRY) |
325 #undef COUNTER_ENTRY | 351 #undef COUNTER_ENTRY |
326 }; // end of stats_ref_table[]. | 352 }; // end of stats_ref_table[]. |
327 | 353 |
328 for (size_t i = 0; i < ARRAY_SIZE(stats_ref_table); ++i) { | 354 for (size_t i = 0; i < ARRAY_SIZE(stats_ref_table); ++i) { |
329 Add(reinterpret_cast<Address>( | 355 Add(reinterpret_cast<Address>( |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 | 567 |
542 | 568 |
543 ExternalReferenceDecoder::~ExternalReferenceDecoder() { | 569 ExternalReferenceDecoder::~ExternalReferenceDecoder() { |
544 for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) { | 570 for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) { |
545 DeleteArray(encodings_[type]); | 571 DeleteArray(encodings_[type]); |
546 } | 572 } |
547 DeleteArray(encodings_); | 573 DeleteArray(encodings_); |
548 } | 574 } |
549 | 575 |
550 | 576 |
551 bool Serializer::serialization_enabled_ = false; | |
552 bool Serializer::too_late_to_enable_now_ = false; | |
553 | |
554 | 577 |
555 Deserializer::Deserializer(SnapshotByteSource* source) | 578 Deserializer::Deserializer(SnapshotByteSource* source) |
556 : source_(source), | 579 : source_(source), |
557 external_reference_decoder_(NULL) { | 580 external_reference_decoder_(NULL) { |
558 } | 581 } |
559 | 582 |
560 | 583 |
561 // This routine both allocates a new object, and also keeps | 584 // This routine both allocates a new object, and also keeps |
562 // track of where objects have been allocated so that we can | 585 // track of where objects have been allocated so that we can |
563 // fix back references when deserializing. | 586 // fix back references when deserializing. |
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1213 fullness_[space] = RoundUp(fullness_[space], Page::kPageSize); | 1236 fullness_[space] = RoundUp(fullness_[space], Page::kPageSize); |
1214 } | 1237 } |
1215 } | 1238 } |
1216 int allocation_address = fullness_[space]; | 1239 int allocation_address = fullness_[space]; |
1217 fullness_[space] = allocation_address + size; | 1240 fullness_[space] = allocation_address + size; |
1218 return allocation_address; | 1241 return allocation_address; |
1219 } | 1242 } |
1220 | 1243 |
1221 | 1244 |
1222 } } // namespace v8::internal | 1245 } } // namespace v8::internal |
OLD | NEW |