Skip to content

Commit 5925e65

Browse files
authored
Adding SetGcNotification API and related runtime simplification (#120083)
* Adding SetGcNotifications cDAC API
1 parent d3ffc5f commit 5925e65

File tree

18 files changed

+193
-325
lines changed

18 files changed

+193
-325
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Contract Notifications
2+
3+
This contract is for debugger notifications.
4+
5+
## APIs of contract
6+
7+
``` csharp
8+
// Set the GC notification for condemned generations
9+
// The argument is a bitmask where the i-th bit set represents the i-th generation.
10+
void SetGcNotification(int condemnedGeneration);
11+
```
12+
13+
## Version 1
14+
15+
Data descriptors used: none
16+
17+
Global variables used:
18+
| Global Name | Type | Purpose |
19+
| --- | --- | --- |
20+
| `GcNotificationFlags` | TargetPointer | Global flag for storing GC notification data |
21+
22+
Contracts used: none
23+
24+
``` csharp
25+
void SetGcNotification(int condemnedGeneration)
26+
{
27+
TargetPointer pGcNotificationFlags = _target.ReadGlobalPointer("GcNotificationFlags");
28+
uint currentFlags = _target.Read<uint>(pGcNotificationFlags);
29+
if (condemnedGeneration == 0)
30+
_target.Write<uint>(pGcNotificationFlags, 0);
31+
else
32+
{
33+
_target.Write<uint>(pGcNotificationFlags, (uint)(currentFlags | condemnedGeneration));
34+
}
35+
}
36+
```

src/coreclr/debug/daccess/daccess.cpp

Lines changed: 4 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3103,7 +3103,6 @@ ClrDataAccess::ClrDataAccess(ICorDebugDataTarget * pTarget, ICLRDataTarget * pLe
31033103
m_logMessageCb = NULL;
31043104
m_enumMemFlags = (CLRDataEnumMemoryFlags)-1; // invalid
31053105
m_jitNotificationTable = NULL;
3106-
m_gcNotificationTable = NULL;
31073106

31083107
#ifdef FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
31093108
m_streams = NULL;
@@ -5326,31 +5325,8 @@ ClrDataAccess::GetGcNotification(GcEvtArgs* gcEvtArgs)
53265325

53275326
EX_TRY
53285327
{
5329-
if (gcEvtArgs->typ >= GC_EVENT_TYPE_MAX)
5330-
{
5331-
status = E_INVALIDARG;
5332-
}
5333-
else
5334-
{
5335-
GcNotifications gn(GetHostGcNotificationTable());
5336-
if (!gn.IsActive())
5337-
{
5338-
status = E_OUTOFMEMORY;
5339-
}
5340-
else
5341-
{
5342-
GcEvtArgs *res = gn.GetNotification(*gcEvtArgs);
5343-
if (res != NULL)
5344-
{
5345-
*gcEvtArgs = *res;
5346-
status = S_OK;
5347-
}
5348-
else
5349-
{
5350-
status = E_FAIL;
5351-
}
5352-
}
5353-
}
5328+
// XXX Microsoft.
5329+
status = E_NOTIMPL;
53545330
}
53555331
EX_CATCH
53565332
{
@@ -5380,22 +5356,8 @@ ClrDataAccess::SetGcNotification(IN GcEvtArgs gcEvtArgs)
53805356
}
53815357
else
53825358
{
5383-
GcNotifications gn(GetHostGcNotificationTable());
5384-
if (!gn.IsActive())
5385-
{
5386-
status = E_OUTOFMEMORY;
5387-
}
5388-
else
5389-
{
5390-
if (gn.SetNotification(gcEvtArgs) && gn.UpdateOutOfProcTable())
5391-
{
5392-
status = S_OK;
5393-
}
5394-
else
5395-
{
5396-
status = E_FAIL;
5397-
}
5398-
}
5359+
GcNotifications::SetNotification(gcEvtArgs);
5360+
status = S_OK;
53995361
}
54005362
}
54015363
EX_CATCH
@@ -6398,18 +6360,6 @@ ClrDataAccess::GetHostJitNotificationTable()
63986360
return m_jitNotificationTable;
63996361
}
64006362

