Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions src/coreclr/jit/morph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6417,16 +6417,6 @@ GenTree* Compiler::fgMorphCall(GenTreeCall* call)

// Couldn't inline - remember that this BB contains method calls

// Mark the block as a GC safe point for the call if possible.
// In the event the call indicates the block isn't a GC safe point
// and the call is unmanaged with a GC transition suppression request
// then insert a GC poll.

if (IsGcSafePoint(call))
{
compCurBB->SetFlags(BBF_GC_SAFE_POINT);
}

// Regardless of the state of the basic block with respect to GC safe point,
// we will always insert a GC Poll for scenarios involving a suppressed GC
// transition. Only mark the block for GC Poll insertion on the first morph.
Expand Down Expand Up @@ -6573,6 +6563,13 @@ GenTree* Compiler::fgMorphCall(GenTreeCall* call)
}
}

// Mark the block as a GC safe point for the call if possible. This is done after the
// stelem.ref handling above, which may remove the call or convert it to a helper call.
if (IsGcSafePoint(call))
{
compCurBB->SetFlags(BBF_GC_SAFE_POINT);
}

if (call->IsNoReturn())
{
//
Expand Down
50 changes: 50 additions & 0 deletions src/tests/JIT/Regression_ro_2/Runtime_134894.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Runtime.CompilerServices;
using System.Threading;
using TestLibrary;
using Xunit;

public class Runtime_134894
{
private static volatile bool s_started;
private static volatile bool s_stop;
private static int s_x;

[MethodImpl(MethodImplOptions.AggressiveInlining)] private static void F6() { s_x++; }
[MethodImpl(MethodImplOptions.AggressiveInlining)] private static void F5() { F6(); F6(); F6(); F6(); }
[MethodImpl(MethodImplOptions.AggressiveInlining)] private static void F4() { F5(); F5(); F5(); F5(); }
[MethodImpl(MethodImplOptions.AggressiveInlining)] private static void F3() { F4(); F4(); F4(); F4(); }
[MethodImpl(MethodImplOptions.AggressiveInlining)] private static void F2() { F3(); F3(); F3(); F3(); }

// Exhausts the inline budget, so StelemRef can't be inlined
private static void F1() => F2();

[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
private static void Test(object[] arr, int i)
{
F1();
s_started = true;
while (!s_stop)
{
object o = null;
arr[i] = o;
}
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsMultithreadingSupported))]
public static void TestEntryPoint()
{
var t = new Thread(() => Test(new string[10], 1)) { IsBackground = true };
t.Start();
while (!s_started) { }
Thread.Sleep(100);

// Hangs if the loop in Test has no GC safe point
GC.Collect();
s_stop = true;
t.Join();
}
}
Loading