From 06a7499853f0a0ef28d981fdf9b6b4331d1f0ef7 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Mon, 27 Jan 2025 02:48:37 -0800 Subject: [PATCH] Add a couple more assertions (#16791) --- src/analytics/analytics_thread.zig | 2 ++ src/s3/credentials.zig | 1 + src/sql/postgres.zig | 4 +++- src/string.zig | 30 +++++++++++++++++++++--------- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/analytics/analytics_thread.zig b/src/analytics/analytics_thread.zig index d8c77de1ed..50c9f2a810 100644 --- a/src/analytics/analytics_thread.zig +++ b/src/analytics/analytics_thread.zig @@ -122,6 +122,8 @@ pub const Features = struct { pub var workers_terminated: usize = 0; pub var napi_module_register: usize = 0; pub var process_dlopen: usize = 0; + pub var postgres_connections: usize = 0; + pub var s3: usize = 0; comptime { @export(napi_module_register, .{ .name = "Bun__napi_module_register_count" }); diff --git a/src/s3/credentials.zig b/src/s3/credentials.zig index fdf2a45c3d..2c10db4d8a 100644 --- a/src/s3/credentials.zig +++ b/src/s3/credentials.zig @@ -45,6 +45,7 @@ pub const S3Credentials = struct { return hasher.final(); } pub fn getCredentialsWithOptions(this: S3Credentials, default_options: MultiPartUploadOptions, options: ?JSC.JSValue, default_acl: ?ACL, default_storage_class: ?StorageClass, globalObject: *JSC.JSGlobalObject) bun.JSError!S3CredentialsWithOptions { + bun.analytics.Features.s3 += 1; // get ENV config var new_credentials = S3CredentialsWithOptions{ .credentials = this, diff --git a/src/sql/postgres.zig b/src/sql/postgres.zig index 874575f8ae..eaf6f6fb15 100644 --- a/src/sql/postgres.zig +++ b/src/sql/postgres.zig @@ -579,6 +579,7 @@ pub const PostgresSQLQuery = struct { const connection: *PostgresSQLConnection = arguments[0].as(PostgresSQLConnection) orelse { return globalObject.throw("connection must be a PostgresSQLConnection", .{}); }; + connection.poll_ref.ref(globalObject.bunVM()); var query = arguments[1]; @@ -1779,7 +1780,7 @@ pub const PostgresSQLConnection = struct { .password = password, .options = options, .options_buf = options_buf, - .socket = undefined, + .socket = .{ .SocketTCP = .{ .socket = .{ .detached = {} } } }, .requests = PostgresRequest.Queue.init(bun.default_allocator), .statements = PreparedStatementsMap{}, .tls_config = tls_config, @@ -1799,6 +1800,7 @@ pub const PostgresSQLConnection = struct { PostgresSQLConnection.onconnectSetCached(js_value, globalObject, on_connect); PostgresSQLConnection.oncloseSetCached(js_value, globalObject, on_close); + bun.analytics.Features.postgres_connections += 1; { const hostname = hostname_str.toUTF8(bun.default_allocator); diff --git a/src/string.zig b/src/string.zig index 5b0c534a16..f0dda92cbb 100644 --- a/src/string.zig +++ b/src/string.zig @@ -384,6 +384,7 @@ pub const String = extern struct { fn createUninitializedLatin1(len: usize) struct { String, []u8 } { bun.assert(len > 0); const string = BunString__fromLatin1Unitialized(len); + _ = validateRefCount(string); const wtf = string.value.WTFStringImpl; return .{ string, @@ -394,6 +395,7 @@ pub const String = extern struct { fn createUninitializedUTF16(len: usize) struct { String, []u16 } { bun.assert(len > 0); const string = BunString__fromUTF16Unitialized(len); + _ = validateRefCount(string); const wtf = string.value.WTFStringImpl; return .{ string, @@ -434,21 +436,31 @@ pub const String = extern struct { pub fn createLatin1(bytes: []const u8) String { JSC.markBinding(@src()); if (bytes.len == 0) return String.empty; - return BunString__fromLatin1(bytes.ptr, bytes.len); + return validateRefCount(BunString__fromLatin1(bytes.ptr, bytes.len)); + } + + pub inline fn validateRefCount(this: String) String { + if (comptime bun.Environment.isDebug) { + // Newly created strings should have a ref count of 1 + if (!this.isEmpty()) { + const ref_count = this.value.WTFStringImpl.refCount(); + bun.assert(ref_count == 1); + } + } + + return this; } pub fn createUTF8(bytes: []const u8) String { - JSC.markBinding(@src()); - if (bytes.len == 0) return String.empty; - return BunString__fromBytes(bytes.ptr, bytes.len); + return JSC.WebCore.Encoder.toBunStringComptime(bytes, .utf8); } pub fn createUTF16(bytes: []const u16) String { if (bytes.len == 0) return String.empty; if (bun.strings.firstNonASCII16([]const u16, bytes) == null) { - return BunString__fromUTF16ToLatin1(bytes.ptr, bytes.len); + return validateRefCount(BunString__fromUTF16ToLatin1(bytes.ptr, bytes.len)); } - return BunString__fromUTF16(bytes.ptr, bytes.len); + return validateRefCount(BunString__fromUTF16(bytes.ptr, bytes.len)); } pub fn createFormat(comptime fmt: [:0]const u8, args: anytype) OOM!String { @@ -642,7 +654,7 @@ pub const String = extern struct { } return dead; } - return BunString__createExternal(bytes.ptr, bytes.len, isLatin1, ctx, callback); + return validateRefCount(BunString__createExternal(bytes.ptr, bytes.len, isLatin1, ctx, callback)); } /// This should rarely be used. The WTF::StringImpl* will never be freed. @@ -682,8 +694,8 @@ pub const String = extern struct { } return switch (comptime kind) { - .latin1 => BunString__createExternalGloballyAllocatedLatin1(bytes.ptr, bytes.len), - .utf16 => BunString__createExternalGloballyAllocatedUTF16(bytes.ptr, bytes.len), + .latin1 => validateRefCount(BunString__createExternalGloballyAllocatedLatin1(bytes.ptr, bytes.len)), + .utf16 => validateRefCount(BunString__createExternalGloballyAllocatedUTF16(bytes.ptr, bytes.len)), }; }