mirror of
https://github.com/oven-sh/bun
synced 2026-02-11 19:38:58 +00:00
microptimize
This commit is contained in:
@@ -216,7 +216,7 @@ pub const HTMLRewriter = struct {
|
||||
|
||||
response.cloneInto(result, getAllocator(global.ref()));
|
||||
this.finalizeWithoutDestroy();
|
||||
return JSValue.fromRef(Response.Class.make(global.ref(), result));
|
||||
return JSValue.fromRef(Response.makeMaybePooled(global.ref(), result));
|
||||
}
|
||||
|
||||
var new_context = this.context;
|
||||
@@ -311,7 +311,7 @@ pub const HTMLRewriter = struct {
|
||||
};
|
||||
|
||||
return JSC.JSValue.fromRef(
|
||||
Response.Class.make(sink.global.ref(), sink.response),
|
||||
Response.makeMaybePooled(sink.global.ref(), sink.response),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -327,7 +327,7 @@ pub const HTMLRewriter = struct {
|
||||
if (prev_value.Locked.promise) |promise| {
|
||||
prev_value.Locked.promise = null;
|
||||
promise.asInternalPromise().?.resolve(this.global, JSC.JSValue.fromRef(
|
||||
Response.Class.make(
|
||||
Response.makeMaybePooled(
|
||||
this.global.ref(),
|
||||
this.response,
|
||||
),
|
||||
|
||||
@@ -92,6 +92,7 @@ pub fn NewServer(comptime ssl_enabled: bool) type {
|
||||
app: *App = undefined,
|
||||
globalThis: *JSGlobalObject,
|
||||
default_server: URL = URL{ .host = "localhost", .port = "3000" },
|
||||
response_objects_pool: JSC.WebCore.Response.Pool = JSC.WebCore.Response.Pool{},
|
||||
|
||||
request_pool_allocator: std.mem.Allocator = undefined,
|
||||
|
||||
@@ -116,6 +117,7 @@ pub fn NewServer(comptime ssl_enabled: bool) type {
|
||||
|
||||
this.listener = socket;
|
||||
VirtualMachine.vm.uws_event_loop = uws.Loop.get();
|
||||
VirtualMachine.vm.response_objects_pool = &this.response_objects_pool;
|
||||
this.app.run();
|
||||
}
|
||||
|
||||
@@ -127,6 +129,7 @@ pub fn NewServer(comptime ssl_enabled: bool) type {
|
||||
method: HTTP.Method,
|
||||
aborted: bool = false,
|
||||
response_jsvalue: JSC.JSValue = JSC.JSValue.zero,
|
||||
response_ptr: ?*JSC.WebCore.Response = null,
|
||||
blob: JSC.WebCore.Blob = JSC.WebCore.Blob{},
|
||||
promise: ?*JSC.JSValue = null,
|
||||
response_headers: ?*JSC.WebCore.Headers.RefCountedHeaders = null,
|
||||
@@ -181,14 +184,13 @@ pub fn NewServer(comptime ssl_enabled: bool) type {
|
||||
.method = HTTP.Method.which(req.method()) orelse .GET,
|
||||
.server = server,
|
||||
};
|
||||
resp.onAborted(*RequestContext, onAbort, this);
|
||||
}
|
||||
|
||||
pub fn onAbort(this: *RequestContext, _: *App.Response) void {
|
||||
this.aborted = true;
|
||||
this.req = undefined;
|
||||
if (!this.response_jsvalue.isEmpty()) {
|
||||
JSC.C.JSValueUnprotect(this.server.globalThis.ref(), this.response_jsvalue.asObjectRef());
|
||||
this.server.response_objects_pool.push(this.server.globalThis, this.response_jsvalue);
|
||||
this.response_jsvalue = JSC.JSValue.zero;
|
||||
}
|
||||
}
|
||||
@@ -196,7 +198,7 @@ pub fn NewServer(comptime ssl_enabled: bool) type {
|
||||
pub fn finalize(this: *RequestContext) void {
|
||||
this.blob.detach();
|
||||
if (!this.response_jsvalue.isEmpty()) {
|
||||
JSC.C.JSValueUnprotect(this.server.globalThis.ref(), this.response_jsvalue.asObjectRef());
|
||||
this.server.response_objects_pool.push(this.server.globalThis, this.response_jsvalue);
|
||||
this.response_jsvalue = JSC.JSValue.zero;
|
||||
}
|
||||
|
||||
@@ -213,11 +215,11 @@ pub fn NewServer(comptime ssl_enabled: bool) type {
|
||||
this.server.request_pool_allocator.destroy(this);
|
||||
}
|
||||
|
||||
pub fn render(this: *RequestContext, response: *JSC.WebCore.Response) void {
|
||||
pub fn doRender(this: *RequestContext) void {
|
||||
if (this.aborted) {
|
||||
return;
|
||||
}
|
||||
|
||||
var response = this.response_ptr.?;
|
||||
this.blob = response.body.use();
|
||||
const status = response.statusCode();
|
||||
|
||||
@@ -236,9 +238,7 @@ pub fn NewServer(comptime ssl_enabled: bool) type {
|
||||
this.resp.writeStatus(std.fmt.bufPrint(&status_text_buf, "{d} HM", .{response.body.init.status_code}) catch unreachable);
|
||||
}
|
||||
|
||||
for (names) |name, i| {
|
||||
this.resp.writeHeader(headers.asStr(name), headers.asStr(values[i]));
|
||||
}
|
||||
this.resp.writeHeaders(names, values, headers.buf.items);
|
||||
}
|
||||
|
||||
if (status == 302 or status == 202 or this.blob.size == 0) {
|
||||
@@ -250,6 +250,12 @@ pub fn NewServer(comptime ssl_enabled: bool) type {
|
||||
this.resp.end(this.blob.sharedView(), false);
|
||||
this.finalize();
|
||||
}
|
||||
|
||||
pub fn render(this: *RequestContext, response: *JSC.WebCore.Response) void {
|
||||
this.response_ptr = response;
|
||||
this.resp.runCorked(*RequestContext, doRender, this);
|
||||
this.response_ptr = null;
|
||||
}
|
||||
};
|
||||
|
||||
pub fn onRequest(this: *ThisServer, req: *uws.Request, resp: *App.Response) void {
|
||||
@@ -286,6 +292,7 @@ pub fn NewServer(comptime ssl_enabled: bool) type {
|
||||
}
|
||||
|
||||
if (ctx.response_jsvalue.jsTypeLoose() == .JSPromise) {
|
||||
resp.onAborted(*RequestContext, RequestContext.onAbort, ctx);
|
||||
JSC.VirtualMachine.vm.tick();
|
||||
|
||||
ctx.response_jsvalue.then(
|
||||
|
||||
@@ -480,7 +480,7 @@ pub const VirtualMachine = struct {
|
||||
ref_strings: JSC.RefString.Map = undefined,
|
||||
|
||||
source_mappings: SavedSourceMap = undefined,
|
||||
|
||||
response_objects_pool: ?*Response.Pool = null,
|
||||
pub inline fn eventLoop(this: *VirtualMachine) *EventLoop {
|
||||
return this.event_loop;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,42 @@ const JSPrinter = @import("../../../js_printer.zig");
|
||||
const picohttp = @import("picohttp");
|
||||
const StringJoiner = @import("../../../string_joiner.zig");
|
||||
pub const Response = struct {
|
||||
pub const Pool = struct {
|
||||
response_objects_pool: [127]JSC.C.JSObjectRef = undefined,
|
||||
response_objects_used: u8 = 0,
|
||||
|
||||
pub fn get(this: *Pool, ptr: *Response) ?JSC.C.JSObjectRef {
|
||||
if (this.response_objects_used > 0) {
|
||||
var result = this.response_objects_pool[this.response_objects_used - 1];
|
||||
this.response_objects_used -= 1;
|
||||
if (JSC.C.JSObjectSetPrivate(result, JSPrivateDataPtr.init(ptr).ptr())) {
|
||||
return result;
|
||||
} else {
|
||||
JSC.C.JSValueUnprotect(VirtualMachine.vm.global.ref(), result);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn push(this: *Pool, globalThis: *JSC.JSGlobalObject, object: JSC.JSValue) void {
|
||||
var remaining = this.response_objects_pool[@minimum(this.response_objects_used, this.response_objects_pool.len)..];
|
||||
if (remaining.len == 0) {
|
||||
JSC.C.JSValueUnprotect(globalThis.ref(), object.asObjectRef());
|
||||
return;
|
||||
}
|
||||
|
||||
if (object.as(Response)) |resp| {
|
||||
_ = JSC.C.JSObjectSetPrivate(object.asObjectRef(), null);
|
||||
|
||||
_ = resp.body.use();
|
||||
resp.finalize();
|
||||
remaining[0] = object.asObjectRef();
|
||||
this.response_objects_used += 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub const Constructor = JSC.NewConstructor(
|
||||
Response,
|
||||
.{
|
||||
@@ -262,7 +298,18 @@ pub const Response = struct {
|
||||
_: js.ExceptionRef,
|
||||
) js.JSValueRef {
|
||||
var cloned = this.clone(getAllocator(ctx));
|
||||
return Response.Class.make(ctx, cloned);
|
||||
return Response.makeMaybePooled(ctx, cloned);
|
||||
}
|
||||
|
||||
pub fn makeMaybePooled(ctx: js.JSContextRef, ptr: *Response) JSC.C.JSObjectRef {
|
||||
if (JSC.VirtualMachine.vm.response_objects_pool) |pool| {
|
||||
if (pool.get(ptr)) |object| {
|
||||
JSC.C.JSValueUnprotect(ctx, object);
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
||||
return Response.Class.make(ctx, ptr);
|
||||
}
|
||||
|
||||
pub fn cloneInto(this: *const Response, new_response: *Response, allocator: std.mem.Allocator) void {
|
||||
@@ -410,7 +457,7 @@ pub const Response = struct {
|
||||
var ptr = response.allocator.create(Response) catch unreachable;
|
||||
ptr.* = response;
|
||||
|
||||
return Response.Class.make(ctx, ptr);
|
||||
return Response.makeMaybePooled(ctx, ptr);
|
||||
}
|
||||
pub fn constructRedirect(
|
||||
_: void,
|
||||
@@ -462,7 +509,7 @@ pub const Response = struct {
|
||||
var ptr = response.allocator.create(Response) catch unreachable;
|
||||
ptr.* = response;
|
||||
|
||||
return Response.Class.make(ctx, ptr);
|
||||
return Response.makeMaybePooled(ctx, ptr);
|
||||
}
|
||||
pub fn constructError(
|
||||
_: void,
|
||||
@@ -485,7 +532,7 @@ pub const Response = struct {
|
||||
.url = "",
|
||||
};
|
||||
|
||||
return Response.Class.make(
|
||||
return Response.makeMaybePooled(
|
||||
ctx,
|
||||
response,
|
||||
);
|
||||
@@ -522,7 +569,7 @@ pub const Response = struct {
|
||||
.allocator = getAllocator(ctx),
|
||||
.url = "",
|
||||
};
|
||||
return Response.Class.make(
|
||||
return Response.makeMaybePooled(
|
||||
ctx,
|
||||
response,
|
||||
);
|
||||
@@ -753,7 +800,7 @@ pub const Fetch = struct {
|
||||
},
|
||||
},
|
||||
};
|
||||
return JSValue.fromRef(Response.Class.make(@ptrCast(js.JSContextRef, this.global_this), response));
|
||||
return JSValue.fromRef(Response.makeMaybePooled(@ptrCast(js.JSContextRef, this.global_this), response));
|
||||
}
|
||||
|
||||
pub fn get(
|
||||
|
||||
Reference in New Issue
Block a user