Chakra GC記憶體管理(未完)

Ox9A82發表於2017-08-08

這一部分是我在網上找Chakra資料的時候偶然發現的zenhumany師傅在Hitcon2015上的議題《Microsoft Edge MemGC Internals》,感覺正好可以瞭解一下chakra的底層機制。但是隻有一個PPT理解起來比較費力,這裡的內容一方面是靠理解ppt,一方面是靠看程式碼和除錯,可能有不正確的地方。

GC的管理模式

Chakra GC use Concurrent Mark-Sweep (CMS) Managing Memory.
Edge use the same data structures to mange DOM and DOM’S supporting objects, called MemGC.

GC針對堆的管理

GC根據分配的size大小分為三類的block。
總體的管理器為HeapInfo

class   HeapInfo
m_HeapBucketGroup[0x40] 陣列
m_LargeHeapBucket[0x20] 陣列
m_lastLargeHeapBucket 
  • 0x400byte以下為small block (目前版本可能改成了0x300)

    資料結構

    pHeapInfo
    ->m_HeapBucketGroup[index]
    ->m_HeapBucketT<SmallNormalHeapBlock>(子結構)
    ->pSmallHeapBlockAllocatorT(子結構)
    ->pSmallHeapBlock
    
    
    class HeapBucketT<SmallNormalHeapBlock>
    size    
    m_SmallHeapBlockAllocator
    pPartialReuseHeapBlockList
    pEmptyHeapBlockList
    pFullMarkedHeapBlockList
    pPendingNewHeapBlockList

HeapBucketT是模版類用於對應不同的block型別,目前還不清楚各個list的作用,一些似乎是用於垃圾回收的

其中SmallHeapBlockAllocator是small block分配的重要結構,startaddress域儲存有下一次分配的起始地址,

    SmallHeapBlockAllocator<SmallNormalHeapBlock>
    0x00    endadderss
    0x04    startaddress
    0x08    pSmallNormalHeapblock

其中SmallHeapBlockAllocator是直接的記憶體控制結構。
pSmallNormalHeapblock是直接對應buffer的底層結構

分配的過程如下:

    pHeapInfo->
    m_HeapBucketGroup[ index].m_HeapBucketT<SmallNormalHeapBlock>->
    pSmallHeapBlockAllocatorT(子結構)->
    pSmallHeapBlock
    
    allocAddress =  pHeapBucketT->startAddress;//取pSmallHeapBlockAllocatorT中地址
    ...//省略了一些校驗
    pSmallHeapBlockAllocator->startAddress = pHeapBucketT->startAddress + align_size;
    return allocAddress;

分配是透過直接讀取操作pSmallHeapBlockAllocatorT中的address實現的
但是如果startaddress不存在的話會進入另一個分配機制稱為慢分配

     if( pSmallHeapBlockAllocator->startAddress ==0 || pSmallHeapBlockAllocator->endAddress!=0 )
        {
            allocAddress = pHeapBucketT->SnailAlloc(pRecycler, pSmallHeapBlockAllocator, align_size, 8, 1);
            if( allocAddress == 0)
                return 0;
            else
                *allocAddress = 0;
                return allocAddress
        }
  • 0x400-0x2400為large block (目前版本的size範圍有不同)
    資料結構

    pHeapInfo
    ->m_LargeHeapBucket[index]
    ->pNewLargeHeapBlockList

    分配過程

    pHeapInfo->m_LargeHeapBucket[ largebucketIndex]->pLargeHeapBlockList->Alloc( align_size, 8)
    allocAddress = pLargeHeapBlock ->Alloc( align_size, 8)
    return allocAddress;
    
    Recycler::LargeAlloc
    allocAddress = Recycler::LargeAlloc( pHeapInfo, size, 8 )//使用到了Recycler
    *allocAddress = 0;
    return allocAddress;

    其中LargeHeapBlock是底層的記憶體管理結構
    LargeHeapBlock管理著LargeObjectHeader和對應的buffer

    LargeObjectHeader
    Buffer
    LargeObjectHeader
    Buffer

LargeObjectHeader存在分配的序號進行排列

    struct LargeObjectHeader
    {
         uint objectIndex;//分配的序號
         UINT_PAD_64BIT(unused1);
         size_t objectSize;//使用者申請的大小
    }
  • 0x2400以上 last large alloc

    //to do

Recycler管理

class   Recycler
0x26c   m_HeaoBlock32Map
0x42bc  m_HeapInfo

//to do

HeapBlock32Map

//to do

相關文章