为什么创建多个单态缓存而不是一个多态缓存

Why multiple monomorphic caches are created instead of one polymorphic

我正在阅读 this article 关于单态的文章,那里有以下代码片段:

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 })

How many property access inline caches are in the function ff? What’s state they are in? Answers: there are 2 caches, both are monomorphic because each sees only objects of one shape.

我认为会有一个多态的,因为作者早些时候显示:

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

该函数传递不同结构的对象,它们将单态缓存变异为多态缓存。为什么与所讨论的示例不同?

那些 "inline cache" 东西存在于代码中每个不同的 属性 引用中。因此在函数中:

function ff(b, o) {
  if (b) {
    return o.x   // IC here
  } else {
    return o.x   // IC here
  }
}

这两个 return 语句每个都有自己的内联缓存。由于示例中调用函数的方式,第一个 return 只发生在第一个形状的对象上,第二个只发生在第二个形状的对象上。因此,每个缓存(在对 ff() 的那四次调用之后)将只看到 1 个形状。

第五次 调用函数之后:

ff(true, { x: 1, z: 10 });

第一个 IC 会看到 两个 形状,因此它的 IC 将是多态的。

每个属性访问o.x都有自己的IC,即使多次访问同一个对象的同一个属性。

如果你运行node --trace-ic someScript.js,你可以看到IC属于哪个行号。