OOL(脱机)代码

时间:2017-07-17 05:06:24

标签: javascript compiler-construction ionmonkey

OOL(Out of line)代码是什么?我在ION编译器中发现了它,但无法理解发生了什么。

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 个答案:

答案 0 :(得分:2)

我查看了源代码,这里的“out of line”似乎意味着在正常代码/函数之后生成的代码。

参见例如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跳回正常的代码流,这也很好。