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