Chromium Code Reviews| Index: src/address-map.h |
| diff --git a/src/address-map.h b/src/address-map.h |
| index df32f89c1ea33cd78bf6c386245b013ac2c1832c..866553c497acc25e9c7bd8d0e4c686f72f687458 100644 |
| --- a/src/address-map.h |
| +++ b/src/address-map.h |
| @@ -40,7 +40,6 @@ class AddressMapBase { |
| } |
| }; |
| - |
| class RootIndexMap : public AddressMapBase { |
| public: |
| explicit RootIndexMap(Isolate* isolate); |
| @@ -59,123 +58,151 @@ class RootIndexMap : public AddressMapBase { |
| DISALLOW_COPY_AND_ASSIGN(RootIndexMap); |
| }; |
| - |
| -class BackReference { |
| +class SerializerReference { |
| public: |
| - explicit BackReference(uint32_t bitfield) : bitfield_(bitfield) {} |
| + explicit SerializerReference(uint32_t bitfield) : bitfield_(bitfield) {} |
|
vogelheim
2016/05/18 11:18:47
Why is this a public constructor?
(It assumes the
Yang
2016/05/18 11:58:42
The deserializer reconstructs references from seri
|
| + SerializerReference() : bitfield_(Special(kInvalidValue)) {} |
| - BackReference() : bitfield_(kInvalidValue) {} |
| + static SerializerReference BackReference(AllocationSpace space, |
| + uint32_t chunk_index, |
| + uint32_t chunk_offset) { |
| + DCHECK(IsAligned(chunk_offset, kObjectAlignment)); |
| + DCHECK_NE(LO_SPACE, space); |
| + return SerializerReference( |
| + SpaceBits::encode(space) | ChunkIndexBits::encode(chunk_index) | |
| + ChunkOffsetBits::encode(chunk_offset >> kObjectAlignmentBits)); |
| + } |
| - static BackReference SourceReference() { return BackReference(kSourceValue); } |
| + static SerializerReference LargeObjectReference(uint32_t index) { |
| + return SerializerReference(SpaceBits::encode(LO_SPACE) | |
| + ValueIndexBits::encode(index)); |
| + } |
| - static BackReference GlobalProxyReference() { |
| - return BackReference(kGlobalProxyValue); |
| + static SerializerReference AttachedReference(uint32_t index) { |
| + return SerializerReference(SpaceBits::encode(kAttachedReferenceSpace) | |
| + ValueIndexBits::encode(index)); |
| } |
| - static BackReference LargeObjectReference(uint32_t index) { |
| - return BackReference(SpaceBits::encode(LO_SPACE) | |
| - ChunkOffsetBits::encode(index)); |
| + static SerializerReference DummyReference() { |
| + return SerializerReference(Special(kDummyValue)); |
| } |
| - static BackReference DummyReference() { return BackReference(kDummyValue); } |
| + bool is_valid() const { return bitfield_ != Special(kInvalidValue); } |
| - static BackReference Reference(AllocationSpace space, uint32_t chunk_index, |
| - uint32_t chunk_offset) { |
| - DCHECK(IsAligned(chunk_offset, kObjectAlignment)); |
| - DCHECK_NE(LO_SPACE, space); |
| - return BackReference( |
| - SpaceBits::encode(space) | ChunkIndexBits::encode(chunk_index) | |
| - ChunkOffsetBits::encode(chunk_offset >> kObjectAlignmentBits)); |
| + bool is_back_reference() const { |
| + return SpaceBits::decode(bitfield_) <= LAST_SPACE; |
| } |
| - bool is_valid() const { return bitfield_ != kInvalidValue; } |
| - bool is_source() const { return bitfield_ == kSourceValue; } |
| - bool is_global_proxy() const { return bitfield_ == kGlobalProxyValue; } |
| - |
| AllocationSpace space() const { |
| - DCHECK(is_valid()); |
| - return SpaceBits::decode(bitfield_); |
| + DCHECK(is_back_reference()); |
| + return static_cast<AllocationSpace>(SpaceBits::decode(bitfield_)); |
| } |
| uint32_t chunk_offset() const { |
| - DCHECK(is_valid()); |
| + DCHECK(is_back_reference()); |
| return ChunkOffsetBits::decode(bitfield_) << kObjectAlignmentBits; |
| } |
| uint32_t large_object_index() const { |
| - DCHECK(is_valid()); |
| + DCHECK(is_back_reference()); |
| DCHECK(chunk_index() == 0); |
| return ChunkOffsetBits::decode(bitfield_); |
| } |
| uint32_t chunk_index() const { |
| - DCHECK(is_valid()); |
| + DCHECK(is_back_reference()); |
| return ChunkIndexBits::decode(bitfield_); |
| } |
| - uint32_t reference() const { |
| - DCHECK(is_valid()); |
| + uint32_t back_reference() const { |
| + DCHECK(is_back_reference()); |
| return bitfield_ & (ChunkOffsetBits::kMask | ChunkIndexBits::kMask); |
| } |
| - uint32_t bitfield() const { return bitfield_; } |
| + bool is_attached_reference() const { |
| + return SpaceBits::decode(bitfield_) == kAttachedReferenceSpace; |
| + } |
| + |
| + int attached_reference_index() const { |
| + DCHECK(is_attached_reference()); |
| + return ValueIndexBits::decode(bitfield_); |
| + } |
| private: |
| - static const uint32_t kInvalidValue = 0xFFFFFFFF; |
| - static const uint32_t kSourceValue = 0xFFFFFFFE; |
| - static const uint32_t kGlobalProxyValue = 0xFFFFFFFD; |
| - static const uint32_t kDummyValue = 0xFFFFFFFC; |
| + inline static uint32_t Special(int value) { |
| + return SpaceBits::encode(kSpecialValueSpace) | |
| + ValueIndexBits::encode(value); |
| + } |
| + |
| + // We use the 32-bit bitfield to encode either a back reference, a special |
| + // value, or a attached reference index. |
|
vogelheim
2016/05/18 11:18:47
super nitpick: "a attached" -> "an attached"
Yang
2016/05/18 11:58:42
Done.
|
| + // Back reference: |
| + // [ Space index ] [ Chunk index ] [ Chunk offset ] |
| + // [ LO_SPACE ] [ large object index ] |
| + // Special value |
| + // [ kSpecialValueSpace ] [ Special value index ] |
| + // Attached reference |
| + // [ kAttachedReferenceSpace ] [ Attached reference index ] |
| + |
| static const int kChunkOffsetSize = kPageSizeBits - kObjectAlignmentBits; |
| static const int kChunkIndexSize = 32 - kChunkOffsetSize - kSpaceTagSize; |
| + static const int kValueIndexSize = kChunkOffsetSize + kChunkIndexSize; |
| - public: |
| - static const int kMaxChunkIndex = (1 << kChunkIndexSize) - 1; |
| + static const int kSpecialValueSpace = LAST_SPACE + 1; |
| + static const int kAttachedReferenceSpace = kSpecialValueSpace + 1; |
| + STATIC_ASSERT(kAttachedReferenceSpace < (1 << kSpaceTagSize)); |
| - private: |
| + static const int kInvalidValue = 0; |
| + static const int kDummyValue = 1; |
| + |
| + // The chunk offset can also be used to encode the index of special values. |
| class ChunkOffsetBits : public BitField<uint32_t, 0, kChunkOffsetSize> {}; |
| class ChunkIndexBits |
| : public BitField<uint32_t, ChunkOffsetBits::kNext, kChunkIndexSize> {}; |
| - class SpaceBits |
| - : public BitField<AllocationSpace, ChunkIndexBits::kNext, kSpaceTagSize> { |
| - }; |
| + class ValueIndexBits : public BitField<uint32_t, 0, kValueIndexSize> {}; |
| + class SpaceBits : public BitField<int, kValueIndexSize, kSpaceTagSize> {}; |
| + STATIC_ASSERT(SpaceBits::kNext == 32); |
|
vogelheim
2016/05/18 11:18:47
Maybe assert for ValueIndexBits::kNext == ChunkInd
Yang
2016/05/18 11:58:42
Done.
|
| uint32_t bitfield_; |
| -}; |
| + friend class SerializerReferenceMap; |
| +}; |
| // Mapping objects to their location after deserialization. |
| // This is used during building, but not at runtime by V8. |
| -class BackReferenceMap : public AddressMapBase { |
| +class SerializerReferenceMap : public AddressMapBase { |
| public: |
| - BackReferenceMap() |
| - : no_allocation_(), map_(new HashMap(HashMap::PointersMatch)) {} |
| + SerializerReferenceMap() |
| + : no_allocation_(), |
| + map_(new HashMap(HashMap::PointersMatch)), |
| + attached_reference_index_(0) {} |
| - ~BackReferenceMap() { delete map_; } |
| + ~SerializerReferenceMap() { delete map_; } |
| - BackReference Lookup(HeapObject* obj) { |
| + SerializerReference Lookup(HeapObject* obj) { |
| HashMap::Entry* entry = LookupEntry(map_, obj, false); |
| - return entry ? BackReference(GetValue(entry)) : BackReference(); |
| + return entry ? SerializerReference(GetValue(entry)) : SerializerReference(); |
| } |
| - void Add(HeapObject* obj, BackReference b) { |
| + void Add(HeapObject* obj, SerializerReference b) { |
| DCHECK(b.is_valid()); |
| DCHECK_NULL(LookupEntry(map_, obj, false)); |
| HashMap::Entry* entry = LookupEntry(map_, obj, true); |
| - SetValue(entry, b.bitfield()); |
| - } |
| - |
| - void AddSourceString(String* string) { |
| - Add(string, BackReference::SourceReference()); |
| + SetValue(entry, b.bitfield_); |
| } |
| - void AddGlobalProxy(HeapObject* global_proxy) { |
| - Add(global_proxy, BackReference::GlobalProxyReference()); |
| + SerializerReference AddAttachedReference(HeapObject* attached_reference) { |
| + SerializerReference reference = |
| + SerializerReference::AttachedReference(attached_reference_index_++); |
| + Add(attached_reference, reference); |
| + return reference; |
| } |
| private: |
| DisallowHeapAllocation no_allocation_; |
| HashMap* map_; |
|
vogelheim
2016/05/18 11:18:47
Why not a regular (non-pointer) member?
(From wha
Yang
2016/05/18 11:58:42
Good point. Done.
|
| - DISALLOW_COPY_AND_ASSIGN(BackReferenceMap); |
| + int attached_reference_index_; |
| + DISALLOW_COPY_AND_ASSIGN(SerializerReferenceMap); |
| }; |
| } // namespace internal |