blob: 7aab2d25979c510824e9904e9209ff623d51a431 [file] [log] [blame]
/*
* Copyright (C) 2025 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.
*/
#ifndef SRC_PROTOVM_TEST_SAMPLE_PROGRAMS_H_
#define SRC_PROTOVM_TEST_SAMPLE_PROGRAMS_H_
#include "protos/perfetto/protovm/vm_program.pb.h"
#include "src/protovm/test/protos/incremental_trace.pb.h"
namespace perfetto {
namespace protovm {
namespace test {
class SamplePrograms {
public:
static perfetto::protos::VmProgram NoInstructions() {
perfetto::protos::VmProgram program;
return program;
}
static perfetto::protos::VmProgram Select_AllCursorTypes() {
perfetto::protos::VmProgram program;
// default
{
auto* instruction = program.add_instructions();
auto* select = instruction->mutable_select();
auto* component = select->add_relative_path();
component->set_field_id(1);
}
// SRC
{
auto* instruction = program.add_instructions();
auto* select = instruction->mutable_select();
select->set_cursor(perfetto::protos::VmCursorEnum::VM_CURSOR_SRC);
auto* component = select->add_relative_path();
component->set_field_id(2);
}
// DST
{
auto* instruction = program.add_instructions();
auto* select = instruction->mutable_select();
select->set_cursor(perfetto::protos::VmCursorEnum::VM_CURSOR_DST);
auto* component = select->add_relative_path();
component->set_field_id(3);
}
return program;
}
static perfetto::protos::VmProgram Select_AllFieldTypes() {
perfetto::protos::VmProgram program;
auto* instruction = program.add_instructions();
auto* select = instruction->mutable_select();
select->set_cursor(perfetto::protos::VmCursorEnum::VM_CURSOR_SRC);
// enter field
{
auto* component = select->add_relative_path();
component->set_field_id(1);
}
// enter repeated field (array index)
{
auto* component_field_id = select->add_relative_path();
component_field_id->set_field_id(2);
auto* component_index = select->add_relative_path();
component_index->set_array_index(1);
}
// enter mapped repeated field
{
auto* component_field_id = select->add_relative_path();
component_field_id->set_field_id(4);
auto* component_map_key = select->add_relative_path();
component_map_key->set_map_key_field_id(5);
component_map_key->set_register_to_match(0);
}
// iterate repeated field
{
auto* component = select->add_relative_path();
component->set_field_id(3);
component->set_is_repeated(true);
}
// nested instruction (reg_load)
{
auto* nested_instruction = instruction->add_nested_instructions();
auto* reg_load = nested_instruction->mutable_reg_load();
reg_load->set_dst_register(0);
}
return program;
}
static perfetto::protos::VmProgram Select_ExecutesNestedInstructions() {
perfetto::protos::VmProgram program;
auto* instruction = program.add_instructions();
// iterate repeated field
{
auto* component = instruction->mutable_select()->add_relative_path();
component->set_field_id(3);
component->set_is_repeated(true);
}
// nested instruction #1 (reg_load)
{
auto* nested_instruction = instruction->add_nested_instructions();
auto* reg_load = nested_instruction->mutable_reg_load();
reg_load->set_dst_register(10);
}
// nested instruction #2 (reg_load)
{
auto* nested_instruction = instruction->add_nested_instructions();
auto* reg_load = nested_instruction->mutable_reg_load();
reg_load->set_dst_register(11);
}
return program;
}
static perfetto::protos::VmProgram Select_CanBreakOuterNestedInstructions() {
perfetto::protos::VmProgram program;
auto* instruction = program.add_instructions();
instruction->mutable_reg_load()->set_dst_register(10);
// nested instruction #1 (reg_load)
{
auto* nested_instruction = instruction->add_nested_instructions();
auto* nested_reg_load = nested_instruction->mutable_reg_load();
nested_reg_load->set_dst_register(10);
}
// nested instruction #2 (failing select)
{
auto* nested_instruction = instruction->add_nested_instructions();
nested_instruction->set_abort_level(
::perfetto::protos::
VmInstruction_AbortLevel_SKIP_CURRENT_INSTRUCTION_AND_BREAK_OUTER);
auto* nested_select = nested_instruction->mutable_select();
auto* component = nested_select->add_relative_path();
component->set_field_id(1);
}
// nested instruction #2 (reg_load)
{
auto* nested_instruction = instruction->add_nested_instructions();
auto* nested_reg_load = nested_instruction->mutable_reg_load();
nested_reg_load->set_dst_register(11);
}
return program;
}
static perfetto::protos::VmProgram RegLoad() {
perfetto::protos::VmProgram program;
program.add_instructions()->mutable_reg_load()->set_dst_register(10);
return program;
}
static perfetto::protos::VmProgram AbortLevel_default() {
perfetto::protos::VmProgram program;
{
auto* instruction = program.add_instructions();
instruction->mutable_reg_load()->set_dst_register(10);
}
{
auto* instruction = program.add_instructions();
instruction->mutable_reg_load()->set_dst_register(11);
}
return program;
}
static perfetto::protos::VmProgram AbortLevel_SKIP_CURRENT_INSTRUCTION() {
perfetto::protos::VmProgram program;
{
auto* instruction = program.add_instructions();
instruction->mutable_reg_load()->set_dst_register(10);
instruction->set_abort_level(
::perfetto::protos::
VmInstruction_AbortLevel_SKIP_CURRENT_INSTRUCTION);
}
{
auto* instruction = program.add_instructions();
instruction->mutable_reg_load()->set_dst_register(11);
}
return program;
}
static perfetto::protos::VmProgram
AbortLevel_SKIP_CURRENT_INSTRUCTION_AND_BREAK_OUTER() {
perfetto::protos::VmProgram program;
{
auto* instruction = program.add_instructions();
instruction->mutable_reg_load()->set_dst_register(10);
instruction->set_abort_level(
::perfetto::protos::
VmInstruction_AbortLevel_SKIP_CURRENT_INSTRUCTION_AND_BREAK_OUTER);
}
{
auto* instruction = program.add_instructions();
instruction->mutable_reg_load()->set_dst_register(11);
}
return program;
}
static perfetto::protos::VmProgram AbortLevel_ABORT() {
perfetto::protos::VmProgram program;
{
auto* instruction = program.add_instructions();
instruction->mutable_reg_load()->set_dst_register(10);
instruction->set_abort_level(
::perfetto::protos::VmInstruction_AbortLevel_ABORT);
}
{
auto* instruction = program.add_instructions();
instruction->mutable_reg_load()->set_dst_register(11);
}
return program;
}
static perfetto::protos::VmProgram Delete() {
perfetto::protos::VmProgram program;
program.add_instructions()->mutable_del();
return program;
}
static perfetto::protos::VmProgram Merge() {
perfetto::protos::VmProgram program;
program.add_instructions()->mutable_merge();
return program;
}
static perfetto::protos::VmProgram Set() {
perfetto::protos::VmProgram program;
program.add_instructions()->mutable_set();
return program;
}
static perfetto::protos::VmProgram IncrementalTraceInstructions() {
perfetto::protos::VmProgram program;
constexpr uint32_t REGISTER_HOLDING_ELEMENT_ID = 0;
// Process elements_to_delete
{
// select element to delete (src)
auto* instr_src_select = program.add_instructions();
auto* src_select = instr_src_select->mutable_select();
auto* src_element = src_select->add_relative_path();
src_element->set_field_id(protos::Patch::kElementsToDeleteFieldNumber);
src_element->set_is_repeated(true);
{
// load element id to delete (src)
auto* instr_reg_load = instr_src_select->add_nested_instructions();
auto* reg_load = instr_reg_load->mutable_reg_load();
reg_load->set_dst_register(REGISTER_HOLDING_ELEMENT_ID);
// select element to delete (dst)
auto* instr_dst_select = instr_src_select->add_nested_instructions();
auto* dst_select = instr_dst_select->mutable_select();
dst_select->set_cursor(perfetto::protos::VmCursorEnum::VM_CURSOR_DST);
dst_select->set_create_if_not_exist(false);
auto* component_elements = dst_select->add_relative_path();
component_elements->set_field_id(
protos::TraceEntry::kElementsFieldNumber);
auto* component_map_key = dst_select->add_relative_path();
component_map_key->set_map_key_field_id(
protos::Element::kIdFieldNumber);
component_map_key->set_register_to_match(REGISTER_HOLDING_ELEMENT_ID);
// delete
{
auto* instr_del = instr_dst_select->add_nested_instructions();
instr_del->mutable_del();
}
}
}
// process elements to merge
{
// select element to merge (src)
auto* instr_src_select = program.add_instructions();
auto* src_select = instr_src_select->mutable_select();
auto* src_element = src_select->add_relative_path();
src_element->set_field_id(protos::Patch::kElementsToMergeFieldNumber);
src_element->set_is_repeated(true);
{
// select element id to merge (src)
auto* instr_src_select_id = instr_src_select->add_nested_instructions();
auto* src_select_id = instr_src_select_id->mutable_select();
auto* src_id = src_select_id->add_relative_path();
src_id->set_field_id(protos::Element::kIdFieldNumber);
// load element id to merge (src)
{
auto* instr_reg_load = instr_src_select_id->add_nested_instructions();
auto* reg_load = instr_reg_load->mutable_reg_load();
reg_load->set_dst_register(REGISTER_HOLDING_ELEMENT_ID);
}
// select element to merge (dst)
auto* instr_dst_select = instr_src_select->add_nested_instructions();
auto* dst_select = instr_dst_select->mutable_select();
dst_select->set_cursor(perfetto::protos::VmCursorEnum::VM_CURSOR_DST);
dst_select->set_create_if_not_exist(true);
auto* component_elements = dst_select->add_relative_path();
component_elements->set_field_id(
protos::TraceEntry::kElementsFieldNumber);
auto* component_map_key = dst_select->add_relative_path();
component_map_key->set_map_key_field_id(
protos::Element::kIdFieldNumber);
component_map_key->set_register_to_match(REGISTER_HOLDING_ELEMENT_ID);
// merge
{
auto* instr_set = instr_dst_select->add_nested_instructions();
instr_set->mutable_merge();
}
}
}
// process elements to set
{
// select element to set (src)
auto* instr_src_select = program.add_instructions();
auto* src_select = instr_src_select->mutable_select();
auto* src_element = src_select->add_relative_path();
src_element->set_field_id(protos::Patch::kElementsToSetFieldNumber);
src_element->set_is_repeated(true);
{
// select element id to set (src)
auto* instr_src_select_id = instr_src_select->add_nested_instructions();
auto* src_select_id = instr_src_select_id->mutable_select();
auto* src_id = src_select_id->add_relative_path();
src_id->set_field_id(protos::Element::kIdFieldNumber);
// load element id to set (src)
{
auto* instr_reg_load = instr_src_select_id->add_nested_instructions();
auto* reg_load = instr_reg_load->mutable_reg_load();
reg_load->set_dst_register(REGISTER_HOLDING_ELEMENT_ID);
}
// select element to set (dst)
auto* instr_dst_select = instr_src_select->add_nested_instructions();
auto* dst_select = instr_dst_select->mutable_select();
dst_select->set_cursor(perfetto::protos::VmCursorEnum::VM_CURSOR_DST);
dst_select->set_create_if_not_exist(true);
auto* component_elements = dst_select->add_relative_path();
component_elements->set_field_id(
protos::TraceEntry::kElementsFieldNumber);
auto* component_map_key = dst_select->add_relative_path();
component_map_key->set_map_key_field_id(
protos::Element::kIdFieldNumber);
component_map_key->set_register_to_match(REGISTER_HOLDING_ELEMENT_ID);
// set
{
auto* instr_set = instr_dst_select->add_nested_instructions();
instr_set->mutable_set();
}
}
}
return program;
}
};
} // namespace test
} // namespace protovm
} // namespace perfetto
#endif // SRC_PROTOVM_TEST_SAMPLE_PROGRAMS_H_