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/migration (classic interpreter) #25

Draft
wants to merge 8 commits into
base: migration-base-commit
Choose a base branch
from
Draft
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
6 changes: 6 additions & 0 deletions build-scripts/runtime_lib.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ if (WAMR_BUILD_DEBUG_INTERP EQUAL 1)
endif ()
endif ()

set (WAMR_BUILD_MIGRATION 1)
if (WAMR_BUILD_MIGRATION EQUAL 1)
include (${IWASM_DIR}/migration/migration.cmake)
endif()

if (WAMR_BUILD_THREAD_MGR EQUAL 1)
include (${IWASM_DIR}/libraries/thread-mgr/thread_mgr.cmake)
endif ()
Expand Down Expand Up @@ -198,6 +203,7 @@ set (source_all
${LIBC_EMCC_SOURCE}
${LIB_RATS_SOURCE}
${DEBUG_ENGINE_SOURCE}
${MIGRATION_SOURCE}
)

set (WAMR_RUNTIME_LIB_SOURCE ${source_all})
5 changes: 5 additions & 0 deletions core/iwasm/common/wasm_runtime_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "../compilation/aot_llvm.h"
#endif
#include "../common/wasm_c_api_internal.h"
#include "../migration/wasm_restore.h"
#include "../../version.h"

/**
Expand Down Expand Up @@ -699,6 +700,10 @@ wasm_runtime_full_init(RuntimeInitArgs *init_args)
return false;
}

if (init_args->restore_flag) {
set_restore_flag(true);
}

#if WASM_ENABLE_THREAD_MGR != 0
wasm_cluster_set_max_thread_num(init_args->max_thread_num);
#endif
Expand Down
2 changes: 2 additions & 0 deletions core/iwasm/include/wasm_export.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ typedef struct RuntimeInitArgs {
uint32_t llvm_jit_size_level;
/* Segue optimization flags for LLVM JIT */
uint32_t segue_flags;
/* Restore from interp.img and frame.img */
bool restore_flag;
/**
* If enabled
* - llvm-jit will output a jitdump file for `perf inject`
Expand Down
111 changes: 110 additions & 1 deletion core/iwasm/interpreter/wasm_interp_classic.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/

#include <time.h>

#include "wasm_interp.h"
#include "bh_log.h"
#include "wasm_runtime.h"
#include "wasm_opcode.h"
#include "wasm_loader.h"
#include "wasm_memory.h"
#include "../common/wasm_exec_env.h"
#include "../migration/wasm_dump.h"
#include "../migration/wasm_restore.h"
#if WASM_ENABLE_SHARED_MEMORY != 0
#include "../common/wasm_shared_memory.h"
#endif
Expand Down Expand Up @@ -1091,7 +1095,18 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
#if WASM_ENABLE_LABELS_AS_VALUES != 0

#define HANDLE_OP(opcode) HANDLE_##opcode:
#define FETCH_OPCODE_AND_DISPATCH() goto *handle_table[*frame_ip++]

#define CHECK_DUMP() \
if (sig_flag) { \
goto migration_async; \
}

// #define FETCH_OPCODE_AND_DISPATCH() goto *handle_table[*frame_ip++]
#define FETCH_OPCODE_AND_DISPATCH() \
do { \
CHECK_DUMP() \
goto *handle_table[*frame_ip++]; \
} while(0);

#if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
#define HANDLE_OP_END() \
Expand All @@ -1107,6 +1122,7 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
wasm_cluster_thread_waiting_run(exec_env); \
} \
os_mutex_unlock(&exec_env->wait_lock); \
CHECK_DUMP(); \
goto *handle_table[*frame_ip++]; \
} while (0)
#else
Expand Down Expand Up @@ -1145,6 +1161,26 @@ get_global_addr(uint8 *global_data, WASMGlobalInstance *global)
#endif
}

static void clear_refs() {
int fd;
char *v = "4";

fd = open("/proc/self/clear_refs", O_WRONLY);
if (write(fd, v, 3) < 3) {
perror("Can't clear soft-dirty bit");
}
close(fd);
}

static bool sig_flag = false;
static void (*native_handler)(void) = NULL;
bool done_flag = false;
void
wasm_interp_sigint(int signum)
{
sig_flag = true;
}

static void
wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMExecEnv *exec_env,
Expand Down Expand Up @@ -1210,11 +1246,84 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#undef HANDLE_OPCODE
#endif

signal(SIGINT, &wasm_interp_sigint);
// Clear soft-dirty bit
clear_refs();

// リストアの初期化時間の計測(終了)
struct timespec ts1;
clock_gettime(CLOCK_MONOTONIC, &ts1);
fprintf(stderr, "boot_end, %lu\n", (uint64_t)(ts1.tv_sec*1e9) + ts1.tv_nsec);

if (get_restore_flag()) {
// bool done_flag;
int rc;
struct timespec ts1, ts2;

clock_gettime(CLOCK_MONOTONIC, &ts1);
frame = wasm_restore_stack(&exec_env);
clock_gettime(CLOCK_MONOTONIC, &ts2);
fprintf(stderr, "stack, %lu\n", get_time(ts1, ts2));
if (frame == NULL) {
perror("Error:wasm_interp_func_bytecode:frame is NULL\n");
return;
}
// debug_wasm_interp_frame(frame, module->e->functions);

cur_func = frame->function;
prev_frame = frame->prev_frame;
if (cur_func == NULL) {
perror("Error:wasm_interp_func_bytecode:cur_func is null\n");
return;
}
if (prev_frame == NULL) {
perror("Error:wasm_interp_func_bytecode:prev_frame is null\n");
return;
}

uint8 *dummy_ip, *dummy_lp, *dummy_sp;
rc = wasm_restore(&module, &exec_env, &cur_func, &prev_frame,
&memory, &globals, &global_data, &global_addr,
&frame, &dummy_ip, &dummy_lp, &dummy_sp, &frame_csp,
&frame_ip_end, &else_addr, &end_addr, &maddr, &done_flag);
if (rc < 0) {
// error
perror("failed to restore\n");
return;
}
frame_ip = dummy_ip;
frame_lp = dummy_lp;
frame_sp = dummy_sp;
frame->ip = frame_ip;
linear_mem_size = memory ? memory->memory_data_size : 0;

frame_lp = frame->lp;
UPDATE_ALL_FROM_FRAME();
FETCH_OPCODE_AND_DISPATCH();
}

#if WASM_ENABLE_LABELS_AS_VALUES == 0
while (frame_ip < frame_ip_end) {
opcode = *frame_ip++;
switch (opcode) {
#else
migration_async:
if (sig_flag) {
SYNC_ALL_TO_FRAME();
uint8 *dummy_ip, *dummy_sp;
dummy_ip = frame_ip;
dummy_sp = frame_sp;
int rc = wasm_dump(exec_env, module, memory,
globals, global_data, global_addr, cur_func,
frame, dummy_ip, dummy_sp, frame_csp,
frame_ip_end, else_addr, end_addr, maddr, done_flag);
if (rc < 0) {
perror("failed to dump\n");
exit(1);
}
LOG_DEBUG("dispatch_count: %d\n", dispatch_count);
exit(0);
}
FETCH_OPCODE_AND_DISPATCH();
#endif
/* control instructions */
Expand Down
9 changes: 9 additions & 0 deletions core/iwasm/migration/migration.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
set (MIGRATION_DIR ${CMAKE_CURRENT_LIST_DIR})

