Skip to content

Commit

Permalink
fix: un-ref'd source map causing memory leak
Browse files Browse the repository at this point in the history
  • Loading branch information
DonIsaac committed Jan 22, 2025
1 parent f463bdb commit 62d29f5
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 2 deletions.
18 changes: 16 additions & 2 deletions src/bun.js/javascript.zig
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ pub const SavedSourceMap = struct {
entry.value_ptr.* = value.ptr();
}

/// You must call `.map.deref()` on the returned url or you'll cause a memory leak.
fn getWithContent(
this: *SavedSourceMap,
path: string,
Expand Down Expand Up @@ -377,10 +378,12 @@ pub const SavedSourceMap = struct {
}
}

/// You must call `.deref()` the returned source map or you'll cause a leak
pub fn get(this: *SavedSourceMap, path: string) ?*ParsedSourceMap {
return this.getWithContent(path, .mappings_only).map;
}

/// You must call `.source_map.deref()` on the result or you'll introduce a memory leak
pub fn resolveMapping(
this: *SavedSourceMap,
path: []const u8,
Expand All @@ -395,8 +398,10 @@ pub const SavedSourceMap = struct {
const map = parse.map orelse return null;

const mapping = parse.mapping orelse
SourceMap.Mapping.find(map.mappings, line, column) orelse
SourceMap.Mapping.find(map.mappings, line, column) orelse {
map.deref();
return null;
};

return .{
.mapping = mapping,
Expand Down Expand Up @@ -1887,7 +1892,12 @@ pub const VirtualMachine = struct {
JSC.markBinding(@src());
const allocator = opts.allocator;
VMHolder.vm = try allocator.create(VirtualMachine);
errdefer {
if (VMHolder.vm) |vm| allocator.destroy(vm);
VMHolder.vm = null;
}
const console = try allocator.create(ConsoleObject);
errdefer allocator.destroy(console);
console.* = ConsoleObject.init(Output.errorWriter(), Output.writer());
const log = opts.log.?;
const transpiler = try Transpiler.init(
Expand Down Expand Up @@ -4322,6 +4332,8 @@ pub const VirtualMachine = struct {
writer.print("\n", .{}) catch {};
}

/// You must call `.source_map.deref()` on the returned lookup, otherwise
/// you'll cause a memory leak.
pub fn resolveSourceMapping(
this: *VirtualMachine,
path: []const u8,
Expand All @@ -4339,8 +4351,10 @@ pub const VirtualMachine = struct {
this.source_mappings.putValue(path, SavedSourceMap.Value.init(map)) catch
bun.outOfMemory();

const mapping = SourceMap.Mapping.find(map.mappings, line, column) orelse
const mapping = SourceMap.Mapping.find(map.mappings, line, column) orelse {
map.deref();
return null;
};

return .{
.mapping = mapping,
Expand Down
1 change: 1 addition & 0 deletions src/sourcemap/CodeCoverage.zig
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ pub const ByteRangeMapping = struct {
var executable_lines: Bitset = Bitset{};
var lines_which_have_executed: Bitset = Bitset{};
const parsed_mappings_ = bun.JSC.VirtualMachine.get().source_mappings.get(source_url.slice());
defer if (parsed_mappings_) |pm| pm.deref();
var line_hits = LinesHits{};

var functions = std.ArrayListUnmanaged(Block){};
Expand Down
1 change: 1 addition & 0 deletions src/sourcemap/sourcemap.zig
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,7 @@ pub const ParseResult = union(enum) {
success: ParsedSourceMap,
};

/// Reference counted.
pub const ParsedSourceMap = struct {
input_line_count: usize = 0,
mappings: Mapping.List = .{},
Expand Down

0 comments on commit 62d29f5

Please sign in to comment.