Refine Fast JIT accessing memory/table instance and global data (#1623)

Some offsets can be directly gotten at the compilation stage after the interp/AOT
module instance refactoring PR was merged, so as to reduce some unnecessary
load instructions and improve the Fast JIT performance:
- Access fields of wasm memory instance structure
- Access fields of wasm table instance structure
- Access the global data
This commit is contained in:
Wenyong Huang 2022-10-21 09:32:51 +08:00 committed by GitHub
parent 4c61bfd10d
commit bbfa39c32c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 199 additions and 199 deletions

View File

@ -459,7 +459,7 @@ jit_compile_op_call_indirect(JitCompContext *cc, uint32 type_idx,
JitReg elem_idx, native_ret, argv, arg_regs[6]; JitReg elem_idx, native_ret, argv, arg_regs[6];
JitFrame *jit_frame = cc->jit_frame; JitFrame *jit_frame = cc->jit_frame;
JitReg tbl_size, offset, offset_i32; JitReg tbl_size, offset, offset_i32;
JitReg func_import, func_idx, tbl_data, func_count; JitReg func_import, func_idx, tbl_elems, func_count;
JitReg func_type_indexes, func_type_idx, fast_jit_func_ptrs; JitReg func_type_indexes, func_type_idx, fast_jit_func_ptrs;
JitReg offset1_i32, offset1, func_type_idx1, res; JitReg offset1_i32, offset1, func_type_idx1, res;
JitReg import_func_ptrs, jitted_code_idx, jitted_code; JitReg import_func_ptrs, jitted_code_idx, jitted_code;
@ -488,8 +488,8 @@ jit_compile_op_call_indirect(JitCompContext *cc, uint32 type_idx,
GEN_INSN(SHL, offset, elem_idx, NEW_CONST(I32, 2)); GEN_INSN(SHL, offset, elem_idx, NEW_CONST(I32, 2));
} }
func_idx = jit_cc_new_reg_I32(cc); func_idx = jit_cc_new_reg_I32(cc);
tbl_data = get_table_data_reg(jit_frame, tbl_idx); tbl_elems = get_table_elems_reg(jit_frame, tbl_idx);
GEN_INSN(LDI32, func_idx, tbl_data, offset); GEN_INSN(LDI32, func_idx, tbl_elems, offset);
GEN_INSN(CMP, cc->cmp_reg, func_idx, NEW_CONST(I32, -1)); GEN_INSN(CMP, cc->cmp_reg, func_idx, NEW_CONST(I32, -1));
if (!jit_emit_exception(cc, EXCE_UNINITIALIZED_ELEMENT, JIT_OP_BEQ, if (!jit_emit_exception(cc, EXCE_UNINITIALIZED_ELEMENT, JIT_OP_BEQ,

View File

@ -136,14 +136,17 @@ check_and_seek(JitCompContext *cc, JitReg addr, uint32 offset, uint32 bytes)
/* ---------- check ---------- */ /* ---------- check ---------- */
/* 1. shortcut if the memory size is 0 */ /* 1. shortcut if the memory size is 0 */
if (0 == cc->cur_wasm_module->memories[mem_idx].init_page_count) { if (0 == cc->cur_wasm_module->memories[mem_idx].init_page_count) {
JitReg memory_inst, cur_mem_page_count; JitReg module_inst, cur_page_count;
uint32 cur_page_count_offset =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
+ (uint32)offsetof(WASMMemoryInstance, cur_page_count);
/* if (cur_mem_page_count == 0) goto EXCEPTION */ /* if (cur_mem_page_count == 0) goto EXCEPTION */
memory_inst = get_memory_inst_reg(cc->jit_frame, mem_idx); module_inst = get_module_inst_reg(cc->jit_frame);
cur_mem_page_count = jit_cc_new_reg_I32(cc); cur_page_count = jit_cc_new_reg_I32(cc);
GEN_INSN(LDI32, cur_mem_page_count, memory_inst, GEN_INSN(LDI32, cur_page_count, module_inst,
NEW_CONST(I32, offsetof(WASMMemoryInstance, cur_page_count))); NEW_CONST(I32, cur_page_count_offset));
GEN_INSN(CMP, cc->cmp_reg, cur_mem_page_count, NEW_CONST(I32, 0)); GEN_INSN(CMP, cc->cmp_reg, cur_page_count, NEW_CONST(I32, 0));
if (!jit_emit_exception(cc, EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, if (!jit_emit_exception(cc, EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS,
JIT_OP_BEQ, cc->cmp_reg, NULL)) { JIT_OP_BEQ, cc->cmp_reg, NULL)) {
goto fail; goto fail;
@ -493,15 +496,17 @@ fail:
bool bool
jit_compile_op_memory_size(JitCompContext *cc, uint32 mem_idx) jit_compile_op_memory_size(JitCompContext *cc, uint32 mem_idx)
{ {
JitReg mem_inst, res; JitReg module_inst, cur_page_count;
uint32 cur_page_count_offset =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
+ (uint32)offsetof(WASMMemoryInstance, cur_page_count);
mem_inst = get_memory_inst_reg(cc->jit_frame, mem_idx); module_inst = get_module_inst_reg(cc->jit_frame);
cur_page_count = jit_cc_new_reg_I32(cc);
GEN_INSN(LDI32, cur_page_count, module_inst,
NEW_CONST(I32, cur_page_count_offset));
res = jit_cc_new_reg_I32(cc); PUSH_I32(cur_page_count);
GEN_INSN(LDI32, res, mem_inst,
NEW_CONST(I32, offsetof(WASMMemoryInstance, cur_page_count)));
PUSH_I32(res);
return true; return true;
fail: fail:
@ -511,14 +516,18 @@ fail:
bool bool
jit_compile_op_memory_grow(JitCompContext *cc, uint32 mem_idx) jit_compile_op_memory_grow(JitCompContext *cc, uint32 mem_idx)
{ {
JitReg memory_inst, grow_res, res; JitReg module_inst, grow_res, res;
JitReg prev_page_count, inc_page_count, args[2]; JitReg prev_page_count, inc_page_count, args[2];
/* Get current page count */ /* Get current page count */
memory_inst = get_memory_inst_reg(cc->jit_frame, mem_idx); uint32 cur_page_count_offset =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
+ (uint32)offsetof(WASMMemoryInstance, cur_page_count);
module_inst = get_module_inst_reg(cc->jit_frame);
prev_page_count = jit_cc_new_reg_I32(cc); prev_page_count = jit_cc_new_reg_I32(cc);
GEN_INSN(LDI32, prev_page_count, memory_inst, GEN_INSN(LDI32, prev_page_count, module_inst,
NEW_CONST(I32, offsetof(WASMMemoryInstance, cur_page_count))); NEW_CONST(I32, cur_page_count_offset));
/* Call wasm_enlarge_memory */ /* Call wasm_enlarge_memory */
POP_I32(inc_page_count); POP_I32(inc_page_count);

View File

@ -30,7 +30,7 @@ jit_compile_op_elem_drop(JitCompContext *cc, uint32 tbl_seg_idx)
bool bool
jit_compile_op_table_get(JitCompContext *cc, uint32 tbl_idx) jit_compile_op_table_get(JitCompContext *cc, uint32 tbl_idx)
{ {
JitReg elem_idx, tbl_sz, tbl_data, elem_idx_long, offset, res; JitReg elem_idx, tbl_sz, tbl_elems, elem_idx_long, offset, res;
POP_I32(elem_idx); POP_I32(elem_idx);
@ -48,8 +48,8 @@ jit_compile_op_table_get(JitCompContext *cc, uint32 tbl_idx)
GEN_INSN(MUL, offset, elem_idx_long, NEW_CONST(I64, sizeof(uint32))); GEN_INSN(MUL, offset, elem_idx_long, NEW_CONST(I64, sizeof(uint32)));
res = jit_cc_new_reg_I32(cc); res = jit_cc_new_reg_I32(cc);
tbl_data = get_table_data_reg(cc->jit_frame, tbl_idx); tbl_elems = get_table_elems_reg(cc->jit_frame, tbl_idx);
GEN_INSN(LDI32, res, tbl_data, offset); GEN_INSN(LDI32, res, tbl_elems, offset);
PUSH_I32(res); PUSH_I32(res);
return true; return true;
@ -60,7 +60,7 @@ fail:
bool bool
jit_compile_op_table_set(JitCompContext *cc, uint32 tbl_idx) jit_compile_op_table_set(JitCompContext *cc, uint32 tbl_idx)
{ {
JitReg elem_idx, elem_val, tbl_sz, tbl_data, elem_idx_long, offset; JitReg elem_idx, elem_val, tbl_sz, tbl_elems, elem_idx_long, offset;
POP_I32(elem_val); POP_I32(elem_val);
POP_I32(elem_idx); POP_I32(elem_idx);
@ -78,8 +78,8 @@ jit_compile_op_table_set(JitCompContext *cc, uint32 tbl_idx)
offset = jit_cc_new_reg_I64(cc); offset = jit_cc_new_reg_I64(cc);
GEN_INSN(MUL, offset, elem_idx_long, NEW_CONST(I64, sizeof(uint32))); GEN_INSN(MUL, offset, elem_idx_long, NEW_CONST(I64, sizeof(uint32)));
tbl_data = get_table_data_reg(cc->jit_frame, tbl_idx); tbl_elems = get_table_elems_reg(cc->jit_frame, tbl_idx);
GEN_INSN(STI32, elem_val, tbl_data, offset); GEN_INSN(STI32, elem_val, tbl_elems, offset);
return true; return true;
fail: fail:

View File

@ -180,15 +180,32 @@ get_global_type(const WASMModule *module, uint32 global_idx)
static uint32 static uint32
get_global_data_offset(const WASMModule *module, uint32 global_idx) get_global_data_offset(const WASMModule *module, uint32 global_idx)
{ {
uint32 module_inst_struct_size =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes);
uint32 mem_inst_size =
(uint32)sizeof(WASMMemoryInstance)
* (module->import_memory_count + module->memory_count);
uint32 global_base_offset;
#if WASM_ENABLE_JIT != 0
/* If the module dosen't have memory, reserve one mem_info space
with empty content to align with llvm jit compiler */
if (mem_inst_size == 0)
mem_inst_size = (uint32)sizeof(WASMMemoryInstance);
#endif
/* Size of module inst and memory instances */
global_base_offset = module_inst_struct_size + mem_inst_size;
if (global_idx < module->import_global_count) { if (global_idx < module->import_global_count) {
const WASMGlobalImport *import_global = const WASMGlobalImport *import_global =
&((module->import_globals + global_idx)->u.global); &((module->import_globals + global_idx)->u.global);
return import_global->data_offset; return global_base_offset + import_global->data_offset;
} }
else { else {
const WASMGlobal *global = const WASMGlobal *global =
module->globals + (global_idx - module->import_global_count); module->globals + (global_idx - module->import_global_count);
return global->data_offset; return global_base_offset + global->data_offset;
} }
} }
@ -204,6 +221,7 @@ jit_compile_op_get_global(JitCompContext *cc, uint32 global_idx)
data_offset = get_global_data_offset(cc->cur_wasm_module, global_idx); data_offset = get_global_data_offset(cc->cur_wasm_module, global_idx);
global_type = get_global_type(cc->cur_wasm_module, global_idx); global_type = get_global_type(cc->cur_wasm_module, global_idx);
switch (global_type) { switch (global_type) {
case VALUE_TYPE_I32: case VALUE_TYPE_I32:
#if WASM_ENABLE_REF_TYPES != 0 #if WASM_ENABLE_REF_TYPES != 0
@ -212,28 +230,28 @@ jit_compile_op_get_global(JitCompContext *cc, uint32 global_idx)
#endif #endif
{ {
value = jit_cc_new_reg_I32(cc); value = jit_cc_new_reg_I32(cc);
GEN_INSN(LDI32, value, get_global_data_reg(cc->jit_frame), GEN_INSN(LDI32, value, get_module_inst_reg(cc->jit_frame),
NEW_CONST(I32, data_offset)); NEW_CONST(I32, data_offset));
break; break;
} }
case VALUE_TYPE_I64: case VALUE_TYPE_I64:
{ {
value = jit_cc_new_reg_I64(cc); value = jit_cc_new_reg_I64(cc);
GEN_INSN(LDI64, value, get_global_data_reg(cc->jit_frame), GEN_INSN(LDI64, value, get_module_inst_reg(cc->jit_frame),
NEW_CONST(I32, data_offset)); NEW_CONST(I32, data_offset));
break; break;
} }
case VALUE_TYPE_F32: case VALUE_TYPE_F32:
{ {
value = jit_cc_new_reg_F32(cc); value = jit_cc_new_reg_F32(cc);
GEN_INSN(LDF32, value, get_global_data_reg(cc->jit_frame), GEN_INSN(LDF32, value, get_module_inst_reg(cc->jit_frame),
NEW_CONST(I32, data_offset)); NEW_CONST(I32, data_offset));
break; break;
} }
case VALUE_TYPE_F64: case VALUE_TYPE_F64:
{ {
value = jit_cc_new_reg_F64(cc); value = jit_cc_new_reg_F64(cc);
GEN_INSN(LDF64, value, get_global_data_reg(cc->jit_frame), GEN_INSN(LDF64, value, get_module_inst_reg(cc->jit_frame),
NEW_CONST(I32, data_offset)); NEW_CONST(I32, data_offset));
break; break;
} }
@ -264,6 +282,7 @@ jit_compile_op_set_global(JitCompContext *cc, uint32 global_idx,
data_offset = get_global_data_offset(cc->cur_wasm_module, global_idx); data_offset = get_global_data_offset(cc->cur_wasm_module, global_idx);
global_type = get_global_type(cc->cur_wasm_module, global_idx); global_type = get_global_type(cc->cur_wasm_module, global_idx);
switch (global_type) { switch (global_type) {
case VALUE_TYPE_I32: case VALUE_TYPE_I32:
#if WASM_ENABLE_REF_TYPES != 0 #if WASM_ENABLE_REF_TYPES != 0
@ -285,28 +304,28 @@ jit_compile_op_set_global(JitCompContext *cc, uint32 global_idx,
JIT_OP_BGTU, cc->cmp_reg, NULL))) JIT_OP_BGTU, cc->cmp_reg, NULL)))
goto fail; goto fail;
} }
GEN_INSN(STI32, value, get_global_data_reg(cc->jit_frame), GEN_INSN(STI32, value, get_module_inst_reg(cc->jit_frame),
NEW_CONST(I32, data_offset)); NEW_CONST(I32, data_offset));
break; break;
} }
case VALUE_TYPE_I64: case VALUE_TYPE_I64:
{ {
POP_I64(value); POP_I64(value);
GEN_INSN(STI64, value, get_global_data_reg(cc->jit_frame), GEN_INSN(STI64, value, get_module_inst_reg(cc->jit_frame),
NEW_CONST(I32, data_offset)); NEW_CONST(I32, data_offset));
break; break;
} }
case VALUE_TYPE_F32: case VALUE_TYPE_F32:
{ {
POP_F32(value); POP_F32(value);
GEN_INSN(STF32, value, get_global_data_reg(cc->jit_frame), GEN_INSN(STF32, value, get_module_inst_reg(cc->jit_frame),
NEW_CONST(I32, data_offset)); NEW_CONST(I32, data_offset));
break; break;
} }
case VALUE_TYPE_F64: case VALUE_TYPE_F64:
{ {
POP_F64(value); POP_F64(value);
GEN_INSN(STF64, value, get_global_data_reg(cc->jit_frame), GEN_INSN(STF64, value, get_module_inst_reg(cc->jit_frame),
NEW_CONST(I32, data_offset)); NEW_CONST(I32, data_offset));
break; break;
} }

View File

@ -93,20 +93,6 @@ get_func_type_indexes_reg(JitFrame *frame)
return frame->func_type_indexes_reg; return frame->func_type_indexes_reg;
} }
JitReg
get_global_data_reg(JitFrame *frame)
{
JitCompContext *cc = frame->cc;
JitReg module_inst_reg = get_module_inst_reg(frame);
if (!frame->global_data_reg) {
frame->global_data_reg = cc->global_data_reg;
GEN_INSN(LDPTR, frame->global_data_reg, module_inst_reg,
NEW_CONST(I32, offsetof(WASMModuleInstance, global_data)));
}
return frame->global_data_reg;
}
JitReg JitReg
get_aux_stack_bound_reg(JitFrame *frame) get_aux_stack_bound_reg(JitFrame *frame)
{ {
@ -135,48 +121,22 @@ get_aux_stack_bottom_reg(JitFrame *frame)
return frame->aux_stack_bottom_reg; return frame->aux_stack_bottom_reg;
} }
JitReg
get_memories_reg(JitFrame *frame)
{
JitCompContext *cc = frame->cc;
JitReg module_inst_reg = get_module_inst_reg(frame);
if (!frame->memories_reg) {
frame->memories_reg = cc->memories_reg;
GEN_INSN(LDPTR, frame->memories_reg, module_inst_reg,
NEW_CONST(I32, offsetof(WASMModuleInstance, memories)));
}
return frame->memories_reg;
}
JitReg
get_memory_inst_reg(JitFrame *frame, uint32 mem_idx)
{
JitCompContext *cc = frame->cc;
JitReg memories_reg = get_memories_reg(frame);
if (!frame->memory_regs[mem_idx].memory_inst) {
frame->memory_regs[mem_idx].memory_inst =
cc->memory_regs[mem_idx].memory_inst;
GEN_INSN(
LDPTR, frame->memory_regs[mem_idx].memory_inst, memories_reg,
NEW_CONST(I32, (uint32)sizeof(WASMMemoryInstance *) * mem_idx));
}
return frame->memory_regs[mem_idx].memory_inst;
}
JitReg JitReg
get_memory_data_reg(JitFrame *frame, uint32 mem_idx) get_memory_data_reg(JitFrame *frame, uint32 mem_idx)
{ {
JitCompContext *cc = frame->cc; JitCompContext *cc = frame->cc;
JitReg memory_inst_reg = get_memory_inst_reg(frame, mem_idx); JitReg module_inst_reg = get_module_inst_reg(frame);
uint32 memory_data_offset =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
+ (uint32)offsetof(WASMMemoryInstance, memory_data);
bh_assert(mem_idx == 0);
if (!frame->memory_regs[mem_idx].memory_data) { if (!frame->memory_regs[mem_idx].memory_data) {
frame->memory_regs[mem_idx].memory_data = frame->memory_regs[mem_idx].memory_data =
cc->memory_regs[mem_idx].memory_data; cc->memory_regs[mem_idx].memory_data;
GEN_INSN(LDPTR, frame->memory_regs[mem_idx].memory_data, GEN_INSN(LDPTR, frame->memory_regs[mem_idx].memory_data,
memory_inst_reg, module_inst_reg, NEW_CONST(I32, memory_data_offset));
NEW_CONST(I32, offsetof(WASMMemoryInstance, memory_data)));
} }
return frame->memory_regs[mem_idx].memory_data; return frame->memory_regs[mem_idx].memory_data;
} }
@ -185,14 +145,18 @@ JitReg
get_memory_data_end_reg(JitFrame *frame, uint32 mem_idx) get_memory_data_end_reg(JitFrame *frame, uint32 mem_idx)
{ {
JitCompContext *cc = frame->cc; JitCompContext *cc = frame->cc;
JitReg memory_inst_reg = get_memory_inst_reg(frame, mem_idx); JitReg module_inst_reg = get_module_inst_reg(frame);
uint32 memory_data_end_offset =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
+ (uint32)offsetof(WASMMemoryInstance, memory_data_end);
bh_assert(mem_idx == 0);
if (!frame->memory_regs[mem_idx].memory_data_end) { if (!frame->memory_regs[mem_idx].memory_data_end) {
frame->memory_regs[mem_idx].memory_data_end = frame->memory_regs[mem_idx].memory_data_end =
cc->memory_regs[mem_idx].memory_data_end; cc->memory_regs[mem_idx].memory_data_end;
GEN_INSN(LDPTR, frame->memory_regs[mem_idx].memory_data_end, GEN_INSN(LDPTR, frame->memory_regs[mem_idx].memory_data_end,
memory_inst_reg, module_inst_reg, NEW_CONST(I32, memory_data_end_offset));
NEW_CONST(I32, offsetof(WASMMemoryInstance, memory_data_end)));
} }
return frame->memory_regs[mem_idx].memory_data_end; return frame->memory_regs[mem_idx].memory_data_end;
} }
@ -201,21 +165,22 @@ JitReg
get_mem_bound_check_1byte_reg(JitFrame *frame, uint32 mem_idx) get_mem_bound_check_1byte_reg(JitFrame *frame, uint32 mem_idx)
{ {
JitCompContext *cc = frame->cc; JitCompContext *cc = frame->cc;
JitReg memory_inst_reg = get_memory_inst_reg(frame, mem_idx); JitReg module_inst_reg = get_module_inst_reg(frame);
uint32 mem_bound_check_1byte_offset =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_1byte);
bh_assert(mem_idx == 0);
if (!frame->memory_regs[mem_idx].mem_bound_check_1byte) { if (!frame->memory_regs[mem_idx].mem_bound_check_1byte) {
frame->memory_regs[mem_idx].mem_bound_check_1byte = frame->memory_regs[mem_idx].mem_bound_check_1byte =
cc->memory_regs[mem_idx].mem_bound_check_1byte; cc->memory_regs[mem_idx].mem_bound_check_1byte;
#if UINTPTR_MAX == UINT64_MAX #if UINTPTR_MAX == UINT64_MAX
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_1byte, GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_1byte,
memory_inst_reg, module_inst_reg, NEW_CONST(I32, mem_bound_check_1byte_offset));
NEW_CONST(
I32, offsetof(WASMMemoryInstance, mem_bound_check_1byte)));
#else #else
GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_1byte, GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_1byte,
memory_inst_reg, module_inst_reg, NEW_CONST(I32, mem_bound_check_1byte_offset));
NEW_CONST(
I32, offsetof(WASMMemoryInstance, mem_bound_check_1byte)));
#endif #endif
} }
return frame->memory_regs[mem_idx].mem_bound_check_1byte; return frame->memory_regs[mem_idx].mem_bound_check_1byte;
@ -225,21 +190,24 @@ JitReg
get_mem_bound_check_2bytes_reg(JitFrame *frame, uint32 mem_idx) get_mem_bound_check_2bytes_reg(JitFrame *frame, uint32 mem_idx)
{ {
JitCompContext *cc = frame->cc; JitCompContext *cc = frame->cc;
JitReg memory_inst_reg = get_memory_inst_reg(frame, mem_idx); JitReg module_inst_reg = get_module_inst_reg(frame);
uint32 mem_bound_check_2bytes_offset =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_2bytes);
bh_assert(mem_idx == 0);
if (!frame->memory_regs[mem_idx].mem_bound_check_2bytes) { if (!frame->memory_regs[mem_idx].mem_bound_check_2bytes) {
frame->memory_regs[mem_idx].mem_bound_check_2bytes = frame->memory_regs[mem_idx].mem_bound_check_2bytes =
cc->memory_regs[mem_idx].mem_bound_check_2bytes; cc->memory_regs[mem_idx].mem_bound_check_2bytes;
#if UINTPTR_MAX == UINT64_MAX #if UINTPTR_MAX == UINT64_MAX
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_2bytes, GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_2bytes,
memory_inst_reg, module_inst_reg,
NEW_CONST(I32, offsetof(WASMMemoryInstance, NEW_CONST(I32, mem_bound_check_2bytes_offset));
mem_bound_check_2bytes)));
#else #else
GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_2bytes, GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_2bytes,
memory_inst_reg, module_inst_reg,
NEW_CONST(I32, offsetof(WASMMemoryInstance, NEW_CONST(I32, mem_bound_check_2bytes_offset));
mem_bound_check_2bytes)));
#endif #endif
} }
return frame->memory_regs[mem_idx].mem_bound_check_2bytes; return frame->memory_regs[mem_idx].mem_bound_check_2bytes;
@ -249,21 +217,24 @@ JitReg
get_mem_bound_check_4bytes_reg(JitFrame *frame, uint32 mem_idx) get_mem_bound_check_4bytes_reg(JitFrame *frame, uint32 mem_idx)
{ {
JitCompContext *cc = frame->cc; JitCompContext *cc = frame->cc;
JitReg memory_inst_reg = get_memory_inst_reg(frame, mem_idx); JitReg module_inst_reg = get_module_inst_reg(frame);
uint32 mem_bound_check_4bytes_offset =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_4bytes);
bh_assert(mem_idx == 0);
if (!frame->memory_regs[mem_idx].mem_bound_check_4bytes) { if (!frame->memory_regs[mem_idx].mem_bound_check_4bytes) {
frame->memory_regs[mem_idx].mem_bound_check_4bytes = frame->memory_regs[mem_idx].mem_bound_check_4bytes =
cc->memory_regs[mem_idx].mem_bound_check_4bytes; cc->memory_regs[mem_idx].mem_bound_check_4bytes;
#if UINTPTR_MAX == UINT64_MAX #if UINTPTR_MAX == UINT64_MAX
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_4bytes, GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_4bytes,
memory_inst_reg, module_inst_reg,
NEW_CONST(I32, offsetof(WASMMemoryInstance, NEW_CONST(I32, mem_bound_check_4bytes_offset));
mem_bound_check_4bytes)));
#else #else
GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_4bytes, GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_4bytes,
memory_inst_reg, module_inst_reg,
NEW_CONST(I32, offsetof(WASMMemoryInstance, NEW_CONST(I32, mem_bound_check_4bytes_offset));
mem_bound_check_4bytes)));
#endif #endif
} }
return frame->memory_regs[mem_idx].mem_bound_check_4bytes; return frame->memory_regs[mem_idx].mem_bound_check_4bytes;
@ -273,21 +244,24 @@ JitReg
get_mem_bound_check_8bytes_reg(JitFrame *frame, uint32 mem_idx) get_mem_bound_check_8bytes_reg(JitFrame *frame, uint32 mem_idx)
{ {
JitCompContext *cc = frame->cc; JitCompContext *cc = frame->cc;
JitReg memory_inst_reg = get_memory_inst_reg(frame, mem_idx); JitReg module_inst_reg = get_module_inst_reg(frame);
uint32 mem_bound_check_8bytes_offset =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_8bytes);
bh_assert(mem_idx == 0);
if (!frame->memory_regs[mem_idx].mem_bound_check_8bytes) { if (!frame->memory_regs[mem_idx].mem_bound_check_8bytes) {
frame->memory_regs[mem_idx].mem_bound_check_8bytes = frame->memory_regs[mem_idx].mem_bound_check_8bytes =
cc->memory_regs[mem_idx].mem_bound_check_8bytes; cc->memory_regs[mem_idx].mem_bound_check_8bytes;
#if UINTPTR_MAX == UINT64_MAX #if UINTPTR_MAX == UINT64_MAX
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_8bytes, GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_8bytes,
memory_inst_reg, module_inst_reg,
NEW_CONST(I32, offsetof(WASMMemoryInstance, NEW_CONST(I32, mem_bound_check_8bytes_offset));
mem_bound_check_8bytes)));
#else #else
GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_8bytes, GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_8bytes,
memory_inst_reg, module_inst_reg,
NEW_CONST(I32, offsetof(WASMMemoryInstance, NEW_CONST(I32, mem_bound_check_8bytes_offset));
mem_bound_check_8bytes)));
#endif #endif
} }
return frame->memory_regs[mem_idx].mem_bound_check_8bytes; return frame->memory_regs[mem_idx].mem_bound_check_8bytes;
@ -297,81 +271,118 @@ JitReg
get_mem_bound_check_16bytes_reg(JitFrame *frame, uint32 mem_idx) get_mem_bound_check_16bytes_reg(JitFrame *frame, uint32 mem_idx)
{ {
JitCompContext *cc = frame->cc; JitCompContext *cc = frame->cc;
JitReg memory_inst_reg = get_memory_inst_reg(frame, mem_idx); JitReg module_inst_reg = get_module_inst_reg(frame);
uint32 mem_bound_check_16bytes_offset =
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
+ (uint32)offsetof(WASMMemoryInstance, mem_bound_check_16bytes);
bh_assert(mem_idx == 0);
if (!frame->memory_regs[mem_idx].mem_bound_check_16bytes) { if (!frame->memory_regs[mem_idx].mem_bound_check_16bytes) {
frame->memory_regs[mem_idx].mem_bound_check_16bytes = frame->memory_regs[mem_idx].mem_bound_check_16bytes =
cc->memory_regs[mem_idx].mem_bound_check_16bytes; cc->memory_regs[mem_idx].mem_bound_check_16bytes;
#if UINTPTR_MAX == UINT64_MAX #if UINTPTR_MAX == UINT64_MAX
GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_16bytes, GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_16bytes,
memory_inst_reg, module_inst_reg,
NEW_CONST(I32, offsetof(WASMMemoryInstance, NEW_CONST(I32, mem_bound_check_16bytes_offset));
mem_bound_check_16bytes)));
#else #else
GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_16bytes, GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_16bytes,
memory_inst_reg, module_inst_reg,
NEW_CONST(I32, offsetof(WASMMemoryInstance, NEW_CONST(I32, mem_bound_check_16bytes_offset));
mem_bound_check_16bytes)));
#endif #endif
} }
return frame->memory_regs[mem_idx].mem_bound_check_16bytes; return frame->memory_regs[mem_idx].mem_bound_check_16bytes;
} }
JitReg static uint32
get_tables_reg(JitFrame *frame) get_table_inst_offset(const WASMModule *module, uint32 tbl_idx)
{ {
JitCompContext *cc = frame->cc; uint32 module_inst_struct_size =
JitReg inst_reg = get_module_inst_reg(frame); (uint32)offsetof(WASMModuleInstance, global_table_data.bytes);
uint32 mem_inst_size =
(uint32)sizeof(WASMMemoryInstance)
* (module->import_memory_count + module->memory_count);
uint32 offset, i = 0;
if (!frame->tables_reg) { #if WASM_ENABLE_JIT != 0
frame->tables_reg = cc->tables_reg; /* If the module dosen't have memory, reserve one mem_info space
GEN_INSN(LDPTR, frame->tables_reg, inst_reg, with empty content to align with llvm jit compiler */
NEW_CONST(I32, offsetof(WASMModuleInstance, tables))); if (mem_inst_size == 0)
mem_inst_size = (uint32)sizeof(WASMMemoryInstance);
#endif
/* Offset of the first table: size of module inst, memory instances
and global data */
offset = module_inst_struct_size + mem_inst_size + module->global_data_size;
while (i < tbl_idx && i < module->import_table_count) {
WASMTableImport *import_table = &module->import_tables[i].u.table;
offset += (uint32)offsetof(WASMTableInstance, elems);
#if WASM_ENABLE_MULTI_MODULE != 0
offset += (uint32)sizeof(uint32) * import_table->max_size;
#else
offset += (uint32)sizeof(uint32)
* (import_table->possible_grow ? import_table->max_size
: import_table->init_size);
#endif
i++;
} }
return frame->tables_reg;
if (i == tbl_idx) {
return offset;
}
tbl_idx -= module->import_table_count;
i -= module->import_table_count;
while (i < tbl_idx && i < module->table_count) {
WASMTable *table = module->tables + i;
offset += (uint32)offsetof(WASMTableInstance, elems);
#if WASM_ENABLE_MULTI_MODULE != 0
offset += (uint32)sizeof(uint32) * table->max_size;
#else
offset += (uint32)sizeof(uint32)
* (table->possible_grow ? table->max_size : table->init_size);
#endif
i++;
}
return offset;
} }
JitReg JitReg
get_table_inst_reg(JitFrame *frame, uint32 tbl_idx) get_table_elems_reg(JitFrame *frame, uint32 tbl_idx)
{ {
JitCompContext *cc = frame->cc; JitCompContext *cc = frame->cc;
JitReg tables_reg = get_tables_reg(frame); JitReg module_inst = get_module_inst_reg(frame);
uint32 offset = get_table_inst_offset(cc->cur_wasm_module, tbl_idx)
+ (uint32)offsetof(WASMTableInstance, elems);
if (!frame->table_regs[tbl_idx].table_inst) { if (!frame->table_regs[tbl_idx].table_elems) {
frame->table_regs[tbl_idx].table_inst = frame->table_regs[tbl_idx].table_elems =
cc->table_regs[tbl_idx].table_inst; cc->table_regs[tbl_idx].table_elems;
GEN_INSN(LDPTR, frame->table_regs[tbl_idx].table_inst, tables_reg, GEN_INSN(ADD, frame->table_regs[tbl_idx].table_elems, module_inst,
NEW_CONST(I32, sizeof(WASMTableInstance *) * tbl_idx)); NEW_CONST(PTR, offset));
} }
return frame->table_regs[tbl_idx].table_inst; return frame->table_regs[tbl_idx].table_elems;
}
JitReg
get_table_data_reg(JitFrame *frame, uint32 tbl_idx)
{
JitCompContext *cc = frame->cc;
JitReg table_reg = get_table_inst_reg(frame, tbl_idx);
if (!frame->table_regs[tbl_idx].table_data) {
frame->table_regs[tbl_idx].table_data =
cc->table_regs[tbl_idx].table_data;
GEN_INSN(ADD, frame->table_regs[tbl_idx].table_data, table_reg,
NEW_CONST(I64, offsetof(WASMTableInstance, elems)));
}
return frame->table_regs[tbl_idx].table_data;
} }
JitReg JitReg
get_table_cur_size_reg(JitFrame *frame, uint32 tbl_idx) get_table_cur_size_reg(JitFrame *frame, uint32 tbl_idx)
{ {
JitCompContext *cc = frame->cc; JitCompContext *cc = frame->cc;
JitReg table_reg = get_table_inst_reg(frame, tbl_idx); JitReg module_inst = get_module_inst_reg(frame);
uint32 offset = get_table_inst_offset(cc->cur_wasm_module, tbl_idx)
+ (uint32)offsetof(WASMTableInstance, cur_size);
if (!frame->table_regs[tbl_idx].table_cur_size) { if (!frame->table_regs[tbl_idx].table_cur_size) {
frame->table_regs[tbl_idx].table_cur_size = frame->table_regs[tbl_idx].table_cur_size =
cc->table_regs[tbl_idx].table_cur_size; cc->table_regs[tbl_idx].table_cur_size;
GEN_INSN(LDI32, frame->table_regs[tbl_idx].table_cur_size, table_reg, GEN_INSN(LDI32, frame->table_regs[tbl_idx].table_cur_size, module_inst,
NEW_CONST(I32, offsetof(WASMTableInstance, cur_size))); NEW_CONST(I32, offset));
} }
return frame->table_regs[tbl_idx].table_cur_size; return frame->table_regs[tbl_idx].table_cur_size;
} }
@ -387,15 +398,11 @@ clear_fixed_virtual_regs(JitFrame *frame)
frame->import_func_ptrs_reg = 0; frame->import_func_ptrs_reg = 0;
frame->fast_jit_func_ptrs_reg = 0; frame->fast_jit_func_ptrs_reg = 0;
frame->func_type_indexes_reg = 0; frame->func_type_indexes_reg = 0;
frame->global_data_reg = 0;
frame->aux_stack_bound_reg = 0; frame->aux_stack_bound_reg = 0;
frame->aux_stack_bottom_reg = 0; frame->aux_stack_bottom_reg = 0;
frame->memories_reg = 0;
frame->tables_reg = 0;
count = module->import_memory_count + module->memory_count; count = module->import_memory_count + module->memory_count;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
frame->memory_regs[i].memory_inst = 0;
frame->memory_regs[i].memory_data = 0; frame->memory_regs[i].memory_data = 0;
frame->memory_regs[i].memory_data_end = 0; frame->memory_regs[i].memory_data_end = 0;
frame->memory_regs[i].mem_bound_check_1byte = 0; frame->memory_regs[i].mem_bound_check_1byte = 0;
@ -407,8 +414,7 @@ clear_fixed_virtual_regs(JitFrame *frame)
count = module->import_table_count + module->table_count; count = module->import_table_count + module->table_count;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
frame->table_regs[i].table_inst = 0; frame->table_regs[i].table_elems = 0;
frame->table_regs[i].table_data = 0;
frame->table_regs[i].table_cur_size = 0; frame->table_regs[i].table_cur_size = 0;
} }
} }
@ -576,11 +582,8 @@ create_fixed_virtual_regs(JitCompContext *cc)
cc->import_func_ptrs_reg = jit_cc_new_reg_ptr(cc); cc->import_func_ptrs_reg = jit_cc_new_reg_ptr(cc);
cc->fast_jit_func_ptrs_reg = jit_cc_new_reg_ptr(cc); cc->fast_jit_func_ptrs_reg = jit_cc_new_reg_ptr(cc);
cc->func_type_indexes_reg = jit_cc_new_reg_ptr(cc); cc->func_type_indexes_reg = jit_cc_new_reg_ptr(cc);
cc->global_data_reg = jit_cc_new_reg_ptr(cc);
cc->aux_stack_bound_reg = jit_cc_new_reg_I32(cc); cc->aux_stack_bound_reg = jit_cc_new_reg_I32(cc);
cc->aux_stack_bottom_reg = jit_cc_new_reg_I32(cc); cc->aux_stack_bottom_reg = jit_cc_new_reg_I32(cc);
cc->memories_reg = jit_cc_new_reg_ptr(cc);
cc->tables_reg = jit_cc_new_reg_ptr(cc);
count = module->import_memory_count + module->memory_count; count = module->import_memory_count + module->memory_count;
if (count > 0) { if (count > 0) {
@ -592,7 +595,6 @@ create_fixed_virtual_regs(JitCompContext *cc)
} }
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
cc->memory_regs[i].memory_inst = jit_cc_new_reg_ptr(cc);
cc->memory_regs[i].memory_data = jit_cc_new_reg_ptr(cc); cc->memory_regs[i].memory_data = jit_cc_new_reg_ptr(cc);
cc->memory_regs[i].memory_data_end = jit_cc_new_reg_ptr(cc); cc->memory_regs[i].memory_data_end = jit_cc_new_reg_ptr(cc);
cc->memory_regs[i].mem_bound_check_1byte = jit_cc_new_reg_ptr(cc); cc->memory_regs[i].mem_bound_check_1byte = jit_cc_new_reg_ptr(cc);
@ -613,8 +615,7 @@ create_fixed_virtual_regs(JitCompContext *cc)
} }
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
cc->table_regs[i].table_inst = jit_cc_new_reg_ptr(cc); cc->table_regs[i].table_elems = jit_cc_new_reg_ptr(cc);
cc->table_regs[i].table_data = jit_cc_new_reg_ptr(cc);
cc->table_regs[i].table_cur_size = jit_cc_new_reg_I32(cc); cc->table_regs[i].table_cur_size = jit_cc_new_reg_I32(cc);
} }
} }

