Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 77f64aa

Browse files
Revert removal of SuppressGCTransition from SystemNative_GetTimestamp() (#27473)
* Revert removal of SuppressGCTransition from SystemNative_GetTimestamp() * Insert GC_POLL before statement with unmanaged call. * JIT test for insertion of GCPoll
1 parent 80867d1 commit 77f64aa

File tree

8 files changed

+213
-6
lines changed

8 files changed

+213
-6
lines changed

src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetTimestamp.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ internal static partial class Sys
1212
internal static extern ulong GetTimestampResolution();
1313

1414
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetTimestamp", ExactSpelling = true)]
15-
// [SuppressGCTransition] // https://github.com/dotnet/coreclr/issues/27465
15+
[SuppressGCTransition]
1616
internal static extern ulong GetTimestamp();
1717
}
1818
}

src/jit/compiler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4827,7 +4827,7 @@ class Compiler
48274827
bool fgGCPollsCreated;
48284828
void fgMarkGCPollBlocks();
48294829
void fgCreateGCPolls();
4830-
bool fgCreateGCPoll(GCPollType pollType, BasicBlock* block);
4830+
bool fgCreateGCPoll(GCPollType pollType, BasicBlock* block, Statement* stmt = nullptr);
48314831

48324832
// Requires that "block" is a block that returns from
48334833
// a finally. Returns the number of successors (jump targets of

src/jit/flowgraph.cpp

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3858,7 +3858,7 @@ void Compiler::fgCreateGCPolls()
38583858
* a basic block.
38593859
*/
38603860

3861-
bool Compiler::fgCreateGCPoll(GCPollType pollType, BasicBlock* block)
3861+
bool Compiler::fgCreateGCPoll(GCPollType pollType, BasicBlock* block, Statement* stmt)
38623862
{
38633863
bool createdPollBlocks;
38643864

@@ -3883,15 +3883,44 @@ bool Compiler::fgCreateGCPoll(GCPollType pollType, BasicBlock* block)
38833883
pollType = GCPOLL_CALL;
38843884
}
38853885

3886+
#ifdef DEBUG
3887+
// If a statment was supplied it should be contained in the block.
3888+
if (stmt != nullptr)
3889+
{
3890+
bool containsStmt = false;
3891+
for (Statement* stmtMaybe : block->Statements())
3892+
{
3893+
containsStmt = (stmtMaybe == stmt);
3894+
if (containsStmt)
3895+
{
3896+
break;
3897+
}
3898+
}
3899+
3900+
assert(containsStmt);
3901+
}
3902+
#endif
3903+
38863904
if (GCPOLL_CALL == pollType)
38873905
{
38883906
createdPollBlocks = false;
38893907
GenTreeCall* call = gtNewHelperCallNode(CORINFO_HELP_POLL_GC, TYP_VOID);
38903908
GenTree* temp = fgMorphCall(call);
38913909

3892-
// for BBJ_ALWAYS I don't need to insert it before the condition. Just append it.
3893-
if (block->bbJumpKind == BBJ_ALWAYS)
3910+
if (stmt != nullptr)
3911+
{
3912+
// The GC_POLL should be inserted relative to the supplied statement. The safer
3913+
// location for the insertion is prior to the current statement since the supplied
3914+
// statement could be a GT_JTRUE (see fgNewStmtNearEnd() for more details).
3915+
Statement* newStmt = gtNewStmt(temp);
3916+
3917+
// Set the GC_POLL statement to have the same IL offset at the subsequent one.
3918+
newStmt->SetILOffsetX(stmt->GetILOffsetX());
3919+
fgInsertStmtBefore(block, stmt, newStmt);
3920+
}
3921+
else if (block->bbJumpKind == BBJ_ALWAYS)
38943922
{
3923+
// for BBJ_ALWAYS I don't need to insert it before the condition. Just append it.
38953924
fgNewStmtAtEnd(block, temp);
38963925
}
38973926
else

src/jit/morph.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8220,7 +8220,7 @@ GenTree* Compiler::fgMorphCall(GenTreeCall* call)
82208220
if (fgGlobalMorph && call->IsUnmanaged() && call->IsSuppressGCTransition())
82218221
{
82228222
// Insert a GC poll.
8223-
bool insertedBB = fgCreateGCPoll(GCPOLL_CALL, compCurBB);
8223+
bool insertedBB = fgCreateGCPoll(GCPOLL_CALL, compCurBB, compCurStmt);
82248224
assert(!insertedBB); // No new block should be inserted
82258225
}
82268226

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
cmake_minimum_required (VERSION 2.6)
2+
project (GCPollNative)
3+
4+
set(SOURCES
5+
GCPollNative.cpp
6+
)
7+
8+
add_library (GCPollNative SHARED ${SOURCES})
9+
10+
# add the install targets
11+
install (TARGETS GCPollNative DESTINATION bin)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
#include <cstdio>
6+
#include <cstdint>
7+
#include <atomic>
8+
9+
#if defined(_MSC_VER)
10+
11+
#define STDMETHODCALLTYPE __stdcall
12+
#define EXPORT(type) extern "C" type __declspec(dllexport)
13+
14+
#else // !defined(_MSC_VER)
15+
16+
#ifdef __i386__
17+
#define STDMETHODCALLTYPE __attribute__((stdcall))
18+
#else
19+
#define STDMETHODCALLTYPE
20+
#endif
21+
#define EXPORT(type) extern "C" __attribute__((visibility("default"))) type
22+
23+
#endif // defined(_MSC_VER)
24+
25+
namespace
26+
{
27+
std::atomic<uint64_t> _n{ 0 };
28+
29+
template<typename T>
30+
T NextUInt(T t)
31+
{
32+
return (T)((++_n) + t);
33+
}
34+
}
35+
36+
EXPORT(uint32_t) STDMETHODCALLTYPE NextUInt32(uint32_t t)
37+
{
38+
return NextUInt(t);
39+
}
40+
41+
EXPORT(uint64_t) STDMETHODCALLTYPE NextUInt64(uint64_t t)
42+
{
43+
return NextUInt(t);
44+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Runtime.InteropServices;
7+
8+
static class GCPollNative
9+
{
10+
// Simple function that can be marked as SuppressGCTransition which will
11+
// result in a GCPoll insertion.
12+
[DllImport(nameof(GCPollNative))]
13+
[SuppressGCTransition]
14+
public static extern uint NextUInt32(uint n);
15+
16+
// Simple function that can be marked as SuppressGCTransition which will
17+
// result in a GCPoll insertion.
18+
[DllImport(nameof(GCPollNative))]
19+
[SuppressGCTransition]
20+
public static extern ulong NextUInt64(ulong n);
21+
}
22+
23+
class InsertGCPoll
24+
{
25+
private static int PropNextInt32 => (int)GCPollNative.NextUInt32(0);
26+
private static long PropNextInt64 => (long)GCPollNative.NextUInt64(0);
27+
28+
private static void AccessAsProperty32()
29+
{
30+
int a = PropNextInt32;
31+
int b = PropNextInt32;
32+
DisplayValues(a, b);
33+
}
34+
35+
private static void AccessAsProperty64()
36+
{
37+
long a = PropNextInt64;
38+
long b = PropNextInt64;
39+
DisplayValues(a, b);
40+
}
41+
42+
private static void DisplayValues<T>(T a, T b)
43+
{
44+
Console.WriteLine($"{a} {b}");
45+
}
46+
47+
private static void BranchOnProperty32()
48+
{
49+
if (-1 == PropNextInt32)
50+
{
51+
Console.WriteLine("");
52+
}
53+
}
54+
55+
private static void BranchOnProperty64()
56+
{
57+
if (-1 == PropNextInt64)
58+
{
59+
Console.WriteLine("");
60+
}
61+
}
62+
63+
private static void CompoundStatementBranchOnProperty()
64+
{
65+
if (-1 == (PropNextInt64 + PropNextInt32 - PropNextInt64 + PropNextInt64 - PropNextInt32))
66+
{
67+
Console.WriteLine("");
68+
}
69+
}
70+
71+
private static void LoopOn32()
72+
{
73+
uint i = 0;
74+
for (int j = 0; j < 10 || i < 32; ++j)
75+
{
76+
i += GCPollNative.NextUInt32(1);
77+
}
78+
}
79+
80+
private static void LoopOn64()
81+
{
82+
ulong i = 0;
83+
for (int j = 0; j < 10 || i < 32; ++j)
84+
{
85+
i += GCPollNative.NextUInt64(1);
86+
}
87+
}
88+
89+
public static int Main()
90+
{
91+
try
92+
{
93+
AccessAsProperty32();
94+
AccessAsProperty64();
95+
BranchOnProperty32();
96+
BranchOnProperty64();
97+
CompoundStatementBranchOnProperty();
98+
LoopOn32();
99+
LoopOn64();
100+
}
101+
catch (Exception e)
102+
{
103+
Console.WriteLine(e.ToString());
104+
return 101;
105+
}
106+
return 100;
107+
}
108+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
5+
</PropertyGroup>
6+
<PropertyGroup>
7+
<Optimize>True</Optimize>
8+
</PropertyGroup>
9+
<ItemGroup>
10+
<Compile Include="InsertGCPoll.cs" />
11+
</ItemGroup>
12+
<ItemGroup>
13+
<ProjectReference Include="CMakeLists.txt" />
14+
</ItemGroup>
15+
</Project>

0 commit comments

Comments
 (0)