@@ -366,6 +366,87 @@ call_aot_free_frame_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
366366#endif /* end of (WASM_ENABLE_DUMP_CALL_STACK != 0) \
367367 || (WASM_ENABLE_PERF_PROFILING != 0) */
368368
369+ static bool
370+ record_stack_usage (AOTCompContext * comp_ctx , AOTFuncContext * func_ctx ,
371+ uint32 callee_cell_num )
372+ {
373+ LLVMBasicBlockRef block_curr = LLVMGetInsertBlock (comp_ctx -> builder );
374+ LLVMBasicBlockRef block_update ;
375+ LLVMBasicBlockRef block_after_update ;
376+ LLVMValueRef callee_local_size , new_sp , cmp ;
377+ LLVMValueRef native_stack_top_min ;
378+ LLVMTypeRef ptrdiff_type ;
379+ if (comp_ctx -> pointer_size == sizeof (uint64_t )) {
380+ ptrdiff_type = I64_TYPE ;
381+ }
382+ else {
383+ ptrdiff_type = I32_TYPE ;
384+ }
385+
386+ /*
387+ * new_sp = last_alloca - callee_local_size;
388+ * if (*native_stack_top_min_addr > new_sp) {
389+ * *native_stack_top_min_addr = new_sp;
390+ * }
391+ */
392+
393+ if (!(callee_local_size = LLVMConstInt (
394+ ptrdiff_type , - (int64_t )callee_cell_num * 4 , true))) {
395+ aot_set_last_error ("llvm build const failed." );
396+ return false;
397+ }
398+ if (!(new_sp = LLVMBuildInBoundsGEP2 (comp_ctx -> builder , INT8_TYPE ,
399+ func_ctx -> last_alloca ,
400+ & callee_local_size , 1 , "new_sp" ))) {
401+ aot_set_last_error ("llvm build gep failed" );
402+ return false;
403+ }
404+ if (!(native_stack_top_min = LLVMBuildLoad2 (
405+ comp_ctx -> builder , OPQ_PTR_TYPE ,
406+ func_ctx -> native_stack_top_min_addr , "native_stack_top_min" ))) {
407+ aot_set_last_error ("llvm build load failed" );
408+ return false;
409+ }
410+ if (!(cmp = LLVMBuildICmp (comp_ctx -> builder , LLVMIntULT , new_sp ,
411+ native_stack_top_min , "cmp" ))) {
412+ aot_set_last_error ("llvm build icmp failed." );
413+ return false;
414+ }
415+
416+ if (!(block_update = LLVMAppendBasicBlockInContext (
417+ comp_ctx -> context , func_ctx -> func , "block_update" ))) {
418+ aot_set_last_error ("llvm add basic block failed." );
419+ return false;
420+ }
421+ if (!(block_after_update = LLVMAppendBasicBlockInContext (
422+ comp_ctx -> context , func_ctx -> func , "block_after_update" ))) {
423+ aot_set_last_error ("llvm add basic block failed." );
424+ return false;
425+ }
426+ LLVMMoveBasicBlockAfter (block_update , block_curr );
427+ LLVMMoveBasicBlockAfter (block_after_update , block_update );
428+
429+ if (!LLVMBuildCondBr (comp_ctx -> builder , cmp , block_update ,
430+ block_after_update )) {
431+ aot_set_last_error ("llvm build cond br failed." );
432+ return false;
433+ }
434+
435+ LLVMPositionBuilderAtEnd (comp_ctx -> builder , block_update );
436+ if (!LLVMBuildStore (comp_ctx -> builder , new_sp ,
437+ func_ctx -> native_stack_top_min_addr )) {
438+ aot_set_last_error ("llvm build store failed" );
439+ return false;
440+ }
441+ if (!LLVMBuildBr (comp_ctx -> builder , block_after_update )) {
442+ aot_set_last_error ("llvm build br failed." );
443+ return false;
444+ }
445+
446+ LLVMPositionBuilderAtEnd (comp_ctx -> builder , block_after_update );
447+ return true;
448+ }
449+
369450static bool
370451check_stack_boundary (AOTCompContext * comp_ctx , AOTFuncContext * func_ctx ,
371452 uint32 callee_cell_num )
@@ -409,6 +490,19 @@ check_stack_boundary(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
409490 return true;
410491}
411492
493+ static bool
494+ check_stack (AOTCompContext * comp_ctx , AOTFuncContext * func_ctx ,
495+ uint32 callee_cell_num )
496+ {
497+ if (comp_ctx -> enable_stack_estimation
498+ && !record_stack_usage (comp_ctx , func_ctx , callee_cell_num ))
499+ return false;
500+ if (comp_ctx -> enable_stack_bound_check
501+ && !check_stack_boundary (comp_ctx , func_ctx , callee_cell_num ))
502+ return false;
503+ return true;
504+ }
505+
412506/**
413507 * Check whether the app address and its buffer are inside the linear memory,
414508 * if no, throw exception
@@ -852,8 +946,7 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
852946 callee_cell_num =
853947 aot_func -> param_cell_num + aot_func -> local_cell_num + 1 ;
854948
855- if (comp_ctx -> enable_stack_bound_check
856- && !check_stack_boundary (comp_ctx , func_ctx , callee_cell_num ))
949+ if (!check_stack (comp_ctx , func_ctx , callee_cell_num ))
857950 goto fail ;
858951
859952#if LLVM_VERSION_MAJOR >= 14
@@ -1467,12 +1560,11 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
14671560 /* Translate call non-import block */
14681561 LLVMPositionBuilderAtEnd (comp_ctx -> builder , block_call_non_import );
14691562
1470- if (comp_ctx -> enable_stack_bound_check
1471- && !check_stack_boundary (comp_ctx , func_ctx ,
1472- param_cell_num + ext_cell_num
1473- + 1
1474- /* Reserve some local variables */
1475- + 16 ))
1563+ if (!check_stack (comp_ctx , func_ctx ,
1564+ param_cell_num + ext_cell_num
1565+ + 1
1566+ /* Reserve some local variables */
1567+ + 16 ))
14761568 goto fail ;
14771569
14781570 /* Load function pointer */
0 commit comments