Commit d1eb6c5f authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm][gc] Add stack guard for code gc

Beside scheduling a foreground task per isolate, do also request a
stack guard interrupt to report live code objects. This ensures that
also workers which never return from wasm code will report their live
wasm code objects.

R=mstarzinger@chromium.org

Bug: v8:8217
Change-Id: I07ba9e5125263365596331197813494d8ad5ee89
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1596739Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61277}
parent c958a1c6
...@@ -665,6 +665,11 @@ Object StackGuard::HandleInterrupts() { ...@@ -665,6 +665,11 @@ Object StackGuard::HandleInterrupts() {
isolate_->wasm_engine()->LogOutstandingCodesForIsolate(isolate_); isolate_->wasm_engine()->LogOutstandingCodesForIsolate(isolate_);
} }
if (CheckAndClearInterrupt(WASM_CODE_GC)) {
TRACE_EVENT0("v8.wasm", "WasmCodeGC");
isolate_->wasm_engine()->ReportLiveCodeFromStackForGC(isolate_);
}
isolate_->counters()->stack_interrupts()->Increment(); isolate_->counters()->stack_interrupts()->Increment();
isolate_->counters()->runtime_profiler_ticks()->Increment(); isolate_->counters()->runtime_profiler_ticks()->Increment();
isolate_->runtime_profiler()->MarkCandidatesForOptimization(); isolate_->runtime_profiler()->MarkCandidatesForOptimization();
......
...@@ -97,7 +97,8 @@ class V8_EXPORT_PRIVATE StackGuard final { ...@@ -97,7 +97,8 @@ class V8_EXPORT_PRIVATE StackGuard final {
V(API_INTERRUPT, ApiInterrupt, 3) \ V(API_INTERRUPT, ApiInterrupt, 3) \
V(DEOPT_MARKED_ALLOCATION_SITES, DeoptMarkedAllocationSites, 4) \ V(DEOPT_MARKED_ALLOCATION_SITES, DeoptMarkedAllocationSites, 4) \
V(GROW_SHARED_MEMORY, GrowSharedMemory, 5) \ V(GROW_SHARED_MEMORY, GrowSharedMemory, 5) \
V(LOG_WASM_CODE, LogWasmCode, 6) V(LOG_WASM_CODE, LogWasmCode, 6) \
V(WASM_CODE_GC, WasmCodeGC, 7)
#define V(NAME, Name, id) \ #define V(NAME, Name, id) \
inline bool Check##Name() { return CheckInterrupt(NAME); } \ inline bool Check##Name() { return CheckInterrupt(NAME); } \
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "src/code-tracer.h" #include "src/code-tracer.h"
#include "src/compilation-statistics.h" #include "src/compilation-statistics.h"
#include "src/counters.h" #include "src/counters.h"
#include "src/frames.h"
#include "src/objects-inl.h" #include "src/objects-inl.h"
#include "src/objects/heap-number.h" #include "src/objects/heap-number.h"
#include "src/objects/js-promise.h" #include "src/objects/js-promise.h"
...@@ -698,22 +699,21 @@ void WasmEngine::ReportLiveCodeForGC(Isolate* isolate, ...@@ -698,22 +699,21 @@ void WasmEngine::ReportLiveCodeForGC(Isolate* isolate,
live_code.size()); live_code.size());
DeadCodeMap dead_code; DeadCodeMap dead_code;
base::MutexGuard guard(&mutex_); base::MutexGuard guard(&mutex_);
DCHECK_NOT_NULL(current_gc_info_); // This report might come in late (note that we trigger both a stack guard and
auto outstanding_isolate_it = // a foreground task). In that case, ignore it.
current_gc_info_->outstanding_isolates.find(isolate); if (current_gc_info_ == nullptr) return;
DCHECK_NE(current_gc_info_->outstanding_isolates.end(), auto& outstanding_isolates = current_gc_info_->outstanding_isolates;
outstanding_isolate_it); auto outstanding_isolate_it = outstanding_isolates.find(isolate);
auto* fg_task = outstanding_isolate_it->second; if (outstanding_isolate_it == outstanding_isolates.end()) return;
if (fg_task) fg_task->Cancel(); if (auto* fg_task = outstanding_isolate_it->second) fg_task->Cancel();
current_gc_info_->outstanding_isolates.erase(outstanding_isolate_it); outstanding_isolates.erase(outstanding_isolate_it);
for (WasmCode* code : live_code) current_gc_info_->dead_code.erase(code); for (WasmCode* code : live_code) current_gc_info_->dead_code.erase(code);
TRACE_CODE_GC( TRACE_CODE_GC(
"Remaining dead code objects: %zu; outstanding isolates: %zu.\n", "Remaining dead code objects: %zu; outstanding isolates: %zu.\n",
current_gc_info_->dead_code.size(), current_gc_info_->dead_code.size(), outstanding_isolates.size());
current_gc_info_->outstanding_isolates.size());
// If there are more outstanding isolates, return here. // If there are more outstanding isolates, return here.
if (!current_gc_info_->outstanding_isolates.empty()) return; if (!outstanding_isolates.empty()) return;
// All remaining code in {current_gc_info->dead_code} is really dead. // All remaining code in {current_gc_info->dead_code} is really dead.
// Move it from the set of potentially dead code to the set of dead code, // Move it from the set of potentially dead code to the set of dead code,
...@@ -736,6 +736,19 @@ void WasmEngine::ReportLiveCodeForGC(Isolate* isolate, ...@@ -736,6 +736,19 @@ void WasmEngine::ReportLiveCodeForGC(Isolate* isolate,
FreeDeadCodeLocked(dead_code); FreeDeadCodeLocked(dead_code);
} }
void WasmEngine::ReportLiveCodeFromStackForGC(Isolate* isolate) {
wasm::WasmCodeRefScope code_ref_scope;
std::unordered_set<wasm::WasmCode*> live_wasm_code;
for (StackFrameIterator it(isolate); !it.done(); it.Advance()) {
StackFrame* const frame = it.frame();
if (frame->type() != StackFrame::WASM_COMPILED) continue;
live_wasm_code.insert(WasmCompiledFrame::cast(frame)->wasm_code());
}
ReportLiveCodeForGC(isolate,
OwnedVector<WasmCode*>::Of(live_wasm_code).as_vector());
}
bool WasmEngine::AddPotentiallyDeadCode(WasmCode* code) { bool WasmEngine::AddPotentiallyDeadCode(WasmCode* code) {
base::MutexGuard guard(&mutex_); base::MutexGuard guard(&mutex_);
auto it = native_modules_.find(code->native_module()); auto it = native_modules_.find(code->native_module());
...@@ -790,7 +803,6 @@ void WasmEngine::TriggerGC() { ...@@ -790,7 +803,6 @@ void WasmEngine::TriggerGC() {
current_gc_info_.reset(new CurrentGCInfo()); current_gc_info_.reset(new CurrentGCInfo());
// Add all potentially dead code to this GC, and trigger a GC task in each // Add all potentially dead code to this GC, and trigger a GC task in each
// isolate. // isolate.
// TODO(clemensh): Also trigger a stack check interrupt.
for (auto& entry : native_modules_) { for (auto& entry : native_modules_) {
NativeModuleInfo* info = entry.second.get(); NativeModuleInfo* info = entry.second.get();
if (info->potentially_dead_code.empty()) continue; if (info->potentially_dead_code.empty()) continue;
...@@ -803,6 +815,7 @@ void WasmEngine::TriggerGC() { ...@@ -803,6 +815,7 @@ void WasmEngine::TriggerGC() {
isolates_[isolate]->foreground_task_runner->PostTask( isolates_[isolate]->foreground_task_runner->PostTask(
std::move(new_task)); std::move(new_task));
} }
isolate->stack_guard()->RequestWasmCodeGC();
} }
for (WasmCode* code : info->potentially_dead_code) { for (WasmCode* code : info->potentially_dead_code) {
current_gc_info_->dead_code.insert(code); current_gc_info_->dead_code.insert(code);
......
...@@ -186,8 +186,11 @@ class V8_EXPORT_PRIVATE WasmEngine { ...@@ -186,8 +186,11 @@ class V8_EXPORT_PRIVATE WasmEngine {
// This will spawn foreground tasks that do *not* keep the NativeModule alive. // This will spawn foreground tasks that do *not* keep the NativeModule alive.
void SampleTopTierCodeSizeInAllIsolates(const std::shared_ptr<NativeModule>&); void SampleTopTierCodeSizeInAllIsolates(const std::shared_ptr<NativeModule>&);
// Called by each Isolate to report its live code for a GC cycle. // Called by each Isolate to report its live code for a GC cycle. First
void ReportLiveCodeForGC(Isolate*, Vector<WasmCode*> live_code); // version reports an externally determined set of live code (might be empty),
// second version gets live code from the execution stack of that isolate.
void ReportLiveCodeForGC(Isolate*, Vector<WasmCode*>);
void ReportLiveCodeFromStackForGC(Isolate*);
// Add potentially dead code. The occurrence in the set of potentially dead // Add potentially dead code. The occurrence in the set of potentially dead
// code counts as a reference, and is decremented on the next GC. // code counts as a reference, and is decremented on the next GC.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment