| Index: src/serialize.h
|
| diff --git a/src/serialize.h b/src/serialize.h
|
| index 3bb0e1a7a774d4a27bce03ece3797c61e4dd001b..43a01e45ac1726e8b50f69d4f9597927759a17ae 100644
|
| --- a/src/serialize.h
|
| +++ b/src/serialize.h
|
| @@ -285,6 +285,43 @@ class BackReferenceMap : public AddressMapBase {
|
| };
|
|
|
|
|
| +class HotObjectsList {
|
| + public:
|
| + HotObjectsList() : index_(0) {
|
| + for (int i = 0; i < kSize; i++) circular_queue_[i] = NULL;
|
| + }
|
| +
|
| + void Add(HeapObject* object) {
|
| + circular_queue_[index_] = object;
|
| + index_ = (index_ + 1) & kSizeMask;
|
| + }
|
| +
|
| + HeapObject* Get(int index) {
|
| + DCHECK_NE(NULL, circular_queue_[index]);
|
| + return circular_queue_[index];
|
| + }
|
| +
|
| + static const int kNotFound = -1;
|
| +
|
| + int Find(HeapObject* object) {
|
| + for (int i = 0; i < kSize; i++) {
|
| + if (circular_queue_[i] == object) return i;
|
| + }
|
| + return kNotFound;
|
| + }
|
| +
|
| + static const int kSize = 8;
|
| +
|
| + private:
|
| + STATIC_ASSERT(IS_POWER_OF_TWO(kSize));
|
| + static const int kSizeMask = kSize - 1;
|
| + HeapObject* circular_queue_[kSize];
|
| + int index_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(HotObjectsList);
|
| +};
|
| +
|
| +
|
| // The Serializer/Deserializer class is a common superclass for Serializer and
|
| // Deserializer which is used to store common constants and methods used by
|
| // both.
|
| @@ -303,6 +340,7 @@ class SerializerDeserializer: public ObjectVisitor {
|
| enum Where {
|
| kNewObject = 0, // Object is next in snapshot.
|
| // 1-7 One per space.
|
| + // 0x8 Unused.
|
| kRootArray = 0x9, // Object is found in root array.
|
| kPartialSnapshotCache = 0xa, // Object is in the cache.
|
| kExternalReference = 0xb, // Pointer to an external reference.
|
| @@ -346,38 +384,58 @@ class SerializerDeserializer: public ObjectVisitor {
|
| // entire code in one memcpy, then fix up stuff with kSkip and other byte
|
| // codes that overwrite data.
|
| static const int kRawData = 0x20;
|
| - // Some common raw lengths: 0x21-0x3f. These autoadvance the current pointer.
|
| - // A tag emitted at strategic points in the snapshot to delineate sections.
|
| - // If the deserializer does not find these at the expected moments then it
|
| - // is an indication that the snapshot and the VM do not fit together.
|
| - // Examine the build process for architecture, version or configuration
|
| - // mismatches.
|
| - static const int kSynchronize = 0x70;
|
| - // Used for the source code of the natives, which is in the executable, but
|
| - // is referred to from external strings in the snapshot.
|
| - static const int kNativesStringResource = 0x71;
|
| - static const int kRepeat = 0x72;
|
| - static const int kConstantRepeat = 0x73;
|
| - // 0x73-0x7f Repeat last word (subtract 0x72 to get the count).
|
| - static const int kMaxRepeats = 0x7f - 0x72;
|
| + // Some common raw lengths: 0x21-0x3f.
|
| + // These autoadvance the current pointer.
|
| + static const int kOnePointerRawData = 0x21;
|
| +
|
| + static const int kVariableRepeat = 0x60;
|
| + // 0x61-0x6f Repeat last word
|
| + static const int kFixedRepeat = 0x61;
|
| + static const int kFixedRepeatBase = kFixedRepeat - 1;
|
| + static const int kLastFixedRepeat = 0x6f;
|
| + static const int kMaxFixedRepeats = kLastFixedRepeat - kFixedRepeatBase;
|
| static int CodeForRepeats(int repeats) {
|
| - DCHECK(repeats >= 1 && repeats <= kMaxRepeats);
|
| - return 0x72 + repeats;
|
| + DCHECK(repeats >= 1 && repeats <= kMaxFixedRepeats);
|
| + return kFixedRepeatBase + repeats;
|
| }
|
| static int RepeatsForCode(int byte_code) {
|
| - DCHECK(byte_code >= kConstantRepeat && byte_code <= 0x7f);
|
| - return byte_code - 0x72;
|
| + DCHECK(byte_code > kFixedRepeatBase && byte_code <= kLastFixedRepeat);
|
| + return byte_code - kFixedRepeatBase;
|
| }
|
| +
|
| + // Hot objects are a small set of recently seen or back-referenced objects.
|
| + // They are represented by a single opcode to save space.
|
| + // We use 0x70..0x77 for 8 hot objects, and 0x78..0x7f to add skip.
|
| + static const int kHotObject = 0x70;
|
| + static const int kMaxHotObjectIndex = 0x77 - kHotObject;
|
| + static const int kHotObjectWithSkip = 0x78;
|
| + STATIC_ASSERT(HotObjectsList::kSize == kMaxHotObjectIndex + 1);
|
| + STATIC_ASSERT(0x7f - kHotObjectWithSkip == kMaxHotObjectIndex);
|
| + static const int kHotObjectIndexMask = 0x7;
|
| +
|
| static const int kRootArrayConstants = 0xa0;
|
| - // 0xa0-0xbf Things from the first 32 elements of the root array.
|
| + // 0xa0-0xbf Things from the first 32 elements of the root array.
|
| static const int kRootArrayNumberOfConstantEncodings = 0x20;
|
| static int RootArrayConstantFromByteCode(int byte_code) {
|
| return byte_code & 0x1f;
|
| }
|
|
|
| - static const int kNop = 0xf; // Do nothing, used for padding.
|
| + // Do nothing, used for padding.
|
| + static const int kNop = 0xf;
|
| +
|
| + // Move to next reserved chunk.
|
| + static const int kNextChunk = 0x4f;
|
| +
|
| + // A tag emitted at strategic points in the snapshot to delineate sections.
|
| + // If the deserializer does not find these at the expected moments then it
|
| + // is an indication that the snapshot and the VM do not fit together.
|
| + // Examine the build process for architecture, version or configuration
|
| + // mismatches.
|
| + static const int kSynchronize = 0x8f;
|
|
|
| - static const int kNextChunk = 0x4f; // Move to next reserved chunk.
|
| + // Used for the source code of the natives, which is in the executable, but
|
| + // is referred to from external strings in the snapshot.
|
| + static const int kNativesStringResource = 0xcf;
|
|
|
| static const int kAnyOldSpace = -1;
|
|
|
| @@ -387,6 +445,11 @@ class SerializerDeserializer: public ObjectVisitor {
|
|
|
| // Sentinel after a new object to indicate that double alignment is needed.
|
| static const int kDoubleAlignmentSentinel = 0;
|
| +
|
| + // Used as index for the attached reference representing the source object.
|
| + static const int kSourceObjectReference = 0;
|
| +
|
| + HotObjectsList hot_objects_;
|
| };
|
|
|
|
|
| @@ -449,24 +512,10 @@ class Deserializer: public SerializerDeserializer {
|
|
|
| // Special handling for serialized code like hooking up internalized strings.
|
| HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj);
|
| - Object* ProcessBackRefInSerializedCode(Object* obj);
|
|
|
| // This returns the address of an object that has been described in the
|
| // snapshot by chunk index and offset.
|
| - HeapObject* GetBackReferencedObject(int space) {
|
| - if (space == LO_SPACE) {
|
| - uint32_t index = source_->GetInt();
|
| - return deserialized_large_objects_[index];
|
| - } else {
|
| - BackReference back_reference(source_->GetInt());
|
| - DCHECK(space < kNumberOfPreallocatedSpaces);
|
| - uint32_t chunk_index = back_reference.chunk_index();
|
| - DCHECK_LE(chunk_index, current_chunk_[space]);
|
| - uint32_t chunk_offset = back_reference.chunk_offset();
|
| - return HeapObject::FromAddress(reservations_[space][chunk_index].start +
|
| - chunk_offset);
|
| - }
|
| - }
|
| + HeapObject* GetBackReferencedObject(int space);
|
|
|
| // Cached current isolate.
|
| Isolate* isolate_;
|
| @@ -576,9 +625,17 @@ class Serializer : public SerializerDeserializer {
|
| void PutRoot(int index, HeapObject* object, HowToCode how, WhereToPoint where,
|
| int skip);
|
|
|
| - void SerializeBackReference(BackReference back_reference,
|
| - HowToCode how_to_code,
|
| - WhereToPoint where_to_point, int skip);
|
| + // Returns true if the object was successfully serialized.
|
| + bool SerializeKnownObject(HeapObject* obj, HowToCode how_to_code,
|
| + WhereToPoint where_to_point, int skip);
|
| +
|
| + inline void FlushSkip(int skip) {
|
| + if (skip != 0) {
|
| + sink_->Put(kSkip, "SkipFromSerializeObject");
|
| + sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
|
| + }
|
| + }
|
| +
|
| void InitializeAllocators();
|
| // This will return the space for an object.
|
| static AllocationSpace SpaceOfObject(HeapObject* object);
|
| @@ -716,6 +773,8 @@ class CodeSerializer : public Serializer {
|
| Isolate* isolate, ScriptData* cached_data, Handle<String> source);
|
|
|
| static const int kSourceObjectIndex = 0;
|
| + STATIC_ASSERT(kSourceObjectReference == kSourceObjectIndex);
|
| +
|
| static const int kCodeStubsBaseIndex = 1;
|
|
|
| String* source() const {
|
|
|