JVM don't merge local values in FixStackAnalyzer
We care only about stacks there. This yields about 10-15% in a pathological case such as KT-41510.
This commit is contained in:
committed by
teamcityserver
parent
230fce65e5
commit
e276dec4de
+33
-5
@@ -29,6 +29,7 @@ import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.JumpInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.LabelNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.Interpreter
|
||||
@@ -88,7 +89,9 @@ internal class FixStackAnalyzer(
|
||||
|
||||
private val analyzer = InternalAnalyzer(owner)
|
||||
|
||||
private inner class InternalAnalyzer(owner: String) : FlexibleMethodAnalyzer<BasicValue>(owner, method, OptimizationBasicInterpreter()) {
|
||||
private inner class InternalAnalyzer(owner: String) :
|
||||
FlexibleMethodAnalyzer<BasicValue>(owner, method, OptimizationBasicInterpreter()) {
|
||||
|
||||
val spilledStacks = hashMapOf<AbstractInsnNode, List<BasicValue>>()
|
||||
var maxExtraStackSize = 0; private set
|
||||
|
||||
@@ -166,13 +169,38 @@ internal class FixStackAnalyzer(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getStack(i: Int): BasicValue {
|
||||
return if (i < super.getMaxStackSize()) {
|
||||
super.getStack(i)
|
||||
override fun setStack(i: Int, value: BasicValue) {
|
||||
if (i < super.getMaxStackSize()) {
|
||||
super.setStack(i, value)
|
||||
} else {
|
||||
extraStack[i - maxStackSize]
|
||||
extraStack[i - maxStackSize] = value
|
||||
}
|
||||
}
|
||||
|
||||
override fun merge(frame: Frame<out BasicValue>, interpreter: Interpreter<BasicValue>): Boolean {
|
||||
val other = frame as FixStackFrame
|
||||
if (stackSizeWithExtra != other.stackSizeWithExtra) {
|
||||
throw AnalyzerException(null, "Incompatible stack heights")
|
||||
}
|
||||
var changed = false
|
||||
for (i in 0 until stackSize) {
|
||||
val v0 = super.getStack(i)
|
||||
val vm = interpreter.merge(v0, other.getStack(i))
|
||||
if (vm != v0) {
|
||||
super.setStack(i, vm)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
for (i in 0 until extraStack.size) {
|
||||
val v0 = extraStack[i]
|
||||
val vm = interpreter.merge(v0, other.extraStack[i])
|
||||
if (vm != v0) {
|
||||
extraStack[i] = vm
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
return changed
|
||||
}
|
||||
}
|
||||
|
||||
private fun FixStackFrame.executeBeforeInlineCallMarker(insn: AbstractInsnNode) {
|
||||
|
||||
+6
@@ -8112,6 +8112,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/controlStructures/quicksort.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("slowHtmlLikeDsl.kt")
|
||||
public void testSlowHtmlLikeDsl() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/controlStructures/slowHtmlLikeDsl.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("tcbInEliminatedCondition.kt")
|
||||
public void testTcbInEliminatedCondition() throws Exception {
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// ^ this test might be rather slow
|
||||
|
||||
class Builder(var content: String)
|
||||
|
||||
fun Builder.begin(t: String) {
|
||||
content += "<$t>"
|
||||
}
|
||||
|
||||
fun Builder.text(t: String) {
|
||||
content += t
|
||||
}
|
||||
|
||||
fun Builder.end(t: String) {
|
||||
content += "</$t>"
|
||||
}
|
||||
|
||||
fun err(e: Throwable) {}
|
||||
|
||||
inline fun Builder.tag(t: String, body: Builder.() -> Unit) {
|
||||
begin(t)
|
||||
try {
|
||||
body()
|
||||
} catch (e: Throwable) {
|
||||
err(e)
|
||||
} finally {
|
||||
end(t)
|
||||
}
|
||||
}
|
||||
|
||||
inline fun Builder.t2(body: Builder.() -> Unit) {
|
||||
tag("t", body)
|
||||
tag("t", body)
|
||||
}
|
||||
|
||||
val expectedLength = 1906
|
||||
|
||||
fun box(): String {
|
||||
val b = Builder("")
|
||||
b.t2 { t2 { t2 { t2 { t2 { t2 { t2 { text("1") } } } } } } }
|
||||
if (b.content.length != expectedLength)
|
||||
return "${b.content.length}"
|
||||
else
|
||||
return "OK"
|
||||
}
|
||||
+6
@@ -8112,6 +8112,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/controlStructures/quicksort.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("slowHtmlLikeDsl.kt")
|
||||
public void testSlowHtmlLikeDsl() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/controlStructures/slowHtmlLikeDsl.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("tcbInEliminatedCondition.kt")
|
||||
public void testTcbInEliminatedCondition() throws Exception {
|
||||
|
||||
+6
@@ -8112,6 +8112,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/controlStructures/quicksort.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("slowHtmlLikeDsl.kt")
|
||||
public void testSlowHtmlLikeDsl() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/controlStructures/slowHtmlLikeDsl.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("tcbInEliminatedCondition.kt")
|
||||
public void testTcbInEliminatedCondition() throws Exception {
|
||||
|
||||
+5
@@ -6217,6 +6217,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/controlStructures/quicksort.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("slowHtmlLikeDsl.kt")
|
||||
public void testSlowHtmlLikeDsl() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/controlStructures/slowHtmlLikeDsl.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("tcbInEliminatedCondition.kt")
|
||||
public void testTcbInEliminatedCondition() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/controlStructures/tcbInEliminatedCondition.kt");
|
||||
|
||||
Reference in New Issue
Block a user