Skip to content

Commit 71110d8

Browse files
committed
docs: (with codex chatgpt) add MemoryView design docs
- document MemoryView layout, virtualization, and highlight behavior - outline implementation plan with frontend/backend/DAP integration steps
1 parent fa78e86 commit 71110d8

File tree

2 files changed

+206
-0
lines changed

2 files changed

+206
-0
lines changed

docs/memory_view.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# MemoryView design doc
2+
3+
## Purpose
4+
MemoryView is a new UI component that visualizes heap memory as a grid of
5+
addressed cells. It allows a user to scroll large heap regions without loading
6+
all bytes at once by virtualizing memory ranges and requesting only the visible
7+
window plus a small buffer.
8+
9+
## Goals
10+
- Show a clear, legible grid of memory locations and values.
11+
- Make scrolling smooth by virtualizing heap ranges and caching results.
12+
- Support quick navigation to a specific address and to known heap regions.
13+
- Handle large heaps safely with predictable memory usage.
14+
15+
## Non-goals
16+
- Editing memory bytes in place.
17+
- Stack or code segment visualization (heap only for v1).
18+
- Full disassembly or pointer graph exploration.
19+
20+
## UX layout
21+
MemoryView borrows the familiar hex-editor layout
22+
(https://en.wikipedia.org/wiki/Hex_editor) but groups bytes into boxes to
23+
improve scanning.
24+
25+
```
26+
+-------------------------------------------------------------+
27+
| MemoryView | Heap | Range: 0x00007f90_1000 - 0x00007f90_5fff |
28+
| Search: [0x00007f90_2a10] [Go] [Bytes: 16] [Group: 4] |
29+
|-------------------------------------------------------------|
30+
| Address | 00 01 02 03 | 04 05 06 07 | 08 09 0A 0B |
31+
| 0x7f90_1000 | 7f 45 4c 46 | 02 01 01 00 | 00 00 00 00 |
32+
| 0x7f90_1010 | 03 00 3e 00 | 01 00 00 00 | 80 00 00 00 |
33+
| 0x7f90_1020 | .. .. .. .. | .. .. .. .. | .. .. .. .. |
34+
| ... ... |
35+
|-------------------------------------------------------------|
36+
| Status: loaded 64 KB, cached 256 KB, requests in flight: 1 |
37+
+-------------------------------------------------------------+
38+
```
39+
40+
Notes:
41+
- Each row shows one base address and a fixed number of bytes.
42+
- Bytes are grouped (default 4) into light boxes for quick reading.
43+
- Empty or unmapped data uses a placeholder token `..`.
44+
45+
## Data model
46+
The UI works with two core concepts:
47+
48+
- HeapSegment: a known address interval describing the heap layout.
49+
- start_addr (u64)
50+
- end_addr (u64)
51+
- label (string, optional, e.g. "young gen")
52+
- MemoryRange: a contiguous byte range plus the byte payload.
53+
- start_addr (u64)
54+
- length (u32)
55+
- bytes (Vec<u8>)
56+
- state (loaded | unmapped | error)
57+
58+
The UI maintains a cache keyed by aligned range start. It should never assume
59+
contiguity beyond the range returned by the backend.
60+
61+
## Virtualization and loading ranges
62+
MemoryView should virtualize rows based on viewport height. Only visible rows
63+
plus a small overscan buffer are requested.
64+
65+
Recommended defaults:
66+
- bytes_per_row: 16
67+
- overscan_rows: 8
68+
- range_align: 256 bytes
69+
- range_request_size: 4 KB (16 rows) or 16 KB when the heap is large
70+
71+
Request algorithm:
72+
1) Map viewport to a requested address interval.
73+
2) Align the interval to `range_align`.
74+
3) Split into chunks of `range_request_size`.
75+
4) For each chunk not in cache and not in flight, issue a request.
76+
77+
Caching:
78+
- LRU capped by a total byte size budget (e.g. 4-16 MB).
79+
- Evict whole ranges, never partial rows.
80+
- Keep the current viewport pinned.
81+
82+
Failure handling:
83+
- If a request fails, store an error state for that range and render a visible
84+
inline error marker in the grid with a retry action.
85+
86+
## Interactions
87+
- Scroll: drives virtualization; show a stable scrollbar based on the active
88+
heap segment.
89+
- Jump to address: parse hex, scroll to the containing row, request the range.
90+
- Range selector: list heap segments and allow quick switching.
91+
- Visualize value: when a value is selected elsewhere (e.g. locals in the state
92+
panel), MemoryView receives its address and size, scrolls to the first byte if
93+
needed, and highlights the full range in the grid.
94+
- Hover: show tooltip with address, byte value, and derived numeric formats.
95+
96+
## Accessibility
97+
- Keep fixed-width numeric columns to maintain alignment.
98+
- Support keyboard navigation with row and cell focus.
99+
- Provide a screen-reader summary for the current range and focused address.
100+
101+
## Edge cases
102+
- Unmapped addresses within a segment: display `..` and mark the row as sparse.
103+
- Extremely large heaps: show a scale indicator and limit the jump list to the
104+
nearest segment to avoid long scroll jumps.
105+
- Time-travel step changes: clear caches that are not safe across steps.
106+
- Highlighted ranges that span unloaded bytes should trigger a range load and
107+
render a placeholder highlight until data arrives.
108+
109+
## Testing plan
110+
- Unit tests for range alignment, chunking, and cache eviction.
111+
- UI tests for smooth scroll with missing ranges.
112+
- Error tests for partial/unmapped ranges and retry behavior.
113+
114+
## Open questions
115+
- Should MemoryView support value decoding (u32/u64, float) in a side panel?
116+
- How should it integrate with object inspection to jump to allocations?

