Drop unnecessary SubFrame creation from interpreter

This commit is contained in:
Ivan Kylchik
2021-06-21 18:32:15 +03:00
committed by TeamCityServer
parent 10efbeb0c9
commit 6ce2f8eb14
2 changed files with 7 additions and 34 deletions
@@ -46,10 +46,10 @@ internal fun unfoldInstruction(element: IrElement?, environment: IrInterpreterEn
null -> return null -> return
is IrSimpleFunction -> unfoldFunction(element, environment) is IrSimpleFunction -> unfoldFunction(element, environment)
is IrConstructor -> unfoldConstructor(element, callStack) is IrConstructor -> unfoldConstructor(element, callStack)
is IrCall -> unfoldCall(element, environment) is IrCall -> unfoldValueParameters(element, callStack)
is IrConstructorCall -> unfoldConstructorCall(element, environment) is IrConstructorCall -> unfoldValueParameters(element, callStack)
is IrEnumConstructorCall -> unfoldConstructorCall(element, environment) is IrEnumConstructorCall -> unfoldValueParameters(element, callStack)
is IrDelegatingConstructorCall -> unfoldConstructorCall(element, environment) is IrDelegatingConstructorCall -> unfoldValueParameters(element, callStack)
is IrInstanceInitializerCall -> unfoldInstanceInitializerCall(element, callStack) is IrInstanceInitializerCall -> unfoldInstanceInitializerCall(element, callStack)
is IrField -> unfoldField(element, callStack) is IrField -> unfoldField(element, callStack)
is IrBody -> unfoldBody(element, callStack) is IrBody -> unfoldBody(element, callStack)
@@ -117,17 +117,7 @@ private fun unfoldConstructor(constructor: IrConstructor, callStack: CallStack)
} }
} }
private fun unfoldCall(call: IrCall, environment: IrInterpreterEnvironment) { private fun unfoldValueParameters(expression: IrFunctionAccessExpression, callStack: CallStack) {
unfoldValueParameters(call, environment)
}
// This function is responsible for IrConstructorCall, IrDelegatingConstructorCall and IrEnumConstructorCall
private fun unfoldConstructorCall(constructorCall: IrFunctionAccessExpression, environment: IrInterpreterEnvironment) {
unfoldValueParameters(constructorCall, environment)
}
private fun unfoldValueParameters(expression: IrFunctionAccessExpression, environment: IrInterpreterEnvironment) {
val callStack = environment.callStack
val irFunction = expression.symbol.owner val irFunction = expression.symbol.owner
val hasDefaults = (0 until expression.valueArgumentsCount).any { expression.getValueArgument(it) == null } val hasDefaults = (0 until expression.valueArgumentsCount).any { expression.getValueArgument(it) == null }
@@ -245,8 +235,6 @@ private fun unfoldValueParameters(expression: IrFunctionAccessExpression, enviro
callStack.addInstruction(CompoundInstruction(callToDefault)) callStack.addInstruction(CompoundInstruction(callToDefault))
} else { } else {
// new sub frame is used to store value arguments, in case then they are used in default args evaluation
callStack.newSubFrame(expression) // TODO drop
callStack.addInstruction(SimpleInstruction(expression)) callStack.addInstruction(SimpleInstruction(expression))
fun IrValueParameter.schedule(arg: IrExpression?) { fun IrValueParameter.schedule(arg: IrExpression?) {
@@ -433,7 +421,6 @@ private fun unfoldThrow(expression: IrThrow, callStack: CallStack) {
private fun unfoldStringConcatenation(expression: IrStringConcatenation, environment: IrInterpreterEnvironment) { private fun unfoldStringConcatenation(expression: IrStringConcatenation, environment: IrInterpreterEnvironment) {
val callStack = environment.callStack val callStack = environment.callStack
callStack.newSubFrame(expression)
callStack.addInstruction(SimpleInstruction(expression)) callStack.addInstruction(SimpleInstruction(expression))
// this callback is used to check the need for an explicit toString call // this callback is used to check the need for an explicit toString call
@@ -453,7 +440,6 @@ private fun unfoldStringConcatenation(expression: IrStringConcatenation, environ
return callStack.pushState(result.toState(environment.irBuiltIns.stringType)) return callStack.pushState(result.toState(environment.irBuiltIns.stringType))
} }
val toStringCall = state.createToStringIrCall() val toStringCall = state.createToStringIrCall()
callStack.newSubFrame(toStringCall)
callStack.addInstruction(SimpleInstruction(toStringCall)) callStack.addInstruction(SimpleInstruction(toStringCall))
callStack.pushState(state) callStack.pushState(state)
} }
@@ -475,7 +461,6 @@ private fun unfoldComposite(element: IrComposite, callStack: CallStack) {
private fun unfoldFunctionReference(reference: IrFunctionReference, callStack: CallStack) { private fun unfoldFunctionReference(reference: IrFunctionReference, callStack: CallStack) {
val function = reference.symbol.owner val function = reference.symbol.owner
callStack.newSubFrame(reference)
callStack.addInstruction(SimpleInstruction(reference)) callStack.addInstruction(SimpleInstruction(reference))
reference.dispatchReceiver?.let { callStack.addInstruction(SimpleInstruction(function.dispatchReceiverParameter!!)) } reference.dispatchReceiver?.let { callStack.addInstruction(SimpleInstruction(function.dispatchReceiverParameter!!)) }
@@ -487,7 +472,6 @@ private fun unfoldFunctionReference(reference: IrFunctionReference, callStack: C
private fun unfoldPropertyReference(propertyReference: IrPropertyReference, callStack: CallStack) { private fun unfoldPropertyReference(propertyReference: IrPropertyReference, callStack: CallStack) {
val getter = propertyReference.getter!!.owner val getter = propertyReference.getter!!.owner
callStack.newSubFrame(propertyReference)
callStack.addInstruction(SimpleInstruction(propertyReference)) callStack.addInstruction(SimpleInstruction(propertyReference))
propertyReference.dispatchReceiver?.let { callStack.addInstruction(SimpleInstruction(getter.dispatchReceiverParameter!!)) } propertyReference.dispatchReceiver?.let { callStack.addInstruction(SimpleInstruction(getter.dispatchReceiverParameter!!)) }
@@ -81,7 +81,6 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
internal fun withNewCallStack(call: IrCall, init: IrInterpreter.() -> Any?): State { internal fun withNewCallStack(call: IrCall, init: IrInterpreter.() -> Any?): State {
return with(IrInterpreter(environment.copyWithNewCallStack(), bodyMap)) { return with(IrInterpreter(environment.copyWithNewCallStack(), bodyMap)) {
callStack.newFrame(call.symbol.owner) callStack.newFrame(call.symbol.owner)
callStack.newSubFrame(call)
init() init()
while (!callStack.hasNoInstructions()) { while (!callStack.hasNoInstructions()) {
@@ -159,8 +158,6 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
IllegalArgumentException("Parameter specified as non-null is null: method $method, parameter $parameter") IllegalArgumentException("Parameter specified as non-null is null: method $method, parameter $parameter")
} ?: return } ?: return
// outer classes can be used in default args evaluation
if (isReceiver() && state is Complex) state.loadOuterClassesInto(callStack)
callStack.pushState(state) callStack.pushState(state)
} }
@@ -182,7 +179,6 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
val irFunction = dispatchReceiver?.getIrFunctionByIrCall(call) ?: call.symbol.owner val irFunction = dispatchReceiver?.getIrFunctionByIrCall(call) ?: call.symbol.owner
val args = listOfNotNull(dispatchReceiver.getThisOrSuperReceiver(irFunction), extensionReceiver) + valueArguments val args = listOfNotNull(dispatchReceiver.getThisOrSuperReceiver(irFunction), extensionReceiver) + valueArguments
callStack.dropSubFrame() // drop intermediate frame that contains variables for default arg evaluation
callStack.newFrame(irFunction) callStack.newFrame(irFunction)
callStack.addInstruction(SimpleInstruction(irFunction)) callStack.addInstruction(SimpleInstruction(irFunction))
@@ -255,7 +251,6 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
if (irClass.isLocal) callStack.storeUpValues(objectState as StateWithClosure) if (irClass.isLocal) callStack.storeUpValues(objectState as StateWithClosure)
val outerClass = receiverSymbol?.let { callStack.popState() } val outerClass = receiverSymbol?.let { callStack.popState() }
callStack.dropSubFrame()
callStack.newFrame(constructor) callStack.newFrame(constructor)
callStack.addInstruction(SimpleInstruction(constructor)) callStack.addInstruction(SimpleInstruction(constructor))
if (irClass.isLocal) callStack.loadUpValues(objectState as StateWithClosure) if (irClass.isLocal) callStack.loadUpValues(objectState as StateWithClosure)
@@ -291,7 +286,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
} }
private fun interpretDelegatingConstructorCall(constructorCall: IrDelegatingConstructorCall) { private fun interpretDelegatingConstructorCall(constructorCall: IrDelegatingConstructorCall) {
if (constructorCall.symbol.owner.parent == irBuiltIns.anyClass.owner) return callStack.dropSubFrame() if (constructorCall.symbol.owner.parent == irBuiltIns.anyClass.owner) return
interpretConstructorCall(constructorCall) interpretConstructorCall(constructorCall)
} }
@@ -588,7 +583,6 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
} }
} }
callStack.dropSubFrame()
callStack.pushState(result.reversed().joinToString(separator = "").toState(expression.type)) callStack.pushState(result.reversed().joinToString(separator = "").toState(expression.type))
} }
@@ -604,8 +598,6 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
val dispatchReceiver = reference.dispatchReceiver?.let { callStack.popState() } val dispatchReceiver = reference.dispatchReceiver?.let { callStack.popState() }
val extensionReceiver = reference.extensionReceiver?.let { callStack.popState() } val extensionReceiver = reference.extensionReceiver?.let { callStack.popState() }
callStack.dropSubFrame()
val function = KFunctionState( val function = KFunctionState(
reference, reference,
dispatchReceiver?.let { Variable(irFunction.getDispatchReceiver()!!, it) }, dispatchReceiver?.let { Variable(irFunction.getDispatchReceiver()!!, it) },
@@ -617,10 +609,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
private fun interpretPropertyReference(propertyReference: IrPropertyReference) { private fun interpretPropertyReference(propertyReference: IrPropertyReference) {
// it is impossible to get KProperty2 through ::, so only one receiver can be not null (or both null) // it is impossible to get KProperty2 through ::, so only one receiver can be not null (or both null)
val receiver = (propertyReference.dispatchReceiver ?: propertyReference.extensionReceiver) val receiver = (propertyReference.dispatchReceiver ?: propertyReference.extensionReceiver)?.let { callStack.popState() }
?.let { callStack.popState() }
callStack.dropSubFrame()
val propertyState = KPropertyState(propertyReference, receiver) val propertyState = KPropertyState(propertyReference, receiver)
fun List<IrTypeParameter>.addToFields() { fun List<IrTypeParameter>.addToFields() {