blob: 614b94e690c9308baba6eb1a8a4b2b2ffe3dd1a7 [file] [log] [blame] [edit]
/*
* 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_VM_H_
#define SRC_PROTOVM_VM_H_
#include <memory>
#include "perfetto/protozero/field.h"
#include "src/protovm/error_handling.h"
#include "src/protovm/executor.h"
#include "src/protovm/parser.h"
namespace perfetto {
namespace protovm {
// A VM that executes programs defined by data sources at registration time.
// Used by traced to apply patches (packets overwritten in the ring buffer) to
// an incremental state packet, thus allowing efficient incremental tracing of
// Layers/Windows/Views without requiring periodic invalidation and achieve
// perfect interning.
//
// Overview of the VM's architecture and interactions:
//
//
// ***********
// * *
// * Program *
// * *
// ***********
// │
// │
// │
// ┌───┴──┐ ┌────────┐
// │ │ │ │
// │Parser├────────────┤Executor│
// │ │ │ │
// └──────┘ └─┬────┬─┘
// │ │
// ┌─────┘ └─────┐
// │ │
// │ │
// ┌───┴────┐ ┌───┴────┐
// │ │ │ │
// │RoCursor│ │RwProto │
// │ │ │::Cursor│
// └────┬───┘ │ │
// │ └───┬────┘
// │ │
// │ │
// │ │
// ********* ***************
// * * * *
// * Patch * * Incremental *
// * * * state *
// ********* * *
// ***************
//
// ┌─┐
// │ │ VM's component
// └─┘
//
// ***
// * * Data
// ***
//
//
// Parser: Understands the instructions semantic and controls the program flow.
// It delegates to the Executor operations like navigating through the
// patch and incremental state data, reading values, and manipulating
// fields.
//
//
// Executor: Thin glue layer that mainly forwards data back and forth between
// the Parser and cursors. Mainly useful for testing, as it can
// be easily mocked and allows to test the Parser in isolation.
//
//
// RoCursor: Provides read-only access to the incoming data (the patch) to be
// applied. It allows to traverse the proto message structure of the
// patch, iterating over fields and extracting field values.
//
//
// RwProto::Cursor: Provides read-write access to the incremental state. It
// allows traversing the proto message structure of the
// incremental state, as well as deleting/inserting/merging
// fields.
class Vm {
public:
Vm(protozero::ConstBytes instructions, size_t memory_limit_bytes);
StatusOr<void> ApplyPatch(protozero::ConstBytes packet);
std::string SerializeIncrementalState() const;
private:
Executor executor_;
Parser parser_;
Allocator allocator_;
RwProto incremental_state_;
};
} // namespace protovm
} // namespace perfetto
#endif // SRC_PROTOVM_VM_H_