V8引擎中的隐藏类是如何实现的? [英] How are hidden classes in the V8 engine implemented?

查看:30
本文介绍了V8引擎中的隐藏类是如何实现的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我广泛阅读了 V8 引擎的公共 Wiki,并且了解了隐藏类如何查找属性的概念.

据此,它说属性存储在不同的偏移量中,但是对于每个偏移量,您必须检查其是否正确的属性.那么,这是否意味着您必须在最坏的情况下遍历所有属性才能获得所需属性的正确偏移量?

由于哈希表是恒定时间查找,所以它们通常不会比这更快吗?

解决方案

看来你的问题是通过这里这里,和此处.

简而言之,根据我对这些链接的理解:

哈希表比常量时间查找慢,所以 V8 尽可能使用后者,但如果对象变得太复杂而无法使用隐藏类很好地处理,则回退到前者.

线性扫描显然也很糟糕,但在我看来,V8 试图通过一种称为内联缓存的技术优化代码以缓解数据结构的这个问题.em>:当您的代码尝试重复访问 obj.prop 时,V8 最终决定只动态修补生成的代码,以便属性访问成为在给定偏移量处的恒定时间查找.
当然,如果预期的类类型错​​误,那么它必须回退并尝试慢速查找.
function CompileNamedLoadFastProperty(klass, key)这个页面 试图解释:

function CompileNamedLoadFastProperty(klass, key) {//已知键是常量(命名为负载).专精索引.var index = klass.getIndex(key);函数 KeyedLoadFastProperty(t, k, ic) {如果(t.klass !== klass){//预期的类别不匹配.不能使用缓存索引.//进入运行时系统.返回 NAMED_LOAD_MISS(t, k, ic);}返回 t.properties[index];//威尼斯.维迪.维西.}返回 KeyedLoadFastProperty;}函数 NAMED_LOAD_MISS(t, k, ic) {var v = LOAD(t, k);如果(t.klass.kind ===快"){//创建一个专门用于固定类和键 k 的加载存根和//从固定偏移量加载属性.var stub = CompileNamedLoadFastProperty(t.klass, k);补丁IC(负载",IC,存根);}返回 v;}

So, I have read up on the public Wiki for the V8 engine extensively, and I get the concept of how the hidden classes look up properties. v8 design elements

However, what I don't get really is how this is faster than a hash table.

According to this, its saying that the properties are stored in different offsets, but for each offset you have to check if its the correct property. So does mean you have to iterate through all properties, at the worst case scenario, to get the right offset for the property you want?

Since hashtables are constant time lookups, wouldn't they be faster than this usually?

解决方案

It seems that your question is answered through some combination of here, here, and here.

Briefly, based on my understanding of those links:

Hashtables are slower than constant-time lookups, so V8 uses the latter when possible, but falls back to the former if objects become too complicated to handle well using hidden classes.

A linear scan is also obviously bad, but it seems to me that V8 tries to optimize the code to alleviate this problem with the data structure, through a technique called inline caching: when your code attempts to access obj.prop repeatedly, V8 eventually decides to just dynamically patch the generated code such that the property access becomes a constant-time lookup at a given offset.
Of course, if the expected class type is wrong, then it has to fall back and try a slow lookup.
function CompileNamedLoadFastProperty(klass, key) on this page tries to explain:

function CompileNamedLoadFastProperty(klass, key) {
  // Key is known to be constant (named load). Specialize index.
  var index = klass.getIndex(key);

  function KeyedLoadFastProperty(t, k, ic) {
    if (t.klass !== klass) {
      // Expected klass does not match. Can't use cached index.
      // Fall through to the runtime system.
      return NAMED_LOAD_MISS(t, k, ic);
    }
    return t.properties[index];  // Veni. Vidi. Vici.
  }

  return KeyedLoadFastProperty;
}

function NAMED_LOAD_MISS(t, k, ic) {
  var v = LOAD(t, k);
  if (t.klass.kind === "fast") {
    // Create a load stub that is specialized for a fixed class and key k and
    // loads property from a fixed offset.
    var stub = CompileNamedLoadFastProperty(t.klass, k);
    PatchIC("LOAD", ic, stub);
  }
  return v;
}

这篇关于V8引擎中的隐藏类是如何实现的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