• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1--
2-- Copyright 2019 The Android Open Source Project
3--
4-- Licensed under the Apache License, Version 2.0 (the "License");
5-- you may not use this file except in compliance with the License.
6-- You may obtain a copy of the License at
7--
8--     https://www.apache.org/licenses/LICENSE-2.0
9--
10-- Unless required by applicable law or agreed to in writing, software
11-- distributed under the License is distributed on an "AS IS" BASIS,
12-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-- See the License for the specific language governing permissions and
14-- limitations under the License.
15--
16
17-- Create the base tables and views containing the launch spans.
18SELECT IMPORT('android.startup.startups');
19SELECT RUN_METRIC('android/process_metadata.sql');
20
21-- Define the helper functions which will be used throught the remainder
22-- of the metric.
23SELECT RUN_METRIC('android/startup/slice_functions.sql');
24SELECT IMPORT('common.timestamps');
25
26-- Run all the HSC metrics.
27SELECT RUN_METRIC('android/startup/hsc.sql');
28
29-- Define some helper functions related to breaking down thread state
30-- for launches.
31SELECT RUN_METRIC('android/startup/thread_state_breakdown.sql');
32
33-- Define helper functions to break down slices/threads by thread
34-- state.
35SELECT RUN_METRIC('android/startup/mcycles_per_launch.sql');
36
37-- Define helper functions for GC slices.
38SELECT RUN_METRIC('android/startup/gc_slices.sql');
39
40-- Define helper functions for system state.
41SELECT RUN_METRIC('android/startup/system_state.sql');
42
43-- Returns the slices for forked processes. Never present in hot starts.
44-- Prefer this over process start_ts, since the process might have
45-- been preforked.
46SELECT CREATE_VIEW_FUNCTION(
47  'ZYGOTE_FORK_FOR_LAUNCH(startup_id INT)',
48  'ts INT, dur INT',
49  '
50    SELECT slice.ts, slice.dur
51    FROM android_startups l
52    JOIN slice ON (
53      l.ts < slice.ts AND
54      slice.ts + slice.dur < l.ts_end AND
55      STR_SPLIT(slice.name, ": ", 1) = l.package
56    )
57    WHERE l.startup_id = $startup_id AND slice.name GLOB "Start proc: *"
58  '
59);
60
61-- Returns the fully drawn slice proto given a launch id.
62SELECT CREATE_FUNCTION(
63  'REPORT_FULLY_DRAWN_FOR_LAUNCH(startup_id INT)',
64  'PROTO',
65  '
66    SELECT
67      STARTUP_SLICE_PROTO(report_fully_drawn_ts - launch_ts)
68    FROM (
69      SELECT
70        launches.ts AS launch_ts,
71        min(slice.ts) AS report_fully_drawn_ts
72      FROM android_startups launches
73      JOIN android_startup_processes ON (launches.startup_id = android_startup_processes.startup_id)
74      JOIN thread USING (upid)
75      JOIN thread_track USING (utid)
76      JOIN slice ON (slice.track_id = thread_track.id)
77      WHERE
78        slice.name GLOB "reportFullyDrawn*" AND
79        slice.ts >= launches.ts AND
80        launches.startup_id = $startup_id
81    )
82  '
83);
84
85-- Define the view
86DROP VIEW IF EXISTS startup_view;
87CREATE VIEW startup_view AS
88SELECT
89  AndroidStartupMetric_Startup(
90    'startup_id',launches.startup_id,
91    'startup_type', (
92      SELECT lp.startup_type
93      FROM android_startup_processes lp
94      WHERE lp.startup_id =launches.startup_id
95      LIMIT 1
96    ),
97    'package_name', launches.package,
98    'process_name', (
99      SELECT p.name
100      FROM android_startup_processes lp
101      JOIN process p USING (upid)
102      WHERE lp.startup_id =launches.startup_id
103      LIMIT 1
104    ),
105    'process', (
106      SELECT m.metadata
107      FROM process_metadata m
108      JOIN android_startup_processes p USING (upid)
109      WHERE p.startup_id =launches.startup_id
110      LIMIT 1
111    ),
112    'activities', (
113      SELECT RepeatedField(AndroidStartupMetric_Activity(
114        'name', (SELECT STR_SPLIT(s.slice_name, ':', 1)),
115        'method', (SELECT STR_SPLIT(s.slice_name, ':', 0)),
116        'ts_method_start', s.slice_ts
117        ))
118      FROM thread_slices_for_all_launches s
119      WHERE
120        s.startup_id =launches.startup_id
121        AND (s.slice_name GLOB 'performResume:*' OR s.slice_name GLOB 'performCreate:*')
122    ),
123    'long_binder_transactions', (
124      SELECT RepeatedField(
125        AndroidStartupMetric_BinderTransaction(
126          "duration", STARTUP_SLICE_PROTO(s.slice_dur),
127          "thread", s.thread_name,
128          "destination_thread", EXTRACT_ARG(s.arg_set_id, "destination name"),
129          "destination_process", s.process,
130          "flags", EXTRACT_ARG(s.arg_set_id, "flags"),
131          "code", EXTRACT_ARG(s.arg_set_id, "code"),
132          "data_size", EXTRACT_ARG(s.arg_set_id, "data_size")
133        )
134      )
135      FROM ANDROID_BINDER_TRANSACTION_SLICES_FOR_STARTUP(launches.startup_id, 5e7) s
136    ),
137    'zygote_new_process', EXISTS(SELECT TRUE FROM ZYGOTE_FORK_FOR_LAUNCH(launches.startup_id)),
138    'activity_hosting_process_count', (
139      SELECT COUNT(1) FROM android_startup_processes p
140      WHERE p.startup_id =launches.startup_id
141    ),
142    'event_timestamps', AndroidStartupMetric_EventTimestamps(
143      'intent_received', launches.ts,
144      'first_frame', launches.ts_end
145    ),
146    'to_first_frame', AndroidStartupMetric_ToFirstFrame(
147      'dur_ns', launches.dur,
148      'dur_ms', launches.dur / 1e6,
149      'main_thread_by_task_state', AndroidStartupMetric_TaskStateBreakdown(
150        'running_dur_ns', IFNULL(
151          MAIN_THREAD_TIME_FOR_LAUNCH_AND_STATE(launches.startup_id, 'Running'), 0
152        ),
153        'runnable_dur_ns', IFNULL(
154          MAIN_THREAD_TIME_FOR_LAUNCH_IN_RUNNABLE_STATE(launches.startup_id), 0
155        ),
156        'uninterruptible_sleep_dur_ns', IFNULL(
157          MAIN_THREAD_TIME_FOR_LAUNCH_AND_STATE(launches.startup_id, 'D*'), 0
158        ),
159        'interruptible_sleep_dur_ns', IFNULL(
160          MAIN_THREAD_TIME_FOR_LAUNCH_AND_STATE(launches.startup_id, 'S'), 0
161        ),
162        'uninterruptible_io_sleep_dur_ns', IFNULL(
163          MAIN_THREAD_TIME_FOR_LAUNCH_STATE_AND_IO_WAIT(launches.startup_id, 'D*', TRUE), 0
164        ),
165        'uninterruptible_non_io_sleep_dur_ns', IFNULL(
166          MAIN_THREAD_TIME_FOR_LAUNCH_STATE_AND_IO_WAIT(launches.startup_id, 'D*', FALSE), 0
167        )
168
169      ),
170      'mcycles_by_core_type', NULL_IF_EMPTY(AndroidStartupMetric_McyclesByCoreType(
171        'little', MCYCLES_FOR_LAUNCH_AND_CORE_TYPE(launches.startup_id, 'little'),
172        'big', MCYCLES_FOR_LAUNCH_AND_CORE_TYPE(launches.startup_id, 'big'),
173        'bigger', MCYCLES_FOR_LAUNCH_AND_CORE_TYPE(launches.startup_id, 'bigger'),
174        'unknown', MCYCLES_FOR_LAUNCH_AND_CORE_TYPE(launches.startup_id, 'unknown')
175      )),
176      'to_post_fork',
177      LAUNCH_TO_MAIN_THREAD_SLICE_PROTO(launches.startup_id, 'PostFork'),
178      'to_activity_thread_main',
179      LAUNCH_TO_MAIN_THREAD_SLICE_PROTO(launches.startup_id, 'ActivityThreadMain'),
180      'to_bind_application',
181      LAUNCH_TO_MAIN_THREAD_SLICE_PROTO(launches.startup_id, 'bindApplication'),
182      'time_activity_manager', (
183        SELECT STARTUP_SLICE_PROTO(l.ts - launches.ts)
184        FROM internal_startup_events l
185        WHERE l.ts BETWEEN launches.ts AND launches.ts + launches.dur
186      ),
187      'time_post_fork',
188      DUR_SUM_SLICE_PROTO_FOR_LAUNCH(launches.startup_id, 'PostFork'),
189      'time_activity_thread_main',
190      DUR_SUM_SLICE_PROTO_FOR_LAUNCH(launches.startup_id, 'ActivityThreadMain'),
191      'time_bind_application',
192      DUR_SUM_SLICE_PROTO_FOR_LAUNCH(launches.startup_id, 'bindApplication'),
193      'time_activity_start',
194      DUR_SUM_SLICE_PROTO_FOR_LAUNCH(launches.startup_id, 'activityStart'),
195      'time_activity_resume',
196      DUR_SUM_SLICE_PROTO_FOR_LAUNCH(launches.startup_id, 'activityResume'),
197      'time_activity_restart',
198      DUR_SUM_SLICE_PROTO_FOR_LAUNCH(launches.startup_id, 'activityRestart'),
199      'time_choreographer',
200      DUR_SUM_SLICE_PROTO_FOR_LAUNCH(launches.startup_id, 'Choreographer#doFrame*'),
201      'time_inflate',
202      DUR_SUM_SLICE_PROTO_FOR_LAUNCH(launches.startup_id, 'inflate'),
203      'time_get_resources',
204      DUR_SUM_SLICE_PROTO_FOR_LAUNCH(launches.startup_id, 'ResourcesManager#getResources'),
205      'time_dex_open',
206      DUR_SUM_SLICE_PROTO_FOR_LAUNCH(launches.startup_id, 'OpenDexFilesFromOat*'),
207      'time_verify_class',
208      DUR_SUM_SLICE_PROTO_FOR_LAUNCH(launches.startup_id, 'VerifyClass*'),
209      'time_gc_total', (
210        SELECT NULL_IF_EMPTY(STARTUP_SLICE_PROTO(TOTAL_GC_TIME_BY_LAUNCH(launches.startup_id)))
211      ),
212      'time_dex_open_thread_main',
213      DUR_SUM_MAIN_THREAD_SLICE_PROTO_FOR_LAUNCH(
214        launches.startup_id,
215        'OpenDexFilesFromOat*'),
216      'time_dlopen_thread_main',
217      DUR_SUM_MAIN_THREAD_SLICE_PROTO_FOR_LAUNCH(
218        launches.startup_id,
219        'dlopen:*.so'),
220      'time_lock_contention_thread_main',
221      DUR_SUM_MAIN_THREAD_SLICE_PROTO_FOR_LAUNCH(
222        launches.startup_id,
223        'Lock contention on*'
224      ),
225      'time_monitor_contention_thread_main',
226      DUR_SUM_MAIN_THREAD_SLICE_PROTO_FOR_LAUNCH(
227        launches.startup_id,
228        'Lock contention on a monitor*'
229      ),
230      'time_before_start_process', (
231        SELECT STARTUP_SLICE_PROTO(ts - launches.ts)
232        FROM ZYGOTE_FORK_FOR_LAUNCH(launches.startup_id)
233      ),
234      'time_jit_thread_pool_on_cpu', NULL_IF_EMPTY(STARTUP_SLICE_PROTO(
235        THREAD_TIME_FOR_LAUNCH_STATE_AND_THREAD(
236         launches.startup_id,
237          'Running',
238          'Jit thread pool'
239        )
240      )),
241      'time_gc_on_cpu', (
242        SELECT STARTUP_SLICE_PROTO(sum_dur)
243        FROM running_gc_slices_materialized
244        WHERE launches.startup_id = startup_id
245      ),
246      'time_during_start_process', (
247        SELECT STARTUP_SLICE_PROTO(dur)
248        FROM ZYGOTE_FORK_FOR_LAUNCH(launches.startup_id)
249      ),
250      'jit_compiled_methods', (
251        SELECT IIF(COUNT(1) = 0, NULL, COUNT(1))
252        FROM ANDROID_SLICES_FOR_STARTUP_AND_SLICE_NAME(launches.startup_id, 'JIT compiling*')
253        WHERE thread_name = 'Jit thread pool'
254      ),
255      'other_processes_spawned_count', (
256        SELECT COUNT(1)
257        FROM process
258        WHERE
259          process.start_ts BETWEEN launches.ts AND launches.ts + launches.dur
260          AND process.upid NOT IN (
261            SELECT upid FROM android_startup_processes
262            WHERE android_startup_processes.startup_id =launches.startup_id
263          )
264      )
265    ),
266    'hsc', NULL_IF_EMPTY(AndroidStartupMetric_HscMetrics(
267      'full_startup', (
268        SELECT STARTUP_SLICE_PROTO(h.ts_total)
269        FROM hsc_based_startup_times h
270        WHERE h.id =launches.startup_id
271      )
272    )),
273    'report_fully_drawn', NULL_IF_EMPTY(REPORT_FULLY_DRAWN_FOR_LAUNCH(launches.startup_id)),
274    'optimization_status', (
275      SELECT RepeatedField(AndroidStartupMetric_OptimizationStatus(
276        'location', SUBSTR(STR_SPLIT(slice_name, ' status=', 0), LENGTH('location=') + 1),
277        'odex_status', STR_SPLIT(STR_SPLIT(slice_name, ' status=', 1), ' filter=', 0),
278        'compilation_filter', STR_SPLIT(STR_SPLIT(slice_name, ' filter=', 1), ' reason=', 0),
279        'compilation_reason', STR_SPLIT(slice_name, ' reason=', 1)
280        ))
281      FROM (
282        SELECT *
283        FROM ANDROID_SLICES_FOR_STARTUP_AND_SLICE_NAME(
284         launches.startup_id,
285          'location=* status=* filter=* reason=*'
286        )
287        ORDER BY slice_name
288      )
289    ),
290    'verify_class', (
291      SELECT RepeatedField(AndroidStartupMetric_VerifyClass(
292        'name', STR_SPLIT(slice_name, "VerifyClass ", 1),
293        'dur_ns', slice_dur))
294      FROM android_thread_slices_for_all_startups
295      WHERE startup_id = launches.startup_id AND slice_name GLOB "VerifyClass *"
296      ORDER BY slice_dur DESC
297      LIMIT 5
298    ),
299    'startup_concurrent_to_launch', (
300      SELECT RepeatedField(package)
301      FROM android_startups l
302      WHERE l.startup_id != launches.startup_id
303        AND IS_SPANS_OVERLAPPING(l.ts, l.ts_end, launches.ts, launches.ts_end)
304    ),
305    'dlopen_file', (
306      SELECT RepeatedField(STR_SPLIT(slice_name, "dlopen: ", 1))
307      FROM android_thread_slices_for_all_startups s
308      WHERE startup_id = launches.startup_id AND slice_name GLOB "dlopen: *.so"
309    ),
310    'system_state', AndroidStartupMetric_SystemState(
311      'dex2oat_running',
312      DUR_OF_PROCESS_RUNNING_CONCURRENT_TO_LAUNCH(launches.startup_id, '*dex2oat64') > 0,
313      'installd_running',
314      DUR_OF_PROCESS_RUNNING_CONCURRENT_TO_LAUNCH(launches.startup_id, '*installd') > 0,
315      'broadcast_dispatched_count',
316      COUNT_SLICES_CONCURRENT_TO_LAUNCH(launches.startup_id, 'Broadcast dispatched*'),
317      'broadcast_received_count',
318      COUNT_SLICES_CONCURRENT_TO_LAUNCH(launches.startup_id, 'broadcastReceiveReg*'),
319      'most_active_non_launch_processes',
320      N_MOST_ACTIVE_PROCESS_NAMES_FOR_LAUNCH(launches.startup_id),
321      'installd_dur_ns',
322      DUR_OF_PROCESS_RUNNING_CONCURRENT_TO_LAUNCH(launches.startup_id, '*installd'),
323      'dex2oat_dur_ns',
324      DUR_OF_PROCESS_RUNNING_CONCURRENT_TO_LAUNCH(launches.startup_id, '*dex2oat64')
325    ),
326    'slow_start_reason', (SELECT RepeatedField(slow_cause)
327      FROM (
328        SELECT 'No baseline or cloud profiles' AS slow_cause
329        WHERE MISSING_BASELINE_PROFILE_FOR_LAUNCH(launches.startup_id, launches.package)
330
331        UNION ALL
332        SELECT 'Optimized artifacts missing, run from apk'
333        WHERE  RUN_FROM_APK_FOR_LAUNCH(launches.startup_id)
334
335        UNION ALL
336        SELECT 'Unlock running during launch'
337        WHERE IS_UNLOCK_RUNNING_DURING_LAUNCH(launches.startup_id)
338
339        UNION ALL
340        SELECT 'App in debuggable mode'
341        WHERE IS_PROCESS_DEBUGGABLE(launches.package)
342
343        UNION ALL
344        SELECT 'GC Activity'
345        WHERE TOTAL_GC_TIME_BY_LAUNCH(launches.startup_id) > 0
346
347        UNION ALL
348        SELECT 'dex2oat running during launch' AS slow_cause
349        WHERE
350          DUR_OF_PROCESS_RUNNING_CONCURRENT_TO_LAUNCH(launches.startup_id, '*dex2oat64') > 0
351
352        UNION ALL
353        SELECT 'installd running during launch' AS slow_cause
354        WHERE
355          DUR_OF_PROCESS_RUNNING_CONCURRENT_TO_LAUNCH(launches.startup_id, '*installd') > 0
356
357        UNION ALL
358        SELECT 'Main Thread - Time spent in Running state'
359          AS slow_cause
360        WHERE
361          MAIN_THREAD_TIME_FOR_LAUNCH_AND_STATE(launches.startup_id, 'Running') > launches.dur * 0.8
362
363        UNION ALL
364        SELECT 'Main Thread - Time spent in Runnable state'
365          AS slow_cause
366        WHERE
367          MAIN_THREAD_TIME_FOR_LAUNCH_IN_RUNNABLE_STATE(launches.startup_id) > launches.dur * 0.15
368
369        UNION ALL
370        SELECT 'Main Thread - Time spent in interruptible sleep state'
371          AS slow_cause
372        WHERE MAIN_THREAD_TIME_FOR_LAUNCH_AND_STATE(launches.startup_id, 'S') > 2900e6
373
374        UNION ALL
375        SELECT 'Main Thread - Time spent in Blocking I/O'
376        WHERE MAIN_THREAD_TIME_FOR_LAUNCH_STATE_AND_IO_WAIT(launches.startup_id, 'D*', TRUE) > 155e6
377
378        UNION ALL
379        SELECT 'Main Thread - Time spent in OpenDexFilesFromOat*'
380          AS slow_cause
381        WHERE ANDROID_SUM_DUR_ON_MAIN_THREAD_FOR_STARTUP_AND_SLICE(
382          launches.startup_id, 'OpenDexFilesFromOat*') > launches.dur * 0.2
383
384        UNION ALL
385        SELECT 'Time spent in bindApplication'
386          AS slow_cause
387        WHERE ANDROID_SUM_DUR_FOR_STARTUP_AND_SLICE(launches.startup_id, 'bindApplication') > 1250e6
388
389        UNION ALL
390        SELECT 'Time spent in view inflation'
391          AS slow_cause
392        WHERE ANDROID_SUM_DUR_FOR_STARTUP_AND_SLICE(launches.startup_id, 'inflate') > 450e6
393
394        UNION ALL
395        SELECT 'Time spent in ResourcesManager#getResources'
396          AS slow_cause
397        WHERE ANDROID_SUM_DUR_FOR_STARTUP_AND_SLICE(
398          launches.startup_id, 'ResourcesManager#getResources') > 130e6
399
400        UNION ALL
401        SELECT 'Time spent verifying classes'
402          AS slow_cause
403        WHERE
404          ANDROID_SUM_DUR_FOR_STARTUP_AND_SLICE(launches.startup_id, 'VerifyClass*')
405            > launches.dur * 0.15
406
407        UNION ALL
408        SELECT 'Potential CPU contention with another process' AS slow_cause
409        WHERE MAIN_THREAD_TIME_FOR_LAUNCH_IN_RUNNABLE_STATE(launches.startup_id) > 100e6
410          AND MOST_ACTIVE_PROCESS_FOR_LAUNCH(launches.startup_id) IS NOT NULL
411
412        UNION ALL
413        SELECT 'JIT Activity'
414          AS slow_cause
415        WHERE THREAD_TIME_FOR_LAUNCH_STATE_AND_THREAD(
416          launches.startup_id,
417          'Running',
418          'Jit thread pool'
419        ) > 100e6
420
421        UNION ALL
422        SELECT 'Main Thread - Lock contention'
423          AS slow_cause
424        WHERE ANDROID_SUM_DUR_ON_MAIN_THREAD_FOR_STARTUP_AND_SLICE(
425          launches.startup_id,
426          'Lock contention on*'
427        ) > launches.dur * 0.2
428
429        UNION ALL
430        SELECT 'Main Thread - Monitor contention'
431          AS slow_cause
432        WHERE ANDROID_SUM_DUR_ON_MAIN_THREAD_FOR_STARTUP_AND_SLICE(
433          launches.startup_id,
434          'Lock contention on a monitor*'
435        ) > launches.dur * 0.15
436
437        UNION ALL
438        SELECT 'JIT compiled methods'
439        WHERE (
440          SELECT COUNT(1)
441          FROM ANDROID_SLICES_FOR_STARTUP_AND_SLICE_NAME(launches.startup_id, 'JIT compiling*')
442          WHERE thread_name = 'Jit thread pool'
443        ) > 65
444
445        UNION ALL
446        SELECT 'Broadcast dispatched count'
447        WHERE COUNT_SLICES_CONCURRENT_TO_LAUNCH(
448          launches.startup_id,
449          'Broadcast dispatched*'
450        ) > 15
451
452        UNION ALL
453        SELECT 'Broadcast received count'
454        WHERE COUNT_SLICES_CONCURRENT_TO_LAUNCH(
455          launches.startup_id,
456          'broadcastReceiveReg*'
457        ) > 50
458
459        UNION ALL
460        SELECT 'Startup running concurrent to launch'
461        WHERE EXISTS(
462          SELECT package
463          FROM android_startups l
464          WHERE l.startup_id != launches.startup_id
465            AND IS_SPANS_OVERLAPPING(l.ts, l.ts_end, launches.ts, launches.ts_end)
466        )
467
468        UNION ALL
469        SELECT 'Main Thread - Binder transactions blocked'
470        WHERE (
471          SELECT COUNT(1)
472          FROM BINDER_TRANSACTION_REPLY_SLICES_FOR_LAUNCH(launches.startup_id, 2e7)
473        ) > 0
474
475      )
476    )
477  ) AS startup
478FROM android_startups launches;
479
480DROP VIEW IF EXISTS android_startup_event;
481CREATE VIEW android_startup_event AS
482SELECT
483  'slice' AS track_type,
484  'Android App Startups' AS track_name,
485  l.ts AS ts,
486  l.dur AS dur,
487  l.package AS slice_name
488FROM android_startups l;
489
490DROP VIEW IF EXISTS android_startup_output;
491CREATE VIEW android_startup_output AS
492SELECT
493  AndroidStartupMetric(
494    'startup', (
495      SELECT RepeatedField(startup) FROM startup_view
496    )
497  );
498