> # HashMap.putAll() optimizations: Eliminating Megamorphic Call Site 
> Bottlenecks
> 
> ## Summary
> 
> This PR addresses performance bottlenecks in `HashMap.putMapEntries()` by 
> implementing direct optimizations for specific input types: `j.u.HashMap` and 
> `j.u.Collections$UnmodifiableMap`. The optimizations target `HashMap(Map)` 
> constructor and `putAll()` operations based on the real-world megamorphic 
> behavior identified in 
> [JDK-8368292](https://bugs.openjdk.org/browse/JDK-8368292), delivering 
> significant performance improvements when multiple `Map` subtypes are used.
> 
> ## Problem Context
> 
> ### Megamorphic Call Site Overhead in Map Iteration
> `HashMap.putMapEntries()` currently uses a generic approach that suffers from 
> megamorphic call site overhead when applications perform bulk creation or 
> population of HashMaps from various source map types:
> 
> 1. `m.entrySet()` becomes megamorphic across different map implementations
> 2. `entrySet().iterator()` creates different iterator types
> 3. `entry.getKey()` and `entry.getValue()` calls vary by map type
> 4. Individual `putVal()` calls for each entry
> 
> When the source is `Collections$UnmodifiableMap`, the problem is compounded 
> by megamorphic wrappers around the already-megamorphic iteration methods. In 
> cases where the unwrapped map is also a HashMap, both the wrapper overhead 
> and the iteration overhead can be eliminated with a single optimization.
> 
> ## Optimized Methods
> 
> ### HashMap
> - **`putMapEntries(Map<? extends K, ? extends V> m, boolean evict)`**: Added 
> fast paths for UnmodifiableMap unwrapping and HashMap-to-HashMap copying
> - **`putMapEntries(HashMap<? extends K, ? extends V> src, boolean evict)`**: 
> copies HashMap-to-HashMap via direct Node processing.  Avoids polymorphic 
> issues and eliminates redundant calls to HashMap.hash().
> 
> ## Implementation Details
> 
> ### HashMap-to-HashMap Fast Path
> Directly iterates over `src.table` to eliminate entrySet() allocation and 
> polymorphic iterator calls, using the internal Node structure for maximum 
> efficiency.
> 
> ### UnmodifiableMap Unwrapping
> Detects UnmodifiableMap instances and accesses the underlying map directly 
> via the `m` field, eliminating wrapper-induced megamorphic call sites. 
> UnmodifiableMap visibility changed from `private` to package-private to 
> enable this direct access.
> 
> ## Performance Impact
> 
> | Source Type | Size | Poisoned | Baseline | Optimized | Improvement |
> |-------------|------|----------|----------|-----------|-------------|
> | HashMap | 0 | true | 9.429 ns/op | 8.875 ns/op |...

jengebr has updated the pull request incrementally with one additional commit 
since the last revision:

  Unit test revisions

-------------

Changes:
  - all: https://git.openjdk.org/jdk/pull/28243/files
  - new: https://git.openjdk.org/jdk/pull/28243/files/05891484..edfc6a2f

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=jdk&pr=28243&range=01
 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=28243&range=00-01

  Stats: 27 lines in 2 files changed: 7 ins; 11 del; 9 mod
  Patch: https://git.openjdk.org/jdk/pull/28243.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/28243/head:pull/28243

PR: https://git.openjdk.org/jdk/pull/28243

Reply via email to