6401-
GcNotification*
6402-
ClrDataAccess::GetHostGcNotificationTable()
6403-
{
6404-
if (m_gcNotificationTable == NULL)
6405-
{
6406-
m_gcNotificationTable =
6407-
GcNotifications::InitializeNotificationTable(128);
6408-
}
6409-
6410-
return m_gcNotificationTable;
6411-
}
6412-
64136363
/* static */ bool
64146364
ClrDataAccess::GetMetaDataFileInfoFromPEFile(PEAssembly *pPEAssembly,
64156365
DWORD &dwTimeStamp,

src/coreclr/debug/daccess/dacimpl.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,7 +1356,6 @@ class ClrDataAccess
13561356

13571357
void ClearDumpStats();
13581358
JITNotification* GetHostJitNotificationTable();
1359-
GcNotification* GetHostGcNotificationTable();
13601359

13611360
void* GetMetaDataFromHost(PEAssembly* pPEAssembly);
13621361

@@ -1471,7 +1470,6 @@ class ClrDataAccess
14711470
ICLRDataLoggingCallback* m_logMessageCb;
14721471
CLRDataEnumMemoryFlags m_enumMemFlags;
14731472
JITNotification* m_jitNotificationTable;
1474-
GcNotification* m_gcNotificationTable;
14751473
TSIZE_T m_cbMemoryReported;
14761474
DumpMemoryReportStatics m_dumpStats;
14771475

src/coreclr/inc/dacvars.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ DEFINE_DACVAR(BOOL, CodeVersionManager__s_HasNonDefaultILVersions, CodeVersionMa
132132

133133
DEFINE_DACVAR(PTR_JITNotification, dac__g_pNotificationTable, ::g_pNotificationTable)
134134
DEFINE_DACVAR(ULONG32, dac__g_dacNotificationFlags, ::g_dacNotificationFlags)
135-
DEFINE_DACVAR(PTR_GcNotification, dac__g_pGcNotificationTable, ::g_pGcNotificationTable)
135+
136+
DEFINE_DACVAR(DWORD, dac__g_gcNotificationFlags, g_gcNotificationFlags)
136137

137138
DEFINE_DACVAR(PTR_EEConfig, dac__g_pConfig, ::g_pConfig)
138139

src/coreclr/vm/datadescriptor/datadescriptor.inc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,7 @@ CDAC_GLOBAL_POINTER(MiniMetaDataBuffMaxSize, &::g_MiniMetaDataBuffMaxSize)
10251025
CDAC_GLOBAL_POINTER(DacNotificationFlags, &::g_dacNotificationFlags)
10261026
CDAC_GLOBAL_POINTER(OffsetOfCurrentThreadInfo, &::g_offsetOfCurrentThreadInfo)
10271027
CDAC_GLOBAL_POINTER(ThinlockThreadIdDispenser, &::g_pThinLockThreadIdDispenser)
1028+
CDAC_GLOBAL_POINTER(GcNotificationFlags, &::g_gcNotificationFlags)
10281029
CDAC_GLOBAL_POINTER(CoreLib, &::g_CoreLib)
10291030
#ifdef TARGET_WINDOWS
10301031
CDAC_GLOBAL_POINTER(TlsIndexBase, &::_tls_index)
@@ -1060,6 +1061,7 @@ CDAC_GLOBAL_CONTRACT(EcmaMetadata, 1)
10601061
CDAC_GLOBAL_CONTRACT(Exception, 1)
10611062
CDAC_GLOBAL_CONTRACT(ExecutionManager, 2)
10621063
CDAC_GLOBAL_CONTRACT(Loader, 1)
1064+
CDAC_GLOBAL_CONTRACT(Notifications, 1)
10631065
CDAC_GLOBAL_CONTRACT(Object, 1)
10641066
CDAC_GLOBAL_CONTRACT(PlatformMetadata, 1)
10651067
CDAC_GLOBAL_CONTRACT(PrecodeStubs, 3)

src/coreclr/vm/gcenv.ee.cpp

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,18 +1724,8 @@ bool GCToEEInterface::AnalyzeSurvivorsRequested(int condemnedGeneration)
17241724
analysisTimer.Start();
17251725
}
17261726

1727-
// Is the list active?
1728-
GcNotifications gn(g_pGcNotificationTable);
1729-
if (gn.IsActive())
1730-
{
1731-
GcEvtArgs gea = { GC_MARK_END, { (1<<condemnedGeneration) } };
1732-
if (gn.GetNotification(gea) != 0)
1733-
{
1734-
return true;
1735-
}
1736-
}
1737-
1738-
return false;
1727+
GcEvtArgs gea = { GC_MARK_END, { (1<<condemnedGeneration) } };
1728+
return GcNotifications::GetNotification(gea);
17391729
}
17401730

