Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OSR failure in System.Text.Json.Tests #67152

Closed
AndyAyersMS opened this issue Mar 25, 2022 · 7 comments · Fixed by #67274
Closed

OSR failure in System.Text.Json.Tests #67152

AndyAyersMS opened this issue Mar 25, 2022 · 7 comments · Fixed by #67274
Assignees
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Milestone

Comments

@AndyAyersMS
Copy link
Member

x64 Ubuntu

export COMPlus_TieredCompilation=1
export COMPlus_TC_OnStackReplacement=1
export COMPlus_TC_QuickJitForLoops=1

  Starting:    System.Text.Json.Tests (parallel test collections = on, max threads = 2)
    System.Text.Json.Tests.Utf8JsonReaderTests.ReadJsonStringsWithCommentsAndTrailingCommas(jsonString: "{\"Property1\": {\"Property1.1\": 42} // comment\n"...) [FAIL]

Via COMPlus_JitEnablePatchpointRange I have isolated this down to

System.Text.Json.Tests.Utf8JsonReaderTests::ReadJsonStringsWithCommentsAndTrailingCommas, IL size = 399, hash=0xc1a3563b 
Tier1-OSR @0x159
@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.Text.Json untriaged New issue has not been triaged by the area owner labels Mar 25, 2022
@AndyAyersMS AndyAyersMS self-assigned this Mar 25, 2022
@ghost
Copy link

ghost commented Mar 25, 2022

Tagging subscribers to this area: @dotnet/area-system-text-json
See info in area-owners.md if you want to be subscribed.

Issue Details

x64 Ubuntu

export COMPlus_TieredCompilation=1
export COMPlus_TC_OnStackReplacement=1
export COMPlus_TC_QuickJitForLoops=1

  Starting:    System.Text.Json.Tests (parallel test collections = on, max threads = 2)
    System.Text.Json.Tests.Utf8JsonReaderTests.ReadJsonStringsWithCommentsAndTrailingCommas(jsonString: "{\"Property1\": {\"Property1.1\": 42} // comment\n"...) [FAIL]

Via COMPlus_JitEnablePatchpointRange I have isolated this down to

System.Text.Json.Tests.Utf8JsonReaderTests::ReadJsonStringsWithCommentsAndTrailingCommas, IL size = 399, hash=0xc1a3563b 
Tier1-OSR @0x159
Author: AndyAyersMS
Assignees: -
Labels:

area-System.Text.Json, untriaged

Milestone: -

@AndyAyersMS AndyAyersMS added area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI and removed area-System.Text.Json untriaged New issue has not been triaged by the area owner labels Mar 25, 2022
@AndyAyersMS AndyAyersMS added this to the 7.0.0 milestone Mar 25, 2022
@AndyAyersMS
Copy link
Member Author

AndyAyersMS commented Mar 26, 2022

Ok, I think I know what's going wrong.

We have an independently promoted struct with some byte sized fields. OSR decides it should live on the Tier0 frame. But elseswhere in the jit (notably LSRA) we assume independently promoted fields are register sized.

;  V57 tmp44        [V57,T28] (  2,  66   )     int  ->  [rbp+168H]   tier0-frame V05._maxDepth(offs=0x00) P-INDEP "field V05._maxDepth (fldOffset=0x0)"
;  V58 tmp45        [V58,T24] (  2,  66   )   ubyte  ->  [rbp+16CH]   tier0-frame V05._commentHandling(offs=0x04) P-INDEP "field V05._commentHandling (fldOffset=0x4)"
;  V59 tmp46        [V59,T29] (  2,  66   )    bool  ->  [rbp+16DH]   tier0-frame V05.<AllowTrailingCommas>k__BackingField(offs=0x05) P-INDEP "field V05.<AllowTrailingCommas>k__BackingField (fldOffset=0x5)"

We end up having to spill V58 and in so doing we clobber V59, which happens to be the part of JsonOptions that controls whether trailing commas are ok.

Generating: N001 (  2,  2) [002377] -----------Z      t2377 =    LCL_VAR   ubyte  V58 tmp45         r13 REG r13
IN0207:        mov      dword ptr [V58 rbp+16CH], r13d

and this clobber causes the errors we see at runtime.

