From 60c27affbb25d1f25db52acb145cfc4c0cbe0604 Mon Sep 17 00:00:00 2001 From: pyos Date: Thu, 28 Apr 2022 14:40:33 +0200 Subject: [PATCH] JVM: inline (!) some DescriptorAsmUtils methods into the inliner Easier to work with it that way --- .../inline/AnonymousObjectTransformer.kt | 62 ++++++++----------- .../codegen/inline/transformationUtils.kt | 44 ------------- 2 files changed, 25 insertions(+), 81 deletions(-) delete mode 100644 compiler/backend/src/org/jetbrains/kotlin/codegen/inline/transformationUtils.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt index 2036c6490bb..2cc31b91bf7 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt @@ -22,10 +22,8 @@ import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil import org.jetbrains.kotlin.metadata.jvm.serialization.JvmStringTable import org.jetbrains.kotlin.protobuf.MessageLite -import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.Companion.NO_ORIGIN import org.jetbrains.org.objectweb.asm.* -import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.Method import org.jetbrains.org.objectweb.asm.tree.* import java.util.* @@ -44,7 +42,6 @@ class AnonymousObjectTransformer( private var constructor: MethodNode? = null private lateinit var sourceMap: SMAP private lateinit var sourceMapper: SourceMapper - private val languageVersionSettings = inliningContext.state.languageVersionSettings // TODO: use IrTypeMapper in the IR backend private val typeMapper: KotlinTypeMapperBase = state.typeMapper @@ -107,7 +104,7 @@ class AnonymousObjectTransformer( return if (isCapturedFieldName(name)) { null } else { - classBuilder.newField(JvmDeclarationOrigin.NO_ORIGIN, access, name, desc, signature, value) + classBuilder.newField(NO_ORIGIN, access, name, desc, signature, value) } } @@ -349,29 +346,9 @@ class AnonymousObjectTransformer( parentRemapper: FieldRemapper, constructorAdditionalFakeParams: List ) { - val descTypes = ArrayList() - val constructorParams = constructorInlineBuilder.buildParameters() - val capturedIndexes = IntArray(constructorParams.parameters.size) - var index = 0 - var size = 0 - - //complex processing cause it could have super constructor call params - for (info in constructorParams) { - if (!info.isSkipped) { //not inlined - if (info.isCaptured || info is CapturedParamInfo) { - capturedIndexes[index] = size - index++ - } - - if (size != 0) { //skip this - descTypes.add(info.type) - } - size += info.type.size - } - } - - val constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, *descTypes.toTypedArray()) + val constructorParamTypes = constructorParams.filter { !it.isSkipped }.map { it.type }.drop(1) + val constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, *constructorParamTypes.toTypedArray()) //TODO for inline method make public class transformationInfo.newConstructorDescriptor = constructorDescriptor val constructorVisitor = classBuilder.newMethod( @@ -380,14 +357,28 @@ class AnonymousObjectTransformer( val newBodyStartLabel = Label() constructorVisitor.visitLabel(newBodyStartLabel) - //initialize captured fields - val newFieldsWithSkipped = getNewFieldsToGenerate(allCapturedBuilder.listCaptured()) - val fieldInfoWithSkipped = transformToFieldInfo(Type.getObjectType(transformationInfo.newClassName), newFieldsWithSkipped) - val capturedFieldInitializer = InstructionAdapter(constructorVisitor) - fieldInfoWithSkipped.forEachIndexed { paramIndex, fieldInfo -> - if (!newFieldsWithSkipped[paramIndex].skip) { - DescriptorAsmUtil.genAssignInstanceFieldFromParam(fieldInfo, capturedIndexes[paramIndex], capturedFieldInitializer) + //initialize captured fields + val capturedIndexes = IntArray(constructorParams.parameters.size) + var index = 0 + var size = 0 + for (info in constructorParams) { + if (!info.isSkipped) { //not inlined + if (info.isCaptured || info is CapturedParamInfo) { + capturedIndexes[index] = size + index++ + } + size += info.type.size + } + } + for ((paramIndex, info) in allCapturedBuilder.listCaptured().filter { it.functionalArgument !is LambdaInfo }.withIndex()) { + if (!info.isSkipInConstructor) { + val desc = info.type.descriptor + val access = AsmUtil.NO_FLAG_PACKAGE_PRIVATE or Opcodes.ACC_SYNTHETIC or Opcodes.ACC_FINAL + classBuilder.newField(NO_ORIGIN, access, info.newFieldName, desc, null, null) + constructorVisitor.visitVarInsn(Opcodes.ALOAD, 0) + constructorVisitor.visitVarInsn(info.type.getOpcode(Opcodes.ILOAD), capturedIndexes[paramIndex]) + constructorVisitor.visitFieldInsn(Opcodes.PUTFIELD, transformationInfo.newClassName, info.newFieldName, desc) } } @@ -417,7 +408,7 @@ class AnonymousObjectTransformer( val first = intermediateMethodNode.instructions.first val oldStartLabel = (first as? LabelNode)?.label - intermediateMethodNode.accept(object : MethodBodyVisitor(capturedFieldInitializer) { + intermediateMethodNode.accept(object : MethodBodyVisitor(constructorVisitor) { override fun visitLocalVariable( name: String, desc: String, signature: String?, start: Label, end: Label, index: Int ) { @@ -430,9 +421,6 @@ class AnonymousObjectTransformer( } }) constructorVisitor.visitEnd() - DescriptorAsmUtil.genClosureFields( - toNameTypePair(filterSkipped(newFieldsWithSkipped)), classBuilder - ) } private fun getMethodParametersWithCaptured(capturedBuilder: ParametersBuilder, sourceNode: MethodNode): Parameters { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/transformationUtils.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/transformationUtils.kt deleted file mode 100644 index 59b2809a9b3..00000000000 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/transformationUtils.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.codegen.inline - -import com.intellij.openapi.util.Pair -import org.jetbrains.kotlin.codegen.FieldInfo -import org.jetbrains.org.objectweb.asm.Type - -class NewJavaField(val name: String, val type: Type, val skip: Boolean) - -fun getNewFieldsToGenerate(params: List): List { - return params.filter { - //not inlined - it.functionalArgument !is LambdaInfo - }.map { - NewJavaField(it.newFieldName, it.type, it.isSkipInConstructor) - } -} - -fun transformToFieldInfo(lambdaType: Type, newFields: List): List { - return newFields.map { field -> - FieldInfo.createForHiddenField(lambdaType, field.type, field.name) - } -} - -fun filterSkipped(fields: List): List { - return fields.filter { !it.skip } -} - -fun toNameTypePair(fields: List): List> = fields.map { Pair(it.name, it.type) }