RtlpCoalesceFreeBlocks

_HEAP_FREE_ENTRY *__stdcall RtlpCoalesceFreeBlocks(
        _HEAP *Heap,
        _HEAP_FREE_ENTRY *FreeBlock,
        UINT64 *FreeSize,
        UINT64 *RemoveFromFreeList,
        UINT64 *a5,
        VOID *a6){
  _HEAP_FREE_ENTRY *v7; 
  unsigned __int64 v8; 
  _HEAP_FREE_ENTRY *v10; 
  unsigned int EncodeFlagMask; 
  VOID **p_Flink; 
  _LIST_ENTRY *p_FreeList; 
  _LIST_ENTRY *Flink; 
  _LIST_ENTRY *v15; 
  _LIST_ENTRY *Blink; 
  _HEAP_LIST_LOOKUP *BlocksIndex; 
  unsigned __int64 i; 
  _HEAP_LIST_LOOKUP *ExtendedLookup; 
  int Size; 
  char Flags; 
  unsigned __int64 v22; 
  __int64 v23; 
  __int64 v24; 
  UINT64 v25; 
  unsigned int v26; 
  VOID **v27; 
  _QWORD *v28; 
  VOID *v29; 
  VOID *v30; 
  _HEAP_LIST_LOOKUP *v31; 
  unsigned __int64 j; 
  _HEAP_LIST_LOOKUP *v33; 
  _LIST_ENTRY *v34; 
  char v35; 
  unsigned __int64 v36; 
  __int64 v37; 
  UINT64 Context; 

  v7 = FreeBlock;
  v8 = 16
     * (Heap->Encoding.UnpackedEntry.PreviousSize ^ (unsigned __int64)FreeBlock->HeapEntry.UnpackedEntry.PreviousSize);
  v10 = (_HEAP_FREE_ENTRY *)((char *)FreeBlock - v8);
  if( (_HEAP_FREE_ENTRY *)((char *)FreeBlock - v8) != FreeBlock )
  {
    EncodeFlagMask = Heap->EncodeFlagMask;
    if( ((v10->HeapEntry.UnpackedEntry.Flags ^ Heap->Encoding.UnpackedEntry.Flags & (EncodeFlagMask >> 20)) & 1) == 0 )
    {
      if( EncodeFlagMask )
      {
        v10->HeapEntry.UnpackedEntry.SubSegmentCode ^= Heap->Encoding.UnpackedEntry.SubSegmentCode;
        if( v10->HeapEntry.UnpackedEntry.SmallTagIndex != (LOBYTE(v10->InterceptorValue) ^ (unsigned __int8)(BYTE1(v10->Code1) ^ v10->HeapEntry.UnpackedEntry.Flags)) )
          RtlpAnalyzeHeapFailure(Heap, (_HEAP_ENTRY *)((char *)&FreeBlock->HeapEntry - v8));
      }
      p_Flink = (VOID **)&v10->FreeList.Blink->Flink;
      p_FreeList = &v10->FreeList;
      Flink = v10->FreeList.Flink;
      v15 = (_LIST_ENTRY *)*p_Flink;
      Blink = Flink->Blink;
      if( *p_Flink == Blink && v15 == p_FreeList )
      {
        Heap->TotalFreeSize -= v10->HeapEntry.UnpackedEntry.Size;
        BlocksIndex = (_HEAP_LIST_LOOKUP *)Heap->BlocksIndex;
        if( BlocksIndex )
        {
          for( i = BlocksIndex->ArraySize; ; i = ExtendedLookup->ArraySize )
          {
            if( v10->HeapEntry.UnpackedEntry.Size < i )
            {
              Size = v10->HeapEntry.UnpackedEntry.Size;
              goto LABEL_14;
            }
            ExtendedLookup = BlocksIndex->ExtendedLookup;
            if( !BlocksIndex->ExtendedLookup )
              break;
            BlocksIndex = BlocksIndex->ExtendedLookup;
          }
          Size = BlocksIndex->ArraySize - 1;
LABEL_14:
          LODWORD(Context) = Size;
          LOBYTE(p_FreeList) = 1;
          RtlpHeapRemoveListEntry(Heap, BlocksIndex, p_FreeList, (UINT64)&v10->FreeList, Context);
        }
        *p_Flink = Flink;
        Flink->Blink = (_LIST_ENTRY *)p_Flink;
        Flags = v10->HeapEntry.UnpackedEntry.Flags;
        if( (Flags & 4) != 0 )
        {
          v22 = 16i64 * v10->HeapEntry.UnpackedEntry.Size - 32;
          if( (Flags & 2) != 0 && v22 > 4 )
            v22 = 16i64 * v10->HeapEntry.UnpackedEntry.Size - 36;
          LODWORD(v23) = RtlCompareMemoryUlong(&v10[1], v22, 0xFEEEFEEEui64);
          if( v23 != v22 )
          {
            DbgPrint("HEAP: Free Heap block %p modified at %p after it was freed\n", v10, (char *)&v10[1] + v23);
            if( (_BYTE)KdDebuggerEnabled )
              __debugbreak();
          }
        }
        v24 = v10->HeapEntry.UnpackedEntry.Size;
        v7 = v10;
        v10->HeapEntry.UnpackedEntry.Flags = 0;
        v10->HeapEntry.UnpackedEntry.UnusedBytes = 0;
        *FreeSize += v24;
        v10->HeapEntry.UnpackedEntry.Size = *(_WORD *)FreeSize;
        *(&v10->HeapEntry.UnpackedEntry.PreviousSize + 8 * *FreeSize) = Heap->Encoding.UnpackedEntry.PreviousSize ^ *(_WORD *)FreeSize;
      }
      else
      {
        RtlpLogHeapFailure(heap_failure_freelists_corruption, Heap, p_FreeList, Blink, v15);
      }
    }
  }
  v25 = (UINT64)v7 + 16 * *FreeSize;
  if( Heap->EncodeFlagMask )
  {
    v26 = *(_DWORD *)(v25 + 8) ^ Heap->Encoding.UnpackedEntry.SubSegmentCode;
    if( HIBYTE(v26) != ((unsigned __int8)v26 ^ (unsigned __int8)(BYTE1(v26) ^ BYTE2(v26))) )
      RtlpLogHeapFailure(heap_failure_entry_corruption, Heap, (VOID *)v25, 0i64, 0i64);
  }
  while( ((*(_BYTE *)(v25 + 10) ^ Heap->Encoding.UnpackedEntry.Flags & (Heap->EncodeFlagMask >> 20)) & 1) == 0 )
  {
    if( Heap->EncodeFlagMask )
    {
      *(_DWORD *)(v25 + 8) ^= Heap->Encoding.UnpackedEntry.SubSegmentCode;
      if( *(_BYTE *)(v25 + 11) != (*(_BYTE *)(v25 + 8) ^ (unsigned __int8)(*(_BYTE *)(v25 + 9) ^ *(_BYTE *)(v25 + 10))) )
        RtlpAnalyzeHeapFailure(Heap, (_HEAP_ENTRY *)v25);
    }
    v27 = *(VOID ***)(v25 + 24);
    v28 = *(_QWORD **)(v25 + 16);
    v29 = *v27;
    v30 = (VOID *)v28[1];
    if( *v27 == v30 && v29 == (VOID *)(v25 + 16) )
    {
      Heap->TotalFreeSize -= *(unsigned __int16 *)(v25 + 8);
      v31 = (_HEAP_LIST_LOOKUP *)Heap->BlocksIndex;
      if( v31 )
      {
        for( j = v31->ArraySize; ; j = v33->ArraySize )
        {
          if( *(unsigned __int16 *)(v25 + 8) < j )
          {
            v34 = (_LIST_ENTRY *)*(unsigned __int16 *)(v25 + 8);
            goto LABEL_41;
          }
          v33 = v31->ExtendedLookup;
          if( !v31->ExtendedLookup )
            break;
          v31 = v31->ExtendedLookup;
        }
        v34 = (_LIST_ENTRY *)(v31->ArraySize - 1);
LABEL_41:
        LODWORD(Context) = (_DWORD)v34;
        LOBYTE(v34) = 1;
        RtlpHeapRemoveListEntry(Heap, v31, v34, v25 + 16, Context);
      }
      *v27 = v28;
      v28[1] = v27;
      v35 = *(_BYTE *)(v25 + 10);
      if( (v35 & 4) != 0 )
      {
        v36 = 16i64 * *(unsigned __int16 *)(v25 + 8) - 32;
        if( (v35 & 2) != 0 && v36 > 4 )
          v36 = 16i64 * *(unsigned __int16 *)(v25 + 8) - 36;
        LODWORD(v37) = RtlCompareMemoryUlong((VOID *)(v25 + 32), v36, 0xFEEEFEEEui64);
        if( v37 != v36 )
        {
          DbgPrint(
            "HEAP: Free Heap block %p modified at %p after it was freed\n",
            (const void *)v25,
            (const void *)(v37 + v25 + 32));
          if( (_BYTE)KdDebuggerEnabled )
            __debugbreak();
        }
      }
      v7->HeapEntry.UnpackedEntry.Flags = 0;
      v7->HeapEntry.UnpackedEntry.UnusedBytes = 0;
      *FreeSize += *(unsigned __int16 *)(v25 + 8);
      v7->HeapEntry.UnpackedEntry.Size = *(_WORD *)FreeSize;
      *(&v7->HeapEntry.UnpackedEntry.PreviousSize + 8 * *FreeSize) = Heap->Encoding.UnpackedEntry.PreviousSize ^ *(_WORD *)FreeSize;
      return v7;
    }
    RtlpLogHeapFailure(heap_failure_freelists_corruption, Heap, (VOID *)(v25 + 16), v30, v29);
  }
  return v7;
}

Referenced by:

RtlpDeCommitFreeBlock
RtlpExtendHeap
RtlpFreeHeap