mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com> Co-authored-by: Dylan Conway <35280289+dylan-conway@users.noreply.github.com>
This commit is contained in:
@@ -164,12 +164,13 @@ pub const WatchEvent = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub const Op = packed struct {
|
||||
pub const Op = packed struct(u8) {
|
||||
delete: bool = false,
|
||||
metadata: bool = false,
|
||||
rename: bool = false,
|
||||
write: bool = false,
|
||||
move_to: bool = false,
|
||||
_padding: u3 = 0,
|
||||
|
||||
pub fn merge(before: Op, after: Op) Op {
|
||||
return .{
|
||||
@@ -185,6 +186,7 @@ pub const WatchEvent = struct {
|
||||
try w.writeAll("{");
|
||||
var first = true;
|
||||
inline for (comptime std.meta.fieldNames(Op)) |name| {
|
||||
if (comptime std.mem.eql(u8, name, "_padding")) continue;
|
||||
if (@field(op, name)) {
|
||||
if (!first) {
|
||||
try w.writeAll(",");
|
||||
|
||||
@@ -1917,9 +1917,8 @@ fn startAsyncBundle(
|
||||
errdefer heap.deinit();
|
||||
const allocator = heap.allocator();
|
||||
const ast_memory_allocator = try allocator.create(bun.JSAst.ASTMemoryAllocator);
|
||||
ast_memory_allocator.* = .{ .allocator = allocator };
|
||||
ast_memory_allocator.reset();
|
||||
ast_memory_allocator.push();
|
||||
var ast_scope = ast_memory_allocator.enter(allocator);
|
||||
defer ast_scope.exit();
|
||||
|
||||
const bv2 = try BundleV2.init(
|
||||
&dev.server_transpiler,
|
||||
|
||||
@@ -595,14 +595,15 @@ pub const Framework = struct {
|
||||
bundler_options: *const BuildConfigSubset,
|
||||
) !void {
|
||||
const JSAst = bun.JSAst;
|
||||
const prev_alloc_stmt = JSAst.Stmt.Data.Store.memory_allocator;
|
||||
const prev_alloc_expr = JSAst.Expr.Data.Store.memory_allocator;
|
||||
defer JSAst.Stmt.Data.Store.memory_allocator = prev_alloc_stmt;
|
||||
defer JSAst.Expr.Data.Store.memory_allocator = prev_alloc_expr;
|
||||
|
||||
var ast_memory_allocator: JSAst.ASTMemoryAllocator = undefined;
|
||||
ast_memory_allocator.initWithoutStack(arena);
|
||||
JSAst.Stmt.Data.Store.memory_allocator = &ast_memory_allocator;
|
||||
JSAst.Expr.Data.Store.memory_allocator = &ast_memory_allocator;
|
||||
var ast_scope = JSAst.ASTMemoryAllocator.Scope{
|
||||
.previous = JSAst.Stmt.Data.Store.memory_allocator,
|
||||
.current = &ast_memory_allocator,
|
||||
};
|
||||
ast_scope.enter();
|
||||
defer ast_scope.exit();
|
||||
|
||||
out.* = try bun.Transpiler.init(
|
||||
arena,
|
||||
|
||||
@@ -845,6 +845,11 @@ pub fn transpileSourceCode(
|
||||
|
||||
switch (loader) {
|
||||
.js, .jsx, .ts, .tsx, .json, .jsonc, .toml, .text => {
|
||||
// Ensure that if there was an ASTMemoryAllocator in use, it's not used anymore.
|
||||
var ast_scope = js_ast.ASTMemoryAllocator.Scope{};
|
||||
ast_scope.enter();
|
||||
defer ast_scope.exit();
|
||||
|
||||
jsc_vm.transpiled_count += 1;
|
||||
jsc_vm.transpiler.resetStore();
|
||||
const hash = bun.Watcher.getHash(path.text);
|
||||
@@ -2320,9 +2325,8 @@ pub const RuntimeTranspilerStore = struct {
|
||||
};
|
||||
}
|
||||
|
||||
ast_memory_store.?.allocator = allocator;
|
||||
ast_memory_store.?.reset();
|
||||
ast_memory_store.?.push();
|
||||
var ast_scope = ast_memory_store.?.enter(allocator);
|
||||
defer ast_scope.exit();
|
||||
|
||||
const path = this.path;
|
||||
const specifier = this.path.text;
|
||||
|
||||
@@ -117,30 +117,13 @@ pub const TransformTask = struct {
|
||||
const name = this.loader.stdinName();
|
||||
const source = logger.Source.initPathString(name, this.input_code.slice());
|
||||
|
||||
const prev_memory_allocators = .{ JSAst.Stmt.Data.Store.memory_allocator, JSAst.Expr.Data.Store.memory_allocator };
|
||||
defer {
|
||||
JSAst.Stmt.Data.Store.memory_allocator = prev_memory_allocators[0];
|
||||
JSAst.Expr.Data.Store.memory_allocator = prev_memory_allocators[1];
|
||||
}
|
||||
|
||||
var arena = Mimalloc.Arena.init() catch unreachable;
|
||||
defer arena.deinit();
|
||||
|
||||
const allocator = arena.allocator();
|
||||
|
||||
var ast_memory_allocator = allocator.create(JSAst.ASTMemoryAllocator) catch bun.outOfMemory();
|
||||
ast_memory_allocator.* = .{
|
||||
.allocator = allocator,
|
||||
};
|
||||
ast_memory_allocator.reset();
|
||||
|
||||
JSAst.Stmt.Data.Store.memory_allocator = ast_memory_allocator;
|
||||
JSAst.Expr.Data.Store.memory_allocator = ast_memory_allocator;
|
||||
|
||||
defer {
|
||||
JSAst.Stmt.Data.Store.reset();
|
||||
JSAst.Expr.Data.Store.reset();
|
||||
arena.deinit();
|
||||
}
|
||||
var ast_scope = ast_memory_allocator.enter(allocator);
|
||||
defer ast_scope.exit();
|
||||
|
||||
this.transpiler.setAllocator(allocator);
|
||||
this.transpiler.setLog(&this.log);
|
||||
@@ -847,7 +830,8 @@ pub fn scan(this: *JSTranspiler, globalThis: *JSC.JSGlobalObject, callframe: *JS
|
||||
|
||||
var arena = Mimalloc.Arena.init() catch unreachable;
|
||||
const prev_allocator = this.transpiler.allocator;
|
||||
this.transpiler.setAllocator(arena.allocator());
|
||||
const allocator = arena.allocator();
|
||||
this.transpiler.setAllocator(allocator);
|
||||
var log = logger.Log.init(arena.backingAllocator());
|
||||
defer log.deinit();
|
||||
this.transpiler.setLog(&log);
|
||||
@@ -856,13 +840,11 @@ pub fn scan(this: *JSTranspiler, globalThis: *JSC.JSGlobalObject, callframe: *JS
|
||||
this.transpiler.setAllocator(prev_allocator);
|
||||
arena.deinit();
|
||||
}
|
||||
var ast_memory_allocator = allocator.create(JSAst.ASTMemoryAllocator) catch bun.outOfMemory();
|
||||
var ast_scope = ast_memory_allocator.enter(allocator);
|
||||
defer ast_scope.exit();
|
||||
|
||||
defer {
|
||||
JSAst.Stmt.Data.Store.reset();
|
||||
JSAst.Expr.Data.Store.reset();
|
||||
}
|
||||
|
||||
var parse_result = getParseResult(this, arena.allocator(), code, loader, Transpiler.MacroJSValueType.zero) orelse {
|
||||
var parse_result = getParseResult(this, allocator, code, loader, Transpiler.MacroJSValueType.zero) orelse {
|
||||
if ((this.transpiler.log.warnings + this.transpiler.log.errors) > 0) {
|
||||
return globalThis.throwValue(try this.transpiler.log.toJS(globalThis, globalThis.allocator(), "Parse error"));
|
||||
}
|
||||
@@ -991,15 +973,14 @@ pub fn transformSync(
|
||||
}
|
||||
}
|
||||
|
||||
JSAst.Stmt.Data.Store.reset();
|
||||
JSAst.Expr.Data.Store.reset();
|
||||
defer {
|
||||
JSAst.Stmt.Data.Store.reset();
|
||||
JSAst.Expr.Data.Store.reset();
|
||||
}
|
||||
const allocator = arena.allocator();
|
||||
|
||||
var ast_memory_allocator = allocator.create(JSAst.ASTMemoryAllocator) catch bun.outOfMemory();
|
||||
var ast_scope = ast_memory_allocator.enter(allocator);
|
||||
defer ast_scope.exit();
|
||||
|
||||
const prev_bundler = this.transpiler;
|
||||
this.transpiler.setAllocator(arena.allocator());
|
||||
this.transpiler.setAllocator(allocator);
|
||||
this.transpiler.macro_context = null;
|
||||
var log = logger.Log.init(arena.backingAllocator());
|
||||
log.level = this.transpiler_options.log.level;
|
||||
@@ -1010,7 +991,7 @@ pub fn transformSync(
|
||||
}
|
||||
const parse_result = getParseResult(
|
||||
this,
|
||||
arena.allocator(),
|
||||
allocator,
|
||||
code,
|
||||
loader,
|
||||
js_ctx_value,
|
||||
@@ -1132,7 +1113,12 @@ pub fn scanImports(this: *JSTranspiler, globalThis: *JSC.JSGlobalObject, callfra
|
||||
|
||||
var arena = Mimalloc.Arena.init() catch unreachable;
|
||||
const prev_allocator = this.transpiler.allocator;
|
||||
this.transpiler.setAllocator(arena.allocator());
|
||||
const allocator = arena.allocator();
|
||||
var ast_memory_allocator = allocator.create(JSAst.ASTMemoryAllocator) catch bun.outOfMemory();
|
||||
var ast_scope = ast_memory_allocator.enter(allocator);
|
||||
defer ast_scope.exit();
|
||||
|
||||
this.transpiler.setAllocator(allocator);
|
||||
var log = logger.Log.init(arena.backingAllocator());
|
||||
defer log.deinit();
|
||||
this.transpiler.setLog(&log);
|
||||
@@ -1155,14 +1141,6 @@ pub fn scanImports(this: *JSTranspiler, globalThis: *JSC.JSGlobalObject, callfra
|
||||
}
|
||||
opts.macro_context = &this.transpiler.macro_context.?;
|
||||
|
||||
JSAst.Stmt.Data.Store.reset();
|
||||
JSAst.Expr.Data.Store.reset();
|
||||
|
||||
defer {
|
||||
JSAst.Stmt.Data.Store.reset();
|
||||
JSAst.Expr.Data.Store.reset();
|
||||
}
|
||||
|
||||
transpiler.resolver.caches.js.scan(
|
||||
transpiler.allocator,
|
||||
&this.scan_pass_result,
|
||||
|
||||
@@ -119,7 +119,7 @@ pub fn NewStore(comptime types: []const type, comptime count: usize) type {
|
||||
log("deinit", .{});
|
||||
var it = store.firstBlock().next; // do not free `store.head`
|
||||
while (it) |next| {
|
||||
if (Environment.isDebug)
|
||||
if (Environment.isDebug or Environment.enable_asan)
|
||||
@memset(next.buffer, undefined);
|
||||
it = next.next;
|
||||
backing_allocator.destroy(next);
|
||||
@@ -133,7 +133,7 @@ pub fn NewStore(comptime types: []const type, comptime count: usize) type {
|
||||
pub fn reset(store: *Store) void {
|
||||
log("reset", .{});
|
||||
|
||||
if (Environment.isDebug) {
|
||||
if (Environment.isDebug or Environment.enable_asan) {
|
||||
var it: ?*Block = store.firstBlock();
|
||||
while (it) |next| : (it = next.next) {
|
||||
next.bytes_used = undefined;
|
||||
@@ -3214,6 +3214,18 @@ pub const Stmt = struct {
|
||||
instance = StoreType.init();
|
||||
}
|
||||
|
||||
/// create || reset
|
||||
pub fn begin() void {
|
||||
if (memory_allocator != null) return;
|
||||
if (instance == null) {
|
||||
create();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!disable_reset)
|
||||
instance.?.reset();
|
||||
}
|
||||
|
||||
pub fn reset() void {
|
||||
if (disable_reset or memory_allocator != null) return;
|
||||
instance.?.reset();
|
||||
@@ -6322,12 +6334,24 @@ pub const Expr = struct {
|
||||
}
|
||||
|
||||
pub inline fn assert() void {
|
||||
if (comptime Environment.allow_assert) {
|
||||
if (comptime Environment.isDebug or Environment.enable_asan) {
|
||||
if (instance == null and memory_allocator == null)
|
||||
bun.unreachablePanic("Store must be init'd", .{});
|
||||
}
|
||||
}
|
||||
|
||||
/// create || reset
|
||||
pub fn begin() void {
|
||||
if (memory_allocator != null) return;
|
||||
if (instance == null) {
|
||||
create();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!disable_reset)
|
||||
instance.?.reset();
|
||||
}
|
||||
|
||||
pub fn append(comptime T: type, value: T) *T {
|
||||
if (memory_allocator) |allocator| {
|
||||
return allocator.append(T, value);
|
||||
@@ -8554,6 +8578,48 @@ pub const ASTMemoryAllocator = struct {
|
||||
allocator: std.mem.Allocator,
|
||||
previous: ?*ASTMemoryAllocator = null,
|
||||
|
||||
pub fn enter(this: *ASTMemoryAllocator, allocator: std.mem.Allocator) ASTMemoryAllocator.Scope {
|
||||
this.allocator = allocator;
|
||||
this.stack_allocator = SFA{
|
||||
.buffer = undefined,
|
||||
.fallback_allocator = allocator,
|
||||
.fixed_buffer_allocator = undefined,
|
||||
};
|
||||
this.bump_allocator = this.stack_allocator.get();
|
||||
this.previous = null;
|
||||
var ast_scope = ASTMemoryAllocator.Scope{
|
||||
.current = this,
|
||||
.previous = Stmt.Data.Store.memory_allocator,
|
||||
};
|
||||
ast_scope.enter();
|
||||
return ast_scope;
|
||||
}
|
||||
pub const Scope = struct {
|
||||
current: ?*ASTMemoryAllocator = null,
|
||||
previous: ?*ASTMemoryAllocator = null,
|
||||
|
||||
pub fn enter(this: *@This()) void {
|
||||
bun.debugAssert(Expr.Data.Store.memory_allocator == Stmt.Data.Store.memory_allocator);
|
||||
|
||||
this.previous = Expr.Data.Store.memory_allocator;
|
||||
|
||||
const current = this.current;
|
||||
|
||||
Expr.Data.Store.memory_allocator = current;
|
||||
Stmt.Data.Store.memory_allocator = current;
|
||||
|
||||
if (current == null) {
|
||||
Stmt.Data.Store.begin();
|
||||
Expr.Data.Store.begin();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exit(this: *const @This()) void {
|
||||
Expr.Data.Store.memory_allocator = this.previous;
|
||||
Stmt.Data.Store.memory_allocator = this.previous;
|
||||
}
|
||||
};
|
||||
|
||||
pub fn reset(this: *ASTMemoryAllocator) void {
|
||||
this.stack_allocator = SFA{
|
||||
.buffer = undefined,
|
||||
|
||||
@@ -292,7 +292,8 @@ pub fn watchLoopCycle(this: *bun.Watcher) bun.JSC.Maybe(void) {
|
||||
this.mutex.lock();
|
||||
defer this.mutex.unlock();
|
||||
if (this.running) {
|
||||
this.onFileUpdate(this.ctx, all_events[0 .. last_event_index + 1], this.changed_filepaths[0 .. name_off + 1], this.watchlist);
|
||||
// all_events.len == 0 is checked above, so last_event_index + 1 is safe
|
||||
this.onFileUpdate(this.ctx, all_events[0 .. last_event_index + 1], this.changed_filepaths[0..name_off], this.watchlist);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user