[JS IR] Cache JsLocation objects and js function signatures
Memory consumption optimization
This commit is contained in:
committed by
Space
parent
ff2f16190d
commit
bf53273b84
@@ -408,4 +408,10 @@ class JsIrBackendContext(
|
||||
outlinedJsCodeFunctions[symbol] = parsedJsFunction
|
||||
return parsedJsFunction
|
||||
}
|
||||
|
||||
private var irFunctionSignatureCache = hashMapOf<IrFunction, String>()
|
||||
|
||||
fun getFunctionSignatureFromCache(f: IrFunction): String {
|
||||
return irFunctionSignatureCache.getOrPut(f) { calculateJsFunctionSignature(f, this) }
|
||||
}
|
||||
}
|
||||
|
||||
+6
-2
@@ -494,11 +494,15 @@ internal fun <T : JsNode> T.withSource(node: IrElement, context: JsGenerationCon
|
||||
private inline fun <T : JsNode> T.addSourceInfoIfNeed(node: IrElement, context: JsGenerationContext) {
|
||||
if (!context.staticContext.genSourcemaps) return
|
||||
|
||||
val sourceInfo = node.getSourceInfo(context.currentFile.fileEntry) ?: return
|
||||
var cachedLocation = context.getLocationFromCache(node)
|
||||
if (cachedLocation == null) {
|
||||
cachedLocation = node.getSourceInfo(context.currentFile.fileEntry) ?: return
|
||||
context.saveLocationToCache(node, cachedLocation)
|
||||
}
|
||||
|
||||
// TODO maybe it's better to fix in JsExpressionStatement
|
||||
val locationTarget = if (this is JsExpressionStatement) this.expression else this
|
||||
locationTarget.source = sourceInfo
|
||||
locationTarget.source = cachedLocation
|
||||
}
|
||||
|
||||
fun IrElement.getSourceInfo(container: IrDeclaration): JsLocation? {
|
||||
|
||||
+8
-1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||
import org.jetbrains.kotlin.ir.expressions.IrReturnableBlock
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsLocation
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsName
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsScope
|
||||
|
||||
@@ -27,7 +28,9 @@ class JsGenerationContext(
|
||||
val localNames: LocalNameGenerator? = null,
|
||||
private val nameCache: MutableMap<IrElement, JsName> = mutableMapOf(),
|
||||
private val useBareParameterNames: Boolean = false,
|
||||
): IrNamer by staticContext {
|
||||
) : IrNamer by staticContext {
|
||||
private val locationCache = mutableMapOf<Int, JsLocation>()
|
||||
|
||||
fun newFile(file: IrFile, func: IrFunction? = null, localNames: LocalNameGenerator? = null): JsGenerationContext {
|
||||
return JsGenerationContext(
|
||||
currentFile = file,
|
||||
@@ -79,4 +82,8 @@ class JsGenerationContext(
|
||||
fun checkIfJsCode(symbol: IrFunctionSymbol): Boolean = symbol == staticContext.backendContext.intrinsics.jsCode
|
||||
|
||||
fun checkIfHasAssociatedJsCode(symbol: IrFunctionSymbol): Boolean = staticContext.backendContext.getJsCodeForFunction(symbol) != null
|
||||
|
||||
fun getLocationFromCache(node: IrElement) = locationCache[node.startOffset]
|
||||
|
||||
fun saveLocationToCache(node: IrElement, location: JsLocation) = locationCache.put(node.startOffset, location)
|
||||
}
|
||||
|
||||
@@ -115,23 +115,8 @@ fun Int.toJsIdentifier(): String {
|
||||
}
|
||||
}
|
||||
|
||||
fun jsFunctionSignature(declaration: IrFunction, context: JsIrBackendContext): String {
|
||||
require(!declaration.isStaticMethodOfClass)
|
||||
require(declaration.dispatchReceiverParameter != null)
|
||||
|
||||
var declarationName = declaration.getJsNameOrKotlinName().asString()
|
||||
|
||||
if (declaration.hasStableJsName(context)) {
|
||||
// TODO: Handle reserved suffix in FE
|
||||
require(!declarationName.endsWith(RESERVED_MEMBER_NAME_SUFFIX)) {
|
||||
"Function ${declaration.fqNameWhenAvailable} uses reserved name suffix \"$RESERVED_MEMBER_NAME_SUFFIX\""
|
||||
}
|
||||
return declarationName
|
||||
}
|
||||
|
||||
declaration.nameIfPropertyAccessor()?.let {
|
||||
declarationName = it
|
||||
}
|
||||
fun calculateJsFunctionSignature(declaration: IrFunction, context: JsIrBackendContext): String {
|
||||
val declarationName = declaration.nameIfPropertyAccessor() ?: declaration.getJsNameOrKotlinName().asString()
|
||||
|
||||
val nameBuilder = StringBuilder()
|
||||
nameBuilder.append(declarationName)
|
||||
@@ -170,6 +155,23 @@ fun jsFunctionSignature(declaration: IrFunction, context: JsIrBackendContext): S
|
||||
) + "_" + abs(signature.hashCode()).toString(Character.MAX_RADIX) + RESERVED_MEMBER_NAME_SUFFIX
|
||||
}
|
||||
|
||||
fun jsFunctionSignature(declaration: IrFunction, context: JsIrBackendContext): String {
|
||||
require(!declaration.isStaticMethodOfClass)
|
||||
require(declaration.dispatchReceiverParameter != null)
|
||||
|
||||
if (declaration.hasStableJsName(context)) {
|
||||
val declarationName = declaration.getJsNameOrKotlinName().asString()
|
||||
// TODO: Handle reserved suffix in FE
|
||||
require(!declarationName.endsWith(RESERVED_MEMBER_NAME_SUFFIX)) {
|
||||
"Function ${declaration.fqNameWhenAvailable} uses reserved name suffix \"$RESERVED_MEMBER_NAME_SUFFIX\""
|
||||
}
|
||||
return declarationName
|
||||
}
|
||||
|
||||
val declarationSignature = (declaration as? IrSimpleFunction)?.resolveFakeOverride() ?: declaration
|
||||
return context.getFunctionSignatureFromCache(declarationSignature)
|
||||
}
|
||||
|
||||
class NameTables(
|
||||
packages: Iterable<IrPackageFragment>,
|
||||
reservedForGlobal: MutableSet<String> = mutableSetOf(),
|
||||
@@ -411,7 +413,8 @@ fun sanitizeName(name: String, withHash: Boolean = true): String {
|
||||
if (name.isValidES5Identifier()) return name
|
||||
if (name.isEmpty()) return "_"
|
||||
|
||||
val builder = StringBuilder()
|
||||
// 7 = _ + MAX_INT.toString(Character.MAX_RADIX)
|
||||
val builder = StringBuilder(name.length + if (withHash) 7 else 0)
|
||||
|
||||
val first = name.first()
|
||||
|
||||
|
||||
@@ -19,12 +19,14 @@ package org.jetbrains.kotlin.js.backend.ast
|
||||
import java.io.Reader
|
||||
|
||||
data class JsLocation(
|
||||
override val file: String,
|
||||
override val startLine: Int,
|
||||
override val startChar: Int
|
||||
override val file: String,
|
||||
override val startLine: Int,
|
||||
override val startChar: Int
|
||||
) : JsLocationWithSource {
|
||||
override val identityObject: Any? = null
|
||||
override val sourceProvider: () -> Reader? = { null }
|
||||
override val identityObject: Any?
|
||||
get() = null
|
||||
override val sourceProvider: () -> Reader?
|
||||
get() = { null }
|
||||
|
||||
override fun asSimpleLocation(): JsLocation = this
|
||||
}
|
||||
@@ -40,7 +42,7 @@ interface JsLocationWithSource {
|
||||
}
|
||||
|
||||
class JsLocationWithEmbeddedSource(
|
||||
private val location: JsLocation,
|
||||
override val identityObject: Any?,
|
||||
override val sourceProvider: () -> Reader?
|
||||
) : JsLocationWithSource by location
|
||||
private val location: JsLocation,
|
||||
override val identityObject: Any?,
|
||||
override val sourceProvider: () -> Reader?
|
||||
) : JsLocationWithSource by location
|
||||
|
||||
Reference in New Issue
Block a user