Skip to content

Commit 749340b

Browse files
authored
Migrate interpreter stack maps to InterpCompiler and use them in place of CORINFO_FLG_CONTAINS_GC_PTR (#118860)
* Use GetInterpreterStackMap to determine whether a class actually contains any refs * Keep a unique stackmap hashtable per InterpCompiler instance that is owned by the compiler * Add dtor to InterpreterStackMap that frees slots if present * Add optional ValueDestroyCallback ctor arg to dn_simdhash_ptr_ptr_holder
1 parent 1f4a061 commit 749340b

File tree

6 files changed

+55
-32
lines changed

6 files changed

+55
-32
lines changed

src/coreclr/interpreter/compiler.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,7 +1078,7 @@ void InterpCompiler::BuildGCInfo(InterpMethod *pInterpMethod)
10781078
break;
10791079
case InterpTypeVT:
10801080
{
1081-
InterpreterStackMap *stackMap = GetInterpreterStackMap(m_compHnd, pVar->clsHnd);
1081+
InterpreterStackMap *stackMap = GetInterpreterStackMap(pVar->clsHnd);
10821082
for (unsigned j = 0; j < stackMap->m_slotCount; j++)
10831083
{
10841084
InterpreterStackMapSlot slotInfo = stackMap->m_slots[j];
@@ -1232,9 +1232,26 @@ int32_t* InterpCompiler::GetCode(int32_t *pCodeSize)
12321232
return m_pMethodCode;
12331233
}
12341234

1235+
InterpreterStackMap* InterpCompiler::GetInterpreterStackMap(CORINFO_CLASS_HANDLE classHandle)
1236+
{
1237+
InterpreterStackMap* result = nullptr;
1238+
if (!dn_simdhash_ptr_ptr_try_get_value(m_stackmapsByClass.GetValue(), classHandle, (void **)&result))
1239+
{
1240+
result = new InterpreterStackMap(m_compHnd, classHandle);
1241+
checkAddedNew(dn_simdhash_ptr_ptr_try_add(m_stackmapsByClass.GetValue(), classHandle, result));
1242+
}
1243+
return result;
1244+
}
1245+
1246+
static void FreeInterpreterStackMap(void *key, void *value, void *userdata)
1247+
{
1248+
delete (InterpreterStackMap *)value;
1249+
}
1250+
12351251
InterpCompiler::InterpCompiler(COMP_HANDLE compHnd,
12361252
CORINFO_METHOD_INFO* methodInfo)
1237-
: m_pInitLocalsIns(nullptr)
1253+
: m_stackmapsByClass(FreeInterpreterStackMap)
1254+
, m_pInitLocalsIns(nullptr)
12381255
, m_globalVarsWithRefsStackTop(0)
12391256
{
12401257
m_genericLookupToDataItemIndex.Init(&m_dataItems, this);
@@ -3220,7 +3237,7 @@ void InterpCompiler::EmitStind(InterpType interpType, CORINFO_CLASS_HANDLE clsHn
32203237
// or in the reverse order if the flag is set
32213238
if (interpType == InterpTypeVT)
32223239
{
3223-
if (m_compHnd->getClassAttribs(clsHnd) & CORINFO_FLG_CONTAINS_GC_PTR)
3240+
if (GetInterpreterStackMap(clsHnd)->m_slotCount)
32243241
{
32253242
AddIns(INTOP_STIND_VT);
32263243
m_pLastNewIns->data[1] = GetDataItemIndex(clsHnd);
@@ -6048,7 +6065,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
60486065
case InterpTypeVT:
60496066
{
60506067
int size = m_compHnd->getClassSize(elemClsHnd);
6051-
bool hasRefs = (m_compHnd->getClassAttribs(elemClsHnd) & CORINFO_FLG_CONTAINS_GC_PTR) != 0;
6068+
bool hasRefs = GetInterpreterStackMap(elemClsHnd)->m_slotCount > 0;
60526069
m_pStackPointer -= 3;
60536070
if (hasRefs)
60546071
{

src/coreclr/interpreter/compiler.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct InterpException
2424
const CorJitResult m_result;
2525
};
2626

27+
class InterpreterStackMap;
2728
class InterpCompiler;
2829

2930
class InterpDataItemIndexMap
@@ -501,6 +502,9 @@ class InterpCompiler
501502
void PrintNameInPointerMap(void* ptr);
502503
#endif // DEBUG
503504

505+
dn_simdhash_ptr_ptr_holder m_stackmapsByClass;
506+
InterpreterStackMap* GetInterpreterStackMap(CORINFO_CLASS_HANDLE classHandle);
507+
504508
static int32_t InterpGetMovForType(InterpType interpType, bool signExtend);
505509

506510
uint8_t* m_ip;

src/coreclr/interpreter/compileropt.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33
#include "interpreter.h"
4+
#include "stackmap.h"
45

56
// Allocates the offset for var at the stack position identified by
67
// *pPos while bumping the pointer to point to the next stack location
@@ -269,7 +270,7 @@ void InterpCompiler::AllocOffsets()
269270

270271
int32_t opcode = InterpGetMovForType(m_pVars[newVar].interpType, false);
271272
InterpInst *newInst = InsertInsBB(pBB, pIns->pPrev, opcode);
272-
// The InsertInsBB assigns m_currentILOffset to ins->ilOffset, which is incorrect for
273+
// The InsertInsBB assigns m_currentILOffset to ins->ilOffset, which is incorrect for
273274
// instructions injected here. Copy the ilOffset from the call instruction instead.
274275
newInst->ilOffset = pIns->ilOffset;
275276

@@ -421,7 +422,7 @@ void InterpCompiler::AllocOffsets()
421422
(pVar->interpType == InterpTypeByRef) ||
422423
(
423424
(pVar->interpType == InterpTypeVT) &&
424-
(m_compHnd->getClassAttribs(pVar->clsHnd) & CORINFO_FLG_CONTAINS_GC_PTR)
425+
(GetInterpreterStackMap(pVar->clsHnd)->m_slotCount > 0)
425426
)
426427
)
427428
)

src/coreclr/interpreter/simdhash.h

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,26 @@
1111

1212
class dn_simdhash_ptr_ptr_holder
1313
{
14+
public:
15+
dn_simdhash_ptr_ptr_foreach_func ValueDestroyCallback;
16+
17+
private:
1418
dn_simdhash_ptr_ptr_t *Value;
19+
20+
void free_hash_and_values()
21+
{
22+
if (Value == nullptr)
23+
return;
24+
if (ValueDestroyCallback)
25+
dn_simdhash_ptr_ptr_foreach(Value, ValueDestroyCallback, nullptr);
26+
dn_simdhash_free(Value);
27+
Value = nullptr;
28+
}
29+
1530
public:
16-
dn_simdhash_ptr_ptr_holder() :
17-
Value(nullptr)
31+
dn_simdhash_ptr_ptr_holder(dn_simdhash_ptr_ptr_foreach_func valueDestroyCallback = nullptr)
32+
: ValueDestroyCallback(valueDestroyCallback)
33+
, Value(nullptr)
1834
{
1935
}
2036

@@ -36,8 +52,7 @@ class dn_simdhash_ptr_ptr_holder
3652
{
3753
if (this != &other)
3854
{
39-
if (Value != nullptr)
40-
dn_simdhash_free(Value);
55+
free_hash_and_values();
4156
Value = other.Value;
4257
other.Value = nullptr;
4358
}
@@ -46,8 +61,7 @@ class dn_simdhash_ptr_ptr_holder
4661

4762
~dn_simdhash_ptr_ptr_holder()
4863
{
49-
if (Value != nullptr)
50-
dn_simdhash_free(Value);
64+
free_hash_and_values();
5165
}
5266
};
5367

src/coreclr/interpreter/stackmap.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,6 @@ dn_simdhash_assert_fail (const char* file, int line, const char* condition) {
1818
#endif
1919
}
2020

21-
thread_local dn_simdhash_ptr_ptr_t *t_sharedStackMapLookup = nullptr;
22-
23-
InterpreterStackMap* GetInterpreterStackMap(ICorJitInfo* jitInfo, CORINFO_CLASS_HANDLE classHandle)
24-
{
25-
InterpreterStackMap* result = nullptr;
26-
if (!t_sharedStackMapLookup)
27-
t_sharedStackMapLookup = dn_simdhash_ptr_ptr_new(0, nullptr);
28-
if (!t_sharedStackMapLookup)
29-
NOMEM();
30-
31-
if (!dn_simdhash_ptr_ptr_try_get_value(t_sharedStackMapLookup, classHandle, (void **)&result))
32-
{
33-
result = new InterpreterStackMap(jitInfo, classHandle);
34-
checkAddedNew(dn_simdhash_ptr_ptr_try_add(t_sharedStackMapLookup, classHandle, result));
35-
}
36-
return result;
37-
}
38-
3921
void InterpreterStackMap::PopulateStackMap(ICorJitInfo* jitInfo, CORINFO_CLASS_HANDLE classHandle)
4022
{
4123
unsigned size = jitInfo->getClassSize(classHandle);

src/coreclr/interpreter/stackmap.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ class InterpreterStackMap
2121
{
2222
PopulateStackMap(jitInfo, classHandle);
2323
}
24-
};
2524

26-
InterpreterStackMap* GetInterpreterStackMap(ICorJitInfo* jitInfo, CORINFO_CLASS_HANDLE classHandle);
25+
~InterpreterStackMap ()
26+
{
27+
if (m_slots)
28+
free(m_slots);
29+
m_slots = nullptr;
30+
}
31+
};

0 commit comments

Comments
 (0)