From 1808f146771b2dd648246a780f1699d3da6491a7 Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Tue, 10 Aug 2021 12:47:39 +0300 Subject: [PATCH] Switch from using of MutableList to ArrayDeque in interpreter's stack --- .../kotlin/ir/interpreter/stack/CallStack.kt | 2 +- .../kotlin/ir/interpreter/stack/Frame.kt | 42 ++++++++++++------- 2 files changed, 29 insertions(+), 15 deletions(-) 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)