removed *almost* all unnecessary calls in interpreter code = much speed
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 18 Dec 2022 03:11:43 +0000 (21:11 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 18 Dec 2022 03:11:43 +0000 (21:11 -0600)
interpreter/include/vm.h
interpreter/src/vm/vm.c
interpreter/src/vm/vm_instrs.h
shared/lib/linux_x86_64/lib/libovmwasm.so

index c4804e9b83ebc674e081667fc6968f83167e81d8..89eb78808e95d7308b6fc9ded29c5b9605a7d662 100644 (file)
@@ -129,6 +129,9 @@ bool ovm_program_load_from_file(ovm_program_t *program, ovm_engine_t *engine, ch
 // Represents ephemeral state / execution context.
 // If multiple threads are used, multiple states are needed.
 // 
+
+#define OVM_MAX_PARAM_COUNT 64
+
 struct ovm_state_t {
     ovm_store_t *store;
     ovm_engine_t *engine;
@@ -138,10 +141,12 @@ struct ovm_state_t {
     i32 value_number_offset;
     
     bh_arr(ovm_value_t) numbered_values;
-    bh_arr(ovm_value_t) params;
     bh_arr(ovm_stack_frame_t) stack_frames;
     bh_arr(ovm_value_t) registers;
 
+    ovm_value_t *param_buf;
+    u32          param_count;
+
     //
     // Originally, these were stored on the ovm_program that
     // this state corresponds with. However, that does not line
index 861325f0d2ec55408918d010666a1ad3166b5715..a877ab803481d6ba5e76c0d35073c767f940109d 100644 (file)
@@ -489,15 +489,16 @@ ovm_state_t *ovm_state_new(ovm_engine_t *engine, ovm_program_t *program) {
     state->value_number_offset = 0;
 
     state->numbered_values = NULL;
-    state->params = NULL;
     state->stack_frames = NULL;
     state->registers = NULL;
     bh_arr_new(store->heap_allocator, state->numbered_values, 128);
-    bh_arr_new(store->heap_allocator, state->params, 16);
     bh_arr_new(store->heap_allocator, state->stack_frames, 32);
     bh_arr_new(store->heap_allocator, state->registers, program->register_count);
     bh_arr_insert_end(state->registers, program->register_count);
 
+    state->param_buf = bh_alloc_array(store->arena_allocator, ovm_value_t, OVM_MAX_PARAM_COUNT);
+    state->param_count = 0;
+
     state->external_funcs = NULL;
     bh_arr_new(store->heap_allocator, state->external_funcs, 8);
 
@@ -517,7 +518,6 @@ void ovm_state_delete(ovm_state_t *state) {
     ovm_store_t *store = state->store;
 
     bh_arr_free(state->numbered_values);
-    bh_arr_free(state->params);
     bh_arr_free(state->stack_frames);
     bh_arr_free(state->registers);
     bh_arr_free(state->external_funcs);
@@ -736,11 +736,13 @@ static void __ovm_debug_hook(ovm_engine_t *engine, ovm_state_t *state) {
 #define OVMI_FUNC_NAME(n) ovmi_exec_##n
 #define OVMI_DISPATCH_NAME ovmi_dispatch
 #define OVMI_DEBUG_HOOK ((void)0)
+#define OVMI_EXCEPTION_HOOK ((void)0)
 #include "./vm_instrs.h"
 
 #define OVMI_FUNC_NAME(n) ovmi_exec_debug_##n
 #define OVMI_DISPATCH_NAME ovmi_debug_dispatch
 #define OVMI_DEBUG_HOOK if (state->debug) __ovm_debug_hook(state->engine, state)
+#define OVMI_EXCEPTION_HOOK __ovm_trigger_exception(state)
 #include "./vm_instrs.h"
 
 ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t *program) {
index 6a5d97fa0d78cb2c7f1e9f0b56426a2ff559e8da..08dd165c44e506f87b4c5880db30be31f87d17a8 100644 (file)
@@ -181,7 +181,7 @@ OVMI_INSTR_EXEC(mov) {
     OVMI_INSTR_EXEC(load_##otype) { \
         ovm_assert(VAL(instr->a).type == OVM_TYPE_I32); \
         u32 dest = VAL(instr->a).u32 + (u32) instr->b; \
-        if (dest == 0) __ovm_trigger_exception(state); \
+        if (dest == 0) OVMI_EXCEPTION_HOOK; \
         VAL(instr->r).stype = * (stype *) &memory[dest]; \
         VAL(instr->r).type = type_; \
         NEXT_OP; \
@@ -200,7 +200,7 @@ OVM_LOAD(f64, OVM_TYPE_F64, f64)
     OVMI_INSTR_EXEC(store_##otype) { \
         ovm_assert(VAL(instr->r).type == OVM_TYPE_I32); \
         u32 dest = VAL(instr->r).u32 + (u32) instr->b; \
-        if (dest == 0) __ovm_trigger_exception(state); \
+        if (dest == 0) OVMI_EXCEPTION_HOOK; \
         *(stype *) &memory[dest] = VAL(instr->a).stype; \
         NEXT_OP; \
     }
@@ -220,7 +220,7 @@ OVMI_INSTR_EXEC(copy) {
     u32 src   = VAL(instr->a).u32;
     u32 count = VAL(instr->b).u32;
 
-    if (!dest || !src) __ovm_trigger_exception(state);
+    if (!dest || !src) OVMI_EXCEPTION_HOOK;
 
     memmove(&memory[dest], &memory[src], count);
 
@@ -232,7 +232,7 @@ OVMI_INSTR_EXEC(fill) {
     u8  byte  = VAL(instr->a).u8;
     i32 count = VAL(instr->b).i32;
 
-    if (!dest) __ovm_trigger_exception(state);
+    if (!dest) OVMI_EXCEPTION_HOOK;
 
     memset(&memory[dest], byte, count);
 
@@ -267,7 +267,9 @@ OVMI_INSTR_EXEC(idx_arr) {
 //
 
 OVMI_INSTR_EXEC(param) {
-    bh_arr_push(state->params, VAL(instr->a));
+    // bh_arr_push(state->params, VAL(instr->a));
+    ovm_assert((state->param_count <= OVM_MAX_PARAM_COUNT));
+    state->param_buf[state->param_count++] = VAL(instr->a);
 
     NEXT_OP;
 }
@@ -304,17 +306,17 @@ OVMI_INSTR_EXEC(return) {
 #define OVM_CALL_CODE(func_idx) \
     i32 fidx = func_idx; \
     ovm_func_t *func = &state->program->funcs[fidx]; \
-    i32 extra_params = bh_arr_length(state->params) - func->param_count; \
+    i32 extra_params = state->param_count - func->param_count; \
     ovm_assert(extra_params >= 0); \
     ovm__func_setup_stack_frame(state, func, instr->r); \
-    bh_arr_fastdeleten(state->params, func->param_count); \
+    state->param_count -= func->param_count; \
     if (func->kind == OVM_FUNC_INTERNAL) { \
         values = state->__frame_values; \
-        memcpy(&VAL(0), &state->params[extra_params], func->param_count * sizeof(ovm_value_t)); \
+        memcpy(&VAL(0), &state->param_buf[extra_params], func->param_count * sizeof(ovm_value_t)); \
         state->pc = func->start_instr; \
     } else { \
         ovm_external_func_t external_func = state->external_funcs[func->external_func_idx]; \
-        external_func.native_func(external_func.userdata, &state->params[extra_params], &state->__tmp_value); \
+        external_func.native_func(external_func.userdata, &state->param_buf[extra_params], &state->__tmp_value); \
 \
         ovm__func_teardown_stack_frame(state); \
 \
@@ -438,7 +440,7 @@ OVM_CVT(f64, i64, f64, u64, OVM_TYPE_I64, u64);
 #define CMPXCHG(otype, ctype) \
     OVMI_INSTR_EXEC(cmpxchg_##ctype) { \
         pthread_mutex_lock(&state->engine->atomic_mutex); \
-        if (VAL(instr->r).u32 == 0) __ovm_trigger_exception(state); \
+        if (VAL(instr->r).u32 == 0) OVMI_EXCEPTION_HOOK; \
         ctype *addr = (ctype *) &memory[VAL(instr->r).u32]; \
  \
         VAL(instr->r).u64 = 0; \
@@ -460,7 +462,7 @@ CMPXCHG(OVM_TYPE_I64, i64)
 
 
 OVMI_INSTR_EXEC(illegal) {
-    __ovm_trigger_exception(state);
+    OVMI_EXCEPTION_HOOK;
     return ((ovm_value_t) {0});
 }
 
@@ -579,4 +581,5 @@ static ovmi_instr_exec_t OVMI_DISPATCH_NAME[] = {
 #undef OVMI_FUNC_NAME
 #undef OVMI_DISPATCH_NAME
 #undef OVMI_DEBUG_HOOK
+#undef OVMI_EXCEPTION_HOOK
 
index 5dd76b8520aed91b5240f664eca72213cb147f6c..0cfe7fceedc7bf769a375c0abd6a956a4599558e 100755 (executable)
Binary files a/shared/lib/linux_x86_64/lib/libovmwasm.so and b/shared/lib/linux_x86_64/lib/libovmwasm.so differ