From eced9bb11a673fd2f8420bc88292ca2de094b253 Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Tue, 21 Feb 2017 17:46:20 +0300 Subject: [PATCH] refactoring --- .../konan/descriptors/ClassVtablesBuilder.kt | 72 +++++++++---------- .../konan/descriptors/DescriptorUtils.kt | 5 +- .../backend/konan/llvm/RTTIGenerator.kt | 9 ++- .../backend/konan/lower/BridgesBuilding.kt | 12 +++- 4 files changed, 56 insertions(+), 42 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/ClassVtablesBuilder.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/ClassVtablesBuilder.kt index b64e06e500c..3d81aafd28f 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/ClassVtablesBuilder.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/ClassVtablesBuilder.kt @@ -23,7 +23,7 @@ internal class OverriddenFunctionDescriptor(val descriptor: FunctionDescriptor, get() = descriptor.target.bridgeDirectionsTo(overriddenDescriptor) val canBeCalledVirtually: Boolean - // We check that either method is open, or one of declarations it overrides is open. + // We check that either method is open, or one of declarations it overrides is open. get() = overriddenDescriptor.isOverridable || DescriptorUtils.getAllOverriddenDeclarations(overriddenDescriptor).any { it.isOverridable } @@ -70,30 +70,29 @@ internal class ClassVtablesBuilder(val classDescriptor: ClassDescriptor, val con if (overridingMethod == null) { superMethod } else { - // Add all possible (descriptor, overriddenDescriptor) edges for now, redundant will be removed later. newVtableSlots.add(OverriddenFunctionDescriptor(overridingMethod, superMethod.descriptor)) - newVtableSlots.add(OverriddenFunctionDescriptor(overridingMethod, overridingMethod)) OverriddenFunctionDescriptor(overridingMethod, superMethod.overriddenDescriptor) } } - println("VTABLE_ENTRIES inherited vtable:") - inheritedVtableSlots.forEach { - println(" VTABLE_ENTRIES descriptor: ${it.descriptor}") - println(" VTABLE_ENTRIES overriddenDescriptor: ${it.overriddenDescriptor}") - println(" VTABLE_ENTRIES needBridge: ${it.needBridge}") - if (it.needBridge) - println(" VTABLE_ENTRIES bridgeDirections: ${it.bridgeDirections.toString()}") - } - println() + println("VTABLE_ENTRIES inherited vtable:") + inheritedVtableSlots.forEach { + println(" VTABLE_ENTRIES descriptor: ${it.descriptor}") + println(" VTABLE_ENTRIES overriddenDescriptor: ${it.overriddenDescriptor}") + println(" VTABLE_ENTRIES needBridge: ${it.needBridge}") + if (it.needBridge) + println(" VTABLE_ENTRIES bridgeDirections: ${it.bridgeDirections.toString()}") + } + println() - val zzz = inheritedVtableSlots.map { it.descriptor to it.bridgeDirections }.toSet() + // Add all possible (descriptor, overriddenDescriptor) edges for now, redundant will be removed later. methods.mapTo(newVtableSlots) { OverriddenFunctionDescriptor(it, it) } + val inheritedVtableSlotsSet = inheritedVtableSlots.map { it.descriptor to it.bridgeDirections }.toSet() val filteredNewVtableSlots = newVtableSlots - .filter { !zzz.contains(it.descriptor to it.bridgeDirections) } + .filterNot { inheritedVtableSlotsSet.contains(it.descriptor to it.bridgeDirections) } .distinctBy { it.descriptor to it.bridgeDirections } .filter { it.descriptor.isOverridable } println("VTABLE_ENTRIES new vtable:") @@ -109,16 +108,16 @@ internal class ClassVtablesBuilder(val classDescriptor: ClassDescriptor, val con val list = inheritedVtableSlots + filteredNewVtableSlots.sortedBy { it.overriddenDescriptor.functionName.localHash.value } - println("VTABLE_ENTRIES vtable:") - list.forEach { - println(" VTABLE_ENTRIES descriptor: ${it.descriptor}") - println(" VTABLE_ENTRIES overriddenDescriptor: ${it.overriddenDescriptor}") - println(" VTABLE_ENTRIES needBridge: ${it.needBridge}") - if (it.needBridge) - println(" VTABLE_ENTRIES bridgeDirections: ${it.bridgeDirections.toString()}") - } - println() - println() + println("VTABLE_ENTRIES vtable:") + list.forEach { + println(" VTABLE_ENTRIES descriptor: ${it.descriptor}") + println(" VTABLE_ENTRIES overriddenDescriptor: ${it.overriddenDescriptor}") + println(" VTABLE_ENTRIES needBridge: ${it.needBridge}") + if (it.needBridge) + println(" VTABLE_ENTRIES bridgeDirections: ${it.bridgeDirections.toString()}") + } + println() + println() return list @@ -126,11 +125,12 @@ internal class ClassVtablesBuilder(val classDescriptor: ClassDescriptor, val con fun vtableIndex(function: FunctionDescriptor): Int { val target = function.target - println("VTABLE_INDEX function: $function") + val bridgeDirections = target.bridgeDirectionsTo(function.original) + println("VTABLE_INDEX function: $function") println("VTABLE_INDEX original: ${function.original}") - println("VTABLE_INDEX target: ${target}") + println("VTABLE_INDEX target: ${target}") println("VTABLE_INDEX bridgeDirections: ${target.bridgeDirectionsTo(function.original).toString()}") - val index = vtableEntries.indexOfFirst { it.descriptor == function.original && it.bridgeDirections == target.bridgeDirectionsTo(function.original) } + val index = vtableEntries.indexOfFirst { it.descriptor == function.original && it.bridgeDirections == bridgeDirections } if (index < 0) throw Error(function.toString() + " not in vtable of " + classDescriptor.toString()) return index.apply { println("VTABLE_INDEX index: $this"); println() } } @@ -153,18 +153,18 @@ internal class ClassVtablesBuilder(val classDescriptor: ClassDescriptor, val con val contributedMethodsWithOverridden = classDescriptor.contributedMethodsWithOverridden println("METHOD_TABLE_ENTRIES: contributed methods") - contributedMethodsWithOverridden.forEach { - println(" METHOD_TABLE_ENTRIES: descriptor = ${it.descriptor}") - println(" METHOD_TABLE_ENTRIES: overriddenDescriptor = ${it.overriddenDescriptor}") - println(" METHOD_TABLE_ENTRIES: overriddenDescriptor.isOverridable = ${it.overriddenDescriptor.isOverridable}") - } + contributedMethodsWithOverridden.forEach { + println(" METHOD_TABLE_ENTRIES: descriptor = ${it.descriptor}") + println(" METHOD_TABLE_ENTRIES: overriddenDescriptor = ${it.overriddenDescriptor}") + println(" METHOD_TABLE_ENTRIES: overriddenDescriptor.isOverridable = ${it.overriddenDescriptor.isOverridable}") + } val result = contributedMethodsWithOverridden.filter { it.canBeCalledVirtually } println("METHOD_TABLE_ENTRIES: result") - result.forEach { - println(" METHOD_TABLE_ENTRIES: descriptor = ${it.descriptor}") - println(" METHOD_TABLE_ENTRIES: overriddenDescriptor = ${it.overriddenDescriptor}") - } + result.forEach { + println(" METHOD_TABLE_ENTRIES: descriptor = ${it.descriptor}") + println(" METHOD_TABLE_ENTRIES: overriddenDescriptor = ${it.overriddenDescriptor}") + } return result // TODO: probably method table should contain all accessible methods to improve binary compatibility } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt index 399f3faff2e..3ba8d76a2f0 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt @@ -269,7 +269,10 @@ internal fun FunctionDescriptor.bridgeDirectionsTo(overriddenDescriptor: Functio for (index in ourDirections.array.indices) ourDirections.array[index] = this.bridgeDirectionToAt(overriddenDescriptor, index) - if (!kind.isReal && OverridingUtil.overrides(this.target, overriddenDescriptor) && ourDirections == this.target.bridgeDirectionsTo(overriddenDescriptor)) { + val target = this.target + if (!kind.isReal + && OverridingUtil.overrides(target, overriddenDescriptor) + && ourDirections == target.bridgeDirectionsTo(overriddenDescriptor)) { // Bridge is inherited from supers return BridgeDirections(this.valueParameters.size) } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt index 1f703419295..b28da83f736 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt @@ -181,8 +181,13 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { val target = descriptor.target println("IMPLEMENTATION target: ${target}") if (!needBridge) return target - //val bridgeOwner = if (!descriptor.kind.isReal && OverridingUtil.overrides(target, overriddenDescriptor) && !descriptor.needBridgeTo(overriddenDescriptor)) if (descriptor.bridgeDirectionsTo(overriddenDescriptor).allNotNeeded()) target else descriptor - val bridgeOwner = if (!descriptor.kind.isReal && OverridingUtil.overrides(target, overriddenDescriptor) && descriptor.bridgeDirectionsTo(overriddenDescriptor).allNotNeeded()) target else descriptor + val bridgeOwner = if (!descriptor.kind.isReal + && OverridingUtil.overrides(target, overriddenDescriptor) + && descriptor.bridgeDirectionsTo(overriddenDescriptor).allNotNeeded()) { + target // Bridge is inherited from supers + } else { + descriptor + } println("IMPLEMENTATION owner: ${bridgeOwner}") return context.specialDescriptorsFactory.getBridgeDescriptor(OverriddenFunctionDescriptor(bridgeOwner, overriddenDescriptor)) } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/BridgesBuilding.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/BridgesBuilding.kt index 9a666332096..4038668fb71 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/BridgesBuilding.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/BridgesBuilding.kt @@ -36,7 +36,12 @@ internal class DirectBridgesCallsLowering(val context: Context) : BodyLoweringPa if (descriptor.kind != CallableMemberDescriptor.Kind.DELEGATION && !needBridge) return expression - val toCall = if (needBridge) target else context.specialDescriptorsFactory.getBridgeDescriptor(OverriddenFunctionDescriptor(descriptor, target)) + val toCall = if (needBridge) { + target + } else { + // Need to call delegating fun. + context.specialDescriptorsFactory.getBridgeDescriptor(OverriddenFunctionDescriptor(descriptor, target)) + } return IrCallImpl(expression.startOffset, expression.endOffset, toCall, remapTypeArguments(expression, toCall)).apply { @@ -150,8 +155,9 @@ internal class BridgesBuilding(val context: Context) : ClassLoweringPass { .filter { !it.bridgeDirections.allNotNeeded() } .filter { it.canBeCalledVirtually } .distinctBy { it.bridgeDirections } - .forEach { buildBridge(it, irClass) - } + .forEach { + buildBridge(it, irClass) + } } } }