perfetto-ui: Fix js stack overflow
Fix a couple of instances where we used:
someArray.push(...someOtherArray);
to append all elements from someOtherArray to someArray as
this (I now realaise) is an anti-pattern. If someOtherArray is very
large this code will cause a stackoverflow attempting to pass all the
elements as arguments.
Also fix an N+1 query pattern in trace_controller that was slow when
there are many tracks.
Bug: 144595839
Change-Id: I5fa8773af66adb617578795c68da8ccfe1035504
diff --git a/ui/src/controller/globals.ts b/ui/src/controller/globals.ts
index 1dde45d..f8b51b3 100644
--- a/ui/src/controller/globals.ts
+++ b/ui/src/controller/globals.ts
@@ -72,8 +72,14 @@
if (iter > 100) throw new Error('Controllers are stuck in a livelock');
const actions = this._queuedActions;
this._queuedActions = new Array<DeferredAction>();
+
for (const action of actions) {
- patches.push(...this.applyAction(action));
+ const originalLength = patches.length;
+ const morePatches = this.applyAction(action);
+ patches.length += morePatches.length;
+ for (let i = 0; i < morePatches.length; ++i) {
+ patches[i + originalLength] = morePatches[i];
+ }
}
this._runningControllers = true;
try {
@@ -109,7 +115,11 @@
(StateActions as any)[action.type](draft, action.args);
},
(morePatches, _) => {
- patches.push(...morePatches);
+ const originalLength = patches.length;
+ patches.length += morePatches.length;
+ for (let i = 0; i < morePatches.length; ++i) {
+ patches[i + originalLength] = morePatches[i];
+ }
});
return patches;
}
diff --git a/ui/src/controller/trace_controller.ts b/ui/src/controller/trace_controller.ts
index ffa27e1..1afdea3 100644
--- a/ui/src/controller/trace_controller.ts
+++ b/ui/src/controller/trace_controller.ts
@@ -534,9 +534,13 @@
pid,
thread.name as threadName,
process.name as processName,
- total_dur as totalDur
+ total_dur as totalDur,
+ ifnull(has_sched, false) as hasSched
from
thread
+ left join (select utid, count(1), true as has_sched
+ from sched group by utid
+ ) using(utid)
left join process using(upid)
left join (select upid, sum(dur) as total_dur
from sched join thread using(utid)
@@ -558,6 +562,7 @@
threadName: STR_NULL,
processName: STR_NULL,
totalDur: NUM_NULL,
+ hasSched: NUM,
})) {
const utid = row.utid;
const tid = row.tid;
@@ -566,9 +571,7 @@
const threadName = row.threadName;
const processName = row.processName;
const hasSchedEvents = !!row.totalDur;
- const threadSched =
- await engine.query(`select count(1) from sched where utid = ${utid}`);
- const threadHasSched = threadSched.columns[0].longValues![0] > 0;
+ const threadHasSched = !!row.hasSched;
const threadTrack =
utid === null ? undefined : utidToThreadTrack.get(utid);