[snapshot] Check CanDiscardCompiled() again before DiscardCompiled()

Since DiscardCompiled() can allocate, it could also a cause a GC. A full
GC might perform bytecode flushing, which could change the return value
of CanDiscardCompiled(). So a DiscardCompiled() invocation in one loop
iteration could violate the assumption that CanDiscardCompiled() holds
in subsequent iterations. Prevent DCHECK failure by checking whether
CanDiscardCompiled() still holds for each SharedFunctionInfo.

Bug: v8:11772
Change-Id: Ie9c704abeea801bd3f4f1bdf8fa9c51a8a9d447d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2960274
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75178}
This commit is contained in:
Dominik Inführ 2021-06-15 09:16:20 +02:00 committed by V8 LUCI CQ
parent c0614e9bce
commit 11891fd6a7

View File

@ -206,7 +206,9 @@ void Snapshot::ClearReconstructableDataForSerialization(
if (clear_recompilable_data) {
HandleScope scope(isolate);
std::vector<i::Handle<i::SharedFunctionInfo>> sfis_to_clear;
{ // Heap allocation is disallowed within this scope.
{
// Heap allocation is disallowed within this scope.
DisallowGarbageCollection disallow_gc;
i::HeapObjectIterator it(isolate->heap());
for (i::HeapObject o = it.Next(); !o.is_null(); o = it.Next()) {
if (o.IsSharedFunctionInfo()) {
@ -229,9 +231,11 @@ void Snapshot::ClearReconstructableDataForSerialization(
// Must happen after heap iteration since SFI::DiscardCompiled may allocate.
for (i::Handle<i::SharedFunctionInfo> shared : sfis_to_clear) {
if (shared->CanDiscardCompiled()) {
i::SharedFunctionInfo::DiscardCompiled(isolate, shared);
}
}
}
// Clear JSFunctions.