~maelkum/viuavm

4f94a2fb5b1f4441f983c2ea7fcb78486e5c77b7 — Marek Marecki 4 months ago bdc0b31
Add a type to hold memory pages allocated to a process

The backing array is aligned to 8-byte boundary to be able to act as a
backing store for arbitrary types.
3 files changed, 41 insertions(+), 11 deletions(-)

M new/include/viua/vm/core.h
M new/include/viua/vm/ins.h
M new/src/vm/ins.cpp
M new/include/viua/vm/core.h => new/include/viua/vm/core.h +33 -2
@@ 427,6 427,38 @@ struct Stack {
    }
};

inline constexpr auto MEM_LINE_SIZE = size_t{16};
inline constexpr auto MEM_PAGE_SIZE = MEM_LINE_SIZE * 16;
struct Page {
    using unit_type = uint8_t;
    using storage_type = std::array<unit_type, MEM_PAGE_SIZE>;

    alignas(uint64_t) storage_type storage;

    inline constexpr auto data() -> uint8_t*
    {
        return storage.data();
    }
    inline constexpr auto data() const -> uint8_t const*
    {
        return storage.data();
    }

    inline constexpr auto at(size_t const i) -> uint8_t&
    {
        return storage.at(i);
    }
    inline constexpr auto at(size_t const i) const -> uint8_t
    {
        return storage.at(i);
    }

    inline constexpr auto size() const -> size_t
    {
        return storage.size();
    }
};

struct Process {
    using pid_type = viua::runtime::PID;
    pid_type const pid;


@@ 439,8 471,7 @@ struct Process {
    using stack_type = Stack;
    stack_type stack;

    static inline constexpr auto MEM_PAGE_SIZE = size_t{256};
    std::vector<std::array<uint8_t, MEM_PAGE_SIZE>> memory;
    std::vector<Page> memory;

    using Pointer = std::pair<bool, uintptr_t>;
    auto memory_at(Pointer const) const -> void const*;

M new/include/viua/vm/ins.h => new/include/viua/vm/ins.h +1 -1
@@ 129,7 129,7 @@ auto execute(viua::vm::Stack&, viua::arch::instruction_type const* const)
auto print_backtrace(viua::vm::Stack const&,
                     std::optional<size_t> const = std::nullopt) -> void;
auto dump_registers(std::vector<Value> const&, std::string_view const) -> void;
auto dump_memory(std::vector<std::array<uint8_t, Process::MEM_PAGE_SIZE>> const&) -> void;
auto dump_memory(std::vector<Page> const&) -> void;
}  // namespace viua::vm::ins

#endif

M new/src/vm/ins.cpp => new/src/vm/ins.cpp +7 -8
@@ 2025,24 2025,23 @@ auto print_backtrace(Stack const& stack, std::optional<size_t> const only_for)
        }
    }
}
auto dump_memory(std::vector<std::array<uint8_t, Process::MEM_PAGE_SIZE>> const& memory) -> void
auto dump_memory(std::vector<Page> const& memory) -> void
{
    viua::TRACE_STREAM << "  memory:" << viua::TRACE_STREAM.endl;
    constexpr auto MEMORY_LINE_SIZE = size_t{16};

    viua::TRACE_STREAM << std::hex << std::setfill('0');
    for (auto line = size_t{0}; line < (memory.front().size() / MEMORY_LINE_SIZE); ++line) {
    for (auto line = size_t{0}; line < (memory.front().size() / MEM_LINE_SIZE); ++line) {
        viua::TRACE_STREAM << "    ";
        viua::TRACE_STREAM << std::setw(16) << (line * MEMORY_LINE_SIZE) << "  ";
        for (auto i = size_t{0}; i < MEMORY_LINE_SIZE; ++i) {
        viua::TRACE_STREAM << std::setw(16) << (line * MEM_LINE_SIZE) << "  ";
        for (auto i = size_t{0}; i < MEM_LINE_SIZE; ++i) {
            viua::TRACE_STREAM
                << std::setw(2)
                << static_cast<int>(memory.front().at(line * MEMORY_LINE_SIZE + i))
                << static_cast<int>(memory.front().at(line * MEM_LINE_SIZE + i))
                << ' ';
        }
        viua::TRACE_STREAM << " | ";
        for (auto i = size_t{0}; i < MEMORY_LINE_SIZE; ++i) {
            auto const c = memory.front().at(line * MEMORY_LINE_SIZE + i);
        for (auto i = size_t{0}; i < MEM_LINE_SIZE; ++i) {
            auto const c = memory.front().at(line * MEM_LINE_SIZE + i);
            viua::TRACE_STREAM << (isprint(c) ? static_cast<char>(c) : '.');
        }
        viua::TRACE_STREAM << viua::TRACE_STREAM.endl;