当前位置: 首页 > 后端技术 > Node.js

V8团队的一个失误让整个互联网都变慢了

时间:2023-04-03 12:19:27 Node.js

Chrome61发布后,有安全漏洞暴露,Chrome团队在修复安全的过程中发现部分漏洞是V8的逃逸分析造成的漏洞,序列号为#765433#752423等。逃逸分析的学名是逃逸分析。在编译器优化理论中,逃逸分析是一种确定指针动态范围的方法——分析指针在程序中的哪些位置可以访问。V8v6.1及更早版本使用了复杂的逃逸分析实现,自引入以来产生了许多错误(2333)。此实现已被删除,以支持V8v6.2中全新的逃逸分析代码库。为了保护用户的安全,Chrome团队在Chrome61中关闭了逃逸分析。关闭逃逸分析会对性能产生负面影响,因为它会禁用某些优化。具体来说,以下ES2015特性可能会更慢:Destructuring(解构)for-of迭代器(for-ofiteration)数组展开(arrayspread)剩余参数(restparameters)Chrome团队的这一举动使计算页面执行速度减慢。不过可以确认,禁用逃逸分析只是临时措施。V86.2中新的逃逸分析功能将在Chrome62中使用。目前,该措施仅影响Chrome61。根据Node.js官方问题#15564的讨论,Node8不受影响,因为该漏洞利用由不受信任的执行JavaScript,除非在Node.js中使用了eval(),否则Node.js运行的代码是开发人员编写的可信代码,Node8仍然会默认启用逃逸分析功能。它没有去优化。只是禁用了优化管道的一个阶段,这个错误只影响Chrome。Node仍然可以打开它(通过适当的错误修复)。什么是逃逸分析?在JavaScript中,如果可以从当前函数外部访问分配的对象,则它会“转义”。简而言之,V8在JavaScript堆上分配新对象。使用逃逸分析,当V8分析出对象只在函数内部工作(它和函数有相同的生命周期),那么V8就可以在栈上分配对象。甚至可以将某些变量分配到寄存器中,将对象视为一个简单的局部变量。如果对象逃逸,则必须在堆上分配它。例如,逃逸分析使V8能够有效地重写以下代码:functionfoo(a,b){constobject={a,b};返回对象.a+对象.b;//注意:`object`不会转义。}...这段代码可以优化如下:functionfoo(a,b){constobject_a=a;constobject_b=b;returnobject_a+object_b;}object_a和object_b分配在堆栈甚至寄存器上。除了将堆分配转换为栈分配外,逃逸分析还可以:同步遗漏:如果发现一个对象只能从一个线程访问,那么对该对象的操作就不需要考虑同步。对象分离或标量替换:有些对象可能不需要作为连续的内存结构存在并且可以访问,那么部分(或全部)对象可能不存储在内存中,而是存储在CPU寄存器中。大多数动态语言都是使用逃逸分析进行优化的。下一个版本的V8将采用新一代的逃逸分析技术。欢迎关注我的公众号,关注前端文章: