dotnet / dotnet/runtime

JIT missing partial escape analysis: object allocated eagerly even when it escapes only on a subset of control-flow paths

Open
#123,141 2 comments 0 reactions 0 assignees View on GitHub
area-CodeGen-coreclr
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

### Description

The .NET JIT currently does not perform partial escape analysis.
If an object escapes only on some control-flow paths, the allocation is still performed eagerly, even when the object’s fields are otherwise only used for local comparisons.

This prevents stack allocation or scalar replacement in cases where the object could be materialized only conditionally.

### Reproduction Steps

```
using System.Runtime.CompilerServices;

class Key
{
public int A;
public int B;
public Key(int a, int b) { A = a; B = b; }
}

static class Test2
{
static Key[] keys = new Key[8];
static object[] values = new object[8];
static int size;

[MethodImpl(MethodImplOptions.NoInlining)]
public static void TestEscape10(int a, int b, object value)
{
var key = new Key(a, b); // allocation happens unconditionally
int index = -1;

for (int i = 0; i < size; i++)
{
if (keys[i].A == key.A && keys[i].B == key.B)
{
index = i;
break;
}
}

if (index == -1)
{
keys[size] = key; // object escapes only on this path
values[size++] = value;
}
else
{
values[index] = value;
}
}
}
```

### Expected behavior

JIT could
1) keep key.A and key.B as scalar locals for the comparison loop, and
2) materialize new Key(a, b) only on the index == -1 path.

### Actual behavior

allocation on enter

```
G_M000_IG01: ;; offset=0x0000
stp fp, lr, [sp, #-0x50]!
stp x19, x20, [sp, #0x18]
stp x21, x22, [sp, #0x28]
stp x23, x24, [sp, #0x38]
str x25, [sp, #0x48]
mov fp, sp
mov w20, w0
mov w21, w1
mov x19, x2

G_M000_IG02: ;; offset=0x0024
movz x0, #0x4BF0
movk x0, #0x732 LSL #16
movk x0, #1 LSL #32
bl CORINFO_HELP_NEWSFAST <- HERE
mov x22, x0
stp w20, w21, [x22, #0x08]
movn w20, #0
mov w21, wzr
movz x0, #0x4B70
movk x0, #0x732 LSL #16
movk x0, #1 LSL #32
ldapr w0, [x0]
tbz w0, #0, G_M000_IG13

and e t c
```

### Regression?

_No response_

### Known Workarounds

_No response_

### Configuration

_No response_

### Other information

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.