@@ -168,6 +168,119 @@ message TrackEventDescriptor {
168168
169169// End of protos/perfetto/common/track_event_descriptor.proto
170170
171+ // Begin of protos/perfetto/protovm/vm_program.proto
172+
173+ message VmProgram {
174+ optional uint32 version = 1 ;
175+ repeated VmInstruction instructions = 2 ;
176+ }
177+
178+ message VmInstruction {
179+ oneof operation {
180+ VmOpSelect select = 1 ;
181+ VmOpRegLoad reg_load = 2 ;
182+ VmOpMerge merge = 3 ;
183+ VmOpSet set = 4 ;
184+ VmOpDel del = 5 ;
185+ }
186+
187+ enum AbortLevel {
188+ // Skip current instruction but execute following ones
189+ SKIP_CURRENT_INSTRUCTION = 1 ;
190+ // Skip current instruction as well as following ones (default)
191+ SKIP_CURRENT_INSTRUCTION_AND_BREAK_OUTER = 2 ;
192+ // Abort whole program
193+ ABORT = 3 ;
194+ };
195+ optional AbortLevel abort_level = 6 ;
196+
197+ // Sub-instructions executed if the current instruction succeeds
198+ repeated VmInstruction nested_instructions = 7 ;
199+ }
200+
201+ message VmOpSelect {
202+ // Enum SRC|DST|BOTH. Default=SRC.
203+ optional VmCursorEnum cursor = 1 ;
204+ repeated PathComponent relative_path = 2 ;
205+
206+ // Creates the submessage if doesn't exist in the DST cursor
207+ // (think of mkdir -p). Only valid when cursor=DST|BOTH.
208+ optional bool create_if_not_exist = 3 ;
209+
210+ // A path component is either: (1) a field id to descend into (common case);
211+ // (2) an array index (for repeated fields); (3) a map lookup operation (for
212+ // repeated fields, where we snoop a sub-field as a map key)
213+ message PathComponent {
214+ oneof field {
215+ uint32 field_id = 1 ;
216+ uint32 array_index = 2 ;
217+
218+ // The ID of the field in the repeated submessage that we
219+ // use as a key (e.g. LayerState.layer_id). When setting this
220+ // register_to_match must also be set, to tell what's the
221+ // expected value of the key we are looking up.
222+ uint32 map_key_field_id = 3 ;
223+ }
224+
225+ // When we are selecting a leaf field, tell what's the field type
226+ // to disambiguate integer types. Using uint64 by default will likely
227+ // do the right thing in 99% cases (so probably we don't need to impl
228+ // this until much later if somebody does a map with a fixed64 key)
229+ // enum ProtoFieldType field_type = 4; // bool | int32 | fixed32 | ...
230+
231+ // Only valid when using field_id. This makes select have foreach
232+ // semantics. This means that the body of nested_instructions is
233+ // executed several times, once per each repeated submessage.
234+ optional bool is_repeated = 5 ;
235+
236+ // Only valid when using map_key_field_id. This defines which
237+ // register (R1..R32) should be used to match the key of the dict
238+ // in a map lookup operation.
239+ // In other words:
240+ // foreach msg in repeated message {
241+ // if msg[map_key_field_id] == R[register_to_match] {
242+ // break; // Lookup succeeded, PathComponent resolves here.
243+ // }
244+ // }
245+ optional uint32 register_to_match = 6 ;
246+
247+ // Only valid when using field_id and is_repeated=true. When iterating
248+ // over repeated fields, stores the current iteration index into the
249+ // the register R1..R32 defined below. This can be used to do complex
250+ // operations like "find the entry in the array that has width==100,
251+ // remember its offset in the SRC array and overwrite the matching
252+ // i-th element in the DST array. We will probably never implement
253+ // this but it's here for completeness.
254+ optional uint32 store_foreach_index_into_register = 7 ;
255+ }
256+ }
257+
258+ message VmOpRegLoad {
259+ // SRC(default) | DST.
260+ optional VmCursorEnum cursor = 1 ;
261+ // 1=R1, 2=R2... 32=R32
262+ optional uint32 dst_register = 2 ;
263+ }
264+
265+ // Merges SRC into DST. Both need to point to a message (not a field).
266+ message VmOpMerge {}
267+
268+ // Copies SRC into DST. If a message, replaces the DST node, discarding any
269+ // pre-existing field.
270+ message VmOpSet {}
271+
272+ // Delete the field or message pointed by DST.
273+ message VmOpDel {}
274+
275+ enum VmCursorEnum {
276+ VM_CURSOR_UNSPECIFIED = 0 ;
277+ VM_CURSOR_SRC = 1 ;
278+ VM_CURSOR_DST = 2 ;
279+ VM_CURSOR_BOTH = 3 ;
280+ }
281+
282+ // End of protos/perfetto/protovm/vm_program.proto
283+
171284// Begin of protos/perfetto/common/data_source_descriptor.proto
172285
173286// This message is sent from Producer(s) to the tracing Service when registering
@@ -208,6 +321,13 @@ message DataSourceDescriptor {
208321 // Introduced in v39 / Android V.
209322 optional bool no_flush = 9 ;
210323
324+ // If present, the tracing service executes this program within a ProtoVM to
325+ // process overwritten packets (patches). The service computes a hash of the
326+ // program to detect and disambiguate between different versions; if multiple
327+ // versions (from different producers) are specified for the same data source,
328+ // the service instantiates a dedicated ProtoVM for each.
329+ optional VmProgram protovm_program = 10 ;
330+
211331 // Optional specification about available GPU counters.
212332 optional GpuCounterDescriptor gpu_counter_descriptor = 5 [lazy = true ];
213333
@@ -2381,6 +2501,14 @@ message PerfEventConfig {
23812501
23822502// End of protos/perfetto/config/profiling/perf_event_config.proto
23832503
2504+ // Begin of protos/perfetto/config/protovm/protovm_config.proto
2505+
2506+ message ProtoVmConfig {
2507+ optional uint32 memory_limit_kb = 1 ;
2508+ }
2509+
2510+ // End of protos/perfetto/config/protovm/protovm_config.proto
2511+
23842512// Begin of protos/perfetto/config/statsd/atom_ids.proto
23852513
23862514// This enum is obtained by post-processing
@@ -4139,6 +4267,20 @@ message DataSourceConfig {
41394267
41404268 optional PriorityBoostConfig priority_boost = 10 ;
41414269
4270+ // If specified, the data source requires the tracing service to process
4271+ // overwritten packets (patches) using a ProtoVM instance with this config.
4272+ // The ProtoVM program is specified at data source registration time through
4273+ // the descriptor.
4274+
4275+ // TODO(primiano): today when we enable a protovm_config, we actually accept
4276+ // that if N producers advertise M different versions of the same program we
4277+ // will create M instances of that program.
4278+ // To overcome this, we could move the program to the TraceConfig. But doing
4279+ // so would bloat the trace config size too big and create problems to statsd.
4280+ // Once the config store (b/482305876) exists we should move protovm programs
4281+ // onto that.
4282+ optional ProtoVmConfig protovm_config = 12 ;
4283+
41424284 // Keep the lower IDs (up to 99) for fields that are *not* specific to
41434285 // data-sources and needs to be processed by the traced daemon.
41444286
0 commit comments