Type in Chakra

Ox9A82發表於2017-08-14

Type in Chakra


Javascript是一個無型別的語言。
我們要討論的型別是指Chakra內建的一些資料結構,這些結構維護了Object的資訊。
Type在一類Object中共享資料,使用執行時型別的目的就是為了效率。

Chakra具有兩類型別,static和dynamic。
static型別是提供給簡單object的,這些object不會在裡面儲存屬性。static型別有string("HELLO")、boolean(true\false)、number。
而Dynamic Object是動態型別的,它們會儲存屬性,比如{}。

每個RecyclableObject都維持著一個指向type的指標。Chakra中每個物件的Class都繼承自RecyclableObject除了tagged float。

var greeting = "hello";
var message = "open source";

這兩個字串中chakra中定義為JavascriptString類,這個類繼承自JavascriptString。greeting和message指向一個共享的type。
此處輸入圖片的描述
這兩個JavascriptString都設定為TypeIds_String,並且這個Type是被兩個字串共享的(type指標指向同一個)。
事實上type物件中含有大量的值域,typeld只是其中一個。

type Js::Type
{
        typeId              Js::TypeId
        flags               TypeFlagMask
        javascriptLibrary   Js::JavascriptLibrary *
        prototype           Js::RecyclableObject * {Js::DynamicObject}
        entryPoint          void *(*)(Js::RecyclableObject *, Js::CallInfo)
        propertyCache       Js::TypePropertyCache *
}

JavascriptString是一個靜態的型別,但是相比之下Dynamic型別的Dynamic object提供了許多可以共享資訊的機會。(DynamicObject和StaticOject都是繼承自RecyclableObject的)

以下程式碼建立的是Dynamic Object

function Point(x, y)
{ 
  this.x = x;
  this.y = y;
}
var one = new Point(10,20);
var two = new Point(40,50);

print(one.x);
print(two.x);

建立了2個Point Object,有x、y兩個屬性,Chakra需要在runtime中儲存以下這些資訊。

1.1、2號物件有x、y兩個屬性
2.1號物件的x屬性為10,y屬性為20
3.2號物件的x屬性為40,y屬性為50

當指令碼要get和set屬性值的時候,上述的資訊就需要獲取了。
(1)是可以在多個物件之間共享的
(2、3)是每個Dynamic Object特有的,彼此不同
解決方法是建立property map和slot array。

Property map, maps between a property and a slot number. Example:
Property x is present at slot 0.

Slot array stores the values. Example slots[0] contains the value of
property x.

就是說Property map表示一個屬性對應於一個slot,而slot實際儲存資料值。
Property map是儲存在dynamic type物件中的。當訪問1.x的時候,chakra在1->type取出property map找到相應的slot number,圖中是0。然後通過1->slots[0]取出實際的值10。
(就是說property map是Type Object中共享的,儲存下標。slot array是每個物件自己的,儲存實際值)

所有從建構函式Point建立的物件都可以共享一個型別。
即使你創造了一百萬個,你也只需要一個型別代表它們。
通過型別的概念可以實現大量的優化,比如

Inline Cache
Object type specialization in JIT
Function specialization

此處輸入圖片的描述

想要更深入地進行優化需要一個單獨的結構。 Typehanlder是Dynamic type的一部分,負責處理property map儲存和一個Dynamic Object獲取它的型別的方式。

Typehandler

Typehandler是一個Dynamic type負責兩個目標。

1.負責維護一個property map
2.維護successor type

var one = {};       
var two = {};       
//Objects one and two points to Type1

one.x = 10;     
//Object one points to Type2 and object two points to Type1
starwars1(one, two);

one.y = 20;     
//Object one points to Type3 and object two points to Type1
starwars2(one, two);

two.x = 40;    
//Object one points to Type3 and object two points to Type2
starwars3(one, two);

two.y = 50;  
//Object one and two points to Type3
starwars4(one, two);

starwars可以為one和two在建立的時候共享相同的屬性。
one和two這兩個物件最後都具有了x和y兩個屬性。
所以在starwars4執行之後,他們可以共享同一個type object。
如果在不同的時間點建立了相同屬性的物件,如何確定所有具有相同屬性的物件呢?
typehanlder中的successor type解決了這個問題。每個typehandler都儲存有一個successor type,如果一個物件獲得了一個新屬性那麼就由它來指派一個新的type物件。這個過程通常叫做型別提升或是型別轉變。
Type in Chakra
因為typehandler儲存有指向後繼型別的指標,因此型別轉換會很快的發生。

https://github.com/Microsoft/ChakraCore/blob/master/lib/Runtime/Types/PathTypeHandler.h#L207
SimpleTypeHanlder擁有一個叫做typePath的property map,它擁有一個[tiny dictionary]去對映property Id 到slot number。同樣存在維護著下一個型別指標的successorTypeWeakRef。SimpleTypeHandler的一個比較有名的變種是 [PathTypeHandler]維持著 PropertySuccessorsMap 到多個successors。

這篇文章討論瞭如下幾個問題
1.為啥所有物件都要存在type物件
2.type物件是怎麼實現多物件共享的
3.為啥typehandler會指向successor type,注意還存在有許多不同的typehandlers 在共享不同的資料。

http://abchatra.github.io/Type/

相關文章