JVM: refactor some SMAP-related classes
In particular, remove redundant copying from SMAPAndMethodNode (which also fails for empty methods).
This commit is contained in:
@@ -233,7 +233,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
val inliner = MethodInliner(
|
||||
node, parameters, info, FieldRemapper(null, null, parameters), isSameModule,
|
||||
"Method inlining " + sourceCompiler.callElementText,
|
||||
createNestedSourceMapper(nodeAndSmap, defaultSourceMapper), info.callSiteInfo,
|
||||
NestedSourceMapper(defaultSourceMapper, nodeAndSmap.classSMAP), info.callSiteInfo,
|
||||
if (functionDescriptor.isInlineOnly()) InlineOnlySmapSkipper(codegen) else null,
|
||||
!isInlinedToInlineFunInKotlinRuntime()
|
||||
) //with captured
|
||||
@@ -576,7 +576,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
result ?: throw IllegalStateException("Couldn't obtain compiled function body for $functionDescriptor")
|
||||
}
|
||||
|
||||
return resultInCache.copyWithNewNode(cloneMethodNode(resultInCache.node))
|
||||
return SMAPAndMethodNode(cloneMethodNode(resultInCache.node), resultInCache.classSMAP)
|
||||
}
|
||||
|
||||
private fun createDefaultFakeSMAP() = SMAPParser.parseOrCreateDefault(null, null, "fake", -1, -1)
|
||||
@@ -704,11 +704,6 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
fun createNestedSourceMapper(nodeAndSmap: SMAPAndMethodNode, parent: SourceMapper): SourceMapper {
|
||||
return NestedSourceMapper(parent, nodeAndSmap.sortedRanges, nodeAndSmap.classSMAP.sourceInfo)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ class InlineCodegenForDefaultBody(
|
||||
val nodeAndSmap = InlineCodegen.createInlineMethodNode(
|
||||
function, methodOwner, jvmSignature, callDefault, null, codegen.typeSystem, state, sourceCompilerForInline
|
||||
)
|
||||
val childSourceMapper = InlineCodegen.createNestedSourceMapper(nodeAndSmap, sourceMapper)
|
||||
val childSourceMapper = NestedSourceMapper(sourceMapper, nodeAndSmap.classSMAP)
|
||||
|
||||
val node = nodeAndSmap.node
|
||||
val transformedMethod = MethodNode(
|
||||
|
||||
@@ -284,10 +284,11 @@ class MethodInliner(
|
||||
|
||||
val childSourceMapper =
|
||||
if (inliningContext.classRegeneration && !inliningContext.isInliningLambda)
|
||||
NestedSourceMapper(sourceMapper, lambdaSMAP.intervals, lambdaSMAP.sourceInfo)
|
||||
else if (info is DefaultLambda) {
|
||||
NestedSourceMapper(sourceMapper.parent!!, lambdaSMAP.intervals, lambdaSMAP.sourceInfo)
|
||||
} else InlineLambdaSourceMapper(sourceMapper.parent!!, info.node)
|
||||
NestedSourceMapper(sourceMapper, lambdaSMAP)
|
||||
else if (info is DefaultLambda)
|
||||
NestedSourceMapper(sourceMapper.parent!!, lambdaSMAP)
|
||||
else
|
||||
SameFileNestedSourceMapper(sourceMapper.parent!!, info.node.classSMAP)
|
||||
|
||||
val inliner = MethodInliner(
|
||||
info.node.node, lambdaParameters, inliningContext.subInlineLambda(info),
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.codegen.inline.SMAP.Companion.FILE_SECTION
|
||||
import org.jetbrains.kotlin.codegen.inline.SMAP.Companion.LINE_SECTION
|
||||
import org.jetbrains.kotlin.codegen.inline.SMAP.Companion.STRATA_SECTION
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
import java.util.*
|
||||
import kotlin.math.max
|
||||
|
||||
@@ -86,8 +87,8 @@ class SMAPBuilder(
|
||||
}
|
||||
|
||||
open class NestedSourceMapper(
|
||||
override val parent: SourceMapper, val ranges: List<RangeMapping>, sourceInfo: SourceInfo
|
||||
) : DefaultSourceMapper(sourceInfo) {
|
||||
override val parent: SourceMapper, protected val smap: SMAP
|
||||
) : DefaultSourceMapper(smap.sourceInfo) {
|
||||
|
||||
private val visitedLines = TIntIntHashMap()
|
||||
|
||||
@@ -104,7 +105,7 @@ open class NestedSourceMapper(
|
||||
mappedLineNumber
|
||||
} else {
|
||||
val rangeForMapping =
|
||||
(if (lastVisitedRange?.contains(lineNumber) == true) lastVisitedRange!! else findMappingIfExists(lineNumber))
|
||||
(if (lastVisitedRange?.contains(lineNumber) == true) lastVisitedRange!! else smap.findRange(lineNumber))
|
||||
?: error("Can't find range to map line $lineNumber in ${sourceInfo.source}: ${sourceInfo.pathOrCleanFQN}")
|
||||
val sourceLineNumber = rangeForMapping.mapDestToSource(lineNumber)
|
||||
val newLineNumber = parent.mapLineNumber(sourceLineNumber, rangeForMapping.parent!!.name, rangeForMapping.parent!!.path)
|
||||
@@ -115,22 +116,12 @@ open class NestedSourceMapper(
|
||||
newLineNumber
|
||||
}
|
||||
}
|
||||
|
||||
private fun findMappingIfExists(lineNumber: Int): RangeMapping? {
|
||||
val index = ranges.binarySearch(RangeMapping(lineNumber, lineNumber, 1), Comparator { value, key ->
|
||||
if (key.dest in value) 0 else RangeMapping.Comparator.compare(value, key)
|
||||
})
|
||||
return if (index < 0) null else ranges[index]
|
||||
}
|
||||
}
|
||||
|
||||
open class InlineLambdaSourceMapper(
|
||||
parent: SourceMapper, smap: SMAPAndMethodNode
|
||||
) : NestedSourceMapper(parent, smap.sortedRanges, smap.classSMAP.sourceInfo) {
|
||||
|
||||
open class SameFileNestedSourceMapper(parent: SourceMapper, smap: SMAP) : NestedSourceMapper(parent, smap) {
|
||||
override fun mapLineNumber(lineNumber: Int): Int {
|
||||
if (ranges.firstOrNull()?.contains(lineNumber) == true) {
|
||||
//don't remap origin lambda line numbers
|
||||
if (lineNumber <= smap.sourceInfo.linesInFile) {
|
||||
// assuming the parent source mapper is for the same file, this line number does not need remapping
|
||||
return lineNumber
|
||||
}
|
||||
return super.mapLineNumber(lineNumber)
|
||||
@@ -250,20 +241,20 @@ open class DefaultSourceMapper(val sourceInfo: SourceInfo) : SourceMapper {
|
||||
}
|
||||
|
||||
class SMAP(val fileMappings: List<FileMapping>) {
|
||||
init {
|
||||
val sourceInfo: SourceInfo = run {
|
||||
assert(fileMappings.isNotEmpty()) { "File Mappings shouldn't be empty" }
|
||||
val defaultFile = fileMappings.first()
|
||||
val defaultRange = defaultFile.lineMappings.first()
|
||||
SourceInfo(defaultFile.name, defaultFile.path, defaultRange.source + defaultRange.range - 1)
|
||||
}
|
||||
|
||||
val default: FileMapping
|
||||
get() = fileMappings.first()
|
||||
private val intervals = fileMappings.flatMap { it.lineMappings }.sortedWith(RangeMapping.Comparator)
|
||||
|
||||
val intervals = fileMappings.flatMap { it.lineMappings }.sortedWith(RangeMapping.Comparator)
|
||||
|
||||
val sourceInfo: SourceInfo
|
||||
|
||||
init {
|
||||
val defaultMapping = default.lineMappings.first()
|
||||
sourceInfo = SourceInfo(default.name, default.path, defaultMapping.source + defaultMapping.range - 1)
|
||||
fun findRange(lineNumber: Int): RangeMapping? {
|
||||
val index = intervals.binarySearch(RangeMapping(lineNumber, lineNumber, 1), Comparator { value, key ->
|
||||
if (key.dest in value) 0 else RangeMapping.Comparator.compare(value, key)
|
||||
})
|
||||
return if (index < 0) null else intervals[index]
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -274,6 +265,7 @@ class SMAP(val fileMappings: List<FileMapping>) {
|
||||
}
|
||||
}
|
||||
|
||||
data class SMAPAndMethodNode(val node: MethodNode, val classSMAP: SMAP)
|
||||
|
||||
class RawFileMapping(val name: String, val path: String) {
|
||||
private val rangeMappings = arrayListOf<RangeMapping>()
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.org.objectweb.asm.tree.LineNumberNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
import java.util.*
|
||||
|
||||
//TODO comment
|
||||
class SMAPAndMethodNode(val node: MethodNode, val classSMAP: SMAP) {
|
||||
val sortedRanges = createLineNumberSequence(node, classSMAP).distinct().toList().sortedWith(RangeMapping.Comparator)
|
||||
|
||||
fun copyWithNewNode(newMethodNode: MethodNode) = SMAPAndMethodNode(newMethodNode, classSMAP)
|
||||
}
|
||||
|
||||
private fun createLineNumberSequence(node: MethodNode, classSMAP: SMAP): Sequence<RangeMapping> {
|
||||
return InsnSequence(node.instructions.first, null).filterIsInstance<LineNumberNode>().map { lineNumber ->
|
||||
val mapping = RangeMapping(lineNumber.line, lineNumber.line, 1)
|
||||
|
||||
if (lineNumber.line in JvmAbi.SYNTHETIC_MARKER_LINE_NUMBERS) {
|
||||
return@map mapping
|
||||
}
|
||||
|
||||
val index = classSMAP.intervals.binarySearch(mapping, Comparator { value, key ->
|
||||
if (key.dest in value) 0 else RangeMapping.Comparator.compare(value, key)
|
||||
})
|
||||
if (index < 0) {
|
||||
error("Unmapped line number in inlined function ${node.name}:${lineNumber.line}")
|
||||
}
|
||||
classSMAP.intervals[index]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user