簡體   English   中英

誰能解釋 V8 字節碼 LdaTheHole?

[英]Can anyone explain V8 bytecode LdaTheHole?

我知道 V8 字節碼“LdaUndefined”將常量“未定義”加載到累加器寄存器中。 那么“LdaTheHole”將什么加載到蓄能器中? 也許是“洞”? “TheHole”的含義是什么? 謝謝你。

(這里是 V8 開發人員。)

“LdaTheHole”將什么加載到蓄能器中? 也許是“洞”?

是的。

“TheHole”的含義是什么?

正如馬克的回答正確猜測的那樣,它是一個內部哨兵,意思是“這里沒有價值”。 但是,需要它的原因不是性能(或分配); 在某些情況下需要獲得正確的行為。

對於基於數組的示例,請考慮以下代碼:

var a = [1, 2, 3];           // (1)
a.__proto__ = [11, 22, 33];  // (2)
delete a[1];                 // (3)
console.log(a[1]);           // (4)

這將打印22 ,因為a在概念上將在索引[1]處有一個“洞”,並且您可以“通過那個洞看到它的原型”,可以這么說。 (如果將第 (1) 行和第 (3) 行替換為var a = [1, , 3]您可以創建相同的情況。)如果a具有默認原型,則可以編寫a[1] = undefined而不是delete a[1] a[1] = undefined ,或者這就是delete可以在幕后做的事情,結果是一樣的。 但是對於自定義原型,有一個區別:如果您編寫a[1] = undefined而不是第 (3) 行,那么第 (4) 行將打印undefined 我們需要“洞”哨兵來區分元素[1]undefined還是根本不存在。

在其他一些情況下,區分“無值”和“定義為‘未定義’”是有用或必要的,例如對於塊范圍變量的“時間死區”。 舊式var - 變量隱式提升其聲明,而在定義之前訪問新式let - 變量是錯誤的。 正確的行為是:

var a = 1; print(a);  // 1
let b = 1; print(b);  // 1
print(c); var c = 1;  // undefined
print(d); let d = 1;  // ReferenceError: Cannot access 'd' before initialization
print(e);             // ReferenceError: e is not defined

所以print語句(這只是一個例子;對於許多其他操作也是如此)必須根據周圍的代碼做三件不同的事情。 V8 通過在內部將這些行轉換為:

let c = undefined; print(c); c = 1;
let d = <TheHole>; print(d); d = 1;

這樣,當正在訪問的變量的值是“洞”時,系統就知道出了問題,所以在這種情況下,與其加載變量的值並將其傳遞給print function,它知道這一定是塊范圍的變量在其定義之前被訪問,因此它會產生適當的錯誤消息。

如果您想玩這些東西,請注意“洞”純粹是內部哨兵。 它永遠不會“泄漏”到 JavaScript。 無法從您的代碼中檢查變量或屬性當前是否具有此值。 這是一個隱藏的實現細節——引擎可以做不同的事情; 碰巧有一個內部“洞”哨兵是解決一堆問題的一種相當優雅和有效的方法,所以 V8 選擇這樣做。

我通過 v8/Chromium 代碼進行了谷歌搜索,看起來TheHole是未分配值的哨兵值。 在 JavaScript 的許多情況下,未分配的值被視為undefined (例如,在訪問尚未分配的數組元素或已聲明但從未分配的 var 時)。

但有時,解釋器需要區分什么時候沒有 value和什么時候設置為 undefined。 這是兩者之間的區別:

var a = [1,2];
console.log(a[2]);

var a = [1,2,3];
delete a[2];
console.log(a[2]);

在這兩種情況下,訪問 a[2] 將返回“未定義”,但在第二種情況下,數組的后備存儲(原始內存)的末尾有一個“洞”,這意味着如果您稍后為a[2] 再次,您不需要先將值復制到更大的數組中。 因此,TheHole 是用於“無”的值。 您不能為此使用undefined ,因為您可以將數組元素的值顯式設置為undefined

真正重要的是像 Array.splice 這樣的操作,或者任何搜索數組的操作。 如果您大量修改內聯數組的內容,您不希望每個操作都需要 memory 分配和釋放,因為這些操作很慢。

因此,LdaTheHole 用於在搜索數組之前初始化變量,或“清除”已刪除的數組值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM