| /* |
| * Copyright (C) 2018 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. |
| */ |
| syntax = "proto3"; |
| |
| package profiler.proto; |
| option java_package = "com.android.tools.profiler.proto"; |
| option java_outer_classname = "Memory"; |
| |
| message MemoryUsageData { |
| int32 java_mem = 1; |
| int32 native_mem = 2; |
| int32 stack_mem = 3; |
| int32 graphics_mem = 4; |
| int32 code_mem = 5; |
| int32 others_mem = 6; |
| int32 total_mem = 7; |
| } |
| |
| message MemoryGcData { |
| // GC duration is only used as metadata and is not represented |
| // on the timeline, so we only send one message per GC event |
| // instead of a pair of start/stop event. |
| int64 duration = 1; |
| // TODO add deallocation stats |
| } |
| |
| message MemoryAllocStatsData { |
| int32 java_allocation_count = 2; |
| int32 java_free_count = 3; |
| } |
| |
| // Proto for describing a heap dump record. |
| // For the new pipeline, this message will appear in a pair of |
| // |MEMORY_HEAP_DUMP| events. For the first event, the HeapDumpInfo |
| // represents the unfinished heap dump (e.g. end_time == LLONG_MAX), |
| // while the second event contains the HeapDumpInfo that has both |
| // the end_time and success fields set. |
| message HeapDumpInfo { |
| int64 start_time = 1; |
| // Set to LLONG_MAX if the heap dump has not finished. |
| int64 end_time = 2; |
| // Whether the heap dump request is successful. |
| // A request can failed if the 'am dumpheap' command fails |
| // (e.g. invalid parameters), or if we fail to detect that |
| // the heap dump file has been finished written to. |
| // Unset if the heap dump has not finished. |
| bool success = 3; |
| } |
| |
| message MemoryHeapDumpData { |
| HeapDumpInfo info = 1; |
| } |
| |
| // Return status for the HEAP_DUMP command. Caller of the command |
| // should query this status message using the command id to check |
| // if the command was successful. |
| message HeapDumpStatus { |
| enum Status { |
| UNSPECIFIED = 0; |
| SUCCESS = 1; |
| // A heap dump is already in progress. |
| IN_PROGRESS = 2; |
| // Profilng has not started on the specified pid. |
| // Only used by the legacy pipeline. |
| // TODO investigate whether it can be removed after full migration. |
| NOT_PROFILING = 3; |
| // Only used by the legacy pipeline. |
| // TODO investigate whether it can be removed after full migration. |
| FAILURE_UNKNOWN = 4; |
| } |
| Status status = 1; |
| // If |SUCESS|, the start time of the HeapDumpInfo record, |
| // which is the id that can be used to retrieve the dump. |
| int64 start_time = 2; |
| } |
| |
| message MemoryHeapDumpStatusData { |
| HeapDumpStatus status = 1; |
| } |
| |
| message MemoryAllocSamplingData { |
| // Number of allocations between samples. |
| // e.g. when set to 100, we only track 1 out of every 100 allocations. |
| // When set to 0, allocation tracking is turned off. |
| // When set to 1, every allocation is tracked (i.e. full tracking). |
| int32 sampling_num_interval = 1; |
| } |
| |
| message StartNativeSample { |
| string app_name = 1; |
| // ABI CPU architecture of the perfetto binary to use. This is used to |
| // sideload Perfetto (API == P). It should match the arch of the device |
| // and should be one of the values defined by SdkConstants.CPU_ARCH_*, |
| // e.g. 'arm', 'arm64', 'x86'. |
| string abi_cpu_arch = 2; |
| // After X bytes in allocations capture a sample. Default is 4096. |
| // A value of 0 here disables sampling interval by bytes and |
| // a value for continuous dump interval should be supplied. |
| int32 sampling_interval_bytes = 3; |
| // After X miliseconds capture a sample default is 0 (disabled). |
| int32 continuous_dump_interval_ms = 4; |
| // Number of bytes to use as a memory buffer for capturing allocation |
| // info. This is used to store stats, and callstacks. |
| int32 shared_memory_buffer_bytes = 5; |
| // The device path to output the trace to. Generated by Studio unless for the |
| // case of initiation_type == |INITIATED_BY_API| which does not need to |
| // specify a path. Note that this is a only for temp storage. A completed |
| // trace will be made available via the |GetBytes| rpc using the trace id as |
| // the byte's id. |
| string temp_path = 6; |
| } |
| |
| message StopNativeSample { |
| int64 start_time = 2; |
| } |
| |
| // Proto for describing an allocation tracking record. |
| // For the new pipeline, this message will appear in a pair of |
| // |MEMORY_ALLOC_TRACKING| events. For the first event, the AllocationsInfo |
| // represents the unfinished record (e.g. end_time == LLONG_MAX), while |
| // the second event contains the AllocationsInfo that has both the end_time |
| // and success fields set. |
| message AllocationsInfo { |
| int64 start_time = 1; |
| // Set to LLONG_MAX if the heap dump has not finished. |
| int64 end_time = 2; |
| bool legacy = 3; |
| // Unset if the tracking record is not properly finished (e.g. if the |
| // profilers terminated before a end-tracking request was issued). |
| bool success = 4; |
| } |
| |
| message MemoryAllocTrackingData { |
| AllocationsInfo info = 1; |
| } |
| |
| message TrackStatus { |
| enum Status { |
| UNSPECIFIED = 0; |
| SUCCESS = 1; |
| IN_PROGRESS = 2; // A tracking sessin is already in-progress |
| NOT_ENABLED = 3; // A tracking session is not started. |
| // Profilng has not started on the specified pid. |
| // Only used by the legacy pipeline. |
| // TODO investigate whether it can be removed after full migration. |
| NOT_PROFILING = 4; |
| // Only used by the legacy pipeline. |
| // TODO investigate whether it can be removed after full migration. |
| FAILURE_UNKNOWN = 5; |
| } |
| Status status = 1; |
| // If |SUCESS|, the start time of the AllocationInfo message which |
| // can be used to retrieve the record. |
| int64 start_time = 2; |
| } |
| |
| // Return status for the TRACK_ALLOCATIONS command. Caller of the |
| // command should query this status message using the command id to |
| // check if the command was successful. If |SUCCESS|, the caller can |
| // expect to receive a corresponding |MEMORY_ALLOC_TRACKING| event. |
| message MemoryAllocTrackingStatusData { |
| TrackStatus status = 1; |
| } |
| |
| message StartAllocTracking { |
| int64 request_time = 1; |
| } |
| |
| message StopAllocTracking { |
| int64 request_time = 1; |
| } |
| |
| message MemoryAllocContextsData { |
| BatchAllocationContexts contexts = 1; |
| } |
| |
| message MemoryAllocEventsData { |
| BatchAllocationEvents events = 1; |
| } |
| |
| message MemoryJniRefData { |
| BatchJNIGlobalRefEvent events = 1; |
| } |
| |
| message AllocatedClass { |
| int32 class_id = 1; |
| string class_name = 2; |
| int32 class_loader_id = 3; |
| } |
| |
| // Proto format for handling stack data for both pre-O and O+. |
| message AllocationStack { |
| message StackFrame { |
| // O+ only for uniquely idenfitying a method. |
| int64 method_id = 1; |
| string class_name = 2; |
| string method_name = 3; |
| |
| // Legacy recording as file name info is unavailable in JVMTI. |
| // Native memory sampling also sets this when able to symbolize |
| string file_name = 4; |
| |
| int32 line_number = 5; |
| |
| // If a module name is given via heapprofd this field is populated, |
| // for use in the native memory UI. A module referrs to a c++ module |
| // typically broken down by individual .so files. eg libart.so |
| string module_name = 6; |
| } |
| |
| // Proto format for storing and transmitting O+ stack data efficiently. |
| // Each |method_id| is referenced by AllocationStack.StackFrame which |
| // contains detailed info about the method. |
| message EncodedFrame { |
| int64 method_id = 1; |
| int32 line_number = 2; |
| } |
| |
| // Wrapper proto for StackFrame since oneof does not |
| // support repeated fields. |
| message StackFrameWrapper { |
| repeated StackFrame frames = 1; |
| } |
| |
| // Wrapper proto for EncodedFrame since oneof does not |
| // support repeated fields. |
| message EncodedFrameWrapper { |
| repeated EncodedFrame frames = 1; |
| } |
| |
| int32 stack_id = 1; |
| oneof frame { |
| StackFrameWrapper full_stack = 2; |
| EncodedFrameWrapper encoded_stack = 3; |
| } |
| } |
| |
| // Proto format for storing and transmitting O+ thread data. |
| // JVMTI provides an API to get a thread's name but not id. To avoid |
| // sending too much duplicated string datas, we encode thread names to |
| // id manually and resolve them on Studio-side. |
| message ThreadInfo { |
| // The time when this thread was first seen. It should match the first |
| // AllocationEvent::Allocation that generated the stack. |
| int32 thread_id = 2; |
| string thread_name = 3; |
| } |
| |
| // Batched AllocationContexts to minimize number of grpc |
| // calls compared to transferring them individually. |
| message BatchAllocationContexts { |
| int64 timestamp = 1; |
| repeated AllocatedClass classes = 2; |
| repeated AllocationStack.StackFrame methods = 3; |
| repeated AllocationStack encoded_stacks = 4; |
| repeated ThreadInfo thread_infos = 5; |
| |
| // For JNI native backtrace. |
| MemoryMap memory_map = 6; |
| } |
| |
| // Batched AllocationEvents to minimize number of grpc |
| // calls compared to transferring them individually. |
| message BatchAllocationEvents { |
| // From Perfa->Perfd and Perfd->Studio, this marks the |
| // time(ns) when the sample was first created in the agent. |
| // Within Studio, this indicates the latest timestamp amongst |
| // the events list. |
| int64 timestamp = 1; |
| repeated AllocationEvent events = 2; |
| } |
| |
| // Raw representation of the native callstack, it is symbolized |
| // and interpreted by Android Studio. |
| message NativeBacktrace { |
| // Sequence of program counter addresses obtained during a native |
| // stack walk. Addresses are ordered bottom-up e.g. the first one |
| // is the return address of the innermost function. |
| repeated uint64 addresses = 1; |
| } |
| |
| message NativeCallStack { |
| message NativeFrame { |
| int64 address = 1; |
| int64 module_offset = 2; |
| string module_name = 3; |
| string symbol_name = 4; |
| string file_name = 5; |
| int32 line_number = 6; |
| } |
| |
| repeated NativeFrame frames = 1; |
| } |
| |
| message MemoryMap { |
| message MemoryRegion { |
| string name = 1; |
| uint64 start_address = 2; |
| uint64 end_address = 3; |
| uint64 file_offset = 4; |
| } |
| |
| repeated MemoryRegion regions = 1; |
| } |
| |
| // Proto format for handling O+ JNI global reference creation / deletion. |
| message JNIGlobalReferenceEvent { |
| enum Type { |
| UNSPECIFIED = 0; |
| CREATE_GLOBAL_REF = 1; |
| DELETE_GLOBAL_REF = 2; |
| CREATE_WEAK_REF = 3; |
| DELETE_WEAK_REF = 4; |
| }; |
| |
| Type event_type = 1; |
| int64 timestamp = 2; |
| NativeBacktrace backtrace = 3; |
| int32 object_tag = 4; |
| int64 ref_value = 5; |
| |
| // Same as in AllocationEvent. |
| int32 thread_id = 6; |
| |
| // Same as in AllocationEvent. |
| string thread_name = 7; |
| } |
| |
| message BatchJNIGlobalRefEvent { |
| int64 timestamp = 1; |
| repeated JNIGlobalReferenceEvent events = 2; |
| } |
| |
| // Proto format for handling O+ allocation data. |
| message AllocationEvent { |
| message Allocation { |
| int32 tag = 1; |
| int32 class_tag = 2; |
| int64 size = 3; |
| // Length for array objects. For non-arrays, set to -1. |
| int32 length = 4; |
| |
| // Profiler-generated Id representing a thread. |
| // Valid id starts at 1 as 0 is used as a default no-value. |
| int32 thread_id = 5; |
| |
| // Profiler-Id representing the allocation stack. |
| // Valid id starts at 1 as 0 is used as a default no-value. |
| int32 stack_id = 6; |
| |
| // Which heap an object was allocated from. |
| // The id's are manually mapped to their corresponding names |
| // in Studio (e.g. Zygote vs App). |
| int32 heap_id = 7; |
| |
| // Entire list of methods corresponding to the allocation stack. |
| // Note that this is only used for temporary storage in perfa. |
| // When the data is sent from perfa->perfd, the list is encoded |
| // as |stack_id| above, and the encoded data is stored/sent |
| // separately using EncodedAllocationStack. |
| // First entry is top of stack. |
| repeated int64 method_ids = 8; |
| // Similar to |method_ids| above, this is only for temporary |
| // storage. The actual converted line numbers are stored/sent to |
| // studio via EncodedAllocationStack. |
| repeated int64 location_ids = 9; |
| // Temporary storage in perfa only. The thread info will be |
| // encoded into |thread_id| before transfer from perfa->perfd. |
| // The thread id -> name mapping is sent separately via ThreadInfo |
| // messages. |
| string thread_name = 10; |
| } |
| |
| message Deallocation { |
| int32 tag = 1; |
| } |
| |
| // If it is an allocation event, this marks the exact time |
| // when the alloc happens. If it is a deallocation event, this |
| // should match the last gc end time. |
| int64 timestamp = 2; |
| |
| oneof event { |
| // Temporary storage for class allocations when they are loaded by |
| // the app. Actual data is transfered and queried via the |classes| |
| // field in BatchAllocationContexts. |
| AllocatedClass class_data = 3; |
| Allocation alloc_data = 4; |
| Deallocation free_data = 5; |
| } |
| } |
| |
| // Return status for the |START_NATIVE_HEAP_SAMPLE| and |STOP_NATIVE_HEAP_SAMPLE| |
| // command. Caller of the command should query this status message using the |
| // command id to check if the command was successful. |
| message MemoryNativeTrackingData { |
| enum Status { |
| UNSPECIFIED = 0; |
| SUCCESS = 1; |
| // A heap dump is already in progress. |
| IN_PROGRESS = 2; |
| // Triggered when a profiling has stopped. |
| NOT_RECORDING = 3; |
| // If start or stop recording fails this status is set |
| // along with a |failure_message|. |
| FAILURE = 4; |
| } |
| Status status = 1; |
| // If |SUCCESS|, the start time of the heapprofd record, |
| // which is the id that can be used to retrieve the recording. |
| int64 start_time = 2; |
| |
| // If |FAILURE| the failure message field will be populated |
| // informing the user of what the error was. |
| string failure_message = 3; |
| } |
| |
| // Returns the capture information for |START_NATIVE_HEAP_SAMPLE|. |
| // This even gets generated on the |STOP_NATIVE_HEAP_SAMPLE|. The |
| // |start_time| is the trace_id that can be used with getBytes to |
| // load the trace. |
| message MemoryNativeSampleData { |
| // Device time in ms the trace was started. |
| // Also the trace id used to retrieve the recording. |
| int64 start_time = 1; |
| // Device time in ms the trace was stopped. |
| int64 end_time = 2; |
| } |