[MNG-8507] Forward port: Reduce allocation pressure in model building pipeline - #12553
Conversation
Reduce allocation pressure in the Maven 4 immutable model building pipeline, measured with JFR on Apache Camel (676 modules). Overall allocation reduction: ~49% (from ~4,000 MB to ~2,054 MB). Key optimizations: - DefaultModelInterpolator: skip interpolation callback for strings without '$' via anonymous MavenTransformer subclass override - DefaultModelInterpolator: share HashSet for cycle detection across all strings in a model, avoiding ~550 allocations per module - DefaultInterpolator.unescape(): fast-path when no escape markers - DefaultModelValidator: hoist scope computation before dep loop - InternalSession.from(): instanceof fast-path before string concat - MavenProject.hashCode(): inline hash to avoid varargs Object[] - TypeRegistryAdapter: cache get() results in ConcurrentHashMap - PropertiesAsMap: eliminate Entry wrapper allocation, replace stream().filter().count() with imperative loop - ReflectionValueExtractor: make accessor prefix list a static constant instead of per-call Arrays.asList() - transformer.vm: add null-check in transform(String) Closes #12540
gnodet
left a comment
There was a problem hiding this comment.
✅ Clean forward port of MNG-8507 allocation-pressure optimizations from maven-4.0.x to master. All ten files are correct; the conflict resolutions (variable names, FQN types, visibility) are appropriate. No functional regressions detected.
Key observations:
- The optimizations are well-targeted at JFR-identified hotspots (cycleMap allocation, scope validation redundancy, wrapper entry objects, varargs arrays, stream pipelines). All changes preserve existing semantics.
- The null-check addition in
transformer.vm(transform(String)) is not just a performance optimization but a correctness fix — it prevents potential NPE when model string fields are null. - The
HashSetreuse for cycle detection inDefaultModelInterpolatoris thread-safe becauseMavenTransformer.visit()processes strings sequentially in a single thread.
Minor notes (non-blocking):
- The cast
(DefaultInterpolator) interpolatorinDefaultModelInterpolatorcouples to a concrete implementation — consider adding a brief comment explaining why the downcast is safe and necessary. - The informational comment about Flex Mojos custom scopes in
DefaultModelValidatorwas removed during refactoring — consider preserving it near the scope validation logic for historical context.
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of gnodet
…ment - DefaultModelInterpolator: explain why the (DefaultInterpolator) cast is safe and necessary (access package-private overload for HashSet reuse) - DefaultModelValidator: restore historical comment about Flex Mojos custom scopes near the scope validation logic Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Addressed both notes in 9eff25c:
|
|
@gnodet Please assign appropriate label to PR according to the type of change. |
Summary
Forward port of #12540 (merged to
maven-4.0.x) tomaster.Cherry-picked from f5426bf with conflict resolution in:
DefaultModelValidator.java— adapted variable names (sessionvss,dependencyvsd) and FQN type references (org.eclipse.aether.scope.DependencyScope)TypeRegistryAdapter.java— keptpublicvisibility (class moved to a different package on master)See #12540 for the full description and JFR profiling results.
Test plan
master🤖 Generated with Claude Code