)]}'
{
  "commit": "961c4894dcf582649a944560c413e1aa682c94b6",
  "tree": "70dabca2c69517bd0356a3f6231c02a267157ab7",
  "parents": [
    "3a294293ca863ead143a240463e36d7aa326f852"
  ],
  "author": {
    "name": "Zimuzo Ezeozue",
    "email": "zezeozue@google.com",
    "time": "Tue Jun 16 23:03:01 2026 +0000"
  },
  "committer": {
    "name": "Zimuzo Ezeozue",
    "email": "zezeozue@google.com",
    "time": "Wed Jun 17 00:06:19 2026 +0100"
  },
  "message": "ui: Heap Dump Explorer flamegraph diff with pprof-style coloring\n\nAdd baseline / diff mode to the Heap Dump Explorer. Load a second trace (or\npick a second dump from the same trace) as a baseline and compare it against\nthe current dump across every tab:\n\n- Overview diff, and a Flamegraph diff coloured pprof-style on the signed,\n  normalised delta (green \u003d smaller, grey \u003d unchanged, red \u003d larger; absolute\n  or relative basis per metric) with a matching legend.\n- Diff grids for Classes, Objects, Dominators, Bitmaps, Strings and Arrays,\n  plus a per-object diff view.\n- A top-bar RadioGroup toggles Diff / Current / Baseline.\n\nSame-trace diffs run as a single SQL JOIN against android_heap_graph_*;\ncross-trace diffs pair objects in JS across the two trace_processor engines\n(NUL-free dense path ids, so the keys are portable to the native engine) and\nwrite the paired rows back into the current engine. Pooled baseline engines\nare torn down via the trace\u0027s trash on close.\n\nRebased onto current upstream/main, which moved the explorer onto a\nstore-backed session with a persisted_state permalink model after this work\nwas first written. The diff state is re-ported onto that model: object tabs\nserialize their (currentId, baselineId) pair, the page keeps a content-keyed\ntab map plus an (engine, filter)-keyed overview cache for the baseline and\ncurrent sides, and all page-level caches reset per trace load. Adds a\npersisted_state round-trip unit test and fixes stale mode-toggle selectors in\nthe e2e tests (the widget is a RadioGroup, not SegmentedButtons).\n",
  "tree_diff": [
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "86b3b37a49f708d06763344080075ab55efe9e92",
      "new_mode": 33188,
      "new_path": "docs/heap_diff/README.md"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "4d235ebfb27542e8f2229ce301a46b110ee3d7cc",
      "new_mode": 33188,
      "new_path": "docs/heap_diff/screenshots/01_overview_diff.png"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "e6cd4d2c1cbc241626f1cbf843b125fad58629b0",
      "new_mode": 33188,
      "new_path": "docs/heap_diff/screenshots/02_flamegraph_diff.png"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "3be457bfa1134ed1ec2819658c2de0f4c9f2161e",
      "new_mode": 33188,
      "new_path": "docs/heap_diff/screenshots/03_classes_diff.png"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "2d0fa5c2336846f248dabda395b10df644eb3632",
      "new_mode": 33188,
      "new_path": "docs/heap_diff/screenshots/04_objects_diff.png"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "1f5a37c5fd027fd2d437a128a666a0ba0f503397",
      "new_mode": 33188,
      "new_path": "docs/heap_diff/screenshots/05_dominators_diff.png"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "0fd759cfbc0b213bd93e044b246946aab1347854",
      "new_mode": 33188,
      "new_path": "docs/heap_diff/screenshots/06_bitmaps_diff.png"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "d6d6dc06fe8f881af4611f7d7d7a42eaebbac63b",
      "new_mode": 33188,
      "new_path": "docs/heap_diff/screenshots/07_strings_diff.png"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "4957e71e022b240dda1cae40b5e4d6f9209a2c4a",
      "new_mode": 33188,
      "new_path": "docs/heap_diff/screenshots/08_arrays_diff.png"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "64b23bd4b04d9f8ce9e92da2de8906c864f54090",
      "new_mode": 33188,
      "new_path": "docs/heap_diff/screenshots/09_popup.png"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "6aadc0ee5dc93474602776d13e416b997ac23753",
      "new_mode": 33188,
      "new_path": "docs/heap_diff/screenshots/cross_trace/01_overview_diff.png"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "0bf7bb8cfebdf1ba5d1095f74d65b9b9d875e1c8",
      "new_mode": 33188,
      "new_path": "docs/heap_diff/screenshots/cross_trace/02_flamegraph_diff.png"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "c71b408861f51b8b83ad0bcb557787203c6e6373",
      "new_mode": 33188,
      "new_path": "docs/heap_diff/screenshots/cross_trace/03_classes_diff.png"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "8d4b487f0cbfa21908b54f1bb5fd16fa65ccb708",
      "new_mode": 33188,
      "new_path": "docs/heap_diff/screenshots/cross_trace/04_objects_diff.png"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "a95c0870fbc8586b92585df2e76d21f1c64228c0",
      "new_mode": 33188,
      "new_path": "docs/heap_diff/screenshots/cross_trace/05_dominators_diff.png"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "bcfa2c01650e7cb9dc02ce318d701bcd38b41ca0",
      "new_mode": 33188,
      "new_path": "docs/heap_diff/screenshots/cross_trace/06_bitmaps_diff.png"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "794901a7c5dd7ffd521c8b303b37e108f50abd3f",
      "new_mode": 33188,
      "new_path": "docs/heap_diff/screenshots/cross_trace/07_strings_diff.png"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "62e8bae46facad8dc2aa50cc5ac3334f46b20124",
      "new_mode": 33188,
      "new_path": "docs/heap_diff/screenshots/cross_trace/08_arrays_diff.png"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "47f7c6bf5b8a91dc03a2e1c1f43b9ee760ff7d16",
      "new_mode": 33188,
      "new_path": "tools/heap_dump_diff_test_app/HeapDumpDiffTest.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "f7652838344cb01333c6779800d1d42caae71160",
      "new_mode": 33188,
      "new_path": "tools/heap_dump_diff_test_app/README.md"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "bafbb1c184fd6a666f4ce6a2564db2556b7c7ffc",
      "new_mode": 33188,
      "new_path": "tools/heap_dump_diff_test_app/build_rich_fixture.py"
    },
    {
      "type": "modify",
      "old_id": "e89111360abc763d420ffa24065d7474b0b4a834",
      "old_mode": 33188,
      "old_path": "ui/src/components/query_flamegraph.ts",
      "new_id": "7701284bdef3f4b722d2f780d5f9e996d484c42d",
      "new_mode": 33188,
      "new_path": "ui/src/components/query_flamegraph.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "5247aca463dcc7798705595c4b313a4f7fe538b7",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/baseline/load_action.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "f5b5b982b13d3b0d3b16f092461f6215b8277d5c",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/baseline/loader.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "39afa9c0f8315ec3e19894c99e10b1dc978bf98a",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/baseline/state.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "5284c23ca841e07283b9303a744a3a44d829f788",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/diff/cross_trace_diff.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "220f3018f54513bc8058fa615f77b575b88c290c",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/diff/cross_trace_diff_unittest.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "554460ffa8d9f611b91bdd745693599794c8cfbd",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/diff/diff_cache.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "703c6e9ffe39c80696c223244928b562cbe6be16",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/diff/diff_debug.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "70b0948e7fe9bfbf96474e1eab710c0eef475dbd",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/diff/diff_rows.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "54da413b5761db9ebf6657a2d12008090aba7034",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/diff/diff_rows_unittest.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "8fa2dfe611b68b11d0340b3fa83cfffcfd7d5a7e",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/diff/diff_schemas.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "4a9ab37bf978c5482179a2bf700f9ea28432d082",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/diff/object_pairing.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "650dc7a1aa89fc3798f3fce76ac5a77796a565af",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/diff/object_pairing_unittest.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "82b27758cd62b65ea1044b9ce0bd6aaeebdd8e7f",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/header.ts"
    },
    {
      "type": "modify",
      "old_id": "452e94560733d292db5b999b9467b81da7c11501",
      "old_mode": 33188,
      "old_path": "ui/src/plugins/com.android.HeapDumpExplorer/heap_dump_page.ts",
      "new_id": "87e87e1b2e9473faf2965e1e64afc5fab4a047cd",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/heap_dump_page.ts"
    },
    {
      "type": "modify",
      "old_id": "806b14bf6493f36bc120b7ccd0b77c3d2f6b8ee0",
      "old_mode": 33188,
      "old_path": "ui/src/plugins/com.android.HeapDumpExplorer/index.ts",
      "new_id": "2ad28597330e3528c7057caa9f7dccc55bd26940",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/index.ts"
    },
    {
      "type": "modify",
      "old_id": "09f64581a52ca6c15f30fde27cdf51d6e6c506bf",
      "old_mode": 33188,
      "old_path": "ui/src/plugins/com.android.HeapDumpExplorer/persisted_state.ts",
      "new_id": "9f184244afc99b9038bc2b359eb9a63f9acf2ce3",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/persisted_state.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "fbc0c3629b9932ee45aa3837421497ec782ed566",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/persisted_state_unittest.ts"
    },
    {
      "type": "modify",
      "old_id": "32b3fbe8656615f159d42c51530ca64959c7ed94",
      "old_mode": 33188,
      "old_path": "ui/src/plugins/com.android.HeapDumpExplorer/queries.ts",
      "new_id": "8daff7c1c018207cd8b424da5a40ae931e823629",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/queries.ts"
    },
    {
      "type": "modify",
      "old_id": "3d07cc9c260886ca7d0e9a6fbd6332f32ba67a33",
      "old_mode": 33188,
      "old_path": "ui/src/plugins/com.android.HeapDumpExplorer/session.ts",
      "new_id": "c4d1200c79d0dc9b22f36be4f368f317cad561d8",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/session.ts"
    },
    {
      "type": "modify",
      "old_id": "bb2caf5e505e71e15cdbc48dd588cf21523612a1",
      "old_mode": 33188,
      "old_path": "ui/src/plugins/com.android.HeapDumpExplorer/styles.scss",
      "new_id": "f5de4cefd5115b8ee0fd0733eccdcd02d61008e2",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/styles.scss"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "ca992df68243379fe416ddbda7574e95781e619a",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/top_bar.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "fad8f98514dfa511b5debb231ff0bb874d344be2",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/views/diff/all_objects_diff_view.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "6d8d0f03a283fad302b8bf500cc324dc9c6b1100",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/views/diff/arrays_diff_view.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "847e3364e7f1c02f24cb5f79c746a36950541c02",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/views/diff/bitmaps_diff_view.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "34033db23c0b8e3f3eff0b4f562162a7e8505e74",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/views/diff/classes_diff_view.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "0b17469becb508b6315f7138cda3570ea1dd05ca",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/views/diff/dominators_diff_view.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "ae5b2fb318abb3442d427d7e7861d7a3fb9ecd06",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/views/diff/object_diff_view.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "fb8c724f1e150450b328b6dd9834423261da0a39",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/views/diff/strings_diff_view.ts"
    },
    {
      "type": "modify",
      "old_id": "12858f2cf9c42c8fa0e0b7ea1413ba598a7e328f",
      "old_mode": 33188,
      "old_path": "ui/src/plugins/com.android.HeapDumpExplorer/views/flamegraph_view.ts",
      "new_id": "6918c1a112bfebf98e098a22c74e82661f7fe494",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/views/flamegraph_view.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "692741b2ec9e3e7e200e8127925201f43f37fa43",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/views/overview/duplicates_section.ts"
    },
    {
      "type": "modify",
      "old_id": "91b6ce2dc863bf5b12266a6171e2d2f466954917",
      "old_mode": 33188,
      "old_path": "ui/src/plugins/com.android.HeapDumpExplorer/views/overview_view.ts",
      "new_id": "56ae9b90949de8f72b42e86c8044b12856072520",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/views/overview_view.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "80d97909ba7899d7359fe2d453884b6993a8797d",
      "new_mode": 33188,
      "new_path": "ui/src/test/heap_dump_diff.test.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "4f7dab7a375c0e40dac815ec995573f08e98cbcb",
      "new_mode": 33188,
      "new_path": "ui/src/test/heap_dump_diff_hprof_primary.test.ts"
    },
    {
      "type": "modify",
      "old_id": "b3e9e73fd361e75d9935d957564d19592280902b",
      "old_mode": 33188,
      "old_path": "ui/src/widgets/flamegraph.ts",
      "new_id": "abfbe5ada20e03b102f9ed81deb7e77246936503",
      "new_mode": 33188,
      "new_path": "ui/src/widgets/flamegraph.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "f7867260f4850c62f622a217ec91a5ab7873324e",
      "new_mode": 33188,
      "new_path": "ui/src/widgets/flamegraph_diff_color_unittest.ts"
    }
  ]
}
