0

What is OOL (Out of line) code? I've found it in ION compiler but can't understand what is going on.

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();
}

I've tried to use google to found information about it, but didn't have a success. Maybe you can give me some idea what it is? Thank you :)

4

1 回答 1

2

我查看了源代码,似乎这里的“异常”是指在正常代码/函数之后生成的代码。

看egCodeGenerator::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 可以将它用于不同的操作。我发现的离线代码的一个例子是OutOfLineTruncateF32OrF64ToI32WASM 的类,它扩展OutOfLineCode了所有离线代码的基类。

另一个好处是,IonMonkey 中的行外代码可以使用该字段rejoin跳回正常的代码流。

于 2017-07-27T11:00:47.053 回答