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
4 changes: 4 additions & 0 deletions src/coreclr/jit/gcencode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4187,7 +4187,11 @@ void GCInfo::gcMakeRegPtrTable(
flags = (GcSlotFlags)(flags | GC_SLOT_INTERIOR);
}

// Per the wasm ABI refs homed on the linear stack are reported pinned, since copies of them
// on the wasm operand stack are invisible to the GC. See "GC References at Call Sites".
#ifndef TARGET_WASM
if (varDsc->lvPinned)
#endif // !TARGET_WASM
Comment thread
lewing marked this conversation as resolved.
{
// Or in pinned_OFFSET_FLAG for 'pinned' pointer tracking
flags = (GcSlotFlags)(flags | GC_SLOT_PINNED);
Expand Down
55 changes: 55 additions & 0 deletions src/tests/JIT/Regression/JitBlue/Runtime_131373/Runtime_131373.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

// A GC ref pushed onto the wasm operand stack is a copy the GC can't update, so it goes stale
// when a call relocates the referent. Only reproduces under crossgen wasm R2R (TargetOS=browser).

using System;
using System.Runtime.CompilerServices;
using Xunit;

public class Runtime_131373
{
public sealed class Box
{
public object Slot;
public int Tag;
}

[Fact]
public static void TestEntryPoint()
{
for (int i = 0; i < 400; i++)
{
for (int j = 0; j < 32; j++)
{
byte[] garbage = new byte[8192];
GC.KeepAlive(garbage);
}

Box box = new Box { Tag = i };
StoreThroughByref(ref box.Slot, i);
Assert.NotNull(box.Slot);
}
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static void StoreThroughByref(ref object slot, int i)
{
slot = Allocate(i);
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static object Allocate(int i)
{
for (int j = 0; j < 48; j++)
{
byte[] garbage = new byte[8192];
GC.KeepAlive(garbage);
}

GC.Collect(2, GCCollectionMode.Forced, blocking: true, compacting: true);

return new string('x', 1 + (i & 7));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Optimize>True</Optimize>
<!-- Force crossgen on the browser leg so this actually runs as wasm R2R. -->
<AlwaysUseCrossGen2 Condition="'$(TargetOS)' == 'browser'">true</AlwaysUseCrossGen2>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
</ItemGroup>
</Project>
Loading