Skip to content

Commit 6b51bc0

Browse files
committed
Change direct call into indirect call in aot_add_precheck_function
1 parent 16a4d71 commit 6b51bc0

File tree

2 files changed

+81
-4
lines changed

2 files changed

+81
-4
lines changed

core/iwasm/compilation/aot_emit_aot_file.c

+35-1
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,12 @@ get_func_section_size(AOTCompContext *comp_ctx, AOTCompData *comp_data,
870870
/* function type indexes */
871871
size += (uint32)sizeof(uint32) * comp_data->func_count;
872872

873+
const bool need_precheck = obj_data->comp_ctx->enable_stack_bound_check
874+
|| obj_data->comp_ctx->enable_stack_estimation;
875+
/* aot_func#xxx + aot_func_internal#xxx in XIP mode for xtensa */
876+
if (obj_data->comp_ctx->is_indirect_mode && need_precheck)
877+
size *= 2;
878+
873879
/* max_local_cell_nums */
874880
size += (uint32)sizeof(uint32) * comp_data->func_count;
875881

@@ -2409,7 +2415,12 @@ aot_emit_init_data_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
24092415
return false;
24102416

24112417
offset = align_uint(offset, 4);
2412-
EMIT_U32(comp_data->func_count);
2418+
const bool need_precheck = obj_data->comp_ctx->enable_stack_bound_check
2419+
|| obj_data->comp_ctx->enable_stack_estimation;
2420+
if (obj_data->comp_ctx->is_indirect_mode && need_precheck)
2421+
EMIT_U32(comp_data->func_count * 2);
2422+
else
2423+
EMIT_U32(comp_data->func_count);
24132424
EMIT_U32(comp_data->start_func_index);
24142425

24152426
EMIT_U32(comp_data->aux_data_end_global_index);
@@ -2594,6 +2605,23 @@ aot_emit_func_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
25942605
EMIT_U64(func->text_offset);
25952606
}
25962607

2608+
const bool need_precheck = obj_data->comp_ctx->enable_stack_bound_check
2609+
|| obj_data->comp_ctx->enable_stack_estimation;
2610+
if (obj_data->comp_ctx->is_indirect_mode && need_precheck) {
2611+
/*
2612+
* Explicitly emit aot_func_internal#xxx for Xtensa XIP, therefore,
2613+
* for aot_func#xxx, func_indexes ranged from 0 ~ func_count,
2614+
* for aot_func_internal#xxxx, from func_count + 1 ~ 2 * func_count.
2615+
*/
2616+
for (i = 0, func = obj_data->funcs; i < obj_data->func_count;
2617+
i++, func++) {
2618+
if (is_32bit_binary(obj_data))
2619+
EMIT_U32(func->text_offset_of_aot_func_internal);
2620+
else
2621+
EMIT_U64(func->text_offset_of_aot_func_internal);
2622+
}
2623+
}
2624+
25972625
for (i = 0; i < comp_data->func_count; i++)
25982626
EMIT_U32(funcs[i]->func_type_index);
25992627

@@ -2660,6 +2688,12 @@ aot_emit_func_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
26602688
}
26612689
#endif /* end of WASM_ENABLE_GC != 0 */
26622690

2691+
if (obj_data->comp_ctx->is_indirect_mode && need_precheck) {
2692+
/* func_type_index for aot_func_internal#xxxx */
2693+
for (i = 0; i < comp_data->func_count; i++)
2694+
EMIT_U32(funcs[i]->func_type_index);
2695+
}
2696+
26632697
if (offset - *p_offset != section_size + sizeof(uint32) * 2) {
26642698
aot_set_last_error("emit function section failed.");
26652699
return false;

core/iwasm/compilation/aot_llvm.c

+46-3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ create_native_stack_bound(const AOTCompContext *comp_ctx,
2424
static bool
2525
create_native_stack_top_min(const AOTCompContext *comp_ctx,
2626
AOTFuncContext *func_ctx);
27+
static bool
28+
create_func_ptrs(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
2729

2830
LLVMTypeRef
2931
wasm_type_to_llvm_type(const AOTCompContext *comp_ctx,
@@ -334,6 +336,9 @@ aot_build_precheck_function(AOTCompContext *comp_ctx, LLVMModuleRef module,
334336
&& !create_native_stack_top_min(comp_ctx, func_ctx)) {
335337
goto fail;
336338
}
339+
if (!create_func_ptrs(comp_ctx, func_ctx)) {
340+
goto fail;
341+
}
337342

338343
uint32 param_count = LLVMCountParams(precheck_func);
339344
uint32 sz = param_count * (uint32)sizeof(LLVMValueRef);
@@ -537,8 +542,46 @@ aot_build_precheck_function(AOTCompContext *comp_ctx, LLVMModuleRef module,
537542
if (ret_type == VOID_TYPE) {
538543
name = "";
539544
}
540-
LLVMValueRef retval =
541-
LLVMBuildCall2(b, func_type, wrapped_func, params, param_count, name);
545+
546+
LLVMValueRef retval;
547+
if (comp_ctx->is_indirect_mode) {
548+
/* call wrapped_func indirectly */
549+
LLVMTypeRef func_ptr_type;
550+
LLVMValueRef wrapped_func_indirect;
551+
uint32 import_func_count = comp_ctx->comp_data->import_func_count;
552+
uint32 func_count = comp_ctx->func_ctx_count;
553+
554+
/* Check function index */
555+
if (func_index >= import_func_count + func_count) {
556+
aot_set_last_error("Function index out of range.");
557+
return false;
558+
}
559+
560+
/* Get function type */
561+
if (!(func_ptr_type = LLVMPointerType(func_type, 0))) {
562+
aot_set_last_error("create LLVM function type failed.");
563+
goto fail;
564+
}
565+
566+
/*
567+
* func_index layout :
568+
* aot_func#xxx, range from 0 ~ func_conut - 1;
569+
* aot_func#internal#xxx, range from func_conut ~ 2 * func_conut - 1;
570+
*/
571+
if (!(wrapped_func_indirect = aot_get_func_from_table(
572+
comp_ctx, func_ctx->func_ptrs, func_ptr_type,
573+
func_index + func_count + import_func_count))) {
574+
goto fail;
575+
}
576+
577+
/* Call the function indirectly */
578+
retval = LLVMBuildCall2(b, func_type, wrapped_func_indirect, params,
579+
param_count, name);
580+
}
581+
else
582+
retval = LLVMBuildCall2(b, func_type, wrapped_func, params, param_count,
583+
name);
584+
542585
if (!retval) {
543586
goto fail;
544587
}
@@ -732,7 +775,7 @@ aot_add_llvm_func(AOTCompContext *comp_ctx, LLVMModuleRef module,
732775
}
733776

734777
if (need_precheck) {
735-
if (!comp_ctx->is_jit_mode)
778+
if (!comp_ctx->is_jit_mode && !comp_ctx->is_indirect_mode)
736779
LLVMSetLinkage(func, LLVMInternalLinkage);
737780
unsigned int kind =
738781
LLVMGetEnumAttributeKindForName("noinline", strlen("noinline"));

0 commit comments

Comments
 (0)