View File

@ -174,21 +174,12 @@ get_fast_jit_func_ptrs_reg(JitFrame *frame);
JitReg JitReg
get_func_type_indexes_reg(JitFrame *frame); get_func_type_indexes_reg(JitFrame *frame);
JitReg
get_global_data_reg(JitFrame *frame);
JitReg JitReg
get_aux_stack_bound_reg(JitFrame *frame); get_aux_stack_bound_reg(JitFrame *frame);
JitReg JitReg
get_aux_stack_bottom_reg(JitFrame *frame); get_aux_stack_bottom_reg(JitFrame *frame);
JitReg
get_memories_reg(JitFrame *frame);
JitReg
get_memory_inst_reg(JitFrame *frame, uint32 mem_idx);
JitReg JitReg
get_memory_data_reg(JitFrame *frame, uint32 mem_idx); get_memory_data_reg(JitFrame *frame, uint32 mem_idx);
@ -211,13 +202,7 @@ JitReg
get_mem_bound_check_16bytes_reg(JitFrame *frame, uint32 mem_idx); get_mem_bound_check_16bytes_reg(JitFrame *frame, uint32 mem_idx);
JitReg JitReg
get_tables_reg(JitFrame *frame); get_table_elems_reg(JitFrame *frame, uint32 table_idx);
JitReg
get_table_inst_reg(JitFrame *frame, uint32 table_idx);
JitReg
get_table_data_reg(JitFrame *frame, uint32 table_idx);
JitReg JitReg
get_table_cur_size_reg(JitFrame *frame, uint32 table_idx); get_table_cur_size_reg(JitFrame *frame, uint32 table_idx);

