diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/CallStack.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/CallStack.kt
index 7bec64dff7e..e85e5941f66 100644
--- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/CallStack.kt
+++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/CallStack.kt
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.fileOrNull
internal class CallStack {
- private val frames = mutableListOf()
+ private val frames = ArrayDeque()
private val currentFrame get() = frames.last()
internal val currentFrameOwner get() = currentFrame.currentSubFrameOwner
diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/Frame.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/Frame.kt
index 5b2154c9101..232a452217e 100644
--- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/Frame.kt
+++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/Frame.kt
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
internal class Frame(subFrameOwner: IrElement, val irFile: IrFile? = null) {
- private val innerStack = mutableListOf(SubFrame(subFrameOwner))
+ private val innerStack = ArrayDeque().apply { add(SubFrame(subFrameOwner)) }
private var currentInstruction: Instruction? = null
private val currentFrame get() = innerStack.last()
@@ -32,8 +32,9 @@ internal class Frame(subFrameOwner: IrElement, val irFile: IrFile? = null) {
}
fun removeSubFrame() {
- currentFrame.peekState()?.let { if (innerStack.size > 1) innerStack[innerStack.size - 2].pushState(it) }
+ val state = currentFrame.peekState()
removeSubFrameWithoutDataPropagation()
+ if (!hasNoSubFrames() && state != null) currentFrame.pushState(state)
}
fun removeSubFrameWithoutDataPropagation() {
@@ -68,19 +69,32 @@ internal class Frame(subFrameOwner: IrElement, val irFile: IrFile? = null) {
currentFrame.addVariable(symbol, variable)
}
- fun getState(symbol: IrSymbol): State {
- return (innerStack.lastIndex downTo 0).firstNotNullOfOrNull { innerStack[it].getState(symbol) }
- ?: throw InterpreterError("$symbol not found") // TODO better message
- }
-
- fun setState(symbol: IrSymbol, newState: State) {
+ private inline fun forEachSubFrame(block: (SubFrame) -> Unit) {
+ // TODO speed up reverse iteration or do it forward
(innerStack.lastIndex downTo 0).forEach {
- if (innerStack[it].containsVariable(symbol))
- return innerStack[it].setState(symbol, newState)
+ block(innerStack[it])
}
}
- fun containsVariable(symbol: IrSymbol): Boolean = (innerStack.lastIndex downTo 0).any { innerStack[it].containsVariable(symbol) }
+ fun getState(symbol: IrSymbol): State {
+ forEachSubFrame {
+ it.getState(symbol)?.let { state -> return state }
+ }
+ throw InterpreterError("$symbol not found") // TODO better message
+ }
+
+ fun setState(symbol: IrSymbol, newState: State) {
+ forEachSubFrame {
+ if (it.containsVariable(symbol)) return it.setState(symbol, newState)
+ }
+ }
+
+ fun containsVariable(symbol: IrSymbol): Boolean {
+ forEachSubFrame {
+ if (it.containsVariable(symbol)) return true
+ }
+ return false
+ }
fun copyMemoryInto(newFrame: Frame) {
this.getAll().forEach { (symbol, variable) -> if (!newFrame.containsVariable(symbol)) newFrame.addVariable(symbol, variable) }
@@ -119,13 +133,13 @@ internal class Frame(subFrameOwner: IrElement, val irFile: IrFile? = null) {
}
private class SubFrame(val owner: IrElement) {
- private val instructions = mutableListOf()
+ private val instructions = ArrayDeque()
private val dataStack = DataStack()
private val memory = mutableMapOf()
// Methods to work with instruction
fun isEmpty() = instructions.isEmpty()
- fun pushInstruction(instruction: Instruction) = instructions.add(0, instruction)
+ fun pushInstruction(instruction: Instruction) = instructions.addFirst(instruction)
fun popInstruction(): Instruction = instructions.removeFirst()
fun dropInstructions() = instructions.lastOrNull()?.apply { instructions.clear() }
@@ -153,7 +167,7 @@ private class SubFrame(val owner: IrElement) {
}
private class DataStack {
- private val stack = mutableListOf()
+ private val stack = ArrayDeque()
fun push(state: State) {
stack.add(state)