add_definitions (-DWASM_ENABLE_MIGRATION=1)

include_directories(${MIGRATION_DIR})

file (GLOB source_all ${MIGRATION_DIR}/*.c)

set (MIGRATION_SOURCE ${source_all})
164 changes: 164 additions & 0 deletions core/iwasm/migration/wasm_dispatch.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
#include <stdio.h>
#include <stdlib.h>

#include "../interpreter/wasm_runtime.h"
#include "../interpreter/wasm_opcode.h"
#include "wasm_dispatch.h"

static uint64
read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
{
uint64 result = 0, byte;
uint32 offset = *p_offset;
uint32 shift = 0;

while (true) {
byte = buf[offset++];
result |= ((byte & 0x7f) << shift);
shift += 7;
if ((byte & 0x80) == 0) {
break;
}
}
if (sign && (shift < maxbits) && (byte & 0x40)) {
/* Sign extend */
result |= (~((uint64)0)) << shift;
}
*p_offset = offset;
return result;
}

#define read_leb_uint32(p, p_end, res) \
do { \
uint8 _val = *p; \
if (!(_val & 0x80)) { \
res = _val; \
p++; \
break; \
} \
uint32 _off = 0; \
res = (uint32)read_leb(p, &_off, 32, false); \
p += _off; \
} while (0)

#define skip_leb(p) while (*p++ & 0x80)

