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

[wasm] Sample code size after top-tier compilation

In order to get a more complete picture about the code sizes of
compiled wasm modules, sample the code size of each module after
top-tier compilation finished. This happens via the {WasmEngine}
because that's where we know which isolates use a given {NativeModule}
and can schedule foreground tasks to sample the code size.

R=mstarzinger@chromium.org

Cq-Include-Trybots: luci.v8.try:v8_linux64_tsan_rel
Bug: v8:8217
Change-Id: Id585db8a9ab8f3aa1060b08411afaa31c5414f87
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1508404
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60167}
parent e242540e
......@@ -1263,7 +1263,10 @@ class RuntimeCallTimerScope {
HR(wasm_module_code_size_mb, V8.WasmModuleCodeSizeMiB, 0, 1024, 32) \
/* code size of modules after baseline compilation */ \
HR(wasm_module_code_size_mb_after_baseline, \
V8.WasmModuleCodeSizeBaselineMiB, 0, 1024, 32)
V8.WasmModuleCodeSizeBaselineMiB, 0, 1024, 32) \
/* code size of modules after top-tier compilation */ \
HR(wasm_module_code_size_mb_after_top_tier, V8.WasmModuleCodeSizeTopTierMiB, \
0, 1024, 32)
#define HISTOGRAM_TIMER_LIST(HT) \
/* Garbage collection timers. */ \
......
......@@ -1237,6 +1237,28 @@ class AsyncCompileJob::CompileFailed : public CompileStep {
}
};
namespace {
class SampleTopTierCodeSizeCallback {
public:
explicit SampleTopTierCodeSizeCallback(
std::weak_ptr<NativeModule> native_module)
: native_module_(std::move(native_module)) {}
void operator()(CompilationEvent event) {
// This callback is registered after baseline compilation finished, so the
// only possible event to follow is {kFinishedTopTierCompilation}.
DCHECK_EQ(CompilationEvent::kFinishedTopTierCompilation, event);
if (std::shared_ptr<NativeModule> native_module = native_module_.lock()) {
native_module->engine()->SampleTopTierCodeSizeInAllIsolates(
native_module);
}
}
private:
std::weak_ptr<NativeModule> native_module_;
};
} // namespace
//==========================================================================
// Step 3b (sync): Compilation finished.
//==========================================================================
......@@ -1247,6 +1269,10 @@ class AsyncCompileJob::CompileFinished : public CompileStep {
// Sample the generated code size when baseline compilation finished.
job->native_module_->SampleCodeSize(job->isolate_->counters(),
NativeModule::kAfterBaseline);
// Also, set a callback to sample the code size after top-tier compilation
// finished. This callback will *not* keep the NativeModule alive.
job->native_module_->compilation_state()->AddCallback(
SampleTopTierCodeSizeCallback{job->native_module_});
// Then finalize and publish the generated module.
job->FinishCompile();
}
......
......@@ -1178,6 +1178,9 @@ void NativeModule::SampleCodeSize(
case kAfterBaseline:
histogram = counters->wasm_module_code_size_mb_after_baseline();
break;
case kAfterTopTier:
histogram = counters->wasm_module_code_size_mb_after_top_tier();
break;
case kSampling:
histogram = counters->wasm_module_code_size_mb();
break;
......
......@@ -361,7 +361,7 @@ class V8_EXPORT_PRIVATE NativeModule final {
const char* GetRuntimeStubName(Address runtime_stub_entry) const;
// Sample the current code size of this modules to the given counters.
enum CodeSamplingTime : int8_t { kAfterBaseline, kSampling };
enum CodeSamplingTime : int8_t { kAfterBaseline, kAfterTopTier, kSampling };
void SampleCodeSize(Counters*, CodeSamplingTime) const;
private:
......
......@@ -515,6 +515,40 @@ void WasmEngine::FreeNativeModule(NativeModule* native_module) {
code_manager_.FreeNativeModule(native_module);
}
namespace {
class SampleTopTierCodeSizeTask : public CancelableTask {
public:
SampleTopTierCodeSizeTask(Isolate* isolate,
std::weak_ptr<NativeModule> native_module)
: CancelableTask(isolate),
isolate_(isolate),
native_module_(std::move(native_module)) {}
void RunInternal() override {
if (std::shared_ptr<NativeModule> native_module = native_module_.lock()) {
native_module->SampleCodeSize(isolate_->counters(),
NativeModule::kAfterTopTier);
}
}
private:
Isolate* const isolate_;
const std::weak_ptr<NativeModule> native_module_;
};
} // namespace
void WasmEngine::SampleTopTierCodeSizeInAllIsolates(
const std::shared_ptr<NativeModule>& native_module) {
base::MutexGuard lock(&mutex_);
DCHECK_EQ(1, isolates_per_native_module_.count(native_module.get()));
for (Isolate* isolate : isolates_per_native_module_[native_module.get()]) {
DCHECK_EQ(1, isolates_.count(isolate));
IsolateInfo* info = isolates_[isolate].get();
info->foreground_task_runner->PostTask(
base::make_unique<SampleTopTierCodeSizeTask>(isolate, native_module));
}
}
namespace {
DEFINE_LAZY_LEAKY_OBJECT_GETTER(std::shared_ptr<WasmEngine>,
......
......@@ -176,6 +176,11 @@ class V8_EXPORT_PRIVATE WasmEngine {
void FreeNativeModule(NativeModule*);
// Sample the code size of the given {NativeModule} in all isolates that have
// access to it. Call this after top-tier compilation finished.
// This will spawn foreground tasks that do *not* keep the NativeModule alive.
void SampleTopTierCodeSizeInAllIsolates(const std::shared_ptr<NativeModule>&);
// Call on process start and exit.
static void InitializeOncePerProcess();
static void GlobalTearDown();
......
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