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"; assert topOfStack == tryWithFinallyBlockStackElement : "Top element of stack doesn't equals processing finally block";
KtTryExpression jetTryExpression = tryWithFinallyBlockStackElement.expression; KtTryExpression jetTryExpression = tryWithFinallyBlockStackElement.expression;
Label finallyStart = new Label(); Label finallyStart = linkedLabel();
v.mark(finallyStart); v.mark(finallyStart);
tryWithFinallyBlockStackElement.addGapLabel(finallyStart); tryWithFinallyBlockStackElement.addGapLabel(finallyStart);
addGapLabelsForNestedTryCatchWithoutFinally(state, nestedTryBlocksWithoutFinally, 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.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.commons.Method import org.jetbrains.org.objectweb.asm.commons.Method
import org.jetbrains.org.objectweb.asm.tree.LabelNode
import java.util.* import java.util.*
fun generateIsCheck( fun generateIsCheck(
@@ -666,3 +667,22 @@ private fun generateLambdaForRunSuspend(
lambdaBuilder.done() lambdaBuilder.done()
return lambdaBuilder.thisName 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.inline.*
import org.jetbrains.kotlin.codegen.optimization.common.* import org.jetbrains.kotlin.codegen.optimization.common.*
import org.jetbrains.kotlin.codegen.optimization.fixStack.FixStackMethodTransformer 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.LanguageVersionSettings
import org.jetbrains.kotlin.config.isReleaseCoroutines import org.jetbrains.kotlin.config.isReleaseCoroutines
import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.resolve.jvm.AsmTypes
@@ -741,7 +742,7 @@ class CoroutineTransformerMethodVisitor(
suspendMarkerVarIndex: Int, suspendMarkerVarIndex: Int,
suspendPointLineNumber: LineNumberNode? suspendPointLineNumber: LineNumberNode?
): LabelNode { ): LabelNode {
val continuationLabel = LabelNode() val continuationLabel = LabelNode().linkWithLabel()
val continuationLabelAfterLoadedResult = LabelNode() val continuationLabelAfterLoadedResult = LabelNode()
val suspendElementLineNumber = lineNumber val suspendElementLineNumber = lineNumber
var nextLineNumberNode = nextDefinitelyHitLineNumber(suspension) var nextLineNumberNode = nextDefinitelyHitLineNumber(suspension)
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.codegen.inline package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.linkWithLabel
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor 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.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.LabelNode
import org.jetbrains.org.objectweb.asm.tree.MethodNode import org.jetbrains.org.objectweb.asm.tree.MethodNode
class InlineCodegenForDefaultBody( class InlineCodegenForDefaultBody(
@@ -27,7 +29,7 @@ class InlineCodegenForDefaultBody(
) : CallGenerator { ) : CallGenerator {
private val sourceMapper: SourceMapper = codegen.parentCodegen.orCreateSourceMapper private val sourceMapper: SourceMapper = codegen.parentCodegen.orCreateSourceMapper
private val methodStartLabel = Label() private val methodStartLabel = linkedLabel()
init { init {
assert(InlineUtil.isInline(function)) { assert(InlineUtil.isInline(function)) {
@@ -33,6 +33,7 @@ import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.*; 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.InlineCodegenUtilsKt.*;
import static org.jetbrains.kotlin.codegen.inline.MethodInlinerUtilKt.getNextMeaningful; 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 //Creating temp node for finally block copy with some additional instruction
MethodNode finallyBlockCopy = createEmptyMethodNode(); MethodNode finallyBlockCopy = createEmptyMethodNode();
Label newFinallyStart = new Label(); Label newFinallyStart = new Label();
Label insertedBlockEnd = new Label(); Label insertedBlockEnd = linkedLabel();
boolean generateAloadAstore = nonLocalReturnType != Type.VOID_TYPE && !finallyInfo.isEmpty(); boolean generateAloadAstore = nonLocalReturnType != Type.VOID_TYPE && !finallyInfo.isEmpty();
if (generateAloadAstore) { if (generateAloadAstore) {
@@ -102,7 +102,7 @@ class MethodInliner(
} }
//substitute returns with "goto end" instruction to keep non local returns in lambdas //substitute returns with "goto end" instruction to keep non local returns in lambdas
val end = Label() val end = linkedLabel()
val isTransformingAnonymousObject = nodeRemapper is RegeneratedLambdaFieldRemapper val isTransformingAnonymousObject = nodeRemapper is RegeneratedLambdaFieldRemapper
transformedNode = doInline(transformedNode) transformedNode = doInline(transformedNode)
if (!isTransformingAnonymousObject) { 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.coroutines.withInstructionAdapter
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods 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.StrictBasicValue
import org.jetbrains.kotlin.codegen.optimization.common.debugText import org.jetbrains.kotlin.codegen.optimization.common.debugText
import org.jetbrains.kotlin.codegen.optimization.common.isInsn import org.jetbrains.kotlin.codegen.optimization.common.isInsn
@@ -269,7 +270,7 @@ class RedundantNullCheckMethodTransformer(private val generationState: Generatio
// <...> -- v is null here // <...> -- v is null here
val jumpsIfNull = insn.opcode == Opcodes.IFNULL val jumpsIfNull = insn.opcode == Opcodes.IFNULL
val originalLabel = insn.label val originalLabel = insn.label.linkWithLabel()
originalLabels[insn] = originalLabel originalLabels[insn] = originalLabel
insn.label = synthetic(LabelNode(Label())) insn.label = synthetic(LabelNode(Label()))
@@ -342,7 +343,7 @@ class RedundantNullCheckMethodTransformer(private val generationState: Generatio
val originalLabel: LabelNode? val originalLabel: LabelNode?
val insertAfterNotNull: AbstractInsnNode val insertAfterNotNull: AbstractInsnNode
if (jumpsIfInstance) { if (jumpsIfInstance) {
originalLabel = next.label originalLabel = next.label.linkWithLabel()
originalLabels[next] = next.label originalLabels[next] = next.label
val newLabel = synthetic(LabelNode(Label())) val newLabel = synthetic(LabelNode(Label()))
methodNode.instructions.add(newLabel) 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.MultifileFacadeFileEntry
import org.jetbrains.kotlin.backend.jvm.lower.constantValue import org.jetbrains.kotlin.backend.jvm.lower.constantValue
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.unboxInlineClass 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.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.coroutines.SuspensionPointKind
import org.jetbrains.kotlin.codegen.extractReificationArgument
import org.jetbrains.kotlin.codegen.inline.* import org.jetbrains.kotlin.codegen.inline.*
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner.Companion.putNeedClassReificationMarker import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner.Companion.putNeedClassReificationMarker
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner.OperationKind.AS 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 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 getLineNumberForOffset(offset: Int): Int = fileEntry?.getLineNumber(offset)?.plus(1) ?: -1
private fun IrElement.markLineNumber(startOffset: Boolean) { private fun IrElement.markLineNumber(startOffset: Boolean) {
@@ -1027,7 +1026,7 @@ class ExpressionCodegen(
data: BlockInfo, data: BlockInfo,
nestedTryWithoutFinally: MutableList<TryInfo> = arrayListOf() nestedTryWithoutFinally: MutableList<TryInfo> = arrayListOf()
) { ) {
val gapStart = markNewLabel() val gapStart = markNewLinkedLabel()
finallyDepth++ finallyDepth++
if (isFinallyMarkerRequired()) { if (isFinallyMarkerRequired()) {
generateFinallyMarker(mv, finallyDepth, true) generateFinallyMarker(mv, finallyDepth, true)