From 068d4d610c83dd7f41e5e9baf751313ee6745403 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Wed, 6 Apr 2022 18:32:33 -0700 Subject: [PATCH] JIT: fix OSR handling for pinned locals 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 8145cbcf2b6b67..081c64c2a4a987 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 00000000000000..5641b0e85c0671 --- /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 00000000000000..14804c23dba34d --- /dev/null +++ b/src/tests/JIT/opt/OSR/pinnedlocal.csproj @@ -0,0 +1,21 @@ + + + Exe + + True + True + + + + + + + + +