Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions src/bun.js/bindings/BunProcess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ typedef int mode_t;
#include <JavaScriptCore/IntegrityInlines.h>
#endif

#include <JavaScriptCore/Options.h>

#pragma mark - Node.js Process

#if defined(__APPLE__)
Expand Down Expand Up @@ -1983,7 +1985,8 @@ static JSValue constructReportObjectComplete(VM& vm, Zig::GlobalObject* globalOb
heapSpaces->putDirect(vm, JSC::Identifier::fromString(vm, "shared_large_object_space"_s), JSC::constructEmptyObject(globalObject), 0);
RETURN_IF_EXCEPTION(scope, {});

heap->putDirect(vm, JSC::Identifier::fromString(vm, "totalMemory"_s), JSC::jsNumber(WTF::ramSize()), 0);
size_t ramSize = JSC::Options::forceRAMSize();
heap->putDirect(vm, JSC::Identifier::fromString(vm, "totalMemory"_s), JSC::jsNumber(ramSize ? ramSize : WTF::ramSize()), 0);
heap->putDirect(vm, JSC::Identifier::fromString(vm, "executableMemory"_s), jsNumber(0), 0);
heap->putDirect(vm, JSC::Identifier::fromString(vm, "totalCommittedMemory"_s), jsNumber(0), 0);
heap->putDirect(vm, JSC::Identifier::fromString(vm, "availableMemory"_s), jsNumber(0), 0);
Expand Down Expand Up @@ -3076,7 +3079,8 @@ static Process* getProcessObject(JSC::JSGlobalObject* lexicalGlobalObject, JSVal

JSC_DEFINE_HOST_FUNCTION(Process_functionConstrainedMemory, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
return JSValue::encode(jsNumber(WTF::ramSize()));
size_t ramSize = JSC::Options::forceRAMSize();
return JSValue::encode(jsNumber(ramSize ? ramSize : WTF::ramSize()));
}

JSC_DEFINE_HOST_FUNCTION(Process_functionResourceUsage, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
Expand Down
7 changes: 5 additions & 2 deletions src/bun.js/bindings/BunProcessReportObjectWindows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "JavaScriptCore/JSGlobalObject.h"
#include "JavaScriptCore/TopExceptionScope.h"
#include "JavaScriptCore/VM.h"
#include "JavaScriptCore/Options.h"
#include "wtf/text/WTFString.h"
#include "wtf/text/StringView.h"
#include "wtf/text/ASCIILiteral.h"
Expand Down Expand Up @@ -302,9 +303,11 @@ JSValue constructReportObjectWindows(VM& vm, Zig::GlobalObject* globalObject, Pr
heapSpaces->putDirect(vm, Identifier::fromString(vm, "shared_large_object_space"_s), constructEmptyObject(globalObject), 0);
heapSpaces->putDirect(vm, Identifier::fromString(vm, "trusted_large_object_space"_s), constructEmptyObject(globalObject), 0);

heap->putDirect(vm, Identifier::fromString(vm, "totalMemory"_s), jsNumber(WTF::ramSize()), 0);
const auto forcedRAMSize = JSC::Options::forceRAMSize();
const auto reportedRAMSize = forcedRAMSize ? forcedRAMSize : WTF::ramSize();
heap->putDirect(vm, Identifier::fromString(vm, "totalMemory"_s), jsNumber(reportedRAMSize), 0);
heap->putDirect(vm, Identifier::fromString(vm, "usedMemory"_s), jsNumber(vm.heap.size()), 0);
heap->putDirect(vm, Identifier::fromString(vm, "memoryLimit"_s), jsNumber(WTF::ramSize()), 0);
heap->putDirect(vm, Identifier::fromString(vm, "memoryLimit"_s), jsNumber(reportedRAMSize), 0);
heap->putDirect(vm, Identifier::fromString(vm, "heapSpaces"_s), heapSpaces, 0);

report->putDirect(vm, Identifier::fromString(vm, "javascriptHeap"_s), heap, 0);
Expand Down
26 changes: 26 additions & 0 deletions test/js/node/process/process.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,32 @@ describe.concurrent(() => {
expect(process.constrainedMemory() >= 0).toBe(true);
});

it("process.constrainedMemory() respects BUN_JSC_forceRAMSize", async () => {
const forcedSize = 500_000_000;

await using proc = Bun.spawn({
cmd: [bunExe(), "-e", "console.log(process.constrainedMemory())"],
env: {
...bunEnv,
BUN_JSC_forceRAMSize: String(forcedSize),
},
stdout: "pipe",
stderr: "pipe",
});

const [stdout, stderr, exitCode] = await Promise.all([
new Response(proc.stdout).text(),
new Response(proc.stderr).text(),
proc.exited,
]);

expect(stderr).toBe("");
expect(exitCode).toBe(0);

const reportedSize = parseInt(stdout.trim(), 10);
expect(reportedSize).toBe(forcedSize);
});
Comment on lines +765 to +789
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Good coverage for BUN_JSC_forceRAMSizeprocess.constrainedMemory().
Uses bunExe/bunEnv and isolates the behavior well.

If this test ever flakes in CI due to incidental stderr output, consider relaxing:

-    expect(stderr).toBe("");
+    expect(stderr).toBeEmpty();

(Or assert it doesn’t contain "error:" rather than being strictly empty.)

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it("process.constrainedMemory() respects BUN_JSC_forceRAMSize", async () => {
const forcedSize = 500_000_000;
await using proc = Bun.spawn({
cmd: [bunExe(), "-e", "console.log(process.constrainedMemory())"],
env: {
...bunEnv,
BUN_JSC_forceRAMSize: String(forcedSize),
},
stdout: "pipe",
stderr: "pipe",
});
const [stdout, stderr, exitCode] = await Promise.all([
new Response(proc.stdout).text(),
new Response(proc.stderr).text(),
proc.exited,
]);
expect(stderr).toBe("");
expect(exitCode).toBe(0);
const reportedSize = parseInt(stdout.trim(), 10);
expect(reportedSize).toBe(forcedSize);
});
it("process.constrainedMemory() respects BUN_JSC_forceRAMSize", async () => {
const forcedSize = 500_000_000;
await using proc = Bun.spawn({
cmd: [bunExe(), "-e", "console.log(process.constrainedMemory())"],
env: {
...bunEnv,
BUN_JSC_forceRAMSize: String(forcedSize),
},
stdout: "pipe",
stderr: "pipe",
});
const [stdout, stderr, exitCode] = await Promise.all([
new Response(proc.stdout).text(),
new Response(proc.stderr).text(),
proc.exited,
]);
expect(stderr).not.toContain("error:");
expect(exitCode).toBe(0);
const reportedSize = parseInt(stdout.trim(), 10);
expect(reportedSize).toBe(forcedSize);
});
🤖 Prompt for AI Agents
In test/js/node/process/process.test.js around lines 763 to 787, the test
currently asserts stderr is exactly empty which can cause flakes if incidental
non-error output appears; change the assertion to be resilient by checking
stderr does not include the substring "error:" (e.g., replace
expect(stderr).toBe("") with expect(stderr).not.toContain("error:") after
trimming) so the test still fails on real errors but tolerates benign stderr
noise.


it("process.report", () => {
// TODO: write better tests
JSON.stringify(process.report.getReport(), null, 2);
Expand Down