我正在阅读这篇关于单态性的文章,其中有以下代码片段:
function ff(b, o) {
if (b) {
return o.x
} else {
return o.x
}
}
ff(true, { x: 1 })
ff(false, { x: 2, y: 0 })
ff(true, { x: 1 })
ff(false, { x: 2, y: 0 })
函数ff中有多少个属性访问内联缓存?什么是他们所处的状态?答案:有两个缓存,都是单态的,因为每个缓存只能看到一个形状的对象。
我认为会有一个多态的,因为作者早些时候显示:
f({ x: 4, y: 1 }) // polymorphic, degree 2
f({ x: 5, z: 1 }) // polymorphic, degree 3
f({ x: 6, a: 1 }) // polymorphic, degree 4
f({ x: 7, b: 1 }) // megamorphic
函数被传递给不同结构的对象,它们将单形态缓存变为多形态缓存。为什么与所讨论的例子不同?
这些"内联缓存"存在于代码中每个不同的属性引用中。因此在功能上:
function ff(b, o) {
if (b) {
return o.x // IC here
} else {
return o.x // IC here
}
}
这两个return
语句都有自己的内联缓存。由于在示例中调用函数的方式,第一个return
仅发生在第一个形状的对象中,第二个仅发生在第二个形状的物体中。因此,每个高速缓存(在对ff()
的那四次调用之后(将只看到一个形状。
在第五次调用如下函数后:
ff(true, { x: 1, z: 10 });
第一个IC将看到两个形状,因此其IC将是多态的。
每个属性访问o.x
都有自己的IC,即使同一对象的同一属性被多次访问也是如此。
如果您运行node --trace-ic someScript.js
,您可以看到IC属于哪个行号。