Revert: Forbid suspension points in critical sections
This commit is contained in:
@@ -2438,11 +2438,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return;
|
||||
}
|
||||
|
||||
if (resolvedCall.getResultingDescriptor() instanceof FunctionDescriptor &&
|
||||
((FunctionDescriptor) resolvedCall.getResultingDescriptor()).isSuspend()) {
|
||||
state.getGlobalCoroutinesContext().checkSuspendCall(resolvedCall);
|
||||
}
|
||||
|
||||
boolean isSuspendNoInlineCall =
|
||||
CoroutineCodegenUtilKt.isSuspendNoInlineCall(resolvedCall, this, state.getLanguageVersionSettings());
|
||||
boolean isConstructor = resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor;
|
||||
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.coroutines
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.peek
|
||||
import org.jetbrains.kotlin.backend.common.pop
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.SUSPENSION_POINT_INSIDE_MONITOR
|
||||
|
||||
class GlobalCoroutinesContext(private val diagnostics: DiagnosticSink) {
|
||||
private var monitorsDepth = 0
|
||||
|
||||
private val inlineLambdaInsideMonitorSourceArgumentIndexes = arrayListOf<Set<Int>>()
|
||||
|
||||
fun pushArgumentIndexes(indexes: Set<Int>) {
|
||||
inlineLambdaInsideMonitorSourceArgumentIndexes.add(indexes)
|
||||
}
|
||||
|
||||
fun popArgumentIndexes() {
|
||||
inlineLambdaInsideMonitorSourceArgumentIndexes.pop()
|
||||
}
|
||||
|
||||
private fun enterMonitor() {
|
||||
monitorsDepth++
|
||||
}
|
||||
|
||||
fun enterMonitorIfNeeded(index: Int?) {
|
||||
if (index == null) return
|
||||
if (inlineLambdaInsideMonitorSourceArgumentIndexes.peek()?.contains(index) != true) return
|
||||
enterMonitor()
|
||||
}
|
||||
|
||||
private fun exitMonitor() {
|
||||
assert(monitorsDepth > 0) {
|
||||
"exitMonitor without corresponding enterMonitor"
|
||||
}
|
||||
monitorsDepth--
|
||||
}
|
||||
|
||||
fun exitMonitorIfNeeded(index: Int?) {
|
||||
if (index == null) return
|
||||
if (inlineLambdaInsideMonitorSourceArgumentIndexes.peek()?.contains(index) != true) return
|
||||
exitMonitor()
|
||||
}
|
||||
|
||||
fun checkSuspendCall(call: ResolvedCall<*>) {
|
||||
if (monitorsDepth != 0) {
|
||||
diagnostics.report(SUSPENSION_POINT_INSIDE_MONITOR.on(call.call.callElement, call.resultingDescriptor))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.codegen.inline
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.util.ArrayUtil
|
||||
import org.jetbrains.kotlin.backend.common.isBuiltInIntercepted
|
||||
import org.jetbrains.kotlin.backend.common.isTopLevelInPackage
|
||||
import org.jetbrains.kotlin.builtins.BuiltInsPackageFragment
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.getMethodAsmFlags
|
||||
@@ -20,8 +19,6 @@ import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForSuspendCorouti
|
||||
import org.jetbrains.kotlin.codegen.coroutines.isBuiltInSuspendCoroutineUninterceptedOrReturnInJvm
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.bytecode
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.classId
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.ControlFlowGraph
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
@@ -247,18 +244,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
}
|
||||
}
|
||||
val reificationResult = reifiedTypeInliner.reifyInstructions(node)
|
||||
|
||||
val hasMonitor = node.instructions.asSequence().any { it.opcode == Opcodes.MONITORENTER }
|
||||
if (hasMonitor) {
|
||||
state.globalCoroutinesContext.pushArgumentIndexes(findInlineLambdasInsideMonitor(node))
|
||||
}
|
||||
try {
|
||||
generateClosuresBodies()
|
||||
} finally {
|
||||
if (hasMonitor) {
|
||||
state.globalCoroutinesContext.popArgumentIndexes()
|
||||
}
|
||||
}
|
||||
generateClosuresBodies()
|
||||
|
||||
//through generation captured parameters will be added to invocationParamBuilder
|
||||
putClosureParametersOnStack()
|
||||
@@ -315,45 +301,6 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
return result
|
||||
}
|
||||
|
||||
private fun findInlineLambdasInsideMonitor(node: MethodNode): Set<Int> {
|
||||
val sources = MethodInliner.analyzeMethodNodeBeforeInline(node)
|
||||
|
||||
val cfg = ControlFlowGraph.build(node)
|
||||
val monitorDepthMap = hashMapOf<AbstractInsnNode, Int>()
|
||||
val result = hashSetOf<Int>()
|
||||
|
||||
fun addMonitorDepthToSuccs(index: Int, depth: Int) {
|
||||
val insn = node.instructions[index]
|
||||
monitorDepthMap[insn] = depth
|
||||
val newDepth = when (insn.opcode) {
|
||||
Opcodes.MONITORENTER -> depth + 1
|
||||
Opcodes.MONITOREXIT -> depth - 1
|
||||
else -> depth
|
||||
}
|
||||
for (succIndex in cfg.getSuccessorsIndices(index)) {
|
||||
if (monitorDepthMap[node.instructions[succIndex]] == null) {
|
||||
addMonitorDepthToSuccs(succIndex, newDepth)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addMonitorDepthToSuccs(0, 0)
|
||||
|
||||
for (insn in node.instructions.asSequence()) {
|
||||
if (insn !is MethodInsnNode) continue
|
||||
if (!isInvokeOnLambda(insn.owner, insn.name)) continue
|
||||
if (monitorDepthMap[insn]?.let { it > 0 } != true) continue
|
||||
val frame = sources[node.instructions.indexOf(insn)] ?: continue
|
||||
for (source in frame.getStack(frame.stackSize - Type.getArgumentTypes(insn.desc).size - 1).insns) {
|
||||
if (source.opcode == Opcodes.ALOAD) {
|
||||
result.add((source as VarInsnNode).`var`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun isInlinedToInlineFunInKotlinRuntime(): Boolean {
|
||||
val codegen = this.codegen as? ExpressionCodegen ?: return false
|
||||
val caller = codegen.context.functionDescriptor
|
||||
@@ -363,16 +310,8 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
}
|
||||
|
||||
private fun generateClosuresBodies() {
|
||||
val parameters = invocationParamBuilder.buildParameters()
|
||||
|
||||
for (info in expressionMap.values) {
|
||||
val index = parameters.find { it.lambda == info }?.index
|
||||
state.globalCoroutinesContext.enterMonitorIfNeeded(index)
|
||||
try {
|
||||
info.generateLambdaBody(sourceCompiler, reifiedTypeInliner)
|
||||
} finally {
|
||||
state.globalCoroutinesContext.exitMonitorIfNeeded(index)
|
||||
}
|
||||
info.generateLambdaBody(sourceCompiler, reifiedTypeInliner)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -998,7 +998,7 @@ class MethodInliner(
|
||||
)
|
||||
}
|
||||
|
||||
fun analyzeMethodNodeBeforeInline(node: MethodNode): Array<Frame<SourceValue>?> {
|
||||
private fun analyzeMethodNodeBeforeInline(node: MethodNode): Array<Frame<SourceValue>?> {
|
||||
val analyzer = object : Analyzer<SourceValue>(SourceInterpreter()) {
|
||||
override fun newFrame(nLocals: Int, nStack: Int): Frame<SourceValue> {
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.codegen.`when`.MappingsClassesForWhenByEnum
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContext
|
||||
import org.jetbrains.kotlin.codegen.context.RootContext
|
||||
import org.jetbrains.kotlin.codegen.coroutines.GlobalCoroutinesContext
|
||||
import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
|
||||
import org.jetbrains.kotlin.codegen.inline.GlobalInlineContext
|
||||
import org.jetbrains.kotlin.codegen.inline.InlineCache
|
||||
@@ -203,7 +202,6 @@ class GenerationState private constructor(
|
||||
}
|
||||
val samWrapperClasses: SamWrapperClasses = SamWrapperClasses(this)
|
||||
val globalInlineContext: GlobalInlineContext = GlobalInlineContext(diagnostics)
|
||||
val globalCoroutinesContext: GlobalCoroutinesContext = GlobalCoroutinesContext(diagnostics)
|
||||
val mappingsClassesForWhenByEnum: MappingsClassesForWhenByEnum = MappingsClassesForWhenByEnum(this)
|
||||
val jvmRuntimeTypes: JvmRuntimeTypes = JvmRuntimeTypes(module, configuration.languageVersionSettings)
|
||||
val factory: ClassFileFactory
|
||||
|
||||
Reference in New Issue
Block a user