Commit 27b8ad20 authored by Thibaud Michaud's avatar Thibaud Michaud Committed by Commit Bot

[wasm][eh] Add metrics for exception events

Sample elapsed time between two consecutive exception events of the same
type (throw/rethrow/catch). This will give us an idea of how frequently
exception handling features are used at runtime during the origin trial.

R=ahaas@chromium.org

Bug: v8:8091
Cq-Include-Trybots: luci.v8.try:v8_linux64_tsan_rel_ng
Cq-Include-Trybots: luci.v8.try:v8_linux64_tsan_isolates_rel_ng
Change-Id: Ic3095eeeca08d2e079a507a492f10d2efb5ecfd2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2684367Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72685}
parent 17a5a3b7
......@@ -16,8 +16,8 @@ extern runtime WasmFunctionTableGet(
extern runtime WasmFunctionTableSet(
Context, WasmInstanceObject, Smi, Smi, Object): JSAny;
extern runtime ThrowWasmError(Context, Smi): JSAny;
extern runtime Throw(Context, Object): JSAny;
extern runtime ReThrow(Context, Object): JSAny;
extern runtime WasmThrow(Context, Object): JSAny;
extern runtime WasmReThrow(Context, Object): JSAny;
extern runtime WasmTriggerTierUp(Context, WasmInstanceObject): JSAny;
extern runtime WasmStackGuard(Context): JSAny;
extern runtime ThrowWasmStackOverflow(Context): JSAny;
......@@ -193,12 +193,12 @@ builtin WasmRefFunc(index: uint32): Object {
}
builtin WasmThrow(exception: Object): JSAny {
tail runtime::Throw(LoadContextFromFrame(), exception);
tail runtime::WasmThrow(LoadContextFromFrame(), exception);
}
builtin WasmRethrow(exception: Object): JSAny {
if (exception == Null) tail ThrowWasmTrapRethrowNull();
tail runtime::ReThrow(LoadContextFromFrame(), exception);
tail runtime::WasmReThrow(LoadContextFromFrame(), exception);
}
builtin WasmTriggerTierUp(): JSAny {
......
......@@ -1763,6 +1763,7 @@ Object Isolate::UnwindAndFindHandler() {
case StackFrame::WASM: {
if (trap_handler::IsThreadInWasm()) {
// TODO(thibaudm): The flag should be cleared already.
trap_handler::ClearThreadInWasm();
}
......@@ -1778,6 +1779,7 @@ Object Isolate::UnwindAndFindHandler() {
wasm_engine()->code_manager()->LookupCode(frame->pc());
int offset = wasm_frame->LookupExceptionHandlerInTable();
if (offset < 0) break;
wasm_engine()->SampleCatchEvent(this);
// Compute the stack pointer from the frame pointer. This ensures that
// argument slots on the stack are dropped as returning would.
Address return_sp = frame->fp() +
......@@ -1795,10 +1797,7 @@ Object Isolate::UnwindAndFindHandler() {
case StackFrame::WASM_COMPILE_LAZY: {
// Can only fail directly on invocation. This happens if an invalid
// function was validated lazily.
DCHECK_IMPLIES(trap_handler::IsTrapHandlerEnabled(),
trap_handler::IsThreadInWasm());
DCHECK(FLAG_wasm_lazy_validation);
trap_handler::ClearThreadInWasm();
break;
}
......
......@@ -189,6 +189,12 @@ namespace internal {
V8.WasmInstantiateModuleMicroSeconds.wasm, 10000000, MICROSECOND) \
HT(wasm_instantiate_asm_module_time, \
V8.WasmInstantiateModuleMicroSeconds.asm, 10000000, MICROSECOND) \
HT(wasm_time_between_throws, V8.WasmTimeBetweenThrowsMilliseconds, 1000, \
MILLISECOND) \
HT(wasm_time_between_rethrows, V8.WasmTimeBetweenRethrowsMilliseconds, 1000, \
MILLISECOND) \
HT(wasm_time_between_catch, V8.WasmTimeBetweenCatchMilliseconds, 1000, \
MILLISECOND) \
/* Total compilation time incl. caching/parsing for various cache states. */ \
HT(compile_script_with_produce_cache, \
V8.CompileScriptMicroSeconds.ProduceCache, 1000000, MICROSECOND) \
......
......@@ -176,6 +176,26 @@ RUNTIME_FUNCTION(Runtime_WasmThrowCreate) {
return *exception;
}
RUNTIME_FUNCTION(Runtime_WasmThrow) {
// Do not clear the flag in a scope. The unwinder will set it if the exception
// is caught by a wasm frame, otherwise we keep it cleared.
trap_handler::ClearThreadInWasm();
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
isolate->wasm_engine()->SampleThrowEvent(isolate);
return isolate->Throw(args[0]);
}
RUNTIME_FUNCTION(Runtime_WasmReThrow) {
// Do not clear the flag in a scope. The unwinder will set it if the exception
// is caught by a wasm frame, otherwise we keep it cleared.
trap_handler::ClearThreadInWasm();
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
isolate->wasm_engine()->SampleRethrowEvent(isolate);
return isolate->ReThrow(args[0]);
}
RUNTIME_FUNCTION(Runtime_WasmStackGuard) {
ClearThreadInWasmScope wasm_flag;
SealHandleScope shs(isolate);
......
......@@ -580,6 +580,8 @@ namespace internal {
F(WasmMemoryGrow, 2, 1) \
F(WasmStackGuard, 0, 1) \
F(WasmThrowCreate, 2, 1) \
F(WasmThrow, 1, 1) \
F(WasmReThrow, 1, 1) \
F(WasmThrowJSTypeError, 0, 1) \
F(WasmRefFunc, 1, 1) \
F(WasmFunctionTableGet, 3, 1) \
......
......@@ -389,6 +389,11 @@ struct WasmEngine::IsolateInfo {
// Keep new modules in tiered down state.
bool keep_tiered_down = false;
// Elapsed time since last throw/rethrow/catch event.
base::ElapsedTimer throw_timer;
base::ElapsedTimer rethrow_timer;
base::ElapsedTimer catch_timer;
};
struct WasmEngine::NativeModuleInfo {
......@@ -1371,6 +1376,35 @@ WasmEngine::GetBarrierForBackgroundCompile() {
return operations_barrier_;
}
namespace {
void SampleExceptionEvent(base::ElapsedTimer* timer, TimedHistogram* counter) {
if (!timer->IsStarted()) {
timer->Start();
return;
}
counter->AddSample(static_cast<int>(timer->Elapsed().InMilliseconds()));
timer->Restart();
}
} // namespace
void WasmEngine::SampleThrowEvent(Isolate* isolate) {
base::MutexGuard guard(&mutex_);
SampleExceptionEvent(&isolates_[isolate]->throw_timer,
isolate->counters()->wasm_time_between_throws());
}
void WasmEngine::SampleRethrowEvent(Isolate* isolate) {
base::MutexGuard guard(&mutex_);
SampleExceptionEvent(&isolates_[isolate]->rethrow_timer,
isolate->counters()->wasm_time_between_rethrows());
}
void WasmEngine::SampleCatchEvent(Isolate* isolate) {
base::MutexGuard guard(&mutex_);
SampleExceptionEvent(&isolates_[isolate]->catch_timer,
isolate->counters()->wasm_time_between_catch());
}
void WasmEngine::TriggerGC(int8_t gc_sequence_index) {
DCHECK(!mutex_.TryLock());
DCHECK_NULL(current_gc_info_);
......
......@@ -339,6 +339,10 @@ class V8_EXPORT_PRIVATE WasmEngine {
// preventing this object from being destroyed.
std::shared_ptr<OperationsBarrier> GetBarrierForBackgroundCompile();
void SampleThrowEvent(Isolate*);
void SampleRethrowEvent(Isolate*);
void SampleCatchEvent(Isolate*);
// 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