Skip to content

Commit a985d18

Browse files
committed
build index lazily
1 parent 90cace2 commit a985d18

File tree

2 files changed

+43
-18
lines changed

2 files changed

+43
-18
lines changed

src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.cpp

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,14 @@ static PTR_VOID GetUnwindDataBlob(TADDR moduleBase, PTR_RUNTIME_FUNCTION pRuntim
173173
#define INDEX_ALIGNMENT 64
174174

175175
CoffNativeCodeManager::CoffNativeCodeManager(TADDR moduleBase,
176-
PTR_VOID pvManagedCodeStartRange, uint32_t cbManagedCodeRange,
177-
PTR_RUNTIME_FUNCTION pRuntimeFunctionTable, uint32_t nRuntimeFunctionTable,
178-
PTR_PTR_VOID pClasslibFunctions, uint32_t nClasslibFunctions)
176+
PTR_VOID pvManagedCodeStartRange, uint32_t cbManagedCodeRange,
177+
PTR_RUNTIME_FUNCTION pRuntimeFunctionTable, uint32_t nRuntimeFunctionTable,
178+
PTR_PTR_VOID pClasslibFunctions, uint32_t nClasslibFunctions)
179179
: m_moduleBase(moduleBase),
180180
m_pvManagedCodeStartRange(pvManagedCodeStartRange), m_cbManagedCodeRange(cbManagedCodeRange),
181181
m_pRuntimeFunctionTable(pRuntimeFunctionTable), m_nRuntimeFunctionTable(nRuntimeFunctionTable),
182-
m_pClasslibFunctions(pClasslibFunctions), m_nClasslibFunctions(nClasslibFunctions), m_indexCount(0)
182+
m_pClasslibFunctions(pClasslibFunctions), m_nClasslibFunctions(nClasslibFunctions),
183+
m_initializedIndices(0), m_indexCount(0), m_indices{ 0 }
183184
{
184185
}
185186

@@ -198,19 +199,40 @@ CoffNativeCodeManager::~CoffNativeCodeManager()
198199
m_indexCount = 0;
199200
}
200201

201-
bool CoffNativeCodeManager::InitFuncTableIndex()
202+
bool CoffNativeCodeManager::AllocFuncTableIndex()
202203
{
203-
// max offset is beyond the range of managed methods.
204-
int maxOffset = (int)((TADDR)m_pvManagedCodeStartRange + m_cbManagedCodeRange - m_moduleBase);
205-
206-
// lets build the index for the runtime table. for every granule that has elements we will have an index entry
207204
uint32_t indexSize = (m_nRuntimeFunctionTable + FUNCTABLE_INDEX_GRANULARITY - 1) / FUNCTABLE_INDEX_GRANULARITY;
208205
uint32_t* index = m_indices[m_indexCount] = (uint32_t*)_aligned_malloc(indexSize * sizeof(uint32_t), INDEX_ALIGNMENT);
209206
if (!index)
210207
return false;
211208

212209
m_indexCount++;
213210

211+
while (indexSize > INDEX_BRANCHING_FACTOR)
212+
{
213+
uint32_t prevSize = indexSize;
214+
indexSize = (indexSize + INDEX_BRANCHING_FACTOR - 1) / INDEX_BRANCHING_FACTOR;
215+
index = m_indices[m_indexCount] = (uint32_t*)_aligned_malloc(indexSize * sizeof(uint32_t), INDEX_ALIGNMENT);
216+
if (!index)
217+
return false;
218+
219+
m_indexCount++;
220+
}
221+
222+
return true;
223+
}
224+
225+
NOINLINE
226+
uint32_t** CoffNativeCodeManager::InitFuncTableIndex()
227+
{
228+
// max offset is beyond the range of managed methods.
229+
int maxOffset = (int)((TADDR)m_pvManagedCodeStartRange + m_cbManagedCodeRange - m_moduleBase);
230+
231+
// lets build the index for the runtime table. for every granule that has elements we will have an index entry
232+
uint32_t indexSize = (m_nRuntimeFunctionTable + FUNCTABLE_INDEX_GRANULARITY - 1) / FUNCTABLE_INDEX_GRANULARITY;
233+
uint32_t indexCount = 0;
234+
uint32_t* index = m_indices[indexCount++];
235+
214236
// in every index N we will put the lowest value from the granule N + 1
215237
// when we will scan the value N in the indices and see that it is higher than the target, we will know
216238
// that the granule N must be scanned for the entry as the next granule will have higher addresses.
@@ -231,11 +253,7 @@ bool CoffNativeCodeManager::InitFuncTableIndex()
231253
{
232254
uint32_t prevSize = indexSize;
233255
indexSize = (indexSize + INDEX_BRANCHING_FACTOR - 1) / INDEX_BRANCHING_FACTOR;
234-
index = m_indices[m_indexCount] = (uint32_t*)_aligned_malloc(indexSize * sizeof(uint32_t), INDEX_ALIGNMENT);
235-
if (!index)
236-
return false;
237-
238-
m_indexCount++;
256+
index = m_indices[indexCount++];
239257

240258
for (uint32_t i = 1; i < indexSize; i++)
241259
{
@@ -247,7 +265,8 @@ bool CoffNativeCodeManager::InitFuncTableIndex()
247265
prevIdx = index;
248266
}
249267

250-
return true;
268+
WriteRelease64((LONG64*)&m_initializedIndices, (LONG64)m_indices);
269+
return m_initializedIndices;
251270
}
252271

253272
struct CoffNativeMethodInfo
@@ -262,10 +281,14 @@ static_assert(sizeof(CoffNativeMethodInfo) <= sizeof(MethodInfo), "CoffNativeMet
262281

263282
int CoffNativeCodeManager::LookupUnwindInfoIdx(uint32_t relativePc)
264283
{
284+
uint32_t** indices = m_initializedIndices;
285+
if (!indices)
286+
indices = InitFuncTableIndex();
287+
265288
uint32_t idx = 0;
266289
for (int j = m_indexCount - 1; j >= 0; j--)
267290
{
268-
uint32_t* index = m_indices[j];
291+
uint32_t* index = indices[j];
269292
idx *= INDEX_BRANCHING_FACTOR;
270293

271294
while ((uint32_t)index[idx] < relativePc)
@@ -1054,7 +1077,7 @@ bool RhRegisterOSModule(void * pModule,
10541077
if (pCoffNativeCodeManager == nullptr)
10551078
return false;
10561079

1057-
if (!pCoffNativeCodeManager->InitFuncTableIndex())
1080+
if (!pCoffNativeCodeManager->AllocFuncTableIndex())
10581081
return false;
10591082

10601083
RegisterCodeManager(pCoffNativeCodeManager, pvManagedCodeStartRange, cbManagedCodeRange);

src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class CoffNativeCodeManager : public ICodeManager
4444
PTR_PTR_VOID m_pClasslibFunctions;
4545
uint32_t m_nClasslibFunctions;
4646

47+
uint32_t** volatile m_initializedIndices;
4748
uint32_t m_indexCount;
4849
uint32_t* m_indices[8];
4950

@@ -56,7 +57,8 @@ class CoffNativeCodeManager : public ICodeManager
5657
PTR_PTR_VOID pClasslibFunctions, uint32_t nClasslibFunctions);
5758
~CoffNativeCodeManager();
5859

59-
bool InitFuncTableIndex();
60+
bool AllocFuncTableIndex();
61+
uint32_t** InitFuncTableIndex();
6062

6163
//
6264
// Code manager methods

0 commit comments

Comments
 (0)