为什么v8会将本机javascript的源代码保存在生成的二进制文件中?

为什么v8会将本机javascript的源代码保存在生成的二进制文件中?,javascript,v8,embedded-v8,Javascript,V8,Embedded V8,我一直在研究v8源代码,特别是“mksnapshot”工具如何在v8二进制文件中包含本机javascript文件(runtime.js、json.js…)的编译映像,并注意到它还包含(某种程度上)简化的源代码版本。例如,在检查d8可执行文件的内容时,我看到以下代码段: var $JSON=global.JSON; function Revive(a,b,c){ var d=a[b]; if((%_IsObject(d))){ if((%_IsArray(d))){ var g=d.length

我一直在研究v8源代码,特别是“mksnapshot”工具如何在v8二进制文件中包含本机javascript文件(runtime.js、json.js…)的编译映像,并注意到它还包含(某种程度上)简化的源代码版本。例如,在检查d8可执行文件的内容时,我看到以下代码段:

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;
显然,这两个代码段是等效的,但第二个代码段在编译过程中被转换为第一个代码段


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

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

实际上,快照并不包括编译表单中的所有内置项

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

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


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

这正是我提出这个问题的原因。如果他们已经保存了编译过的机器代码,为什么还要保存生成它的源代码呢?以防发生了一些疯狂的事情,客户机决定需要源代码。带宽很容易获得,特别是当你可以缓存东西的时候。v8的编写考虑到了速度,所以带宽成本被放在了速度更快的引擎后面。你应该在Google IO 2012期间问这个问题:)以下是我对这个问题的一些观察。您能告诉我如何保存此文件的输出并在以后运行它吗?当你编译nodejs时,它似乎不再使用javascript文件,因为除了在源代码中,我无法在任何地方找到或定位它们。因此,如果我运行一个包含两个函数的nodejs脚本,并且只使用一个函数,那么另一个将永远不会被编译?我可以在源代码中找到关于这种惰性编译行为的更多信息的哪个文件?这取决于许多因素,在大多数情况下,只编译一个使用过的函数。您可以在
compiler.cc
中开始读取代码: