[K/N][codegen] Fixed bug with huge arrays during escape analysis
Escape analysis tried to allocate some very big arrays on the stack because an overflow happened during size computation
This commit is contained in:
+11
-10
@@ -656,8 +656,8 @@ internal object EscapeAnalysis {
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun arraySize(itemSize: Int, length: Int) =
|
private fun arraySize(itemSize: Int, length: Int): Long =
|
||||||
pointerSize /* typeinfo */ + 4 /* size */ + itemSize * length
|
pointerSize /* typeinfo */ + 4 /* size */ + itemSize * length.toLong()
|
||||||
|
|
||||||
private fun analyze(callGraph: CallGraph, pointsToGraph: PointsToGraph, function: DataFlowIR.FunctionSymbol.Declared) {
|
private fun analyze(callGraph: CallGraph, pointsToGraph: PointsToGraph, function: DataFlowIR.FunctionSymbol.Declared) {
|
||||||
context.log {"Before calls analysis" }
|
context.log {"Before calls analysis" }
|
||||||
@@ -1573,6 +1573,8 @@ internal object EscapeAnalysis {
|
|||||||
|
|
||||||
escapeOrigins.forEach { propagateEscapeOrigin(it) }
|
escapeOrigins.forEach { propagateEscapeOrigin(it) }
|
||||||
|
|
||||||
|
// TODO: To a setting?
|
||||||
|
val allowedToAlloc = 65536
|
||||||
val stackArrayCandidates = mutableListOf<ArrayStaticAllocation>()
|
val stackArrayCandidates = mutableListOf<ArrayStaticAllocation>()
|
||||||
for ((node, ptgNode) in nodes) {
|
for ((node, ptgNode) in nodes) {
|
||||||
if (node.ir == null) continue
|
if (node.ir == null) continue
|
||||||
@@ -1592,9 +1594,9 @@ internal object EscapeAnalysis {
|
|||||||
if (itemSize != null) {
|
if (itemSize != null) {
|
||||||
val sizeArgument = node.arguments.first().node
|
val sizeArgument = node.arguments.first().node
|
||||||
val arrayLength = arrayLengthOf(sizeArgument)
|
val arrayLength = arrayLengthOf(sizeArgument)
|
||||||
if (arrayLength != null) {
|
val arraySize = arraySize(itemSize, arrayLength ?: Int.MAX_VALUE)
|
||||||
stackArrayCandidates +=
|
if (arraySize <= allowedToAlloc) {
|
||||||
ArrayStaticAllocation(ptgNode, irClass, arraySize(itemSize, arrayLength))
|
stackArrayCandidates += ArrayStaticAllocation(ptgNode, irClass, arraySize.toInt())
|
||||||
} else {
|
} else {
|
||||||
// Can be placed into the local arena.
|
// Can be placed into the local arena.
|
||||||
// TODO. Support Lifetime.LOCAL
|
// TODO. Support Lifetime.LOCAL
|
||||||
@@ -1616,14 +1618,13 @@ internal object EscapeAnalysis {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stackArrayCandidates.sortBy { it.size }
|
stackArrayCandidates.sortBy { it.size }
|
||||||
// TODO: To a setting?
|
var remainedToAlloc = allowedToAlloc
|
||||||
var allowedToAlloc = 65536
|
|
||||||
for ((ptgNode, irClass, size) in stackArrayCandidates) {
|
for ((ptgNode, irClass, size) in stackArrayCandidates) {
|
||||||
if (lifetimeOf(ptgNode) != Lifetime.STACK) continue
|
if (lifetimeOf(ptgNode) != Lifetime.STACK) continue
|
||||||
if (size <= allowedToAlloc)
|
if (size <= remainedToAlloc)
|
||||||
allowedToAlloc -= size
|
remainedToAlloc -= size
|
||||||
else {
|
else {
|
||||||
allowedToAlloc = 0
|
remainedToAlloc = 0
|
||||||
// Do not exile primitive arrays - they ain't reference no object.
|
// Do not exile primitive arrays - they ain't reference no object.
|
||||||
if (irClass.symbol == symbols.array && propagateExiledToHeapObjects) {
|
if (irClass.symbol == symbols.array && propagateExiledToHeapObjects) {
|
||||||
context.log { "Forcing node ${nodeToString(ptgNode.node!!)} to escape" }
|
context.log { "Forcing node ${nodeToString(ptgNode.node!!)} to escape" }
|
||||||
|
|||||||
Reference in New Issue
Block a user