Use handwritten tokenizer for SMAP parsing

SMAP parsing is a hot spot. Handwritten tokenization significantly boosts the performance.

See ^KT-61527
This commit is contained in:
Vladislav Grechko
2023-08-23 19:22:51 +02:00
committed by Space Team
parent 4eac193463
commit f11c96cba2
@@ -35,9 +35,46 @@ object SMAPParser {
fun parseOrNull(mappingInfo: String): SMAP? =
parseStratum(mappingInfo, KOTLIN_STRATA_NAME, parseStratum(mappingInfo, KOTLIN_DEBUG_STRATA_NAME, null))
private class SMAPTokenizer(private val text: String, private val headerString: String) : Iterator<String> {
private var pos = 0
private var currentLine: String? = null
init {
advance()
while (currentLine != null && currentLine != headerString) {
advance()
}
if (currentLine == headerString) {
advance()
}
}
private fun advance() {
if (pos >= text.length) {
currentLine = null
return
}
val fromPos = pos
while (pos < text.length && text[pos] != '\n' && text[pos] != '\r') pos++
currentLine = text.substring(fromPos, pos)
pos++
}
override fun hasNext(): Boolean {
return currentLine != null
}
override fun next(): String {
val res = currentLine ?: throw NoSuchElementException()
advance()
return res
}
}
private fun parseStratum(mappingInfo: String, stratum: String, callSites: SMAP?): SMAP? {
val fileMappings = linkedMapOf<Int, FileMapping>()
val iterator = mappingInfo.lineSequence().dropWhile { it != "${SMAP.STRATA_SECTION} $stratum" }.drop(1).iterator()
val iterator = SMAPTokenizer(mappingInfo, "${SMAP.STRATA_SECTION} $stratum")
// JSR-045 allows the line section to come before the file section, but we don't generate SMAPs like this.
if (!iterator.hasNext() || iterator.next() != SMAP.FILE_SECTION) return null