mirror of
https://github.com/oven-sh/bun
synced 2026-02-11 03:18:53 +00:00
Re-enable heap breakdown
This commit is contained in:
@@ -34,6 +34,7 @@ const BunBuildOptions = struct {
|
||||
enable_asan: bool,
|
||||
enable_fuzzilli: bool,
|
||||
enable_valgrind: bool,
|
||||
enable_heap_breakdown: bool,
|
||||
use_mimalloc: bool,
|
||||
tracy_callstack_depth: u16,
|
||||
reported_nodejs_version: Version,
|
||||
@@ -84,6 +85,7 @@ const BunBuildOptions = struct {
|
||||
opts.addOption(bool, "enable_asan", this.enable_asan);
|
||||
opts.addOption(bool, "enable_fuzzilli", this.enable_fuzzilli);
|
||||
opts.addOption(bool, "enable_valgrind", this.enable_valgrind);
|
||||
opts.addOption(bool, "enable_heap_breakdown", this.enable_heap_breakdown);
|
||||
opts.addOption(bool, "use_mimalloc", this.use_mimalloc);
|
||||
opts.addOption([]const u8, "reported_nodejs_version", b.fmt("{f}", .{this.reported_nodejs_version}));
|
||||
opts.addOption(bool, "zig_self_hosted_backend", this.no_llvm);
|
||||
@@ -259,6 +261,7 @@ pub fn build(b: *Build) !void {
|
||||
.enable_asan = b.option(bool, "enable_asan", "Enable asan") orelse false,
|
||||
.enable_fuzzilli = b.option(bool, "enable_fuzzilli", "Enable fuzzilli instrumentation") orelse false,
|
||||
.enable_valgrind = b.option(bool, "enable_valgrind", "Enable valgrind") orelse false,
|
||||
.enable_heap_breakdown = b.option(bool, "enable_heap_breakdown", "Enable malloc heap breakdown (macOS only)") orelse false,
|
||||
.use_mimalloc = b.option(bool, "use_mimalloc", "Use mimalloc as default allocator") orelse false,
|
||||
.llvm_codegen_threads = b.option(u32, "llvm_codegen_threads", "Number of threads to use for LLVM codegen") orelse 1,
|
||||
};
|
||||
@@ -494,6 +497,7 @@ fn addMultiCheck(
|
||||
.enable_asan = root_build_options.enable_asan,
|
||||
.enable_valgrind = root_build_options.enable_valgrind,
|
||||
.enable_fuzzilli = root_build_options.enable_fuzzilli,
|
||||
.enable_heap_breakdown = root_build_options.enable_heap_breakdown,
|
||||
.use_mimalloc = root_build_options.use_mimalloc,
|
||||
.override_no_export_cpp_apis = root_build_options.override_no_export_cpp_apis,
|
||||
};
|
||||
@@ -609,7 +613,6 @@ fn configureObj(b: *Build, opts: *BunBuildOptions, obj: *Compile) void {
|
||||
|
||||
obj.no_link_obj = opts.os != .windows and !opts.no_llvm;
|
||||
|
||||
|
||||
if (opts.enable_asan and !enableFastBuild(b)) {
|
||||
if (@hasField(Build.Module, "sanitize_address")) {
|
||||
if (opts.enable_fuzzilli) {
|
||||
|
||||
@@ -129,6 +129,13 @@ endif()
|
||||
|
||||
optionx(ENABLE_FUZZILLI BOOL "If fuzzilli support should be enabled" DEFAULT OFF)
|
||||
|
||||
optionx(ENABLE_HEAP_BREAKDOWN BOOL "If malloc heap breakdown support should be enabled (macOS only)" DEFAULT OFF)
|
||||
|
||||
if(ENABLE_HEAP_BREAKDOWN AND NOT APPLE)
|
||||
message(WARNING "ENABLE_HEAP_BREAKDOWN is only supported on macOS, disabling")
|
||||
setx(ENABLE_HEAP_BREAKDOWN OFF)
|
||||
endif()
|
||||
|
||||
if(RELEASE AND LINUX AND CI AND NOT ENABLE_ASSERTIONS AND NOT ENABLE_ASAN)
|
||||
set(DEFAULT_LTO ON)
|
||||
else()
|
||||
|
||||
@@ -697,6 +697,7 @@ register_command(
|
||||
-Denable_asan=$<IF:$<BOOL:${ENABLE_ZIG_ASAN}>,true,false>
|
||||
-Denable_fuzzilli=$<IF:$<BOOL:${ENABLE_FUZZILLI}>,true,false>
|
||||
-Denable_valgrind=$<IF:$<BOOL:${ENABLE_VALGRIND}>,true,false>
|
||||
-Denable_heap_breakdown=$<IF:$<BOOL:${ENABLE_HEAP_BREAKDOWN}>,true,false>
|
||||
-Duse_mimalloc=$<IF:$<BOOL:${USE_MIMALLOC_AS_DEFAULT_ALLOCATOR}>,true,false>
|
||||
-Dllvm_codegen_threads=${LLVM_ZIG_CODEGEN_THREADS}
|
||||
-Dversion=${VERSION}
|
||||
|
||||
@@ -29,11 +29,11 @@ if(WEBKIT_LOCAL)
|
||||
include_directories(
|
||||
${WEBKIT_PATH}
|
||||
${WEBKIT_PATH}/JavaScriptCore/Headers/JavaScriptCore
|
||||
${WEBKIT_PATH}/JavaScriptCore/DerivedSources/inspector
|
||||
${WEBKIT_PATH}/JavaScriptCore/PrivateHeaders
|
||||
${WEBKIT_PATH}/JavaScriptCore/PrivateHeaders/JavaScriptCore
|
||||
${WEBKIT_PATH}/bmalloc/Headers
|
||||
${WEBKIT_PATH}/WTF/Headers
|
||||
${WEBKIT_PATH}/JavaScriptCore/DerivedSources/inspector
|
||||
${WEBKIT_PATH}/JavaScriptCore/PrivateHeaders/JavaScriptCore
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
"build:smol": "bun ./scripts/build.mjs -GNinja -DCMAKE_BUILD_TYPE=MinSizeRel -B build/release-smol",
|
||||
"build:local": "bun ./scripts/build.mjs -GNinja -DCMAKE_BUILD_TYPE=Debug -DWEBKIT_LOCAL=ON -B build/debug-local",
|
||||
"build:release:local": "bun ./scripts/build.mjs -GNinja -DCMAKE_BUILD_TYPE=Release -DWEBKIT_LOCAL=ON -B build/release-local",
|
||||
"build:release:local:heap-breakdown": "NO_SCCACHE=1 bun ./scripts/build.mjs -GNinja -DCMAKE_BUILD_TYPE=Release -DWEBKIT_LOCAL=ON -DWEBKIT_PATH=$PWD/../WebKit/WebKitBuild/ReleaseHeapBreakdown -DENABLE_HEAP_BREAKDOWN=ON -DENABLE_ASAN=OFF -B build/release-heap-breakdown",
|
||||
"build:release:with_logs": "cmake . -DCMAKE_BUILD_TYPE=Release -DENABLE_LOGS=true -GNinja -Bbuild-release && ninja -Cbuild-release",
|
||||
"build:debug-zig-release": "cmake . -DCMAKE_BUILD_TYPE=Release -DZIG_OPTIMIZE=Debug -GNinja -Bbuild-debug-zig-release && ninja -Cbuild-debug-zig-release",
|
||||
"run:linux": "docker run --rm -v \"$PWD:/root/bun/\" -w /root/bun ghcr.io/oven-sh/bun-development-docker-image",
|
||||
@@ -54,6 +55,7 @@
|
||||
"jsc:build": "bun ./scripts/build-jsc.ts release",
|
||||
"jsc:build:debug": "bun ./scripts/build-jsc.ts debug",
|
||||
"jsc:build:lto": "bun ./scripts/build-jsc.ts lto",
|
||||
"jsc:build:heap-breakdown": "bun ./scripts/build-jsc.ts heap-breakdown",
|
||||
"typecheck": "tsc --noEmit && cd test && bun run typecheck",
|
||||
"fmt": "bun run prettier",
|
||||
"fmt:cpp": "bun run clang-format",
|
||||
|
||||
@@ -5,12 +5,12 @@ import { arch, platform } from "os";
|
||||
import { join, resolve } from "path";
|
||||
|
||||
// Build configurations
|
||||
type BuildConfig = "debug" | "release" | "lto";
|
||||
type BuildConfig = "debug" | "release" | "lto" | "heap-breakdown";
|
||||
|
||||
// Parse command line arguments
|
||||
const args = process.argv.slice(2);
|
||||
const buildConfig: BuildConfig = (args[0] as BuildConfig) || "debug";
|
||||
const validConfigs = ["debug", "release", "lto"];
|
||||
const validConfigs = ["debug", "release", "lto", "heap-breakdown"];
|
||||
|
||||
if (!validConfigs.includes(buildConfig)) {
|
||||
console.error(`Invalid build configuration: ${buildConfig}`);
|
||||
@@ -32,6 +32,7 @@ const WEBKIT_BUILD_DIR = join(WEBKIT_DIR, "WebKitBuild");
|
||||
const WEBKIT_RELEASE_DIR = join(WEBKIT_BUILD_DIR, "Release");
|
||||
const WEBKIT_DEBUG_DIR = join(WEBKIT_BUILD_DIR, "Debug");
|
||||
const WEBKIT_RELEASE_DIR_LTO = join(WEBKIT_BUILD_DIR, "ReleaseLTO");
|
||||
const WEBKIT_HEAP_BREAKDOWN_DIR = join(WEBKIT_BUILD_DIR, "ReleaseHeapBreakdown");
|
||||
|
||||
// Homebrew prefix detection
|
||||
const HOMEBREW_PREFIX = IS_ARM64 ? "/opt/homebrew/" : "/usr/local/";
|
||||
@@ -57,6 +58,8 @@ const getBuildDir = (config: BuildConfig) => {
|
||||
return WEBKIT_DEBUG_DIR;
|
||||
case "lto":
|
||||
return WEBKIT_RELEASE_DIR_LTO;
|
||||
case "heap-breakdown":
|
||||
return WEBKIT_HEAP_BREAKDOWN_DIR;
|
||||
default:
|
||||
return WEBKIT_RELEASE_DIR;
|
||||
}
|
||||
@@ -122,6 +125,10 @@ const getBuildFlags = (config: BuildConfig) => {
|
||||
flags.push("-DCMAKE_BUILD_TYPE=Release", "-DCMAKE_C_FLAGS=-flto=full", "-DCMAKE_CXX_FLAGS=-flto=full");
|
||||
break;
|
||||
|
||||
case "heap-breakdown":
|
||||
flags.push("-DCMAKE_BUILD_TYPE=RelWithDebInfo", "-DENABLE_MALLOC_HEAP_BREAKDOWN=ON");
|
||||
break;
|
||||
|
||||
default: // release
|
||||
flags.push("-DCMAKE_BUILD_TYPE=RelWithDebInfo");
|
||||
break;
|
||||
@@ -172,7 +179,7 @@ function runCommand(command: string, args: string[], options: any = {}) {
|
||||
}
|
||||
|
||||
// Main build function
|
||||
function buildJSC() {
|
||||
async function buildJSC() {
|
||||
const buildDir = getBuildDir(buildConfig);
|
||||
const cmakeFlags = getBuildFlags(buildConfig);
|
||||
const env = getBuildEnv();
|
||||
@@ -198,18 +205,27 @@ function buildJSC() {
|
||||
|
||||
// Build with CMake
|
||||
console.log("\n🔨 Building JSC...");
|
||||
const buildType = buildConfig === "debug" ? "Debug" : buildConfig === "lto" ? "Release" : "RelWithDebInfo";
|
||||
const buildType = buildConfig === "debug" ? "Debug" : buildConfig === "lto" ? "Release" : "RelWithDebInfo"; // heap-breakdown uses RelWithDebInfo
|
||||
|
||||
runCommand("cmake", ["--build", buildDir, "--config", buildType, "--target", "jsc"], {
|
||||
cwd: buildDir,
|
||||
env,
|
||||
});
|
||||
|
||||
// Remove duplicate InspectorProtocolObjects.h to prevent redefinition errors when building Bun
|
||||
// The file exists in both DerivedSources/inspector and PrivateHeaders/JavaScriptCore,
|
||||
// and #pragma once doesn't prevent double-inclusion from different paths
|
||||
const duplicateHeader = join(buildDir, "JavaScriptCore/DerivedSources/inspector/InspectorProtocolObjects.h");
|
||||
if (await Bun.file(duplicateHeader).exists()) {
|
||||
console.log("\n🧹 Removing duplicate InspectorProtocolObjects.h...");
|
||||
await Bun.$`rm ${duplicateHeader}`;
|
||||
}
|
||||
|
||||
console.log(`\n✅ JSC build completed successfully!`);
|
||||
console.log(`Build output: ${buildDir}`);
|
||||
}
|
||||
|
||||
// Entry point
|
||||
if (import.meta.main) {
|
||||
buildJSC();
|
||||
await buildJSC();
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
#include <JavaScriptCore/ControlFlowProfiler.h>
|
||||
|
||||
#if OS(DARWIN)
|
||||
#if ASSERT_ENABLED
|
||||
#if (ASSERT_ENABLED || ENABLE(MALLOC_HEAP_BREAKDOWN))
|
||||
#if !__has_feature(address_sanitizer)
|
||||
#include <malloc/malloc.h>
|
||||
#define IS_MALLOC_DEBUGGING_ENABLED 1
|
||||
@@ -310,13 +310,16 @@ JSC_DEFINE_HOST_FUNCTION(functionMemoryUsageStatistics,
|
||||
Vector<std::pair<Identifier, size_t>> zoneSizes;
|
||||
zoneSizes.reserveInitialCapacity(count);
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
auto zone = reinterpret_cast<malloc_zone_t*>(zones[i]);
|
||||
if (const char* name = malloc_get_zone_name(zone)) {
|
||||
malloc_zone_statistics(reinterpret_cast<malloc_zone_t*>(zones[i]),
|
||||
&zone_stats);
|
||||
zoneSizes.append(
|
||||
std::make_pair(Identifier::fromString(vm, String::fromUTF8(name)),
|
||||
zone_stats.size_in_use));
|
||||
auto* zone = reinterpret_cast<malloc_zone_t*>(zones[i]);
|
||||
if (zone) {
|
||||
if (const char* name = malloc_get_zone_name(zone)) {
|
||||
auto nameString = String::fromUTF8(name);
|
||||
malloc_zone_statistics(reinterpret_cast<malloc_zone_t*>(zones[i]),
|
||||
&zone_stats);
|
||||
zoneSizes.append(
|
||||
std::make_pair(Identifier::fromString(vm, nameString),
|
||||
zone_stats.size_in_use));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ pub const dump_source = isDebug and !isTest;
|
||||
pub const base_path = build_options.base_path;
|
||||
pub const enable_logs = build_options.enable_logs;
|
||||
pub const enable_asan = build_options.enable_asan;
|
||||
pub const enable_heap_breakdown = build_options.enable_heap_breakdown;
|
||||
pub const enable_fuzzilli = build_options.enable_fuzzilli;
|
||||
pub const codegen_path = build_options.codegen_path;
|
||||
pub const codegen_embed = build_options.codegen_embed;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const vm_size_t = usize;
|
||||
|
||||
pub const enabled = Environment.allow_assert and Environment.isMac and !Environment.enable_asan;
|
||||
pub const enabled = Environment.enable_heap_breakdown and Environment.isMac;
|
||||
|
||||
fn heapLabel(comptime T: type) [:0]const u8 {
|
||||
const base_name = if (comptime bun.meta.hasDecl(T, "heap_label"))
|
||||
|
||||
Reference in New Issue
Block a user