Fix compilation with ASM 8

General rule to use linkedLabel or linkWithLabel
  when label from node is reused in other instructions.
  If label is not linked then it will point to another labelNode when visited

  #KT-39013 Fixed
This commit is contained in:
Mikhail Bogdanov
2020-06-12 20:18:20 +02:00
parent 1186d1affd
commit db50afeafe
8 changed files with 36 additions and 12 deletions
@@ -1585,7 +1585,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
assert topOfStack == tryWithFinallyBlockStackElement : "Top element of stack doesn't equals processing finally block";
KtTryExpression jetTryExpression = tryWithFinallyBlockStackElement.expression;
Label finallyStart = new Label();
Label finallyStart = linkedLabel();
v.mark(finallyStart);
tryWithFinallyBlockStackElement.addGapLabel(finallyStart);
addGapLabelsForNestedTryCatchWithoutFinally(state, nestedTryBlocksWithoutFinally, finallyStart);
@@ -60,6 +60,7 @@ import org.jetbrains.org.objectweb.asm.Opcodes.*
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.commons.Method
import org.jetbrains.org.objectweb.asm.tree.LabelNode
import java.util.*
fun generateIsCheck(
@@ -666,3 +667,22 @@ private fun generateLambdaForRunSuspend(
lambdaBuilder.done()
return lambdaBuilder.thisName
}
internal fun LabelNode.linkWithLabel(): LabelNode {
// Remember labelNode in label and vise versa.
// Before ASM 8 there was JB patch in MethodNode that makes such linking in constructor of LabelNode.
//
// protected LabelNode getLabelNode(final Label label) {
// if (!(label.info instanceof LabelNode)) {
// //label.info = new LabelNode(label); //[JB: needed for Coverage agent]
// label.info = new LabelNode(); //ASM 8
// }
// return (LabelNode) label.info;
// }
if (label.info == null) {
label.info = this
}
return this
}
fun linkedLabel(): Label = LabelNode().linkWithLabel().label
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.codegen.TransformationMethodVisitor
import org.jetbrains.kotlin.codegen.inline.*
import org.jetbrains.kotlin.codegen.optimization.common.*
import org.jetbrains.kotlin.codegen.optimization.fixStack.FixStackMethodTransformer
import org.jetbrains.kotlin.codegen.linkWithLabel
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.isReleaseCoroutines
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
@@ -741,7 +742,7 @@ class CoroutineTransformerMethodVisitor(
suspendMarkerVarIndex: Int,
suspendPointLineNumber: LineNumberNode?
): LabelNode {
val continuationLabel = LabelNode()
val continuationLabel = LabelNode().linkWithLabel()
val continuationLabelAfterLoadedResult = LabelNode()
val suspendElementLineNumber = lineNumber
var nextLineNumberNode = nextDefinitelyHitLineNumber(suspension)
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.linkWithLabel
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
@@ -15,6 +16,7 @@ import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.LabelNode
import org.jetbrains.org.objectweb.asm.tree.MethodNode
class InlineCodegenForDefaultBody(
@@ -27,7 +29,7 @@ class InlineCodegenForDefaultBody(
) : CallGenerator {
private val sourceMapper: SourceMapper = codegen.parentCodegen.orCreateSourceMapper
private val methodStartLabel = Label()
private val methodStartLabel = linkedLabel()
init {
assert(InlineUtil.isInline(function)) {
@@ -33,6 +33,7 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;
import static org.jetbrains.kotlin.codegen.CodegenUtilKt.linkedLabel;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.*;
import static org.jetbrains.kotlin.codegen.inline.MethodInlinerUtilKt.getNextMeaningful;
@@ -198,7 +199,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
//Creating temp node for finally block copy with some additional instruction
MethodNode finallyBlockCopy = createEmptyMethodNode();
Label newFinallyStart = new Label();
Label insertedBlockEnd = new Label();
Label insertedBlockEnd = linkedLabel();
boolean generateAloadAstore = nonLocalReturnType != Type.VOID_TYPE && !finallyInfo.isEmpty();
if (generateAloadAstore) {
@@ -102,7 +102,7 @@ class MethodInliner(
}
//substitute returns with "goto end" instruction to keep non local returns in lambdas
val end = Label()
val end = linkedLabel()
val isTransformingAnonymousObject = nodeRemapper is RegeneratedLambdaFieldRemapper
transformedNode = doInline(transformedNode)
if (!isTransformingAnonymousObject) {
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.codegen.optimization.nullCheck
import org.jetbrains.kotlin.codegen.coroutines.withInstructionAdapter
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
import org.jetbrains.kotlin.codegen.linkWithLabel
import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue
import org.jetbrains.kotlin.codegen.optimization.common.debugText
import org.jetbrains.kotlin.codegen.optimization.common.isInsn
@@ -269,7 +270,7 @@ class RedundantNullCheckMethodTransformer(private val generationState: Generatio
// <...> -- v is null here
val jumpsIfNull = insn.opcode == Opcodes.IFNULL
val originalLabel = insn.label
val originalLabel = insn.label.linkWithLabel()
originalLabels[insn] = originalLabel
insn.label = synthetic(LabelNode(Label()))
@@ -342,7 +343,7 @@ class RedundantNullCheckMethodTransformer(private val generationState: Generatio
val originalLabel: LabelNode?
val insertAfterNotNull: AbstractInsnNode
if (jumpsIfInstance) {
originalLabel = next.label
originalLabel = next.label.linkWithLabel()
originalLabels[next] = next.label
val newLabel = synthetic(LabelNode(Label()))
methodNode.instructions.add(newLabel)
@@ -13,12 +13,9 @@ import org.jetbrains.kotlin.backend.jvm.intrinsics.JavaClassProperty
import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry
import org.jetbrains.kotlin.backend.jvm.lower.constantValue
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.unboxInlineClass
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.AsmUtil.*
import org.jetbrains.kotlin.codegen.BaseExpressionCodegen
import org.jetbrains.kotlin.codegen.CallGenerator
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.coroutines.SuspensionPointKind
import org.jetbrains.kotlin.codegen.extractReificationArgument
import org.jetbrains.kotlin.codegen.inline.*
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner.Companion.putNeedClassReificationMarker
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner.OperationKind.AS
@@ -148,6 +145,8 @@ class ExpressionCodegen(
private fun markNewLabel() = Label().apply { mv.visitLabel(this) }
private fun markNewLinkedLabel() = linkedLabel().apply { mv.visitLabel(this) }
private fun getLineNumberForOffset(offset: Int): Int = fileEntry?.getLineNumber(offset)?.plus(1) ?: -1
private fun IrElement.markLineNumber(startOffset: Boolean) {
@@ -1027,7 +1026,7 @@ class ExpressionCodegen(
data: BlockInfo,
nestedTryWithoutFinally: MutableList<TryInfo> = arrayListOf()
) {
val gapStart = markNewLabel()
val gapStart = markNewLinkedLabel()
finallyDepth++
if (isFinallyMarkerRequired()) {
generateFinallyMarker(mv, finallyDepth, true)