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
is IrSimpleFunction -> unfoldFunction(element, environment)
is IrConstructor -> unfoldConstructor(element, callStack)
is IrCall -> unfoldCall(element, environment)
is IrConstructorCall -> unfoldConstructorCall(element, environment)
is IrEnumConstructorCall -> unfoldConstructorCall(element, environment)
is IrDelegatingConstructorCall -> unfoldConstructorCall(element, environment)
is IrCall -> unfoldValueParameters(element, callStack)
is IrConstructorCall -> unfoldValueParameters(element, callStack)
is IrEnumConstructorCall -> unfoldValueParameters(element, callStack)
is IrDelegatingConstructorCall -> unfoldValueParameters(element, callStack)
is IrInstanceInitializerCall -> unfoldInstanceInitializerCall(element, callStack)
is IrField -> unfoldField(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) {
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
private fun unfoldValueParameters(expression: IrFunctionAccessExpression, callStack: CallStack) {
val irFunction = expression.symbol.owner
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))
} 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))
fun IrValueParameter.schedule(arg: IrExpression?) {
@@ -433,7 +421,6 @@ private fun unfoldThrow(expression: IrThrow, callStack: CallStack) {
private fun unfoldStringConcatenation(expression: IrStringConcatenation, environment: IrInterpreterEnvironment) {
val callStack = environment.callStack
callStack.newSubFrame(expression)
callStack.addInstruction(SimpleInstruction(expression))
// 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))
}
val toStringCall = state.createToStringIrCall()
callStack.newSubFrame(toStringCall)
callStack.addInstruction(SimpleInstruction(toStringCall))
callStack.pushState(state)
}
@@ -475,7 +461,6 @@ private fun unfoldComposite(element: IrComposite, callStack: CallStack) {
private fun unfoldFunctionReference(reference: IrFunctionReference, callStack: CallStack) {
val function = reference.symbol.owner
callStack.newSubFrame(reference)
callStack.addInstruction(SimpleInstruction(reference))
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) {
val getter = propertyReference.getter!!.owner
callStack.newSubFrame(propertyReference)
callStack.addInstruction(SimpleInstruction(propertyReference))
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 {
return with(IrInterpreter(environment.copyWithNewCallStack(), bodyMap)) {
callStack.newFrame(call.symbol.owner)
callStack.newSubFrame(call)
init()
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")
} ?: return
// outer classes can be used in default args evaluation
if (isReceiver() && state is Complex) state.loadOuterClassesInto(callStack)
callStack.pushState(state)
}
@@ -182,7 +179,6 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
val irFunction = dispatchReceiver?.getIrFunctionByIrCall(call) ?: call.symbol.owner
val args = listOfNotNull(dispatchReceiver.getThisOrSuperReceiver(irFunction), extensionReceiver) + valueArguments
callStack.dropSubFrame() // drop intermediate frame that contains variables for default arg evaluation
callStack.newFrame(irFunction)
callStack.addInstruction(SimpleInstruction(irFunction))
@@ -255,7 +251,6 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
if (irClass.isLocal) callStack.storeUpValues(objectState as StateWithClosure)
val outerClass = receiverSymbol?.let { callStack.popState() }
callStack.dropSubFrame()
callStack.newFrame(constructor)
callStack.addInstruction(SimpleInstruction(constructor))
if (irClass.isLocal) callStack.loadUpValues(objectState as StateWithClosure)
@@ -291,7 +286,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
}
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)
}
@@ -588,7 +583,6 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
}
}
callStack.dropSubFrame()
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 extensionReceiver = reference.extensionReceiver?.let { callStack.popState() }
callStack.dropSubFrame()
val function = KFunctionState(
reference,
dispatchReceiver?.let { Variable(irFunction.getDispatchReceiver()!!, it) },
@@ -617,10 +609,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
private fun interpretPropertyReference(propertyReference: IrPropertyReference) {
// it is impossible to get KProperty2 through ::, so only one receiver can be not null (or both null)
val receiver = (propertyReference.dispatchReceiver ?: propertyReference.extensionReceiver)
?.let { callStack.popState() }
callStack.dropSubFrame()
val receiver = (propertyReference.dispatchReceiver ?: propertyReference.extensionReceiver)?.let { callStack.popState() }
val propertyState = KPropertyState(propertyReference, receiver)
fun List<IrTypeParameter>.addToFields() {