Merge "[ui] Prettier missing tracks e.g. when loading from permalink." into main
diff --git a/src/trace_processor/perfetto_sql/engine/created_function.cc b/src/trace_processor/perfetto_sql/engine/created_function.cc
index 162dbc6..9c32a97 100644
--- a/src/trace_processor/perfetto_sql/engine/created_function.cc
+++ b/src/trace_processor/perfetto_sql/engine/created_function.cc
@@ -587,6 +587,10 @@
                                   SqlValue& out,
                                   Destructors&) {
   State* state = static_cast<State*>(ctx);
+
+  // Enter the function and ensure that we have a statement allocated.
+  RETURN_IF_ERROR(state->PushStackEntry());
+
   if (argc != state->prototype().arguments.size()) {
     return base::ErrStatus(
         "%s: invalid number of args; expected %zu, received %zu",
@@ -608,9 +612,6 @@
     }
   }
 
-  // Enter the function and ensure that we have a statement allocated.
-  RETURN_IF_ERROR(state->PushStackEntry());
-
   std::optional<Memoizer::MemoizedArgs> memoized_args =
       Memoizer::AsMemoizedArgs(argc, argv);
 
diff --git a/tools/install-build-deps b/tools/install-build-deps
index c3822f6..fd17b81 100755
--- a/tools/install-build-deps
+++ b/tools/install-build-deps
@@ -63,7 +63,7 @@
     'buildtools/test_data',  # Moved to test/data by r.android.com/1539381 .
     'buildtools/d8',  # Removed by r.android.com/1424334 .
 
-    # Build toools moved to third_party/ by r.android.com/2327602 .
+    # Build tools moved to third_party/ by r.android.com/2327602 .
     'buildtools/mac/clang-format',
     'buildtools/mac/gn',
     'buildtools/mac/ninja',
@@ -95,6 +95,11 @@
         'f706aaa0676e3e22f5fc9ca482295d7caee8535d1869f99efa2358177b64f5cd',
         'linux', 'x64'),
     Dependency(
+        'third_party/gn/gn',
+        'https://storage.googleapis.com/perfetto/gn-linux-arm64-1968-0725d782',
+        'c2a372cd4f911028d8bc351fbf24835c9b1194fcc92beadf6c5a2b3addae973c',
+        'linux', 'arm64'),
+    Dependency(
         'third_party/gn/gn.exe',
         'https://storage.googleapis.com/perfetto/gn-win-1968-0725d782',
         '001f777f023c7a6959c778fb3a6b6cfc63f6baef953410ecdeaec350fb12285b',
@@ -150,6 +155,11 @@
         'https://storage.googleapis.com/perfetto/ninja-win-182',
         '09ced0fcd1a4dec7d1b798a2cf9ce5d20e5d2fbc2337343827f192ce47d0f491',
         'windows', 'x64'),
+    Dependency(
+        'third_party/ninja/ninja',
+        'https://storage.googleapis.com/perfetto/ninja-linux-arm64-1111',
+        '05031a734ec4310a51b2cfe9f0096b26fce25ab4ff19e5b51abe6371de066cc5',
+        'linux', 'arm64'),
 
     # Keep the revision in sync with Chrome's PACKAGE_VERSION in
     # tools/clang/scripts/update.py.
@@ -463,6 +473,8 @@
   arch = machine()
   if arch == 'arm64':
     return 'arm64'
+  elif arch == 'aarch64':
+    return 'arm64'
   else:
     # Assume everything else is x64 matching previous behaviour.
     return 'x64'
