2017-07-17 18 views
0

什麼是OOL(行外)代碼?我在ION編譯器中找到它,但無法理解正在發生的事情。OOL(行外)代碼

bool CodeGeneratorShared::generateOutOfLineCode() { 
    for (size_t i = 0; i < outOfLineCode_.length(); i++) { 
    // Add native => bytecode mapping entries for OOL sites. 
    // Not enabled on asm.js yet since asm doesn't contain bytecode mappings. 
    if (!gen->compilingAsmJS()) { 
     if (!addNativeToBytecodeEntry(outOfLineCode_[i]->bytecodeSite())) 
      return false; 
    } 

    if (!gen->alloc().ensureBallast()) 
     return false; 

    JitSpew(JitSpew_Codegen, "# Emitting out of line code"); 

    masm.setFramePushed(outOfLineCode_[i]->framePushed()); 
    lastPC_ = outOfLineCode_[i]->pc(); 
    outOfLineCode_[i]->bind(&masm); 

    outOfLineCode_[i]->generate(this); 
    } 

    return !masm.oom(); 
} 

我試圖用谷歌找到它的信息,但沒有成功。也許你可以給我一些想法是什麼?謝謝:)

+1

你能鏈接源代碼嗎? – Bergi

+0

所有代碼都很大。我只附加了生成行外代碼的方法。所以你可以從https://archive.mozilla.org/pub/mozilla.org/js/ – Mano

+0

克隆所有的代碼謝謝,是的,但具體哪個zip文件(或哪個引擎版本)是哪個文件? – Bergi

回答

2

我看了看源代碼,看起來這裏的「不符合」是指在​​普通代碼/函數之後生成的代碼。

參見例如CodeGenerator::generate基本上是這樣的:

generateProlog(); 
generateBody(); 
generateEpilog(); 
generateOutOfLineCode(); 

所以脫節的代碼代碼的結束後產生。這通常用於優異的控制流程,並且保留調用去優化,拋出異常等等的指令緩存和「正常」程序代碼。

假設我們有一個函數int f(int a, int b) { return a/b; }和語言語義迫使我們如果除數爲0。這引發異常是僞彙編代碼:

cmp b, 0 
    jump-if-not-zero lbl1 
    call throw_exception 

lbl1: 
    div c, a, b 
    ret c 

你可以看到,正常程序流的需求跳過引發異常的代碼。通常情況下b在幾乎所有情況下都不爲零,所以看起來很浪費。隨着脫節的代碼中,我們可以生成更高效的代碼:

cmp b, 0 
    jump-if-zero out-of-line1 
    div c, a, b 
    ret c 

out-of-line1: 
    call throw_exception 

在這裏我們只跳了零個值應該是罕見的。指令cmpdiv也彼此更接近,這對指令高速緩存的使用很有幫助。

在我的JIT中,我爲空指針異常拋出,失敗斷言等產生了行外代碼。JS和IonMonkey可能會將它用於不同的操作。我發現的一個非線性代碼示例是WASM的OutOfLineTruncateF32OrF64ToI32類,它將OutOfLineCode擴展爲所有不連續代碼的基類。

還有什麼更好的是,IonMonkey中的行外代碼可以使用rejoin字段跳轉回正常的代碼流。