mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
Lower @returnAddress to a constant 0 in Emscripten release builds
Emscripten currently implements `emscripten_return_address()` by calling out into JavaScript and parsing a stack trace, which introduces significant overhead that we would prefer to avoid in release builds. This is especially problematic for allocators because the generic parts of `std.mem.Allocator` make frequent use of `@returnAddress`, even though very few allocator implementations even observe the return address, which makes allocators nigh unusable for performance-critical applications like games if the compiler is unable to devirtualize the allocator calls.
This commit is contained in:
parent
9f235a105b
commit
f45f9649e3
@ -183,9 +183,11 @@ pub const sys_can_stack_trace = switch (builtin.cpu.arch) {
|
||||
|
||||
// `@returnAddress()` in LLVM 10 gives
|
||||
// "Non-Emscripten WebAssembly hasn't implemented __builtin_return_address".
|
||||
// On Emscripten, Zig only supports `@returnAddress()` in debug builds
|
||||
// because Emscripten's implementation is very slow.
|
||||
.wasm32,
|
||||
.wasm64,
|
||||
=> native_os == .emscripten,
|
||||
=> native_os == .emscripten and builtin.mode == .Debug,
|
||||
|
||||
// `@returnAddress()` is unsupported in LLVM 13.
|
||||
.bpfel,
|
||||
|
||||
@ -9525,7 +9525,7 @@ pub const FuncGen = struct {
|
||||
_ = inst;
|
||||
const o = self.ng.object;
|
||||
const llvm_usize = try o.lowerType(Type.usize);
|
||||
if (!target_util.supportsReturnAddress(o.pt.zcu.getTarget())) {
|
||||
if (!target_util.supportsReturnAddress(o.pt.zcu.getTarget(), self.ng.ownerModule().optimize_mode)) {
|
||||
// https://github.com/ziglang/zig/issues/11946
|
||||
return o.builder.intValue(llvm_usize, 0);
|
||||
}
|
||||
|
||||
@ -248,9 +248,14 @@ pub fn libcProvidesStackProtector(target: std.Target) bool {
|
||||
return !target.isMinGW() and target.os.tag != .wasi and !target.cpu.arch.isSpirV();
|
||||
}
|
||||
|
||||
pub fn supportsReturnAddress(target: std.Target) bool {
|
||||
/// Returns true if `@returnAddress()` is supported by the target and has a
|
||||
/// reasonably performant implementation for the requested optimization mode.
|
||||
pub fn supportsReturnAddress(target: std.Target, optimize: std.builtin.OptimizeMode) bool {
|
||||
return switch (target.cpu.arch) {
|
||||
.wasm32, .wasm64 => target.os.tag == .emscripten,
|
||||
// Emscripten currently implements `emscripten_return_address()` by calling
|
||||
// out into JavaScript and parsing a stack trace, which introduces significant
|
||||
// overhead that we would prefer to avoid in release builds.
|
||||
.wasm32, .wasm64 => target.os.tag == .emscripten and optimize == .Debug,
|
||||
.bpfel, .bpfeb => false,
|
||||
.spirv, .spirv32, .spirv64 => false,
|
||||
else => true,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user