View File

@ -856,7 +856,6 @@ typedef struct JitValueSlot {
} JitValueSlot; } JitValueSlot;
typedef struct JitMemRegs { typedef struct JitMemRegs {
JitReg memory_inst;
/* The following registers should be re-loaded after /* The following registers should be re-loaded after
memory.grow, callbc and callnative */ memory.grow, callbc and callnative */
JitReg memory_data; JitReg memory_data;
@ -869,8 +868,7 @@ typedef struct JitMemRegs {
} JitMemRegs; } JitMemRegs;
typedef struct JitTableRegs { typedef struct JitTableRegs {
JitReg table_inst; JitReg table_elems;
JitReg table_data;
/* Should be re-loaded after table.grow, /* Should be re-loaded after table.grow,
callbc and callnative */ callbc and callnative */
JitReg table_cur_size; JitReg table_cur_size;
@ -915,18 +913,12 @@ typedef struct JitFrame {
JitReg fast_jit_func_ptrs_reg; JitReg fast_jit_func_ptrs_reg;
/* module_inst->func_type_indexes */ /* module_inst->func_type_indexes */
JitReg func_type_indexes_reg; JitReg func_type_indexes_reg;
/* Base address of global data */
JitReg global_data_reg;
/* Boundary of auxiliary stack */ /* Boundary of auxiliary stack */
JitReg aux_stack_bound_reg; JitReg aux_stack_bound_reg;
/* Bottom of auxiliary stack */ /* Bottom of auxiliary stack */
JitReg aux_stack_bottom_reg; JitReg aux_stack_bottom_reg;
/* Memory instances */
JitReg memories_reg;
/* Data of memory instances */ /* Data of memory instances */
JitMemRegs *memory_regs; JitMemRegs *memory_regs;
/* Table instances */
JitReg tables_reg;
/* Data of table instances */ /* Data of table instances */
JitTableRegs *table_regs; JitTableRegs *table_regs;
@ -1037,18 +1029,12 @@ typedef struct JitCompContext {
JitReg fast_jit_func_ptrs_reg; JitReg fast_jit_func_ptrs_reg;
/* module_inst->func_type_indexes */ /* module_inst->func_type_indexes */
JitReg func_type_indexes_reg; JitReg func_type_indexes_reg;
/* Base address of global data */
JitReg global_data_reg;
/* Boundary of auxiliary stack */ /* Boundary of auxiliary stack */
JitReg aux_stack_bound_reg; JitReg aux_stack_bound_reg;
/* Bottom of auxiliary stack */ /* Bottom of auxiliary stack */
JitReg aux_stack_bottom_reg; JitReg aux_stack_bottom_reg;
/* Memory instances */
JitReg memories_reg;
/* Data of memory instances */ /* Data of memory instances */
JitMemRegs *memory_regs; JitMemRegs *memory_regs;
/* Table instances */
JitReg tables_reg;
/* Data of table instances */ /* Data of table instances */
JitTableRegs *table_regs; JitTableRegs *table_regs;