【问题标题】:Why does v8 saves the source code of native javascript in generated binaries?为什么 v8 将原生 javascript 的源代码保存在生成​​的二进制文件中?
【发布时间】:2012-09-29 14:18:44
【问题描述】:

我一直在研究 v8 源代码,特别是“mksnapshot”工具如何在 v8 二进制文件中包含本机 javascript 文件(runtime.js、json.js...)的编译图像,并注意到它也包括源的(有点)缩小版本。例如,在检查 d8 可执行文件的内容时,我看到以下 sn-p:

var $JSON=global.JSON;

function Revive(a,b,c){
var d=a[b];
if((%_IsObject(d))){
if((%_IsArray(d))){
var g=d.length;

在 'src/json.js' 的开头我看到了:

var $JSON = global.JSON;

function Revive(holder, name, reviver) {
  var val = holder[name];
  if (IS_OBJECT(val)) {
    if (IS_ARRAY(val)) {
      var length = val.length;

显然两个 sn-ps 是等价的,但第二个在编译过程中被转换为第一个。

如果包含原始代码以使用“toString”进行检查,我会理解,但是当我在 d8 中输入“JSON.stringify”时,我看到的只是“function stringify() { [native code] }”,那么什么是这是什么意思?

【问题讨论】:

  • 你应该在 Google IO 2012 上问过这个问题 :)
  • 以下是我对这个主题的一些观察。你能知道如何保存这个nodejs.org/api/vm.html#vm_vm_createscript_code_filename 的输出并在以后运行它吗?当您编译 nodejs 时,它似乎仍然没有使用 javascript 文件,因为除了源代码之外,我无法在任何地方找到或找到它们。

标签: javascript v8 embedded-v8


【解决方案1】:

实际上快照不包括编译形式的所有内置函数。

V8 通常更喜欢惰性编译以节省空间和时间。如果您编译不使用的东西,则会浪费内存来生成代码(非优化编译器生成的代码非常“冗长”)和时间(如果我们谈论的是快照,则在编译或反序列化时)。

所以它可以延迟编译的所有东西 V8 都会延迟编译,这包括内置函数。因此快照实际上并不包含所有函数的编译版本,并且需要源来编译 rest。

当源存在时,另一件可能的事情是优化:V8 必须有权访问源以应用其自适应优化管道。

【讨论】:

  • 那么,如果我运行一个带有两个函数的 nodejs 脚本并且只使用一个函数,那么另一个函数永远不会被编译?我可以在源代码中的哪个文件中找到更多关于这种惰性编译行为的信息?
  • 这取决于许多因素,在大多数情况下,只会编译一个使用过的函数。你可以在compiler.cc开始阅读代码:code.google.com/p/v8/source/browse/trunk/src/…
  • 什么是snapshot
【解决方案2】:

可能是因为缓存二进制文件使 v8 变得如此之快:它的构建速度非常快。因此,他们采取了极端措施来加快速度。本机代码的预生成二进制文件消除了客户端的思考,使其运行得更快。整个 v8 都有这样的优化。 :)

【讨论】:

  • 这正是我提出这个问题的原因。如果他们已经保存了编译的机器代码,为什么还要保存生成它的源代码?
  • 以防万一发生了一些疯狂的事情并且客户决定它需要源。带宽很容易获得,尤其是当您可以缓存内容时。 v8 在编写时考虑了速度,因此带宽成本让位给更快的引擎。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-27
  • 2017-07-19
  • 1970-01-01
  • 2019-11-22
  • 1970-01-01
  • 1970-01-01
  • 2014-08-27
相关资源
最近更新 更多