Files
Aleksei.Glushko 3efd98df1a [K/N] More work to do for weak-sweeper in weak ref benchmarks
Merge-request: KT-MR-11899
Merged-by: Alexey Glushko <aleksei.glushko@jetbrains.com>
2023-08-29 10:52:33 +00:00

87 lines
1.9 KiB
Swift

/*
* Copyright 2010-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the LICENSE file.
*/
import Foundation
import benchmark
private let REPEAT_COUNT = 10000
private class ReferenceWrapper {
private weak var weakRef: KotlinData?
private var strongRef: KotlinData?
init() {
let data = KotlinData(x: Int32.random(in: 1 ... 1000))
self.strongRef = data
self.weakRef = data
}
// This function must not be inlined. We must ensure `weakRef` is accessed at each loop iteration.
@inline(never) func value() -> Int32 {
let ref: KotlinData? = self.weakRef
if ref == nil {
return 0
}
return ref!.x
}
func dispose() {
self.strongRef = nil
}
func stress() -> Int32 {
var counter: Int32 = 0
for _ in 1...REPEAT_COUNT {
counter += self.value()
}
return counter
}
}
private func deadReferenceWrapper() -> ReferenceWrapper {
let ref = ReferenceWrapper()
ref.dispose()
GCKt.collect()
return ref
}
class WeakRefBenchmark {
private let weight = (0..<10_000).map { _ in ReferenceWrapper() }
private let aliveRef = ReferenceWrapper()
private let deadRef = deadReferenceWrapper()
// Access alive reference.
func aliveReference() {
let counter = aliveRef.stress()
if counter == 0 {
fatalError()
}
}
// Access dead reference.
func deadReference() {
let counter = deadRef.stress()
if counter != 0 {
fatalError()
}
}
// Access reference that is nulled out in the middle.
func dyingReference() {
let ref = ReferenceWrapper()
ref.dispose()
GCKt.schedule()
let counter = ref.stress()
Blackhole.companion.consume(value: counter)
}
func clean() {
weight.forEach { $0.dispose() }
}
}