// *ipにopcodeが入ってる状態で引数に渡す
uint8* dispatch(uint8 *ip, uint8 *ip_end) {
uint32 lidx;
switch (*ip++) {
case WASM_OP_CALL_INDIRECT:
case WASM_OP_RETURN_CALL_INDIRECT:
skip_leb(ip);
skip_leb(ip);
break;
case WASM_OP_BR_TABLE:
read_leb_uint32(ip, ip_end, lidx);
for (uint32 i = 0; i < lidx; i++)
skip_leb(ip);
skip_leb(ip);
break;
/* control instructions */
case EXT_OP_BLOCK:
case WASM_OP_BLOCK:
case EXT_OP_LOOP:
case WASM_OP_LOOP:
case EXT_OP_IF:
case WASM_OP_IF:
case WASM_OP_BR:
case WASM_OP_BR_IF:
case WASM_OP_CALL:
case WASM_OP_RETURN_CALL:
#if WASM_ENABLE_REF_TYPES != 0
case WASM_OP_SELECT_T:
case WASM_OP_TABLE_GET:
case WASM_OP_TABLE_SET:
case WASM_OP_REF_NULL:
case WASM_OP_REF_FUNC:
#endif
/* variable instructions */
case WASM_OP_GET_LOCAL:
case WASM_OP_SET_LOCAL:
case WASM_OP_TEE_LOCAL:
case WASM_OP_GET_GLOBAL:
case WASM_OP_GET_GLOBAL_64:
case WASM_OP_SET_GLOBAL:
case WASM_OP_SET_GLOBAL_AUX_STACK:
case WASM_OP_SET_GLOBAL_64:
skip_leb(ip);
break;
case EXT_OP_GET_LOCAL_FAST:
case EXT_OP_SET_LOCAL_FAST:
case EXT_OP_TEE_LOCAL_FAST:
ip++;
break;
/* memory load instructions */
case WASM_OP_I32_LOAD:
case WASM_OP_F32_LOAD:
case WASM_OP_I64_LOAD:
case WASM_OP_F64_LOAD:
case WASM_OP_I32_LOAD8_S:
case WASM_OP_I32_LOAD8_U:
case WASM_OP_I32_LOAD16_S:
case WASM_OP_I32_LOAD16_U:
case WASM_OP_I64_LOAD8_S:
case WASM_OP_I64_LOAD8_U:
case WASM_OP_I64_LOAD16_S:
case WASM_OP_I64_LOAD16_U:
case WASM_OP_I64_LOAD32_S:
case WASM_OP_I64_LOAD32_U:
case WASM_OP_I32_STORE:
case WASM_OP_F32_STORE:
case WASM_OP_I64_STORE:
case WASM_OP_F64_STORE:
case WASM_OP_I32_STORE8:
case WASM_OP_I32_STORE16:
case WASM_OP_I64_STORE8:
case WASM_OP_I64_STORE16:
case WASM_OP_I64_STORE32:
case WASM_OP_MEMORY_SIZE:
case WASM_OP_MEMORY_GROW:
skip_leb(ip);
skip_leb(ip);
break;
/* constant instructions */
case WASM_OP_I32_CONST:
case WASM_OP_I64_CONST:
skip_leb(ip);
break;
case WASM_OP_F32_CONST:
ip += sizeof(float32);
break;
case WASM_OP_F64_CONST:
ip += sizeof(float64);
break;
case WASM_OP_MISC_PREFIX:
skip_leb(ip);
switch (*ip++) {
#if WASM_ENABLE_BULK_MEMORY != 0
case WASM_OP_MEMORY_INIT:
case WASM_OP_DATA_DROP:
case WASM_OP_MEMORY_COPY:
case WASM_OP_MEMORY_FILL:
#endif /* WASM_ENABLE_BULK_MEMORY */
#if WASM_ENABLE_REF_TYPES != 0
case WASM_OP_TABLE_INIT:
case WASM_OP_ELEM_DROP:
case WASM_OP_TABLE_COPY:
case WASM_OP_TABLE_GROW:
case WASM_OP_TABLE_SIZE:
case WASM_OP_TABLE_FILL:
#endif /* WASM_ENABLE_REF_TYPES */
skip_leb(ip);
default:
break;
}

case WASM_OP_ATOMIC_PREFIX:
/* TODO */
break;
default:
break;
}
return ip;
}
2 changes: 2 additions & 0 deletions core/iwasm/migration/wasm_dispatch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#include "../interpreter/wasm_runtime.h"
uint8* dispatch(uint8 *ip, uint8 *ip_end);
Loading
Loading