Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22,292 changes: 12 additions & 22,280 deletions benchmarks/wasm/compare_wasp/small-snapshot.wat

Large diffs are not rendered by default.

16 changes: 9 additions & 7 deletions genwasym_runtime/include/wasm/concrete_rt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

#include "concrete_num.hpp"
#include "controls.hpp"
#include "immer/vector_transient.hpp"
#include <cstdint>
#include <memory>
#include <optional>
Expand Down Expand Up @@ -39,9 +38,16 @@ class SymFrames_t;

const int FRAME_SIZE = 1024 * 8;

struct FramesRepr;

class Frames_t {
public:
Frames_t();
~Frames_t();
Frames_t(const Frames_t &other);
Frames_t &operator=(const Frames_t &other);
Frames_t(Frames_t &&other) noexcept;
Frames_t &operator=(Frames_t &&other) noexcept;

std::monostate popFrameCaller(std::int32_t size);
std::monostate popFrameCallee(std::int32_t size);
Expand All @@ -62,11 +68,7 @@ class Frames_t {
int32_t count;
Num *stack_ptr;

#ifdef USE_IMM
immer::vector_transient<size_t> frame_ptrs;
#else
std::vector<size_t> frame_ptrs;
#endif
std::unique_ptr<FramesRepr> repr_;
};

extern Frames_t Frames;
Expand Down Expand Up @@ -134,4 +136,4 @@ struct FuncTable_t {

extern FuncTable_t FuncTable;

#endif // WASM_CONCRETE_RT_HPP
#endif // WASM_CONCRETE_RT_HPP
66 changes: 41 additions & 25 deletions genwasym_runtime/include/wasm/sym_rt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@
#include "config.hpp"
#include "controls.hpp"
#include "heap_mem_bookkeeper.hpp"
#include "immer/map.hpp"
#include "immer/map_transient.hpp"
#include "immer/vector.hpp"
#include "immer/vector_transient.hpp"
#include "profile.hpp"
#include "symbolic.hpp"
#include "symval.hpp"
Expand All @@ -34,9 +30,20 @@
#include <vector>

class Snapshot_t;
struct SymStackRepr;
struct SymFramesRepr;
struct SymMemoryRepr;
struct PathConditionsRepr;

class SymStack_t {
public:
SymStack_t();
~SymStack_t();
SymStack_t(const SymStack_t &other);
SymStack_t &operator=(const SymStack_t &other);
SymStack_t(SymStack_t &&other) noexcept;
SymStack_t &operator=(SymStack_t &&other) noexcept;

void push(SymVal val);

SymVal pop();
Expand All @@ -55,18 +62,21 @@ class SymStack_t {

private:
int symbolic_size = 0;
#ifdef USE_IMM
immer::vector_transient<SymVal> stack;
#else
std::vector<SymVal> stack;
#endif
std::unique_ptr<SymStackRepr> repr_;
};

extern SymStack_t SymStack;

class SymFrames_t {

public:
SymFrames_t();
~SymFrames_t();
SymFrames_t(const SymFrames_t &other);
SymFrames_t &operator=(const SymFrames_t &other);
SymFrames_t(SymFrames_t &&other) noexcept;
SymFrames_t &operator=(SymFrames_t &&other) noexcept;

void restore_frame_ptr(Frames_t &frame) const;

void pushFramePtr();
Expand All @@ -93,25 +103,21 @@ class SymFrames_t {
size_t current_frame_base() const;

int symbolic_size = 0;
#ifdef USE_IMM
immer::vector_transient<size_t> frame_ptrs;
immer::vector_transient<SymVal> stack;
#else
std::vector<size_t> frame_ptrs;
std::vector<SymVal> stack;
#endif
std::unique_ptr<SymFramesRepr> repr_;
};

struct NodeBox;
struct SymEnv_t;
class SymEnv_t;

class SymMemory_t {
public:
#ifdef USE_IMM
immer::map_transient<int, SymVal> memory;
#else
std::unordered_map<int, SymVal> memory;
#endif
SymMemory_t();
~SymMemory_t();
SymMemory_t(const SymMemory_t &other);
SymMemory_t &operator=(const SymMemory_t &other);
SymMemory_t(SymMemory_t &&other) noexcept;
SymMemory_t &operator=(SymMemory_t &&other) noexcept;

int symbolic_size = 0;

SymVal loadSymByte(int32_t addr);
Expand Down Expand Up @@ -171,6 +177,13 @@ class SymMemory_t {
std::monostate reset();

int total_sym_size() const;

private:
friend void resume_conc_memory(const SymMemory_t &, Memory_t &,
const SymEnv_t &);
friend void resume_conc_memory_by_model(const SymMemory_t &, Memory_t &,
z3::model &);
std::unique_ptr<SymMemoryRepr> repr_;
};

extern SymMemory_t SymMemory;
Expand Down Expand Up @@ -274,12 +287,15 @@ struct NodeBox {
bool isUnexplored() const;
bool isSnapshotNode() const;
std::vector<SymVal> collect_path_conds();
// Collect and cache path conditions in an immutable vector.
immer::vector<SymVal> collect_path_conds_imm();
// Collect path conditions using the runtime's shared cache.
std::vector<SymVal> collect_path_conds_imm();

[[deprecated]] void reach_here(std::function<void()>);

Node *operator->();

private:
const PathConditionsRepr &cached_path_conds();
};

struct Node {
Expand All @@ -305,7 +321,7 @@ struct Node {

private:
double instr_cost = 0.0;
std::optional<immer::vector<SymVal>> path_conds_cache;
std::shared_ptr<const PathConditionsRepr> path_conds_cache;
};

struct IfElseNode : Node {
Expand Down
16 changes: 10 additions & 6 deletions genwasym_runtime/include/wasm/union_find.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,28 @@
#define WASM_UNION_FIND_HPP

#include "config.hpp"
#include "immer/map.hpp"
#include <immer/map_transient.hpp>
#include <immer/vector.hpp>
#include <memory>
#include <optional>

// TODO: merge this file with headers/gensym/unionfind.hpp with a general implementation in a new PR
struct UnionFindRepr;

class UnionFind {
private:
immer::map_transient<int, int> parent;
immer::map_transient<int, int> rank;
std::unique_ptr<UnionFindRepr> repr_;

public:
UnionFind();
~UnionFind();
UnionFind(const UnionFind &other);
UnionFind &operator=(const UnionFind &other);
UnionFind(UnionFind &&other) noexcept;
UnionFind &operator=(UnionFind &&other) noexcept;

int find(int x) const;
void unite(int x, int y);
bool connected(int x, int y) const;
void clear();
};

#endif // WASM_UNION_FIND_HPP
#endif // WASM_UNION_FIND_HPP
46 changes: 28 additions & 18 deletions genwasym_runtime/lib/concrete_rt.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "wasm/concrete_rt.hpp"
#include "runtime_repr.hpp"

#include <cassert>
#include <cstdio>
Expand Down Expand Up @@ -114,24 +115,40 @@ void Stack_t::set_from_front(int32_t index, const Num &num) {
stack_ptr[index] = num;
}

Frames_t::Frames_t() : count(0), stack_ptr(new Num[FRAME_SIZE]), frame_ptrs() {
Frames_t::Frames_t()
: count(0), stack_ptr(new Num[FRAME_SIZE]),
repr_(std::make_unique<FramesRepr>()) {
size_t page_size = static_cast<size_t>(sysconf(_SC_PAGESIZE));
for (int i = 0; i < FRAME_SIZE; i += page_size) {
stack_ptr[i] = Num(0);
}
}

Frames_t::~Frames_t() = default;
Frames_t::Frames_t(Frames_t &&other) noexcept = default;
Frames_t &Frames_t::operator=(Frames_t &&other) noexcept = default;

Frames_t::Frames_t(const Frames_t &other)
: count(other.count), stack_ptr(other.stack_ptr),
repr_(other.repr_ ? std::make_unique<FramesRepr>(*other.repr_)
: std::make_unique<FramesRepr>()) {}

Frames_t &Frames_t::operator=(const Frames_t &other) {
if (this != &other) *this = Frames_t(other);
return *this;
}

std::monostate Frames_t::popFrameCaller(std::int32_t size) {
assert(size >= 0);
assert(size <= count);
assert(!frame_ptrs.empty());
assert(!repr_->frame_ptrs.empty());
auto frame_base = current_frame_base();
assert(frame_base + size == count);
count -= size;
#ifdef USE_IMM
frame_ptrs.take(frame_ptrs.size() - 1);
repr_->frame_ptrs.take(repr_->frame_ptrs.size() - 1);
#else
frame_ptrs.pop_back();
repr_->frame_ptrs.pop_back();
#endif
return std::monostate{};
}
Expand All @@ -144,7 +161,7 @@ std::monostate Frames_t::popFrameCallee(std::int32_t size) {
}

Num Frames_t::get(std::int32_t index) {
assert(!frame_ptrs.empty() && "No active frame");
assert(!repr_->frame_ptrs.empty() && "No active frame");
auto frame_base = current_frame_base();
assert(index >= 0 && frame_base + index < count && "Index out of bounds");
Profile.step(StepProfileKind::GET);
Expand All @@ -153,16 +170,17 @@ Num Frames_t::get(std::int32_t index) {
}

void Frames_t::set(std::int32_t index, Num num) {
assert(!frame_ptrs.empty() && "No active frame");
assert(!repr_->frame_ptrs.empty() && "No active frame");
auto frame_base = current_frame_base();
assert(index >= 0 && frame_base + index < count && "Index out of bounds");
Profile.step(StepProfileKind::SET);
stack_ptr[frame_base + index] = num;
}

void Frames_t::pushFrameCaller(std::int32_t size) {
if (!repr_) repr_ = std::make_unique<FramesRepr>();
assert(size >= 0);
frame_ptrs.push_back(count);
repr_->frame_ptrs.push_back(count);
count += size;
for (std::int32_t i = 0; i < size; ++i) {
stack_ptr[count - size + i] = Num(0);
Expand All @@ -171,7 +189,7 @@ void Frames_t::pushFrameCaller(std::int32_t size) {

void Frames_t::pushFrameCallee(std::int32_t size) {
assert(size >= 0);
assert(!frame_ptrs.empty() && "No active frame");
assert(!repr_->frame_ptrs.empty() && "No active frame");
auto old_count = count;
count += size;
for (std::int32_t i = 0; i < size; ++i) {
Expand All @@ -181,11 +199,7 @@ void Frames_t::pushFrameCallee(std::int32_t size) {

void Frames_t::reset() {
count = 0;
#ifdef USE_IMM
frame_ptrs = immer::vector_transient<size_t>();
#else
frame_ptrs.clear();
#endif
if (repr_) repr_->frame_ptrs = {};
}

size_t Frames_t::size() const { return count; }
Expand All @@ -201,11 +215,7 @@ void Frames_t::resize(int32_t new_size) {
}

size_t Frames_t::current_frame_base() const {
#ifdef USE_IMM
return *(frame_ptrs.end() - 1);
#else
return frame_ptrs.back();
#endif
return repr_->frame_ptrs[repr_->frame_ptrs.size() - 1];
}

void initRand() {
Expand Down
48 changes: 48 additions & 0 deletions genwasym_runtime/lib/runtime_repr.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#ifndef WASM_RUNTIME_REPR_HPP
#define WASM_RUNTIME_REPR_HPP

#include "wasm/symval.hpp"
#include <immer/map.hpp>
#include <immer/map_transient.hpp>
#include <immer/vector_transient.hpp>
#include <cstddef>
#include <unordered_map>
#include <vector>

#ifdef USE_IMM
using SymbolicStackStorage = immer::vector_transient<SymVal>;
using FramePointers = immer::vector_transient<std::size_t>;
using SymbolicMemoryStorage = immer::map_transient<int, SymVal>;
#else
using SymbolicStackStorage = std::vector<SymVal>;
using FramePointers = std::vector<std::size_t>;
using SymbolicMemoryStorage = std::unordered_map<int, SymVal>;
#endif

struct SymStackRepr {
SymbolicStackStorage stack;
};

struct SymFramesRepr {
SymbolicStackStorage stack;
FramePointers frame_ptrs;
};

struct SymMemoryRepr {
SymbolicMemoryStorage memory;
};

struct FramesRepr {
FramePointers frame_ptrs;
};

struct UnionFindRepr {
immer::map_transient<int, int> parent;
immer::map_transient<int, int> rank;
};

struct PathConditionsRepr {
immer::vector_transient<SymVal> values;
};

#endif // WASM_RUNTIME_REPR_HPP
Loading
Loading