v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
read-only-spaces.h
Go to the documentation of this file.
1// Copyright 2020 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_HEAP_READ_ONLY_SPACES_H_
6#define V8_HEAP_READ_ONLY_SPACES_H_
7
8#include <memory>
9#include <optional>
10#include <utility>
11
12#include "include/v8-platform.h"
13#include "src/base/macros.h"
14#include "src/common/globals.h"
17#include "src/heap/base-space.h"
20
21namespace v8 {
22namespace internal {
23
24class MemoryAllocator;
25class ReadOnlyHeap;
26class SnapshotByteSource;
27
29 public:
30 ReadOnlyPageMetadata(Heap* heap, BaseSpace* space, size_t chunk_size,
32 VirtualMemory reservation);
34
35 // Clears any pointers in the header that point out of the page that would
36 // otherwise make the header non-relocatable.
38
39 size_t ShrinkToHighWaterMark();
40
41 // Returns the address for a given offset in this page.
43 Address address_in_page = ChunkAddress() + offset;
45 // Pointer compression with multiple pointer cages and shared
46 // ReadOnlyPages means that the area_start and area_end cannot be defined
47 // since they are stored within the pages which can be mapped at multiple
48 // memory addresses.
50 } else {
51 DCHECK_GE(address_in_page, area_start());
52 DCHECK_LT(address_in_page, area_end());
53 }
54 return address_in_page;
55 }
56
57 // Returns the start area of the page without using area_start() which cannot
58 // return the correct result when the page is remapped multiple times.
63
64 private:
65 friend class ReadOnlySpace;
66};
67
68// -----------------------------------------------------------------------------
69// Artifacts used to construct a new SharedReadOnlySpace
70class ReadOnlyArtifacts final {
71 public:
72 ReadOnlyArtifacts() = default;
73
75
76 // Initialize the ReadOnlyArtifacts from an Isolate that has just been created
77 // either by serialization or by creating the objects directly.
78 void Initialize(Isolate* isolate, std::vector<ReadOnlyPageMetadata*>&& pages,
79 const AllocationStats& stats);
80
81 // This replaces the ReadOnlySpace in the given Heap with a newly constructed
82 // SharedReadOnlySpace that has pages created from the ReadOnlyArtifacts. This
83 // is only called for the first Isolate, where the ReadOnlySpace is created
84 // during the bootstrap process.
85 void ReinstallReadOnlySpace(Isolate* isolate);
86
88
89 std::vector<ReadOnlyPageMetadata*>& pages() { return pages_; }
90
91 const AllocationStats& accounting_stats() const { return stats_; }
92
96
97 void set_read_only_heap(std::unique_ptr<ReadOnlyHeap> read_only_heap);
98 ReadOnlyHeap* read_only_heap() const { return read_only_heap_.get(); }
99
103 uint32_t initial_next_unique_sfi_id() const {
105 }
106
116 std::vector<ExternalPointerRegistryEntry>&& registry) {
118 external_pointer_registry_ = std::move(registry);
119 }
120 const std::vector<ExternalPointerRegistryEntry>& external_pointer_registry()
121 const {
123 }
124
125 void InitializeChecksum(SnapshotData* read_only_snapshot_data);
126 void VerifyChecksum(SnapshotData* read_only_snapshot_data,
127 bool read_only_heap_created);
128
129 private:
130 friend class ReadOnlyHeap;
131
132 std::vector<ReadOnlyPageMetadata*> pages_;
134 std::unique_ptr<SharedReadOnlySpace> shared_read_only_space_;
135 std::unique_ptr<ReadOnlyHeap> read_only_heap_;
137 std::vector<ExternalPointerRegistryEntry> external_pointer_registry_;
138#ifdef DEBUG
139 // The checksum of the blob the read-only heap was deserialized from, if
140 // any.
141 std::optional<uint32_t> read_only_blob_checksum_;
142#endif // DEBUG
144};
145
146// -----------------------------------------------------------------------------
147// Read Only space for all Immortal Immovable and Immutable objects
148class ReadOnlySpace : public BaseSpace {
149 public:
151
152 // Detach the pages and add them to artifacts for using in creating a
153 // SharedReadOnlySpace. Since the current space no longer has any pages, it
154 // should be replaced straight after this in its Heap.
156
158 V8_EXPORT_PRIVATE virtual void TearDown(MemoryAllocator* memory_allocator);
159
160 bool IsDetached() const { return heap_ == nullptr; }
161
162 bool writable() const { return !is_marked_read_only_; }
163
164 bool Contains(Address a) = delete;
165 bool Contains(Tagged<Object> o) = delete;
166
168 AllocationResult AllocateRaw(int size_in_bytes,
169 AllocationAlignment alignment);
170
172
178
179 // Seal the space by marking it read-only, optionally detaching it
180 // from the heap and forgetting it for memory bookkeeping purposes (e.g.
181 // prevent space's memory from registering as leaked).
182 V8_EXPORT_PRIVATE void Seal(SealMode ro_mode);
183
184 // During boot the free_space_map is created, and afterwards we may need
185 // to write it into the free space nodes that were already created.
187
188 size_t Size() const override { return accounting_stats_.Size(); }
189 V8_EXPORT_PRIVATE size_t CommittedPhysicalMemory() const override;
190
191 const std::vector<ReadOnlyPageMetadata*>& pages() const { return pages_; }
192 Address top() const { return top_; }
193 Address limit() const { return limit_; }
194 size_t Capacity() const { return capacity_; }
195
196 // Returns the index within pages_. The chunk must be part of this space.
197 size_t IndexOf(const MemoryChunkMetadata* chunk) const;
198
199 bool ContainsSlow(Address addr) const;
201
202#ifdef VERIFY_HEAP
203 void Verify(Isolate* isolate, SpaceVerificationVisitor* visitor) const final;
204#ifdef DEBUG
205 void VerifyCounters(Heap* heap) const;
206#endif // DEBUG
207#endif // VERIFY_HEAP
208
209 Address FirstPageAddress() const { return pages_.front()->ChunkAddress(); }
210
211 // Ensure the read only space has at least one allocated page
212 void EnsurePage();
213
214 protected:
215 void SetPermissionsForPages(MemoryAllocator* memory_allocator,
217
219
220 // Accounting information for this space.
222
223 std::vector<ReadOnlyPageMetadata*> pages_;
224
227
228 private:
229 AllocationResult AllocateRawUnaligned(int size_in_bytes);
230 AllocationResult AllocateRawAligned(int size_in_bytes,
231 AllocationAlignment alignment);
233 AllocationAlignment alignment);
234
235 // Return the index within pages_ of the newly allocated page.
236 size_t AllocateNextPage();
239 size_t area_size_in_bytes);
241
242 void EnsureSpaceForAllocation(int size_in_bytes);
244
245 size_t capacity_ = 0;
246
247 friend class Heap;
249};
250
252 public:
254
256
257 void TearDown(MemoryAllocator* memory_allocator) override;
258
259 private:
263};
264
265} // namespace internal
266
267namespace base {
268// Define special hash function for page pointers, to be used with std data
269// structures, e.g. std::unordered_set<ReadOnlyPageMetadata*,
270// base::hash<ReadOnlyPageMetadata*>
271template <>
272struct hash<i::ReadOnlyPageMetadata*> : hash<i::MemoryChunkMetadata*> {};
273template <>
274struct hash<const i::ReadOnlyPageMetadata*>
275 : hash<const i::MemoryChunkMetadata*> {};
276} // namespace base
277
278} // namespace v8
279
280#endif // V8_HEAP_READ_ONLY_SPACES_H_
SourcePosition pos
static constexpr size_t ObjectStartOffsetInMemoryChunk(AllocationSpace space)
ReadOnlyHeap * read_only_heap() const
uint32_t initial_next_unique_sfi_id() const
std::unique_ptr< ReadOnlyHeap > read_only_heap_
std::vector< ReadOnlyPageMetadata * > pages_
void ReinstallReadOnlySpace(Isolate *isolate)
void InitializeChecksum(SnapshotData *read_only_snapshot_data)
void VerifyChecksum(SnapshotData *read_only_snapshot_data, bool read_only_heap_created)
void set_initial_next_unique_sfi_id(uint32_t id)
void set_read_only_heap(std::unique_ptr< ReadOnlyHeap > read_only_heap)
std::vector< ExternalPointerRegistryEntry > external_pointer_registry_
std::vector< ReadOnlyPageMetadata * > & pages()
const AllocationStats & accounting_stats() const
void Initialize(Isolate *isolate, std::vector< ReadOnlyPageMetadata * > &&pages, const AllocationStats &stats)
void VerifyHeapAndSpaceRelationships(Isolate *isolate)
SharedReadOnlySpace * shared_read_only_space()
std::unique_ptr< SharedReadOnlySpace > shared_read_only_space_
void set_external_pointer_registry(std::vector< ExternalPointerRegistryEntry > &&registry)
const std::vector< ExternalPointerRegistryEntry > & external_pointer_registry() const
MemoryChunk::MainThreadFlags InitialFlags() const
Address OffsetToAddress(size_t offset) const
ReadOnlyPageMetadata(Heap *heap, BaseSpace *space, size_t chunk_size, Address area_start, Address area_end, VirtualMemory reservation)
Tagged< HeapObject > TryAllocateLinearlyAligned(int size_in_bytes, AllocationAlignment alignment)
V8_EXPORT_PRIVATE ~ReadOnlySpace() override
V8_EXPORT_PRIVATE void Seal(SealMode ro_mode)
AllocationResult AllocateRawAligned(int size_in_bytes, AllocationAlignment alignment)
virtual V8_EXPORT_PRIVATE void TearDown(MemoryAllocator *memory_allocator)
std::vector< ReadOnlyPageMetadata * > pages_
V8_EXPORT_PRIVATE void ShrinkPages()
size_t Size() const override
V8_EXPORT_PRIVATE size_t CommittedPhysicalMemory() const override
bool Contains(Address a)=delete
V8_EXPORT_PRIVATE void ClearStringPaddingIfNeeded()
bool ContainsSlow(Address addr) const
bool Contains(Tagged< Object > o)=delete
V8_EXPORT_PRIVATE AllocationResult AllocateRaw(int size_in_bytes, AllocationAlignment alignment)
size_t IndexOf(const MemoryChunkMetadata *chunk) const
V8_EXPORT_PRIVATE ReadOnlySpace(Heap *heap)
void DetachPagesAndAddToArtifacts(ReadOnlyArtifacts *artifacts)
AllocationResult AllocateRawUnaligned(int size_in_bytes)
void EnsureSpaceForAllocation(int size_in_bytes)
size_t AllocateNextPageAt(Address pos)
void InitializePageForDeserialization(ReadOnlyPageMetadata *page, size_t area_size_in_bytes)
const std::vector< ReadOnlyPageMetadata * > & pages() const
void SetPermissionsForPages(MemoryAllocator *memory_allocator, PageAllocator::Permission access)
SharedReadOnlySpace(Heap *heap, ReadOnlyArtifacts *artifacts)
SharedReadOnlySpace(const SharedReadOnlySpace &)=delete
void TearDown(MemoryAllocator *memory_allocator) override
#define COMPRESS_POINTERS_IN_MULTIPLE_CAGES_BOOL
Definition globals.h:117
int32_t offset
uint32_t ExternalPointerHandle
static constexpr Address kNullAddress
Definition v8-internal.h:53
#define DCHECK_GE(v1, v2)
Definition logging.h:488
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define V8_EXPORT_PRIVATE
Definition macros.h:460
ExternalPointerRegistryEntry(ExternalPointerHandle handle, Address value, ExternalPointerTag tag)