diff options
| author | Carl Ã…stholm <carl@astholm.se> | 2025-03-23 13:12:45 +0100 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2025-03-23 17:13:19 -0400 |
| commit | f45f9649e3fc2aa2b6a76476f2467f02ffc7d461 (patch) | |
| tree | 4d10ac814ef9d7d7e9f06fffac796217336bfbc5 /src | |
| parent | 9f235a105b29c6f1c0c773f66c40e7ee655da559 (diff) | |
| download | zig-f45f9649e3fc2aa2b6a76476f2467f02ffc7d461.tar.gz zig-f45f9649e3fc2aa2b6a76476f2467f02ffc7d461.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/codegen/llvm.zig | 2 | ||||
| -rw-r--r-- | src/target.zig | 9 |
2 files changed, 8 insertions, 3 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 167e0d1607..f4e4c1cdd6 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -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); } diff --git a/src/target.zig b/src/target.zig index 76eec4fa6e..5c8f7895b5 100644 --- a/src/target.zig +++ b/src/target.zig @@ -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, |
