[wasm][gc] Fix several minor issues
This CL fixes some issues with GC. 1) It removes dead code from the set of potentially dead code to avoid considering the same code for GC again and again. 2) It resets the {new_potentially_dead_code_size_} counter to avoid triggering too many GCs. 3) When code becomes dead after GC, do not unconditionally free it; just decrement its ref count (there might still be {WasmCodeRefScope}s holding the code alive). 4) Update the comment of the ref count to be more accurate. R=titzer@chromium.org Bug: v8:8217 Change-Id: I28e5a1fed74411b8473bb66ddbad3ffe7643f266 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1574518 Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Reviewed-by: Ben Titzer <titzer@chromium.org> Cr-Commit-Position: refs/heads/master@{#60949}
This commit is contained in:
parent
e453f72264
commit
0820ee1adc
@ -219,6 +219,9 @@ class OwnedVector {
|
||||
return data_.get();
|
||||
}
|
||||
|
||||
constexpr T* begin() const { return start(); }
|
||||
constexpr T* end() const { return start() + size(); }
|
||||
|
||||
// Returns a {Vector<T>} view of the data in this vector.
|
||||
Vector<T> as_vector() const { return Vector<T>(start(), size()); }
|
||||
|
||||
|
@ -1333,6 +1333,7 @@ void NativeModule::SampleCodeSize(
|
||||
histogram = counters->wasm_module_code_size_mb();
|
||||
// Also, add a sample of freed code size, absolute and relative.
|
||||
size_t freed_size = freed_code_size_.load(std::memory_order_relaxed);
|
||||
DCHECK_LE(freed_size, generated_code_size_);
|
||||
int total_freed_mb = static_cast<int>(freed_size / MB);
|
||||
counters->wasm_module_freed_code_size_mb()->AddSample(total_freed_mb);
|
||||
int freed_percent =
|
||||
|
@ -248,15 +248,15 @@ class V8_EXPORT_PRIVATE WasmCode final {
|
||||
ExecutionTier tier_;
|
||||
|
||||
// WasmCode is ref counted. Counters are held by:
|
||||
// 1) The jump table.
|
||||
// 2) Function tables.
|
||||
// 3) {WasmCodeRefScope}s.
|
||||
// 4) The set of potentially dead code in the {WasmEngine}.
|
||||
// If a decrement of (1) or (2) would drop the ref count to 0, that code
|
||||
// becomes a candidate for garbage collection. At that point, we add
|
||||
// ref counts for (4) *before* decrementing the counter to ensure the code
|
||||
// stays alive as long as it's being used. Once the ref count drops to zero,
|
||||
// the code object is deleted and the memory for the machine code is freed.
|
||||
// 1) The jump table / code table.
|
||||
// 2) {WasmCodeRefScope}s.
|
||||
// 3) The set of potentially dead code in the {WasmEngine}.
|
||||
// If a decrement of (1) would drop the ref count to 0, that code becomes a
|
||||
// candidate for garbage collection. At that point, we add a ref count for (3)
|
||||
// *before* decrementing the counter to ensure the code stays alive as long as
|
||||
// it's being used. Once the ref count drops to zero (i.e. after being removed
|
||||
// from (3) and all (2)), the code object is deleted and the memory for the
|
||||
// machine code is freed.
|
||||
std::atomic<int> ref_count_{1};
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WasmCode);
|
||||
|
@ -675,14 +675,15 @@ void WasmEngine::ReportLiveCodeForGC(Isolate* isolate,
|
||||
for (WasmCode* code : live_code) current_gc_info_->dead_code.erase(code);
|
||||
|
||||
if (current_gc_info_->outstanding_isolates.empty()) {
|
||||
std::unordered_map<NativeModule*, std::vector<WasmCode*>>
|
||||
dead_code_per_native_module;
|
||||
for (WasmCode* code : current_gc_info_->dead_code) {
|
||||
dead_code_per_native_module[code->native_module()].push_back(code);
|
||||
}
|
||||
for (auto& entry : dead_code_per_native_module) {
|
||||
entry.first->FreeCode(VectorOf(entry.second));
|
||||
// All remaining code in {current_gc_info->dead_code} is really dead. Remove
|
||||
// it from the set of potentially dead code, and decrement its ref count.
|
||||
auto dead_code = OwnedVector<WasmCode*>::Of(current_gc_info_->dead_code);
|
||||
for (WasmCode* code : dead_code) {
|
||||
auto* native_module_info = native_modules_[code->native_module()].get();
|
||||
DCHECK_EQ(1, native_module_info->potentially_dead_code.count(code));
|
||||
native_module_info->potentially_dead_code.erase(code);
|
||||
}
|
||||
WasmCode::DecrementRefCount(dead_code.as_vector());
|
||||
current_gc_info_.reset();
|
||||
}
|
||||
}
|
||||
@ -698,6 +699,7 @@ bool WasmEngine::AddPotentiallyDeadCode(WasmCode* code) {
|
||||
size_t dead_code_limit = 1 * MB + code_manager_.committed_code_space() / 10;
|
||||
if (FLAG_wasm_code_gc && new_potentially_dead_code_size_ > dead_code_limit &&
|
||||
!current_gc_info_) {
|
||||
new_potentially_dead_code_size_ = 0;
|
||||
TriggerGC();
|
||||
}
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user