Skip to content

fix: wrap EditDelta.new_lines in Arc to reduce memory from deep cloning#11623

Draft
warp-dev-github-integration[bot] wants to merge 1 commit into
masterfrom
fix/memory-arc-edit-delta-new-lines
Draft

fix: wrap EditDelta.new_lines in Arc to reduce memory from deep cloning#11623
warp-dev-github-integration[bot] wants to merge 1 commit into
masterfrom
fix/memory-arc-edit-delta-new-lines

Conversation

@warp-dev-github-integration
Copy link
Copy Markdown

Summary

Wraps EditDelta.new_lines in Arc<Vec<StyledBufferBlock>> to eliminate expensive deep cloning when EditDelta is propagated through the event system.

Problem

Heap profiling from Sentry issue 7259255054 shows ~9.3 GB of cumulative allocations from Vec<StyledBufferBlock>::clone() in CodeEditorModel::handle_content_model_event. This is the #2 allocation site after the buffer's SumTree construction itself.

When a file is loaded or its content changes, the EditDelta (containing styled buffer blocks for the entire changed region) gets deep-cloned every time it passes through the event system:

  1. From BufferEvent::ContentChanged to delay rendering queue (delta.clone())
  2. From delay rendering to render state (delta.clone()this one was completely unnecessary since the delta was already owned)
  3. From BufferEvent::ContentChanged to render state (delta.clone())

For large files, each clone duplicates all the StyledBufferBlock strings, causing massive transient allocations.

Changes

  • EditDelta.new_lines: Changed from Vec<StyledBufferBlock> to Arc<Vec<StyledBufferBlock>> so cloning is O(1) reference counting instead of O(n) deep copy
  • layout_delta(): Uses Arc::try_unwrap() to cheaply unwrap when sole owner, falling back to clone only when shared
  • DelayRendering::flush_render(): Removed unnecessary delta.clone() — the delta was already owned by value from consuming the vec
  • Updated all EditDelta construction sites to wrap with Arc::new()

Testing

  • cargo check -p warp_editor passes
  • Existing tests are compatible since Arc<Vec<T>> auto-derefs to Vec<T> for reads

Changelog

CHANGELOG-IMPROVEMENT:
CHANGELOG-BUG-FIX:
CHANGELOG-IMAGE:
CHANGELOG-NEW-FEATURE:


Conversation: https://staging.warp.dev/conversation/57e99221-45e9-483b-bf35-ffee7c71c874
Run: https://oz.staging.warp.dev/runs/019e5841-4d9f-7185-969b-487b41700e56
This PR was generated with Oz.

… changes

Heap profiling from Sentry issue 7259255054 shows ~9.3 GB of cumulative
allocations from Vec<StyledBufferBlock>::clone() in
CodeEditorModel::handle_content_model_event. This happens because the
EditDelta (containing the full styled buffer blocks) is deeply cloned
every time it's propagated through the event system to the render state
and delay rendering queues.

Changes:
- Wrap EditDelta.new_lines in Arc<Vec<StyledBufferBlock>> so cloning is
  O(1) reference counting instead of O(n) deep copy.
- In layout_delta(), use Arc::try_unwrap() to cheaply unwrap the sole
  owner, falling back to clone only if shared.
- Remove an unnecessary delta.clone() in DelayRendering::flush_render()
  where the delta was already owned by value.
- Update all EditDelta construction sites to wrap with Arc::new().

Co-Authored-By: Oz <oz-agent@warp.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant