Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/hetero migration #34

Open
wants to merge 6 commits into
base: migration_wasmedge2wamr
Choose a base branch
from
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
4 changes: 2 additions & 2 deletions include/driver/tool.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ struct DriverToolOptions {
"Enable generating code for all statistics options include instruction counting, gas measuring, and execution time"sv)),
ConfForceInterpreter(
PO::Description("Forcibly run WASM in interpreter mode."sv)),
DumpFlag(PO::Description("Snapshot statement to img files."sv)),
DumpFlag(PO::Description("Unsnapshot statement to img files."sv)),
RestoreFlag(PO::Description("Restore statement by img files."sv)),
TimeLim(
PO::Description(
Expand Down Expand Up @@ -141,7 +141,7 @@ struct DriverToolOptions {
.add_option("enable-extended-const"sv, PropExtendConst)
.add_option("enable-threads"sv, PropThreads)
.add_option("enable-all"sv, PropAll)
.add_option("snapshot"sv, DumpFlag)
.add_option("no-snapshot"sv, DumpFlag)
.add_option("restore"sv, RestoreFlag)
.add_option("debug-mode"sv, DebugMode)
.add_option("time-limit"sv, TimeLim)
Expand Down
1 change: 1 addition & 0 deletions include/executor/engine/memory.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ TypeN<T> Executor::runStoreOp(Runtime::StackManager &StackMgr,

// Calculate EA = i + offset
uint32_t I = StackMgr.pop().get<uint32_t>();
// std::cerr << "[DEBUG]Memory Base Addr: " << I << std::endl;
if (I > std::numeric_limits<uint32_t>::max() - Instr.getMemoryOffset()) {
spdlog::error(ErrCode::Value::MemoryOutOfBounds);
spdlog::error(ErrInfo::InfoBoundary(
Expand Down
129 changes: 70 additions & 59 deletions include/executor/migrator.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,17 @@ class Migrator {
return std::make_pair(Data.FuncIdx, Offset);
}

uint32_t getFuncIdx(const AST::InstrView::iterator PC) {
if (PC == nullptr) return -1;
struct SourceLoc Data = getSourceLoc(PC);
return Data.FuncIdx;
}

// FunctioninstanceからFuncIdxを取得する
uint32_t getFuncIdx(const Runtime::Instance::FunctionInstance* Func) {
if (Func == nullptr) return -1;
AST::InstrView::iterator PC = Func->getInstrs().begin();
struct SourceLoc Data = getSourceLoc(PC);
return Data.FuncIdx;
return getFuncIdx(PC);
}


Expand Down Expand Up @@ -236,38 +241,39 @@ class Migrator {
}

Expect<void> dumpProgramCounter(const Runtime::Instance::ModuleInstance* ModInst, AST::InstrView::iterator Iter) {
IterMigratorType IterMigrator = getIterMigratorByName(BaseModName);
// IterMigratorType IterMigrator = getIterMigratorByName(BaseModName);
// assert(IterMigrator);

struct SourceLoc Data = IterMigrator[Iter];
// struct SourceLoc Data = IterMigrator[Iter];
std::ofstream ofs("program_counter.img", std::ios::trunc | std::ios::binary);
if (!ofs) {
return Unexpect(ErrCode::Value::IllegalPath);
}

auto Res = ModInst->getFunc(Data.FuncIdx);
if (unlikely(!Res)) {
return Unexpect(Res);
}
Runtime::Instance::FunctionInstance* FuncInst = Res.value();
AST::InstrView::iterator PCStart = FuncInst->getInstrs().begin();
// auto Res = ModInst->getFunc(Data.FuncIdx);
// if (unlikely(!Res)) {
// return Unexpect(Res);
// }
// Runtime::Instance::FunctionInstance* FuncInst = Res.value();
// AST::InstrView::iterator PCStart = FuncInst->getInstrs().begin();


uint32_t Offset = Iter->getOffset() - PCStart->getOffset();
ofs.write(reinterpret_cast<char *>(&Data.FuncIdx), sizeof(uint32_t));
auto [FuncIdx, Offset] = getInstrAddrExpr(ModInst, Iter);
// uint32_t Offset = Iter->getOffset() - PCStart->getOffset();
ofs.write(reinterpret_cast<char *>(&FuncIdx), sizeof(uint32_t));
ofs.write(reinterpret_cast<char *>(&Offset), sizeof(uint32_t));

ofs.close();
return {};
}

void dumpStack(Runtime::StackManager& StackMgr) {
void dumpStack(Runtime::StackManager& StackMgr, AST::InstrView::iterator PC) {
std::vector<Runtime::StackManager::Frame> FrameStack = StackMgr.getFrameStack();
std::vector<uint8_t> TypeStack = StackMgr.getTypeStack();
std::ofstream frame_fout("frame.img", std::ios::trunc | std::ios::binary);

// header file. frame stackのサイズを記録
uint32_t LenFrame = FrameStack.size();
uint32_t LenFrame = FrameStack.size()-1;
frame_fout.write(reinterpret_cast<char *>(&LenFrame), sizeof(uint32_t));
frame_fout.close();

Expand All @@ -278,13 +284,15 @@ class Migrator {
WamrCellSums[I+1] = WamrCellSums[I] + (TypeStack[I] == 0 ? 1 : 2);
}

std::map<std::string_view, bool> seenModInst;
uint32_t PreStackTop = FrameStack[0].VPos - FrameStack[0].Locals;
for (size_t I = 1; I < LenFrame; ++I) {
std::ofstream ofs("stack" + std::to_string(I) + ".img", std::ios::trunc | std::ios::binary);
// uint32_t PreStackTop = FrameStack[0].VPos - FrameStack[0].Locals;
// フレームスタックを上から見ていく。上からstack1, stack2...とする
uint32_t StackIdx = 1;
uint32_t StackTop = StackMgr.size();
for (size_t I = FrameStack.size()-1; I > 0; --I, ++StackIdx) {
std::ofstream ofs("stack" + std::to_string(StackIdx) + ".img", std::ios::trunc | std::ios::binary);
Runtime::StackManager::Frame f = FrameStack[I];

// ModuleInstance
// ModuleInstance
const Runtime::Instance::ModuleInstance* ModInst = f.Module;

// ModInstがnullの場合、ModNameだけ出力してcontinue
Expand All @@ -294,36 +302,40 @@ class Migrator {
}

// 関数インデックス
uint32_t EnterFuncIdx = getFuncIdx(f.EnterFunc);
// uint32_t EnterFuncIdx = getFuncIdx(f.EnterFunc);
uint32_t EnterFuncIdx = getFuncIdx(PC);
ofs.write(reinterpret_cast<char *>(&EnterFuncIdx), sizeof(uint32_t));

// リターンアドレス(uint32 fidx, uint32 offset)
auto [FuncIdx, Offset] = getInstrAddrExpr(ModInst, f.From);
// NOTE: 共通仕様ではリターンアドレスは次に実行するアドレスなのでf.From+1
// I==1のときだけ, f.Fromにend()が入ってるので場合分け
AST::InstrView::iterator From = (I == 1 ? f.From : f.From+1);
auto [FuncIdx, Offset] = getInstrAddrExpr(ModInst, From);
ofs.write(reinterpret_cast<char *>(&FuncIdx), sizeof(uint32_t));
ofs.write(reinterpret_cast<char *>(&Offset), sizeof(uint32_t));

// 型スタック
uint32_t TspOfs = (f.VPos - f.Locals) - PreStackTop;
uint32_t StackBottom = f.VPos - f.Locals;
uint32_t TspOfs = StackTop - StackBottom;
ofs.write(reinterpret_cast<char *>(&TspOfs), sizeof(uint32_t));
for (uint32_t I = PreStackTop; I < PreStackTop+TspOfs; I++) {
for (uint32_t I = StackBottom; I < StackTop; I++) {
ofs.write(reinterpret_cast<char *>(&TypeStack[I]), sizeof(uint8_t));
}

// 値スタック
std::vector<ValVariant> ValueStack = StackMgr.getValueStack();
for (uint32_t I = PreStackTop; I < PreStackTop+TspOfs; I++) {
for (uint32_t I = StackBottom; I < StackTop; I++) {
ofs.write(reinterpret_cast<char *>(&ValueStack[I].get<uint128_t>()), sizeof(uint32_t) * TypeStack[I]);
}
PreStackTop += TspOfs;

// ラベルスタック
auto Res = ModInst->getFunc(FuncIdx);
auto Res = ModInst->getFunc(EnterFuncIdx);
if (!Res) {
std::cerr << "FuncIdx isn't correct" << std::endl;
exit(1);
}
Runtime::Instance::FunctionInstance* FuncInst = Res.value();
std::vector<struct CtrlInfo> CtrlStack = getCtrlStack(f.From, FuncInst, WamrCellSums);
std::vector<struct CtrlInfo> CtrlStack = getCtrlStack(PC, FuncInst, WamrCellSums);
uint32_t LenCs = CtrlStack.size();
ofs.write(reinterpret_cast<char *>(&LenCs), sizeof(uint32_t));
for (uint32_t I = 0; I < LenCs; I++) {
Expand All @@ -338,8 +350,13 @@ class Migrator {

ofs.close();

// 各値を更新
PC = f.From;
StackTop = StackBottom;
// std::cerr << "[DEBUG]StackTop is " << StackTop << std::endl;

// debug
debugFrame(I, EnterFuncIdx, f.Locals, f.Arity, f.VPos);
// debugFrame(I, EnterFuncIdx, f.Locals, f.Arity, f.VPos);
}
}

Expand Down Expand Up @@ -429,10 +446,8 @@ class Migrator {
ifs.read(reinterpret_cast<char *>(&LenFrame), sizeof(uint32_t));
ifs.close();

std::cerr << "frame stack size is " << StackMgr.getFrameStack().size() << std::endl;
std::cerr << "[DEBUG]ValueStack size: " << StackMgr.size() << std::endl;

for (size_t I = 2; I < LenFrame; I++) {
// LenFrame-1から始まるのは、Stack{LenFrame}.imgがダミーフレームだから
for (size_t I = LenFrame-1; I > 0; --I) {
ifs.open("stack" + std::to_string(I) + ".img", std::ios::binary);

// 関数インデックスのロード
Expand All @@ -443,34 +458,12 @@ class Migrator {
uint32_t FuncIdx, Offset;
ifs.read(reinterpret_cast<char *>(&FuncIdx), sizeof(uint32_t));
ifs.read(reinterpret_cast<char *>(&Offset), sizeof(uint32_t));

// 型スタック
uint32_t TspOfs;
std::vector<uint8_t> TypeStack;
ifs.read(reinterpret_cast<char *>(&TspOfs), sizeof(uint32_t));
for (uint32_t I = 0; I < TspOfs; I++) {
uint8_t type;
ifs.read(reinterpret_cast<char *>(&type), sizeof(uint8_t));
TypeStack.push_back(type);
}

// 値スタック
for (uint32_t I = 0; I < TspOfs; I++) {
ValVariant Value;
ifs.read(reinterpret_cast<char *>(&Value), sizeof(uint32_t) * TypeStack[I]);
StackMgr.push(Value, TypeStack[I]);
}

// 最後のフレームは元のWasmEdgeフレームスタックには入ってないもの
// 値スタックと型スタックのみ復元する
if (I == LenFrame-1) break;

// リターンアドレスの復元
auto ResFrom = _restorePC(Module, FuncIdx, Offset);
if (!ResFrom) {
return Unexpect(ResFrom);
}
AST::InstrView::iterator From = ResFrom.value();
AST::InstrView::iterator From = ResFrom.value()-1;

// ローカルと返り値の数
auto ResFunc = Module->getFunc(EnterFuncIdx);
Expand All @@ -485,13 +478,31 @@ class Migrator {

// TODO: Localsに対応する値をenterFunctionと対応してるか確認する
uint32_t Locals = ArgsN + Func->getLocalNum();
uint32_t VPos = StackMgr.getValueStack().size() + Locals;
uint32_t VPos = StackMgr.size() + Locals;

StackMgr._pushFrame(Module, From, Locals, RetsN, VPos, false);

// 型スタック
uint32_t TspOfs;
std::vector<uint8_t> TypeStack;
ifs.read(reinterpret_cast<char *>(&TspOfs), sizeof(uint32_t));
for (uint32_t I = 0; I < TspOfs; I++) {
uint8_t type;
ifs.read(reinterpret_cast<char *>(&type), sizeof(uint8_t));
TypeStack.push_back(type);
}

// 値スタック
for (uint32_t I = 0; I < TspOfs; I++) {
ValVariant Value;
ifs.read(reinterpret_cast<char *>(&Value), sizeof(uint32_t) * TypeStack[I]);
StackMgr.push(Value, TypeStack[I]);
}

StackMgr._pushFrame(Module, From, Func, Locals, RetsN, VPos, false);
ifs.close();

// debug
debugFrame(I, EnterFuncIdx, Locals, RetsN, VPos);
// debugFrame(I, EnterFuncIdx, Locals, RetsN, VPos);
}
return {};
}
Expand Down
16 changes: 7 additions & 9 deletions include/runtime/stackmgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,11 @@ class StackManager {
public:
struct Frame {
Frame() = delete;
Frame(const Instance::ModuleInstance *Mod, AST::InstrView::iterator FromIt, const Instance::FunctionInstance *Func,
Frame(const Instance::ModuleInstance *Mod, AST::InstrView::iterator FromIt,
uint32_t L, uint32_t A, uint32_t V) noexcept
: Module(Mod), From(FromIt), EnterFunc(Func), Locals(L), Arity(A), VPos(V) {}
: Module(Mod), From(FromIt), Locals(L), Arity(A), VPos(V) {}
const Instance::ModuleInstance *Module;
AST::InstrView::iterator From;
const Instance::FunctionInstance *EnterFunc;
uint32_t Locals;
uint32_t Arity;
uint32_t VPos;
Expand Down Expand Up @@ -98,10 +97,10 @@ class StackManager {
}

void _pushFrame(const Instance::ModuleInstance *Module,
AST::InstrView::iterator From, const Runtime::Instance::FunctionInstance *EnterFunc,
AST::InstrView::iterator From,
uint32_t LocalNum, uint32_t Arity, uint32_t VPos, bool IsTailCall) noexcept {
if (likely(!IsTailCall)) {
FrameStack.emplace_back(Module, From, EnterFunc, LocalNum, Arity, VPos);
FrameStack.emplace_back(Module, From, LocalNum, Arity, VPos);
} else {
assuming(!FrameStack.empty());
assuming(FrameStack.back().VPos >= FrameStack.back().Locals);
Expand All @@ -116,7 +115,6 @@ class StackManager {

FrameStack.back().Module = Module;
FrameStack.back().Locals = LocalNum;
FrameStack.back().EnterFunc = EnterFunc;
FrameStack.back().Arity = Arity;
FrameStack.back().VPos = VPos;
}
Expand All @@ -127,13 +125,13 @@ class StackManager {
AST::InstrView::iterator From, uint32_t LocalNum = 0,
uint32_t Arity = 0, bool IsTailCall = false) noexcept {

_pushFrame(Module, From, nullptr, LocalNum, Arity, ValueStack.size(), IsTailCall);
_pushFrame(Module, From, LocalNum, Arity, ValueStack.size(), IsTailCall);
}

void pushFrameExt(const Instance::ModuleInstance *Module,
AST::InstrView::iterator From, const Runtime::Instance::FunctionInstance *EnterFunc,
AST::InstrView::iterator From,
uint32_t LocalNum = 0, uint32_t Arity = 0, bool IsTailCall = false) noexcept {
_pushFrame(Module, From, EnterFunc, LocalNum, Arity, ValueStack.size(), IsTailCall);
_pushFrame(Module, From, LocalNum, Arity, ValueStack.size(), IsTailCall);
}

/// Unsafe pop top frame.
Expand Down
3 changes: 2 additions & 1 deletion lib/executor/engine/debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ void InteractiveMode(SourceLoc &bp, SourceLoc pc, Runtime::StackManager &StackMg
std::cout << "PC is " << pc.FuncIdx << " " << pc.Offset << std::endl;
}
if (commands[1] == "frame") {
Migr.dumpStack(StackMgr);
StackMgr.size();
// Migr.dumpStack(StackMgr, PC);
}
}
else if (commands[0] == "d" || commands[0] == "dump") {
Expand Down
20 changes: 15 additions & 5 deletions lib/executor/engine/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Executor::runFunction(Runtime::StackManager &StackMgr,
}

if (Res) {
if (Conf.getStatisticsConfigure().getDumpFlag() || Conf.getStatisticsConfigure().getRestoreFlag()) {
if (!Conf.getStatisticsConfigure().getDumpFlag() || Conf.getStatisticsConfigure().getRestoreFlag()) {
Migr.preDumpIter(Func.getModule());
}

Expand All @@ -82,6 +82,17 @@ Executor::runFunction(Runtime::StackManager &StackMgr,
Migr.restoreGlobal(StackMgr.getModule());
std::cerr << "Restore global" << std::endl;

// debug: wamrから取り込んだimageをリストアしてすぐdumpすると、同じものが出てくるはず
// Migr.dumpMemory(StackMgr.getModule());
// std::cerr << "Success dumpMemory" << std::endl;
// Migr.dumpGlobal(StackMgr.getModule());
// std::cerr << "Success dumpGlobal" << std::endl;
// Migr.dumpProgramCounter(StackMgr.getModule(), StartIt);
// std::cerr << "Success dumpIter" << std::endl;

// Migr.dumpStack(StackMgr, StartIt);
// std::cerr << "Success dumpStack" << std::endl;

RestoreFlag = false;
}

Expand Down Expand Up @@ -1904,7 +1915,8 @@ Expect<void> Executor::execute(Runtime::StackManager &StackMgr,
}

if (DumpFlag) {
if (Conf.getStatisticsConfigure().getDumpFlag()) {
// DumpFlag=1のとき、すなわち--no-snapshotオプションをつけたときダンプしない
if (!Conf.getStatisticsConfigure().getDumpFlag()) {
// For WasmEdge
Migr.dumpMemory(StackMgr.getModule());
std::cerr << "Success dumpMemory" << std::endl;
Expand All @@ -1913,9 +1925,7 @@ Expect<void> Executor::execute(Runtime::StackManager &StackMgr,
Migr.dumpProgramCounter(StackMgr.getModule(), PC);
std::cerr << "Success dumpIter" << std::endl;

StackMgr.pushFrame(StackMgr.getModule(), PC, 0, 0, false);
Migr.dumpStack(StackMgr);
StackMgr.popFrame();
Migr.dumpStack(StackMgr, PC);
std::cerr << "Success dumpStack" << std::endl;
}
return {};
Expand Down
Loading
Loading