2017-07-17 17 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字段跳转回正常的代码流。