我們正在對LLVM庫進行研究,我們發現IR庫有時可以調用多達29個方法調用的堆棧。是否產生深層調用堆棧的代碼被視爲反模式?
有時,當我在iOS框架中看到一些崩潰時,我也觀察到相當深的調用堆棧。
我的問題是,我們是否可以推斷一個代碼的設計是否可能會出現問題,這種代碼的設計如此深度。
下面是一個例子:
/usr/local/LLVM/llvm/unittests/IR/AttributesTest.cpp:54
/usr/local/LLVM/llvm/lib/IR/LLVMContext.cpp:162
/usr/local/LLVM/llvm/lib/IR/LLVMContext.cpp:162
/usr/local/LLVM/llvm/lib/IR/LLVMContextImpl.cpp:54
/usr/local/LLVM/llvm/lib/IR/LLVMContextImpl.cpp:59
/usr/local/LLVM/llvm/lib/IR/Module.cpp:60
/usr/local/LLVM/llvm/lib/IR/Module.cpp:62
/usr/local/LLVM/llvm/lib/IR/Module.cpp:456
/usr/local/LLVM/llvm/lib/IR/Function.cpp:350
/usr/local/LLVM/llvm/lib/IR/BasicBlock.cpp:98
/usr/local/LLVM/llvm/include/llvm/ADT/ilist.h:282
/usr/local/LLVM/llvm/include/llvm/ADT/ilist.h:267
/usr/local/LLVM/llvm/lib/IR/SymbolTableListTraitsImpl.h:76
/usr/local/LLVM/llvm/lib/IR/BasicBlock.cpp:90
/usr/local/LLVM/llvm/lib/IR/SymbolTableListTraitsImpl.h:58
/usr/local/LLVM/llvm/lib/IR/ValueSymbolTable.cpp:75
/usr/local/LLVM/llvm/lib/IR/ValueSymbolTable.cpp:47
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:132
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:112
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:122
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:96
/usr/local/LLVM/llvm/include/llvm/IR/Value.h:777
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:132
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:122
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:75
/usr/local/LLVM/llvm/include/llvm/IR/Value.h:771
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:132
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:122
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:75
/usr/local/LLVM/llvm/include/llvm/IR/Value.h:759
P.S.示例調用堆棧實際上是由LLVMContext類的析構函數生成的:LLVMContext::~LLVMContext()
。這是來自Java世界的一篇非常古老的帖子的另一個例子:Java call stack – from HTTP upto JDBC as a picture。
取決於「深」的尺度。例如,對於樹遍歷來說,使用樹深度來生成調用堆棧比例是非常標準的。 – user2357112
它在旁觀者的眼中。也許虛擬方法是一種反模式。也許甚至C++或者面向對象都是反模式。 – wildplasser
除非我們保證遞歸深度,否則樹遍歷和其他遞歸模式不應該使用調用堆棧進行遞歸,而是使用迭代實現,以避免爆炸堆棧大小限制。這在Clang/LLVM中是有效的。 – Joky