| # 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. |
| """Contains tables for relevant for TODO.""" |
| |
| from python.generators.trace_processor_table.public import Column as C |
| from python.generators.trace_processor_table.public import ColumnFlag |
| from python.generators.trace_processor_table.public import CppInt32 |
| from python.generators.trace_processor_table.public import CppInt64 |
| from python.generators.trace_processor_table.public import CppOptional |
| from python.generators.trace_processor_table.public import CppSelfTableId |
| from python.generators.trace_processor_table.public import CppString |
| from python.generators.trace_processor_table.public import Table |
| from python.generators.trace_processor_table.public import TableDoc |
| from python.generators.trace_processor_table.public import CppTableId |
| from python.generators.trace_processor_table.public import CppUint32 |
| |
| from src.trace_processor.tables.track_tables import TRACK_TABLE, COUNTER_TRACK_TABLE |
| |
| PROFILER_SMAPS_TABLE = Table( |
| python_module=__file__, |
| class_name='ProfilerSmapsTable', |
| sql_name='profiler_smaps', |
| columns=[ |
| C('upid', CppUint32()), |
| C('ts', CppInt64()), |
| C('path', CppString()), |
| C('size_kb', CppInt64()), |
| C('private_dirty_kb', CppInt64()), |
| C('swap_kb', CppInt64()), |
| C('file_name', CppString()), |
| C('start_address', CppInt64()), |
| C('module_timestamp', CppInt64()), |
| C('module_debugid', CppString()), |
| C('module_debug_path', CppString()), |
| C('protection_flags', CppInt64()), |
| C('private_clean_resident_kb', CppInt64()), |
| C('shared_dirty_resident_kb', CppInt64()), |
| C('shared_clean_resident_kb', CppInt64()), |
| C('locked_kb', CppInt64()), |
| C('proportional_resident_kb', CppInt64()), |
| ], |
| tabledoc=TableDoc( |
| doc=''' |
| The profiler smaps contains the memory stats for virtual memory ranges |
| captured by the |
| [heap profiler](/docs/data-sources/native-heap-profiler.md). |
| ''', |
| group='Callstack profilers', |
| columns={ |
| 'upid': |
| '''The unique PID of the process.''', |
| 'ts': |
| '''Timestamp of the snapshot. Multiple rows will have the same |
| timestamp.''', |
| 'path': |
| '''The mmaped file, as per /proc/pid/smaps.''', |
| 'size_kb': |
| '''Total size of the mapping.''', |
| 'private_dirty_kb': |
| '''KB of this mapping that are private dirty RSS.''', |
| 'swap_kb': |
| '''KB of this mapping that are in swap.''', |
| 'file_name': |
| '''''', |
| 'start_address': |
| '''''', |
| 'module_timestamp': |
| '''''', |
| 'module_debugid': |
| '''''', |
| 'module_debug_path': |
| '''''', |
| 'protection_flags': |
| '''''', |
| 'private_clean_resident_kb': |
| '''''', |
| 'shared_dirty_resident_kb': |
| '''''', |
| 'shared_clean_resident_kb': |
| '''''', |
| 'locked_kb': |
| '''''', |
| 'proportional_resident_kb': |
| '''''' |
| })) |
| |
| PACKAGE_LIST_TABLE = Table( |
| python_module=__file__, |
| class_name='PackageListTable', |
| sql_name='package_list', |
| columns=[ |
| C('package_name', CppString()), |
| C('uid', CppInt64()), |
| C('debuggable', CppInt32()), |
| C('profileable_from_shell', CppInt32()), |
| C('version_code', CppInt64()), |
| ], |
| tabledoc=TableDoc( |
| doc=''' |
| Metadata about packages installed on the system. |
| This is generated by the packages_list data-source. |
| ''', |
| group='Misc', |
| columns={ |
| 'package_name': |
| '''name of the package, e.g. com.google.android.gm.''', |
| 'uid': |
| '''UID processes of this package run as.''', |
| 'debuggable': |
| '''bool whether this app is debuggable.''', |
| 'profileable_from_shell': |
| '''bool whether this app is profileable.''', |
| 'version_code': |
| '''versionCode from the APK.''' |
| })) |
| |
| STACK_PROFILE_MAPPING_TABLE = Table( |
| python_module=__file__, |
| class_name='StackProfileMappingTable', |
| sql_name='stack_profile_mapping', |
| columns=[ |
| C('build_id', CppString()), |
| C('exact_offset', CppInt64()), |
| C('start_offset', CppInt64()), |
| C('start', CppInt64()), |
| C('end', CppInt64()), |
| C('load_bias', CppInt64()), |
| C('name', CppString()), |
| ], |
| tabledoc=TableDoc( |
| doc=''' |
| A mapping (binary / library) in a process. |
| This is generated by the stack profilers: heapprofd and traced_perf. |
| ''', |
| group='Callstack profilers', |
| columns={ |
| 'build_id': '''Hex-encoded Build ID of the binary / library.''', |
| 'start': '''Start of the mapping in the process' address space.''', |
| 'end': '''End of the mapping in the process' address space.''', |
| 'name': '''Filename of the binary / library.''', |
| 'exact_offset': '''''', |
| 'start_offset': '''''', |
| 'load_bias': '''''' |
| })) |
| |
| STACK_PROFILE_FRAME_TABLE = Table( |
| python_module=__file__, |
| class_name='StackProfileFrameTable', |
| sql_name='stack_profile_frame', |
| columns=[ |
| C('name', CppString()), |
| C('mapping', CppTableId(STACK_PROFILE_MAPPING_TABLE)), |
| C('rel_pc', CppInt64()), |
| C('symbol_set_id', CppOptional(CppUint32()), flags=ColumnFlag.DENSE), |
| C('deobfuscated_name', CppOptional(CppString())), |
| ], |
| tabledoc=TableDoc( |
| doc=''' |
| A frame on the callstack. This is a location in a program. |
| This is generated by the stack profilers: heapprofd and traced_perf. |
| ''', |
| group='Callstack profilers', |
| columns={ |
| 'name': |
| '''Name of the function this location is in.''', |
| 'mapping': |
| '''The mapping (library / binary) this location is in.''', |
| 'rel_pc': |
| '''The program counter relative to the start of the mapping.''', |
| 'symbol_set_id': |
| '''If the profile was offline symbolized, the offline |
| symbol information of this frame.''', |
| 'deobfuscated_name': |
| '''Deobfuscated name of the function this location is in.''' |
| })) |
| |
| STACK_PROFILE_CALLSITE_TABLE = Table( |
| python_module=__file__, |
| class_name='StackProfileCallsiteTable', |
| sql_name='stack_profile_callsite', |
| columns=[ |
| C('depth', CppUint32()), |
| C('parent_id', CppOptional(CppSelfTableId())), |
| C('frame_id', CppTableId(STACK_PROFILE_FRAME_TABLE)), |
| ], |
| tabledoc=TableDoc( |
| doc=''' |
| A callsite. This is a list of frames that were on the stack. |
| This is generated by the stack profilers: heapprofd and traced_perf. |
| ''', |
| group='Callstack profilers', |
| columns={ |
| 'depth': |
| '''Distance from the bottom-most frame of the callstack.''', |
| 'parent_id': |
| '''Parent frame on the callstack. NULL for the bottom-most.''', |
| 'frame_id': |
| '''Frame at this position in the callstack.''' |
| })) |
| |
| CPU_PROFILE_STACK_SAMPLE_TABLE = Table( |
| python_module=__file__, |
| class_name='CpuProfileStackSampleTable', |
| sql_name='cpu_profile_stack_sample', |
| columns=[ |
| C('ts', CppInt64(), flags=ColumnFlag.SORTED), |
| C('callsite_id', CppTableId(STACK_PROFILE_CALLSITE_TABLE)), |
| C('utid', CppUint32()), |
| C('process_priority', CppInt32()), |
| ], |
| tabledoc=TableDoc( |
| doc='Table containing stack samples from CPU profiling.', |
| group='Callstack profilers', |
| columns={ |
| 'ts': '''timestamp of the sample.''', |
| 'callsite_id': '''unwound callstack.''', |
| 'utid': '''thread that was active when the sample was taken.''', |
| 'process_priority': '''''' |
| })) |
| |
| PERF_SESSION_TABLE = Table( |
| python_module=__file__, |
| class_name='PerfSessionTable', |
| sql_name='__intrinsic_perf_session', |
| columns=[ |
| C('cmdline', CppOptional(CppString())), |
| ], |
| tabledoc=TableDoc( |
| doc='''Perf sessions.''', |
| group='Callstack profilers', |
| columns={ |
| 'cmdline': '''Command line used to collect the data.''', |
| })) |
| |
| PERF_SAMPLE_TABLE = Table( |
| python_module=__file__, |
| class_name='PerfSampleTable', |
| sql_name='perf_sample', |
| columns=[ |
| C('ts', CppInt64(), flags=ColumnFlag.SORTED), |
| C('utid', CppUint32()), |
| C('cpu', CppOptional(CppUint32())), |
| C('cpu_mode', CppString()), |
| C('callsite_id', CppOptional(CppTableId(STACK_PROFILE_CALLSITE_TABLE))), |
| C('unwind_error', CppOptional(CppString())), |
| C('perf_session_id', CppTableId(PERF_SESSION_TABLE)), |
| ], |
| tabledoc=TableDoc( |
| doc='''Samples from the traced_perf profiler.''', |
| group='Callstack profilers', |
| columns={ |
| 'ts': |
| '''Timestamp of the sample.''', |
| 'utid': |
| '''Sampled thread.''', |
| 'cpu': |
| '''Core the sampled thread was running on.''', |
| 'cpu_mode': |
| '''Execution state (userspace/kernelspace) of the sampled |
| thread.''', |
| 'callsite_id': |
| '''If set, unwound callstack of the sampled thread.''', |
| 'unwind_error': |
| '''If set, indicates that the unwinding for this sample |
| encountered an error. Such samples still reference the |
| best-effort result via the callsite_id, with a synthetic error |
| frame at the point where unwinding stopped.''', |
| 'perf_session_id': |
| '''Distinguishes samples from different profiling |
| streams (i.e. multiple data sources).''' |
| })) |
| |
| INSTRUMENTS_SAMPLE_TABLE = Table( |
| python_module=__file__, |
| class_name='InstrumentsSampleTable', |
| sql_name='instruments_sample', |
| columns=[ |
| C('ts', CppInt64(), flags=ColumnFlag.SORTED), |
| C('utid', CppUint32()), |
| C('cpu', CppOptional(CppUint32())), |
| C('callsite_id', CppOptional(CppTableId(STACK_PROFILE_CALLSITE_TABLE))), |
| ], |
| tabledoc=TableDoc( |
| doc=''' |
| Samples from MacOS Instruments. |
| ''', |
| group='Callstack profilers', |
| columns={ |
| 'ts': |
| '''Timestamp of the sample.''', |
| 'utid': |
| '''Sampled thread.''', |
| 'cpu': |
| '''Core the sampled thread was running on.''', |
| 'callsite_id': |
| '''If set, unwound callstack of the sampled thread.''', |
| })) |
| |
| SYMBOL_TABLE = Table( |
| python_module=__file__, |
| class_name='SymbolTable', |
| sql_name='stack_profile_symbol', |
| columns=[ |
| C('symbol_set_id', |
| CppUint32(), |
| flags=ColumnFlag.SORTED | ColumnFlag.SET_ID), |
| C('name', CppString()), |
| C('source_file', CppOptional(CppString())), |
| C('line_number', CppOptional(CppUint32())), |
| ], |
| tabledoc=TableDoc( |
| doc=''' |
| Symbolization data for a frame. Rows with the same symbol_set_id |
| describe one callframe, with the most-inlined symbol having |
| id == symbol_set_id. |
| |
| For instance, if the function foo has an inlined call to the |
| function bar, which has an inlined call to baz, the |
| stack_profile_symbol table would look like this. |
| |
| ``` |
| |id|symbol_set_id|name |source_file|line_number| |
| |--|-------------|-------------|-----------|-----------| |
| |1 | 1 |baz |foo.cc | 36 | |
| |2 | 1 |bar |foo.cc | 30 | |
| |3 | 1 |foo |foo.cc | 60 | |
| ``` |
| ''', |
| group='Callstack profilers', |
| columns={ |
| 'name': |
| '''name of the function.''', |
| 'source_file': |
| '''name of the source file containing the function.''', |
| 'line_number': |
| ''' |
| line number of the frame in the source file. This is the |
| exact line for the corresponding program counter, not the |
| beginning of the function. |
| ''', |
| 'symbol_set_id': |
| '''''' |
| })) |
| |
| HEAP_PROFILE_ALLOCATION_TABLE = Table( |
| python_module=__file__, |
| class_name='HeapProfileAllocationTable', |
| sql_name='heap_profile_allocation', |
| columns=[ |
| # TODO(b/193757386): readd the sorted flag once this bug is fixed. |
| C('ts', CppInt64()), |
| C('upid', CppUint32()), |
| C('heap_name', CppString()), |
| C('callsite_id', CppTableId(STACK_PROFILE_CALLSITE_TABLE)), |
| C('count', CppInt64()), |
| C('size', CppInt64()), |
| ], |
| tabledoc=TableDoc( |
| doc=''' |
| Allocations that happened at a callsite. |
| |
| NOTE: this table is not sorted by timestamp intentionanlly - |
| see b/193757386 for details. |
| |
| This is generated by heapprofd. |
| ''', |
| group='Callstack profilers', |
| columns={ |
| 'ts': |
| '''The timestamp the allocations happened at. heapprofd batches |
| allocations and frees, and all data from a dump will have the |
| same timestamp.''', |
| 'upid': |
| '''The unique PID of the allocating process.''', |
| 'callsite_id': |
| '''The callsite the allocation happened at.''', |
| 'count': |
| '''If positive: number of allocations that happened at this |
| callsite. if negative: number of allocations that happened at |
| this callsite that were freed.''', |
| 'size': |
| '''If positive: size of allocations that happened at this |
| callsite. if negative: size of allocations that happened at this |
| callsite that were freed.''', |
| 'heap_name': |
| '''''' |
| })) |
| |
| EXPERIMENTAL_FLAMEGRAPH_TABLE = Table( |
| python_module=__file__, |
| class_name='ExperimentalFlamegraphTable', |
| sql_name='experimental_flamegraph', |
| columns=[ |
| C('profile_type', CppString(), flags=ColumnFlag.HIDDEN), |
| C('ts_in', |
| CppOptional(CppInt64()), |
| flags=ColumnFlag.SORTED | ColumnFlag.HIDDEN), |
| C('ts_constraint', CppOptional(CppString()), flags=ColumnFlag.HIDDEN), |
| C('upid', CppOptional(CppUint32()), flags=ColumnFlag.HIDDEN), |
| C('upid_group', CppOptional(CppString()), flags=ColumnFlag.HIDDEN), |
| C('focus_str', CppOptional(CppString()), flags=ColumnFlag.HIDDEN), |
| C('ts', CppInt64(), flags=ColumnFlag.SORTED), |
| C('depth', CppUint32()), |
| C('name', CppString()), |
| C('map_name', CppString()), |
| C('count', CppInt64()), |
| C('cumulative_count', CppInt64()), |
| C('size', CppInt64()), |
| C('cumulative_size', CppInt64()), |
| C('alloc_count', CppInt64()), |
| C('cumulative_alloc_count', CppInt64()), |
| C('alloc_size', CppInt64()), |
| C('cumulative_alloc_size', CppInt64()), |
| C('parent_id', CppOptional(CppSelfTableId())), |
| C('source_file', CppOptional(CppString())), |
| C('line_number', CppOptional(CppUint32())), |
| ], |
| tabledoc=TableDoc( |
| doc=''' |
| Table used to render flamegraphs. This gives cumulative sizes of |
| nodes in the flamegraph. |
| |
| WARNING: This is experimental and the API is subject to change. |
| ''', |
| group='Callstack profilers', |
| columns={ |
| 'ts': '''''', |
| 'upid': '''''', |
| 'profile_type': '''''', |
| 'focus_str': '''''', |
| 'depth': '''''', |
| 'name': '''''', |
| 'map_name': '''''', |
| 'count': '''''', |
| 'cumulative_count': '''''', |
| 'size': '''''', |
| 'cumulative_size': '''''', |
| 'alloc_count': '''''', |
| 'cumulative_alloc_count': '''''', |
| 'alloc_size': '''''', |
| 'cumulative_alloc_size': '''''', |
| 'parent_id': '''''', |
| 'source_file': '''''', |
| 'line_number': '''''', |
| 'upid_group': '''''' |
| })) |
| |
| HEAP_GRAPH_CLASS_TABLE = Table( |
| python_module=__file__, |
| class_name='HeapGraphClassTable', |
| sql_name='heap_graph_class', |
| columns=[ |
| C('name', CppString()), |
| C('deobfuscated_name', CppOptional(CppString())), |
| C('location', CppOptional(CppString())), |
| C('superclass_id', CppOptional(CppSelfTableId())), |
| # classloader_id should really be HeapGraphObject::id, but that |
| # would create a loop, which is currently not possible. |
| # TODO(lalitm): resolve this |
| C('classloader_id', CppOptional(CppUint32())), |
| C('kind', CppString()), |
| ], |
| tabledoc=TableDoc( |
| doc='''''', |
| group='ART Heap Graphs', |
| columns={ |
| 'name': |
| '''(potentially obfuscated) name of the class.''', |
| 'deobfuscated_name': |
| '''if class name was obfuscated and deobfuscation map |
| for it provided, the deobfuscated name.''', |
| 'location': |
| '''the APK / Dex / JAR file the class is contained in. |
| ''', |
| 'superclass_id': |
| '''''', |
| 'classloader_id': |
| '''''', |
| 'kind': |
| '''''' |
| })) |
| |
| HEAP_GRAPH_OBJECT_TABLE = Table( |
| python_module=__file__, |
| class_name='HeapGraphObjectTable', |
| sql_name='heap_graph_object', |
| columns=[ |
| C('upid', CppUint32()), |
| C('graph_sample_ts', CppInt64()), |
| C('self_size', CppInt64()), |
| C('native_size', CppInt64()), |
| C('reference_set_id', CppOptional(CppUint32()), flags=ColumnFlag.DENSE), |
| C('reachable', CppInt32()), |
| C('type_id', CppTableId(HEAP_GRAPH_CLASS_TABLE)), |
| C('root_type', CppOptional(CppString())), |
| C('root_distance', CppInt32(), flags=ColumnFlag.HIDDEN), |
| ], |
| tabledoc=TableDoc( |
| doc=''' |
| The objects on the Dalvik heap. |
| |
| All rows with the same (upid, graph_sample_ts) are one dump. |
| ''', |
| group='ART Heap Graphs', |
| columns={ |
| 'upid': |
| '''Unique PID of the target.''', |
| 'graph_sample_ts': |
| '''timestamp this dump was taken at.''', |
| 'self_size': |
| '''size this object uses on the Java Heap.''', |
| 'native_size': |
| '''approximate amount of native memory used by this object, |
| as reported by libcore.util.NativeAllocationRegistry.size.''', |
| 'reference_set_id': |
| '''join key with heap_graph_reference containing all |
| objects referred in this object's fields.''', |
| 'reachable': |
| '''bool whether this object is reachable from a GC root. If |
| false, this object is uncollected garbage.''', |
| 'type_id': |
| '''class this object is an instance of.''', |
| 'root_type': |
| '''if not NULL, this object is a GC root.''', |
| 'root_distance': |
| '''''' |
| })) |
| |
| HEAP_GRAPH_REFERENCE_TABLE = Table( |
| python_module=__file__, |
| class_name='HeapGraphReferenceTable', |
| sql_name='heap_graph_reference', |
| columns=[ |
| C('reference_set_id', |
| CppUint32(), |
| flags=ColumnFlag.SORTED | ColumnFlag.SET_ID), |
| C('owner_id', CppTableId(HEAP_GRAPH_OBJECT_TABLE)), |
| C('owned_id', CppOptional(CppTableId(HEAP_GRAPH_OBJECT_TABLE))), |
| C('field_name', CppString()), |
| C('field_type_name', CppString()), |
| C('deobfuscated_field_name', CppOptional(CppString())), |
| ], |
| tabledoc=TableDoc( |
| doc=''' |
| Many-to-many mapping between heap_graph_object. |
| |
| This associates the object with given reference_set_id with the |
| objects that are referred to by its fields. |
| ''', |
| group='ART Heap Graphs', |
| columns={ |
| 'reference_set_id': |
| '''Join key to heap_graph_object.''', |
| 'owner_id': |
| '''Id of object that has this reference_set_id.''', |
| 'owned_id': |
| '''Id of object that is referred to.''', |
| 'field_name': |
| '''The field that refers to the object. E.g. Foo.name.''', |
| 'field_type_name': |
| '''The static type of the field. E.g. java.lang.String.''', |
| 'deobfuscated_field_name': |
| '''The deobfuscated name, if field_name was obfuscated and a |
| deobfuscation mapping was provided for it.''' |
| })) |
| |
| VULKAN_MEMORY_ALLOCATIONS_TABLE = Table( |
| python_module=__file__, |
| class_name='VulkanMemoryAllocationsTable', |
| sql_name='vulkan_memory_allocations', |
| columns=[ |
| C('arg_set_id', CppOptional(CppUint32())), |
| C('source', CppString()), |
| C('operation', CppString()), |
| C('timestamp', CppInt64()), |
| C('upid', CppOptional(CppUint32())), |
| C('device', CppOptional(CppInt64())), |
| C('device_memory', CppOptional(CppInt64())), |
| C('memory_type', CppOptional(CppUint32())), |
| C('heap', CppOptional(CppUint32())), |
| C('function_name', CppOptional(CppString())), |
| C('object_handle', CppOptional(CppInt64())), |
| C('memory_address', CppOptional(CppInt64())), |
| C('memory_size', CppOptional(CppInt64())), |
| C('scope', CppString()), |
| ], |
| tabledoc=TableDoc( |
| doc='''''', |
| group='Misc', |
| columns={ |
| 'arg_set_id': '''''', |
| 'source': '''''', |
| 'operation': '''''', |
| 'timestamp': '''''', |
| 'upid': '''''', |
| 'device': '''''', |
| 'device_memory': '''''', |
| 'memory_type': '''''', |
| 'heap': '''''', |
| 'function_name': '''''', |
| 'object_handle': '''''', |
| 'memory_address': '''''', |
| 'memory_size': '''''', |
| 'scope': '''''' |
| })) |
| |
| GPU_COUNTER_GROUP_TABLE = Table( |
| python_module=__file__, |
| class_name='GpuCounterGroupTable', |
| sql_name='gpu_counter_group', |
| columns=[ |
| C('group_id', CppInt32()), |
| C('track_id', CppTableId(TRACK_TABLE)), |
| ], |
| tabledoc=TableDoc( |
| doc='''''', |
| group='Misc', |
| columns={ |
| 'group_id': '''''', |
| 'track_id': '''''' |
| })) |
| |
| PERF_COUNTER_TRACK_TABLE = Table( |
| python_module=__file__, |
| class_name='PerfCounterTrackTable', |
| sql_name='perf_counter_track', |
| columns=[ |
| C('perf_session_id', CppTableId(PERF_SESSION_TABLE)), |
| C('cpu', CppUint32()), |
| C('is_timebase', CppUint32()), |
| ], |
| parent=COUNTER_TRACK_TABLE, |
| tabledoc=TableDoc( |
| doc='Sampled counters\' values for samples in the perf_sample table.', |
| group='Counter Tracks', |
| columns={ |
| 'perf_session_id': |
| 'id of a distict profiling stream', |
| 'cpu': |
| 'the core the sample was taken on', |
| 'is_timebase': |
| ''' |
| If true, indicates this counter was the sampling timebase for |
| this perf_session_id |
| ''' |
| })) |
| |
| # Keep this list sorted. |
| ALL_TABLES = [ |
| CPU_PROFILE_STACK_SAMPLE_TABLE, |
| EXPERIMENTAL_FLAMEGRAPH_TABLE, |
| GPU_COUNTER_GROUP_TABLE, |
| HEAP_GRAPH_CLASS_TABLE, |
| HEAP_GRAPH_OBJECT_TABLE, |
| HEAP_GRAPH_REFERENCE_TABLE, |
| INSTRUMENTS_SAMPLE_TABLE, |
| HEAP_PROFILE_ALLOCATION_TABLE, |
| PACKAGE_LIST_TABLE, |
| PERF_SAMPLE_TABLE, |
| PERF_SESSION_TABLE, |
| PROFILER_SMAPS_TABLE, |
| STACK_PROFILE_CALLSITE_TABLE, |
| STACK_PROFILE_FRAME_TABLE, |
| STACK_PROFILE_MAPPING_TABLE, |
| SYMBOL_TABLE, |
| VULKAN_MEMORY_ALLOCATIONS_TABLE, |
| PERF_COUNTER_TRACK_TABLE, |
| ] |