Chrome 61 發佈後,被爆存在安全漏洞,而 Chrome 團隊在修復安全漏洞的過程當中發現一些漏洞是由 V8 的 escape analysis 引發的,編號爲 #765433 #752423 等。javascript
escape analysis 學名是逃逸分析。在編譯優化理論中,逃逸分析是一種肯定指針動態範圍的方法——分析在程序的哪些地方能夠訪問到指針。前端
V8 v6.1 及更早版本使用了一個複雜的逃逸分析實現,自從引入以來就產生了許多錯誤(2333)。此實施已被刪除,並在 V8 v6.2 中提供了全新的逃逸分析代碼庫。java
爲了保護用戶的安全,Chrome 團隊在 Chrome 61 中關閉了逃逸分析。關閉逃脫分析會對性能產生負面影響,由於它會禁用某些優化。具體來講,如下 ES2015 功能可能會變慢:數組
Chrome 團隊的這一舉措,使得數以億計的頁面執行速度變慢。安全
不過能夠確認的是,禁用逃逸分析只是臨時措施。在 Chrome 62 版本中將使用 V8 6.2 中全新的逃逸分析功能。微信
目前這個舉措隻影響到 Chrome 61,根據 Node.js 官方 issue #15564 的討論,Node 8 不受影響,由於漏洞利用不受信任的 JavaScript 執行,除非在 Node.js 中使用了 eval()
,不然 Node.js 運行的代碼都是有開發者寫的受信代碼,Node 8 依然會默認開啓逃逸分析特性。app
It's not deoptimized. It's just that one phase of the optimization pipeline is disabled, and this bug only affects Chrome. Node can still turn it on (with an appropriate bugfix in place).函數
什麼是逃逸分析?性能
在 JavaScript 中,若是從當前函數外部可訪問某個對象,則這個分配的對象"逃逸(escape)"了。優化
一句話歸納就是,V8 在JavaScript 堆上分配新對象,使用逃逸分析,當 V8 分析出此對象只在函數內部起做用(和函數有相同的生命週期),則 V8 能夠把對象分配到棧上,甚至能夠把某些變量分配到寄存器中,把對象做爲一個簡單的局部變量。
若是對象逃逸了,則必須在堆上分配。
例如,逃逸分析使 V8 可以有效地重寫如下代碼:
function foo(a, b) { const object = { a, b }; return object.a + object.b; // Note: `object` does not escape. }
...這個代碼,能夠進行以下優化:
function foo(a, b) { const object_a = a; const object_b = b; return object_a + object_b; }
object_a
和 object_b
分配在棧上甚至寄存器上。
逃逸分析除了能夠將堆分配轉化爲棧分配之外,還能夠:
大部分動態語言都使用逃逸分析進行優化。而 V8 下一個版本將採用新一代逃逸分析技術。
歡迎關注個人公衆號,關注前端文章: