Use non-local functions to avoid creating lambdas in heap
This commit is contained in:
committed by
Nikolay Krasko
parent
99a693a14b
commit
909ced5fa2
@@ -17,13 +17,13 @@
|
|||||||
package org.jetbrains.kotlin.cfg.pseudocodeTraverser
|
package org.jetbrains.kotlin.cfg.pseudocodeTraverser
|
||||||
|
|
||||||
import org.jetbrains.kotlin.cfg.ControlFlowInfo
|
import org.jetbrains.kotlin.cfg.ControlFlowInfo
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.*
|
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode
|
||||||
import java.util.*
|
|
||||||
import org.jetbrains.kotlin.cfg.pseudocodeTraverser.TraversalOrder.FORWARD
|
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.special.SubroutineSinkInstruction
|
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.special.LocalFunctionDeclarationInstruction
|
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
|
||||||
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.special.LocalFunctionDeclarationInstruction
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.special.SubroutineEnterInstruction
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.special.SubroutineEnterInstruction
|
||||||
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.special.SubroutineSinkInstruction
|
||||||
|
import org.jetbrains.kotlin.cfg.pseudocodeTraverser.TraversalOrder.FORWARD
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
fun Pseudocode.traverse(
|
fun Pseudocode.traverse(
|
||||||
traversalOrder: TraversalOrder,
|
traversalOrder: TraversalOrder,
|
||||||
@@ -109,26 +109,7 @@ private fun <I : ControlFlowInfo<*>> Pseudocode.collectDataFromSubgraph(
|
|||||||
if (!isLocal && isStart)
|
if (!isLocal && isStart)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
fun getPreviousIncludingSubGraphInstructions(): Collection<Instruction> {
|
val previousInstructions = getPreviousIncludingSubGraphInstructions(instruction, traversalOrder, startInstruction, previousSubGraphInstructions)
|
||||||
val previous = instruction.getPreviousInstructions(traversalOrder)
|
|
||||||
if (instruction != startInstruction || previousSubGraphInstructions.isEmpty()) {
|
|
||||||
return previous
|
|
||||||
}
|
|
||||||
val result = ArrayList(previous)
|
|
||||||
result.addAll(previousSubGraphInstructions)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
val previousInstructions = getPreviousIncludingSubGraphInstructions()
|
|
||||||
|
|
||||||
fun updateEdgeDataForInstruction(
|
|
||||||
previousValue: Edges<I>?,
|
|
||||||
newValue: Edges<I>?
|
|
||||||
) {
|
|
||||||
if (previousValue != newValue && newValue != null) {
|
|
||||||
changed[0] = true
|
|
||||||
edgesMap.put(instruction, newValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instruction is LocalFunctionDeclarationInstruction) {
|
if (instruction is LocalFunctionDeclarationInstruction) {
|
||||||
val subroutinePseudocode = instruction.body
|
val subroutinePseudocode = instruction.body
|
||||||
@@ -146,7 +127,7 @@ private fun <I : ControlFlowInfo<*>> Pseudocode.collectDataFromSubgraph(
|
|||||||
else
|
else
|
||||||
Edges(updateEdge(lastInstruction, instruction, newValue.incoming),
|
Edges(updateEdge(lastInstruction, instruction, newValue.incoming),
|
||||||
updateEdge(lastInstruction, instruction, newValue.outgoing))
|
updateEdge(lastInstruction, instruction, newValue.outgoing))
|
||||||
updateEdgeDataForInstruction(previousValue, updatedValue)
|
updateEdgeDataForInstruction(instruction, previousValue, updatedValue, edgesMap, changed)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,7 +143,30 @@ private fun <I : ControlFlowInfo<*>> Pseudocode.collectDataFromSubgraph(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val mergedData = mergeEdges(instruction, incomingEdgesData)
|
val mergedData = mergeEdges(instruction, incomingEdgesData)
|
||||||
updateEdgeDataForInstruction(previousDataValue, mergedData)
|
updateEdgeDataForInstruction(instruction, previousDataValue, mergedData, edgesMap, changed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getPreviousIncludingSubGraphInstructions(
|
||||||
|
instruction: Instruction,
|
||||||
|
traversalOrder: TraversalOrder,
|
||||||
|
startInstruction: Instruction,
|
||||||
|
previousSubGraphInstructions: Collection<Instruction>
|
||||||
|
): Collection<Instruction> {
|
||||||
|
val previous = instruction.getPreviousInstructions(traversalOrder)
|
||||||
|
if (instruction != startInstruction || previousSubGraphInstructions.isEmpty()) {
|
||||||
|
return previous
|
||||||
|
}
|
||||||
|
val result = ArrayList(previous)
|
||||||
|
result.addAll(previousSubGraphInstructions)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <I : ControlFlowInfo<*>> updateEdgeDataForInstruction(
|
||||||
|
instruction: Instruction, previousValue: Edges<I>?, newValue: Edges<I>?, edgesMap: MutableMap<Instruction, Edges<I>>, changed: BooleanArray) {
|
||||||
|
if (previousValue != newValue && newValue != null) {
|
||||||
|
changed[0] = true
|
||||||
|
edgesMap.put(instruction, newValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user