Print list of CPU features in crash reports (#12350)

Co-authored-by: Jarred-Sumner <Jarred-Sumner@users.noreply.github.com>
This commit is contained in:
Jarred Sumner
2024-07-08 15:08:07 -07:00
committed by GitHub
parent c2a5451e93
commit a4b0817cd3
7 changed files with 212 additions and 5 deletions

View File

@@ -3,7 +3,7 @@ cmake_policy(SET CMP0091 NEW)
cmake_policy(SET CMP0067 NEW)
set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
set(Bun_VERSION "1.1.18")
set(Bun_VERSION "1.1.19")
set(WEBKIT_TAG 615e8585f96aa718b0f5158210259b83fe8440ea)
set(BUN_WORKDIR "${CMAKE_CURRENT_BINARY_DIR}")
@@ -1126,6 +1126,7 @@ if(WIN32)
set_property(TARGET ${bun} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
target_compile_options(${bun} PUBLIC "/EHsc" "/GR-")
target_link_options(${bun} PUBLIC "/STACK:0x1200000,0x100000" "/DEF:${BUN_SRC}/symbols.def" "/errorlimit:0")
else()
target_compile_options(${bun} PUBLIC

2
LATEST
View File

@@ -1 +1 @@
1.1.17
1.1.18

View File

@@ -101,7 +101,6 @@ pub const Features = struct {
pub var loaders: usize = 0;
pub var lockfile_migration_from_package_lock: usize = 0;
pub var macros: usize = 0;
pub var origin: usize = 0;
pub var shell: usize = 0;
pub var spawn: usize = 0;
pub var standalone_shell: usize = 0;
@@ -110,7 +109,8 @@ pub const Features = struct {
pub var tsconfig: usize = 0;
pub var virtual_modules: usize = 0;
pub var WebSocket: usize = 0;
pub var no_avx: usize = 0;
pub var no_avx2: usize = 0;
pub var builtin_modules = std.enums.EnumSet(bun.JSC.HardcodedModule).initEmpty();
pub fn formatter() Formatter {

View File

@@ -0,0 +1,110 @@
#include "root.h"
enum class X86CPUFeature : uint8_t {
sse42 = 1,
popcnt = 2,
avx = 3,
avx2 = 4,
avx512 = 5,
};
enum class AArch64CPUFeature : uint8_t {
neon = 1,
fp = 2,
aes = 3,
crc32 = 4,
atomics = 5,
sve = 6,
};
#if CPU(X86_64)
#if OS(WINDOWS)
#include <windows.h>
#endif
static uint8_t x86_cpu_features()
{
uint8_t features = 0;
#if OS(WINDOWS)
if (IsProcessorFeaturePresent(PF_SSE4_2_INSTRUCTIONS_AVAILABLE))
features |= 1 << static_cast<uint8_t>(X86CPUFeature::sse42);
if (IsProcessorFeaturePresent(PF_AVX_INSTRUCTIONS_AVAILABLE))
features |= 1 << static_cast<uint8_t>(X86CPUFeature::avx);
if (IsProcessorFeaturePresent(PF_AVX2_INSTRUCTIONS_AVAILABLE))
features |= 1 << static_cast<uint8_t>(X86CPUFeature::avx2);
if (IsProcessorFeaturePresent(PF_AVX512F_INSTRUCTIONS_AVAILABLE))
features |= 1 << static_cast<uint8_t>(X86CPUFeature::avx512);
#else
#if __has_builtin(__builtin_cpu_supports)
__builtin_cpu_init();
if (__builtin_cpu_supports("sse4.2"))
features |= 1 << static_cast<uint8_t>(X86CPUFeature::sse42);
if (__builtin_cpu_supports("popcnt"))
features |= 1 << static_cast<uint8_t>(X86CPUFeature::popcnt);
if (__builtin_cpu_supports("avx"))
features |= 1 << static_cast<uint8_t>(X86CPUFeature::avx);
if (__builtin_cpu_supports("avx2"))
features |= 1 << static_cast<uint8_t>(X86CPUFeature::avx2);
if (__builtin_cpu_supports("avx512f"))
features |= 1 << static_cast<uint8_t>(X86CPUFeature::avx512);
#endif
#endif
return features;
}
#endif
#if CPU(ARM64)
static uint8_t aarch64_cpu_features()
{
uint8_t features = 0;
#if OS(WINDOWS)
#pragma error "TODO: Implement AArch64 CPU features for Windows"
#endif
#if __has_builtin(__builtin_cpu_supports)
__builtin_cpu_init();
if (__builtin_cpu_supports("neon"))
features |= 1 << static_cast<uint8_t>(AArch64CPUFeature::neon);
if (__builtin_cpu_supports("crypto"))
features |= 1 << static_cast<uint8_t>(AArch64CPUFeature::fp);
if (__builtin_cpu_supports("aes"))
features |= 1 << static_cast<uint8_t>(AArch64CPUFeature::aes);
if (__builtin_cpu_supports("crc32"))
features |= 1 << static_cast<uint8_t>(AArch64CPUFeature::crc32);
if (__builtin_cpu_supports("atomics"))
features |= 1 << static_cast<uint8_t>(AArch64CPUFeature::atomics);
if (__builtin_cpu_supports("sve"))
features |= 1 << static_cast<uint8_t>(AArch64CPUFeature::sve);
#endif
return features;
}
#endif
extern "C" uint8_t bun_cpu_features()
{
#if CPU(X86_64)
return x86_cpu_features();
#elif CPU(ARM64)
return aarch64_cpu_features();
#else
return 0;
#endif
}

View File

@@ -0,0 +1,89 @@
const bun = @import("root").bun;
const std = @import("std");
fn Impl(comptime T: type) type {
return struct {
pub fn format(this: T, comptime _: []const u8, _: anytype, writer: anytype) !void {
var is_first = true;
inline for (comptime std.meta.fieldNames(T)) |fieldName| {
if (comptime bun.strings.eqlComptime(fieldName, "padding") or bun.strings.eqlComptime(fieldName, "none"))
continue;
const value = @field(this, fieldName);
if (value) {
if (!is_first)
try writer.writeAll(" ");
is_first = false;
try writer.writeAll(fieldName);
}
}
}
pub fn isEmpty(this: T) bool {
return @as(u8, @bitCast(this)) == 0;
}
pub fn get() T {
const this: T = @bitCast(bun_cpu_features());
// sanity check
assert(this.none == false and this.padding == 0);
if (bun.Environment.isX64) {
bun.analytics.Features.no_avx += @as(usize, @intFromBool(!this.avx));
bun.analytics.Features.no_avx2 += @as(usize, @intFromBool(!this.avx2));
}
return this;
}
};
}
const X86CPUFeatures = packed struct(u8) {
none: bool = false,
sse42: bool = false,
popcnt: bool = false,
avx: bool = false,
avx2: bool = false,
avx512: bool = false,
padding: u2 = 0,
pub usingnamespace Impl(@This());
};
const AArch64CPUFeatures = packed struct(u8) {
none: bool = false,
neon: bool = false,
fp: bool = false,
aes: bool = false,
crc32: bool = false,
atomics: bool = false,
sve: bool = false,
padding: u1 = 0,
pub usingnamespace Impl(@This());
};
pub const CPUFeatures = if (bun.Environment.isX64)
X86CPUFeatures
else if (bun.Environment.isAarch64)
AArch64CPUFeatures
else
struct {
pub fn get() @This() {
return .{};
}
pub fn format(_: @This(), comptime _: []const u8, _: anytype, _: anytype) !void {}
pub fn isEmpty(_: @This()) bool {
return true;
}
};
extern "C" fn bun_cpu_features() u8;
const assert = bun.debugAssert;

View File

@@ -50,6 +50,8 @@ var panic_mutex = std.Thread.Mutex{};
/// This is used to catch and handle panics triggered by the panic handler.
threadlocal var panic_stage: usize = 0;
const CPUFeatures = @import("./bun.js/bindings/CPUFeatures.zig").CPUFeatures;
/// This structure and formatter must be kept in sync with `bun.report`'s decoder implementation.
pub const CrashReason = union(enum) {
/// From @panic()
@@ -746,6 +748,7 @@ pub fn printMetadata(writer: anytype) !void {
try writer.writeAll(metadata_version_line);
{
const platform = bun.Analytics.GenerateHeader.GeneratePlatform.forOS();
const cpu_features = CPUFeatures.get();
if (bun.Environment.isLinux) {
// TODO: musl
const version = gnu_get_libc_version() orelse "";
@@ -758,6 +761,11 @@ pub fn printMetadata(writer: anytype) !void {
} else if (bun.Environment.isMac) {
try writer.print("macOS v{s}\n", .{platform.version});
}
if (!cpu_features.isEmpty()) {
try writer.print("CPU: {}\n", .{cpu_features});
}
try writer.print("Args: ", .{});
var arg_chars_left: usize = if (bun.Environment.isDebug) 4096 else 196;
for (bun.argv, 0..) |arg, i| {

View File

@@ -1754,7 +1754,6 @@ pub const BundleOptions = struct {
opts.polyfill_node_globals = opts.target == .browser;
Analytics.Features.filesystem_router += @as(usize, @intFromBool(opts.routes.routes_enabled));
Analytics.Features.origin += @as(usize, @intFromBool(opts.origin.href.len > 0));
Analytics.Features.macros += @as(usize, @intFromBool(opts.target == .bun_macro));
Analytics.Features.external += @as(usize, @intFromBool(transform.external.len > 0));
return opts;