Apple:使用-O0和-O2(内核)编译clang框架大小

问题描述 投票:2回答:1

我有一个现有项目,我们为开发人员编译DEBUG(和-O0,所以lldb有意义)。但是我有一个功能,特别是当使用-O0时气球的大小:

-O2 -Wframe-larger-than=100
warning: stack frame size of 168 bytes in function 'dsl_scan_visitbp'
-O0 -Wframe-larger-than=100
warning: stack frame size of 1160 bytes in function 'dsl_scan_visitbp'

并进行一些递归,可能会非常浪费堆栈(内核中有16K堆栈)。

首先要检查的是任何局部变量,但我相信只有两个:

        dsl_pool_t *dp = scn->scn_dp;
        blkptr_t *bp_toread = NULL;

如果要查看整个功能:https://github.com/openzfs/zfs/blob/master/module/zfs/dsl_scan.c#L1908(Linux资料来源,但处理Apple clang端口)

该源文件中有一堆alwaysinline,也可能在这里播放。

但是我很好奇为什么-O0会使它变得如此之大?

然后该怎么办,我看不到任何Apple-clang #pragmas在一个文件或一个文件的源文件中打开(打开)优化(仅关闭优化)。如果我知道原因是什么,也许我可以用另一个编译指示来控制该特定问题。

[我现在看到的唯一解决方案是在Makefile中对dsl_scan.c进行不同的处理,以便仅该文件始终获得-O2。但这有点乏味。

c macos kernel clang kernel-extension
1个回答
0
投票

由于我对代码库不熟悉,所以我看不到任何明显的变量会占用大量堆栈空间。但是,我注意到函数(包括always_inline d)很长。通常,在调试版本中,无论范围如何,都会在堆栈帧中为every变量和临时表达式结果分配一个unique空间。因此,即使2个变量的生存期不重叠(例如,在if块中声明了一个变量,在else块中声明了另一个变量),也将在内存中为其分配单独的空间。因此,即使存在很多小的短期变量和临时值,这也可能加起来。

您最好在调试版本中禁用此函数调用的所有函数中的always_inline属性,因为这样可以避免为所有可能的执行分支预先分配内存,即使它们从未被使用过,或者即使它们在递归不涉及的函数。

© www.soinside.com 2019 - 2024. All rights reserved.