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

Side by Side Diff: src/serialize.h

Issue 766893002: Serializer: cache recent back references for shorter encoding. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: addressed comments Created 6 years 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/flag-definitions.h ('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/compiler.h" 8 #include "src/compiler.h"
9 #include "src/hashmap.h" 9 #include "src/hashmap.h"
10 #include "src/heap-profiler.h" 10 #include "src/heap-profiler.h"
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 Add(string, BackReference::SourceReference()); 278 Add(string, BackReference::SourceReference());
279 } 279 }
280 280
281 private: 281 private:
282 DisallowHeapAllocation no_allocation_; 282 DisallowHeapAllocation no_allocation_;
283 HashMap* map_; 283 HashMap* map_;
284 DISALLOW_COPY_AND_ASSIGN(BackReferenceMap); 284 DISALLOW_COPY_AND_ASSIGN(BackReferenceMap);
285 }; 285 };
286 286
287 287
288 class HotObjectsList {
289 public:
290 HotObjectsList() : index_(0) {
291 for (int i = 0; i < kSize; i++) circular_queue_[i] = NULL;
292 }
293
294 void Add(HeapObject* object) {
295 circular_queue_[index_] = object;
296 index_ = (index_ + 1) & kSizeMask;
297 }
298
299 HeapObject* Get(int index) {
300 DCHECK_NE(NULL, circular_queue_[index]);
301 return circular_queue_[index];
302 }
303
304 static const int kNotFound = -1;
305
306 int Find(HeapObject* object) {
307 for (int i = 0; i < kSize; i++) {
308 if (circular_queue_[i] == object) return i;
309 }
310 return kNotFound;
311 }
312
313 static const int kSize = 8;
314
315 private:
316 STATIC_ASSERT(IS_POWER_OF_TWO(kSize));
317 static const int kSizeMask = kSize - 1;
318 HeapObject* circular_queue_[kSize];
319 int index_;
320
321 DISALLOW_COPY_AND_ASSIGN(HotObjectsList);
322 };
323
324
288 // The Serializer/Deserializer class is a common superclass for Serializer and 325 // The Serializer/Deserializer class is a common superclass for Serializer and
289 // Deserializer which is used to store common constants and methods used by 326 // Deserializer which is used to store common constants and methods used by
290 // both. 327 // both.
291 class SerializerDeserializer: public ObjectVisitor { 328 class SerializerDeserializer: public ObjectVisitor {
292 public: 329 public:
293 static void Iterate(Isolate* isolate, ObjectVisitor* visitor); 330 static void Iterate(Isolate* isolate, ObjectVisitor* visitor);
294 331
295 static int nop() { return kNop; } 332 static int nop() { return kNop; }
296 333
297 // No reservation for large object space necessary. 334 // No reservation for large object space necessary.
298 static const int kNumberOfPreallocatedSpaces = LO_SPACE; 335 static const int kNumberOfPreallocatedSpaces = LO_SPACE;
299 static const int kNumberOfSpaces = LAST_SPACE + 1; 336 static const int kNumberOfSpaces = LAST_SPACE + 1;
300 337
301 protected: 338 protected:
302 // Where the pointed-to object can be found: 339 // Where the pointed-to object can be found:
303 enum Where { 340 enum Where {
304 kNewObject = 0, // Object is next in snapshot. 341 kNewObject = 0, // Object is next in snapshot.
305 // 1-7 One per space. 342 // 1-7 One per space.
343 // 0x8 Unused.
306 kRootArray = 0x9, // Object is found in root array. 344 kRootArray = 0x9, // Object is found in root array.
307 kPartialSnapshotCache = 0xa, // Object is in the cache. 345 kPartialSnapshotCache = 0xa, // Object is in the cache.
308 kExternalReference = 0xb, // Pointer to an external reference. 346 kExternalReference = 0xb, // Pointer to an external reference.
309 kSkip = 0xc, // Skip n bytes. 347 kSkip = 0xc, // Skip n bytes.
310 kBuiltin = 0xd, // Builtin code object. 348 kBuiltin = 0xd, // Builtin code object.
311 kAttachedReference = 0xe, // Object is described in an attached list. 349 kAttachedReference = 0xe, // Object is described in an attached list.
312 // 0xf Used by misc. See below. 350 // 0xf Used by misc. See below.
313 kBackref = 0x10, // Object is described relative to end. 351 kBackref = 0x10, // Object is described relative to end.
314 // 0x11-0x17 One per space. 352 // 0x11-0x17 One per space.
315 kBackrefWithSkip = 0x18, // Object is described relative to end. 353 kBackrefWithSkip = 0x18, // Object is described relative to end.
(...skipping 23 matching lines...) Expand all
339 kInnerPointer = 0x80, // First insn in code object or payload of cell. 377 kInnerPointer = 0x80, // First insn in code object or payload of cell.
340 kWhereToPointMask = 0x80 378 kWhereToPointMask = 0x80
341 }; 379 };
342 380
343 // Misc. 381 // Misc.
344 // Raw data to be copied from the snapshot. This byte code does not advance 382 // Raw data to be copied from the snapshot. This byte code does not advance
345 // the current pointer, which is used for code objects, where we write the 383 // the current pointer, which is used for code objects, where we write the
346 // entire code in one memcpy, then fix up stuff with kSkip and other byte 384 // entire code in one memcpy, then fix up stuff with kSkip and other byte
347 // codes that overwrite data. 385 // codes that overwrite data.
348 static const int kRawData = 0x20; 386 static const int kRawData = 0x20;
349 // Some common raw lengths: 0x21-0x3f. These autoadvance the current pointer. 387 // Some common raw lengths: 0x21-0x3f.
388 // These autoadvance the current pointer.
389 static const int kOnePointerRawData = 0x21;
390
391 static const int kVariableRepeat = 0x60;
392 // 0x61-0x6f Repeat last word
393 static const int kFixedRepeat = 0x61;
394 static const int kFixedRepeatBase = kFixedRepeat - 1;
395 static const int kLastFixedRepeat = 0x6f;
396 static const int kMaxFixedRepeats = kLastFixedRepeat - kFixedRepeatBase;
397 static int CodeForRepeats(int repeats) {
398 DCHECK(repeats >= 1 && repeats <= kMaxFixedRepeats);
399 return kFixedRepeatBase + repeats;
400 }
401 static int RepeatsForCode(int byte_code) {
402 DCHECK(byte_code > kFixedRepeatBase && byte_code <= kLastFixedRepeat);
403 return byte_code - kFixedRepeatBase;
404 }
405
406 // Hot objects are a small set of recently seen or back-referenced objects.
407 // They are represented by a single opcode to save space.
408 // We use 0x70..0x77 for 8 hot objects, and 0x78..0x7f to add skip.
409 static const int kHotObject = 0x70;
410 static const int kMaxHotObjectIndex = 0x77 - kHotObject;
411 static const int kHotObjectWithSkip = 0x78;
412 STATIC_ASSERT(HotObjectsList::kSize == kMaxHotObjectIndex + 1);
413 STATIC_ASSERT(0x7f - kHotObjectWithSkip == kMaxHotObjectIndex);
414 static const int kHotObjectIndexMask = 0x7;
415
416 static const int kRootArrayConstants = 0xa0;
417 // 0xa0-0xbf Things from the first 32 elements of the root array.
418 static const int kRootArrayNumberOfConstantEncodings = 0x20;
419 static int RootArrayConstantFromByteCode(int byte_code) {
420 return byte_code & 0x1f;
421 }
422
423 // Do nothing, used for padding.
424 static const int kNop = 0xf;
425
426 // Move to next reserved chunk.
427 static const int kNextChunk = 0x4f;
428
350 // A tag emitted at strategic points in the snapshot to delineate sections. 429 // A tag emitted at strategic points in the snapshot to delineate sections.
351 // If the deserializer does not find these at the expected moments then it 430 // If the deserializer does not find these at the expected moments then it
352 // is an indication that the snapshot and the VM do not fit together. 431 // is an indication that the snapshot and the VM do not fit together.
353 // Examine the build process for architecture, version or configuration 432 // Examine the build process for architecture, version or configuration
354 // mismatches. 433 // mismatches.
355 static const int kSynchronize = 0x70; 434 static const int kSynchronize = 0x8f;
435
356 // Used for the source code of the natives, which is in the executable, but 436 // Used for the source code of the natives, which is in the executable, but
357 // is referred to from external strings in the snapshot. 437 // is referred to from external strings in the snapshot.
358 static const int kNativesStringResource = 0x71; 438 static const int kNativesStringResource = 0xcf;
359 static const int kRepeat = 0x72;
360 static const int kConstantRepeat = 0x73;
361 // 0x73-0x7f Repeat last word (subtract 0x72 to get the count).
362 static const int kMaxRepeats = 0x7f - 0x72;
363 static int CodeForRepeats(int repeats) {
364 DCHECK(repeats >= 1 && repeats <= kMaxRepeats);
365 return 0x72 + repeats;
366 }
367 static int RepeatsForCode(int byte_code) {
368 DCHECK(byte_code >= kConstantRepeat && byte_code <= 0x7f);
369 return byte_code - 0x72;
370 }
371 static const int kRootArrayConstants = 0xa0;
372 // 0xa0-0xbf Things from the first 32 elements of the root array.
373 static const int kRootArrayNumberOfConstantEncodings = 0x20;
374 static int RootArrayConstantFromByteCode(int byte_code) {
375 return byte_code & 0x1f;
376 }
377
378 static const int kNop = 0xf; // Do nothing, used for padding.
379
380 static const int kNextChunk = 0x4f; // Move to next reserved chunk.
381 439
382 static const int kAnyOldSpace = -1; 440 static const int kAnyOldSpace = -1;
383 441
384 // A bitmask for getting the space out of an instruction. 442 // A bitmask for getting the space out of an instruction.
385 static const int kSpaceMask = 7; 443 static const int kSpaceMask = 7;
386 STATIC_ASSERT(kNumberOfSpaces <= kSpaceMask + 1); 444 STATIC_ASSERT(kNumberOfSpaces <= kSpaceMask + 1);
387 445
388 // Sentinel after a new object to indicate that double alignment is needed. 446 // Sentinel after a new object to indicate that double alignment is needed.
389 static const int kDoubleAlignmentSentinel = 0; 447 static const int kDoubleAlignmentSentinel = 0;
448
449 // Used as index for the attached reference representing the source object.
450 static const int kSourceObjectReference = 0;
451
452 HotObjectsList hot_objects_;
390 }; 453 };
391 454
392 455
393 // A Deserializer reads a snapshot and reconstructs the Object graph it defines. 456 // A Deserializer reads a snapshot and reconstructs the Object graph it defines.
394 class Deserializer: public SerializerDeserializer { 457 class Deserializer: public SerializerDeserializer {
395 public: 458 public:
396 // Create a deserializer from a snapshot byte source. 459 // Create a deserializer from a snapshot byte source.
397 explicit Deserializer(SnapshotByteSource* source); 460 explicit Deserializer(SnapshotByteSource* source);
398 461
399 virtual ~Deserializer(); 462 virtual ~Deserializer();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 // of the object we are writing into, or NULL if we are not writing into an 505 // of the object we are writing into, or NULL if we are not writing into an
443 // object, i.e. if we are writing a series of tagged values that are not on 506 // object, i.e. if we are writing a series of tagged values that are not on
444 // the heap. 507 // the heap.
445 void ReadData(Object** start, Object** end, int space, 508 void ReadData(Object** start, Object** end, int space,
446 Address object_address); 509 Address object_address);
447 void ReadObject(int space_number, Object** write_back); 510 void ReadObject(int space_number, Object** write_back);
448 Address Allocate(int space_index, int size); 511 Address Allocate(int space_index, int size);
449 512
450 // Special handling for serialized code like hooking up internalized strings. 513 // Special handling for serialized code like hooking up internalized strings.
451 HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj); 514 HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj);
452 Object* ProcessBackRefInSerializedCode(Object* obj);
453 515
454 // This returns the address of an object that has been described in the 516 // This returns the address of an object that has been described in the
455 // snapshot by chunk index and offset. 517 // snapshot by chunk index and offset.
456 HeapObject* GetBackReferencedObject(int space) { 518 HeapObject* GetBackReferencedObject(int space);
457 if (space == LO_SPACE) {
458 uint32_t index = source_->GetInt();
459 return deserialized_large_objects_[index];
460 } else {
461 BackReference back_reference(source_->GetInt());
462 DCHECK(space < kNumberOfPreallocatedSpaces);
463 uint32_t chunk_index = back_reference.chunk_index();
464 DCHECK_LE(chunk_index, current_chunk_[space]);
465 uint32_t chunk_offset = back_reference.chunk_offset();
466 return HeapObject::FromAddress(reservations_[space][chunk_index].start +
467 chunk_offset);
468 }
469 }
470 519
471 // Cached current isolate. 520 // Cached current isolate.
472 Isolate* isolate_; 521 Isolate* isolate_;
473 522
474 // Objects from the attached object descriptions in the serialized user code. 523 // Objects from the attached object descriptions in the serialized user code.
475 Vector<Handle<Object> >* attached_objects_; 524 Vector<Handle<Object> >* attached_objects_;
476 525
477 SnapshotByteSource* source_; 526 SnapshotByteSource* source_;
478 // The address of the next object that will be allocated in each space. 527 // The address of the next object that will be allocated in each space.
479 // Each space has a number of chunks reserved by the GC, with each chunk 528 // Each space has a number of chunks reserved by the GC, with each chunk
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 bool code_object_; 618 bool code_object_;
570 bool code_has_been_output_; 619 bool code_has_been_output_;
571 }; 620 };
572 621
573 virtual void SerializeObject(HeapObject* o, HowToCode how_to_code, 622 virtual void SerializeObject(HeapObject* o, HowToCode how_to_code,
574 WhereToPoint where_to_point, int skip) = 0; 623 WhereToPoint where_to_point, int skip) = 0;
575 624
576 void PutRoot(int index, HeapObject* object, HowToCode how, WhereToPoint where, 625 void PutRoot(int index, HeapObject* object, HowToCode how, WhereToPoint where,
577 int skip); 626 int skip);
578 627
579 void SerializeBackReference(BackReference back_reference, 628 // Returns true if the object was successfully serialized.
580 HowToCode how_to_code, 629 bool SerializeKnownObject(HeapObject* obj, HowToCode how_to_code,
581 WhereToPoint where_to_point, int skip); 630 WhereToPoint where_to_point, int skip);
631
632 inline void FlushSkip(int skip) {
633 if (skip != 0) {
634 sink_->Put(kSkip, "SkipFromSerializeObject");
635 sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
636 }
637 }
638
582 void InitializeAllocators(); 639 void InitializeAllocators();
583 // This will return the space for an object. 640 // This will return the space for an object.
584 static AllocationSpace SpaceOfObject(HeapObject* object); 641 static AllocationSpace SpaceOfObject(HeapObject* object);
585 BackReference AllocateLargeObject(int size); 642 BackReference AllocateLargeObject(int size);
586 BackReference Allocate(AllocationSpace space, int size); 643 BackReference Allocate(AllocationSpace space, int size);
587 int EncodeExternalReference(Address addr) { 644 int EncodeExternalReference(Address addr) {
588 return external_reference_encoder_->Encode(addr); 645 return external_reference_encoder_->Encode(addr);
589 } 646 }
590 647
591 // GetInt reads 4 bytes at once, requiring padding at the end. 648 // GetInt reads 4 bytes at once, requiring padding at the end.
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 class CodeSerializer : public Serializer { 766 class CodeSerializer : public Serializer {
710 public: 767 public:
711 static ScriptData* Serialize(Isolate* isolate, 768 static ScriptData* Serialize(Isolate* isolate,
712 Handle<SharedFunctionInfo> info, 769 Handle<SharedFunctionInfo> info,
713 Handle<String> source); 770 Handle<String> source);
714 771
715 MUST_USE_RESULT static MaybeHandle<SharedFunctionInfo> Deserialize( 772 MUST_USE_RESULT static MaybeHandle<SharedFunctionInfo> Deserialize(
716 Isolate* isolate, ScriptData* cached_data, Handle<String> source); 773 Isolate* isolate, ScriptData* cached_data, Handle<String> source);
717 774
718 static const int kSourceObjectIndex = 0; 775 static const int kSourceObjectIndex = 0;
776 STATIC_ASSERT(kSourceObjectReference == kSourceObjectIndex);
777
719 static const int kCodeStubsBaseIndex = 1; 778 static const int kCodeStubsBaseIndex = 1;
720 779
721 String* source() const { 780 String* source() const {
722 DCHECK(!AllowHeapAllocation::IsAllowed()); 781 DCHECK(!AllowHeapAllocation::IsAllowed());
723 return source_; 782 return source_;
724 } 783 }
725 784
726 List<uint32_t>* stub_keys() { return &stub_keys_; } 785 List<uint32_t>* stub_keys() { return &stub_keys_; }
727 int num_internalized_strings() const { return num_internalized_strings_; } 786 int num_internalized_strings() const { return num_internalized_strings_; }
728 787
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 // Following the header, we store, in sequential order 927 // Following the header, we store, in sequential order
869 // - code stub keys 928 // - code stub keys
870 // - serialization payload 929 // - serialization payload
871 930
872 ScriptData* script_data_; 931 ScriptData* script_data_;
873 bool owns_script_data_; 932 bool owns_script_data_;
874 }; 933 };
875 } } // namespace v8::internal 934 } } // namespace v8::internal
876 935
877 #endif // V8_SERIALIZE_H_ 936 #endif // V8_SERIALIZE_H_
OLDNEW
« no previous file with comments | « src/flag-definitions.h ('k') | src/serialize.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698