• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1--
2-- Copyright 2024 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
16INCLUDE PERFETTO MODULE android.memory.heap_graph.excluded_refs;
17
18INCLUDE PERFETTO MODULE android.memory.heap_graph.helpers;
19
20INCLUDE PERFETTO MODULE graphs.search;
21
22-- Converts the heap graph into a tree by performing a BFS on the graph from
23-- the roots. This basically ends up with all paths being the shortest path
24-- from the root to the node (with lower ids being picked in the case of ties).
25CREATE PERFETTO TABLE _heap_graph_object_min_depth_tree AS
26SELECT
27  node_id AS id,
28  parent_node_id AS parent_id
29FROM graph_reachable_bfs!(
30  (
31    SELECT owner_id AS source_node_id, owned_id AS dest_node_id
32    FROM heap_graph_reference ref
33    WHERE ref.id NOT IN _excluded_refs AND ref.owned_id IS NOT NULL
34    ORDER BY ref.owned_id
35  ),
36  (
37    SELECT id AS node_id
38    FROM heap_graph_object
39    WHERE root_type IS NOT NULL
40  )
41)
42ORDER BY
43  id;
44
45CREATE PERFETTO TABLE _heap_graph_path_hashes AS
46SELECT
47  *
48FROM _heap_graph_type_path_hash!(_heap_graph_object_min_depth_tree);
49
50CREATE PERFETTO TABLE _heap_graph_path_hashes_aggregated AS
51SELECT
52  *
53FROM _heap_graph_path_hash_aggregate!(_heap_graph_path_hashes);
54
55CREATE PERFETTO TABLE _heap_graph_class_tree AS
56SELECT
57  *
58FROM _heap_graph_path_hashes_to_class_tree!(_heap_graph_path_hashes_aggregated);
59
60CREATE PERFETTO MACRO _heap_graph_object_references_agg(
61    path_hashes TableOrSubquery,
62    path_hash_values TableOrSubquery
63)
64RETURNS TableOrSubquery AS
65(
66  WITH
67    _path_hashes AS (
68      SELECT
69        *
70      FROM $path_hashes
71      JOIN $path_hash_values
72        USING (path_hash)
73    )
74  SELECT
75    path_hash,
76    c.name AS class_name,
77    count(r.owned_id) AS outgoing_reference_count,
78    o.*
79  FROM _path_hashes AS h
80  JOIN heap_graph_object AS o
81    ON h.id = o.id
82  JOIN heap_graph_class AS c
83    ON o.type_id = c.id
84  JOIN heap_graph_reference AS r
85    ON r.owner_id = o.id
86  GROUP BY
87    o.id
88  ORDER BY
89    outgoing_reference_count DESC
90);
91
92CREATE PERFETTO MACRO _heap_graph_incoming_references_agg(
93    path_hashes TableOrSubquery,
94    path_hash_values TableOrSubquery
95)
96RETURNS TableOrSubquery AS
97(
98  WITH
99    _path_hashes AS (
100      SELECT
101        *
102      FROM $path_hashes
103      JOIN $path_hash_values
104        USING (path_hash)
105    )
106  SELECT
107    path_hash,
108    c.name AS class_name,
109    r.field_name,
110    r.field_type_name,
111    src.*
112  FROM _path_hashes AS h
113  JOIN heap_graph_object AS dst
114    ON h.id = dst.id
115  JOIN heap_graph_reference AS r
116    ON r.owned_id = dst.id
117  JOIN heap_graph_object AS src
118    ON r.owner_id = src.id
119  JOIN heap_graph_class AS c
120    ON src.type_id = c.id
121  ORDER BY
122    self_size DESC
123);
124
125CREATE PERFETTO MACRO _heap_graph_outgoing_references_agg(
126    path_hashes TableOrSubquery,
127    path_hash_values TableOrSubquery
128)
129RETURNS TableOrSubquery AS
130(
131  WITH
132    _path_hashes AS (
133      SELECT
134        *
135      FROM $path_hashes
136      JOIN $path_hash_values
137        USING (path_hash)
138    )
139  SELECT
140    path_hash,
141    c.name AS class_name,
142    r.field_name,
143    r.field_type_name,
144    dst.*
145  FROM _path_hashes AS h
146  JOIN heap_graph_object AS src
147    ON h.id = src.id
148  JOIN heap_graph_reference AS r
149    ON r.owner_id = src.id
150  JOIN heap_graph_object AS dst
151    ON r.owned_id = dst.id
152  JOIN heap_graph_class AS c
153    ON dst.type_id = c.id
154  ORDER BY
155    dst.self_size DESC
156);
157
158CREATE PERFETTO MACRO _heap_graph_retained_object_count_agg(
159    path_hashes TableOrSubquery,
160    path_hash_values TableOrSubquery
161)
162RETURNS TableOrSubquery AS
163(
164  SELECT
165    c.name AS class_name,
166    o.heap_type,
167    o.root_type,
168    o.reachable,
169    sum(o.self_size) AS total_size,
170    sum(o.native_size) AS total_native_size,
171    count() AS count
172  FROM graph_reachable_bfs
173    !(
174      (
175        SELECT
176          IFNULL(parent_id, id) AS source_node_id,
177          IFNULL(id, parent_id) AS dest_node_id
178        FROM _heap_graph_object_min_depth_tree
179      ),
180      (
181        SELECT o.id AS node_id
182        FROM $path_hashes h
183        JOIN heap_graph_object o
184          ON h.id = o.id
185        JOIN heap_graph_class c
186          ON o.type_id = c.id
187        JOIN $path_hash_values USING(path_hash)
188      )) AS b
189  JOIN heap_graph_object AS o
190    ON b.node_id = o.id
191  JOIN heap_graph_class AS c
192    ON o.type_id = c.id
193  GROUP BY
194    class_name,
195    heap_type,
196    root_type,
197    reachable
198  ORDER BY
199    count DESC
200);
201
202CREATE PERFETTO MACRO _heap_graph_retaining_object_count_agg(
203    path_hashes TableOrSubquery,
204    path_hash_values TableOrSubquery
205)
206RETURNS TableOrSubquery AS
207(
208  SELECT
209    c.name AS class_name,
210    o.heap_type,
211    o.root_type,
212    o.reachable,
213    sum(o.self_size) AS total_size,
214    sum(o.native_size) AS total_native_size,
215    count() AS count
216  FROM graph_reachable_bfs
217    !(
218      (
219        SELECT
220          IFNULL(id, parent_id) AS source_node_id,
221          IFNULL(parent_id, id) AS dest_node_id
222        FROM _heap_graph_object_min_depth_tree
223      ),
224      (
225        SELECT o.id AS node_id
226        FROM $path_hashes h
227        JOIN heap_graph_object o
228          ON h.id = o.id
229        JOIN heap_graph_class c
230          ON o.type_id = c.id
231        JOIN $path_hash_values USING(path_hash)
232      )) AS b
233  JOIN heap_graph_object AS o
234    ON b.node_id = o.id
235  JOIN heap_graph_class AS c
236    ON o.type_id = c.id
237  GROUP BY
238    class_name,
239    heap_type,
240    root_type,
241    reachable
242  ORDER BY
243    count DESC
244);
245
246CREATE PERFETTO MACRO _heap_graph_duplicate_objects_agg(
247    path_hashes TableOrSubquery
248)
249RETURNS TableOrSubquery AS
250(
251  SELECT
252    count(DISTINCT path_hash) AS path_count,
253    count() AS object_count,
254    sum(o.self_size) AS total_size,
255    sum(o.native_size) AS total_native_size,
256    c.name AS class_name
257  FROM $path_hashes AS h
258  JOIN heap_graph_object AS o
259    ON h.id = o.id
260  JOIN heap_graph_class AS c
261    ON o.type_id = c.id
262  GROUP BY
263    class_name
264  ORDER BY
265    path_count DESC
266);
267