docs/memory_view_plan.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# MemoryView implementation plan
2+
3+
## Scope
4+
Implement the MemoryView component described in `docs/memory_view.md` with heap
5+
range virtualization, value highlighting from state panel locals, and basic
6+
range navigation.
7+
8+
## Milestones
9+
1) Data contract and backend integration
10+
- Define a request/response shape for memory range loading (address, length,
11+
optional step id, optional heap segment id; response includes aligned start,
12+
length, payload bytes, and state).
13+
- Add an RPC/IPC endpoint for fetching a range by address and length.
14+
- Include error and unmapped signaling in the response.
15+
- Decide on a transport encoding for bytes (base64 string vs. numeric array)
16+
and mirror it in both Rust and Nim conversions.
17+
- Add MemoryView request/response types in the shared common types
18+
(`src/common/common_types/language_features/value.nim`) and ensure they are
19+
available to the frontend via `src/frontend/types.nim`.
20+
- Add new `CtEventKind` entries in `src/common/ct_event.nim` (request and
21+
response kinds) and map them in `src/frontend/dap.nim`:
22+
- `EVENT_KIND_TO_DAP_MAPPING`
23+
- `toCtDapResponseEventKind`
24+
- `commandToCtResponseEventKind`
25+
- Add custom Codetracer DAP requests for MemoryView and wire send/receive
26+
plumbing in `src/frontend/middleware.nim` (subscribe + emit).
27+
- Add a new db-backend DAP server case for the memory query in
28+
`src/db-backend/src/dap_server.rs` (and in
29+
`src/db-backend/crates/db-backend-core/src/dap_server.rs` if that path is
30+
used), define its arguments in `src/db-backend/src/task.rs`, and implement a
31+
corresponding handler in `src/db-backend/src/handler.rs` to load memory
32+
ranges.
33+
- Extend the replay abstraction to support memory reads (e.g. add
34+
`load_memory_range` to `src/db-backend/src/replay.rs`) and implement it in
35+
`src/db-backend/src/db.rs` and `src/db-backend/src/rr_dispatcher.rs`
36+
(returning a clear error for unsupported backends if needed).
37+
38+
2) UI component skeleton
39+
- Create the MemoryView container with header, range selector, and grid (e.g.
40+
`src/frontend/ui/memory_view.nim`).
41+
- Implement the UI-facing `render`/frontend methods in
42+
`src/frontend/ui/memory_view.nim` to integrate with the existing component
43+
lifecycle.
44+
- Add a new `Content.MemoryView` entry in
45+
`src/common/common_types/codetracer_features/frontend.nim`, then register the
46+
component in `src/frontend/utils.nim` (`makeComponent` + component mapping).
47+
- Add a panel entry (menu or command palette) so users can open MemoryView,
48+
following the existing patterns in `src/frontend/ui_js.nim`.
49+
- Implement fixed-width address column and grouped byte boxes.
50+
- Add placeholder rows for unloaded data.
51+
52+
3) Virtualization and cache
53+
- Implement row virtualization based on viewport height.
54+
- Add aligned range requests and an LRU cache with a byte budget.
55+
- Ensure overscan range loads and in-flight de-duplication.
56+
57+
4) Interactions
58+
- Implement jump-to-address parsing and scroll-to-row.
59+
- Wire “visualize value” from state panel locals to highlight the memory range:
60+
add a UI action in `src/frontend/ui/value.nim` (or the state panel row
61+
renderer) that emits the MemoryView highlight request using the local’s
62+
`address` and a byte length. If size is not available, default to a single
63+
byte or pointer-size highlight and document the fallback.
64+
- Add hover tooltip for address and byte value decoding.
65+
- Emit MemoryView request events from the view and subscribe to response/update
66+
events to refresh the grid.
67+
68+
5) Error handling and resilience
69+
- Render error markers for failed range requests with a retry action.
70+
- Handle step changes by clearing unsafe caches.
71+
- Guard against invalid addresses and zero-length ranges.
72+
73+
6) Testing
74+
- Unit tests for alignment, chunking, and cache eviction.
75+
- UI tests for scrolling, highlighting, and error states.
76+
77+
## Dependencies
78+
- State panel locals already expose a stable `address`, but a byte length is not
79+
currently part of the shared `Variable` type; decide whether to infer size
80+
from type metadata or add an explicit size field for highlights.
81+
- Backend must provide memory range access for the active trace step.
82+
83+
## Risks and mitigations
84+
- Large heap performance: mitigate with strict cache limits and range alignment.
85+
- Unmapped address density: render sparse rows and avoid repeated requests.
86+
87+
## Deliverables
88+
- MemoryView UI component and styling.
89+
- Range loading service with cache and request scheduling.
90+
- Tests covering virtualized loading and value highlighting.

0 commit comments

Comments
 (0)