Fix performance issue in JS inliner
See KT-18679
This commit is contained in:
@@ -79,6 +79,7 @@ public class JsInliner extends JsVisitorWithContextImpl {
|
|||||||
}
|
}
|
||||||
FunctionReader functionReader = new FunctionReader(reporter, config, currentModuleName, fragments);
|
FunctionReader functionReader = new FunctionReader(reporter, config, currentModuleName, fragments);
|
||||||
JsInliner inliner = new JsInliner(config, functions, accessors, functionReader, trace);
|
JsInliner inliner = new JsInliner(config, functions, accessors, functionReader, trace);
|
||||||
|
List<JsNode> nodesToPostProcess = new ArrayList<>();
|
||||||
for (JsProgramFragment fragment : fragmentsToProcess) {
|
for (JsProgramFragment fragment : fragmentsToProcess) {
|
||||||
inliner.inliningContexts.push(inliner.new JsInliningContext());
|
inliner.inliningContexts.push(inliner.new JsInliningContext());
|
||||||
inliner.accept(fragment.getDeclarationBlock());
|
inliner.accept(fragment.getDeclarationBlock());
|
||||||
@@ -89,8 +90,10 @@ public class JsInliner extends JsVisitorWithContextImpl {
|
|||||||
|
|
||||||
inliner.inliningContexts.pop();
|
inliner.inliningContexts.pop();
|
||||||
JsBlock block = new JsBlock(fragment.getDeclarationBlock(), fragment.getInitializerBlock(), fragment.getExportBlock());
|
JsBlock block = new JsBlock(fragment.getDeclarationBlock(), fragment.getInitializerBlock(), fragment.getExportBlock());
|
||||||
RemoveUnusedFunctionDefinitionsKt.removeUnusedFunctionDefinitions(block, functions);
|
nodesToPostProcess.add(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RemoveUnusedFunctionDefinitionsKt.removeUnusedFunctionDefinitions(nodesToPostProcess, functions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsInliner(
|
private JsInliner(
|
||||||
|
|||||||
+9
-8
@@ -17,9 +17,8 @@
|
|||||||
package org.jetbrains.kotlin.js.inline.clean
|
package org.jetbrains.kotlin.js.inline.clean
|
||||||
|
|
||||||
import org.jetbrains.kotlin.js.backend.ast.*
|
import org.jetbrains.kotlin.js.backend.ast.*
|
||||||
import org.jetbrains.kotlin.js.backend.ast.metadata.staticRef
|
|
||||||
import org.jetbrains.kotlin.js.backend.ast.metadata.isLocal
|
import org.jetbrains.kotlin.js.backend.ast.metadata.isLocal
|
||||||
|
import org.jetbrains.kotlin.js.backend.ast.metadata.staticRef
|
||||||
import org.jetbrains.kotlin.js.inline.util.IdentitySet
|
import org.jetbrains.kotlin.js.inline.util.IdentitySet
|
||||||
import org.jetbrains.kotlin.js.inline.util.collectFunctionReferencesInside
|
import org.jetbrains.kotlin.js.inline.util.collectFunctionReferencesInside
|
||||||
|
|
||||||
@@ -30,21 +29,23 @@ import org.jetbrains.kotlin.js.inline.util.collectFunctionReferencesInside
|
|||||||
* At now, it only removes unused local functions and function literals,
|
* At now, it only removes unused local functions and function literals,
|
||||||
* because named functions can be referenced from another module.
|
* because named functions can be referenced from another module.
|
||||||
*/
|
*/
|
||||||
fun removeUnusedFunctionDefinitions(root: JsNode, functions: Map<JsName, JsFunction>) {
|
fun removeUnusedFunctionDefinitions(roots: List<JsNode>, functions: Map<JsName, JsFunction>) {
|
||||||
val removable = with(UnusedLocalFunctionsCollector(functions)) {
|
val removable = with(UnusedLocalFunctionsCollector(functions)) {
|
||||||
process()
|
process()
|
||||||
accept(root)
|
roots.forEach { accept(it) }
|
||||||
removableFunctions.toSet()
|
removableFunctions
|
||||||
}
|
}.toSet()
|
||||||
|
|
||||||
NodeRemover(JsStatement::class.java) { statement ->
|
val remover = NodeRemover(JsStatement::class.java) { statement ->
|
||||||
val expression = when (statement) {
|
val expression = when (statement) {
|
||||||
is JsExpressionStatement -> statement.expression
|
is JsExpressionStatement -> statement.expression
|
||||||
is JsVars -> if (statement.vars.size == 1) statement.vars[0].initExpression else null
|
is JsVars -> if (statement.vars.size == 1) statement.vars[0].initExpression else null
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
expression is JsFunction && expression in removable
|
expression is JsFunction && expression in removable
|
||||||
}.accept(root)
|
}
|
||||||
|
|
||||||
|
roots.forEach { remover.accept(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class UnusedLocalFunctionsCollector(private val functions: Map<JsName, JsFunction>) : JsVisitorWithContextImpl() {
|
private class UnusedLocalFunctionsCollector(private val functions: Map<JsName, JsFunction>) : JsVisitorWithContextImpl() {
|
||||||
|
|||||||
Reference in New Issue
Block a user