)]}'
{
  "commit": "a6944943ed44fda376b540b554d85d09012607d6",
  "tree": "068e7329df48de79bba20b2fa6921290018840c9",
  "parents": [
    "47211ef9918bf68ec9434021fa0da0b4276bcfc0"
  ],
  "author": {
    "name": "Jackson Gardner",
    "email": "jacksongardner@google.com",
    "time": "Fri Jun 06 09:27:08 2025 -0700"
  },
  "committer": {
    "name": "dart-internal-monorepo",
    "email": "dart-internal-monorepo@dart-ci-internal.iam.gserviceaccount.com",
    "time": "Fri Jun 06 10:05:41 2025 -0700"
  },
  "message": "Lazy paths and frame object arenas (#168996)\n\nThe lifecycle of `Path` objects are currently not managed by the user.\nThat is to say, there is no `dispose` method on path objects and\ntherefore no explicit way to detect when the user is done with the path\nobject and the native-side object can be exposed. As of right now, we\nuse `FinalizationRegistry` to clean up the native-side objects when the\ndart-side objects are garbage collected. However, this has a number of\nissues:\n* Adding objects to the finalization registry actually ends up\nprolonging their lifetime in V8, since the V8 garbage collector will\nonly collect them in a major GC and not a minor GC once they are\nregistered with the finalization registry. See the following Chrome bug:\nhttps://issues.chromium.org/issues/340777103\n* We can run into OOM issues where the linear memory of canvaskit/skwasm\nexceeds 2GB if the collection of paths go on too long.\n* Even if the paths do get collected by the GC, they often happen\ninfrequently enough that paths over many frames have accumulated and are\nbeing collected all at once. This gap can often be dozens or hundreds of\nframes long, and when collection does occur it is freeing a lot of paths\nat once, which causes a janky frame. I have seen this take upwards of\n800ms on my M1 Macbook Pro.\n\nThere are some more details in\nhttps://github.com/flutter/flutter/issues/153678\n\nThis PR alleviates this issue by creating a `LazyPath` object. This\nobject is added to an arena that explicitly collects the underlying\nnative objects at the end of each frame. The object also tracks the API\ncalls made to it so that if it is actually used across a frame boundary\nthat we can recreate the native object if it was freed.\n\nRunning our benchmarks, this has a non-trivial performance cost to\nbuilding and using these paths (30-50% in a microbenchmark, 3-6% in a\nbroader full app benchmark). However, as a team we\u0027ve decided that this\ncost is worth it to avoid OOM issues as well as the non-deterministic\njank associated with large collections of these objects.\nhttps://dart.googlesource.com/external/github.com/flutter/flutter/+/a11524896eaecaa2a6a44c14cdb65aa31492e479\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "2a0e17c8ee29133a8d853c8c2271dc9d8131bda6",
      "old_mode": 33188,
      "old_path": "DEPS",
      "new_id": "cd4561c4c98ca0e72bdeffaf24b4d61702e27e81",
      "new_mode": 33188,
      "new_path": "DEPS"
    },
    {
      "type": "modify",
      "old_id": "4283465e4edccf4b3d12c7a2c83f34e12dacb060",
      "old_mode": 33188,
      "old_path": "commits.json",
      "new_id": "5d429442a035f21c06315aa7fce7c1e15303af2c",
      "new_mode": 33188,
      "new_path": "commits.json"
    }
  ]
}
