Repository navigation
Conversation
@ImpliedFor on a contract annotation lists types the contract is implied for. @Staticlifetime now applies to every ClassValue and ThreadLocal field, since a per-instance one discards its per-class or per-thread values with each instance. The perf-review rubric checks the implied types too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
@codex review |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 36646d1fc0
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
StaticLifetime and the perf-review rubric now point to @ImpliedFor instead of restating its matching rule and type list, and @ImpliedFor drops the unused type-contract clause until a type contract adopts it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A per-instance ThreadLocal is often deliberate per-owner state (about a third of ThreadLocal fields on master), so implying the contract for it would flag correct code. ClassValue fields are static 17:1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Open question for reviewers: should I've left it out for now (014549b) and only
The alternative is to imply it anyway and add |
There was a problem hiding this comment.
More details
The annotation contract and review rubric consistently extend StaticLifetime checks to ClassValue and ThreadLocal fields, including subtypes, while preserving the accepted static-final, Singleton, and suppression forms.
🤖 Bits Code Review · Commit 36646d1 · @DataDog review to ask questions
🟢 Java Benchmark SLOs — All performance SLOs passed
PR vs. master results
Commit: Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion. |
What Does This Do
Adds
@ImpliedFor, a meta-annotation for perf-contract annotations that lists types the contract is implied for. This covers types we can't annotate ourselves, such as JDK or third-party classes.@ImpliedFor(datadog.perfcontract) carries its own Javadoc checker contract. On a field contract, a field whose declared type is a listed type (or a subtype) is checked as if it were annotated. On a type contract, a listed type is treated as if it carried the contract.@SuppressPerfContractexempts implied findings the same way it exempts explicit ones.@StaticLifetimeis now@ImpliedFor(ClassValue.class), and its Javadoc covers implied fields.ThreadLocalis deliberately left out for now (see below).checks.mditem 9) checks implied types too.Motivation
Perf contracts are opt-in, so they only guard declarations someone remembered to annotate. A non-
staticClassValuefield is always a bug: each instance discards the per-class cache. But nobody annotates the broken field, so@StaticLifetimecouldn't catch it. On master,ClassValuefields arestatic17:1.Additional Notes
Stacked on #12646 (
@StaticLifetime/@Singleton). Review that first.Only the AI reviewer enforces this, and it reviews diffs, so existing code is only flagged when someone touches it. Master has one non-
staticClassValue:ClassLatch.latched. It's deliberate, because eachClassLatchis heldstatic finalper call site. The plan is to cover it with a type-level@StaticLifetimeonClassLatchin a follow-up, not with a suppression.Why not
ThreadLocal? It's a gray area. On master,ThreadLocalfields arestaticonly about 2:1 (22 static, 11 instance), and some instance ones are deliberately per owner. For example,TagContextExtractorbuilds itsThreadLocalfrom an instance-specific interpreter factory, so a sharedstaticwould mix state between propagation configs. Implying the contract would flag that correct code, and the obviousstatic finalfix would make it wrong. Opinions welcome on whetherThreadLocalbelongs here with@SuppressPerfContractfor the per-owner cases.🤖 Generated with Claude Code