v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
mutable-page-metadata.cc
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
6
7#include <new>
8
9#include "src/base/logging.h"
12#include "src/common/globals.h"
19#include "src/heap/spaces.h"
21
22namespace v8::internal {
23
25 size_t chunk_size, Address area_start,
26 Address area_end,
27 VirtualMemory reservation,
28 PageSize page_size)
29 : MemoryChunkMetadata(heap, space, chunk_size, area_start, area_end,
30 std::move(reservation)) {
31 DCHECK_NE(space->identity(), RO_SPACE);
32
33 if (page_size == PageSize::kRegular) {
34 active_system_pages_ = std::make_unique<ActiveSystemPages>();
37 }
38
39 // We do not track active system pages for large pages and use this fact for
40 // `IsLargePage()`.
41 DCHECK_EQ(page_size == PageSize::kLarge, IsLargePage());
42
43 // TODO(sroettger): The following fields are accessed most often (AFAICT) and
44 // are moved to the end to occupy the same cache line as the slot set array.
45 // Without this change, there was a 0.5% performance impact after cache line
46 // aligning the metadata on x64 (before, the metadata started at offset 0x10).
47 // After reordering, the impact is still 0.1%/0.2% on jetstream2/speedometer3,
48 // so there should be some more optimization potential here.
49 // TODO(mlippautz): Replace 64 below with
50 // `hardware_destructive_interference_size` once supported.
51 static constexpr auto kOffsetOfFirstFastField =
52 offsetof(MutablePageMetadata, heap_);
53 static constexpr auto kOffsetOfLastFastField =
56 // This assert is merely necessary but not sufficient to guarantee that the
57 // fields sit on the same cacheline as the metadata object itself is
58 // dynamically allocated without alignment restrictions.
59 static_assert(kOffsetOfFirstFastField / 64 == kOffsetOfLastFastField / 64);
60}
61
63 Executability executable) const {
65
66 if (owner()->identity() == NEW_SPACE || owner()->identity() == NEW_LO_SPACE) {
68 heap()->incremental_marking()->marking_mode());
69 } else {
71 heap()->incremental_marking()->marking_mode(), owner()->identity());
72 }
73
74 if (executable == EXECUTABLE) {
76 // Executable chunks are also trusted as they contain machine code and live
77 // outside the sandbox (when it is enabled). While mostly symbolic, this is
78 // needed for two reasons:
79 // 1. We have the invariant that IsTrustedObject(obj) implies
80 // IsTrustedSpaceObject(obj), where IsTrustedSpaceObject checks the
81 // MemoryChunk::IS_TRUSTED flag on the host chunk. As InstructionStream
82 // objects are
83 // trusted, their host chunks must also be marked as such.
84 // 2. References between trusted objects must use the TRUSTED_TO_TRUSTED
85 // remembered set. However, that will only be used if both the host
86 // and the value chunk are marked as IS_TRUSTED.
88 }
89
90 // All pages of a shared heap need to be marked with this flag.
91 if (InSharedSpace()) {
93 }
94
95 // All pages belonging to a trusted space need to be marked with this flag.
96 if (InTrustedSpace()) {
98 }
99
100 // "Trusted" chunks should never be located inside the sandbox as they
101 // couldn't be trusted in that case.
104
105 return flags;
106}
107
112
113// -----------------------------------------------------------------------------
114// MutablePageMetadata implementation
115
139
143
145 SlotSet* new_slot_set = SlotSet::Allocate(BucketsInSlotSet());
147 &slot_set_[type], nullptr, new_slot_set);
148 if (old_slot_set) {
149 SlotSet::Delete(new_slot_set);
150 new_slot_set = old_slot_set;
151 }
152 DCHECK_NOT_NULL(new_slot_set);
153 return new_slot_set;
154}
155
163
176
184
186 for (int rs_type = 0; rs_type < NUMBER_OF_REMEMBERED_SET_TYPES; rs_type++) {
187 if (slot_set_[rs_type] || typed_slot_set_[rs_type]) {
188 return true;
189 }
190 }
191 return false;
192}
193
195 int length = 0;
196 for (int cat = kFirstCategory; cat <= owner()->free_list()->last_category();
197 cat++) {
198 if (categories_[cat] != nullptr) {
199 length += categories_[cat]->FreeListLength();
200 }
201 }
202 return length;
203}
204
206 CHECK_IMPLIES(marking_bitmap()->IsClean(), live_bytes() == 0);
207 return marking_bitmap()->IsClean();
208}
209
210} // namespace v8::internal
static void Delete(BasicSlotSet *slot_set)
static T AcquireRelease_CompareAndSwap(T *addr, typename std::remove_reference< T >::type old_value, typename std::remove_reference< T >::type new_value)
static T Release_CompareAndSwap(T *addr, typename std::remove_reference< T >::type old_value, typename std::remove_reference< T >::type new_value)
static bool HasLazyCommits()
FreeListCategoryType last_category()
Definition free-list.h:196
static V8_INLINE intptr_t GetCommitPageSizeBits()
static MainThreadFlags OldGenerationPageFlags(MarkingMode marking_mode, AllocationSpace space)
static MainThreadFlags YoungGenerationPageFlags(MarkingMode marking_mode)
void ReleaseTypedSlotSet(RememberedSetType type)
MemoryChunk::MainThreadFlags InitialFlags(Executability executable) const
TypedSlotSet * AllocateTypedSlotSet(RememberedSetType type)
V8_EXPORT_PRIVATE SlotSet * AllocateSlotSet(RememberedSetType type)
V8_EXPORT_PRIVATE size_t CommittedPhysicalMemory() const
void ReleaseSlotSet(RememberedSetType type)
MutablePageMetadata(Heap *heap, BaseSpace *space, size_t size, Address area_start, Address area_end, VirtualMemory reservation, PageSize page_size)
std::unique_ptr< ActiveSystemPages > active_system_pages_
SlotSet * slot_set_[NUMBER_OF_REMEMBERED_SET_TYPES]
TypedSlotSet * typed_slot_set_[NUMBER_OF_REMEMBERED_SET_TYPES]
static SlotSet * Allocate(size_t buckets)
Definition slot-set.h:133
FreeList * free_list()
Definition spaces.h:123
STL namespace.
static constexpr FreeListCategoryType kFirstCategory
Definition free-list.h:39
Flag flags[]
Definition flags.cc:3797
V8_INLINE bool InsideSandbox(uintptr_t address)
Definition sandbox.h:334
#define CHECK_IMPLIES(lhs, rhs)
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define DCHECK_IMPLIES(v1, v2)
Definition logging.h:493
#define DCHECK_NE(v1, v2)
Definition logging.h:486
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
wasm::ValueType type