GC plan_phase二叉樹掛接的一個算法

楔子

在看GC垃圾回收plan_phase的時候,發現了一段特殊的代碼,仔細研究下得知,獲取當前數字bit位裏面爲1的個數。

通過這個bit位爲1的個數(count),來確定掛接當前二叉樹子節點的一個地方。


算法

size_t logcount (size_t word)
{
    //counts the number of high bits in a 16 bit word.
    assert (word < 0x10000);
    size_t count;
    count = (word & 0x5555) + ( (word >> 1 ) & 0x5555);
    count = (count & 0x3333) + ( (count >> 2) & 0x3333);
    count = (count & 0x0F0F) + ( (count >> 4) & 0x0F0F);
    count = (count & 0x00FF) + ( (count >> 8) & 0x00FF);
    return count;
}

counts the number of high bits in a 16 bit word.這一段英文註釋很有誤導性,它的意思翻一下大致是:獲取當前16位字裏面的高位bit數。
如果按照這個理解,基本上不知道這個logcount函數是幹嘛的。

但實際上它做的事情非常簡單。

舉個例子:
5的二進制:0101,那麼經過logcount函數計算之後,返回值爲2。因爲5的二進制裏面有兩個1。
以此類推,6返回2,7返回3,8返回1。


背景

GC垃圾回收的計劃階段,當plan_phase構建二叉樹的時候,需要區分根節點,左子節點,和右子節點。新加入的新節點作爲根節點,新節點的左子節點(G)就是上一個根節點(C)的右子節點。新節點本身又作爲上一個根節點(C)的右子節點。

圖:
image

上面這個算法的作用就是,把新加入的新節點掛接到二叉樹深度N(logcount返回值)的地方。
圖兩個二叉樹,分別深度爲2和3。logcount返回其參數bit位裏面爲1的個數,作爲二叉樹的深度。然後進行一個掛接。其行爲邏輯是二叉樹構建的核心。


整體

GC計劃階段(plan_phase)的二叉樹構建主要是爲後面的重定位,壓縮和清掃做準備。
二叉樹是其關鍵一步。
大致爲:

1.區分固定對象和非固定對象,如果非固定對象後面跟着非固定對象就會形成一個堆段,如果後面繼續有非固定對象,則繼續加入這個小堆段。如果後面跟着固定對象則到小堆段到此爲止。然後判斷固定對象後面是否跟着固定對象,如果是則把這兩個固定對象形成一個小堆段。後面繼續判斷,如果還是固定對象則加入到小堆段。如沒有,則此小堆段到此爲止。其邏輯跟非固定對象一樣。如此一直遍歷完這個堆,這樣的話堆裏面形成了一個個小堆段。

2.這些小堆段,會被plan_phase當成一個個的節點,然後把這些節點通過相關的邏輯構建成一顆二叉樹。

3.如果二叉樹過於龐大,則無論是在時間還是在空間上的複雜度都很高。爲了避免性能問題,於是引入了brick_table來分割這顆龐大的二叉樹


結尾

理解其行爲,則需聯繫上下文,查看其整體構建,然後逐步推導。

image

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章