Compare commits

...

5 Commits

Author SHA1 Message Date
Jarred Sumner
5c476d60c0 Merge branch 'main' into jarred/experiment-fragmentation 2024-12-26 10:25:54 -08:00
Jarred Sumner
f5e874e1b5 Update BuildMimalloc.cmake 2024-12-24 03:58:29 -08:00
Jarred Sumner
4eefe8eb29 Bump mimalloc 2024-12-24 03:48:14 -08:00
Jarred Sumner
6c73395d04 Merge branch 'main' into jarred/experiment-fragmentation 2024-12-24 02:27:17 -08:00
Jarred Sumner
1ce2a10f2d experiment: tweak GC timings 2024-12-24 00:55:43 -08:00
5 changed files with 48 additions and 12 deletions

View File

@@ -0,0 +1,17 @@
import { readFile } from "node:fs/promises";
import { writeFileSync } from "node:fs";
(function () {
writeFileSync("/tmp/bun-bench-large.text", Buffer.alloc(1024 * 1024 * 8, "abcdefg!"));
})();
if (globalThis.Bun) {
Bun.gc(true);
}
console.log("Before:", "RSS", (process.memoryUsage.rss() / 1024 / 1024) | 0, "MB");
for (let i = 0; i < 1024; i++) {
await readFile("/tmp/bun-bench-large.text");
}
console.log("After:", "RSS", (process.memoryUsage.rss() / 1024 / 1024) | 0, "MB");

View File

@@ -4,7 +4,7 @@ register_repository(
REPOSITORY
oven-sh/mimalloc
COMMIT
82b2c2277a4d570187c07b376557dc5bde81d848
7085b6cec31641fddaca3d40932cda82e91baf07
)
set(MIMALLOC_CMAKE_ARGS

View File

@@ -218,6 +218,18 @@ extern "C" unsigned getJSCBytecodeCacheVersion()
return getWebKitBytecodeCacheVersion();
}
extern "C" void Bun__onEachMicrotaskTick(void* bun_vm, JSC::VM* vm);
static void defaultOnEachMicrotaskTick(JSC::VM& vm)
{
Bun__onEachMicrotaskTick(clientData(vm)->bunVM, &vm);
}
static void defaultOnEachMicrotaskTickWithVM(void* bun_vm, JSC::VM& vm)
{
Bun__onEachMicrotaskTick(bun_vm, &vm);
}
extern "C" void JSCInitialize(const char* envp[], size_t envc, void (*onCrash)(const char* ptr, size_t length), bool evalMode)
{
static bool has_loaded_jsc = false;
@@ -799,6 +811,8 @@ static void checkIfNextTickWasCalledDuringMicrotask(JSC::VM& vm)
globalObject->resetOnEachMicrotaskTick();
queue->drain(vm, globalObject);
}
Bun__onEachMicrotaskTick(globalObject->m_bunVM, &vm);
}
static void cleanupAsyncHooksData(JSC::VM& vm)
@@ -810,7 +824,8 @@ static void cleanupAsyncHooksData(JSC::VM& vm)
vm.setOnEachMicrotaskTick(&checkIfNextTickWasCalledDuringMicrotask);
checkIfNextTickWasCalledDuringMicrotask(vm);
} else {
vm.setOnEachMicrotaskTick(nullptr);
vm.setOnEachMicrotaskTick(&defaultOnEachMicrotaskTick);
Bun__onEachMicrotaskTick(globalObject->m_bunVM, &vm);
}
}
@@ -856,7 +871,7 @@ void Zig::GlobalObject::resetOnEachMicrotaskTick()
vm.setOnEachMicrotaskTick(&cleanupAsyncHooksData);
} else {
if (this->m_nextTickQueue) {
vm.setOnEachMicrotaskTick(nullptr);
vm.setOnEachMicrotaskTick(&defaultOnEachMicrotaskTick);
} else {
vm.setOnEachMicrotaskTick(&checkIfNextTickWasCalledDuringMicrotask);
}
@@ -923,8 +938,10 @@ extern "C" JSC__JSGlobalObject* Zig__GlobalObject__create(void* console_client,
globalObject->resetOnEachMicrotaskTick();
Bun::JSNextTickQueue* queue = jsCast<Bun::JSNextTickQueue*>(nextTickQueue);
queue->drain(vm, globalObject);
Bun__onEachMicrotaskTick(globalObject->m_bunVM, &vm);
return;
}
Bun__onEachMicrotaskTick(globalObject->m_bunVM, &vm);
});
if (executionContextId > -1) {

View File

@@ -5747,7 +5747,7 @@ extern "C" JSC__JSValue JSC__JSValue__createRopeString(JSC__JSValue JSValue0, JS
extern "C" size_t JSC__VM__blockBytesAllocated(JSC__VM* vm)
{
#if ENABLE(RESOURCE_USAGE)
return vm->heap.blockBytesAllocated() + vm->heap.extraMemorySize();
return vm->heap.blockBytesAllocated() + vm->heap.extraMemorySize() + vm->heap.externalMemorySize();
#else
return 0;
#endif

View File

@@ -543,6 +543,9 @@ pub const GarbageCollectionController = struct {
gc_repeating_timer_fast: bool = true,
disabled: bool = false,
pub export fn Bun__onEachMicrotaskTick(vm: *VirtualMachine, jsc_vm: *JSC.VM) void {
vm.gc_controller.processGCTimerWithHeapSize(jsc_vm, jsc_vm.blockBytesAllocated());
}
pub fn init(this: *GarbageCollectionController, vm: *VirtualMachine) void {
const actual = uws.Loop.get();
this.gc_timer = uws.Timer.createFallthrough(actual, this);
@@ -612,7 +615,7 @@ pub const GarbageCollectionController = struct {
pub fn onGCRepeatingTimer(timer: *uws.Timer) callconv(.C) void {
var this = timer.as(*GarbageCollectionController);
const prev_heap_size = this.gc_last_heap_size_on_repeating_timer;
this.performGC();
this.performGC(this.bunVM().jsc);
this.gc_last_heap_size_on_repeating_timer = this.gc_last_heap_size;
if (prev_heap_size == this.gc_last_heap_size_on_repeating_timer) {
this.heap_size_didnt_change_for_repeating_timer_ticks_count +|= 1;
@@ -652,7 +655,7 @@ pub const GarbageCollectionController = struct {
this.updateGCRepeatTimer(.fast);
if (this_heap_size > prev * 2) {
this.performGC();
this.performGC(vm);
} else {
this.scheduleGCTimer();
}
@@ -661,17 +664,16 @@ pub const GarbageCollectionController = struct {
.scheduled => {
if (this_heap_size > prev * 2) {
this.updateGCRepeatTimer(.fast);
this.performGC();
this.performGC(vm);
}
},
}
}
pub fn performGC(this: *GarbageCollectionController) void {
pub fn performGC(this: *GarbageCollectionController, js_vm: *JSC.VM) void {
if (this.disabled) return;
var vm = this.bunVM().jsc;
vm.collectAsync();
this.gc_last_heap_size = vm.blockBytesAllocated();
js_vm.collectAsync();
this.gc_last_heap_size = js_vm.blockBytesAllocated();
}
pub const GCTimerState = enum {
@@ -1618,7 +1620,7 @@ pub const EventLoop = struct {
/// Asynchronously run the garbage collector and track how much memory is now allocated
pub fn performGC(this: *EventLoop) void {
this.virtual_machine.gc_controller.performGC();
this.virtual_machine.gc_controller.performGC(this.virtual_machine.jsc);
}
pub fn wakeup(this: *EventLoop) void {