Skip to content

LibWeb: Add shared layout node storage for Rust - #10870

Merged
kalenikaliaksandr merged 2 commits into
LadybirdBrowser:masterfrom
kalenikaliaksandr:layout-node-arena
Jul 25, 2026
Merged

LibWeb: Add shared layout node storage for Rust#10870
kalenikaliaksandr merged 2 commits into
LadybirdBrowser:masterfrom
kalenikaliaksandr:layout-node-arena

Conversation

@kalenikaliaksandr

Copy link
Copy Markdown
Member

Prep work before converting layout code in Rust but also removes ffi_layout_node_facts() which was very heavy in profiles on https://www.nyan.cat/

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 167ea76e-2ba0-4c20-a865-071bb5e02e25

📥 Commits

Reviewing files that changed from the base of the PR and between 26f4aae and 183c10a.

📒 Files selected for processing (19)
  • Libraries/LibWeb/CMakeLists.txt
  • Libraries/LibWeb/DOM/Document.cpp
  • Libraries/LibWeb/DOM/Document.h
  • Libraries/LibWeb/Forward.h
  • Libraries/LibWeb/Layout/AudioBox.h
  • Libraries/LibWeb/Layout/Box.h
  • Libraries/LibWeb/Layout/Node.cpp
  • Libraries/LibWeb/Layout/Node.h
  • Libraries/LibWeb/Layout/NodeArena.cpp
  • Libraries/LibWeb/Layout/NodeArena.h
  • Libraries/LibWeb/Layout/ReplacedBox.cpp
  • Libraries/LibWeb/Layout/Rust/cbindgen.toml
  • Libraries/LibWeb/Layout/Rust/src/layout_node_arena.rs
  • Libraries/LibWeb/Layout/Rust/src/lib.rs
  • Libraries/LibWeb/Layout/Rust/src/node_data.rs
  • Libraries/LibWeb/Layout/Rust/src/tree_builder.rs
  • Libraries/LibWeb/Layout/TreeBuilder.cpp
  • Libraries/LibWeb/Layout/VideoBox.h
  • Libraries/LibWeb/RefCountedTreeNode.h
🚧 Files skipped from review as they are similar to previous changes (18)
  • Libraries/LibWeb/Layout/VideoBox.h
  • Libraries/LibWeb/CMakeLists.txt
  • Libraries/LibWeb/Layout/NodeArena.cpp
  • Libraries/LibWeb/Forward.h
  • Libraries/LibWeb/Layout/ReplacedBox.cpp
  • Libraries/LibWeb/Layout/Rust/cbindgen.toml
  • Libraries/LibWeb/Layout/NodeArena.h
  • Libraries/LibWeb/Layout/Rust/src/lib.rs
  • Libraries/LibWeb/DOM/Document.cpp
  • Libraries/LibWeb/Layout/AudioBox.h
  • Libraries/LibWeb/DOM/Document.h
  • Libraries/LibWeb/Layout/Rust/src/node_data.rs
  • Libraries/LibWeb/RefCountedTreeNode.h
  • Libraries/LibWeb/Layout/Box.h
  • Libraries/LibWeb/Layout/Rust/src/layout_node_arena.rs
  • Libraries/LibWeb/Layout/Node.h
  • Libraries/LibWeb/Layout/TreeBuilder.cpp
  • Libraries/LibWeb/Layout/Rust/src/tree_builder.rs

📝 Walkthrough

Walkthrough

Adds a Rust-backed layout-node arena with stable slot IDs and mirrored node data, integrates arena ownership into Document and C++ layout nodes, and migrates Rust/C++ tree-building interfaces from raw pointers to arena-resolved handles.

Changes

Layout node arena migration

