Default body compilation for inline fun extracted from InlineCodegen to separate one
This commit is contained in:
@@ -38,11 +38,6 @@ abstract class CallGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
override fun genCallWithoutAssertions(
|
||||
callableMethod: CallableMethod, codegen: ExpressionCodegen) {
|
||||
callableMethod.genInvokeInstruction(codegen.v)
|
||||
}
|
||||
|
||||
override fun afterParameterPut(
|
||||
type: Type,
|
||||
stackValue: StackValue?,
|
||||
@@ -107,8 +102,6 @@ abstract class CallGenerator {
|
||||
|
||||
abstract fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen)
|
||||
|
||||
abstract fun genCallWithoutAssertions(callableMethod: CallableMethod, codegen: ExpressionCodegen)
|
||||
|
||||
abstract fun afterParameterPut(
|
||||
type: Type,
|
||||
stackValue: StackValue?,
|
||||
|
||||
@@ -2492,7 +2492,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
if (!isInline) return defaultCallGenerator;
|
||||
|
||||
FunctionDescriptor original = DescriptorUtils.unwrapFakeOverride((FunctionDescriptor) descriptor.getOriginal());
|
||||
return new InlineCodegen(this, state, original, callElement, typeParameterMappings, isDefaultCompilation);
|
||||
if (isDefaultCompilation) {
|
||||
return new InlineCodegenForDefaultBody(original, this, state);
|
||||
}
|
||||
else {
|
||||
return new InlineCodegen(this, state, original, callElement, typeParameterMappings);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -756,7 +756,7 @@ public class FunctionCodegen {
|
||||
|
||||
CallableMethod method = state.getTypeMapper().mapToCallableMethod(functionDescriptor, false);
|
||||
|
||||
generator.genCallWithoutAssertions(method, codegen);
|
||||
generator.genCall(method, null, false, codegen);
|
||||
|
||||
iv.areturn(signature.getReturnType());
|
||||
}
|
||||
|
||||
@@ -86,7 +86,6 @@ public class InlineCodegen extends CallGenerator {
|
||||
|
||||
private final ReifiedTypeInliner reifiedTypeInliner;
|
||||
@Nullable private final TypeParameterMappings typeParameterMappings;
|
||||
private final boolean isDefaultMethodCompilation;
|
||||
|
||||
private LambdaInfo activeLambda;
|
||||
|
||||
@@ -97,12 +96,10 @@ public class InlineCodegen extends CallGenerator {
|
||||
@NotNull GenerationState state,
|
||||
@NotNull FunctionDescriptor function,
|
||||
@NotNull KtElement callElement,
|
||||
@Nullable TypeParameterMappings typeParameterMappings,
|
||||
boolean isDefaultMethodCompilation
|
||||
@Nullable TypeParameterMappings typeParameterMappings
|
||||
) {
|
||||
assert InlineUtil.isInline(function) || InlineUtil.isArrayConstructorWithLambda(function) :
|
||||
"InlineCodegen can inline only inline functions and array constructors: " + function;
|
||||
this.isDefaultMethodCompilation = isDefaultMethodCompilation;
|
||||
this.state = state;
|
||||
this.typeMapper = state.getTypeMapper();
|
||||
this.codegen = codegen;
|
||||
@@ -129,15 +126,10 @@ public class InlineCodegen extends CallGenerator {
|
||||
sourceMapper = codegen.getParentCodegen().getOrCreateSourceMapper();
|
||||
|
||||
if (!(functionDescriptor instanceof FictitiousArrayConstructor)) {
|
||||
reportIncrementalInfo(functionDescriptor, codegen.getContext().getFunctionDescriptor().getOriginal());
|
||||
reportIncrementalInfo(functionDescriptor, codegen.getContext().getFunctionDescriptor().getOriginal(), jvmSignature, state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void genCallWithoutAssertions(@NotNull CallableMethod callableMethod, @NotNull ExpressionCodegen codegen) {
|
||||
genCall(callableMethod, null, false, codegen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void genCallInner(@NotNull Callable callableMethod, @Nullable ResolvedCall<?> resolvedCall, boolean callDefault, @NotNull ExpressionCodegen codegen) {
|
||||
SMAPAndMethodNode nodeAndSmap = null;
|
||||
@@ -148,11 +140,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
|
||||
try {
|
||||
nodeAndSmap = createMethodNode(callDefault);
|
||||
if (isDefaultMethodCompilation) {
|
||||
nodeAndSmap.getNode().accept(new MethodBodyVisitor(codegen.v));
|
||||
} else {
|
||||
endCall(inlineCall(nodeAndSmap));
|
||||
}
|
||||
endCall(inlineCall(nodeAndSmap));
|
||||
}
|
||||
catch (CompilationException e) {
|
||||
throw e;
|
||||
@@ -190,6 +178,18 @@ public class InlineCodegen extends CallGenerator {
|
||||
|
||||
@NotNull
|
||||
private SMAPAndMethodNode createMethodNode(boolean callDefault) throws IOException {
|
||||
return createMethodNode(functionDescriptor, jvmSignature, codegen, context, callDefault, state);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static SMAPAndMethodNode createMethodNode(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull JvmMethodSignature jvmSignature,
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@NotNull CodegenContext context,
|
||||
boolean callDefault,
|
||||
@NotNull GenerationState state) throws IOException {
|
||||
JetTypeMapper typeMapper = state.getTypeMapper();
|
||||
Method asmMethod = callDefault
|
||||
? typeMapper.mapDefaultMethod(functionDescriptor, context.getContextKind())
|
||||
: jvmSignature.getAsmMethod();
|
||||
@@ -257,7 +257,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
smap = createSMAPWithDefaultMapping(inliningFunction, parentCodegen.getOrCreateSourceMapper().getResultMappings());
|
||||
}
|
||||
else {
|
||||
smap = generateMethodBody(maxCalcAdapter, functionDescriptor, methodContext, inliningFunction, jvmSignature, false);
|
||||
smap = generateMethodBody(maxCalcAdapter, functionDescriptor, methodContext, inliningFunction, jvmSignature, false, codegen, state);
|
||||
}
|
||||
|
||||
nodeAndSMAP = new SMAPAndMethodNode(node, smap);
|
||||
@@ -355,24 +355,27 @@ public class InlineCodegen extends CallGenerator {
|
||||
|
||||
MethodVisitor adapter = InlineCodegenUtil.wrapWithMaxLocalCalc(methodNode);
|
||||
|
||||
SMAP smap = generateMethodBody(adapter, descriptor, context, declaration, jvmMethodSignature, true);
|
||||
SMAP smap = generateMethodBody(adapter, descriptor, context, declaration, jvmMethodSignature, true, codegen, state);
|
||||
adapter.visitMaxs(-1, -1);
|
||||
return new SMAPAndMethodNode(methodNode, smap);
|
||||
}
|
||||
|
||||
private SMAP generateMethodBody(
|
||||
private static SMAP generateMethodBody(
|
||||
@NotNull MethodVisitor adapter,
|
||||
@NotNull FunctionDescriptor descriptor,
|
||||
@NotNull MethodContext context,
|
||||
@NotNull KtExpression expression,
|
||||
@NotNull JvmMethodSignature jvmMethodSignature,
|
||||
boolean isLambda
|
||||
boolean isLambda,
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@NotNull GenerationState state
|
||||
|
||||
) {
|
||||
FakeMemberCodegen parentCodegen =
|
||||
new FakeMemberCodegen(codegen.getParentCodegen(), expression,
|
||||
(FieldOwnerContext) context.getParentContext(),
|
||||
isLambda ? codegen.getParentCodegen().getClassName()
|
||||
: typeMapper.mapImplementationOwner(descriptor).getInternalName());
|
||||
: state.getTypeMapper().mapImplementationOwner(descriptor).getInternalName());
|
||||
|
||||
FunctionGenerationStrategy strategy =
|
||||
expression instanceof KtCallableReferenceExpression ?
|
||||
@@ -682,11 +685,6 @@ public class InlineCodegen extends CallGenerator {
|
||||
@NotNull Type parameterType,
|
||||
@NotNull StackValue value
|
||||
) {
|
||||
if (isDefaultMethodCompilation) {
|
||||
//original method would be inlined directly into default impl body without any inline magic
|
||||
//so we no need to load variables on stack to further method call
|
||||
return;
|
||||
}
|
||||
putValueIfNeeded(parameterType, value, -1);
|
||||
}
|
||||
|
||||
@@ -803,9 +801,11 @@ public class InlineCodegen extends CallGenerator {
|
||||
return new NestedSourceMapper(sourceMapper, nodeAndSmap.getRanges(), nodeAndSmap.getClassSMAP().getSourceInfo());
|
||||
}
|
||||
|
||||
private void reportIncrementalInfo(
|
||||
static void reportIncrementalInfo(
|
||||
@NotNull FunctionDescriptor sourceDescriptor,
|
||||
@NotNull FunctionDescriptor targetDescriptor
|
||||
@NotNull FunctionDescriptor targetDescriptor,
|
||||
@NotNull JvmMethodSignature jvmSignature,
|
||||
@NotNull GenerationState state
|
||||
) {
|
||||
IncrementalCompilationComponents incrementalCompilationComponents = state.getIncrementalCompilationComponents();
|
||||
TargetId targetId = state.getTargetId();
|
||||
@@ -813,7 +813,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
if (incrementalCompilationComponents == null || targetId == null) return;
|
||||
|
||||
IncrementalCache incrementalCache = incrementalCompilationComponents.getIncrementalCache(targetId);
|
||||
String classFilePath = InlineCodegenUtilsKt.getClassFilePath(sourceDescriptor, typeMapper, incrementalCache);
|
||||
String classFilePath = InlineCodegenUtilsKt.getClassFilePath(sourceDescriptor, state.getTypeMapper(), incrementalCache);
|
||||
String sourceFilePath = InlineCodegenUtilsKt.getSourceFilePath(targetDescriptor);
|
||||
incrementalCache.registerInline(classFilePath, jvmSignature.toString(), sourceFilePath);
|
||||
}
|
||||
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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 org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class InlineCodegenForDefaultBody(
|
||||
function: FunctionDescriptor,
|
||||
codegen: ExpressionCodegen,
|
||||
val state: GenerationState
|
||||
) : CallGenerator() {
|
||||
|
||||
private val functionDescriptor =
|
||||
if (InlineUtil.isArrayConstructorWithLambda(function))
|
||||
FictitiousArrayConstructor.create(function as ConstructorDescriptor)
|
||||
else
|
||||
function.original
|
||||
|
||||
|
||||
private val context = InlineCodegen.getContext(
|
||||
functionDescriptor, state,
|
||||
DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor)?.containingFile as? KtFile
|
||||
)
|
||||
|
||||
private val jvmSignature = state.typeMapper.mapSignature(functionDescriptor, context.contextKind)
|
||||
|
||||
init {
|
||||
assert(InlineUtil.isInline(function)) {
|
||||
"InlineCodegen can inline only inline functions and array constructors: " + function
|
||||
}
|
||||
InlineCodegen.reportIncrementalInfo(functionDescriptor, codegen.context.functionDescriptor.original, jvmSignature, state)
|
||||
}
|
||||
|
||||
override fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen) {
|
||||
val nodeAndSmap = InlineCodegen.createMethodNode(functionDescriptor, jvmSignature, codegen, context, callDefault, state)
|
||||
nodeAndSmap.node.accept(MethodBodyVisitor(codegen.v))
|
||||
}
|
||||
|
||||
override fun afterParameterPut(type: Type, stackValue: StackValue?, parameterIndex: Int) {
|
||||
throw UnsupportedOperationException("Shouldn't be called")
|
||||
}
|
||||
|
||||
override fun genValueAndPut(valueParameterDescriptor: ValueParameterDescriptor, argumentExpression: KtExpression, parameterType: Type, parameterIndex: Int) {
|
||||
throw UnsupportedOperationException("Shouldn't be called")
|
||||
}
|
||||
|
||||
override fun putValueIfNeeded(parameterType: Type, value: StackValue) {
|
||||
//original method would be inlined directly into default impl body without any inline magic
|
||||
//so we no need to load variables on stack to further method call
|
||||
}
|
||||
|
||||
override fun putCapturedValueOnStack(stackValue: StackValue, valueType: Type, paramIndex: Int) {
|
||||
throw UnsupportedOperationException("Shouldn't be called")
|
||||
}
|
||||
|
||||
override fun putHiddenParams() {
|
||||
throw UnsupportedOperationException("Shouldn't be called")
|
||||
}
|
||||
|
||||
override fun reorderArgumentsIfNeeded(actualArgsWithDeclIndex: List<ArgumentAndDeclIndex>, valueParameterTypes: List<Type>) {
|
||||
throw UnsupportedOperationException("Shouldn't be called")
|
||||
}
|
||||
}
|
||||
+1
-12
@@ -20,15 +20,4 @@ public inline fun massert(value: Boolean, message: Any = "Assertion failed") {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO SHOULD BE ABSENT
|
||||
|
||||
//SMAP
|
||||
//assertion.2.kt
|
||||
//Kotlin
|
||||
//*S Kotlin
|
||||
//*F
|
||||
//+ 1 assertion.2.kt
|
||||
//test/Assertion_2Kt
|
||||
//*L
|
||||
//1#1,34:1
|
||||
//*E
|
||||
//SMAP ABSENT
|
||||
|
||||
Reference in New Issue
Block a user