Skip to content

Commit 2213b4e

Browse files
committed
[stdlib] Set, Dictionary: Review _SwiftDeferredNS*
1 parent 548f59a commit 2213b4e

File tree

2 files changed

+134
-143
lines changed

2 files changed

+134
-143
lines changed

stdlib/public/core/Dictionary.swift

Lines changed: 86 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -2826,7 +2826,7 @@ final internal class _SwiftDeferredNSDictionary<Key: Hashable, Value>
28262826
//
28272827
// Do not access this property directly.
28282828
@nonobjc
2829-
internal var _heapStorageBridged_DoNotUse: AnyObject?
2829+
private var _bridgedStorage_DoNotUse: AnyObject?
28302830

28312831
/// The unbridged elements.
28322832
internal var native: _NativeDictionary<Key, Value>
@@ -2836,11 +2836,63 @@ final internal class _SwiftDeferredNSDictionary<Key: Hashable, Value>
28362836
super.init()
28372837
}
28382838

2839-
@objc(copyWithZone:)
2840-
internal func copy(with zone: _SwiftNSZone?) -> AnyObject {
2841-
// Instances of this class should be visible outside of standard library as
2842-
// having `NSDictionary` type, which is immutable.
2843-
return self
2839+
/// Returns the pointer to the stored property, which contains bridged
2840+
/// Dictionary elements.
2841+
@nonobjc
2842+
private var _bridgedStoragePtr: UnsafeMutablePointer<AnyObject?> {
2843+
return _getUnsafePointerToStoredProperties(self).assumingMemoryBound(
2844+
to: Optional<AnyObject>.self)
2845+
}
2846+
2847+
/// The buffer for bridged Dictionary elements, if present.
2848+
@nonobjc
2849+
private var _bridgedStorage: _RawNativeDictionaryStorage? {
2850+
get {
2851+
if let ref = _stdlib_atomicLoadARCRef(object: _bridgedStoragePtr) {
2852+
return unsafeDowncast(ref, to: _RawNativeDictionaryStorage.self)
2853+
}
2854+
return nil
2855+
}
2856+
}
2857+
2858+
/// Attach a buffer for bridged Dictionary elements.
2859+
@nonobjc
2860+
private func _initializeBridgedStorage(_ storage: AnyObject) {
2861+
_stdlib_atomicInitializeARCRef(object: _bridgedStoragePtr, desired: storage)
2862+
}
2863+
2864+
/// Returns the bridged Dictionary values.
2865+
internal var bridged: _NativeDictionary<AnyObject, AnyObject> {
2866+
return _NativeDictionary(_storage: _bridgedStorage!)
2867+
}
2868+
2869+
@nonobjc
2870+
internal func bridgeEverything() {
2871+
if _fastPath(_bridgedStorage != nil) {
2872+
return
2873+
}
2874+
2875+
// FIXME: rdar://problem/19486139 (split bridged buffers for keys and values)
2876+
// We bridge keys and values unconditionally here, even if one of them
2877+
// actually is verbatim bridgeable (e.g. Dictionary<Int, AnyObject>).
2878+
// Investigate only allocating the buffer for a Set in this case.
2879+
2880+
// Create buffer for bridged data.
2881+
let bridged = _NativeDictionary<AnyObject, AnyObject>(
2882+
_exactBucketCount: native.bucketCount,
2883+
unhashable: ())
2884+
2885+
// Bridge everything.
2886+
for i in 0..<native.bucketCount {
2887+
if native.isInitializedEntry(at: i) {
2888+
let key = _bridgeAnythingToObjectiveC(native.key(at: i))
2889+
let val = _bridgeAnythingToObjectiveC(native.value(at: i))
2890+
bridged.initializeKey(key, value: val, at: i)
2891+
}
2892+
}
2893+
2894+
// Atomically put the bridged elements in place.
2895+
_initializeBridgedStorage(bridged._storage)
28442896
}
28452897

28462898
//
@@ -2859,9 +2911,24 @@ final internal class _SwiftDeferredNSDictionary<Key: Hashable, Value>
28592911
_sanityCheckFailure("don't call this designated initializer")
28602912
}
28612913