Layer / File(s) Summary
Arena and FFI contracts
Libraries/LibWeb/Layout/Rust/src/*, Libraries/LibWeb/Layout/NodeArena.*, Libraries/LibWeb/DOM/Document.*, Libraries/LibWeb/CMakeLists.txt
Defines NodeData, NodeSlotId, flags, chunked allocation, generation tracking, C ABI entry points, C++ RAII wrapping, and lazy document-owned arena creation.
C++ node state migration
Libraries/LibWeb/Layout/Node.*, Box.h, AudioBox.h, VideoBox.h, ReplacedBox.cpp, RefCountedTreeNode.h
Stores node state in RustFFI data and flags, adds node-kind and topology synchronization hooks, updates layout state accessors, and marks replaced nodes through flags.
C++ tree-builder bridge
Libraries/LibWeb/Layout/TreeBuilder.cpp
Passes arena handles through layout-tree operations and changes callback results from raw layout-node pointers to NodeSlotId.
Rust arena-based tree builder
Libraries/LibWeb/Layout/Rust/src/tree_builder.rs
Migrates traversal, pseudo-element construction, wrapper insertion, SVG handling, first-letter discovery, and table fixups to arena-backed NodeSlotId and NodeData access.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Document
  participant LayoutTreeBuildBridge
  participant NodeArena
  participant rust_build_layout_tree
  participant TreeBuilderHost
  Document->>NodeArena: create or retrieve arena
  LayoutTreeBuildBridge->>NodeArena: get arena handle
  LayoutTreeBuildBridge->>rust_build_layout_tree: pass callbacks and handle
  rust_build_layout_tree->>TreeBuilderHost: resolve NodeSlotId values
  TreeBuilderHost->>NodeArena: read NodeData and shell pointers
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description matches the PR’s Rust layout prep work and the removal of heavy ffi_layout_node_facts() profiling overhead.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Libraries/LibWeb/Layout/Rust/src/layout_node_arena.rs`:
- Around line 235-241: Update the test module containing
node_data_slots_are_cache_line_aligned to import std::mem::align_of, or fully
qualify the align_of::<Chunk>() call, so the alignment assertion resolves
without changing the test behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d205210f-b444-431b-92ca-5934abd92a10

📥 Commits

Reviewing files that changed from the base of the PR and between 27d11da and 26f4aae.

📒 Files selected for processing (19)
  • Libraries/LibWeb/CMakeLists.txt
  • Libraries/LibWeb/DOM/Document.cpp
  • Libraries/LibWeb/DOM/Document.h
  • Libraries/LibWeb/Forward.h
  • Libraries/LibWeb/Layout/AudioBox.h
  • Libraries/LibWeb/Layout/Box.h
  • Libraries/LibWeb/Layout/Node.cpp
  • Libraries/LibWeb/Layout/Node.h
  • Libraries/LibWeb/Layout/NodeArena.cpp
  • Libraries/LibWeb/Layout/NodeArena.h
  • Libraries/LibWeb/Layout/ReplacedBox.cpp
  • Libraries/LibWeb/Layout/Rust/cbindgen.toml
  • Libraries/LibWeb/Layout/Rust/src/layout_node_arena.rs
  • Libraries/LibWeb/Layout/Rust/src/lib.rs
  • Libraries/LibWeb/Layout/Rust/src/node_data.rs
  • Libraries/LibWeb/Layout/Rust/src/tree_builder.rs
  • Libraries/LibWeb/Layout/TreeBuilder.cpp
  • Libraries/LibWeb/Layout/VideoBox.h
  • Libraries/LibWeb/RefCountedTreeNode.h

Comment on lines +235 to +241
#[test]
fn node_data_slots_are_cache_line_aligned() {
assert_eq!(align_of::<Chunk>() % 64, 0);
let mut arena = LayoutNodeArena::new();
let allocation = arena.allocate();
assert_eq!(allocation.data as usize % 64, 0);
arena.free(allocation.slot, allocation.generation);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

sed -n '200,280p' Libraries/LibWeb/Layout/Rust/src/layout_node_arena.rs

Repository: LadybirdBrowser/ladybird

Length of output: 2130


Import align_of in the test module. align_of::<Chunk>() is unresolved here unless std::mem::align_of is imported or the call is fully qualified.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Libraries/LibWeb/Layout/Rust/src/layout_node_arena.rs` around lines 235 -
241, Update the test module containing node_data_slots_are_cache_line_aligned to
import std::mem::align_of, or fully qualify the align_of::<Chunk>() call, so the
alignment assertion resolves without changing the test behavior.

Add stable Rust-owned storage for the layout node data that the future
Rust layout rewrite will need, including topology, kinds, flags,
generated-node state, style pointers, layout indices, and containing
blocks. Existing C++ interfaces read from or synchronize with this
representation so future Rust code can access the data without adding
per-field FFI.
Tree construction currently asks C++ for topology and a large bundle of
layout-node facts on every native walk. This keeps read-only traversal
tied to callback traffic even though the same state is already mirrored
in the shared node arena.

Pass the arena into Rust tree-building and detach entry points, use slot
IDs as the walker's node currency, and add a C++ shell back-pointer only
for mutation callbacks. Mirror display and replaced-element state at
their existing write points, then read topology, kinds, flags, and
display facts directly from NodeData. Lazy text, DOM pseudo-style,
child-capability, and fieldset legend queries remain targeted C++ calls.

This removes the topology and aggregate facts callbacks, reducing the
FFI surface that a future native layout rewrite must carry.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant