Skip to content

Methods with both stackalloc and loops bypass tiering #85548

Open
@AndyAyersMS

Description

@AndyAyersMS

For example:

private bool TryGetNamedPropertyValue(
int startIndex,
int endIndex,
ReadOnlySpan<byte> propertyName,
out JsonElement value)
{
ReadOnlySpan<byte> documentSpan = _utf8Json.Span;
Span<byte> utf8UnescapedStack = stackalloc byte[JsonConstants.StackallocByteThreshold];
// Move to the row before the EndObject
int index = endIndex - DbRow.Size;
while (index > startIndex)
{
DbRow row = _parsedData.Get(index);

Our current method of tiering for methods with loops relies on OSR, but OSR currently cannot handle stackalloc. Instead, such methods are initially jitted with full optimization. Thus they do not benefit from tiering or Dynamic PGO.

Note this is not a new issue; things have been this way since .NET 7 where we enabled OSR, but it may become more pressing now that we are considering enabling PGO by default.

I don't know how many cases of this there are yet, or what if any performance we might gain by trying to address this. But I ran across one example here: #84264 (comment).

Adding stackalloc support to OSR is currently considered to be difficult. A method with stackalloc has two independently addressable areas of its stack frame (commonly handled by using both stack pointer and frame pointer to address locals). But an OSR method must potentially support three areas, and we currently do not have support in the jit or the diagnostics stack for a third stack frame base register.

If this combination turns out to be relatively uncommon, we might consider refactoring the code to avoid this pattern.

cc @dotnet/jit-contrib @stephentoub

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions