protovm: insert/delete array operations Change-Id: I2d6f25c903e6df227e454891e037913b412245dc
diff --git a/protos/perfetto/protovm/vm_program.proto b/protos/perfetto/protovm/vm_program.proto index 292e6f5..23daabb 100644 --- a/protos/perfetto/protovm/vm_program.proto +++ b/protos/perfetto/protovm/vm_program.proto
@@ -30,6 +30,7 @@ VmOpMerge merge = 3; VmOpSet set = 4; VmOpDel del = 5; + VmOpInsert insert = 8; } enum AbortLevel { @@ -56,12 +57,14 @@ optional bool create_if_not_exist = 3; // A path component is either: (1) a field id to descend into (common case); - // (2) an array index (for repeated fields); (3) a map lookup operation (for - // repeated fields, where we snoop a sub-field as a map key) + // (2) an hardcoded array index (for repeated fields); (3) an array index in a + // register (for repeated fields) (4) a map lookup operation (for repeated + // fields, where we snoop a sub-field as a map key) message PathComponent { oneof field { uint32 field_id = 1; uint32 array_index = 2; + uint32 array_index_register = 4; // The ID of the field in the repeated submessage that we // use as a key (e.g. LayerState.layer_id). When setting this @@ -117,9 +120,16 @@ // pre-existing field. message VmOpSet {} -// Delete the field or message pointed by DST. +// Deletes the field or message pointed by DST. +// If DST points to an array element (repeated field), subsequent elements are +// shifted left by one position. message VmOpDel {} +// Inserts SRC into DST. If DST points to an array element, the pointed element +// (and the subsequent ones) are shited right by one position. In other cases, +// the operation is semantically equivalent to VmOpSet. +message VmOpInsert {} + enum VmCursorEnum { VM_CURSOR_UNSPECIFIED = 0; VM_CURSOR_SRC = 1;
diff --git a/src/protovm/test/protos/incremental_trace.proto b/src/protovm/test/protos/incremental_trace.proto index 549b939..e0a17c7 100644 --- a/src/protovm/test/protos/incremental_trace.proto +++ b/src/protovm/test/protos/incremental_trace.proto
@@ -29,8 +29,15 @@ repeated Element elements = 1; } +message ElementAndIndex { + optional Element element = 1; + optional int32 index = 2; +} + message Patch { - repeated int32 elements_to_delete = 1; + repeated int32 elements_to_delete_by_id = 1; repeated Element elements_to_merge = 2; repeated Element elements_to_set = 3; -}; + repeated int32 elements_to_delete_by_index = 4; + repeated ElementAndIndex elements_to_insert_by_index = 5; +}
diff --git a/src/protovm/test/sample_packets.h b/src/protovm/test/sample_packets.h index c117617..15b8079 100644 --- a/src/protovm/test/sample_packets.h +++ b/src/protovm/test/sample_packets.h
@@ -69,7 +69,7 @@ static protos::Patch PatchWithDelOperation() { protos::Patch patch; - patch.add_elements_to_delete(0); + patch.add_elements_to_delete_by_id(0); return patch; }
diff --git a/src/protovm/test/sample_programs.h b/src/protovm/test/sample_programs.h index 7aab2d2..4924513 100644 --- a/src/protovm/test/sample_programs.h +++ b/src/protovm/test/sample_programs.h
@@ -268,14 +268,16 @@ perfetto::protos::VmProgram program; constexpr uint32_t REGISTER_HOLDING_ELEMENT_ID = 0; + constexpr uint32_t REGISTER_HOLDING_ELEMENT_INDEX = 1; - // Process elements_to_delete + // Process elements_to_delete_by_id { - // select element to delete (src) + // select element to delete by id (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_field_id( + protos::Patch::kElementsToDeleteByIdFieldNumber); src_element->set_is_repeated(true); { @@ -393,6 +395,101 @@ } } + // SRC: for each Patch.elements_to_delete_by_index[i] + { + 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::kElementsToDeleteByIndexFieldNumber); + src_element->set_is_repeated(true); + + // SRC: load index into register + { + 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_INDEX); + } + + // DST: select TraceEntry.elements[register] + { + 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_array_index = dst_select->add_relative_path(); + component_array_index->set_array_index_register( + REGISTER_HOLDING_ELEMENT_INDEX); + + // delete + { + auto* instr_del = instr_dst_select->add_nested_instructions(); + instr_del->mutable_del(); + } + } + } + + // SRC: for each Patch.elements_to_insert_by_index[i] + { + auto* instr_select_element_and_index = program.add_instructions(); + auto* select_elemente_and_index = + instr_select_element_and_index->mutable_select(); + auto* element_and_index = select_elemente_and_index->add_relative_path(); + element_and_index->set_field_id( + protos::Patch::kElementsToInsertByIndexFieldNumber); + element_and_index->set_is_repeated(true); + + // SRC: select Patch.elements_to_insert_by_index[i].index + { + auto* instr_select_index = + instr_select_element_and_index->add_nested_instructions(); + auto* select_index = instr_select_index->mutable_select(); + auto* index = select_index->add_relative_path(); + index->set_field_id(protos::ElementAndIndex::kIndexFieldNumber); + + // SRC: load index into register + { + auto* instr_reg_load = instr_select_index->add_nested_instructions(); + auto* reg_load = instr_reg_load->mutable_reg_load(); + reg_load->set_dst_register(REGISTER_HOLDING_ELEMENT_INDEX); + } + } + + // SRC: select Patch.elements_to_insert_by_index[i].element + { + auto* instr_select_element = + instr_select_element_and_index->add_nested_instructions(); + auto* select_element = instr_select_element->mutable_select(); + auto* element = select_element->add_relative_path(); + element->set_field_id(protos::ElementAndIndex::kElementFieldNumber); + + // DST: select TraceEntry.elements[register] + { + auto* instr_dst_select_element = + instr_select_element_and_index->add_nested_instructions(); + auto* select_dst_element = instr_dst_select_element->mutable_select(); + select_dst_element->set_cursor( + perfetto::protos::VmCursorEnum::VM_CURSOR_DST); + select_dst_element->set_create_if_not_exist(true); + auto* dst_element = select_dst_element->add_relative_path(); + dst_element->set_field_id(protos::TraceEntry::kElementsFieldNumber); + auto* component_array_index = select_dst_element->add_relative_path(); + component_array_index->set_array_index_register( + REGISTER_HOLDING_ELEMENT_INDEX); + + // insert + { + auto* instr_array_insert = + instr_dst_select_element->add_nested_instructions(); + instr_array_insert->mutable_insert(); + } + } + } + } + return program; } };