diff --git a/src/d8/d8.cc b/src/d8/d8.cc index 798bec98b4..e927ab6a25 100644 --- a/src/d8/d8.cc +++ b/src/d8/d8.cc @@ -453,7 +453,9 @@ class ExternalOwningOneByteStringResource std::unique_ptr file_; }; +// static variables: CounterMap* Shell::counter_map_; +base::SharedMutex Shell::counter_mutex_; base::OS::MemoryMappedFile* Shell::counters_file_ = nullptr; CounterCollection Shell::local_counters_; CounterCollection* Shell::counters_ = &local_counters_; @@ -2585,7 +2587,10 @@ void Shell::QuitOnce(v8::FunctionCallbackInfo* args) { .FromMaybe(0); WaitForRunningWorkers(); args->GetIsolate()->Exit(); - OnExit(args->GetIsolate()); + // As we exit the process anyway, we do not dispose the platform and other + // global data. Other isolates might still be running, so disposing here can + // cause them to crash. + OnExit(args->GetIsolate(), false); base::OS::ExitProcess(exit_code); } @@ -2738,8 +2743,9 @@ int32_t* Counter::Bind(const char* name, bool is_histogram) { } void Counter::AddSample(int32_t sample) { - count_++; - sample_total_ += sample; + base::Relaxed_AtomicIncrement(reinterpret_cast(&count_), 1); + base::Relaxed_AtomicIncrement( + reinterpret_cast(&sample_total_), sample); } CounterCollection::CounterCollection() { @@ -2770,19 +2776,32 @@ void Shell::MapCounters(v8::Isolate* isolate, const char* name) { } Counter* Shell::GetCounter(const char* name, bool is_histogram) { - auto map_entry = counter_map_->find(name); - Counter* counter = - map_entry != counter_map_->end() ? map_entry->second : nullptr; + Counter* counter = nullptr; + { + base::SharedMutexGuard mutex_guard(&counter_mutex_); + auto map_entry = counter_map_->find(name); + if (map_entry != counter_map_->end()) { + counter = map_entry->second; + } + } - if (counter == nullptr) { - counter = counters_->GetNextCounter(); - if (counter != nullptr) { + if (!counter) { + base::SharedMutexGuard mutex_guard(&counter_mutex_); + + counter = (*counter_map_)[name]; + + if (counter == nullptr) { + counter = counters_->GetNextCounter(); + if (counter == nullptr) { + // Too many counters. + return nullptr; + } (*counter_map_)[name] = counter; counter->Bind(name, is_histogram); } - } else { - DCHECK(counter->is_histogram() == is_histogram); } + + DCHECK_EQ(is_histogram, counter->is_histogram()); return counter; } @@ -3340,13 +3359,19 @@ void Shell::WriteLcovData(v8::Isolate* isolate, const char* file) { } } -void Shell::OnExit(v8::Isolate* isolate) { +void Shell::OnExit(v8::Isolate* isolate, bool dispose) { isolate->Dispose(); if (shared_isolate) { i::Isolate::Delete(reinterpret_cast(shared_isolate)); } + if (dispose) { + V8::Dispose(); + V8::DisposePlatform(); + } + if (i::FLAG_dump_counters || i::FLAG_dump_counters_nvp) { + base::SharedMutexGuard mutex_guard(&counter_mutex_); std::vector> counters( counter_map_->begin(), counter_map_->end()); std::sort(counters.begin(), counters.end()); @@ -5374,10 +5399,7 @@ int Shell::Main(int argc, char* argv[]) { #endif // V8_FUZZILLI } while (fuzzilli_reprl); } - OnExit(isolate); - - V8::Dispose(); - V8::DisposePlatform(); + OnExit(isolate, true); // Delete the platform explicitly here to write the tracing output to the // tracing file. diff --git a/src/d8/d8.h b/src/d8/d8.h index 5461611200..63f68e32dd 100644 --- a/src/d8/d8.h +++ b/src/d8/d8.h @@ -478,7 +478,7 @@ class Shell : public i::AllStatic { static int RunMain(Isolate* isolate, bool last_run); static int Main(int argc, char* argv[]); static void Exit(int exit_code); - static void OnExit(Isolate* isolate); + static void OnExit(Isolate* isolate, bool dispose); static void CollectGarbage(Isolate* isolate); static bool EmptyMessageQueues(Isolate* isolate); static bool CompleteMessageLoop(Isolate* isolate); @@ -669,6 +669,7 @@ class Shell : public i::AllStatic { static Global stringify_function_; static const char* stringify_source_; static CounterMap* counter_map_; + static base::SharedMutex counter_mutex_; // We statically allocate a set of local counters to be used if we // don't want to store the stats in a memory-mapped file static CounterCollection local_counters_; diff --git a/test/mjsunit/dump-counters.js b/test/mjsunit/dump-counters.js new file mode 100644 index 0000000000..b3d5ae17c0 --- /dev/null +++ b/test/mjsunit/dump-counters.js @@ -0,0 +1,15 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --dump-counters + +d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); + +(function testWasm() { + // Regression test for https://crbug.com/v8/12453. + if (typeof WebAssembly === 'undefined') return; // Skip on jitless. + const builder = new WasmModuleBuilder(); + builder.addFunction('f', kSig_v_v).addBody([]); + builder.instantiate(); +})();