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/base/bit-field.h" 9 #include "src/base/hashmap.h" 10 #include "src/common/assert-scope.h" 11 #include "src/execution/isolate.h" 12 #include "src/utils/identity-map.h" 13 14 namespace v8 { 15 namespace internal { 16 17 enum class SnapshotSpace : byte { 18 kReadOnlyHeap, 19 kOld, 20 kCode, 21 kMap, 22 }; 23 static constexpr int kNumberOfSnapshotSpaces = 24 static_cast<int>(SnapshotSpace::kMap) + 1; 25 26 class SerializerReference { 27 private: 28 enum SpecialValueType { 29 kBackReference, 30 kAttachedReference, 31 kOffHeapBackingStore, 32 kBuiltinReference, 33 }; 34 SerializerReference(SpecialValueType type,uint32_t value)35 SerializerReference(SpecialValueType type, uint32_t value) 36 : bit_field_(TypeBits::encode(type) | ValueBits::encode(value)) {} 37 38 public: BackReference(uint32_t index)39 static SerializerReference BackReference(uint32_t index) { 40 return SerializerReference(kBackReference, index); 41 } 42 OffHeapBackingStoreReference(uint32_t index)43 static SerializerReference OffHeapBackingStoreReference(uint32_t index) { 44 return SerializerReference(kOffHeapBackingStore, index); 45 } 46 AttachedReference(uint32_t index)47 static SerializerReference AttachedReference(uint32_t index) { 48 return SerializerReference(kAttachedReference, index); 49 } 50 BuiltinReference(uint32_t index)51 static SerializerReference BuiltinReference(uint32_t index) { 52 return SerializerReference(kBuiltinReference, index); 53 } 54 is_back_reference()55 bool is_back_reference() const { 56 return TypeBits::decode(bit_field_) == kBackReference; 57 } 58 back_ref_index()59 uint32_t back_ref_index() const { 60 DCHECK(is_back_reference()); 61 return ValueBits::decode(bit_field_); 62 } 63 is_off_heap_backing_store_reference()64 bool is_off_heap_backing_store_reference() const { 65 return TypeBits::decode(bit_field_) == kOffHeapBackingStore; 66 } 67 off_heap_backing_store_index()68 uint32_t off_heap_backing_store_index() const { 69 DCHECK(is_off_heap_backing_store_reference()); 70 return ValueBits::decode(bit_field_); 71 } 72 is_attached_reference()73 bool is_attached_reference() const { 74 return TypeBits::decode(bit_field_) == kAttachedReference; 75 } 76 attached_reference_index()77 uint32_t attached_reference_index() const { 78 DCHECK(is_attached_reference()); 79 return ValueBits::decode(bit_field_); 80 } 81 is_builtin_reference()82 bool is_builtin_reference() const { 83 return TypeBits::decode(bit_field_) == kBuiltinReference; 84 } 85 builtin_index()86 uint32_t builtin_index() const { 87 DCHECK(is_builtin_reference()); 88 return ValueBits::decode(bit_field_); 89 } 90 91 private: 92 using TypeBits = base::BitField<SpecialValueType, 0, 2>; 93 using ValueBits = TypeBits::Next<uint32_t, 32 - TypeBits::kSize>; 94 95 uint32_t bit_field_; 96 97 friend class SerializerReferenceMap; 98 }; 99 100 // SerializerReference has to fit in an IdentityMap value field. 101 STATIC_ASSERT(sizeof(SerializerReference) <= sizeof(void*)); 102 103 class SerializerReferenceMap { 104 public: SerializerReferenceMap(Isolate * isolate)105 explicit SerializerReferenceMap(Isolate* isolate) 106 : map_(isolate->heap()), attached_reference_index_(0) {} 107 LookupReference(HeapObject object)108 const SerializerReference* LookupReference(HeapObject object) const { 109 return map_.Find(object); 110 } 111 LookupReference(Handle<HeapObject> object)112 const SerializerReference* LookupReference(Handle<HeapObject> object) const { 113 return map_.Find(object); 114 } 115 LookupBackingStore(void * backing_store)116 const SerializerReference* LookupBackingStore(void* backing_store) const { 117 auto it = backing_store_map_.find(backing_store); 118 if (it == backing_store_map_.end()) return nullptr; 119 return &it->second; 120 } 121 Add(HeapObject object,SerializerReference reference)122 void Add(HeapObject object, SerializerReference reference) { 123 DCHECK_NULL(LookupReference(object)); 124 map_.Insert(object, reference); 125 } 126 AddBackingStore(void * backing_store,SerializerReference reference)127 void AddBackingStore(void* backing_store, SerializerReference reference) { 128 DCHECK(backing_store_map_.find(backing_store) == backing_store_map_.end()); 129 backing_store_map_.emplace(backing_store, reference); 130 } 131 AddAttachedReference(HeapObject object)132 SerializerReference AddAttachedReference(HeapObject object) { 133 SerializerReference reference = 134 SerializerReference::AttachedReference(attached_reference_index_++); 135 map_.Insert(object, reference); 136 return reference; 137 } 138 139 private: 140 IdentityMap<SerializerReference, base::DefaultAllocationPolicy> map_; 141 std::unordered_map<void*, SerializerReference> backing_store_map_; 142 int attached_reference_index_; 143 }; 144 145 } // namespace internal 146 } // namespace v8 147 148 #endif // V8_SNAPSHOT_REFERENCES_H_ 149