Bug 1635783 - Add a fast path for stack normalization. r=rhunt
authorLars T Hansen <lhansen@mozilla.com>
Mon, 11 May 2020 14:30:44 +0000
changeset 529284 ec2d66612ed02cfb1e458f8780ba3aaf8777e28a
parent 529283 d4756b84d2d52774ce2b93e61774a4aa9c8dde78
child 529285 1706d4d54ec68fae1280305b70a02cb24c16ff68
push id37406
push userdluca@mozilla.com
push dateTue, 12 May 2020 09:34:21 +0000
treeherdermozilla-central@1706d4d54ec6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrhunt
bugs1635783
milestone78.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1635783 - Add a fast path for stack normalization. r=rhunt Stack normalization is uber-slow on emulator because it relies on regexes that are compiled to native instructions which are then emulated. That makes stack normalization very slow too, and as it's very hot some tests will time out nearly always. This patch inserts a simple cache for previously matched strings in stack normalization to avoid the regex engine altogether. This speeds up normalization and hence stack matching greatly (I observed a factor of four speedup per test iteration on an arm-sim noopt debug build for ion-error-ool.js). I also attempted some other fixes (filtering on simple strings, avoiding regex.replace, etc) but caching is by far the most effective fix, and with caching in place the other fixes still don't really move the needle. Depends on D74220 Differential Revision: https://phabricator.services.mozilla.com/D74607
js/src/jit-test/lib/wasm.js
--- a/js/src/jit-test/lib/wasm.js
+++ b/js/src/jit-test/lib/wasm.js
@@ -185,16 +185,22 @@ const WasmHelpers = {};
     try {
         enableSingleStepProfiling();
         disableSingleStepProfiling();
         enabled = true;
     } catch (e) {}
     WasmHelpers.isSingleStepProfilingEnabled = enabled;
 })();
 
+// The cache of matched and unmatched strings seriously speeds up matching on
+// the emulators and makes tests time out less often.
+
+var matched = {};
+var unmatched = {};
+
 WasmHelpers._normalizeStack = (stack, preciseStacks) => {
     var wasmFrameTypes = [
         {re:/^jit call to int64 wasm function$/,                          sub:"i64>"},
         {re:/^out-of-line coercion for jit entry arguments \(in wasm\)$/, sub:"ool>"},
         {re:/^wasm-function\[(\d+)\] \(.*\)$/,                            sub:"$1"},
         {re:/^(fast|slow) exit trampoline (to native )?\(in wasm\)$/,     sub:"<"},
         {re:/^call to[ asm.js]? native (.*) \(in wasm\)$/,                sub:"$1"},
         {re:/ \(in wasm\)$/,                                              sub:""}
@@ -210,23 +216,34 @@ WasmHelpers._normalizeStack = (stack, pr
         entryRegexps = [
             {re:/^(fast|slow) entry trampoline \(in wasm\)$/,             sub:">"}
         ];
     }
     wasmFrameTypes = entryRegexps.concat(wasmFrameTypes);
 
     var framesIn = stack.split(',');
     var framesOut = [];
+  outer:
     for (let frame of framesIn) {
+        if (unmatched[frame])
+            continue;
+        let probe = matched[frame];
+        if (probe !== undefined) {
+            framesOut.push(probe);
+            continue;
+        }
         for (let {re, sub} of wasmFrameTypes) {
             if (re.test(frame)) {
-                framesOut.push(frame.replace(re, sub));
-                break;
+                let repr = frame.replace(re, sub);
+                framesOut.push(repr);
+                matched[frame] = repr;
+                continue outer;
             }
         }
+        unmatched[frame] = true;
     }
 
     return framesOut.join(',');
 };
 
 WasmHelpers._removeAdjacentDuplicates = array => {
     if (array.length < 2)
         return;