)]}'
{
  "commit": "b98227b7c386f0c0434758588ae577a7dbdf838a",
  "tree": "e8cca3a179ff7bc8e8dc0bc4b42859e26a316d62",
  "parents": [
    "018bad7658017c397b47964f6cde71cab37ed6b1"
  ],
  "author": {
    "name": "Takuto Ikuta",
    "email": "tikuta@google.com",
    "time": "Mon Sep 14 21:15:21 2026 +0900"
  },
  "committer": {
    "name": "gn-scoped@luci-project-accounts.iam.gserviceaccount.com",
    "email": "gn-scoped@luci-project-accounts.iam.gserviceaccount.com",
    "time": "Mon Sep 14 19:39:22 2026 -0700"
  },
  "message": "[gn] Make ResolvedTargetData stateless\n\nProfiling \u0027gn gen\u0027 on Chromium \u0027out/Default\u0027 (36k targets, 64 cores)\nrevealed that ResolvedTargetData::GetTargetInfo was a major bottleneck:\n- std::__Cr::__shared_mutex_base::lock_shared() consumed 9.01% cycles.\n- Hash computation (CityHash/hash_memory) consumed 14.35% cycles.\nTogether, about 23% of total CPU cycles were spent on every query\nacquiring shared_locks and probing shard hash maps, even though targets\nare queried repeatedly and their pointers are immutable after\nresolution.\n\nAs suggested by Matt Stark (msta@), we can simplify this significantly:\n\n1. Move TargetInfo directly into Target as \u0027std::optional\u003cTargetInfo\u003e\u0027.\n2. Initialize \u0027info_\u0027 when Target::OnResolvedWithoutChecks() is called\n   (with a fallback lazy initialization in info() for unit tests that\n   skip OnResolved).\n3. Make ResolvedTargetData completely stateless. GetTargetInfo() simply\n   returns \u0027\u0026target-\u003einfo()\u0027 inline with zero locks, zero hashing, and\n   zero dynamic heap allocations for TargetInfo map entries.\n4. Because Target owns its TargetInfo directly, the lifetime of\n   TargetInfo perfectly matches Target, eliminating any possibility of\n   use-after-free or address-reuse (ABA) bugs when Targets or\n   ResolvedTargetData instances are destroyed in unit tests.\n\nPerformance impact on Chromium \u0027out/Default\u0027 (vs origin/main):\n- Wall-clock time: 3.281s -\u003e 3.173s (-108ms, -3.3%)\n- User CPU time:   30.87s -\u003e 27.32s (-3.55s, -11.5%)\n- CPU cycles:     102.91G -\u003e 89.86G (-13.05G cycles, -12.7%)\n- Instructions:   110.14G -\u003e 102.72G (-7.42G instrs, -6.7%)\n\nAll 845 unit tests passed. Output ninja files are bit-for-bit identical.\n\nTAG\u003dagy\nCONV\u003d4cb5d931-60a8-4f44-8632-3e8d9fb10a8d\nChange-Id: Ib23f999522044d5b4b46128491d54ef9061ef4b5\nReviewed-on: https://gn-review.googlesource.com/c/gn/+/26480\nReviewed-by: Matt Stark \u003cmsta@google.com\u003e\nCommit-Queue: Takuto Ikuta \u003ctikuta@google.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "fe906d79e724fe6e42c05aa0ee6ece21a95ec386",
      "old_mode": 33188,
      "old_path": "src/gn/resolved_target_data.cc",
      "new_id": "de936c57bd113353f152ec73dce4d569fbab5d36",
      "new_mode": 33188,
      "new_path": "src/gn/resolved_target_data.cc"
    },
    {
      "type": "modify",
      "old_id": "e7c6e865cee218f08d61a5b60bbb78c7df284c9d",
      "old_mode": 33188,
      "old_path": "src/gn/resolved_target_data.h",
      "new_id": "2c0f8360f6f24e7d788a85b5a0e8d0fe7379e8f6",
      "new_mode": 33188,
      "new_path": "src/gn/resolved_target_data.h"
    },
    {
      "type": "modify",
      "old_id": "d1eaf091eb8fbb36cd5c9c5928961071ac000a6a",
      "old_mode": 33188,
      "old_path": "src/gn/target.cc",
      "new_id": "0e30f413004c7d881dd8ff7adce12fac61782e5b",
      "new_mode": 33188,
      "new_path": "src/gn/target.cc"
    },
    {
      "type": "modify",
      "old_id": "19972b3a714afdead737a0c04161fb82519779e6",
      "old_mode": 33188,
      "old_path": "src/gn/target.h",
      "new_id": "17995f7fe931a77f6107cad030bf698da2bb3eb7",
      "new_mode": 33188,
      "new_path": "src/gn/target.h"
    }
  ]
}
