Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: DataDog/java-profiler
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: DataDog/java-profiler
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: feat/refchain_3
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 20 commits
  • 26 files changed
  • 1 contributor

Commits on Sep 22, 2026

  1. Add JFR event types for reference chains

    Introduces the ReferenceChainEvent/ReferenceChainAbandonedEvent payloads
    (event.h), their JFR metadata (jfrMetadata.*), and the FlightRecorder
    emission paths that serialize chain events into JFR recording buffers,
    including the constant-pool handling for per-hop edge labels. Emission
    is pull-style: profiler.cpp snapshots events and hands them to
    FlightRecorder; this layer does not depend on the tracker itself.
    jbachorik committed Sep 22, 2026
    Configuration menu
    Copy the full SHA
    a3ef3b6 View commit details
    Browse the repository at this point in the history
  2. Keep chain events inside the recording buffer; keep truncated labels

    Review findings on the JFR plumbing layer:
    
    - MAX_REFERENCE_CHAIN_EVENT_HOPS was a fixed 4096, permitting a ~438 KB
      worst-case event (near-limit edge labels) against a ~61 KB recording
      buffer - the reservation flushed first but the margin underflowed, so
      the write ran past the buffer (debug assert, release corruption). The
      cap is now derived from RECORDING_BUFFER_LIMIT minus the event's fixed
      fields, divided by the per-hop worst case, so a full-cap event always
      fits.
    - Truncation dropped ALL edge labels: the label count was gated on
      _edges.size() == emitted_size, which only holds for untruncated
      chains. Labels align with the chain's leaf-first element order, so
      truncation now emits the first emitted_size labels and loses only the
      root-side ones.
    - ObjectLivenessEvent::leak_tag is default-initialized to 0 so any
      construction path that forgets to set it serializes a defined
      untagged value (flush_table() overwrites it from the entry, which
      track() zeroes at insert).
    
    Moves the JFR round-trip and arguments parsing unit tests into this
    layer (they test exactly this code), rewrites the round-trip test to
    construct events directly instead of through the tracker, and adds
    byte-level boundary tests: oversize-chain truncation with label
    preservation, the size-prefix invariant, and the default leak tag.
    jbachorik committed Sep 22, 2026
    Configuration menu
    Copy the full SHA
    ecc9e3f View commit details
    Browse the repository at this point in the history
  3. Drop transient and stale line-number references from comments

    Uncommitted plan documents, rotted .cpp:NNN line references, and a
    nonexistent j9WallClock.cpp path replaced with symbol references that
    stay valid as the code moves.
    jbachorik committed Sep 22, 2026
    Configuration menu
    Copy the full SHA
    c3e0128 View commit details
    Browse the repository at this point in the history
  4. Address review: merge chain hops, trim comments, drop doc/jira refs

    - ReferenceChainEvent carries one vector of ReferenceChainHop
      (klass id + retention-edge label) instead of two parallel vectors
    - Compress the sub-option floor/ceiling rationale and the provisional
      default constant comments to one concise statement each
    - Drop design-doc and Jira references from code comments; revert the
      unrelated LineNumberTable comment rewrite
    jbachorik committed Sep 22, 2026
    Configuration menu
    Copy the full SHA
    a285c97 View commit details
    Browse the repository at this point in the history
  5. Make comments layer-local: no references to later stack layers

    The event/argument comments named collector classes, methods and files
    that do not exist at this layer of the stack; describe the contracts
    without those forward references instead.
    jbachorik committed Sep 22, 2026
    Configuration menu
    Copy the full SHA
    e693a4a View commit details
    Browse the repository at this point in the history
  6. Configuration menu
    Copy the full SHA
    8c59cd1 View commit details
    Browse the repository at this point in the history
  7. Implement reference-chain tracking and the leak-signal engine

    ReferenceChainTracker: per-klass class tags, the frontier table of
    retained references, the BFS expansion thread, chain resolution into
    per-sample ReferenceChainEvent payloads, and leak-tag correlation.
    LivenessTracker: the per-klass population table, heap-floor ring with
    time-to-OOM projection, and leak-candidate selection feeding the
    tracker's search gate. Adds the referencechains Arguments block, the
    string-dictionary generation counter used to invalidate the class-tag
    cache, and the container-memory/os queries the projection needs.
    jbachorik committed Sep 22, 2026
    Configuration menu
    Copy the full SHA
    358532e View commit details
    Browse the repository at this point in the history
  8. Deallocate GetObjectsWithTags results in hopLabelClassFor

    hopLabelClassFor() was the only GetObjectsWithTags() call site that did
    not Deallocate() the returned object/tag arrays - a per-cache-miss leak
    on the BFS thread's hop-label path (caught by the asan gtest run). Free
    both right after the class object is extracted, and null-guard the error
    path, matching the file's other call sites.
    jbachorik committed Sep 22, 2026
    Configuration menu
    Copy the full SHA
    de4603c View commit details
    Browse the repository at this point in the history
  9. Fix clang scan-build findings in the tracker and engine

    - collectStaticFieldAnchorsForRotation: the other tier is the last
      consumer of the anchor budget - stop accumulating its leftover back
      into budget_left (dead store).
    - buildCanaryChainEvent: capture the chain size before moving the vector
      into the event instead of reading the moved-from object for the log.
    - secondsToOOM: check ringThirdsStats()'s return for the time ring
      instead of reading time_stats uninitialized on its (unreachable-in-
      practice, but analyzer-visible) failure path - same head/fill/min-fill
      gate as the byte call, so it cannot trigger once the byte call passed.
    jbachorik committed Sep 22, 2026
    Configuration menu
    Copy the full SHA
    bd6259a View commit details
    Browse the repository at this point in the history
  10. Fix review findings in the tracker and liveness engine

    - Leak-tag pool: start() reset the free list while the preserved tracking
      table still had tagged entries (the table survives stop()/start()), so a
      new object could receive a tag another live object owns and a later
      double release could write past the free list. Reclaim owned tags first
      and keep their correlation info.
    - track() published a reserved slot before initializing it while shared-mode
      scanners (tagLeakInstances, getLiveTraceIds) could read the uninitialized
      malloc storage; slots now carry a release/acquire ready flag and fresh
      table regions start unpublished.
    - secondsToOOM projects BOTH the heap and the container boundary and takes
      the shorter time instead of picking a ring by the raw limit comparison -
      container usage includes native memory and siblings, so a container with
      a numerically larger limit can still be closer to exhaustion.
    - cleanup_table() claimed the GC epoch before acquiring the table lock, so
      a newer epoch's fold could enter the population history before an older
      one's; the claim now happens under the lock (the pre-lock check remains
      as an advisory early exit).
    - threadLoop's urgency ramp multiplied the budget by four on every rounded
      pause-target change and never restored it; the boost now applies once
      per urgency episode and the configured budget is restored when it ends.
    - The terminal restart gate now charges the finished search's accumulated
      safepoint cost BEFORE checking affordability, so an expensive search no
      longer earns one free immediate successor (restartSearch() no longer
      spends it itself; the pain-budget test asserts the new order).
    - hopLabelClassFor() deleted cls twice on the superclass-walk path.
    - The class-shape reconciliation loop never deleted the class-object local
      refs GetObjectsWithTags() returned (BFS thread - pins classes against
      unload).
    - walkStaticFieldAnchors() early breaks left later anchors' local refs
      undeleted; a cleanup pass now releases them.
    - The static-field sweep's truncation cursor resumed by a visited-count
      index that assumes HotSpot's LIFO FollowReferences order; it now redoes
      the chunk, which is order-independent (shared code must not rely on
      HotSpot internals).
    - buildDiscoveredInstanceChains() treated a cache hit from an earlier
      search generation as current; the generation check now mirrors the
      representative-refresh paths.
    - cacheResolvedChain() reports success so coverage accounting (found bits,
      resolved counts) only advances for a chain that was actually stored.
    - os_linux: container usage is now read from the same cgroup level that
      supplied the selected limit (an ancestor limit covers sibling cgroups
      whose usage the leaf excludes).
    
    Moves referenceChains_ut.cpp and livenessTracker_ut.cpp into this layer -
    they test exactly this code, and the pain-budget ordering change requires
    its test to land with it.
    jbachorik committed Sep 22, 2026
    Configuration menu
    Copy the full SHA
    f459b3c View commit details
    Browse the repository at this point in the history
  11. Clear the klass-population scratch in the test-reset seam

    A stale full scratch surviving klassPopulationResetForTest() lets the
    first post-reset GC fold fill the population table in one pass, making
    the synthetic-epoch seeded entry the permanent LRU-eviction victim - a
    fold landing mid-seeding (few-ms GC cadence on slow runners) resets the
    seeded ring and breaks the trend gate. Observed as the
    shouldSelectSeededKlassAsLeakCandidateOnPositiveSlope flake on
    musl-aarch64 (librca 21 and 11).
    jbachorik committed Sep 22, 2026
    Configuration menu
    Copy the full SHA
    2bcb2cd View commit details
    Browse the repository at this point in the history
  12. CI: retrigger

    jbachorik committed Sep 22, 2026
    Configuration menu
    Copy the full SHA
    0430ff7 View commit details
    Browse the repository at this point in the history
  13. Replace uncommitted-plan and line-number references with symbol refs

    Comments pointing at locally-kept plan documents, rotted .cpp:NNN
    references, and a duplicated four-times comment block consolidated to
    the constant it documents.
    jbachorik committed Sep 22, 2026
    Configuration menu
    Copy the full SHA
    c9be6f7 View commit details
    Browse the repository at this point in the history
  14. Adapt tracker to merged ReferenceChainHop; drop Jira refs

    fillHopEdgeLabels() fills hop edge labels in place; buildChainEvent()
    and the canary builder assemble ReferenceChainEvent::_hops from the
    parallel internal vectors.
    jbachorik committed Sep 22, 2026
    Configuration menu
    Copy the full SHA
    0ef7fe3 View commit details
    Browse the repository at this point in the history
  15. Make comments layer-local and drop stale plan refs from tests

    No references to Java integration tests, stresstest repros, or
    uncommitted plan documents from this layer; the gtest files carry the
    comment cleanups with the code they test.
    jbachorik committed Sep 22, 2026
    Configuration menu
    Copy the full SHA
    eb60cfb View commit details
    Browse the repository at this point in the history
  16. Configuration menu
    Copy the full SHA
    38e99f8 View commit details
    Browse the repository at this point in the history
  17. Configuration menu
    Copy the full SHA
    485ab7d View commit details
    Browse the repository at this point in the history
  18. Configuration menu
    Copy the full SHA
    afb2e3a View commit details
    Browse the repository at this point in the history
  19. Configuration menu
    Copy the full SHA
    32d9188 View commit details
    Browse the repository at this point in the history

Commits on Sep 23, 2026

  1. Trim comment narration across reference-chain code and tests

    Comment-only cleanup for review: drop revision-history and design-doc
    narration, unverifiable anecdotes, and essays restating the code; keep
    condensed mechanism-backed invariants. Fixes a swallowed assertion and a
    duplicate declaration in referenceChains_ut.cpp, one misplaced
    indentation in livenessTracker_ut.cpp, and trims an unverifiable claim
    from one test failure message.
    jbachorik committed Sep 23, 2026
    Configuration menu
    Copy the full SHA
    f72646d View commit details
    Browse the repository at this point in the history
Loading