RFR: JDK-8316756: C2 EA fails with "missing memory path" when encountering unsafe_arraycopy stub call

Vladimir Kozlov kvn at openjdk.org
Fri Jan 12 19:01:19 UTC 2024


On Wed, 10 Jan 2024 13:35:17 GMT, Tobias Holenstein <tholenstein at openjdk.org> wrote:

> Before https://github.com/openjdk/jdk/pull/5259 the graph of the following program looked like this during Escape Analysis:
> 
> 
> static int test() {
>     MyClass obj = new MyClass(); // Non-escaping to trigger Escape Analysis
>     UNSAFE.copyMemory(null, SRC_BASE, null, DST_BASE, 4);
>     obj.x = 42;
>     return obj.x;
> }
> 
> With MemBarCPUOrder:
> <img width="395" alt="working" src="https://github.com/openjdk/jdk/assets/71546117/63a82554-49ff-4373-8567-4457b094093f">
> 
> Setting `RC_NARROW_MEM` flag in `LibraryCallKit::inline_unsafe_copyMemory()` removes the `428 MergeMem` node. Without a `MergeMem` node after `432 StoreB` EA failes in Phase 2 of `ConnectionGraph::split_unique_types(...)` when trying to push the allocation's users on the appropriate worklist - `429 CallLeafNoFP` is not an expected user of `428 StoreB`. Therefore the assert `"EA: missing memory path"` is hit. 
> Without MemBarCPUOrdera and after setting `RC_NARROW_MEM`:
> <img width="370" alt="failing" src="https://github.com/openjdk/jdk/assets/71546117/5d98c38c-d404-4ac4-bd11-bc1e1b7b481f">
> 
> 
> ### Proposed Fix
> Dropping the `RC_NARROW_MEM` flag in `LibraryCallKit::inline_unsafe_copyMemory()` causes the introduction of a `MergeMem` between `StoreB` and `CallLeafNoFP`, so the corresponding code in EA doesn't encounter a `CallLeafNoFP` anymore:
> <img width="336" alt="fixed" src="https://github.com/openjdk/jdk/assets/71546117/c538c199-6676-49a4-aaac-a2b3b8f11694">
> 
> Testing: Tier1-4 passed

I think EA expect MergeMem node before all calls as memory edge. Even if we move StoreB inside stub we will have runtime call node. I made test more complicated to see how it will react to such runtime calls:


    static int[] test() {
         int[] src = new int[4];
         int[] dst = new int[4];
         MyClass obj = new MyClass();
         UNSAFE.copyMemory(src, 0, dst, 0, 4);
         obj.x = 42;
         dst[1] = obj.x;
         return dst;
    }

and it hit same assert:

 119  Proj  === 117  [[ 15 654 640 644 178 178 178 178 ]] #2  Memory: @rawptr:BotPTR, idx=Raw; !jvms: UnsafeArrayCopy::test @ bci:8 (line 25)
 640  CallLeafNoFP  === 181 1 119 8 1 (62 91 30 1 ) [[ 641 643 ]] # unsafe_arraycopy void ( NotNull *+bot, NotNull *+bot, long, half ) !jvms: Unsafe::copyMemory @ bci:29 (line 806) UnsafeArrayCopy::test @ bci:26 (line 26)

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

PR Comment: https://git.openjdk.org/jdk/pull/17347#issuecomment-1889802171


More information about the hotspot-compiler-dev mailing list