热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

理解谷歌的V8c++代码库中的继承-UnderstandinginheritanceinGoogle'sV8C++codebase

IcannotunderstandtheimplementationofinheritanceinGooglesV8JavaScriptengine.Itclearly(

I cannot understand the implementation of inheritance in Google's V8 Javascript engine. It clearly (?) implements an inheritance hierarchy, but seems to completely do away with virtual functions.

我无法理解谷歌的V8 Javascript引擎中继承的实现。它显然(?)实现了继承层次结构,但似乎完全不使用虚拟函数。

This is the inheritance hierarchy as detailed in the objects.h header file:

这是对象中详细介绍的继承层次结构。h头文件:

// Inheritance hierarchy:
// - Object
//   - Smi          (immediate small integer)
//   - HeapObject   (superclass for everything allocated in the heap)
//     - JSReceiver  (suitable for property access)
//       - JSObject
//         - JSArray
// ... and many more entries

Most object types are derived from Object, which is declared as follows:

大多数对象类型都是从对象派生出来的,声明如下:

// Object is the abstract superclass for all classes in the
// object hierarchy.
// Object does not use any virtual functions to avoid the
// allocation of the C++ vtable.
// Since both Smi and HeapObject are subclasses of Object no
// data members can be present in Object.
class Object {
// ... bunch of method declarations and definitions
};

The relatively simple Smi class is declared next:

相对简单的Smi类将在下面声明:

class Smi: public Object {
 public:
 // methods declarations and static member definitions
};

and so on.

等等。

For the life of me, I cannot understand how can, say, an instance of Smi can be used as an Object; there are no virtual functions and I cannot find overrides in the the implementation file, objects.cc. At 17,290 lines, though, trying to understand what is going on is proving a difficult task.

在我的一生中,我无法理解如何,比方说,Smi实例可以作为对象;在实现文件objects.cc中没有虚拟函数,我也找不到重写。然而,在17,290行,试图弄明白到底发生了什么是一项困难的任务。

As another difficulty, I found an ObjectVisitor class in the same header file (this one is more classical; it consists of virtual methods). But I could not find the equivalent Accept(Visitor*) (or similar) method in the Object base class.

另一个困难是,我在同一个头文件中发现了ObjectVisitor类(这个更经典;它由虚拟方法组成)。但是我在对象基类中找不到等效的Accept(Visitor*)(或类似的)方法。

What I am asking in concrete is for a minimal example that illustrates how does this inheritance pattern works.

我在具体的内容中要问的是一个最小的示例,它说明了这个继承模式是如何工作的。

2 个解决方案

#1


3  

The classes in objects.h do not actually define real C++ classes. They do not have any fields. The classes are merely facades to objects managed on the V8 Javascript heap. Hence they cannot have any virtual functions either, because that would require putting vtable pointers into the JS heap. Instead, all dispatch is done manual, via explicit type checks and down casts.

类的对象。h实际上没有定义真正的c++类。它们没有任何字段。这些类只是V8 Javascript堆上管理的对象的外观。因此它们也不能有任何虚函数,因为这需要将vtable指针放入到JS堆中。相反,所有的分派都是手工完成的,通过显式类型检查和下拉类型转换。

The this pointer inside methods isn't real either. For smis, this is simply an integer. For everything else it is a pointer into the V8 heap, off by one for tagging. Any actual accessor method masks this pointer and adds an offset to access the appropriate address in the heap. The offsets of each field is also defined manually in the classes.

方法中的这个指针也不是真实的。对于smis,这只是一个整数。对于其他一切,它是一个指向V8堆的指针,一个用于标记。任何实际的访问器方法都会掩盖这个指针,并添加一个偏移量来访问堆中的适当地址。每个字段的偏移量也在类中手工定义。

#2


2  

Take a look at Object::IsPromise() for a perfect example of how it works:

看看Object::IsPromise(),它是如何工作的一个完美例子:

bool Object::IsPromise(Handle object) {
  if (!object->IsJSObject()) return false;
  auto js_object = Handle::cast(object);
  // Promises can't have access checks.
  if (js_object->map()->is_access_check_needed()) return false;
  auto isolate = js_object->GetIsolate();
  // TODO(dcarney): this should just be read from the symbol registry so as not
  // to be context dependent.
  auto key = isolate->promise_status();
  // Shouldn't be possible to throw here.
  return JSObject::HasRealNamedProperty(js_object, key).FromJust();
}

The way inheritance is used here is static. That is, type queries are done by a proxy or container (using some hidden magic, that, at a glance looks like they're using references to query a tag), and conversions from Object to a derived class is done by static_cast<>(). In that way, the member functions of the derived class can be called.

这里使用继承的方式是静态的。即类型查询是通过代理或容器(使用一些隐藏的魔法,乍一看像他们使用引用来查询一个标签),和转换从一个派生类对象是通过static_cast <>()。这样的话,派生类的成员函数可以调用。

Note that in the above function, the type query and cast is indirectly performed by the Handle<> class, not by Object or any of its derived classes.

注意,在上面的函数中,类型查询和转换是由句柄<>类间接执行的,而不是由对象或它的任何派生类执行的。

Note also that the functions which accept ObjectVisitor as a parameter are rather uniformly called Iterate, and that these functions all appear on proxies or handles.

还请注意,接受ObjectVisitor作为参数的函数相当一致地称为Iterate,并且这些函数都出现在代理或句柄上。


推荐阅读
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文概述了JNI的原理以及常用方法。JNI提供了一种Java字节码调用C/C++的解决方案,但引用类型不能直接在Native层使用,需要进行类型转化。多维数组(包括二维数组)都是引用类型,需要使用jobjectArray类型来存取其值。此外,由于Java支持函数重载,根据函数名无法找到对应的JNI函数,因此介绍了JNI函数签名信息的解决方案。 ... [详细]
  • 1、PLSQLDeveloper记住登陆密码在使用PLSQLDeveloper时,为了工作方便希望PLSQLDeveloper记住登录Oracle的用户名和密码&#x ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • vb6集成ad登录共享文件_SCSP实验2单点登录
    01—实验目的掌握单点登陆相关原理和深信服配置02—实验环境1.AC版本v12.0.42AC1地址:https:172.172.1.1AC2地址:htt ... [详细]
  • 图解 Google V8 # 19 :异步编程(二):V8 是如何实现 async/await 的?
    说明图解GoogleV8学习笔记前端异步编程的方案史1、什么是回调地狱?如果在代码中过多地使用异步回调函数,会将整个代码逻辑打乱,从 ... [详细]
author-avatar
静静敲代码
很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有