[heap] Fix race in MemoryChunk protection logic

... when allocating Code objects from background thread.

Bug: chromium:1329012, chromium:1330887
Change-Id: Ia2731ba463381c826d14591f4ba3b3fe15d15a0b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3688517
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80948}
This commit is contained in:
Igor Sheludko 2022-06-03 19:29:30 +02:00 committed by V8 LUCI CQ
parent 620388b1a6
commit a4d12a861b
3 changed files with 11 additions and 13 deletions

View File

@ -651,10 +651,7 @@ CodePageCollectionMemoryModificationScope::
CodePageCollectionMemoryModificationScope::
~CodePageCollectionMemoryModificationScope() {
if (heap_->write_protect_code_memory()) {
heap_->DecrementCodePageCollectionMemoryModificationScopeDepth();
if (heap_->code_page_collection_memory_modification_scope_depth() == 0) {
heap_->ProtectUnprotectedMemoryChunks();
}
heap_->ProtectUnprotectedMemoryChunks();
}
}

View File

@ -2768,8 +2768,12 @@ void Heap::ComputeFastPromotionMode() {
void Heap::UnprotectAndRegisterMemoryChunk(MemoryChunk* chunk,
UnprotectMemoryOrigin origin) {
if (!write_protect_code_memory()) return;
base::MutexGuard guard(&unprotected_memory_chunks_mutex_);
// CodePageCollectionMemoryModificationScope can be used in multiple threads,
// so we have to check its depth behind the lock.
if (code_page_collection_memory_modification_scope_depth_ > 0) {
base::MutexGuard guard(&unprotected_memory_chunks_mutex_);
if (unprotected_memory_chunks_.insert(chunk).second) {
chunk->SetCodeModificationPermissions();
}
@ -2790,6 +2794,11 @@ void Heap::UnregisterUnprotectedMemoryChunk(MemoryChunk* chunk) {
void Heap::ProtectUnprotectedMemoryChunks() {
base::MutexGuard guard(&unprotected_memory_chunks_mutex_);
// CodePageCollectionMemoryModificationScope can be used in multiple threads,
// so we have to check its depth behind the lock.
if (--code_page_collection_memory_modification_scope_depth_ > 0) return;
for (auto chunk = unprotected_memory_chunks_.begin();
chunk != unprotected_memory_chunks_.end(); chunk++) {
DCHECK(memory_allocator()->IsMemoryChunkExecutable(*chunk));

View File

@ -675,14 +675,6 @@ class Heap {
code_page_collection_memory_modification_scope_depth_++;
}
void DecrementCodePageCollectionMemoryModificationScopeDepth() {
code_page_collection_memory_modification_scope_depth_--;
}
uintptr_t code_page_collection_memory_modification_scope_depth() {
return code_page_collection_memory_modification_scope_depth_;
}
inline HeapState gc_state() const {
return gc_state_.load(std::memory_order_relaxed);
}