[heap] Sweep code pages only on the main thread

Code pages need to be swept on the main thread for now. Originally this
was done to prevent RWX on code pages, but there might be more other
smaller issues like the linked bug. Most likely this restriction isn't
a problem for concurrent SP at the moment, so stick with this
invariant for now.

Bug: chromium:1269558, v8:12054
Change-Id: Icf7a7ce9714b9ef07b1a5070f0b0dd963b6d3011
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3279682
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77901}
This commit is contained in:
Dominik Inführ 2021-11-15 10:05:28 +01:00 committed by V8 LUCI CQ
parent 490a9ead23
commit 5f20156341
3 changed files with 30 additions and 16 deletions

View File

@ -602,23 +602,26 @@ base::Optional<std::pair<Address, size_t>> PagedSpace::RawRefillLabBackground(
local_heap, min_size_in_bytes, max_size_in_bytes, alignment, origin);
if (result) return result;
// Now contribute to sweeping from background thread and then try to
// reallocate.
Sweeper::FreeSpaceMayContainInvalidatedSlots
invalidated_slots_in_free_space =
Sweeper::FreeSpaceMayContainInvalidatedSlots::kNo;
if (IsSweepingAllowedOnThread(local_heap)) {
// Now contribute to sweeping from background thread and then try to
// reallocate.
Sweeper::FreeSpaceMayContainInvalidatedSlots
invalidated_slots_in_free_space =
Sweeper::FreeSpaceMayContainInvalidatedSlots::kNo;
const int kMaxPagesToSweep = 1;
int max_freed = collector->sweeper()->ParallelSweepSpace(
identity(), static_cast<int>(min_size_in_bytes), kMaxPagesToSweep,
invalidated_slots_in_free_space);
const int kMaxPagesToSweep = 1;
int max_freed = collector->sweeper()->ParallelSweepSpace(
identity(), static_cast<int>(min_size_in_bytes), kMaxPagesToSweep,
invalidated_slots_in_free_space);
RefillFreeList();
RefillFreeList();
if (static_cast<size_t>(max_freed) >= min_size_in_bytes) {
result = TryAllocationFromFreeListBackground(
local_heap, min_size_in_bytes, max_size_in_bytes, alignment, origin);
if (result) return result;
if (static_cast<size_t>(max_freed) >= min_size_in_bytes) {
result = TryAllocationFromFreeListBackground(
local_heap, min_size_in_bytes, max_size_in_bytes, alignment,
origin);
if (result) return result;
}
}
}
@ -633,7 +636,9 @@ base::Optional<std::pair<Address, size_t>> PagedSpace::RawRefillLabBackground(
if (collector->sweeping_in_progress()) {
// Complete sweeping for this space.
collector->DrainSweepingWorklistForSpace(identity());
if (IsSweepingAllowedOnThread(local_heap)) {
collector->DrainSweepingWorklistForSpace(identity());
}
RefillFreeList();
@ -692,6 +697,11 @@ PagedSpace::TryAllocationFromFreeListBackground(LocalHeap* local_heap,
return std::make_pair(start, used_size_in_bytes);
}
bool PagedSpace::IsSweepingAllowedOnThread(LocalHeap* local_heap) {
// Code space sweeping is only allowed on main thread.
return local_heap->is_main_thread() || identity() != CODE_SPACE;
}
#ifdef DEBUG
void PagedSpace::Print() {}
#endif

View File

@ -357,6 +357,10 @@ class V8_EXPORT_PRIVATE PagedSpace
bool HasPages() { return first_page() != nullptr; }
// Returns whether sweeping of this space is safe on this thread. Code space
// sweeping is only allowed on the main thread.
bool IsSweepingAllowedOnThread(LocalHeap* local_heap);
// Cleans up the space, frees all pages in this space except those belonging
// to the initial chunk, uncommits addresses in the initial chunk.
void TearDown();

View File

@ -412,8 +412,8 @@ int Sweeper::RawSweep(
CleanupInvalidTypedSlotsOfFreeRanges(p, free_ranges_map);
ClearMarkBitsAndHandleLivenessStatistics(p, live_bytes, free_list_mode);
p->set_concurrent_sweeping_state(Page::ConcurrentSweepingState::kDone);
if (code_object_registry) code_object_registry->Finalize();
p->set_concurrent_sweeping_state(Page::ConcurrentSweepingState::kDone);
if (free_list_mode == IGNORE_FREE_LIST) return 0;
return static_cast<int>(