Remove external finally block interval on splitting during inline

#KT-20433 Fixed
This commit is contained in:
Mikhael Bogdanov
2017-11-03 14:08:10 +01:00
parent f51709e61c
commit 800cc63347
12 changed files with 330 additions and 4 deletions
@@ -22,8 +22,8 @@ import org.jetbrains.org.objectweb.asm.tree.*
import java.util.*
abstract class CoveringTryCatchNodeProcessor(parameterSize: Int) {
val tryBlocksMetaInfo: IntervalMetaInfo<TryCatchBlockNodeInfo> = IntervalMetaInfo()
val localVarsMetaInfo: IntervalMetaInfo<LocalVarNodeWrapper> = IntervalMetaInfo()
val tryBlocksMetaInfo: IntervalMetaInfo<TryCatchBlockNodeInfo> = IntervalMetaInfo(this)
val localVarsMetaInfo: IntervalMetaInfo<LocalVarNodeWrapper> = IntervalMetaInfo(this)
var nextFreeLocalIndex: Int = parameterSize
private set
@@ -84,24 +84,27 @@ abstract class CoveringTryCatchNodeProcessor(parameterSize: Int) {
}
}
class IntervalMetaInfo<T : SplittableInterval<T>> {
class IntervalMetaInfo<T : SplittableInterval<T>>(private val processor: CoveringTryCatchNodeProcessor) {
val intervalStarts = LinkedListMultimap.create<LabelNode, T>()
val intervalEnds = LinkedListMultimap.create<LabelNode, T>()
val allIntervals: ArrayList<T> = arrayListOf()
val currentIntervals: MutableSet<T> = linkedSetOf()
fun addNewInterval(newInfo: T) {
newInfo.verify(processor)
intervalStarts.put(newInfo.startLabel, newInfo)
intervalEnds.put(newInfo.endLabel, newInfo)
allIntervals.add(newInfo)
}
private fun remapStartLabel(oldStart: LabelNode, remapped: T) {
remapped.verify(processor)
intervalStarts.remove(oldStart, remapped)
intervalStarts.put(remapped.startLabel, remapped)
}
private fun remapEndLabel(oldEnd: LabelNode, remapped: T) {
remapped.verify(processor)
intervalEnds.remove(oldEnd, remapped)
intervalEnds.put(remapped.endLabel, remapped)
}
@@ -110,6 +113,10 @@ class IntervalMetaInfo<T : SplittableInterval<T>> {
return currentIntervals.map { split(it, by, keepStart) }
}
fun splitAndRemoveCurrentIntervals(by: Interval, keepStart: Boolean) {
currentIntervals.map { splitAndRemoveInterval(it, by, keepStart) }
}
fun processCurrent(curIns: LabelNode, directOrder: Boolean) {
getInterval(curIns, directOrder).forEach {
val added = currentIntervals.add(it)
@@ -366,7 +366,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
insertNodeBefore(finallyNode, intoNode, curInstr)
val splitBy = SimpleInterval(start.info as LabelNode, extension.finallyIntervalEnd)
processor.tryBlocksMetaInfo.splitCurrentIntervals(splitBy, true)
processor.tryBlocksMetaInfo.splitAndRemoveCurrentIntervals(splitBy, true)
//processor.getLocalVarsMetaInfo().splitAndRemoveIntervalsFromCurrents(splitBy);
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
import org.jetbrains.org.objectweb.asm.tree.LabelNode
import org.jetbrains.org.objectweb.asm.tree.TryCatchBlockNode
@@ -35,6 +36,12 @@ interface Interval {
/*note that some intervals are mutable */
fun isEmpty(): Boolean = startLabel == endLabel
fun verify(processor: CoveringTryCatchNodeProcessor) {
assert (processor.instructionIndex(startLabel) <= processor.instructionIndex(endLabel)) {
"Try block body starts after body end: ${processor.instructionIndex(startLabel)} > ${processor.instructionIndex(endLabel)}"
}
}
}
interface SplittableInterval<out T : Interval> : Interval {
@@ -77,6 +84,9 @@ class TryCatchBlockNodeInfo(
}
}
val TryCatchBlockNodeInfo.bodyInstuctions
get() = InsnSequence(startLabel, endLabel)
class TryCatchBlockNodePosition(
val nodeInfo: TryCatchBlockNodeInfo,
var position: TryCatchPosition