2914+
@objc(copyWithZone:)
2915+
internal func copy(with zone: _SwiftNSZone?) -> AnyObject {
2916+
// Instances of this class should be visible outside of standard library as
2917+
// having `NSDictionary` type, which is immutable.
2918+
return self
2919+
}
2920+
28622921
@objc(objectForKey:)
28632922
internal func objectFor(_ aKey: AnyObject) -> AnyObject? {
2864-
return bridgingObjectForKey(aKey)
2923+
guard let nativeKey = _conditionallyBridgeFromObjectiveC(aKey, Key.self)
2924+
else { return nil }
2925+
2926+
let (i, found) = native._find(nativeKey)
2927+
if found {
2928+
bridgeEverything()
2929+
return bridged.value(at: i.bucket)
2930+
}
2931+
return nil
28652932
}
28662933

28672934
@objc
@@ -2885,18 +2952,18 @@ final internal class _SwiftDeferredNSDictionary<Key: Hashable, Value>
28852952
if let unmanagedObjects = _UnmanagedAnyObjectArray(objects) {
28862953
// keys nonnull, objects nonnull
28872954
for position in 0..<bucketCount {
2888-
if bridgedDictionary.isInitializedEntry(at: position) {
2889-
unmanagedObjects[i] = bridgedDictionary.value(at: position)
2890-
unmanagedKeys[i] = bridgedDictionary.key(at: position)
2955+
if bridged.isInitializedEntry(at: position) {
2956+
unmanagedObjects[i] = bridged.value(at: position)
2957+
unmanagedKeys[i] = bridged.key(at: position)
28912958
i += 1
28922959
guard i < count else { break }
28932960
}
28942961
}
28952962
} else {
28962963
// keys nonnull, objects null
28972964
for position in 0..<bucketCount {
2898-
if bridgedDictionary.isInitializedEntry(at: position) {
2899-
unmanagedKeys[i] = bridgedDictionary.key(at: position)
2965+
if bridged.isInitializedEntry(at: position) {
2966+
unmanagedKeys[i] = bridged.key(at: position)
29002967
i += 1
29012968
guard i < count else { break }
29022969
}
@@ -2906,8 +2973,8 @@ final internal class _SwiftDeferredNSDictionary<Key: Hashable, Value>
29062973
if let unmanagedObjects = _UnmanagedAnyObjectArray(objects) {
29072974
// keys null, objects nonnull
29082975
for position in 0..<bucketCount {
2909-
if bridgedDictionary.isInitializedEntry(at: position) {
2910-
unmanagedObjects[i] = bridgedDictionary.value(at: position)
2976+
if bridged.isInitializedEntry(at: position) {
2977+
unmanagedObjects[i] = bridged.value(at: position)
29112978
i += 1
29122979
guard i < count else { break }
29132980
}
@@ -2926,99 +2993,24 @@ final internal class _SwiftDeferredNSDictionary<Key: Hashable, Value>
29262993
let bucketCount = native.bucketCount
29272994
var stop: UInt8 = 0
29282995
for position in 0..<bucketCount {
2929-
if bridgedDictionary.isInitializedEntry(at: position) {
2930-
block(Unmanaged.passUnretained(bridgedDictionary.key(at: position)),
2931-
Unmanaged.passUnretained(bridgedDictionary.value(at: position)),
2996+
if bridged.isInitializedEntry(at: position) {
2997+
block(Unmanaged.passUnretained(bridged.key(at: position)),
2998+
Unmanaged.passUnretained(bridged.value(at: position)),
29322999
&stop)
29333000
}
29343001
if stop != 0 { return }
29353002
}
29363003
}
29373004

2938-
/// Returns the pointer to the stored property, which contains bridged
2939-
/// Dictionary elements.
2940-
@nonobjc
2941-
internal var _heapStorageBridgedPtr: UnsafeMutablePointer<AnyObject?> {
2942-
return _getUnsafePointerToStoredProperties(self).assumingMemoryBound(
2943-
to: Optional<AnyObject>.self)
2944-
}
2945-
2946-
/// The buffer for bridged Dictionary elements, if present.
2947-
@nonobjc
2948-
internal var _bridgedStorage: _RawNativeDictionaryStorage? {
2949-
get {
2950-
if let ref = _stdlib_atomicLoadARCRef(object: _heapStorageBridgedPtr) {
2951-
return unsafeDowncast(ref, to: _RawNativeDictionaryStorage.self)
2952-
}
2953-
return nil
2954-
}
2955-
}
2956-
2957-
/// Attach a buffer for bridged Dictionary elements.
2958-
@nonobjc
2959-
internal func _initializeHeapStorageBridged(_ newStorage: AnyObject) {
2960-
_stdlib_atomicInitializeARCRef(
2961-
object: _heapStorageBridgedPtr, desired: newStorage)
2962-
}
2963-
2964-
/// Returns the bridged Dictionary values.
2965-
internal var bridgedDictionary: _NativeDictionary<AnyObject, AnyObject> {
2966-
return _NativeDictionary(_storage: _bridgedStorage!)
2967-
}
2968-
2969-
@nonobjc
2970-
internal func bridgeEverything() {
2971-
if _fastPath(_bridgedStorage != nil) {
2972-
return
2973-
}
2974-
2975-
// FIXME: rdar://problem/19486139 (split bridged buffers for keys and values)
2976-
// We bridge keys and values unconditionally here, even if one of them
2977-
// actually is verbatim bridgeable (e.g. Dictionary<Int, AnyObject>).
2978-
// Investigate only allocating the buffer for a Set in this case.
2979-
2980-
// Create buffer for bridged data.
2981-
let bridged = _NativeDictionary<AnyObject, AnyObject>(
2982-
_exactBucketCount: native.bucketCount,
2983-
unhashable: ())
2984-
2985-
// Bridge everything.
2986-
for i in 0..<native.bucketCount {
2987-
if native.isInitializedEntry(at: i) {
2988-
let key = _bridgeAnythingToObjectiveC(native.key(at: i))
2989-
let val = _bridgeAnythingToObjectiveC(native.value(at: i))
2990-
bridged.initializeKey(key, value: val, at: i)
2991-
}
2992-
}
2993-
2994-
// Atomically put the bridged elements in place.
2995-
_initializeHeapStorageBridged(bridged._storage)
2996-
}
2997-
29983005
@objc
29993006
internal var count: Int {
30003007
return native.count
30013008
}
30023009

3003-
@nonobjc
3004-
internal func bridgingObjectForKey(_ aKey: AnyObject)
3005-
-> AnyObject? {
3006-
guard let nativeKey = _conditionallyBridgeFromObjectiveC(aKey, Key.self)
3007-
else { return nil }
3008-
3009-
let (i, found) = native._find(
3010-
nativeKey, startBucket: native._bucket(nativeKey))
3011-
if found {
3012-
bridgeEverything()
3013-
return bridgedDictionary.value(at: i.bucket)
3014-
}
3015-
return nil
3016-
}
3017-
30183010
@objc
30193011
internal func enumerator() -> _NSEnumerator {
30203012
bridgeEverything()
3021-
return _SwiftDictionaryNSEnumerator<AnyObject, AnyObject>(bridgedDictionary)
3013+
return _SwiftDictionaryNSEnumerator<AnyObject, AnyObject>(bridged)
30223014
}
30233015

30243016
@objc(countByEnumeratingWithState:objects:count:)
@@ -3058,7 +3050,7 @@ final internal class _SwiftDeferredNSDictionary<Key: Hashable, Value>
30583050
break
30593051
}
30603052

3061-
let bridgedKey = bridgedDictionary.key(at: currIndex.bucket)
3053+
let bridgedKey = bridged.key(at: currIndex.bucket)
30623054
unmanagedObjects[i] = bridgedKey
30633055
stored += 1
30643056
native.formIndex(after: &currIndex)

0 commit comments

Comments
 (0)