Generate INSTANCEOF barrier in bridges for Collection.contains

This commit is contained in:
Denis Zharkov
2015-10-08 11:08:25 +03:00
parent 80da320c2c
commit 35783f129b
4 changed files with 118 additions and 1 deletions
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.backend.common.bridges.Bridge;
import org.jetbrains.kotlin.backend.common.bridges.BridgesPackage;
import org.jetbrains.kotlin.codegen.annotation.AnnotatedWithOnlyTargetedAnnotations;
import org.jetbrains.kotlin.codegen.context.*;
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics;
import org.jetbrains.kotlin.codegen.optimization.OptimizationMethodVisitor;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
@@ -54,6 +55,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
@@ -815,6 +817,8 @@ public class FunctionCodegen {
InstructionAdapter iv = new InstructionAdapter(mv);
ImplementationBodyCodegen.markLineNumberForSyntheticFunction(owner.getThisDescriptor(), iv);
generateInstanceOfBarrierIfNeeded(iv, descriptor, bridge, delegateTo);
iv.load(0, OBJECT_TYPE);
for (int i = 0, reg = 1; i < argTypes.length; i++) {
StackValue.local(reg, argTypes[i]).put(originalArgTypes[i], iv);
@@ -822,7 +826,6 @@ public class FunctionCodegen {
reg += argTypes[i].getSize();
}
if (superCallNeeded) {
ClassDescriptor parentClass = getSuperClassDescriptor((ClassDescriptor) descriptor.getContainingDeclaration());
assert parentClass != null;
@@ -839,6 +842,56 @@ public class FunctionCodegen {
endVisit(mv, "bridge method", origin);
}
private static void generateInstanceOfBarrierIfNeeded(
@NotNull InstructionAdapter iv,
@NotNull FunctionDescriptor descriptor,
@NotNull Method bridge,
@NotNull Method delegateTo
) {
if (BuiltinsPropertiesUtilKt.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(descriptor) == null) return;
assert descriptor.getValueParameters().size() == 1 : "Should be descriptor with one value parameter, but found: " + descriptor;
iv.load(1, OBJECT_TYPE);
JetType jetType = descriptor.getValueParameters().get(0).getType();
// TODO: reuse logic from ExpressionCodegen
if (jetType.isMarkedNullable()) {
Label nope = new Label();
Label end = new Label();
iv.dup();
iv.ifnull(nope);
TypeIntrinsics.instanceOf(
iv,
jetType,
boxType(delegateTo.getArgumentTypes()[0])
);
iv.goTo(end);
iv.mark(nope);
iv.pop();
iv.iconst(1);
iv.mark(end);
}
else {
TypeIntrinsics.instanceOf(
iv,
jetType,
boxType(delegateTo.getArgumentTypes()[0])
);
}
Label afterBarrier = new Label();
iv.ifne(afterBarrier);
StackValue.none().put(bridge.getReturnType(), iv);
iv.areturn(bridge.getReturnType());
iv.visitLabel(afterBarrier);
}
public void genDelegate(@NotNull FunctionDescriptor functionDescriptor, FunctionDescriptor overriddenDescriptor, StackValue field) {
genDelegate(functionDescriptor, overriddenDescriptor.getOriginal(),
(ClassDescriptor) overriddenDescriptor.getContainingDeclaration(), field);