Assuming the conditions are met for -dev_fast to work (linux, debug, x86-64
without sanitizers), the -dev_fast now defaults to true.
download-v8 make target always downloads the .a (as before) and on linux x86-64
it also downloads the .so.
Some WPT tests just take more memory, e.g. shadow-dom/declarative/gethtml.html.
Also left some placeholder comments for profiling JS (which I used to make sure
this was just v8 memory usage). These placeholders used to exist but didn't
survive the session multi-page refactor (figured I'd fix it next time I needed
it, and now I needed it).
Supports prebuild-v8 shared library and adds a `download-v8-shared` make target.
Depends on: https://github.com/lightpanda-io/zig-v8-fork/pull/198
The auto-discovery of the .so is done in the build.zig, which is different than
the auto-discovery of the .a which is done in the Makefile. This is intentional
and if we inverse -Ddev_fast so that it's on by default, the .a's auto discovery
will be moved to build.zig for consistency and explicitness. As-is, we have no
way to tell whether -Dprebuilt_v8_path=v8.a is being injected by Makefile or
is explicit (which isn't a problem so long as we're not doing dev_fast by
default).
Saw a non-fatal error on cnn.com related to console. All members are supposed
to be static. Ran it through WPT /console/ and improved a few different thigns:
- added dir and dirxml
- assert condition is optional
Cancel termination only when all context have a call_depth == 0. This ensures
that termination "sticks" all the way up a nested call. Without this, a nested
call could clear a terminate which targeted something up the stack.
A JS entry (JSEntry) clears V8's terminating state when the termination
exception unwinds past it, which is what tryCall and friends rely on.
A microtask checkpoint does not: when a requested termination (watchdog,
CDP-disconnect kill) lands inside a checkpoint-delivered callback such
as MutationObserver delivery, PerformCheckpoint returns with
IsExecutionTerminating still set and nothing ever clears it. Every
later V8 call in that isolate then runs against a terminating isolate
and can return empty where callers don't expect it, ending in SIGSEGV
during connection teardown.
Cancel the V8-level termination after a checkpoint in which a terminate
landed, keeping the sticky terminate_requested so the existing entry
gates keep refusing new JS, and skip the remaining context queues.
Production-observed sequence this covers (SIGSEGV/139 tails):
watchdog stall -> MutObserver.deliverRecords err=ExecutionTerminated
-> frame.deliverMutations -> closing connection (pending terminate)
-> SIGSEGV
Assisted-By: devx/95b8cb7f-8baf-4a28-93bf-61bc21612890
Split active_conns and active_threads to free a CDP conn slot as soon as
possible.
It gives a room where we have more active threads than allowed CDP
connections while threads shudown.
Adds the getHTML methods to Element and ShadowRoot. This is expected to add
another ~6K passing WPT tests (significantly improving out score in the
/shadow-dom/ category). It's also probably also a useful API to implement.
All add/remove node operations come down to Frame.removeNode and
Frame._insertNodeRelative. But not all remove/insert are the same, e.g. removing
a disconnect node is different than removing a connected node. Also, a "move"
operation is a remove+insert, but some move operations appear more atomic than
others. There is both a correctness and an optimization side to these
differences.
Previously, removeNode took a will_be_reconnected: bool option and insert took
a child_already_connected: bool. Essentially, remove wants to know the
post-removal intention, and insert wants to know the pre-insert state.
The simple booleans work for simple cases, but fail for ShadowDOM: it isn't
enough to know if `will_be_reconnected`...we need to know in what root it'll
be reconnected. Both remove and insert become tristate:
1 - is staying in the same root
2 - is staying connected, but in a different root
3 - is becoming connected for the first time
This commits changes `will_be_reconnected: bool` to `reconnect_to: ?*Node` and
`child_already_connected: bool` to `previous_root: ?*Node`. So most callsites
had to be updated - which is why so many files were touched. But the bulk of
the change is in those two Frame method which must now handle the tristate.