Type in Chakra

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对象。这个过程通常叫做类型提升或是类型转变。

因为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/

posted @ 2017-08-14 20:00  Ox9A82  阅读(343)  评论(0编辑  收藏