MiCoalesceFreeLargePages
VOID __stdcall MiCoalesceFreeLargePages(INT64 rcx0, INT64 rdx0, UINT64 a3){
unsigned __int64 v3;
unsigned __int64 v4;
INT64 v5;
INT64 v6;
INT64 v7;
unsigned __int8 v8;
unsigned int v9;
unsigned __int64 v10;
INT64 v11;
unsigned int v12;
__int128 *v13;
int v14;
unsigned int v15;
INT64 v16;
unsigned int v17;
unsigned int v18;
unsigned int v19;
unsigned int v20;
INT64 v21;
__int64 v22;
INT64 v23;
INT64 v24;
__int64 v25;
unsigned __int64 i;
unsigned int a2;
int a4;
INT64 v30;
INT64 v31;
INT64 v32;
INT64 CurrentThread;
__int128 v34;
a2 = a3;
v32 = rcx0;
v3 = MiLargePageSizes[(unsigned int)a3];
v4 = MiLargePageSizes[(unsigned int)(a3 - 1)];
LODWORD(v31) = a3 - 1;
v34 = 0i64;
v5 = (INT64)MmGetPfnDb() + 48 * rdx0;
v6 = rdx0;
a4 = 0;
v7 = v5;
v30 = v5;
v8 = 17;
CurrentThread = (INT64)KeGetCurrentThread();
--*(_WORD *)(CurrentThread + 486);
ExAcquirePushLockSharedEx(rcx0 + 192, 0i64);
v9 = 0;
v10 = v4 / v3;
if( v4 / v3 )
{
v11 = v32;
do
{
if( !(unsigned int)MiIsPfn(v6) )
break;
if( !MiLargePfnPromoteCandidate(v11, v7) )
break;
++v9;
v6 += v3;
++*((_DWORD *)&v34 + ((unsigned __int64)*(unsigned __int8 *)(v7 + 34) >> 6));
v7 += 48 * v3;
}
while( v9 < v10 );
v5 = v30;
v8 = 17;
}
if( v9 == v10 )
{
v12 = 0;
v13 = &v34;
v14 = 0;
v15 = 1;
LODWORD(v16) = 0;
do
{
v17 = *(_DWORD *)v13;
v18 = v15;
v19 = v12;
if( *(_DWORD *)v13 && v12 )
v14 = 1;
v15 = v16;
v12 = *(_DWORD *)v13;
if( v19 >= v17 )
v15 = v18;
v16 = (unsigned int)(v16 + 1);
v13 = (__int128 *)((char *)v13 + 4);
if( v19 >= v17 )
v12 = v19;
}
while( (unsigned int)v16 < 4 );
if( v14 && (v20 = 0, v21 = v5, v10) )
{
while( (unsigned int)MiChangePageAttributeLargeFreeZeroPage(v21, a2, v15) )
{
++v20;
v21 += 48 * v3;
if( v20 >= v10 )
goto LABEL_21;
}
}
else
{
LABEL_21:
v22 = 0i64;
v23 = rdx0;
v24 = v5;
v30 = rdx0;
if( v10 )
{
while( (unsigned int)MiIsPfn(v23) )
{
if( v24 == v5 )
{
v8 = MiLockPageInline(v24);
}
else if( _interlockedbittestandset64((volatile signed __int32 *)(v24 + 24), 0x3Fui64) )
{
break;
}
if( !MiLargePfnPromoteCandidate(v32, v24) || *(unsigned __int8 *)(v24 + 34) >> 6 != v15 )
{
_InterlockedAnd64((volatile signed __int64 *)(v24 + 24), 0x7FFFFFFFFFFFFFFFui64);
if( v24 == v5 )
__writecr8(v8);
break;
}
v22 = (unsigned int)(v22 + 1);
v24 += 48 * v3;
v23 = v3 + v30;
v30 += v3;
if( (unsigned int)v22 >= v10 )
break;
}
}
if( (unsigned int)v22 == v10 )
{
MiLargePagePromote(rdx0, a2, v16, &a4);
v25 = v5 + 48 * v3;
}
else
{
v25 = v5 & -(__int64)((_DWORD)v22 != 0);
}
if( (_DWORD)v22 )
{
for( i = v5 + v3 * (48 * v22 - 48); i != v25; i -= 48 * v3 )
_InterlockedAnd64((volatile signed __int64 *)(i + 24), 0x7FFFFFFFFFFFFFFFui64);
_InterlockedAnd64((volatile signed __int64 *)(i + 24), 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v8);
}
if( a4 )
MiChangePageHeatImmediate(rdx0, (unsigned int)v31, 0i64);
}
}
MiUnlockDynamicMemoryShared(v32, CurrentThread);
}Referenced by:
MiRebuildLargeZeroPage