mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-31 14:07:10 +00:00
Refine code, fix some issues and add codegen framework (#1045)
Add more return value checks and set lass error Implement exception throw and add operand stack overflow check Remove lower_fe pass Use cc->cmp_reg for cmp/branch IRs Fix jit dump issues Fix some compile warnings Add part of codegen framework Remove some unused JIT IRs
This commit is contained in:
parent
24aae4f0d6
commit
eb518c0423
|
@ -94,6 +94,14 @@
|
|||
#define WASM_ENABLE_LAZY_JIT 0
|
||||
#endif
|
||||
|
||||
#ifndef WASM_ENABLE_FAST_JIT
|
||||
#define WASM_ENABLE_FAST_JIT 0
|
||||
#endif
|
||||
|
||||
#ifndef WASM_ENABLE_FAST_JIT_DUMP
|
||||
#define WASM_ENABLE_FAST_JIT_DUMP 0
|
||||
#endif
|
||||
|
||||
#ifndef WASM_ENABLE_WAMR_COMPILER
|
||||
#define WASM_ENABLE_WAMR_COMPILER 0
|
||||
#endif
|
||||
|
|
|
@ -1,120 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "jit_codegen.h"
|
||||
|
||||
bool
|
||||
jit_codegen_init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
jit_codegen_destroy()
|
||||
{}
|
||||
|
||||
/* clang-format off */
|
||||
static const uint8 hreg_info_I4[3][7] = {
|
||||
/* ebp, eax, ebx, ecx, edx, edi, esi */
|
||||
{ 1, 0, 0, 0, 0, 0, 1 }, /* fixed, esi is freely used */
|
||||
{ 0, 1, 0, 1, 1, 0, 0 }, /* caller_saved_native */
|
||||
{ 0, 1, 0, 1, 1, 1, 0 } /* caller_saved_jitted */
|
||||
};
|
||||
|
||||
static const uint8 hreg_info_I8[3][16] = {
|
||||
/* rbp, rax, rbx, rcx, rdx, rdi, rsi, rsp,
|
||||
r8, r9, r10, r11, r12, r13, r14, r15 */
|
||||
{ 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 1 }, /* fixed, rsi is freely used */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 1, 0, 0, 0, 0, 0, 0 }, /* caller_saved_native */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 1, 0, 0, 0, 0, 0, 0 }, /* caller_saved_jitted */
|
||||
};
|
||||
|
||||
static uint8 hreg_info_F4[3][16] = {
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 1, 1, 1, 1 }, /* fixed, rsi is freely used */
|
||||
{ 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1 }, /* caller_saved_native */
|
||||
{ 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1 }, /* caller_saved_jitted */
|
||||
};
|
||||
|
||||
static uint8 hreg_info_F8[3][16] = {
|
||||
{ 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0 }, /* fixed, rsi is freely used */
|
||||
{ 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1 }, /* caller_saved_native */
|
||||
{ 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1 }, /* caller_saved_jitted */
|
||||
};
|
||||
|
||||
static const JitHardRegInfo hreg_info = {
|
||||
{
|
||||
{ 0, NULL, NULL, NULL }, /* VOID */
|
||||
|
||||
{ sizeof(hreg_info_I4[0]), /* I4 */
|
||||
hreg_info_I4[0],
|
||||
hreg_info_I4[1],
|
||||
hreg_info_I4[2] },
|
||||
|
||||
{ sizeof(hreg_info_I8[0]), /* I8 */
|
||||
hreg_info_I8[0],
|
||||
hreg_info_I8[1],
|
||||
hreg_info_I8[2] },
|
||||
|
||||
{ sizeof(hreg_info_F4[0]), /* F4 */
|
||||
hreg_info_F4[0],
|
||||
hreg_info_F4[1],
|
||||
hreg_info_F4[2] },
|
||||
|
||||
{ sizeof(hreg_info_F8[0]), /* F8 */
|
||||
hreg_info_F8[0],
|
||||
hreg_info_F8[1],
|
||||
hreg_info_F8[2] },
|
||||
|
||||
{ 0, NULL, NULL, NULL }, /* V8 */
|
||||
{ 0, NULL, NULL, NULL }, /* V16 */
|
||||
{ 0, NULL, NULL, NULL } /* V32 */
|
||||
},
|
||||
/* frame pointer hreg index: rbp */
|
||||
0,
|
||||
/* exec_env hreg index: r15 */
|
||||
15,
|
||||
/* cmp hreg index: esi */
|
||||
6
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
const JitHardRegInfo *
|
||||
jit_codegen_get_hreg_info()
|
||||
{
|
||||
return &hreg_info;
|
||||
}
|
||||
|
||||
bool
|
||||
jit_codegen_gen_native(JitCompContext *cc)
|
||||
{
|
||||
jit_set_last_error(cc, "jit_codegen_gen_native failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
jit_codegen_lower(JitCompContext *cc)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
jit_codegen_dump_native(void *begin_addr, void *end_addr)
|
||||
{}
|
||||
|
||||
bool
|
||||
jit_codegen_call_func_jitted(void *exec_env, void *frame, void *func_inst,
|
||||
void *target)
|
||||
{
|
||||
return false;
|
||||
}
|
3233
core/iwasm/fast-jit/cg/x86-64/jit_codegen_x86_64.cpp
Normal file
3233
core/iwasm/fast-jit/cg/x86-64/jit_codegen_x86_64.cpp
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -27,13 +27,14 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#define BUILD_COND_BR(value_if, block_then, block_else) \
|
||||
do { \
|
||||
if (!GEN_INSN(BNE, value_if, jit_basic_block_label(block_then), \
|
||||
jit_basic_block_label(block_else))) { \
|
||||
jit_set_last_error(cc, "generate bne insn failed"); \
|
||||
goto fail; \
|
||||
} \
|
||||
#define BUILD_COND_BR(value_if, block_then, block_else) \
|
||||
do { \
|
||||
if (!GEN_INSN(CMP, cc->cmp_reg, value_if, NEW_CONST(cc, 0)) \
|
||||
|| !GEN_INSN(BNE, cc->cmp_reg, jit_basic_block_label(block_then), \
|
||||
jit_basic_block_label(block_else))) { \
|
||||
jit_set_last_error(cc, "generate bne insn failed"); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SET_BUILDER_POS(basic_block) \
|
||||
|
@ -73,7 +74,7 @@ load_block_params(JitCompContext *cc, JitBlock *block)
|
|||
{
|
||||
JitFrame *jit_frame = cc->jit_frame;
|
||||
uint32 offset, i;
|
||||
JitReg value;
|
||||
JitReg value = 0;
|
||||
|
||||
/* Clear jit frame's locals and stacks */
|
||||
clear_values(jit_frame);
|
||||
|
@ -181,8 +182,9 @@ push_jit_block_to_stack_and_pass_params(JitCompContext *cc, JitBlock *block,
|
|||
BUILD_BR(basic_block);
|
||||
}
|
||||
else { /* IF block with condition br insn */
|
||||
if (!(insn = GEN_INSN(BNE, cond, jit_basic_block_label(basic_block),
|
||||
0))) {
|
||||
if (!GEN_INSN(CMP, cc->cmp_reg, cond, NEW_CONST(I32, 0))
|
||||
|| !(insn = GEN_INSN(BNE, cc->cmp_reg,
|
||||
jit_basic_block_label(basic_block), 0))) {
|
||||
jit_set_last_error(cc, "generate cond br failed");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -318,7 +320,7 @@ handle_func_return(JitCompContext *cc, JitBlock *block)
|
|||
/* fp_reg = prev_frame */
|
||||
GEN_INSN(MOV, cc->fp_reg, prev_frame);
|
||||
/* return 0 */
|
||||
GEN_INSN(RETURN, NEW_CONST(I32, 0));
|
||||
GEN_INSN(RETURNBC, NEW_CONST(I32, 0));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -836,7 +838,9 @@ jit_compile_op_br_if(JitCompContext *cc, uint32 br_depth, uint8 **p_frame_ip)
|
|||
clear_values(jit_frame);
|
||||
|
||||
CREATE_BASIC_BLOCK(if_basic_block);
|
||||
if (!GEN_INSN(BNE, cond, jit_basic_block_label(if_basic_block), 0)) {
|
||||
if (!GEN_INSN(CMP, cc->cmp_reg, cond, NEW_CONST(I32, 0))
|
||||
|| !GEN_INSN(BNE, cc->cmp_reg, jit_basic_block_label(if_basic_block),
|
||||
0)) {
|
||||
jit_set_last_error(cc, "generate bne insn failed");
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
@ -7,8 +7,72 @@
|
|||
#include "../jit_frontend.h"
|
||||
|
||||
bool
|
||||
jit_emit_exception(JitCompContext *cc, int32 exception_id, bool is_cond_br,
|
||||
jit_emit_exception(JitCompContext *cc, int32 exception_id, uint8 jit_opcode,
|
||||
JitReg cond_br_if, JitBasicBlock *cond_br_else_block)
|
||||
{
|
||||
return false;
|
||||
JitInsn *insn = NULL;
|
||||
JitIncomingInsn *incoming_insn;
|
||||
JitReg else_label;
|
||||
|
||||
bh_assert(exception_id < EXCE_NUM);
|
||||
|
||||
if (jit_opcode >= JIT_OP_BNE && jit_opcode <= JIT_OP_BLEU) {
|
||||
bh_assert(cond_br_if == cc->cmp_reg);
|
||||
else_label =
|
||||
cond_br_else_block ? jit_basic_block_label(cond_br_else_block) : 0;
|
||||
switch (jit_opcode) {
|
||||
case JIT_OP_BEQ:
|
||||
insn = GEN_INSN(BEQ, cond_br_if, 0, else_label);
|
||||
break;
|
||||
case JIT_OP_BNE:
|
||||
insn = GEN_INSN(BNE, cond_br_if, 0, else_label);
|
||||
break;
|
||||
case JIT_OP_BGTS:
|
||||
insn = GEN_INSN(BGTS, cond_br_if, 0, else_label);
|
||||
break;
|
||||
case JIT_OP_BGES:
|
||||
insn = GEN_INSN(BGES, cond_br_if, 0, else_label);
|
||||
break;
|
||||
case JIT_OP_BLTS:
|
||||
insn = GEN_INSN(BLTS, cond_br_if, 0, else_label);
|
||||
break;
|
||||
case JIT_OP_BLES:
|
||||
insn = GEN_INSN(BLES, cond_br_if, 0, else_label);
|
||||
break;
|
||||
case JIT_OP_BGTU:
|
||||
insn = GEN_INSN(BGTU, cond_br_if, 0, else_label);
|
||||
break;
|
||||
case JIT_OP_BGEU:
|
||||
insn = GEN_INSN(BGEU, cond_br_if, 0, else_label);
|
||||
break;
|
||||
case JIT_OP_BLTU:
|
||||
insn = GEN_INSN(BLTU, cond_br_if, 0, else_label);
|
||||
break;
|
||||
case JIT_OP_BLEU:
|
||||
insn = GEN_INSN(BLEU, cond_br_if, 0, else_label);
|
||||
break;
|
||||
}
|
||||
if (!insn) {
|
||||
jit_set_last_error(cc, "generate cond br insn failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (jit_opcode == JIT_OP_JMP) {
|
||||
insn = GEN_INSN(JMP, 0);
|
||||
if (!insn) {
|
||||
jit_set_last_error(cc, "generate jmp insn failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
incoming_insn = jit_calloc(sizeof(JitIncomingInsn));
|
||||
if (!incoming_insn) {
|
||||
jit_set_last_error(cc, "allocate memory failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
incoming_insn->insn = insn;
|
||||
incoming_insn->next = cc->incoming_insns_for_exec_bbs[exception_id];
|
||||
cc->incoming_insns_for_exec_bbs[exception_id] = incoming_insn;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
bool
|
||||
jit_emit_exception(JitCompContext *cc, int32 exception_id, bool is_cond_br,
|
||||
jit_emit_exception(JitCompContext *cc, int32 exception_id, uint8 jit_opcode,
|
||||
JitReg cond_br_if, JitBasicBlock *cond_br_else_block);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -31,7 +31,7 @@ jit_compile_op_get_local(JitCompContext *cc, uint32 local_idx)
|
|||
uint16 *local_offsets = wasm_func->local_offsets;
|
||||
uint16 local_offset;
|
||||
uint8 local_type;
|
||||
JitReg value;
|
||||
JitReg value = 0;
|
||||
|
||||
CHECK_LOCAL(local_idx);
|
||||
|
||||
|
@ -119,7 +119,7 @@ jit_compile_op_tee_local(JitCompContext *cc, uint32 local_idx)
|
|||
uint16 *local_offsets = wasm_func->local_offsets;
|
||||
uint16 local_offset;
|
||||
uint8 local_type;
|
||||
JitReg value;
|
||||
JitReg value = 0;
|
||||
|
||||
CHECK_LOCAL(local_idx);
|
||||
|
||||
|
|
|
@ -3,16 +3,84 @@
|
|||
|
||||
set (IWASM_FAST_JIT_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
add_definitions (-DWASM_ENABLE_FAST_JIT=1)
|
||||
add_definitions(-DWASM_ENABLE_FAST_JIT=1)
|
||||
if (WAMR_BUILD_FAST_JIT_DUMP EQUAL 1)
|
||||
add_definitions(-DWASM_ENABLE_FAST_JIT_DUMP=1)
|
||||
endif ()
|
||||
|
||||
include_directories (${IWASM_FAST_JIT_DIR})
|
||||
|
||||
if (WAMR_BUILD_TARGET STREQUAL "X86_64" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
asmjit
|
||||
GIT_REPOSITORY https://github.com/asmjit/asmjit.git
|
||||
)
|
||||
FetchContent_GetProperties(asmjit)
|
||||
if (NOT asmjit_POPULATED)
|
||||
message ("-- Fetching asmjit ..")
|
||||
FetchContent_Populate(asmjit)
|
||||
add_definitions(-DASMJIT_STATIC)
|
||||
add_definitions(-DASMJIT_NO_DEPRECATED)
|
||||
add_definitions(-DASMJIT_NO_BUILDER)
|
||||
add_definitions(-DASMJIT_NO_COMPILER)
|
||||
add_definitions(-DASMJIT_NO_JIT)
|
||||
add_definitions(-DASMJIT_NO_LOGGING)
|
||||
add_definitions(-DASMJIT_NO_TEXT)
|
||||
add_definitions(-DASMJIT_NO_VALIDATION)
|
||||
add_definitions(-DASMJIT_NO_INTROSPECTION)
|
||||
add_definitions(-DASMJIT_NO_INTRINSICS)
|
||||
add_definitions(-DASMJIT_NO_AARCH64)
|
||||
add_definitions(-DASMJIT_NO_AARCH32)
|
||||
include_directories("${asmjit_SOURCE_DIR}/src")
|
||||
add_subdirectory(${asmjit_SOURCE_DIR} ${asmjit_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
file (GLOB_RECURSE cpp_source_asmjit
|
||||
${asmjit_SOURCE_DIR}/src/asmjit/core/*.cpp
|
||||
${asmjit_SOURCE_DIR}/src/asmjit/x86/*.cpp
|
||||
)
|
||||
endif ()
|
||||
if (WAMR_BUILD_FAST_JIT_DUMP EQUAL 1)
|
||||
FetchContent_Declare(
|
||||
zycore
|
||||
GIT_REPOSITORY https://github.com/zyantific/zycore-c.git
|
||||
)
|
||||
FetchContent_GetProperties(zycore)
|
||||
if (NOT zycore_POPULATED)
|
||||
message ("-- Fetching zycore ..")
|
||||
FetchContent_Populate(zycore)
|
||||
option(ZYDIS_BUILD_TOOLS "" OFF)
|
||||
option(ZYDIS_BUILD_EXAMPLES "" OFF)
|
||||
include_directories("${zycore_SOURCE_DIR}/include")
|
||||
include_directories("${zycore_BINARY_DIR}")
|
||||
add_subdirectory(${zycore_SOURCE_DIR} ${zycore_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
file (GLOB_RECURSE c_source_zycore ${zycore_SOURCE_DIR}/src/*.c)
|
||||
endif ()
|
||||
FetchContent_Declare(
|
||||
zydis
|
||||
GIT_REPOSITORY https://github.com/zyantific/zydis.git
|
||||
)
|
||||
FetchContent_GetProperties(zydis)
|
||||
if (NOT zydis_POPULATED)
|
||||
message ("-- Fetching zydis ..")
|
||||
FetchContent_Populate(zydis)
|
||||
option(ZYDIS_BUILD_TOOLS "" OFF)
|
||||
option(ZYDIS_BUILD_EXAMPLES "" OFF)
|
||||
include_directories("${zydis_BINARY_DIR}")
|
||||
include_directories("${zydis_SOURCE_DIR}/include")
|
||||
include_directories("${zydis_SOURCE_DIR}/src")
|
||||
add_subdirectory(${zydis_SOURCE_DIR} ${zydis_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
file (GLOB_RECURSE c_source_zydis ${zydis_SOURCE_DIR}/src/*.c)
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
file (GLOB c_source_jit ${IWASM_FAST_JIT_DIR}/*.c ${IWASM_FAST_JIT_DIR}/fe/*.c)
|
||||
|
||||
if (WAMR_BUILD_TARGET STREQUAL "X86_64" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
|
||||
file (GLOB_RECURSE c_source_jit_cg ${IWASM_FAST_JIT_DIR}/cg/x86-64/*.c)
|
||||
file (GLOB_RECURSE cpp_source_jit_cg ${IWASM_FAST_JIT_DIR}/cg/x86-64/*.cpp)
|
||||
else ()
|
||||
message (FATAL_ERROR "Fast JIT codegen for target ${WAMR_BUILD_TARGET} isn't implemented")
|
||||
endif ()
|
||||
|
||||
set (IWASM_FAST_JIT_SOURCE ${c_source_jit} ${c_source_jit_cg})
|
||||
set (IWASM_FAST_JIT_SOURCE ${c_source_jit} ${cpp_source_jit_cg}
|
||||
${cpp_source_asmjit} ${c_source_zycore} ${c_source_zydis})
|
||||
|
|
|
@ -41,7 +41,7 @@ jit_code_cache_destroy()
|
|||
}
|
||||
|
||||
void *
|
||||
jit_code_cache_malloc(uint32 size)
|
||||
jit_code_cache_alloc(uint32 size)
|
||||
{
|
||||
return mem_allocator_malloc(code_cache_pool_allocator, size);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#define _JIT_CODEGEN_H_
|
||||
|
||||
#include "bh_platform.h"
|
||||
#include "jit_ir.h"
|
||||
#include "jit_compiler.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -64,14 +64,8 @@ jit_codegen_lower(JitCompContext *cc);
|
|||
void
|
||||
jit_codegen_dump_native(void *begin_addr, void *end_addr);
|
||||
|
||||
/**
|
||||
* Call jitted code
|
||||
*
|
||||
* @param exec_env the current exec_env
|
||||
*/
|
||||
bool
|
||||
jit_codegen_call_func_jitted(void *exec_env, void *frame, void *func_inst,
|
||||
void *target);
|
||||
int
|
||||
jit_codegen_interp_jitted_glue(void *self, JitInterpSwitchInfo *info, void *pc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -9,13 +9,6 @@
|
|||
#include "jit_codecache.h"
|
||||
#include "../interpreter/wasm.h"
|
||||
|
||||
typedef struct JitGlobals {
|
||||
/* Compiler pass sequence. The last element must be 0. */
|
||||
const uint8 *passes;
|
||||
/* Code cache size. */
|
||||
uint32 code_cache_size;
|
||||
} JitGlobals;
|
||||
|
||||
typedef struct JitCompilerPass {
|
||||
/* Name of the pass. */
|
||||
const char *name;
|
||||
|
@ -30,7 +23,6 @@ static JitCompilerPass compiler_passes[] = {
|
|||
REG_PASS(dump),
|
||||
REG_PASS(update_cfg),
|
||||
REG_PASS(frontend),
|
||||
REG_PASS(lower_fe),
|
||||
REG_PASS(lower_cg),
|
||||
REG_PASS(regalloc),
|
||||
REG_PASS(codegen),
|
||||
|
@ -41,20 +33,18 @@ static JitCompilerPass compiler_passes[] = {
|
|||
/* Number of compiler passes. */
|
||||
#define COMPILER_PASS_NUM (sizeof(compiler_passes) / sizeof(compiler_passes[0]))
|
||||
|
||||
#define WASM_ENABLE_FAST_JIT_DUMP 1
|
||||
|
||||
#if WASM_ENABLE_FAST_JIT_DUMP == 0
|
||||
static const uint8 compiler_passes_without_dump[] = {
|
||||
3, 4, 5, 6, 7, 8, 0
|
||||
3, 4, 5, 6, 7, 0
|
||||
};
|
||||
#else
|
||||
static const uint8 compiler_passes_with_dump[] = {
|
||||
3, 2, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 0
|
||||
3, 2, 1, 4, 1, 5, 1, 6, 1, 7, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
/* The exported global data of JIT compiler. */
|
||||
JitGlobals jit_globals = {
|
||||
static JitGlobals jit_globals = {
|
||||
#if WASM_ENABLE_FAST_JIT_DUMP == 0
|
||||
.passes = compiler_passes_without_dump,
|
||||
#else
|
||||
|
@ -109,6 +99,12 @@ jit_compiler_destroy()
|
|||
jit_code_cache_destroy();
|
||||
}
|
||||
|
||||
const JitGlobals *
|
||||
jit_compiler_get_jit_globals()
|
||||
{
|
||||
return &jit_globals;
|
||||
}
|
||||
|
||||
const char *
|
||||
jit_compiler_get_pass_name(unsigned i)
|
||||
{
|
||||
|
@ -119,6 +115,7 @@ bool
|
|||
jit_compiler_compile(WASMModule *module, uint32 func_idx)
|
||||
{
|
||||
JitCompContext *cc;
|
||||
char *last_error;
|
||||
bool ret = true;
|
||||
|
||||
/* Initialize compilation context. */
|
||||
|
@ -138,8 +135,10 @@ jit_compiler_compile(WASMModule *module, uint32 func_idx)
|
|||
|| (!module->possible_memory_grow);
|
||||
|
||||
/* Apply compiler passes. */
|
||||
if (!apply_compiler_passes(cc)) {
|
||||
os_printf("fast jit compilation failed: %s\n", jit_get_last_error(cc));
|
||||
if (!apply_compiler_passes(cc) || jit_get_last_error(cc)) {
|
||||
last_error = jit_get_last_error(cc);
|
||||
os_printf("fast jit compilation failed: %s\n",
|
||||
last_error ? last_error : "unknown error");
|
||||
ret = false;
|
||||
}
|
||||
|
||||
|
@ -153,6 +152,7 @@ bool
|
|||
jit_compiler_compile_all(WASMModule *module)
|
||||
{
|
||||
JitCompContext *cc;
|
||||
char *last_error;
|
||||
bool ret = false;
|
||||
uint32 i;
|
||||
|
||||
|
@ -174,9 +174,10 @@ jit_compiler_compile_all(WASMModule *module)
|
|||
|| (!module->possible_memory_grow);
|
||||
|
||||
/* Apply compiler passes. */
|
||||
if (!apply_compiler_passes(cc)) {
|
||||
if (!apply_compiler_passes(cc) || jit_get_last_error(cc)) {
|
||||
last_error = jit_get_last_error(cc);
|
||||
os_printf("fast jit compilation failed: %s\n",
|
||||
jit_get_last_error(cc));
|
||||
last_error ? last_error : "unknown error");
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
|
@ -188,9 +189,8 @@ jit_compiler_compile_all(WASMModule *module)
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
jit_interp_switch_to_jitted(void *exec_env, void *frame,
|
||||
WASMFunctionInstance *func_inst, void *target)
|
||||
int
|
||||
jit_interp_switch_to_jitted(void *exec_env, JitInterpSwitchInfo *info, void *pc)
|
||||
{
|
||||
return jit_codegen_call_func_jitted(exec_env, func_inst, frame, target);
|
||||
return jit_codegen_interp_jitted_glue(exec_env, info, pc);
|
||||
}
|
||||
|
|
|
@ -14,12 +14,31 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct JitGlobals {
|
||||
/* Compiler pass sequence, the last element must be 0 */
|
||||
const uint8 *passes;
|
||||
/* Code cache size. */
|
||||
uint32 code_cache_size;
|
||||
} JitGlobals;
|
||||
|
||||
/**
|
||||
* Information exchanged between JITed code and interpreter.
|
||||
*/
|
||||
typedef struct JitInterpSwitchInfo {
|
||||
/* Points to the frame that is passed to JITed code and the frame
|
||||
that is returned from JITed code. */
|
||||
void *frame;
|
||||
} JitInterpSwitchInfo;
|
||||
|
||||
bool
|
||||
jit_compiler_init();
|
||||
|
||||
void
|
||||
jit_compiler_destroy();
|
||||
|
||||
const JitGlobals *
|
||||
jit_compiler_get_jit_globals();
|
||||
|
||||
const char *
|
||||
jit_compiler_get_pass_name(unsigned i);
|
||||
|
||||
|
@ -29,9 +48,8 @@ jit_compiler_compile(WASMModule *module, uint32 func_idx);
|
|||
bool
|
||||
jit_compiler_compile_all(WASMModule *module);
|
||||
|
||||
bool
|
||||
jit_interp_switch_to_jitted(void *exec_env, void *frame,
|
||||
WASMFunctionInstance *func_inst, void *target);
|
||||
int
|
||||
jit_interp_switch_to_jitted(void *self, JitInterpSwitchInfo *info, void *pc);
|
||||
|
||||
/*
|
||||
* Pass declarations:
|
||||
|
@ -55,11 +73,13 @@ jit_pass_update_cfg(JitCompContext *cc);
|
|||
bool
|
||||
jit_pass_frontend(JitCompContext *cc);
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Convert MIR to LIR.
|
||||
*/
|
||||
bool
|
||||
jit_pass_lower_fe(JitCompContext *cc);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Lower unsupported operations into supported ones.
|
||||
|
|
|
@ -89,6 +89,7 @@ jit_dump_insn_VReg(JitCompContext *cc, JitInsn *insn, unsigned opnd_num)
|
|||
os_printf("\n");
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
jit_dump_insn_TableSwitch(JitCompContext *cc, JitInsn *insn, unsigned opnd_num)
|
||||
{
|
||||
|
@ -107,6 +108,7 @@ jit_dump_insn_TableSwitch(JitCompContext *cc, JitInsn *insn, unsigned opnd_num)
|
|||
os_printf("\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
jit_dump_insn_LookupSwitch(JitCompContext *cc, JitInsn *insn, unsigned opnd_num)
|
||||
|
@ -307,9 +309,14 @@ jit_dump_cc(JitCompContext *cc)
|
|||
bool
|
||||
jit_pass_dump(JitCompContext *cc)
|
||||
{
|
||||
os_printf("JIT.COMPILER.DUMP: PASS_NO=%d PREV_PASS=%s\n\n", cc->cur_pass_no,
|
||||
(cc->cur_pass_no > 0 ? jit_compiler_get_pass_name(cc->cur_pass_no)
|
||||
: "NULL"));
|
||||
const JitGlobals *jit_globals = jit_compiler_get_jit_globals();
|
||||
const uint8 *passes = jit_globals->passes;
|
||||
uint8 pass_no = cc->cur_pass_no;
|
||||
const char *pass_name =
|
||||
pass_no > 0 ? jit_compiler_get_pass_name(passes[pass_no - 1]) : "NULL";
|
||||
|
||||
os_printf("JIT.COMPILER.DUMP: PASS_NO=%d PREV_PASS=%s\n\n", pass_no,
|
||||
pass_name);
|
||||
jit_dump_cc(cc);
|
||||
os_printf("\n");
|
||||
return true;
|
||||
|
|
|
@ -20,6 +20,28 @@
|
|||
#include "../interpreter/wasm_opcode.h"
|
||||
#include "../common/wasm_exec_env.h"
|
||||
|
||||
/* clang-format off */
|
||||
static const char *jit_exception_msgs[] = {
|
||||
"unreachable", /* EXCE_UNREACHABLE */
|
||||
"allocate memory failed", /* EXCE_OUT_OF_MEMORY */
|
||||
"out of bounds memory access", /* EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS */
|
||||
"integer overflow", /* EXCE_INTEGER_OVERFLOW */
|
||||
"integer divide by zero", /* EXCE_INTEGER_DIVIDE_BY_ZERO */
|
||||
"invalid conversion to integer", /* EXCE_INVALID_CONVERSION_TO_INTEGER */
|
||||
"indirect call type mismatch", /* EXCE_INVALID_FUNCTION_TYPE_INDEX */
|
||||
"invalid function index", /* EXCE_INVALID_FUNCTION_INDEX */
|
||||
"undefined element", /* EXCE_UNDEFINED_ELEMENT */
|
||||
"uninitialized element", /* EXCE_UNINITIALIZED_ELEMENT */
|
||||
"failed to call unlinked import function", /* EXCE_CALL_UNLINKED_IMPORT_FUNC */
|
||||
"native stack overflow", /* EXCE_NATIVE_STACK_OVERFLOW */
|
||||
"unaligned atomic", /* EXCE_UNALIGNED_ATOMIC */
|
||||
"wasm auxiliary stack overflow", /* EXCE_AUX_STACK_OVERFLOW */
|
||||
"wasm auxiliary stack underflow", /* EXCE_AUX_STACK_UNDERFLOW */
|
||||
"out of bounds table access", /* EXCE_OUT_OF_BOUNDS_TABLE_ACCESS */
|
||||
"wasm operand stack overflow", /* EXCE_OPERAND_STACK_OVERFLOW */
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
JitReg
|
||||
gen_load_i32(JitFrame *frame, unsigned n)
|
||||
{
|
||||
|
@ -124,29 +146,41 @@ gen_commit_sp_ip(JitFrame *frame)
|
|||
JitReg sp;
|
||||
|
||||
if (frame->sp != frame->committed_sp) {
|
||||
#if UINTPTR_MAX == UINT32_MAX
|
||||
GEN_INSN_NORM(I32, sp, ADD, 0, cc->fp_reg,
|
||||
NEW_CONST(I32, offset_of_local(frame->sp - frame->lp)));
|
||||
GEN_INSN(STI32, sp, cc->fp_reg,
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
sp = jit_cc_new_reg_I64(cc);
|
||||
GEN_INSN(ADD, sp, cc->fp_reg,
|
||||
NEW_CONST(I32, offset_of_local(frame->sp - frame->lp)));
|
||||
GEN_INSN(STI64, sp, cc->fp_reg,
|
||||
NEW_CONST(I32, offsetof(WASMInterpFrame, sp)));
|
||||
#else
|
||||
GEN_INSN_NORM(I64, sp, ADD, 0, cc->fp_reg,
|
||||
NEW_CONST(I32, offset_of_local(frame->sp - frame->lp)));
|
||||
GEN_INSN(STI64, sp, cc->fp_reg,
|
||||
sp = jit_cc_new_reg_I32(cc);
|
||||
GEN_INSN(ADD, sp, cc->fp_reg,
|
||||
NEW_CONST(I32, offset_of_local(frame->sp - frame->lp)));
|
||||
GEN_INSN(STI32, sp, cc->fp_reg,
|
||||
NEW_CONST(I32, offsetof(WASMInterpFrame, sp)));
|
||||
#endif
|
||||
frame->committed_sp = frame->sp;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (frame->ip != frame->committed_ip) {
|
||||
GEN_INSN (STI32,
|
||||
NEW_REL (BCIP, NONE, offset_of_addr (frame, frame->ip), frame->ip),
|
||||
cc->fp_reg,
|
||||
NEW_CONST (I32, offsetof (WASMInterpFrame, ip)));
|
||||
frame->committed_ip = frame->ip;
|
||||
}
|
||||
if (frame->ip != frame->committed_ip) {
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
GEN_INSN(STI64, NEW_CONST(I64, (uint64)(uintptr_t)frame->ip),
|
||||
cc->fp_reg, NEW_CONST(I32, offsetof(WASMInterpFrame, ip)));
|
||||
#else
|
||||
GEN_INSN(STI32, NEW_CONST(I32, (uint32)(uintptr_t)frame->ip),
|
||||
cc->fp_reg, NEW_CONST(I32, offsetof(WASMInterpFrame, ip)));
|
||||
#endif
|
||||
frame->committed_ip = frame->ip;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
jit_set_exception_with_id(WASMModuleInstance *module_inst, uint32 id)
|
||||
{
|
||||
if (id < EXCE_NUM)
|
||||
wasm_set_exception(module_inst, jit_exception_msgs[id]);
|
||||
else
|
||||
wasm_set_exception(module_inst, "unknown exception");
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -154,7 +188,9 @@ form_and_translate_func(JitCompContext *cc)
|
|||
{
|
||||
JitBasicBlock *func_entry_basic_block;
|
||||
JitReg func_entry_label;
|
||||
JitInsn *jmp_insn;
|
||||
JitInsn *insn;
|
||||
JitIncomingInsn *incoming_insn, *incoming_insn_next;
|
||||
uint32 i;
|
||||
|
||||
if (!(func_entry_basic_block = jit_frontend_translate_func(cc)))
|
||||
return false;
|
||||
|
@ -165,11 +201,58 @@ form_and_translate_func(JitCompContext *cc)
|
|||
func_entry_label = jit_basic_block_label(func_entry_basic_block);
|
||||
|
||||
/* Create a JMP instruction jumping to the func entry. */
|
||||
if (!(jmp_insn = jit_cc_new_insn(cc, JMP, func_entry_label)))
|
||||
if (!(insn = jit_cc_new_insn(cc, JMP, func_entry_label)))
|
||||
return false;
|
||||
|
||||
/* Insert the instruction into the cc entry block. */
|
||||
jit_basic_block_append_insn(jit_cc_entry_basic_block(cc), jmp_insn);
|
||||
jit_basic_block_append_insn(jit_cc_entry_basic_block(cc), insn);
|
||||
|
||||
/* Patch INSNs jumping to exception basic blocks. */
|
||||
for (i = 0; i < EXCE_NUM; i++) {
|
||||
incoming_insn = cc->incoming_insns_for_exec_bbs[i];
|
||||
if (incoming_insn) {
|
||||
if (!(cc->exce_basic_blocks[i] = jit_cc_new_basic_block(cc, 0))) {
|
||||
jit_set_last_error(cc, "create basic block failed");
|
||||
return false;
|
||||
}
|
||||
while (incoming_insn) {
|
||||
incoming_insn_next = incoming_insn->next;
|
||||
insn = incoming_insn->insn;
|
||||
if (insn->opcode == JIT_OP_JMP) {
|
||||
*(jit_insn_opnd(insn, 0)) =
|
||||
jit_basic_block_label(cc->exce_basic_blocks[i]);
|
||||
}
|
||||
else if (insn->opcode >= JIT_OP_BNE
|
||||
&& insn->opcode <= JIT_OP_BLEU) {
|
||||
*(jit_insn_opnd(insn, 1)) =
|
||||
jit_basic_block_label(cc->exce_basic_blocks[i]);
|
||||
}
|
||||
incoming_insn = incoming_insn_next;
|
||||
}
|
||||
cc->cur_basic_block = cc->exce_basic_blocks[i];
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
insn = GEN_INSN(
|
||||
CALLNATIVE, 0,
|
||||
NEW_CONST(I64, (uint64)(uintptr_t)jit_set_exception_with_id),
|
||||
1);
|
||||
#else
|
||||
insn = GEN_INSN(
|
||||
CALLNATIVE, 0,
|
||||
NEW_CONST(I32, (uint32)(uintptr_t)jit_set_exception_with_id),
|
||||
1);
|
||||
#endif
|
||||
if (insn) {
|
||||
*(jit_insn_opndv(insn, 2)) = NEW_CONST(I32, i);
|
||||
}
|
||||
GEN_INSN(RETURNBC, NEW_CONST(I32, i));
|
||||
|
||||
*(jit_annl_begin_bcip(cc,
|
||||
jit_basic_block_label(cc->cur_basic_block))) =
|
||||
*(jit_annl_end_bcip(
|
||||
cc, jit_basic_block_label(cc->cur_basic_block))) =
|
||||
cc->cur_wasm_module->load_addr;
|
||||
}
|
||||
}
|
||||
|
||||
*(jit_annl_begin_bcip(cc, cc->entry_label)) =
|
||||
*(jit_annl_end_bcip(cc, cc->entry_label)) =
|
||||
|
@ -199,11 +282,13 @@ jit_pass_frontend(JitCompContext *cc)
|
|||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool
|
||||
jit_pass_lower_fe(JitCompContext *cc)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static JitFrame *
|
||||
init_func_translation(JitCompContext *cc)
|
||||
|
@ -239,6 +324,7 @@ init_func_translation(JitCompContext *cc)
|
|||
jit_frame->max_locals = max_locals;
|
||||
jit_frame->max_stacks = max_stacks;
|
||||
jit_frame->sp = jit_frame->lp + max_locals;
|
||||
jit_frame->ip = cur_wasm_func->code;
|
||||
|
||||
cc->jit_frame = jit_frame;
|
||||
cc->cur_basic_block = jit_cc_entry_basic_block(cc);
|
||||
|
@ -266,9 +352,14 @@ init_func_translation(JitCompContext *cc)
|
|||
NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top_boundary)));
|
||||
/* frame_boundary = top + frame_size + outs_size */
|
||||
GEN_INSN(ADD, frame_boundary, top, NEW_CONST(I32, frame_size + outs_size));
|
||||
GEN_INSN(CHECK_SOE, NEW_CONST(I32, 0), frame_boundary, top_boundary);
|
||||
/* if frame_boundary > top_boundary, throw stack overflow exception */
|
||||
GEN_INSN(CMP, cc->cmp_reg, frame_boundary, top_boundary);
|
||||
if (!jit_emit_exception(cc, EXCE_OPERAND_STACK_OVERFLOW, JIT_OP_BGTU,
|
||||
cc->cmp_reg, 0)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Add first and then sub to reduce one used register. */
|
||||
/* Add first and then sub to reduce one used register */
|
||||
/* new_top = frame_boundary - outs_size = top + frame_size */
|
||||
GEN_INSN(SUB, new_top, frame_boundary, NEW_CONST(I32, outs_size));
|
||||
/* exec_env->wasm_stack.s.top = new_top */
|
||||
|
@ -283,6 +374,7 @@ init_func_translation(JitCompContext *cc)
|
|||
/* frame->prev_frame = fp_reg */
|
||||
GEN_INSN(STI64, cc->fp_reg, top,
|
||||
NEW_CONST(I32, offsetof(WASMInterpFrame, prev_frame)));
|
||||
/* TODO: do we need to set frame->function? */
|
||||
/*
|
||||
GEN_INSN(STI64, func_inst, top,
|
||||
NEW_CONST(I32, offsetof(WASMInterpFrame, function)));
|
||||
|
@ -293,6 +385,52 @@ init_func_translation(JitCompContext *cc)
|
|||
/* fp_reg = top */
|
||||
GEN_INSN(MOV, cc->fp_reg, top);
|
||||
#else
|
||||
top = jit_cc_new_reg_I32(cc);
|
||||
top_boundary = jit_cc_new_reg_I32(cc);
|
||||
new_top = jit_cc_new_reg_I32(cc);
|
||||
frame_boundary = jit_cc_new_reg_I32(cc);
|
||||
frame_sp = jit_cc_new_reg_I32(cc);
|
||||
|
||||
/* top = exec_env->wasm_stack.s.top */
|
||||
GEN_INSN(LDI32, top, cc->exec_env_reg,
|
||||
NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top)));
|
||||
/* top_boundary = exec_env->wasm_stack.s.top_boundary */
|
||||
GEN_INSN(LDI32, top_boundary, cc->exec_env_reg,
|
||||
NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top_boundary)));
|
||||
/* frame_boundary = top + frame_size + outs_size */
|
||||
GEN_INSN(ADD, frame_boundary, top, NEW_CONST(I32, frame_size + outs_size));
|
||||
/* if frame_boundary > top_boundary, throw stack overflow exception */
|
||||
GEN_INSN(CMP, cc->cmp_reg, frame_boundary, top_boundary);
|
||||
if (!jit_emit_exception(cc, EXCE_OPERAND_STACK_OVERFLOW, JIT_OP_BGTU,
|
||||
cc->cmp_reg, 0)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Add first and then sub to reduce one used register */
|
||||
/* new_top = frame_boundary - outs_size = top + frame_size */
|
||||
GEN_INSN(SUB, new_top, frame_boundary, NEW_CONST(I32, outs_size));
|
||||
/* exec_env->wasm_stack.s.top = new_top */
|
||||
GEN_INSN(STI32, new_top, cc->exec_env_reg,
|
||||
NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top)));
|
||||
/* frame_sp = frame->lp + local_size */
|
||||
GEN_INSN(ADD, frame_sp, top,
|
||||
NEW_CONST(I32, offsetof(WASMInterpFrame, lp) + local_size));
|
||||
/* frame->sp = frame_sp */
|
||||
GEN_INSN(STI32, frame_sp, top,
|
||||
NEW_CONST(I32, offsetof(WASMInterpFrame, sp)));
|
||||
/* frame->prev_frame = fp_reg */
|
||||
GEN_INSN(STI32, cc->fp_reg, top,
|
||||
NEW_CONST(I32, offsetof(WASMInterpFrame, prev_frame)));
|
||||
/* TODO: do we need to set frame->function? */
|
||||
/*
|
||||
GEN_INSN(STI32, func_inst, top,
|
||||
NEW_CONST(I32, offsetof(WASMInterpFrame, function)));
|
||||
*/
|
||||
/* exec_env->cur_frame = top */
|
||||
GEN_INSN(STI32, top, cc->exec_env_reg,
|
||||
NEW_CONST(I32, offsetof(WASMExecEnv, cur_frame)));
|
||||
/* fp_reg = top */
|
||||
GEN_INSN(MOV, cc->fp_reg, top);
|
||||
#endif
|
||||
|
||||
return jit_frame;
|
||||
|
@ -1535,6 +1673,12 @@ jit_compile_func(JitCompContext *cc)
|
|||
jit_set_last_error(cc, "unsupported opcode");
|
||||
return false;
|
||||
}
|
||||
/* Error may occur when creating registers, basic blocks, insns,
|
||||
consts and labels, in which the return value may be unchecked,
|
||||
here we check again */
|
||||
if (jit_get_last_error(cc)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
(void)func_idx;
|
||||
|
|
|
@ -308,6 +308,7 @@ static inline void
|
|||
gen_commit_for_exception(JitFrame *frame)
|
||||
{
|
||||
gen_commit_values(frame, frame->lp, frame->lp + frame->max_locals);
|
||||
gen_commit_sp_ip(frame);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -315,6 +315,9 @@ JitBasicBlock *
|
|||
jit_basic_block_new(JitReg label, int n)
|
||||
{
|
||||
JitBasicBlock *block = jit_insn_new_PHI(label, n);
|
||||
if (!block)
|
||||
return NULL;
|
||||
|
||||
block->prev = block->next = block;
|
||||
return block;
|
||||
}
|
||||
|
@ -380,7 +383,7 @@ jit_basic_block_succs(JitBasicBlock *block)
|
|||
vec._base = jit_insn_opnd(last_insn, 1);
|
||||
break;
|
||||
|
||||
case JIT_OP_LOOKUP_SWITCH:
|
||||
case JIT_OP_LOOKUPSWITCH:
|
||||
{
|
||||
JitOpndLookupSwitch *opnd = jit_insn_opndls(last_insn);
|
||||
vec.num = opnd->match_pairs_num + 1;
|
||||
|
@ -412,10 +415,14 @@ jit_cc_init(JitCompContext *cc, unsigned htab_size)
|
|||
|| !(exit_block = jit_cc_new_basic_block(cc, 0)))
|
||||
goto fail;
|
||||
|
||||
if (!(cc->exception_basic_blocks =
|
||||
if (!(cc->exce_basic_blocks =
|
||||
jit_calloc(sizeof(JitBasicBlock *) * EXCE_NUM)))
|
||||
goto fail;
|
||||
|
||||
if (!(cc->incoming_insns_for_exec_bbs =
|
||||
jit_calloc(sizeof(JitIncomingInsnList) * EXCE_NUM)))
|
||||
goto fail;
|
||||
|
||||
/* Record the entry and exit labels, whose indexes must be 0 and 1
|
||||
respectively. */
|
||||
cc->entry_label = jit_basic_block_label(entry_block);
|
||||
|
@ -437,14 +444,14 @@ jit_cc_init(JitCompContext *cc, unsigned htab_size)
|
|||
}
|
||||
|
||||
/* Create registers for frame pointer, exec_env and cmp. */
|
||||
#if UINTPTR_MAX == UINT32_MAX
|
||||
cc->fp_reg = jit_reg_new(JIT_REG_KIND_I32, cc->hreg_info->fp_hreg_index);
|
||||
cc->exec_env_reg =
|
||||
jit_reg_new(JIT_REG_KIND_I32, cc->hreg_info->exec_env_hreg_index);
|
||||
#else
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
cc->fp_reg = jit_reg_new(JIT_REG_KIND_I64, cc->hreg_info->fp_hreg_index);
|
||||
cc->exec_env_reg =
|
||||
jit_reg_new(JIT_REG_KIND_I64, cc->hreg_info->exec_env_hreg_index);
|
||||
#else
|
||||
cc->fp_reg = jit_reg_new(JIT_REG_KIND_I32, cc->hreg_info->fp_hreg_index);
|
||||
cc->exec_env_reg =
|
||||
jit_reg_new(JIT_REG_KIND_I32, cc->hreg_info->exec_env_hreg_index);
|
||||
#endif
|
||||
cc->cmp_reg = jit_reg_new(JIT_REG_KIND_I32, cc->hreg_info->cmp_hreg_index);
|
||||
|
||||
|
@ -466,6 +473,7 @@ jit_cc_destroy(JitCompContext *cc)
|
|||
{
|
||||
unsigned i, end;
|
||||
JitBasicBlock *block;
|
||||
JitIncomingInsn *incoming_insn, *incoming_insn_next;
|
||||
|
||||
jit_block_stack_destroy(&cc->block_stack);
|
||||
|
||||
|
@ -476,7 +484,19 @@ jit_cc_destroy(JitCompContext *cc)
|
|||
/* Release the instruction hash table. */
|
||||
jit_cc_disable_insn_hash(cc);
|
||||
|
||||
jit_free(cc->exception_basic_blocks);
|
||||
jit_free(cc->exce_basic_blocks);
|
||||
|
||||
if (cc->incoming_insns_for_exec_bbs) {
|
||||
for (i = 0; i < EXCE_NUM; i++) {
|
||||
incoming_insn = cc->incoming_insns_for_exec_bbs[i];
|
||||
while (incoming_insn) {
|
||||
incoming_insn_next = incoming_insn->next;
|
||||
jit_free(incoming_insn);
|
||||
incoming_insn = incoming_insn_next;
|
||||
}
|
||||
}
|
||||
jit_free(cc->incoming_insns_for_exec_bbs);
|
||||
}
|
||||
|
||||
/* Release entry and exit blocks. */
|
||||
jit_basic_block_delete(jit_cc_entry_basic_block(cc));
|
||||
|
@ -619,6 +639,7 @@ _jit_cc_new_const(JitCompContext *cc, int kind, unsigned size, void *val)
|
|||
cc->_const_val._next[kind] = new_next;
|
||||
}
|
||||
else {
|
||||
jit_set_last_error(cc, "create const register failed");
|
||||
jit_free(new_value);
|
||||
jit_free(new_next);
|
||||
return 0;
|
||||
|
@ -770,8 +791,10 @@ jit_cc_new_label(JitCompContext *cc)
|
|||
#undef ANN_LABEL
|
||||
#undef EMPTY_POSTFIX
|
||||
|
||||
if (!successful)
|
||||
if (!successful) {
|
||||
jit_set_last_error(cc, "create label register failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cc->_ann._label_capacity = capacity;
|
||||
}
|
||||
|
@ -790,6 +813,8 @@ jit_cc_new_basic_block(JitCompContext *cc, int n)
|
|||
if (label && (block = jit_basic_block_new(label, n)))
|
||||
/* Void 0 register indicates error in creation. */
|
||||
*(jit_annl_basic_block(cc, label)) = block;
|
||||
else
|
||||
jit_set_last_error(cc, "create basic block failed");
|
||||
|
||||
return block;
|
||||
}
|
||||
|
@ -801,8 +826,10 @@ jit_cc_resize_basic_block(JitCompContext *cc, JitBasicBlock *block, int n)
|
|||
JitInsn *insn = jit_basic_block_first_insn(block);
|
||||
JitBasicBlock *new_block = jit_basic_block_new(label, n);
|
||||
|
||||
if (!new_block)
|
||||
if (!new_block) {
|
||||
jit_set_last_error(cc, "resize basic block failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jit_insn_unlink(block);
|
||||
|
||||
|
@ -877,8 +904,10 @@ jit_cc_set_insn_uid(JitCompContext *cc, JitInsn *insn)
|
|||
#undef ANN_INSN
|
||||
#undef EMPTY_POSTFIX
|
||||
|
||||
if (!successful)
|
||||
if (!successful) {
|
||||
jit_set_last_error(cc, "set insn uid failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cc->_ann._insn_capacity = capacity;
|
||||
}
|
||||
|
@ -900,6 +929,7 @@ _jit_cc_set_insn_uid_for_new_insn(JitCompContext *cc, JitInsn *insn)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static JitReg
|
||||
normalize_insn(JitCompContext *cc, JitInsn **pinsn)
|
||||
{
|
||||
|
@ -1059,6 +1089,7 @@ _gen_insn_norm_1(JitCompContext *cc, JitBasicBlock *block, unsigned kind,
|
|||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
JitReg
|
||||
jit_cc_new_reg(JitCompContext *cc, unsigned kind)
|
||||
|
@ -1080,8 +1111,10 @@ jit_cc_new_reg(JitCompContext *cc, unsigned kind)
|
|||
#include "jit_ir.def"
|
||||
#undef ANN_REG
|
||||
|
||||
if (!successful)
|
||||
if (!successful) {
|
||||
jit_set_last_error(cc, "create register failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cc->_ann._reg_capacity[kind] = capacity;
|
||||
}
|
||||
|
@ -1093,33 +1126,37 @@ jit_cc_new_reg(JitCompContext *cc, unsigned kind)
|
|||
|
||||
#undef _JIT_REALLOC_ANN
|
||||
|
||||
#define ANN_LABEL(TYPE, NAME) \
|
||||
bool jit_annl_enable_##NAME(JitCompContext *cc) \
|
||||
{ \
|
||||
if (cc->_ann._label_##NAME##_enabled) \
|
||||
return true; \
|
||||
\
|
||||
if (cc->_ann._label_capacity > 0 \
|
||||
&& !(cc->_ann._label_##NAME = \
|
||||
jit_calloc(cc->_ann._label_capacity * sizeof(TYPE)))) \
|
||||
return false; \
|
||||
\
|
||||
cc->_ann._label_##NAME##_enabled = 1; \
|
||||
return true; \
|
||||
#define ANN_LABEL(TYPE, NAME) \
|
||||
bool jit_annl_enable_##NAME(JitCompContext *cc) \
|
||||
{ \
|
||||
if (cc->_ann._label_##NAME##_enabled) \
|
||||
return true; \
|
||||
\
|
||||
if (cc->_ann._label_capacity > 0 \
|
||||
&& !(cc->_ann._label_##NAME = \
|
||||
jit_calloc(cc->_ann._label_capacity * sizeof(TYPE)))) { \
|
||||
jit_set_last_error(cc, "annl enable " #NAME "failed"); \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
cc->_ann._label_##NAME##_enabled = 1; \
|
||||
return true; \
|
||||
}
|
||||
#define ANN_INSN(TYPE, NAME) \
|
||||
bool jit_anni_enable_##NAME(JitCompContext *cc) \
|
||||
{ \
|
||||
if (cc->_ann._insn_##NAME##_enabled) \
|
||||
return true; \
|
||||
\
|
||||
if (cc->_ann._insn_capacity > 0 \
|
||||
&& !(cc->_ann._insn_##NAME = \
|
||||
jit_calloc(cc->_ann._insn_capacity * sizeof(TYPE)))) \
|
||||
return false; \
|
||||
\
|
||||
cc->_ann._insn_##NAME##_enabled = 1; \
|
||||
return true; \
|
||||
#define ANN_INSN(TYPE, NAME) \
|
||||
bool jit_anni_enable_##NAME(JitCompContext *cc) \
|
||||
{ \
|
||||
if (cc->_ann._insn_##NAME##_enabled) \
|
||||
return true; \
|
||||
\
|
||||
if (cc->_ann._insn_capacity > 0 \
|
||||
&& !(cc->_ann._insn_##NAME = \
|
||||
jit_calloc(cc->_ann._insn_capacity * sizeof(TYPE)))) { \
|
||||
jit_set_last_error(cc, "anni enable " #NAME "failed"); \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
cc->_ann._insn_##NAME##_enabled = 1; \
|
||||
return true; \
|
||||
}
|
||||
#define ANN_REG(TYPE, NAME) \
|
||||
bool jit_annr_enable_##NAME(JitCompContext *cc) \
|
||||
|
@ -1133,6 +1170,7 @@ jit_cc_new_reg(JitCompContext *cc, unsigned kind)
|
|||
if (cc->_ann._reg_capacity[k] > 0 \
|
||||
&& !(cc->_ann._reg_##NAME[k] = jit_calloc( \
|
||||
cc->_ann._reg_capacity[k] * sizeof(TYPE)))) { \
|
||||
jit_set_last_error(cc, "annr enable " #NAME "failed"); \
|
||||
jit_annr_disable_##NAME(cc); \
|
||||
return false; \
|
||||
} \
|
||||
|
@ -1179,7 +1217,7 @@ jit_cc_new_reg(JitCompContext *cc, unsigned kind)
|
|||
char *
|
||||
jit_get_last_error(JitCompContext *cc)
|
||||
{
|
||||
return cc->last_error[0] == '\0' ? "" : cc->last_error;
|
||||
return cc->last_error[0] == '\0' ? NULL : cc->last_error;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1385,8 +1423,8 @@ to_stack_value_type(uint8 type)
|
|||
bool
|
||||
jit_cc_pop_value(JitCompContext *cc, uint8 type, JitReg *p_value)
|
||||
{
|
||||
JitValue *jit_value;
|
||||
JitReg value;
|
||||
JitValue *jit_value = NULL;
|
||||
JitReg value = 0;
|
||||
|
||||
if (!cc->block_stack.block_list_end) {
|
||||
jit_set_last_error(cc, "WASM block stack underflow");
|
||||
|
|
|
@ -72,78 +72,10 @@
|
|||
#define INSN(NAME, OPND_KIND, OPND_NUM, FIRST_USE)
|
||||
#endif
|
||||
|
||||
/* Comparison instructions */
|
||||
INSN(I32_EQZ, Reg, 3, 1)
|
||||
INSN(I32_EQ, Reg, 3, 1)
|
||||
INSN(I32_NE, Reg, 3, 1)
|
||||
INSN(I32_LT_S, Reg, 3, 1)
|
||||
INSN(I32_LT_U, Reg, 3, 1)
|
||||
INSN(I32_GT_S, Reg, 3, 1)
|
||||
INSN(I32_GT_U, Reg, 3, 1)
|
||||
INSN(I32_LE_S, Reg, 3, 1)
|
||||
INSN(I32_LE_U, Reg, 3, 1)
|
||||
INSN(I32_GE_S, Reg, 3, 1)
|
||||
INSN(I32_GE_U, Reg, 3, 1)
|
||||
|
||||
INSN(I64_EQZ, Reg, 3, 1)
|
||||
INSN(I64_EQ, Reg, 3, 1)
|
||||
INSN(I64_NE, Reg, 3, 1)
|
||||
INSN(I64_LT_S, Reg, 3, 1)
|
||||
INSN(I64_LT_U, Reg, 3, 1)
|
||||
INSN(I64_GT_S, Reg, 3, 1)
|
||||
INSN(I64_GT_U, Reg, 3, 1)
|
||||
INSN(I64_LE_S, Reg, 3, 1)
|
||||
INSN(I64_LE_U, Reg, 3, 1)
|
||||
INSN(I64_GE_S, Reg, 3, 1)
|
||||
INSN(I64_GE_U, Reg, 3, 1)
|
||||
|
||||
INSN(F32_EQ, Reg, 3, 1)
|
||||
INSN(F32_NE, Reg, 3, 1)
|
||||
INSN(F32_LT, Reg, 3, 1)
|
||||
INSN(F32_GT, Reg, 3, 1)
|
||||
INSN(F32_LE, Reg, 3, 1)
|
||||
INSN(F32_GE, Reg, 3, 1)
|
||||
|
||||
INSN(F64_EQ, Reg, 3, 1)
|
||||
INSN(F64_NE, Reg, 3, 1)
|
||||
INSN(F64_LT, Reg, 3, 1)
|
||||
INSN(F64_GT, Reg, 3, 1)
|
||||
INSN(F64_LE, Reg, 3, 1)
|
||||
INSN(F64_GE, Reg, 3, 1)
|
||||
|
||||
/* Select instruction */
|
||||
INSN(SELECT, Reg, 4, 1)
|
||||
|
||||
/* Control instructions */
|
||||
INSN(JMP, Reg, 1, 0)
|
||||
INSN(BEQ, Reg, 3, 0)
|
||||
INSN(BNE, Reg, 3, 0)
|
||||
INSN(BGTS, Reg, 3, 0)
|
||||
INSN(BGES, Reg, 3, 0)
|
||||
INSN(BLTS, Reg, 3, 0)
|
||||
INSN(BLES, Reg, 3, 0)
|
||||
INSN(BGTU, Reg, 3, 0)
|
||||
INSN(BGEU, Reg, 3, 0)
|
||||
INSN(BLTU, Reg, 3, 0)
|
||||
INSN(BLEU, Reg, 3, 0)
|
||||
INSN(TABLE_SWITCH, TableSwitch, 1, 0)
|
||||
INSN(LOOKUP_SWITCH, LookupSwitch, 1, 0)
|
||||
|
||||
/* check zero divisor */
|
||||
INSN(CHECK_DIV_ZERO, Reg, 3, 0)
|
||||
/* check stack overflow */
|
||||
INSN(CHECK_SOE, Reg, 3, 0)
|
||||
|
||||
/* Call and return instructions */
|
||||
INSN(CALLNATIVE, VReg, 2, 1)
|
||||
INSN(CALLBC, Reg, 3, 0)
|
||||
INSN(RETURN, Reg, 1, 0)
|
||||
|
||||
/* Move and conversion instructions that transfer values among
|
||||
registers of the same kind (move) or different kinds (convert) */
|
||||
INSN(MOV, Reg, 2, 1)
|
||||
INSN(PHI, VReg, 1, 1)
|
||||
|
||||
INSN(I32TOI8, Reg, 2, 1)
|
||||
INSN(I32TOU8, Reg, 2, 1)
|
||||
INSN(I32TOI16, Reg, 2, 1)
|
||||
|
@ -193,7 +125,7 @@ INSN(SELECTLTU, Reg, 4, 1)
|
|||
INSN(SELECTLEU, Reg, 4, 1)
|
||||
|
||||
/* Memory access instructions: */
|
||||
INSN(LDSELF, Reg, 1, 1)
|
||||
INSN(LDEXECENV, Reg, 1, 1)
|
||||
INSN(LDJITINFO, Reg, 1, 1)
|
||||
INSN(LDI8, Reg, 3, 1)
|
||||
INSN(LDU8, Reg, 3, 1)
|
||||
|
@ -218,7 +150,69 @@ INSN(STV64, Reg, 3, 1)
|
|||
INSN(STV128, Reg, 3, 1)
|
||||
INSN(STV256, Reg, 3, 1)
|
||||
|
||||
/* Control instructions */
|
||||
INSN(JMP, Reg, 1, 0)
|
||||
INSN(BEQ, Reg, 3, 0)
|
||||
INSN(BNE, Reg, 3, 0)
|
||||
INSN(BGTS, Reg, 3, 0)
|
||||
INSN(BGES, Reg, 3, 0)
|
||||
INSN(BLTS, Reg, 3, 0)
|
||||
INSN(BLES, Reg, 3, 0)
|
||||
INSN(BGTU, Reg, 3, 0)
|
||||
INSN(BGEU, Reg, 3, 0)
|
||||
INSN(BLTU, Reg, 3, 0)
|
||||
INSN(BLEU, Reg, 3, 0)
|
||||
INSN(LOOKUPSWITCH, LookupSwitch, 1, 0)
|
||||
/* INSN(TABLESWITCH, TableSwitch, 1, 0) */
|
||||
|
||||
/* Call and return instructions */
|
||||
INSN(CALLNATIVE, VReg, 2, 1)
|
||||
INSN(CALLBC, Reg, 3, 0)
|
||||
INSN(RETURNBC, Reg, 1, 0)
|
||||
|
||||
#if 0
|
||||
/* Comparison instructions, can be translate to SELECTXXX */
|
||||
INSN(I32_EQZ, Reg, 3, 1)
|
||||
INSN(I32_EQ, Reg, 3, 1)
|
||||
INSN(I32_NE, Reg, 3, 1)
|
||||
INSN(I32_LT_S, Reg, 3, 1)
|
||||
INSN(I32_LT_U, Reg, 3, 1)
|
||||
INSN(I32_GT_S, Reg, 3, 1)
|
||||
INSN(I32_GT_U, Reg, 3, 1)
|
||||
INSN(I32_LE_S, Reg, 3, 1)
|
||||
INSN(I32_LE_U, Reg, 3, 1)
|
||||
INSN(I32_GE_S, Reg, 3, 1)
|
||||
INSN(I32_GE_U, Reg, 3, 1)
|
||||
|
||||
INSN(I64_EQZ, Reg, 3, 1)
|
||||
INSN(I64_EQ, Reg, 3, 1)
|
||||
INSN(I64_NE, Reg, 3, 1)
|
||||
INSN(I64_LT_S, Reg, 3, 1)
|
||||
INSN(I64_LT_U, Reg, 3, 1)
|
||||
INSN(I64_GT_S, Reg, 3, 1)
|
||||
INSN(I64_GT_U, Reg, 3, 1)
|
||||
INSN(I64_LE_S, Reg, 3, 1)
|
||||
INSN(I64_LE_U, Reg, 3, 1)
|
||||
INSN(I64_GE_S, Reg, 3, 1)
|
||||
INSN(I64_GE_U, Reg, 3, 1)
|
||||
|
||||
INSN(F32_EQ, Reg, 3, 1)
|
||||
INSN(F32_NE, Reg, 3, 1)
|
||||
INSN(F32_LT, Reg, 3, 1)
|
||||
INSN(F32_GT, Reg, 3, 1)
|
||||
INSN(F32_LE, Reg, 3, 1)
|
||||
INSN(F32_GE, Reg, 3, 1)
|
||||
|
||||
INSN(F64_EQ, Reg, 3, 1)
|
||||
INSN(F64_NE, Reg, 3, 1)
|
||||
INSN(F64_LT, Reg, 3, 1)
|
||||
INSN(F64_GT, Reg, 3, 1)
|
||||
INSN(F64_LE, Reg, 3, 1)
|
||||
INSN(F64_GE, Reg, 3, 1)
|
||||
|
||||
/* Select instruction */
|
||||
INSN(SELECT, Reg, 4, 1)
|
||||
|
||||
/* Memory instructions */
|
||||
INSN(I32_LOAD, Reg, 2, 1)
|
||||
INSN(I64_LOAD, Reg, 2, 1)
|
||||
|
|
|
@ -907,9 +907,15 @@ typedef struct JitFrame {
|
|||
/* Max operand stack slot number. */
|
||||
uint32 max_stacks;
|
||||
|
||||
/* Instruction pointer */
|
||||
uint8 *ip;
|
||||
|
||||
/* Stack top pointer */
|
||||
JitValueSlot *sp;
|
||||
|
||||
/* Committed instruction pointer */
|
||||
uint8 *committed_ip;
|
||||
|
||||
/* Committed stack top pointer */
|
||||
JitValueSlot *committed_sp;
|
||||
|
||||
|
@ -998,7 +1004,8 @@ typedef struct JitCompContext {
|
|||
be 0 and 1 respectively (see JIT_FOREACH_BLOCK). */
|
||||
JitReg entry_label;
|
||||
JitReg exit_label;
|
||||
JitBasicBlock *exception_basic_blocks;
|
||||
JitBasicBlock **exce_basic_blocks;
|
||||
JitIncomingInsnList *incoming_insns_for_exec_bbs;
|
||||
|
||||
/* The current basic block to generate instructions */
|
||||
JitBasicBlock *cur_basic_block;
|
||||
|
@ -1229,6 +1236,15 @@ jit_cc_inc_ref(JitCompContext *cc)
|
|||
void
|
||||
jit_cc_delete(JitCompContext *cc);
|
||||
|
||||
char *
|
||||
jit_get_last_error(JitCompContext *cc);
|
||||
|
||||
void
|
||||
jit_set_last_error(JitCompContext *cc, const char *error);
|
||||
|
||||
void
|
||||
jit_set_last_error_v(JitCompContext *cc, const char *format, ...);
|
||||
|
||||
/**
|
||||
* Create a I32 constant value with relocatable into the compilation
|
||||
* context. A constant value that has relocation info cannot be
|
||||
|
@ -1520,6 +1536,8 @@ _gen_insn(JitCompContext *cc, JitInsn *insn)
|
|||
{
|
||||
if (insn)
|
||||
jit_basic_block_append_insn(cc->cur_basic_block, insn);
|
||||
else
|
||||
jit_set_last_error(cc, "generate insn failed");
|
||||
|
||||
return insn;
|
||||
}
|
||||
|
@ -1529,6 +1547,7 @@ _gen_insn(JitCompContext *cc, JitInsn *insn)
|
|||
*/
|
||||
#define GEN_INSN(...) _gen_insn(cc, jit_cc_new_insn(cc, __VA_ARGS__))
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Helper function for GEN_INSN_NORM_1
|
||||
*
|
||||
|
@ -1559,6 +1578,7 @@ _gen_insn_norm_1(JitCompContext *cc, JitBasicBlock *block, unsigned kind,
|
|||
*/
|
||||
#define GEN_INSN_NORM(Type, result, ...) \
|
||||
GEN_INSN_NORM_1(JIT_REG_KIND_##Type, result, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Create a constant register without relocation info.
|
||||
|
@ -1737,15 +1757,6 @@ jit_cc_exit_basic_block(JitCompContext *cc)
|
|||
return *(jit_annl_basic_block(cc, cc->exit_label));
|
||||
}
|
||||
|
||||
char *
|
||||
jit_get_last_error(JitCompContext *cc);
|
||||
|
||||
void
|
||||
jit_set_last_error(JitCompContext *cc, const char *error);
|
||||
|
||||
void
|
||||
jit_set_last_error_v(JitCompContext *cc, const char *format, ...);
|
||||
|
||||
void
|
||||
jit_value_stack_push(JitValueStack *stack, JitValue *value);
|
||||
|
||||
|
|
|
@ -312,8 +312,11 @@ rc_init(RegallocContext *rc, JitCompContext *cc)
|
|||
const unsigned vreg_num = jit_cc_reg_num(cc, i);
|
||||
const unsigned hreg_num = jit_cc_hreg_num(cc, i);
|
||||
|
||||
if (!(rc->vregs[i] = jit_calloc(sizeof(VirtualReg) * vreg_num))
|
||||
|| !(rc->hregs[i] = jit_calloc(sizeof(HardReg) * hreg_num)))
|
||||
if (vreg_num > 0
|
||||
&& !(rc->vregs[i] = jit_calloc(sizeof(VirtualReg) * vreg_num)))
|
||||
goto fail;
|
||||
if (hreg_num > 0
|
||||
&& !(rc->hregs[i] = jit_calloc(sizeof(HardReg) * hreg_num)))
|
||||
goto fail;
|
||||
|
||||
/* Hard registers can only be allocated to themselves. */
|
||||
|
@ -407,8 +410,8 @@ reload_vreg(RegallocContext *rc, JitReg vreg, JitInsn *cur_insn)
|
|||
JitInsn *insn = NULL;
|
||||
|
||||
if (vreg == rc->cc->exec_env_reg)
|
||||
/* Reload exec_env_reg with LDSELF. */
|
||||
insn = jit_cc_new_insn(rc->cc, LDSELF, vr->hreg);
|
||||
/* Reload exec_env_reg with LDEXECENV. */
|
||||
insn = jit_cc_new_insn(rc->cc, LDEXECENV, vr->hreg);
|
||||
else
|
||||
/* Allocate spill slot if not yet and reload from there. */
|
||||
{
|
||||
|
|
|
@ -3767,8 +3767,11 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
|||
#if WASM_ENABLE_FAST_JIT == 0
|
||||
wasm_interp_call_func_bytecode(module_inst, exec_env, function, frame);
|
||||
#else
|
||||
jit_interp_switch_to_jitted(exec_env, frame, function,
|
||||
JitInterpSwitchInfo info;
|
||||
info.frame = frame;
|
||||
jit_interp_switch_to_jitted(exec_env, &info,
|
||||
function->u.func->jitted_code);
|
||||
(void)wasm_interp_call_func_bytecode;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -123,11 +123,15 @@ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security -W
|
|||
if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
|
||||
if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang"))
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mindirect-branch-register")
|
||||
# UNDEFINED BEHAVIOR, refer to https://en.cppreference.com/w/cpp/language/ub
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT WAMR_BUILD_JIT EQUAL 1)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined \
|
||||
-fno-sanitize=bounds,bounds-strict,alignment \
|
||||
-fno-sanitize-recover")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined \
|
||||
-fno-sanitize=bounds,bounds-strict,alignment \
|
||||
-fno-sanitize-recover")
|
||||
endif()
|
||||
else ()
|
||||
# UNDEFINED BEHAVIOR, refer to https://en.cppreference.com/w/cpp/language/ub
|
||||
|
@ -135,6 +139,9 @@ if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
|
|||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined \
|
||||
-fno-sanitize=bounds,alignment \
|
||||
-fno-sanitize-recover")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined \
|
||||
-fno-sanitize=bounds,alignment \
|
||||
-fno-sanitize-recover")
|
||||
endif()
|
||||
endif ()
|
||||
endif ()
|
||||
|
|
Loading…
Reference in New Issue
Block a user