【发布时间】:2019-11-10 17:09:19
【问题描述】:
我今天有一个想法,可以通过构造一个迭代计数器来实现对数组的边界检查循环,该计数器将在最后一次递增时溢出并根据生成的溢出中断停止执行。
所以假设你有一个数组,例如int[32] 并且您想要迭代它。为了避免每次循环运行中的边界检查,您现在可以做的是为溢出中断注册一个中断处理程序并将一个寄存器分配给值MAX - 32。该寄存器在每次循环迭代运行时递增,最后一次迭代运行将溢出,即触发中断处理程序。假设中断处理程序可以增加原始函数的程序计数器,这种机制可以用来避免边界检查。
这样的代码
for (int i = 0; i < array.length; i++) {
// do something
}
可以像这样实现
// setup interrupt somehow
SOME_REGISTER = MAX - array.length;
while (true) {
// do something
SOME_REGISTER++;
}
我不知道这是否可行,但我听说 Java 正在做类似的事情来避免在运行时生成的代码中进行空检查。您认为这是可行的,还是任何语言运行时都考虑过/尝试过?
【问题讨论】:
-
这个明显的问题是大多数系统没有在溢出时自动生成中断的方法。 Java 依靠地址 0 未映射到有效内存这一事实来避免空检查,并且任何访问内存中此位置(以及任何更高的地址直到某个点)的尝试都将导致 Java 运行时可以捕获的页面错误.这得到了广泛的 CPU 的支持,并且是现代非嵌入式操作系统的默认行为。
标签: arrays assembly runtime interrupt bounds-check-elimination