diff --git a/ui/src/plugins/dev.perfetto.AndroidPerf/index.ts b/ui/src/plugins/dev.perfetto.AndroidPerf/index.ts
index 7658fb6..a521724 100644
--- a/ui/src/plugins/dev.perfetto.AndroidPerf/index.ts
+++ b/ui/src/plugins/dev.perfetto.AndroidPerf/index.ts
@@ -58,6 +58,59 @@
            SELECT * FROM android_binder_graph(-1000, 1000, -1000, 1000)`,
           'all process binder graph'),
     });
+
+    ctx.registerCommand({
+      id: 'dev.perfetto.AndroidPerf#ThreadClusterDistribution',
+      name: 'Run query: runtime cluster distribution for a thread',
+      callback: async (tid) => {
+        if (tid === undefined) {
+          tid = prompt('Enter a thread tid', '');
+          if (tid === null) return;
+        }
+        ctx.tabs.openQuery(`
+          INCLUDE PERFETTO MODULE common.cpus;
+          WITH
+            total_runtime AS (
+              SELECT sum(dur) AS total_runtime
+              FROM sched s
+              LEFT JOIN thread t
+                USING (utid)
+              WHERE t.tid = ${tid}
+            )
+            SELECT
+              c.size AS cluster,
+              sum(dur)/1e6 AS total_dur_ms,
+              sum(dur) * 1.0 / (SELECT * FROM total_runtime) AS percentage
+            FROM sched s
+            LEFT JOIN thread t
+              USING (utid)
+            LEFT JOIN cpus c
+              ON s.cpu = c.cpu_index
+            WHERE t.tid = ${tid}
+            GROUP BY 1`, `runtime cluster distrubtion for tid ${tid}`);
+      },
+    });
+
+    ctx.registerCommand({
+      id: 'dev.perfetto.AndroidPerf#SchedLatency',
+      name: 'Run query: top 50 sched latency for a thread',
+      callback: async (tid) => {
+        if (tid === undefined) {
+          tid = prompt('Enter a thread tid', '');
+          if (tid === null) return;
+        }
+        ctx.tabs.openQuery(`
+          SELECT ts.*, t.tid, t.name, tt.id AS track_id
+          FROM thread_state ts
+          LEFT JOIN thread_track tt
+           USING (utid)
+          LEFT JOIN thread t
+           USING (utid)
+          WHERE ts.state IN ('R', 'R+') AND tid = ${tid}
+           ORDER BY dur DESC
+          LIMIT 50`, `top 50 sched latency slice for tid ${tid}`);
+      },
+    });
   }
 }
 
diff --git a/ui/src/plugins/dev.perfetto.AndroidPerfTraceCounters/OWNERS b/ui/src/plugins/dev.perfetto.AndroidPerfTraceCounters/OWNERS
new file mode 100644
index 0000000..e5632b1
--- /dev/null
+++ b/ui/src/plugins/dev.perfetto.AndroidPerfTraceCounters/OWNERS
@@ -0,0 +1 @@
+lukechang@google.com
diff --git a/ui/src/plugins/dev.perfetto.AndroidPerfTraceCounters/index.ts b/ui/src/plugins/dev.perfetto.AndroidPerfTraceCounters/index.ts
new file mode 100644
index 0000000..46fbb46
--- /dev/null
+++ b/ui/src/plugins/dev.perfetto.AndroidPerfTraceCounters/index.ts
@@ -0,0 +1,109 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {
+  Plugin,
+  PluginContext,
+  PluginContextTrace,
+  PluginDescriptor,
+} from '../../public';
+import {addDebugSliceTrack} from '../../tracks/debug/slice_track';
+
+class AndroidPerfTraceCounters implements Plugin {
+
+  onActivate(_: PluginContext): void {}
+
+  async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
+    ctx.registerCommand({
+      id: 'dev.perfetto.AndroidPerfTraceCounters#ThreadRuntimeIPC',
+      name: 'Add a track to show a thread runtime ipc',
+      callback: async (tid) => {
+        if (tid === undefined) {
+          tid = prompt('Enter a thread tid', '');
+          if (tid === null) return;
+        }
+        const sql_prefix = `
+WITH
+  sched_switch_ipc AS (
+    SELECT
+      ts,
+      EXTRACT_ARG(arg_set_id, 'prev_pid') AS tid,
+      EXTRACT_ARG(arg_set_id, 'prev_comm') AS thread_name,
+      EXTRACT_ARG(arg_set_id, 'inst') / (EXTRACT_ARG(arg_set_id, 'cyc') * 1.0) AS ipc,
+      EXTRACT_ARG(arg_set_id, 'inst') AS instruction,
+      EXTRACT_ARG(arg_set_id, 'cyc') AS cycle,
+      EXTRACT_ARG(arg_set_id, 'stallbm') AS stall_backend_mem,
+      EXTRACT_ARG(arg_set_id, 'l3dm') AS l3_cache_miss
+    FROM ftrace_event
+    WHERE name = 'sched_switch_with_ctrs' AND tid = ${tid}
+  ),
+  target_thread_sched_slice AS (
+    SELECT s.*, t.tid, t.name FROM sched s LEFT JOIN thread t USING (utid) WHERE t.tid = ${tid}
+  ),
+  target_thread_ipc_slice AS (
+    SELECT
+      (
+        SELECT
+          ts
+        FROM target_thread_sched_slice ts
+        WHERE ts.tid = ssi.tid AND ts.ts < ssi.ts
+        ORDER BY ts.ts DESC
+        LIMIT 1
+      ) AS ts,
+      (
+        SELECT
+          dur
+        FROM target_thread_sched_slice ts
+        WHERE ts.tid = ssi.tid AND ts.ts < ssi.ts
+        ORDER BY ts.ts DESC
+        LIMIT 1
+      ) AS dur,
+      ssi.ipc,
+      ssi.instruction,
+      ssi.cycle,
+      ssi.stall_backend_mem,
+      ssi.l3_cache_miss
+    FROM sched_switch_ipc ssi
+  )
+`
+
+        await addDebugSliceTrack(
+          ctx.engine,
+          {
+            sqlSource: sql_prefix + `
+SELECT * FROM target_thread_ipc_slice WHERE ts IS NOT NULL`,
+          },
+          'Rutime IPC:' + tid,
+          {ts: 'ts', dur: 'dur', name: 'ipc'},
+          ['instruction', 'cycle', 'stall_backend_mem', 'l3_cache_miss' ],
+        );
+        ctx.tabs.openQuery(sql_prefix + `
+SELECT
+  (sum(instruction) * 1.0 / sum(cycle)*1.0) AS avg_ipc,
+  sum(dur)/1e6 as total_runtime_ms,
+  sum(instruction) AS total_instructions,
+  sum(cycle) AS total_cycles,
+  sum(stall_backend_mem) as total_stall_backend_mem,
+  sum(l3_cache_miss) as total_l3_cache_miss
+FROM target_thread_ipc_slice WHERE ts IS NOT NULL`,
+          'target thread ipc statistic');
+      },
+    });
+  }
+}
+
+export const plugin: PluginDescriptor = {
+  pluginId: 'dev.perfetto.AndroidPerfTraceCounters',
+  plugin: AndroidPerfTraceCounters,
+};