mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-10-08 20:32:00 -04:00
mem: Track / Free abandoned html5ever parsers
A parser created via document.open() is only freed when done/close is called (or some parse error happens). If close() isn't called, the parser is leaked. This has the Frame track documents that call open so that, on Frame.deinit(), it can free any parser still associated with the document.
This commit is contained in:
2 files changed
+19
No files matched your search
@@ -133,6 +133,10 @@ _event_target_attr_listeners: GlobalEventHandlersLookup = .empty,
|
||||
// File objects (reference counted via their Blob proto); released at teardown.
|
||||
_file_lists: std.ArrayList(*FileList) = .empty,
|
||||
|
||||
// List of Documents which called document.open() and potentially need to have
|
||||
// the parser freed.
|
||||
_script_created_parser_docs: std.ArrayList(*Document) = .empty,
|
||||
|
||||
// Every matchMedia() result of this document, so a viewport change can fire
|
||||
// their `change`.
|
||||
_media_query_lists: std.ArrayList(*MediaQueryList) = .empty,
|
||||
@@ -456,6 +460,16 @@ pub fn deinit(self: *Frame) void {
|
||||
|
||||
self._parse_state.deinit(self);
|
||||
|
||||
for (self._script_created_parser_docs.items) |doc| {
|
||||
const parser = &(doc._script_created_parser orelse continue);
|
||||
if (parser.parser.frame != self) {
|
||||
// The document was closed and re-opened on another frame
|
||||
continue;
|
||||
}
|
||||
parser.deinit();
|
||||
doc._script_created_parser = null;
|
||||
}
|
||||
|
||||
// Unregister CookieStore from session notifications before the JS
|
||||
// context (and thus the scheduler) is destroyed, otherwise a late
|
||||
// mutation could schedule a callback that never runs.
|
||||
|
||||
@@ -1157,6 +1157,11 @@ pub fn open(self: *Document, call_frame: *Frame) !*Document {
|
||||
// gone for good, as in Chrome.
|
||||
frame.cancelQueuedNavigation();
|
||||
|
||||
if (std.mem.indexOfScalar(*Document, frame._script_created_parser_docs.items, self) == null) {
|
||||
// have the page track this document (if it isn't already)
|
||||
// so that, on shutdown, it can close the parser if needed.
|
||||
try frame._script_created_parser_docs.append(frame.arena, self);
|
||||
}
|
||||
self._script_created_parser = Parser.Streaming.init(frame.arena, doc_node, frame, .{ .allow_declarative_shadow = true });
|
||||
try self._script_created_parser.?.start();
|
||||
frame._parse_mode = .document;
|
||||
|
||||
Reference in new issue
Block a user