[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:
Clemens Hammacher 2019-04-18 20:54:23 +02:00 committed by Commit Bot
parent e453f72264
commit 0820ee1adc
4 changed files with 22 additions and 16 deletions

View File

@ -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()); }

View File

@ -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 =

View File

@ -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);

View File

@ -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;