Added additional strata for stacktraces

This commit is contained in:
Michael Bogdanov
2016-03-22 12:32:31 +03:00
parent f6edf311d7
commit af68f3d019
5 changed files with 52 additions and 16 deletions
@@ -86,7 +86,8 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
protected ExpressionCodegen clInit;
private NameGenerator inlineNameGenerator;
private SourceMapper sourceMapper;
private DefaultSourceMapper sourceMapper;
private final ConstantExpressionEvaluator constantExpressionEvaluator;
public MemberCodegen(
@@ -557,7 +558,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
}
@NotNull
public SourceMapper getOrCreateSourceMapper() {
public DefaultSourceMapper getOrCreateSourceMapper() {
if (sourceMapper == null) {
sourceMapper = new DefaultSourceMapper(SourceInfo.Companion.createInfo(element, getClassName()));
}
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.builtins.BuiltInsPackageFragment;
import org.jetbrains.kotlin.codegen.*;
import org.jetbrains.kotlin.codegen.context.*;
import org.jetbrains.kotlin.codegen.inline2.*;
import org.jetbrains.kotlin.codegen.inline2.DefaultSourceMapper;
import org.jetbrains.kotlin.codegen.inline2.NestedSourceMapper;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicArrayConstructorsKt;
import org.jetbrains.kotlin.codegen.state.GenerationState;
@@ -352,6 +353,8 @@ public class InlineCodegen extends CallGenerator {
}
private InlineResult inlineCall(SMAPAndMethodNode nodeAndSmap) {
DefaultSourceMapper defaultSourceMapper = codegen.getParentCodegen().getOrCreateSourceMapper();
defaultSourceMapper.setCallSiteMarker(new CallSiteMarker(codegen.getLastLineNumber()));
MethodNode node = nodeAndSmap.getNode();
ReifiedTypeParametersUsages reificationResult = reifiedTypeInliner.reifyInstructions(node);
generateClosuresBodies();
@@ -402,6 +405,8 @@ public class InlineCodegen extends CallGenerator {
addInlineMarker(codegen.v, false);
defaultSourceMapper.setCallSiteMarker(null);
return result;
}
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.codegen.inline
import gnu.trove.TIntIntHashMap
import org.jetbrains.kotlin.codegen.ClassBuilder
import org.jetbrains.kotlin.codegen.SourceInfo
import org.jetbrains.kotlin.codegen.inline2.CallSiteMarker
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.MethodVisitor
import java.util.*
@@ -29,10 +30,10 @@ class SMAPBuilder(
val path: String,
val fileMappings: List<FileMapping>
) {
private val header = "SMAP\n$source\nKotlin\n*S Kotlin"
private val header = "SMAP\n$source\nKotlin"
fun build(): String? {
var realMappings = fileMappings.filter {
val realMappings = fileMappings.filter {
val mappings = it.lineMappings
mappings.isNotEmpty() && mappings.first() != RangeMapping.SKIP
}
@@ -41,10 +42,32 @@ class SMAPBuilder(
return null
}
val defaultStrata = generateDefaultStrata(realMappings)
val debugStrata = generateDebugStrata(realMappings)
return "$header\n$defaultStrata$debugStrata"
}
private fun generateDefaultStrata(realMappings: List<FileMapping>): String {
val fileIds = "*F" + realMappings.mapIndexed { id, file -> "\n${file.toSMAPFile(id + 1)}" }.joinToString("")
val lineMappings = "*L" + realMappings.joinToString("") { it.toSMAPMapping() }
return "*S Kotlin\n$fileIds\n$lineMappings\n*E\n"
}
return "$header\n$fileIds\n$lineMappings\n*E\n"
private fun generateDebugStrata(realMappings: List<FileMapping>): String {
val combinedMapping = FileMapping(source, path)
realMappings.forEach { fileMapping ->
fileMapping.lineMappings.filter { it.callSiteMarker != null }.forEach { rangeMapping ->
combinedMapping.addRangeMapping(RangeMapping(rangeMapping.callSiteMarker!!.lineNumber, rangeMapping.dest, rangeMapping.range))
}
}
if (combinedMapping.lineMappings.isEmpty()) return ""
val newMappings = listOf(combinedMapping)
val fileIds = "*F" + newMappings.mapIndexed { id, file -> "\n${file.toSMAPFile(id + 1)}" }.joinToString("")
val lineMappings = "*L" + newMappings.joinToString("") { it.toSMAPMapping() }
return "*S KotlinDebug\n$fileIds\n$lineMappings\n*E\n"
}
private fun RangeMapping.toSMAP(fileId: Int): String {
@@ -145,9 +168,7 @@ interface SourceMapper {
companion object {
fun flushToClassBuilder(mapper: SourceMapper, v: ClassBuilder) {
for (fileMapping in mapper.resultMappings) {
v.addSMAP(fileMapping)
}
mapper.resultMappings.forEach { fileMapping -> v.addSMAP(fileMapping) }
}
fun createFromSmap(smap: SMAP): SourceMapper {
@@ -333,7 +354,7 @@ open class FileMapping(val name: String, val path: String) {
}
//TODO comparable
data class RangeMapping(val source: Int, val dest: Int, var range: Int = 1) {
data class RangeMapping(val source: Int, val dest: Int, var range: Int = 1, var callSiteMarker: CallSiteMarker? = null) {
var parent: FileMapping? = null
private val skip = source == -1 && dest == -1
@@ -370,3 +391,6 @@ data class RangeMapping(val source: Int, val dest: Int, var range: Int = 1) {
val SKIP = RangeMapping(-1, -1, 1)
}
}
val RangeMapping.toRange: IntRange
get() = this.dest..this.maxDest
@@ -26,6 +26,9 @@ import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.MethodVisitor
import java.util.*
class CallSiteMarker(val lineNumber: Int)
open class NestedSourceMapper(
override val parent: SourceMapper, val ranges: List<RangeMapping>, sourceInfo: SourceInfo
) : DefaultSourceMapper(sourceInfo) {
@@ -86,6 +89,12 @@ open class DefaultSourceMapper @JvmOverloads constructor(
protected var maxUsedValue: Int = sourceInfo.linesInFile
) : SourceMapper {
var callSiteMarker: CallSiteMarker? = null;
set(value) {
lastMappedWithChanges = null
field = value
}
var lastVisited: RawFileMapping? = null
private var lastMappedWithChanges: RawFileMapping? = null
private var fileMappings: LinkedHashMap<String, RawFileMapping> = linkedMapOf()
@@ -139,8 +148,7 @@ open class DefaultSourceMapper @JvmOverloads constructor(
protected fun createMapping(lineNumber: Int): Int {
val fileMapping = lastVisited!!
//val mappedLineIndex = fileMapping.mapLine(lineNumber, maxUsedValue, lastMappedWithChanges == lastVisited)
val mappedLineIndex = fileMapping.mapNewLineNumber(lineNumber, maxUsedValue, lastMappedWithChanges == lastVisited)
val mappedLineIndex = fileMapping.mapNewLineNumber(lineNumber, maxUsedValue, lastMappedWithChanges == lastVisited, callSiteMarker)
if (mappedLineIndex > maxUsedValue) {
lastMappedWithChanges = fileMapping
maxUsedValue = mappedLineIndex
@@ -167,7 +175,7 @@ class RawFileMapping(val name: String, val path: String) {
lastMappedWithNewIndex = end
}
fun mapNewLineNumber(source: Int, currentIndex: Int, isLastMapped: Boolean): Int {
fun mapNewLineNumber(source: Int, currentIndex: Int, isLastMapped: Boolean, callSiteMarker: CallSiteMarker?): Int {
val dest: Int
val rangeMapping: RangeMapping
if (rangeMappings.isNotEmpty() && isLastMapped && couldFoldInRange(lastMappedWithNewIndex, source)) {
@@ -177,7 +185,7 @@ class RawFileMapping(val name: String, val path: String) {
}
else {
dest = currentIndex + 1
rangeMapping = RangeMapping(source, dest)
rangeMapping = RangeMapping(source, dest, callSiteMarker = callSiteMarker)
rangeMappings.add(rangeMapping)
}
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.backend.common.output.OutputFile
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil
import org.jetbrains.kotlin.codegen.inline.RangeMapping
import org.jetbrains.kotlin.codegen.inline.SMAPParser
import org.jetbrains.kotlin.codegen.inline.toRange
import org.jetbrains.kotlin.utils.keysToMap
import org.jetbrains.org.objectweb.asm.ClassReader
import org.jetbrains.org.objectweb.asm.ClassVisitor
@@ -121,6 +122,3 @@ object SMAPTestUtil {
}
}
}
val RangeMapping.toRange: IntRange
get() = this.dest..this.maxDest