Implement memory access bound check with hardware trap for 64-bit platforms (#293)

Also implement native stack overflow check with hardware trap for 64-bit platforms
Refine classic interpreter and fast interpreter to improve performance
Update document
This commit is contained in:
wenyongh
2020-06-28 15:41:25 +08:00
committed by GitHub
parent 548926ab1a
commit ee315e4049
33 changed files with 1143 additions and 438 deletions

View File

@ -182,29 +182,6 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}
}
/* Load total memory size */
offset = I32_CONST(offsetof(AOTModuleInstance, total_mem_size));
if (!(func_ctx->total_mem_size =
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
&offset, 1, "bound_check_1byte_offset"))) {
aot_set_last_error("llvm build in bounds gep failed");
return false;
}
if (!(func_ctx->total_mem_size =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->total_mem_size,
INT32_PTR_TYPE, "bound_check_1byte_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (mem_space_unchanged) {
if (!(func_ctx->total_mem_size =
LLVMBuildLoad(comp_ctx->builder, func_ctx->total_mem_size,
"bound_check_1byte"))) {
aot_set_last_error("llvm build load failed");
return false;
}
}
/* Load memory bound check constants */
offset = I32_CONST(offsetof(AOTModuleInstance, mem_bound_check_1byte));
if (!(func_ctx->mem_bound_check_1byte =
@ -215,7 +192,7 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}
if (!(func_ctx->mem_bound_check_1byte =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_bound_check_1byte,
INT32_PTR_TYPE, "bound_check_1byte_ptr"))) {
INT64_PTR_TYPE, "bound_check_1byte_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
@ -237,7 +214,7 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}
if (!(func_ctx->mem_bound_check_2bytes =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_bound_check_2bytes,
INT32_PTR_TYPE, "bound_check_2bytes_ptr"))) {
INT64_PTR_TYPE, "bound_check_2bytes_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
@ -259,7 +236,7 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}
if (!(func_ctx->mem_bound_check_4bytes =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_bound_check_4bytes,
INT32_PTR_TYPE, "bound_check_4bytes_ptr"))) {
INT64_PTR_TYPE, "bound_check_4bytes_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
@ -281,7 +258,7 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}
if (!(func_ctx->mem_bound_check_8bytes =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_bound_check_8bytes,
INT32_PTR_TYPE, "bound_check_8bytes_ptr"))) {
INT64_PTR_TYPE, "bound_check_8bytes_ptr"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
@ -294,23 +271,23 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}
}
/* Load heap base offset */
offset = I32_CONST(offsetof(AOTModuleInstance, heap_base_offset));
if (!(func_ctx->heap_base_offset =
/* Load bound_check_heap_base */
offset = I32_CONST(offsetof(AOTModuleInstance, mem_bound_check_heap_base));
if (!(func_ctx->mem_bound_check_heap_base =
LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
&offset, 1, "heap_base_offset_offset"))) {
&offset, 1, "bound_check_heap_base_offset"))) {
aot_set_last_error("llvm build in bounds gep failed");
return false;
}
if (!(func_ctx->heap_base_offset =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->heap_base_offset,
INT32_PTR_TYPE, "heap_base_offset_tmp"))) {
if (!(func_ctx->mem_bound_check_heap_base =
LLVMBuildBitCast(comp_ctx->builder, func_ctx->mem_bound_check_heap_base,
INT64_PTR_TYPE, "bound_check_heap_base_tmp"))) {
aot_set_last_error("llvm build bit cast failed");
return false;
}
if (!(func_ctx->heap_base_offset =
LLVMBuildLoad(comp_ctx->builder, func_ctx->heap_base_offset,
"heap_base_offset"))) {
if (!(func_ctx->mem_bound_check_heap_base =
LLVMBuildLoad(comp_ctx->builder, func_ctx->mem_bound_check_heap_base,
"bound_check_heap_base"))) {
aot_set_last_error("llvm build load failed");
return false;
}
@ -936,6 +913,11 @@ aot_create_comp_context(AOTCompData *comp_data,
comp_ctx->is_jit_mode = true;
comp_ctx->target_machine =
LLVMGetExecutionEngineTargetMachine(comp_ctx->exec_engine);
#ifndef OS_ENABLE_HW_BOUND_CHECK
comp_ctx->enable_bound_check = true;
#else
comp_ctx->enable_bound_check = false;
#endif
}
else {
/* Create LLVM target machine */
@ -1049,6 +1031,21 @@ aot_create_comp_context(AOTCompData *comp_data,
get_target_arch_from_triple(triple_norm, comp_ctx->target_arch,
sizeof(comp_ctx->target_arch));
if (option->bounds_checks == 1 || option->bounds_checks == 0) {
/* Set by user */
comp_ctx->enable_bound_check =
(option->bounds_checks == 1) ? true : false;
}
else {
/* Unset by user, use default value */
if (strstr(comp_ctx->target_arch, "64") && !option->is_sgx_platform) {
comp_ctx->enable_bound_check = false;
}
else {
comp_ctx->enable_bound_check = true;
}
}
os_printf("Create AoT compiler with:\n");
os_printf(" target: %s\n", comp_ctx->target_arch);
os_printf(" target cpu: %s\n", cpu);
@ -1114,14 +1111,11 @@ aot_create_comp_context(AOTCompData *comp_data,
goto fail;
}
LLVMAddBasicAliasAnalysisPass(comp_ctx->pass_mgr);
LLVMAddPromoteMemoryToRegisterPass(comp_ctx->pass_mgr);
LLVMAddInstructionCombiningPass(comp_ctx->pass_mgr);
LLVMAddCFGSimplificationPass(comp_ctx->pass_mgr);
LLVMAddJumpThreadingPass(comp_ctx->pass_mgr);
LLVMAddConstantPropagationPass(comp_ctx->pass_mgr);
LLVMAddReassociatePass(comp_ctx->pass_mgr);
LLVMAddGVNPass(comp_ctx->pass_mgr);
LLVMAddCFGSimplificationPass(comp_ctx->pass_mgr);
/* Create metadata for llvm float experimental constrained intrinsics */
if (!(comp_ctx->fp_rounding_mode =