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

Side by Side Diff: src/serialize.h

Issue 548149: Another step on the way to context snapshots. We can now refer to... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « src/mksnapshot.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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 f(7, 7) \ 178 f(7, 7) \
179 f(8, 8) \ 179 f(8, 8) \
180 f(9, 12) \ 180 f(9, 12) \
181 f(10, 16) \ 181 f(10, 16) \
182 f(11, 20) \ 182 f(11, 20) \
183 f(12, 24) \ 183 f(12, 24) \
184 f(13, 28) \ 184 f(13, 28) \
185 f(14, 32) \ 185 f(14, 32) \
186 f(15, 36) 186 f(15, 36)
187 187
188 // The SerDes class is a common superclass for Serializer and Deserializer 188 // The Serializer/Deserializer class is a common superclass for Serializer and
189 // which is used to store common constants and methods used by both. 189 // Deserializer which is used to store common constants and methods used by
190 class SerDes: public ObjectVisitor { 190 // both.
191 class SerializerDeserializer: public ObjectVisitor {
192 public:
193 static void Iterate(ObjectVisitor* visitor);
194 static void SetSnapshotCacheSize(int size);
195
191 protected: 196 protected:
192 enum DataType { 197 enum DataType {
193 RAW_DATA_SERIALIZATION = 0, 198 RAW_DATA_SERIALIZATION = 0,
194 // And 15 common raw lengths. 199 // And 15 common raw lengths.
195 OBJECT_SERIALIZATION = 16, 200 OBJECT_SERIALIZATION = 16,
196 // One variant per space. 201 // One variant per space.
197 CODE_OBJECT_SERIALIZATION = 25, 202 CODE_OBJECT_SERIALIZATION = 25,
198 // One per space (only code spaces in use). 203 // One per space (only code spaces in use).
199 EXTERNAL_REFERENCE_SERIALIZATION = 34, 204 EXTERNAL_REFERENCE_SERIALIZATION = 34,
200 EXTERNAL_BRANCH_TARGET_SERIALIZATION = 35, 205 EXTERNAL_BRANCH_TARGET_SERIALIZATION = 35,
201 SYNCHRONIZE = 36, 206 SYNCHRONIZE = 36,
202 START_NEW_PAGE_SERIALIZATION = 37, 207 START_NEW_PAGE_SERIALIZATION = 37,
203 NATIVES_STRING_RESOURCE = 38, 208 NATIVES_STRING_RESOURCE = 38,
204 ROOT_SERIALIZATION = 39, 209 ROOT_SERIALIZATION = 39,
205 // Free: 40-47. 210 PARTIAL_SNAPSHOT_CACHE_ENTRY = 40,
211 // Free: 41-47.
206 BACKREF_SERIALIZATION = 48, 212 BACKREF_SERIALIZATION = 48,
207 // One per space, must be kSpaceMask aligned. 213 // One per space, must be kSpaceMask aligned.
208 // Free: 57-63. 214 // Free: 57-63.
209 REFERENCE_SERIALIZATION = 64, 215 REFERENCE_SERIALIZATION = 64,
210 // One per space and common references. Must be kSpaceMask aligned. 216 // One per space and common references. Must be kSpaceMask aligned.
211 CODE_BACKREF_SERIALIZATION = 80, 217 CODE_BACKREF_SERIALIZATION = 80,
212 // One per space, must be kSpaceMask aligned. 218 // One per space, must be kSpaceMask aligned.
213 // Free: 89-95. 219 // Free: 89-95.
214 CODE_REFERENCE_SERIALIZATION = 96 220 CODE_REFERENCE_SERIALIZATION = 96
215 // One per space, must be kSpaceMask aligned. 221 // One per space, must be kSpaceMask aligned.
216 // Free: 105-255. 222 // Free: 105-255.
217 }; 223 };
218 static const int kLargeData = LAST_SPACE; 224 static const int kLargeData = LAST_SPACE;
219 static const int kLargeCode = kLargeData + 1; 225 static const int kLargeCode = kLargeData + 1;
220 static const int kLargeFixedArray = kLargeCode + 1; 226 static const int kLargeFixedArray = kLargeCode + 1;
221 static const int kNumberOfSpaces = kLargeFixedArray + 1; 227 static const int kNumberOfSpaces = kLargeFixedArray + 1;
222 228
223 // A bitmask for getting the space out of an instruction. 229 // A bitmask for getting the space out of an instruction.
224 static const int kSpaceMask = 15; 230 static const int kSpaceMask = 15;
225 231
226 static inline bool SpaceIsLarge(int space) { return space >= kLargeData; } 232 static inline bool SpaceIsLarge(int space) { return space >= kLargeData; }
227 static inline bool SpaceIsPaged(int space) { 233 static inline bool SpaceIsPaged(int space) {
228 return space >= FIRST_PAGED_SPACE && space <= LAST_PAGED_SPACE; 234 return space >= FIRST_PAGED_SPACE && space <= LAST_PAGED_SPACE;
229 } 235 }
236
237 static int partial_snapshot_cache_length_;
238 static const int kPartialSnapshotCacheCapacity = 1024;
239 static Object* partial_snapshot_cache_[];
230 }; 240 };
231 241
232 242
233 243
234 // A Deserializer reads a snapshot and reconstructs the Object graph it defines. 244 // A Deserializer reads a snapshot and reconstructs the Object graph it defines.
235 class Deserializer: public SerDes { 245 class Deserializer: public SerializerDeserializer {
236 public: 246 public:
237 // Create a deserializer from a snapshot byte source. 247 // Create a deserializer from a snapshot byte source.
238 explicit Deserializer(SnapshotByteSource* source); 248 explicit Deserializer(SnapshotByteSource* source);
239 249
240 virtual ~Deserializer() { } 250 virtual ~Deserializer();
241 251
242 // Deserialize the snapshot into an empty heap. 252 // Deserialize the snapshot into an empty heap.
243 void Deserialize(); 253 void Deserialize();
244 254
245 // Deserialize a single object and the objects reachable from it. 255 // Deserialize a single object and the objects reachable from it.
246 void DeserializePartial(Object** root); 256 void DeserializePartial(Object** root);
247 257
248 #ifdef DEBUG 258 #ifdef DEBUG
249 virtual void Synchronize(const char* tag); 259 virtual void Synchronize(const char* tag);
250 #endif 260 #endif
251 261
252 static void TearDown();
253
254 private: 262 private:
255 virtual void VisitPointers(Object** start, Object** end); 263 virtual void VisitPointers(Object** start, Object** end);
256 264
257 virtual void VisitExternalReferences(Address* start, Address* end) { 265 virtual void VisitExternalReferences(Address* start, Address* end) {
258 UNREACHABLE(); 266 UNREACHABLE();
259 } 267 }
260 268
261 virtual void VisitRuntimeEntry(RelocInfo* rinfo) { 269 virtual void VisitRuntimeEntry(RelocInfo* rinfo) {
262 UNREACHABLE(); 270 UNREACHABLE();
263 } 271 }
264 272
265 void ReadChunk(Object** start, Object** end, int space, Address address); 273 void ReadChunk(Object** start, Object** end, int space, Address address);
266 HeapObject* GetAddressFromStart(int space); 274 HeapObject* GetAddressFromStart(int space);
267 inline HeapObject* GetAddressFromEnd(int space); 275 inline HeapObject* GetAddressFromEnd(int space);
268 Address Allocate(int space_number, Space* space, int size); 276 Address Allocate(int space_number, Space* space, int size);
269 void ReadObject(int space_number, Space* space, Object** write_back); 277 void ReadObject(int space_number, Space* space, Object** write_back);
270 278
271 // Keep track of the pages in the paged spaces. 279 // Keep track of the pages in the paged spaces.
272 // (In large object space we are keeping track of individual objects 280 // (In large object space we are keeping track of individual objects
273 // rather than pages.) In new space we just need the address of the 281 // rather than pages.) In new space we just need the address of the
274 // first object and the others will flow from that. 282 // first object and the others will flow from that.
275 List<Address> pages_[SerDes::kNumberOfSpaces]; 283 List<Address> pages_[SerializerDeserializer::kNumberOfSpaces];
276 284
277 SnapshotByteSource* source_; 285 SnapshotByteSource* source_;
278 static ExternalReferenceDecoder* external_reference_decoder_; 286 static ExternalReferenceDecoder* external_reference_decoder_;
279 // This is the address of the next object that will be allocated in each 287 // This is the address of the next object that will be allocated in each
280 // space. It is used to calculate the addresses of back-references. 288 // space. It is used to calculate the addresses of back-references.
281 Address high_water_[LAST_SPACE + 1]; 289 Address high_water_[LAST_SPACE + 1];
282 // This is the address of the most recent object that was allocated. It 290 // This is the address of the most recent object that was allocated. It
283 // is used to set the location of the new page when we encounter a 291 // is used to set the location of the new page when we encounter a
284 // START_NEW_PAGE_SERIALIZATION tag. 292 // START_NEW_PAGE_SERIALIZATION tag.
285 Address last_object_address_; 293 Address last_object_address_;
286 294
287 DISALLOW_COPY_AND_ASSIGN(Deserializer); 295 DISALLOW_COPY_AND_ASSIGN(Deserializer);
288 }; 296 };
289 297
290 298
291 class SnapshotByteSink { 299 class SnapshotByteSink {
292 public: 300 public:
293 virtual ~SnapshotByteSink() { } 301 virtual ~SnapshotByteSink() { }
294 virtual void Put(int byte, const char* description) = 0; 302 virtual void Put(int byte, const char* description) = 0;
295 virtual void PutSection(int byte, const char* description) { 303 virtual void PutSection(int byte, const char* description) {
296 Put(byte, description); 304 Put(byte, description);
297 } 305 }
298 void PutInt(uintptr_t integer, const char* description); 306 void PutInt(uintptr_t integer, const char* description);
299 virtual int Position() = 0; 307 virtual int Position() = 0;
300 }; 308 };
301 309
302 310
303 class Serializer : public SerDes { 311 // Mapping objects to their location after deserialization.
312 // This is used during building, but not at runtime by V8.
313 class SerializationAddressMapper {
314 public:
315 SerializationAddressMapper()
316 : serialization_map_(new HashMap(&SerializationMatchFun)),
317 no_allocation_(new AssertNoAllocation()) { }
318
319 ~SerializationAddressMapper() {
320 delete serialization_map_;
321 delete no_allocation_;
322 }
323
324 bool IsMapped(HeapObject* obj) {
325 return serialization_map_->Lookup(Key(obj), Hash(obj), false) != NULL;
326 }
327
328 int MappedTo(HeapObject* obj) {
329 ASSERT(IsMapped(obj));
330 return static_cast<int>(reinterpret_cast<intptr_t>(
331 serialization_map_->Lookup(Key(obj), Hash(obj), false)->value));
332 }
333
334 void AddMapping(HeapObject* obj, int to) {
335 ASSERT(!IsMapped(obj));
336 HashMap::Entry* entry =
337 serialization_map_->Lookup(Key(obj), Hash(obj), true);
338 entry->value = Value(to);
339 }
340
341 private:
342 static bool SerializationMatchFun(void* key1, void* key2) {
343 return key1 == key2;
344 }
345
346 static uint32_t Hash(HeapObject* obj) {
347 return static_cast<int32_t>(reinterpret_cast<intptr_t>(obj->address()));
348 }
349
350 static void* Key(HeapObject* obj) {
351 return reinterpret_cast<void*>(obj->address());
352 }
353
354 static void* Value(int v) {
355 return reinterpret_cast<void*>(v);
356 }
357
358 HashMap* serialization_map_;
359 AssertNoAllocation* no_allocation_;
360 DISALLOW_COPY_AND_ASSIGN(SerializationAddressMapper);
361 };
362
363
364 class Serializer : public SerializerDeserializer {
304 public: 365 public:
305 explicit Serializer(SnapshotByteSink* sink); 366 explicit Serializer(SnapshotByteSink* sink);
306 // Serialize the current state of the heap.
307 void Serialize();
308 // Serialize a single object and the objects reachable from it.
309 void SerializePartial(Object** obj);
310 void VisitPointers(Object** start, Object** end); 367 void VisitPointers(Object** start, Object** end);
311 // You can call this after serialization to find out how much space was used 368 // You can call this after serialization to find out how much space was used
312 // in each space. 369 // in each space.
313 int CurrentAllocationAddress(int space) { 370 int CurrentAllocationAddress(int space) {
314 if (SpaceIsLarge(space)) return large_object_total_; 371 if (SpaceIsLarge(space)) return large_object_total_;
315 return fullness_[space]; 372 return fullness_[space];
316 } 373 }
317 374
318 static void Enable() { 375 static void Enable() {
319 if (!serialization_enabled_) { 376 if (!serialization_enabled_) {
320 ASSERT(!too_late_to_enable_now_); 377 ASSERT(!too_late_to_enable_now_);
321 } 378 }
322 serialization_enabled_ = true; 379 serialization_enabled_ = true;
323 } 380 }
324 381
325 static void Disable() { serialization_enabled_ = false; } 382 static void Disable() { serialization_enabled_ = false; }
326 // Call this when you have made use of the fact that there is no serialization 383 // Call this when you have made use of the fact that there is no serialization
327 // going on. 384 // going on.
328 static void TooLateToEnableNow() { too_late_to_enable_now_ = true; } 385 static void TooLateToEnableNow() { too_late_to_enable_now_ = true; }
329 static bool enabled() { return serialization_enabled_; } 386 static bool enabled() { return serialization_enabled_; }
387 SerializationAddressMapper* address_mapper() { return &address_mapper_; }
330 #ifdef DEBUG 388 #ifdef DEBUG
331 virtual void Synchronize(const char* tag); 389 virtual void Synchronize(const char* tag);
332 #endif 390 #endif
333 391
334 private: 392 protected:
335 enum ReferenceRepresentation { 393 enum ReferenceRepresentation {
336 TAGGED_REPRESENTATION, // A tagged object reference. 394 TAGGED_REPRESENTATION, // A tagged object reference.
337 CODE_TARGET_REPRESENTATION // A reference to first instruction in target. 395 CODE_TARGET_REPRESENTATION // A reference to first instruction in target.
338 }; 396 };
397 static const int kInvalidRootIndex = -1;
398 virtual int RootIndex(HeapObject* heap_object) = 0;
399 virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) = 0;
400
339 class ObjectSerializer : public ObjectVisitor { 401 class ObjectSerializer : public ObjectVisitor {
340 public: 402 public:
341 ObjectSerializer(Serializer* serializer, 403 ObjectSerializer(Serializer* serializer,
342 Object* o, 404 Object* o,
343 SnapshotByteSink* sink, 405 SnapshotByteSink* sink,
344 ReferenceRepresentation representation) 406 ReferenceRepresentation representation)
345 : serializer_(serializer), 407 : serializer_(serializer),
346 object_(HeapObject::cast(o)), 408 object_(HeapObject::cast(o)),
347 sink_(sink), 409 sink_(sink),
348 reference_representation_(representation), 410 reference_representation_(representation),
(...skipping 15 matching lines...) Expand all
364 private: 426 private:
365 void OutputRawData(Address up_to); 427 void OutputRawData(Address up_to);
366 428
367 Serializer* serializer_; 429 Serializer* serializer_;
368 HeapObject* object_; 430 HeapObject* object_;
369 SnapshotByteSink* sink_; 431 SnapshotByteSink* sink_;
370 ReferenceRepresentation reference_representation_; 432 ReferenceRepresentation reference_representation_;
371 int bytes_processed_so_far_; 433 int bytes_processed_so_far_;
372 }; 434 };
373 435
374 void SerializeObject(Object* o, ReferenceRepresentation representation); 436 virtual void SerializeObject(Object* o,
437 ReferenceRepresentation representation) = 0;
438 void SerializeReferenceToPreviousObject(
439 int space,
440 int address,
441 ReferenceRepresentation reference_representation);
375 void InitializeAllocators(); 442 void InitializeAllocators();
376 // This will return the space for an object. If the object is in large 443 // This will return the space for an object. If the object is in large
377 // object space it may return kLargeCode or kLargeFixedArray in order 444 // object space it may return kLargeCode or kLargeFixedArray in order
378 // to indicate to the deserializer what kind of large object allocation 445 // to indicate to the deserializer what kind of large object allocation
379 // to make. 446 // to make.
380 static int SpaceOfObject(HeapObject* object); 447 static int SpaceOfObject(HeapObject* object);
381 // This just returns the space of the object. It will return LO_SPACE 448 // This just returns the space of the object. It will return LO_SPACE
382 // for all large objects since you can't check the type of the object 449 // for all large objects since you can't check the type of the object
383 // once the map has been used for the serialization address. 450 // once the map has been used for the serialization address.
384 static int SpaceOfAlreadySerializedObject(HeapObject* object); 451 static int SpaceOfAlreadySerializedObject(HeapObject* object);
385 int Allocate(int space, int size, bool* new_page_started); 452 int Allocate(int space, int size, bool* new_page_started);
386 int EncodeExternalReference(Address addr) { 453 int EncodeExternalReference(Address addr) {
387 return external_reference_encoder_->Encode(addr); 454 return external_reference_encoder_->Encode(addr);
388 } 455 }
389 int RootIndex(HeapObject* heap_object);
390 static const int kInvalidRootIndex = -1;
391 456
392 // Keep track of the fullness of each space in order to generate 457 // Keep track of the fullness of each space in order to generate
393 // relative addresses for back references. Large objects are 458 // relative addresses for back references. Large objects are
394 // just numbered sequentially since relative addresses make no 459 // just numbered sequentially since relative addresses make no
395 // sense in large object space. 460 // sense in large object space.
396 int fullness_[LAST_SPACE + 1]; 461 int fullness_[LAST_SPACE + 1];
397 SnapshotByteSink* sink_; 462 SnapshotByteSink* sink_;
398 int current_root_index_; 463 int current_root_index_;
399 ExternalReferenceEncoder* external_reference_encoder_; 464 ExternalReferenceEncoder* external_reference_encoder_;
400 bool partial_;
401 static bool serialization_enabled_; 465 static bool serialization_enabled_;
402 // Did we already make use of the fact that serialization was not enabled? 466 // Did we already make use of the fact that serialization was not enabled?
403 static bool too_late_to_enable_now_; 467 static bool too_late_to_enable_now_;
404 int large_object_total_; 468 int large_object_total_;
469 SerializationAddressMapper address_mapper_;
405 470
406 friend class ObjectSerializer; 471 friend class ObjectSerializer;
407 friend class Deserializer; 472 friend class Deserializer;
408 473
409 DISALLOW_COPY_AND_ASSIGN(Serializer); 474 DISALLOW_COPY_AND_ASSIGN(Serializer);
410 }; 475 };
411 476
477
478 class PartialSerializer : public Serializer {
479 public:
480 PartialSerializer(Serializer* startup_snapshot_serializer,
481 SnapshotByteSink* sink)
482 : Serializer(sink),
483 startup_serializer_(startup_snapshot_serializer) {
484 }
485
486 // Serialize the objects reachable from a single object pointer.
487 virtual void Serialize(Object** o);
488 virtual void SerializeObject(Object* o,
489 ReferenceRepresentation representation);
490
491 protected:
492 virtual int RootIndex(HeapObject* o);
493 virtual int PartialSnapshotCacheIndex(HeapObject* o);
494 virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) {
495 return o->IsString() || o->IsSharedFunctionInfo();
496 }
497
498 private:
499 Serializer* startup_serializer_;
500 DISALLOW_COPY_AND_ASSIGN(PartialSerializer);
501 };
502
503
504 class StartupSerializer : public Serializer {
505 public:
506 explicit StartupSerializer(SnapshotByteSink* sink) : Serializer(sink) {
507 // Clear the cache of objects used by the partial snapshot. After the
508 // strong roots have been serialized we can create a partial snapshot
509 // which will repopulate the cache with objects neede by that partial
510 // snapshot.
511 partial_snapshot_cache_length_ = 0;
512 }
513 // Serialize the current state of the heap. The order is:
514 // 1) Strong references.
515 // 2) Partial snapshot cache.
516 // 3) Weak references (eg the symbol table).
517 virtual void SerializeStrongReferences();
518 virtual void SerializeObject(Object* o,
519 ReferenceRepresentation representation);
520 void SerializeWeakReferences();
521 void Serialize() {
522 SerializeStrongReferences();
523 SerializeWeakReferences();
524 }
525
526 private:
527 virtual int RootIndex(HeapObject* o) { return kInvalidRootIndex; }
528 virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) {
529 return false;
530 }
531 };
532
412 } } // namespace v8::internal 533 } } // namespace v8::internal
413 534
414 #endif // V8_SERIALIZE_H_ 535 #endif // V8_SERIALIZE_H_
OLDNEW
« no previous file with comments | « src/mksnapshot.cc ('k') | src/serialize.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698