Possible options for a fix:
(1) teach LSRA (and maybe more) that memory homes for LSRA local struct fields are not resized actual sized
(2) teach OSR that independently promoted fields do not live on the Tier0 frame, and update the prolog generation to copy from the Tier0 to the Tier1 stack slot when the promoted field is live on entry and not initially assigned to a register.
(3) Bail on independent promotion of OSR locals completely
(4) Don't allocate small independently promoted OSR locals (see below)

@AndyAyersMS
Copy link
Member Author

One possible workaround:

@@ -1536,6 +1536,13 @@ bool LinearScan::isRegCandidate(LclVarDsc* varDsc)
         return false;
     }
 
+    // Don't enregister small promoted struct fields for OSR locals.
+    //
+    if (varTypeIsSmall(varDsc->lvType) && varDsc->lvIsStructField && compiler->lvaIsOSRLocal(lclNum))
+    {
+        return false;
+    }
+

@AndyAyersMS
Copy link
Member Author

This bit of related code is confusing as the comment and code no longer match (consequence of #52039). We used to use the declared type for the local here, not the stack type. This widens the store to V58 from 8 to 32 bits, as seen above.

// In order for a lclVar to have been allocated to a register, it must not have been aliasable, and can
// therefore be store-normalized (rather than load-normalized). In fact, not performing store normalization
// can lead to problems on architectures where a lclVar may be allocated to a register that is not
// addressable at the granularity of the lclVar's defined type (e.g. x86).
var_types lclType = varDsc->GetActualRegisterType();
emitAttr size = emitTypeSize(lclType);

AndyAyersMS added a commit to AndyAyersMS/runtime that referenced this issue Mar 29, 2022
Fix two cases where small enregisterable locals can't be saved to the stack
using actual (widened) types:
* small memory args for OSX ARM64
* promoted fields of OSR locals

Closes dotnet#67152.
Closes dotnet#67188.
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Mar 29, 2022
AndyAyersMS added a commit that referenced this issue Mar 29, 2022
Fix two cases where small enregisterable locals can't be saved to the stack
using actual (widened) types:
* small memory args for OSX ARM64
* promoted fields of OSR locals

Closes #67152.
Closes #67188.
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Mar 29, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Apr 29, 2022
@jtschuster
Copy link
Member

Looks like this might have been hit again in rolling build 1874165, but it's on arm (net7.0-Linux-Release-arm-CoreCLR_checked-(Alpine.314.Arm32.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.14-helix-arm32v7-20210910135806-8a6f4f3).
Log

Starting:    System.Text.Json.Tests (parallel test collections = on, max threads = 4)
    System.Text.Json.Tests.Utf8JsonReaderTests.ReadJsonStringsWithComments(jsonString: "{\"Property1\": {\"Property1.1\": 42}, // comment\"...) [FAIL]
      System.InvalidOperationException : End position was not reached during enumeration.
      Stack Trace:
        /_/src/libraries/System.Memory/src/System/ThrowHelper.cs(43,0): at System.ThrowHelper.ThrowInvalidOperationException_EndPositionNotReached()
        /_/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.MultiSegment.cs(325,0): at System.Text.Json.Utf8JsonReader.GetNextSpan()
        /_/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.MultiSegment.cs(1561,0): at System.Text.Json.Utf8JsonReader.ConsumeNextTokenMultiSegment(Byte marker)
        /_/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.MultiSegment.cs(213,0): at System.Text.Json.Utf8JsonReader.ReadMultiSegment()
        /_/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.cs(285,0): at System.Text.Json.Utf8JsonReader.Read()
        /_/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Utf8JsonReaderTests.MultiSegment.cs(2096,0): at System.Text.Json.Tests.Utf8JsonReaderTests.ReadWithCommentsHelper(Utf8JsonReader& reader, Int32 expectedConsumed, Boolean validateThrows)
        /_/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Utf8JsonReaderTests.MultiSegment.cs(1989,0): at System.Text.Json.Tests.Utf8JsonReaderTests.ReadJsonStringsWithComments(String jsonString)
           at InvokeStub_Utf8JsonReaderTests.ReadJsonStringsWithComments(Object, Object, IntPtr*)
           at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

@jtschuster jtschuster reopened this Jul 12, 2022
@AndyAyersMS
Copy link
Member Author

There is no OSR for arm so it's likely a different issue.

@jtschuster
Copy link
Member

There is no OSR for arm so it's likely a different issue.

Made a new issue: #72100

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

2 participants