Line data Source code
1 : // Copyright 2018 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_SNAPSHOT_REFERENCES_H_
6 : #define V8_SNAPSHOT_REFERENCES_H_
7 :
8 : #include "src/assert-scope.h"
9 : #include "src/base/hashmap.h"
10 : #include "src/utils.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 :
15 : class SerializerReference {
16 : private:
17 : enum SpecialValueType {
18 : kInvalidValue,
19 : kAttachedReference,
20 : kOffHeapBackingStore,
21 : kBuiltinReference,
22 : };
23 :
24 : static const int kSpecialValueSpace = LAST_SPACE + 1;
25 : STATIC_ASSERT(kSpecialValueSpace < (1 << kSpaceTagSize));
26 :
27 : SerializerReference(SpecialValueType type, uint32_t value)
28 : : bitfield_(SpaceBits::encode(kSpecialValueSpace) |
29 : SpecialValueTypeBits::encode(type)),
30 : value_(value) {}
31 :
32 : public:
33 : SerializerReference() : SerializerReference(kInvalidValue, 0) {}
34 :
35 : SerializerReference(uint32_t space, uint32_t chunk_index,
36 : uint32_t chunk_offset)
37 1829377 : : bitfield_(SpaceBits::encode(space) |
38 : ChunkIndexBits::encode(chunk_index)),
39 : value_(chunk_offset) {}
40 :
41 : static SerializerReference BackReference(AllocationSpace space,
42 : uint32_t chunk_index,
43 : uint32_t chunk_offset) {
44 : DCHECK(IsAligned(chunk_offset, kObjectAlignment));
45 : DCHECK_LT(space, LO_SPACE);
46 : return SerializerReference(space, chunk_index, chunk_offset);
47 : }
48 :
49 : static SerializerReference MapReference(uint32_t index) {
50 : return SerializerReference(MAP_SPACE, 0, index);
51 : }
52 :
53 : static SerializerReference OffHeapBackingStoreReference(uint32_t index) {
54 : return SerializerReference(kOffHeapBackingStore, index);
55 : }
56 :
57 : static SerializerReference LargeObjectReference(uint32_t index) {
58 : return SerializerReference(LO_SPACE, 0, index);
59 : }
60 :
61 : static SerializerReference AttachedReference(uint32_t index) {
62 : return SerializerReference(kAttachedReference, index);
63 : }
64 :
65 : static SerializerReference BuiltinReference(uint32_t index) {
66 : return SerializerReference(kBuiltinReference, index);
67 : }
68 :
69 : bool is_valid() const {
70 5479519 : return SpaceBits::decode(bitfield_) != kSpecialValueSpace ||
71 : SpecialValueTypeBits::decode(bitfield_) != kInvalidValue;
72 : }
73 :
74 : bool is_back_reference() const {
75 : return SpaceBits::decode(bitfield_) <= LAST_SPACE;
76 : }
77 :
78 : AllocationSpace space() const {
79 : DCHECK(is_back_reference());
80 701523 : return static_cast<AllocationSpace>(SpaceBits::decode(bitfield_));
81 : }
82 :
83 : uint32_t chunk_offset() const {
84 : DCHECK(is_back_reference());
85 : return value_;
86 : }
87 :
88 : uint32_t chunk_index() const {
89 : DCHECK(space() != MAP_SPACE && space() != LO_SPACE);
90 : return ChunkIndexBits::decode(bitfield_);
91 : }
92 :
93 : uint32_t map_index() const {
94 : DCHECK_EQ(MAP_SPACE, SpaceBits::decode(bitfield_));
95 : return value_;
96 : }
97 :
98 : bool is_off_heap_backing_store_reference() const {
99 : return SpaceBits::decode(bitfield_) == kSpecialValueSpace &&
100 : SpecialValueTypeBits::decode(bitfield_) == kOffHeapBackingStore;
101 : }
102 :
103 : uint32_t off_heap_backing_store_index() const {
104 : DCHECK(is_off_heap_backing_store_reference());
105 : return value_;
106 : }
107 :
108 : uint32_t large_object_index() const {
109 : DCHECK_EQ(LO_SPACE, SpaceBits::decode(bitfield_));
110 : return value_;
111 : }
112 :
113 : bool is_attached_reference() const {
114 699801 : return SpaceBits::decode(bitfield_) == kSpecialValueSpace &&
115 : SpecialValueTypeBits::decode(bitfield_) == kAttachedReference;
116 : }
117 :
118 : uint32_t attached_reference_index() const {
119 : DCHECK(is_attached_reference());
120 : return value_;
121 : }
122 :
123 : bool is_builtin_reference() const {
124 : return SpaceBits::decode(bitfield_) == kSpecialValueSpace &&
125 : SpecialValueTypeBits::decode(bitfield_) == kBuiltinReference;
126 : }
127 :
128 : uint32_t builtin_index() const {
129 : DCHECK(is_builtin_reference());
130 : return value_;
131 : }
132 :
133 : private:
134 : class SpaceBits : public BitField<int, 0, kSpaceTagSize> {};
135 : class ChunkIndexBits
136 : : public BitField<uint32_t, SpaceBits::kNext, 32 - kSpaceTagSize> {};
137 : class SpecialValueTypeBits
138 : : public BitField<SpecialValueType, SpaceBits::kNext,
139 : 32 - kSpaceTagSize> {};
140 :
141 : // We use two fields to store a reference.
142 : // In case of a normal back reference, the bitfield_ stores the space and
143 : // the chunk index. In case of special references, it uses a special value
144 : // for space and stores the special value type.
145 : uint32_t bitfield_;
146 : // value_ stores either chunk offset or special value.
147 : uint32_t value_;
148 :
149 : friend class SerializerReferenceMap;
150 : };
151 :
152 : class SerializerReferenceMap
153 : : public base::TemplateHashMapImpl<uintptr_t, SerializerReference,
154 : base::KeyEqualityMatcher<intptr_t>,
155 : base::DefaultAllocationPolicy> {
156 : public:
157 : typedef base::TemplateHashMapEntry<uintptr_t, SerializerReference> Entry;
158 :
159 2244 : SerializerReferenceMap() : attached_reference_index_(0) {}
160 :
161 3092634 : SerializerReference LookupReference(void* value) const {
162 : uintptr_t key = Key(value);
163 3092634 : Entry* entry = Lookup(key, Hash(key));
164 3092634 : if (entry == nullptr) return SerializerReference();
165 702820 : return entry->value;
166 : }
167 :
168 : void Add(void* obj, SerializerReference reference) {
169 : DCHECK(reference.is_valid());
170 : DCHECK(!LookupReference(obj).is_valid());
171 1889803 : uintptr_t key = Key(obj);
172 3779606 : LookupOrInsert(key, Hash(key))->value = reference;
173 : }
174 :
175 610 : SerializerReference AddAttachedReference(void* attached_reference) {
176 : SerializerReference reference =
177 610 : SerializerReference::AttachedReference(attached_reference_index_++);
178 : Add(attached_reference, reference);
179 610 : return reference;
180 : }
181 :
182 : private:
183 : static inline uintptr_t Key(void* value) {
184 3093279 : return reinterpret_cast<uintptr_t>(value);
185 : }
186 :
187 4982437 : static uint32_t Hash(uintptr_t key) { return static_cast<uint32_t>(key); }
188 :
189 : DISALLOW_HEAP_ALLOCATION(no_allocation_)
190 : int attached_reference_index_;
191 : DISALLOW_COPY_AND_ASSIGN(SerializerReferenceMap);
192 : };
193 :
194 : } // namespace internal
195 : } // namespace v8
196 :
197 : #endif // V8_SNAPSHOT_REFERENCES_H_
|