17411731
void GCToEEInterface::AnalyzeSurvivorsFinished(size_t gcIndex, int condemnedGeneration, uint64_t promoted_bytes, void (*reportGenerationBounds)())
@@ -1749,15 +1739,10 @@ void GCToEEInterface::AnalyzeSurvivorsFinished(size_t gcIndex, int condemnedGene
17491739
elapsed = analysisTimer.Elapsed100nsTicks();
17501740
}
17511741

1752-
// Is the list active?
1753-
GcNotifications gn(g_pGcNotificationTable);
1754-
if (gn.IsActive())
1742+
GcEvtArgs gea = { GC_MARK_END, { (1<<condemnedGeneration) } };
1743+
if (GcNotifications::GetNotification(gea))
17551744
{
1756-
GcEvtArgs gea = { GC_MARK_END, { (1<<condemnedGeneration) } };
1757-
if (gn.GetNotification(gea) != 0)
1758-
{
1759-
DACNotify::DoGCNotification(gea);
1760-
}
1745+
DACNotify::DoGCNotification(gea);
17611746
}
17621747

17631748
if (gcGenAnalysisState == GcGenAnalysisState::Enabled)

src/coreclr/vm/util.cpp

Lines changed: 28 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,33 @@ BOOL CLRFreeLibrary(HMODULE hModule)
10161016

10171017

10181018
#endif // #ifndef DACCESS_COMPILE
1019+
namespace GcNotifications
1020+
{
1021+
VOID SetNotification(GcEvtArgs ev)
1022+
{
1023+
LIMITED_METHOD_CONTRACT;
1024+
if (ev.typ == GC_MARK_END)
1025+
{
1026+
if (ev.condemnedGeneration == 0)
1027+
g_gcNotificationFlags = 0;
1028+
else
1029+
g_gcNotificationFlags = (DWORD)(g_gcNotificationFlags | ev.condemnedGeneration);
1030+
}
1031+
}
1032+
BOOL GetNotification(GcEvtArgs ev)
1033+
{
1034+
LIMITED_METHOD_CONTRACT;
1035+
// check to see if we have a notification for this generation
1036+
if (ev.typ == GC_MARK_END && (ev.condemnedGeneration == 0 || (g_gcNotificationFlags & ev.condemnedGeneration) != 0))
1037+
{
1038+
return TRUE;
1039+
}
1040+
else
1041+
{
1042+
return FALSE;
1043+
}
1044+
}
1045+
};
10191046

10201047
GPTR_IMPL(JITNotification, g_pNotificationTable);
10211048
GVAL_IMPL(ULONG32, g_dacNotificationFlags);
@@ -1320,155 +1347,10 @@ BOOL JITNotifications::UpdateOutOfProcTable()
13201347
}
13211348
#endif // DACCESS_COMPILE
13221349

