From c288acdb794b1f2edba90868a823b161d88bd2b0 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Thu, 7 Apr 2022 08:14:09 -0700 Subject: [PATCH] JIT: fix OSR handling for pinned locals (#67680) The OSR method may not see any references to the pinned local, but must still report it in the GC info. So under OSR, mark (root method) pinned locals as implicitly referenced. This should address the issue seen in #67688. --- src/coreclr/jit/lclvars.cpp | 8 +++++ src/tests/JIT/opt/OSR/pinnedlocal.cs | 37 ++++++++++++++++++++++++ src/tests/JIT/opt/OSR/pinnedlocal.csproj | 21 ++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 src/tests/JIT/opt/OSR/pinnedlocal.cs create mode 100644 src/tests/JIT/opt/OSR/pinnedlocal.csproj diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index ed777b0316dfd..d2996f4b12f47 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -289,6 +289,14 @@ void Compiler::lvaInitTypeRef() { JITDUMP("Setting lvPinned for V%02u\n", varNum); varDsc->lvPinned = 1; + + if (opts.IsOSR()) + { + // OSR method may not see any references to the pinned local, + // but must still report it in GC info. + // + varDsc->lvImplicitlyReferenced = 1; + } } else { diff --git a/src/tests/JIT/opt/OSR/pinnedlocal.cs b/src/tests/JIT/opt/OSR/pinnedlocal.cs new file mode 100644 index 0000000000000..5641b0e85c067 --- /dev/null +++ b/src/tests/JIT/opt/OSR/pinnedlocal.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +// Run under COMPlus_GCStress=3 + +class PinnedLocal +{ + static int F(char c) + { + return (int) c; + } + + public static unsafe int Main() + { + string ss = "goodbye, world\n"; + string s = "hello, world\n"; + int r = 0; + fixed(char* p = s) + { + for (int i = 0; i < 100_000; i++) + { + r += F(p[i % s.Length]); + + if ((i % 10_000) == 0) + { + GC.Collect(2); + ss = new String('a', 100); + } + } + + Console.WriteLine($"r is {r}"); + return r - 9000061 + 100; + } + } +} diff --git a/src/tests/JIT/opt/OSR/pinnedlocal.csproj b/src/tests/JIT/opt/OSR/pinnedlocal.csproj new file mode 100644 index 0000000000000..14804c23dba34 --- /dev/null +++ b/src/tests/JIT/opt/OSR/pinnedlocal.csproj @@ -0,0 +1,21 @@ + + + Exe + + True + True + + + + + + + + +