Skip to content

Commit 00dab30

Browse files
kvakilRafaelGSS
authored andcommitted
deps: V8: cherry-pick 475c8cdf9a95
Original commit message: [ptr-compr] Fix multi-cage mode This CL introduces PtrComprCageAccessScope which sets/restores current thread's pointer compression cage base values. It's supposed to be used by V8 jobs accessing V8 heap outside of v8::Isolate::Scope or i::LocalHeap or i::LocalIsolate scopes (they already ensure that the cage base values are properly initialized). For all other build modes PtrComprCageAccessScope is a no-op. For simplicity reasons the multi-cage mode is made incompatible with external code space. Bug: v8:13788, v8:14292 Change-Id: I06c2d19a1eb7254fa7af07a17617e22d98abea9f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4846592 Reviewed-by: Jakob Linke <jgruber@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Commit-Queue: Igor Sheludko <ishell@chromium.org> Reviewed-by: Dominik Inführ <dinfuehr@chromium.org> Cr-Commit-Position: refs/heads/main@{#90075} Refs: v8/v8@475c8cd PR-URL: #50680 Refs: https://bugs.chromium.org/p/v8/issues/detail?id=14292 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Darshan Sen <raisinten@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 8468daf commit 00dab30

27 files changed

+316
-101
lines changed

deps/v8/BUILD.gn

+7
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,7 @@ if (v8_enable_short_builtin_calls == "") {
500500
if (v8_enable_external_code_space == "") {
501501
v8_enable_external_code_space =
502502
v8_enable_pointer_compression &&
503+
v8_enable_pointer_compression_shared_cage &&
503504
(v8_current_cpu == "x64" || v8_current_cpu == "arm64")
504505
}
505506
if (v8_enable_maglev == "") {
@@ -683,6 +684,12 @@ assert(
683684
!v8_enable_pointer_compression_shared_cage || v8_enable_pointer_compression,
684685
"Can't share a pointer compression cage if pointers aren't compressed")
685686

687+
assert(
688+
!v8_enable_pointer_compression ||
689+
v8_enable_pointer_compression_shared_cage ||
690+
!v8_enable_external_code_space,
691+
"Multi-cage pointer compression mode is not compatible with external code space")
692+
686693
assert(
687694
!v8_enable_pointer_compression_shared_cage || v8_current_cpu == "x64" ||
688695
v8_current_cpu == "arm64" || v8_current_cpu == "riscv64" ||

deps/v8/src/api/api.cc

+16
Original file line numberDiff line numberDiff line change
@@ -9227,6 +9227,14 @@ void Isolate::TerminateExecution() {
92279227

92289228
bool Isolate::IsExecutionTerminating() {
92299229
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
9230+
#ifdef DEBUG
9231+
// This method might be called on a thread that's not bound to any Isolate
9232+
// and thus pointer compression schemes might have cage base value unset.
9233+
// Read-only roots accessors contain type DCHECKs which require access to
9234+
// V8 heap in order to check the object type. So, allow heap access here
9235+
// to let the checks work.
9236+
i::PtrComprCageAccessScope ptr_compr_cage_access_scope(i_isolate);
9237+
#endif // DEBUG
92309238
return i_isolate->is_execution_terminating();
92319239
}
92329240

@@ -9898,6 +9906,14 @@ void Isolate::LowMemoryNotification() {
98989906
i::NestedTimedHistogramScope idle_notification_scope(
98999907
i_isolate->counters()->gc_low_memory_notification());
99009908
TRACE_EVENT0("v8", "V8.GCLowMemoryNotification");
9909+
#ifdef DEBUG
9910+
// This method might be called on a thread that's not bound to any Isolate
9911+
// and thus pointer compression schemes might have cage base value unset.
9912+
// Read-only roots accessors contain type DCHECKs which require access to
9913+
// V8 heap in order to check the object type. So, allow heap access here
9914+
// to let the checks work.
9915+
i::PtrComprCageAccessScope ptr_compr_cage_access_scope(i_isolate);
9916+
#endif // DEBUG
99019917
i_isolate->heap()->CollectAllAvailableGarbage(
99029918
i::GarbageCollectionReason::kLowMemoryNotification);
99039919
}

deps/v8/src/common/ptr-compr-inl.h

+27-4
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,16 @@ Address V8HeapCompressionScheme::DecompressTaggedSigned(Tagged_t raw_value) {
9191
template <typename TOnHeapAddress>
9292
Address V8HeapCompressionScheme::DecompressTagged(TOnHeapAddress on_heap_addr,
9393
Tagged_t raw_value) {
94-
#if defined(V8_COMPRESS_POINTERS_IN_SHARED_CAGE)
94+
#ifdef V8_COMPRESS_POINTERS
9595
Address cage_base = base();
96+
#ifdef V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE
97+
DCHECK_WITH_MSG(cage_base != kNullAddress,
98+
"V8HeapCompressionScheme::base is not initialized for "
99+
"current thread");
100+
#endif // V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE
96101
#else
97102
Address cage_base = GetPtrComprCageBaseAddress(on_heap_addr);
98-
#endif
103+
#endif // V8_COMPRESS_POINTERS
99104
Address result = cage_base + static_cast<Address>(raw_value);
100105
V8_ASSUME(static_cast<uint32_t>(result) == raw_value);
101106
return result;
@@ -191,11 +196,16 @@ Address ExternalCodeCompressionScheme::DecompressTaggedSigned(
191196
template <typename TOnHeapAddress>
192197
Address ExternalCodeCompressionScheme::DecompressTagged(
193198
TOnHeapAddress on_heap_addr, Tagged_t raw_value) {
194-
#if defined(V8_COMPRESS_POINTERS_IN_SHARED_CAGE)
199+
#ifdef V8_COMPRESS_POINTERS
195200
Address cage_base = base();
201+
#ifdef V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE
202+
DCHECK_WITH_MSG(cage_base != kNullAddress,
203+
"ExternalCodeCompressionScheme::base is not initialized for "
204+
"current thread");
205+
#endif // V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE
196206
#else
197207
Address cage_base = GetPtrComprCageBaseAddress(on_heap_addr);
198-
#endif
208+
#endif // V8_COMPRESS_POINTERS
199209
Address result = cage_base + static_cast<Address>(raw_value);
200210
V8_ASSUME(static_cast<uint32_t>(result) == raw_value);
201211
return result;
@@ -275,6 +285,19 @@ V8_INLINE PtrComprCageBase GetPtrComprCageBase(Tagged<HeapObject> object) {
275285
return GetPtrComprCageBaseFromOnHeapAddress(object.ptr());
276286
}
277287

288+
#ifdef V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE
289+
290+
PtrComprCageAccessScope::PtrComprCageAccessScope(Isolate* isolate)
291+
: cage_base_(V8HeapCompressionScheme::base()) {
292+
V8HeapCompressionScheme::InitBase(isolate->cage_base());
293+
}
294+
295+
PtrComprCageAccessScope::~PtrComprCageAccessScope() {
296+
V8HeapCompressionScheme::InitBase(cage_base_);
297+
}
298+
299+
#endif // V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE
300+
278301
} // namespace internal
279302
} // namespace v8
280303

deps/v8/src/common/ptr-compr.h

+25-2
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ class V8HeapCompressionScheme {
5555
private:
5656
// These non-inlined accessors to base_ field are used in component builds
5757
// where cross-component access to thread local variables is not allowed.
58-
static Address base_non_inlined();
59-
static void set_base_non_inlined(Address base);
58+
static V8_EXPORT_PRIVATE Address base_non_inlined();
59+
static V8_EXPORT_PRIVATE void set_base_non_inlined(Address base);
6060

6161
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
6262
static V8_EXPORT_PRIVATE uintptr_t base_ V8_CONSTINIT;
@@ -156,6 +156,29 @@ static inline void WriteMaybeUnalignedValue(Address p, V value) {
156156
}
157157
}
158158

159+
// When multi-cage pointer compression mode is enabled this scope object
160+
// saves current cage's base values and sets them according to given Isolate.
161+
// For all other configurations this scope object is a no-op.
162+
class PtrComprCageAccessScope final {
163+
public:
164+
#ifdef V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE
165+
V8_INLINE explicit PtrComprCageAccessScope(Isolate* isolate);
166+
V8_INLINE ~PtrComprCageAccessScope();
167+
#else
168+
V8_INLINE explicit PtrComprCageAccessScope(Isolate* isolate) {}
169+
V8_INLINE ~PtrComprCageAccessScope() {}
170+
#endif
171+
172+
private:
173+
#ifdef V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE
174+
const Address cage_base_;
175+
#ifdef V8_EXTERNAL_CODE_SPACE
176+
// In case this configuration is necessary the code cage base must be saved too.
177+
#error Multi-cage pointer compression with external code space is not supported
178+
#endif // V8_EXTERNAL_CODE_SPACE
179+
#endif // V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE
180+
};
181+
159182
} // namespace v8::internal
160183

161184
#endif // V8_COMMON_PTR_COMPR_H_

deps/v8/src/execution/isolate.cc

+8
Original file line numberDiff line numberDiff line change
@@ -3933,6 +3933,14 @@ Isolate::~Isolate() {
39333933

39343934
void Isolate::InitializeThreadLocal() {
39353935
thread_local_top()->Initialize(this);
3936+
#ifdef DEBUG
3937+
// This method might be called on a thread that's not bound to any Isolate
3938+
// and thus pointer compression schemes might have cage base value unset.
3939+
// Read-only roots accessors contain type DCHECKs which require access to
3940+
// V8 heap in order to check the object type. So, allow heap access here
3941+
// to let the checks work.
3942+
i::PtrComprCageAccessScope ptr_compr_cage_access_scope(this);
3943+
#endif // DEBUG
39363944
clear_pending_exception();
39373945
clear_pending_message();
39383946
clear_scheduled_exception();

deps/v8/src/execution/v8threads.cc

+12
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ bool ThreadManager::RestoreThread() {
124124
InitThread(access);
125125
return false;
126126
}
127+
// In case multi-cage pointer compression mode is enabled ensure that
128+
// current thread's cage base values are properly initialized.
129+
PtrComprCageAccessScope ptr_compr_cage_access_scope(isolate_);
130+
127131
ThreadState* state = per_thread->thread_state();
128132
char* from = state->data();
129133
from = isolate_->handle_scope_implementer()->RestoreThread(from);
@@ -274,6 +278,14 @@ void ThreadManager::EagerlyArchiveThread() {
274278
}
275279

276280
void ThreadManager::FreeThreadResources() {
281+
#ifdef DEBUG
282+
// This method might be called on a thread that's not bound to any Isolate
283+
// and thus pointer compression schemes might have cage base value unset.
284+
// Read-only roots accessors contain type DCHECKs which require access to
285+
// V8 heap in order to check the object type. So, allow heap access here
286+
// to let the checks work.
287+
PtrComprCageAccessScope ptr_compr_cage_access_scope(isolate_);
288+
#endif // DEBUG
277289
DCHECK(!isolate_->has_pending_exception());
278290
DCHECK(!isolate_->external_caught_exception());
279291
DCHECK_NULL(isolate_->try_catch_handler());

deps/v8/src/heap/collection-barrier.cc

+6-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,12 @@ class BackgroundCollectionInterruptTask : public CancelableTask {
5151

5252
private:
5353
// v8::internal::CancelableTask overrides.
54-
void RunInternal() override { heap_->CheckCollectionRequested(); }
54+
void RunInternal() override {
55+
// In case multi-cage pointer compression mode is enabled ensure that
56+
// current thread's cage base values are properly initialized.
57+
PtrComprCageAccessScope ptr_compr_cage_access_scope(heap_->isolate());
58+
heap_->CheckCollectionRequested();
59+
}
5560

5661
Heap* heap_;
5762
};

deps/v8/src/heap/concurrent-marking.cc

+10
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,11 @@ class ConcurrentMarking::JobTaskMajor : public v8::JobTask {
153153

154154
// v8::JobTask overrides.
155155
void Run(JobDelegate* delegate) override {
156+
// In case multi-cage pointer compression mode is enabled ensure that
157+
// current thread's cage base values are properly initialized.
158+
PtrComprCageAccessScope ptr_compr_cage_access_scope(
159+
concurrent_marking_->heap_->isolate());
160+
156161
if (delegate->IsJoiningThread()) {
157162
// TRACE_GC is not needed here because the caller opens the right scope.
158163
concurrent_marking_->RunMajor(delegate, code_flush_mode_,
@@ -197,6 +202,11 @@ class ConcurrentMarking::JobTaskMinor : public v8::JobTask {
197202

198203
// v8::JobTask overrides.
199204
void Run(JobDelegate* delegate) override {
205+
// In case multi-cage pointer compression mode is enabled ensure that
206+
// current thread's cage base values are properly initialized.
207+
PtrComprCageAccessScope ptr_compr_cage_access_scope(
208+
concurrent_marking_->heap_->isolate());
209+
200210
if (delegate->IsJoiningThread()) {
201211
TRACE_GC_WITH_FLOW(concurrent_marking_->heap_->tracer(),
202212
GCTracer::Scope::MINOR_MS_MARK_PARALLEL, trace_id_,

deps/v8/src/heap/incremental-marking-job.cc

+3
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ void IncrementalMarkingJob::Task::RunInternal() {
9191
VMState<GC> state(isolate());
9292
TRACE_EVENT_CALL_STATS_SCOPED(isolate(), "v8",
9393
"V8.IncrementalMarkingJob.Task");
94+
// In case multi-cage pointer compression mode is enabled ensure that
95+
// current thread's cage base values are properly initialized.
96+
PtrComprCageAccessScope ptr_compr_cage_access_scope(isolate());
9497

9598
isolate()->stack_guard()->ClearStartIncrementalMarking();
9699

deps/v8/src/heap/local-heap.cc

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ void LocalHeap::VerifyCurrent() const {
4848
LocalHeap::LocalHeap(Heap* heap, ThreadKind kind,
4949
std::unique_ptr<PersistentHandles> persistent_handles)
5050
: heap_(heap),
51+
ptr_compr_cage_access_scope_(heap->isolate()),
5152
is_main_thread_(kind == ThreadKind::kMain),
5253
state_(ThreadState::Parked()),
5354
allocation_failed_(false),

deps/v8/src/heap/local-heap.h

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "src/base/platform/condition-variable.h"
1414
#include "src/base/platform/mutex.h"
1515
#include "src/common/assert-scope.h"
16+
#include "src/common/ptr-compr.h"
1617
#include "src/execution/isolate.h"
1718
#include "src/handles/global-handles.h"
1819
#include "src/handles/persistent-handles.h"
@@ -348,6 +349,7 @@ class V8_EXPORT_PRIVATE LocalHeap {
348349
void SetUpSharedMarking();
349350

350351
Heap* heap_;
352+
V8_NO_UNIQUE_ADDRESS PtrComprCageAccessScope ptr_compr_cage_access_scope_;
351353
bool is_main_thread_;
352354

353355
AtomicThreadState state_;

deps/v8/src/heap/mark-compact.cc

+14
Original file line numberDiff line numberDiff line change
@@ -2522,6 +2522,10 @@ class ClearStringTableJobItem final : public ParallelClearingJob::ClearingItem {
25222522
GCTracer::Scope::MC_CLEAR_STRING_TABLE)) {}
25232523

25242524
void Run(JobDelegate* delegate) final {
2525+
// In case multi-cage pointer compression mode is enabled ensure that
2526+
// current thread's cage base values are properly initialized.
2527+
PtrComprCageAccessScope ptr_compr_cage_access_scope(isolate_);
2528+
25252529
if (isolate_->OwnsStringTables()) {
25262530
TRACE_GC1_WITH_FLOW(isolate_->heap()->tracer(),
25272531
GCTracer::Scope::MC_CLEAR_STRING_TABLE,
@@ -4135,6 +4139,11 @@ class PageEvacuationJob : public v8::JobTask {
41354139
tracer_->CurrentEpoch(GCTracer::Scope::MC_EVACUATE)) {}
41364140

41374141
void Run(JobDelegate* delegate) override {
4142+
// In case multi-cage pointer compression mode is enabled ensure that
4143+
// current thread's cage base values are properly initialized.
4144+
PtrComprCageAccessScope ptr_compr_cage_access_scope(
4145+
collector_->heap()->isolate());
4146+
41384147
Evacuator* evacuator = (*evacuators_)[delegate->GetTaskId()].get();
41394148
if (delegate->IsJoiningThread()) {
41404149
TRACE_GC_WITH_FLOW(tracer_, GCTracer::Scope::MC_EVACUATE_COPY_PARALLEL,
@@ -4471,6 +4480,11 @@ class PointersUpdatingJob : public v8::JobTask {
44714480
tracer_->CurrentEpoch(GCTracer::Scope::MC_EVACUATE)) {}
44724481

44734482
void Run(JobDelegate* delegate) override {
4483+
// In case multi-cage pointer compression mode is enabled ensure that
4484+
// current thread's cage base values are properly initialized.
4485+
PtrComprCageAccessScope ptr_compr_cage_access_scope(
4486+
collector_->heap()->isolate());
4487+
44744488
if (delegate->IsJoiningThread()) {
44754489
TRACE_GC_WITH_FLOW(tracer_,
44764490
GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_PARALLEL,

deps/v8/src/heap/mark-compact.h

+2
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ class MarkCompactCollector final {
161161
return use_background_threads_in_cycle_;
162162
}
163163

164+
Heap* heap() { return heap_; }
165+
164166
explicit MarkCompactCollector(Heap* heap);
165167
~MarkCompactCollector();
166168

deps/v8/src/heap/scavenger.cc

+4
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,10 @@ ScavengerCollector::JobTask::JobTask(
200200

201201
void ScavengerCollector::JobTask::Run(JobDelegate* delegate) {
202202
DCHECK_LT(delegate->GetTaskId(), scavengers_->size());
203+
// In case multi-cage pointer compression mode is enabled ensure that
204+
// current thread's cage base values are properly initialized.
205+
PtrComprCageAccessScope ptr_compr_cage_access_scope(outer_->heap_->isolate());
206+
203207
Scavenger* scavenger = (*scavengers_)[delegate->GetTaskId()].get();
204208
if (delegate->IsJoiningThread()) {
205209
TRACE_GC_WITH_FLOW(outer_->heap_->tracer(),

deps/v8/src/heap/sweeper.cc

+10
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ class Sweeper::MajorSweeperJob final : public JobTask {
144144

145145
private:
146146
void RunImpl(JobDelegate* delegate, bool is_joining_thread) {
147+
// In case multi-cage pointer compression mode is enabled ensure that
148+
// current thread's cage base values are properly initialized.
149+
PtrComprCageAccessScope ptr_compr_cage_access_scope(
150+
sweeper_->heap_->isolate());
151+
147152
DCHECK(sweeper_->major_sweeping_in_progress());
148153
const int offset = delegate->GetTaskId();
149154
DCHECK_LT(offset, concurrent_sweepers.size());
@@ -213,6 +218,11 @@ class Sweeper::MinorSweeperJob final : public JobTask {
213218
tracer_, sweeper_->GetTracingScope(NEW_SPACE, is_joining_thread),
214219
is_joining_thread ? ThreadKind::kMain : ThreadKind::kBackground,
215220
trace_id_, TRACE_EVENT_FLAG_FLOW_IN);
221+
// In case multi-cage pointer compression mode is enabled ensure that
222+
// current thread's cage base values are properly initialized.
223+
PtrComprCageAccessScope ptr_compr_cage_access_scope(
224+
sweeper_->heap_->isolate());
225+
216226
if (!concurrent_sweeper.ConcurrentSweepSpace(delegate)) return;
217227
concurrent_sweeper.ConcurrentSweepPromotedPages(delegate);
218228
}

0 commit comments

Comments
 (0)