1323-
GPTR_IMPL(GcNotification, g_pGcNotificationTable);
1324-
1325-
GcNotifications::GcNotifications(GcNotification *gcTable)
1326-
{
1327-
LIMITED_METHOD_CONTRACT;
1328-
if (gcTable)
1329-
{
1330-
// Bookkeeping info is held in the first slot
1331-
m_gcTable = gcTable + 1;
1332-
}
1333-
else
1334-
{
1335-
m_gcTable = NULL;
1336-
}
1337-
}
1338-
1339-
BOOL GcNotifications::FindItem(GcEvtArgs ev_, UINT *indexOut)
1340-
{
1341-
LIMITED_METHOD_CONTRACT;
1342-
if (m_gcTable == NULL)
1343-
{
1344-
return FALSE;
1345-
}
1346-
1347-
if (indexOut == NULL)
1348-
{
1349-
return FALSE;
1350-
}
1351-
1352-
UINT length = Length();
1353-
for (UINT i = 0; i < length; i++)
1354-
{
1355-
if (m_gcTable[i].IsMatch(ev_))
1356-
{
1357-
*indexOut = i;
1358-
return TRUE;
1359-
}
1360-
}
1361-
1362-
return FALSE;
1363-
}
1364-
1365-
1366-
BOOL GcNotifications::SetNotification(GcEvtArgs ev)
1367-
{
1368-
if (!IsActive())
1369-
{
1370-
return FALSE;
1371-
}
1372-
1373-
if (ev.typ < 0 || ev.typ >= GC_EVENT_TYPE_MAX)
1374-
{
1375-
return FALSE;
1376-
}
1377-
1378-
// build the "match" event
1379-
GcEvtArgs evStar = { ev.typ };
1380-
switch (ev.typ)
1381-
{
1382-
case GC_MARK_END:
1383-
// specify mark event matching all generations
1384-
evStar.condemnedGeneration = -1;
1385-
break;
1386-
default:
1387-
break;
1388-
}
1389-
1390-
// look for the entry that matches the evStar argument
1391-
UINT idx;
1392-
if (!FindItem(evStar, &idx))
1393-
{
1394-
// Find first free item
1395-
UINT iFirstFree = Length();
1396-
for (UINT i = 0; i < iFirstFree; i++)
1397-
{
1398-
GcNotification *pCurrent = m_gcTable + i;
1399-
if (pCurrent->IsFree())
1400-
{
1401-
iFirstFree = i;
1402-
break;
1403-
}
1404-
}
1405-
1406-
if (iFirstFree == Length() &&
1407-
iFirstFree == GetTableSize())
1408-
{
1409-
// No more room
1410-
return FALSE;
1411-
}
1412-
1413-
// guarantee the free cell is zeroed out
1414-
m_gcTable[iFirstFree].SetFree();
1415-
idx = iFirstFree;
1416-
}
1417-
1418-
// Now update the state
1419-
m_gcTable[idx].ev.typ = ev.typ;
1420-
switch (ev.typ)
1421-
{
1422-
case GC_MARK_END:
1423-
if (ev.condemnedGeneration == 0)
1424-
{
1425-
m_gcTable[idx].SetFree();
1426-
}
1427-
else
1428-
{
1429-
m_gcTable[idx].ev.condemnedGeneration |= ev.condemnedGeneration;
1430-
}
1431-
break;
1432-
default:
1433-
break;
1434-
}
1435-
1436-
// and if needed, update the array's length
1437-
if (idx == Length())
1438-
{
1439-
IncrementLength();
1440-
}
1441-
1442-
return TRUE;
1443-
}
14441350

14451351
GARY_IMPL(size_t, g_clrNotificationArguments, MAX_CLR_NOTIFICATION_ARGS);
14461352

1447-
#ifdef DACCESS_COMPILE
1448-
1449-
GcNotification *GcNotifications::InitializeNotificationTable(UINT TableSize)
1450-
{
1451-
// We use the first entry in the table for recordkeeping info.
1452-
1453-
GcNotification *retTable = new (nothrow) GcNotification[TableSize+1];
1454-
if (retTable)
1455-
{
1456-
// Set the length
1457-
UINT *pUint = (UINT *) &(retTable[0].ev.typ);
1458-
*pUint = 0;
1459-
// Set the table size
1460-
++pUint;
1461-
*pUint = TableSize;
1462-
}
1463-
return retTable;
1464-
}
1465-
1466-
BOOL GcNotifications::UpdateOutOfProcTable()
1467-
{
1468-
return ::UpdateOutOfProcTable<GcNotification>(g_pGcNotificationTable, m_gcTable - 1, GetTableSize() + 1);
1469-
}
1470-
1471-
#else // DACCESS_COMPILE
1353+
#ifndef DACCESS_COMPILE
14721354

14731355
static CrstStatic g_clrNotificationCrst;
14741356

0 commit comments

Comments
 (0)