3efd98df1a
Merge-request: KT-MR-11899 Merged-by: Alexey Glushko <aleksei.glushko@jetbrains.com>
87 lines
1.9 KiB
Swift
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() }
|
|
}
|
|
}
|