aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-11-18 03:47:10 -0800
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-11-18 03:47:10 -0800
commitf3fb71205110448a4fb69ee39d11dc092a97069c (patch)
treed73b9eebb4278af711004d4bc8f6af58347ec019
parentf6779193c0e1c57b6d78979b7aacecda4e29081b (diff)
downloadbun-f3fb71205110448a4fb69ee39d11dc092a97069c.tar.gz
bun-f3fb71205110448a4fb69ee39d11dc092a97069c.tar.zst
bun-f3fb71205110448a4fb69ee39d11dc092a97069c.zip
Fix crash in process.env.FOO = bar that happened sometimes
-rw-r--r--src/__global.zig4
-rw-r--r--src/boringssl.zig8
-rw-r--r--src/bun.js/api/bun.zig4
-rw-r--r--src/bun.js/base.zig2
-rw-r--r--src/bun.js/bindings/bindings.zig26
-rw-r--r--src/bun.js/javascript.zig2
-rw-r--r--src/bun.js/webcore/streams.zig2
-rw-r--r--src/bun_js.zig2
-rw-r--r--src/global.zig13
-rw-r--r--src/memory_allocator.zig1
-rw-r--r--src/mimalloc_arena.zig3
-rw-r--r--src/napi/napi.zig4
12 files changed, 45 insertions, 26 deletions
diff --git a/src/__global.zig b/src/__global.zig
index ceabb12d9..b95de724e 100644
--- a/src/__global.zig
+++ b/src/__global.zig
@@ -69,8 +69,6 @@ pub const AllocatorConfiguration = struct {
long_running: bool = false,
};
-pub const Mimalloc = @import("./allocators/mimalloc.zig");
-
pub inline fn mimalloc_cleanup(force: bool) void {
if (comptime use_mimalloc) {
Mimalloc.mi_collect(force);
@@ -168,3 +166,5 @@ pub export const Bun__userAgent: [*:0]const u8 = Global.user_agent;
comptime {
_ = Bun__userAgent;
}
+
+const Mimalloc = @import("./global.zig").Mimalloc;
diff --git a/src/boringssl.zig b/src/boringssl.zig
index b0a52e358..248c1f152 100644
--- a/src/boringssl.zig
+++ b/src/boringssl.zig
@@ -54,19 +54,19 @@ pub fn initClient() *boring.SSL {
export fn OPENSSL_memory_alloc(size: usize) ?*anyopaque {
const global = @import("./global.zig");
- return global.Global.Mimalloc.mi_malloc(size);
+ return global.Mimalloc.mi_malloc(size);
}
// BoringSSL always expects memory to be zero'd
export fn OPENSSL_memory_free(ptr: *anyopaque) void {
const global = @import("./global.zig");
- @memset(@ptrCast([*]u8, ptr), 0, global.Global.Mimalloc.mi_usable_size(ptr));
- global.Global.Mimalloc.mi_free(ptr);
+ @memset(@ptrCast([*]u8, ptr), 0, global.Mimalloc.mi_usable_size(ptr));
+ global.Mimalloc.mi_free(ptr);
}
export fn OPENSSL_memory_get_size(ptr: ?*const anyopaque) usize {
const global = @import("./global.zig");
- return global.Global.Mimalloc.mi_usable_size(ptr);
+ return global.Mimalloc.mi_usable_size(ptr);
}
test "load" {
diff --git a/src/bun.js/api/bun.zig b/src/bun.js/api/bun.zig
index b6abde2b0..49143ec5c 100644
--- a/src/bun.js/api/bun.zig
+++ b/src/bun.js/api/bun.zig
@@ -3408,7 +3408,9 @@ pub const EnvironmentVariables = struct {
entry.value_ptr.* = value_str.slice();
} else {
- allocator.free(bun.constStrToU8(entry.value_ptr.*));
+ // this can be a statically allocated string
+ if (bun.isHeapMemory(entry.value_ptr.*))
+ allocator.free(bun.constStrToU8(entry.value_ptr.*));
const cloned_value = value.?.value().toSlice(globalThis, allocator).cloneIfNeeded(allocator) catch return false;
entry.value_ptr.* = cloned_value.slice();
}
diff --git a/src/bun.js/base.zig b/src/bun.js/base.zig
index 3d1233589..663861547 100644
--- a/src/bun.js/base.zig
+++ b/src/bun.js/base.zig
@@ -2481,7 +2481,7 @@ pub const ArrayBuffer = extern struct {
}
// If it's not a mimalloc heap buffer, we're not going to call a deallocator
- if (this.len > 0 and !bun.Global.Mimalloc.mi_is_in_heap_region(this.ptr)) {
+ if (this.len > 0 and !bun.Mimalloc.mi_is_in_heap_region(this.ptr)) {
if (this.typed_array_type == .ArrayBuffer) {
return JSC.JSValue.fromRef(JSC.C.JSObjectMakeArrayBufferWithBytesNoCopy(
ctx,
diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig
index 509138cf2..e9e4d5cbf 100644
--- a/src/bun.js/bindings/bindings.zig
+++ b/src/bun.js/bindings/bindings.zig
@@ -541,7 +541,7 @@ pub const ZigString = extern struct {
inline fn assertGlobal(this: *const ZigString) void {
if (comptime bun.Environment.allow_assert) {
- std.debug.assert(bun.Global.Mimalloc.mi_is_in_heap_region(untagged(this.ptr)) or bun.Global.Mimalloc.mi_check_owned(untagged(this.ptr)));
+ std.debug.assert(bun.Mimalloc.mi_is_in_heap_region(untagged(this.ptr)) or bun.Mimalloc.mi_check_owned(untagged(this.ptr)));
}
}
@@ -2889,7 +2889,7 @@ pub const JSValue = enum(JSValueReprInt) {
extern fn JSBuffer__isBuffer(*JSGlobalObject, JSValue) bool;
pub fn isBuffer(value: JSValue, global: *JSGlobalObject) bool {
- if (comptime JSC.is_bindgen) unreachable;
+ JSC.markBinding(@src());
return JSBuffer__isBuffer(global, value);
}
@@ -2938,7 +2938,7 @@ pub const JSValue = enum(JSValueReprInt) {
/// Must come from globally-allocated memory if allocator is not null
pub fn createBuffer(globalObject: *JSGlobalObject, slice: []u8, allocator: ?std.mem.Allocator) JSValue {
- if (comptime JSC.is_bindgen) unreachable;
+ JSC.markBinding(@src());
@setRuntimeSafety(false);
if (allocator) |alloc| {
return JSBuffer__bufferFromPointerAndLengthAndDeinit(globalObject, slice.ptr, slice.len, alloc.ptr, JSC.MarkedArrayBuffer_deallocator);
@@ -2948,12 +2948,12 @@ pub const JSValue = enum(JSValueReprInt) {
}
pub fn createUninitializedUint8Array(globalObject: *JSGlobalObject, len: usize) JSValue {
- if (comptime JSC.is_bindgen) unreachable;
+ JSC.markBinding(@src());
return shim.cppFn("createUninitializedUint8Array", .{ globalObject, len });
}
pub fn createBufferWithCtx(globalObject: *JSGlobalObject, slice: []u8, ptr: ?*anyopaque, func: JSC.C.JSTypedArrayBytesDeallocator) JSValue {
- if (comptime JSC.is_bindgen) unreachable;
+ JSC.markBinding(@src());
@setRuntimeSafety(false);
return JSBuffer__bufferFromPointerAndLengthAndDeinit(globalObject, slice.ptr, slice.len, ptr, func);
}
@@ -4252,7 +4252,7 @@ const private = struct {
};
pub fn NewFunctionPtr(globalObject: *JSGlobalObject, symbolName: ?*const ZigString, argCount: u32, functionPointer: anytype, strong: bool) *anyopaque {
- if (comptime JSC.is_bindgen) unreachable;
+ JSC.markBinding(@src());
return private.Bun__CreateFFIFunction(globalObject, symbolName, argCount, @ptrCast(*const anyopaque, functionPointer), strong);
}
@@ -4263,17 +4263,17 @@ pub fn NewFunction(
functionPointer: anytype,
strong: bool,
) JSValue {
- if (comptime JSC.is_bindgen) unreachable;
+ JSC.markBinding(@src());
return private.Bun__CreateFFIFunctionValue(globalObject, symbolName, argCount, @ptrCast(*const anyopaque, functionPointer), strong);
}
pub fn getFunctionData(function: JSValue) ?*anyopaque {
- if (comptime JSC.is_bindgen) unreachable;
+ JSC.markBinding(@src());
return private.Bun__FFIFunction_getDataPtr(function);
}
pub fn setFunctionData(function: JSValue, value: ?*anyopaque) void {
- if (comptime JSC.is_bindgen) unreachable;
+ JSC.markBinding(@src());
return private.Bun__FFIFunction_setDataPtr(function, value);
}
@@ -4285,7 +4285,7 @@ pub fn NewFunctionWithData(
strong: bool,
data: *anyopaque,
) JSValue {
- if (comptime JSC.is_bindgen) unreachable;
+ JSC.markBinding(@src());
return private.Bun__CreateFFIFunctionWithDataValue(
globalObject,
symbolName,
@@ -4300,7 +4300,7 @@ pub fn untrackFunction(
globalObject: *JSGlobalObject,
value: JSValue,
) bool {
- if (comptime JSC.is_bindgen) unreachable;
+ JSC.markBinding(@src());
return private.Bun__untrackFFIFunction(globalObject, value);
}
@@ -4394,7 +4394,7 @@ pub const WTF = struct {
/// This uses SSE2 instructions and/or ARM NEON to copy 16-bit characters efficiently
/// See wtf/Text/ASCIIFastPath.h for details
pub fn copyLCharsFromUCharSource(destination: [*]u8, comptime Source: type, source: Source) void {
- if (comptime JSC.is_bindgen) unreachable;
+ JSC.markBinding(@src());
// This is any alignment
WTF__copyLCharsFromUCharSource(destination, source.ptr, source.len);
@@ -4403,7 +4403,7 @@ pub const WTF = struct {
/// Encode a byte array to a URL-safe base64 string for use with JS
/// Memory is managed by JavaScriptCore instead of us
pub fn toBase64URLStringValue(bytes: []const u8, globalObject: *JSGlobalObject) JSValue {
- if (comptime JSC.is_bindgen) unreachable;
+ JSC.markBinding(@src());
return WTF__toBase64URLStringValue(bytes.ptr, bytes.len, globalObject);
}
diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig
index 260aca28e..fe559fac8 100644
--- a/src/bun.js/javascript.zig
+++ b/src/bun.js/javascript.zig
@@ -1950,7 +1950,7 @@ pub const EventListenerMixin = struct {
ctx: *CtxType,
comptime onError: fn (ctx: *CtxType, err: anyerror, value: JSValue, request_ctx: *http.RequestContext) anyerror!void,
) !void {
- if (comptime JSC.is_bindgen) unreachable;
+ JSC.markBinding(@src());
var listeners = vm.event_listeners.get(EventType.fetch) orelse (return onError(ctx, error.NoListeners, JSValue.jsUndefined(), request_context) catch {});
if (listeners.items.len == 0) return onError(ctx, error.NoListeners, JSValue.jsUndefined(), request_context) catch {};
diff --git a/src/bun.js/webcore/streams.zig b/src/bun.js/webcore/streams.zig
index cac5fbafd..7a20b8562 100644
--- a/src/bun.js/webcore/streams.zig
+++ b/src/bun.js/webcore/streams.zig
@@ -2820,7 +2820,7 @@ pub fn ReadableStreamSource(
}
pub fn load(globalThis: *JSGlobalObject) callconv(.C) JSC.JSValue {
- if (comptime JSC.is_bindgen) unreachable;
+ JSC.markBinding(@src());
// This is used also in Node.js streams
return JSC.JSArray.from(globalThis, &.{
JSC.NewFunction(globalThis, null, 2, JSReadableStreamSource.pull, true),
diff --git a/src/bun_js.zig b/src/bun_js.zig
index d406033a1..2510183aa 100644
--- a/src/bun_js.zig
+++ b/src/bun_js.zig
@@ -43,7 +43,7 @@ pub const Run = struct {
arena: Arena = undefined,
pub fn boot(ctx: Command.Context, file: std.fs.File, entry_path: string) !void {
- if (comptime JSC.is_bindgen) unreachable;
+ JSC.markBinding(@src());
@import("bun.js/javascript_core_c_api.zig").JSCInitialize();
js_ast.Expr.Data.Store.create(default_allocator);
diff --git a/src/global.zig b/src/global.zig
index 6135e807d..c5d6af7a8 100644
--- a/src/global.zig
+++ b/src/global.zig
@@ -396,3 +396,16 @@ pub fn once(comptime function: anytype, comptime ReturnType: type) ReturnType {
return Result.execute();
}
+
+pub fn isHeapMemory(memory: anytype) bool {
+ if (comptime use_mimalloc) {
+ const Memory = @TypeOf(memory);
+ if (comptime std.meta.trait.isSingleItemPtr(Memory)) {
+ return Mimalloc.mi_is_in_heap_region(memory);
+ }
+ return Mimalloc.mi_is_in_heap_region(std.mem.sliceAsBytes(memory).ptr);
+ }
+ return false;
+}
+
+pub const Mimalloc = @import("./allocators/mimalloc.zig");
diff --git a/src/memory_allocator.zig b/src/memory_allocator.zig
index a8fbd116a..cb73bfb89 100644
--- a/src/memory_allocator.zig
+++ b/src/memory_allocator.zig
@@ -109,6 +109,7 @@ const CAllocator = struct {
// so it's faster if we don't pass that value through
// but its good to have that assertion
if (comptime Environment.allow_assert) {
+ assert(mimalloc.mi_is_in_heap_region(buf.ptr));
mimalloc.mi_free_size(buf.ptr, buf.len);
} else {
mimalloc.mi_free(buf.ptr);
diff --git a/src/mimalloc_arena.zig b/src/mimalloc_arena.zig
index 0f54cdea6..a313c7dfe 100644
--- a/src/mimalloc_arena.zig
+++ b/src/mimalloc_arena.zig
@@ -129,6 +129,9 @@ pub const Arena = struct {
) void {
_ = buf_align;
_ = return_address;
+ if (comptime Environment.allow_assert)
+ assert(mimalloc.mi_is_in_heap_region(buf.ptr));
+
mimalloc.mi_free(buf.ptr);
}
};
diff --git a/src/napi/napi.zig b/src/napi/napi.zig
index 3beaa03d7..c30f1d565 100644
--- a/src/napi/napi.zig
+++ b/src/napi/napi.zig
@@ -613,7 +613,7 @@ pub export fn napi_strict_equals(env: napi_env, lhs: napi_value, rhs: napi_value
return .ok;
}
pub export fn napi_call_function(env: napi_env, recv: napi_value, func: napi_value, argc: usize, argv: [*c]const napi_value, result: *napi_value) napi_status {
- if (comptime JSC.is_bindgen) unreachable;
+ JSC.markBinding(@src());
var exception = [_]JSC.C.JSValueRef{null};
result.* =
JSC.C.JSObjectCallAsFunctionReturnValue(
@@ -1416,7 +1416,7 @@ pub const SRC_NODE_API_TYPES_H_ = "";
pub const NAPI_MODULE_VERSION = @as(c_int, 1);
pub fn fixDeadCodeElimination() void {
- if (comptime JSC.is_bindgen) unreachable;
+ JSC.markBinding(@src());
std.mem.doNotOptimizeAway(&napi_get_undefined);
std.mem.doNotOptimizeAway(&napi_get_null);
std.mem.doNotOptimizeAway(&napi_get_boolean);