[JS IR] Optimize JS AST scopes memory consumption

This commit is contained in:
Alexander Korepanov
2022-08-25 17:06:28 +02:00
committed by Space
parent bf53273b84
commit ea34e10b67
3 changed files with 24 additions and 14 deletions
@@ -14,13 +14,16 @@ import org.jetbrains.kotlin.js.backend.ast.JsLocation
import org.jetbrains.kotlin.js.backend.ast.JsName import org.jetbrains.kotlin.js.backend.ast.JsName
import org.jetbrains.kotlin.js.backend.ast.JsScope import org.jetbrains.kotlin.js.backend.ast.JsScope
val emptyScope: JsScope val emptyScope: JsScope = object : JsScope("nil") {
get() = object : JsScope("nil") { override fun doCreateName(ident: String): JsName {
override fun doCreateName(ident: String): JsName { error("Trying to create name in empty scope")
error("Trying to create name in empty scope")
}
} }
override fun copyOwnNames(other: JsScope?) {
error("Trying to copy names to empty scope")
}
}
class JsGenerationContext( class JsGenerationContext(
val currentFile: IrFile, val currentFile: IrFile,
val currentFunction: IrFunction?, val currentFunction: IrFunction?,
@@ -154,8 +154,10 @@ public abstract class JsScope {
} }
public void copyOwnNames(JsScope other) { public void copyOwnNames(JsScope other) {
names = new HashMap<>(names); if (!other.names.isEmpty()) {
names.putAll(other.names); names = new HashMap<>(names);
names.putAll(other.names);
}
} }
@NotNull @NotNull
@@ -17,7 +17,7 @@
package org.jetbrains.kotlin.js.backend.ast package org.jetbrains.kotlin.js.backend.ast
import org.jetbrains.kotlin.js.common.RESERVED_KEYWORDS import org.jetbrains.kotlin.js.common.RESERVED_KEYWORDS
import java.util.* import kotlin.collections.ArrayList
class JsObjectScope(parent: JsScope, description: String) : JsScope(parent, description) class JsObjectScope(parent: JsScope, description: String) : JsScope(parent, description)
@@ -32,21 +32,26 @@ open class JsFunctionScope(parent: JsScope, description: String) : JsDeclaration
} }
open class JsDeclarationScope(parent: JsScope, description: String, useParentScopeStack: Boolean = false) : JsScope(parent, description) { open class JsDeclarationScope(parent: JsScope, description: String, useParentScopeStack: Boolean = false) : JsScope(parent, description) {
private val labelScopes: Stack<LabelScope> = private var labelScopesImpl: ArrayList<LabelScope>? =
if (parent is JsDeclarationScope && useParentScopeStack) parent.labelScopes else Stack<LabelScope>() if (parent is JsDeclarationScope && useParentScopeStack) parent.labelScopesImpl else null
private val topLabelScope private val topLabelScope
get() = if (labelScopes.isNotEmpty()) labelScopes.peek() else null get() = labelScopesImpl?.let { if (it.isNotEmpty()) it.last() else null }
private val labelScopes: ArrayList<LabelScope>
get() = labelScopesImpl ?: ArrayList<LabelScope>().also { labelScopesImpl = it }
open fun enterLabel(label: String, outputName: String): JsName { open fun enterLabel(label: String, outputName: String): JsName {
val scope = LabelScope(topLabelScope, label, outputName) val scope = LabelScope(topLabelScope, label, outputName)
labelScopes.push(scope) labelScopes.add(scope)
return scope.labelName return scope.labelName
} }
open fun exitLabel() { open fun exitLabel() {
assert(labelScopes.isNotEmpty()) { "No scope to exit from" } labelScopes.let {
labelScopes.pop() assert(it.isNotEmpty()) { "No scope to exit from" }
it.removeLast()
}
} }
open fun findLabel(label: String): JsName? = open fun findLabel(label: String): JsName? =