Skip to content

Commit 80d55a1

Browse files
committed
[stdlib] Dictionary: Override getObjects:andKeys:count:
Dictionary’s native storage classes and _SwiftDeferredNSDictionary override -[NSDictionary getObjects:andKeys:] instead of its safer replacement, -[NSDictionary getObjects:andKeys:count:]. Overriding the correct method will considerably speed up some Cocoa operations on bridged dictionaries. rdar://problem/39285882 (cherry picked from commit 6aec05a)
1 parent 1e2dc99 commit 80d55a1

File tree

2 files changed

+28
-11
lines changed

2 files changed

+28
-11
lines changed

stdlib/public/core/Dictionary.swift

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1999,8 +1999,11 @@ internal class _RawNativeDictionaryStorage
19991999
}
20002000

20012001
@inlinable // FIXME(sil-serialize-all)
2002-
internal func getObjects(_ objects: UnsafeMutablePointer<AnyObject>?,
2003-
andKeys keys: UnsafeMutablePointer<AnyObject>?) {
2002+
@objc(getObjects:andKeys:count:)
2003+
internal func getObjects(
2004+
_ objects: UnsafeMutablePointer<AnyObject>?,
2005+
andKeys keys: UnsafeMutablePointer<AnyObject>?,
2006+
count: Int) {
20042007
// Do nothing, we're empty
20052008
}
20062009
#endif
@@ -2168,28 +2171,33 @@ final internal class _HashableTypedNativeDictionaryStorage<Key: Hashable, Value>
21682171

21692172
// We also override the following methods for efficiency.
21702173
@inlinable // FIXME(sil-serialize-all)
2171-
@objc
2172-
override func getObjects(_ objects: UnsafeMutablePointer<AnyObject>?,
2173-
andKeys keys: UnsafeMutablePointer<AnyObject>?) {
2174+
@objc(getObjects:andKeys:count:)
2175+
override func getObjects(
2176+
_ objects: UnsafeMutablePointer<AnyObject>?,
2177+
andKeys keys: UnsafeMutablePointer<AnyObject>?,
2178+
count: Int) {
21742179
// The user is expected to provide a storage of the correct size
21752180
if let unmanagedKeys = _UnmanagedAnyObjectArray(keys) {
21762181
if let unmanagedObjects = _UnmanagedAnyObjectArray(objects) {
21772182
// keys nonnull, objects nonnull
21782183
for (offset: i, element: (key: key, value: val)) in full.enumerated() {
21792184
unmanagedObjects[i] = _bridgeAnythingToObjectiveC(val)
21802185
unmanagedKeys[i] = _bridgeAnythingToObjectiveC(key)
2186+
guard i < count else { break }
21812187
}
21822188
} else {
21832189
// keys nonnull, objects null
21842190
for (offset: i, element: (key: key, value: _)) in full.enumerated() {
21852191
unmanagedKeys[i] = _bridgeAnythingToObjectiveC(key)
2192+
guard i < count else { break }
21862193
}
21872194
}
21882195
} else {
21892196
if let unmanagedObjects = _UnmanagedAnyObjectArray(objects) {
21902197
// keys null, objects nonnull
21912198
for (offset: i, element: (key: _, value: val)) in full.enumerated() {
21922199
unmanagedObjects[i] = _bridgeAnythingToObjectiveC(val)
2200+
guard i < count else { break }
21932201
}
21942202
} else {
21952203
// do nothing, both are null
@@ -2862,12 +2870,13 @@ final internal class _SwiftDeferredNSDictionary<Key: Hashable, Value>
28622870
}
28632871

28642872
@inlinable // FIXME(sil-serialize-all)
2865-
@objc
2873+
@objc(getObjects:andKeys:count:)
28662874
internal func getObjects(
28672875
_ objects: UnsafeMutablePointer<AnyObject>?,
2868-
andKeys keys: UnsafeMutablePointer<AnyObject>?
2876+
andKeys keys: UnsafeMutablePointer<AnyObject>?,
2877+
count: Int
28692878
) {
2870-
bridgedAllKeysAndValues(objects, keys)
2879+
bridgedAllKeysAndValues(objects, keys, count)
28712880
}
28722881

28732882
@inlinable // FIXME(sil-serialize-all)
@@ -2957,7 +2966,8 @@ final internal class _SwiftDeferredNSDictionary<Key: Hashable, Value>
29572966
@nonobjc
29582967
internal func bridgedAllKeysAndValues(
29592968
_ objects: UnsafeMutablePointer<AnyObject>?,
2960-
_ keys: UnsafeMutablePointer<AnyObject>?
2969+
_ keys: UnsafeMutablePointer<AnyObject>?,
2970+
_ count: Int
29612971
) {
29622972
bridgeEverything()
29632973
// The user is expected to provide a storage of the correct size
@@ -2972,6 +2982,7 @@ final internal class _SwiftDeferredNSDictionary<Key: Hashable, Value>
29722982
unmanagedObjects[i] = bridgedBuffer.value(at: position)
29732983
unmanagedKeys[i] = bridgedBuffer.key(at: position)
29742984
i += 1
2985+
guard i < count else { break }
29752986
}
29762987
}
29772988
} else {
@@ -2980,6 +2991,7 @@ final internal class _SwiftDeferredNSDictionary<Key: Hashable, Value>
29802991
if bridgedBuffer.isInitializedEntry(at: position) {
29812992
unmanagedKeys[i] = bridgedBuffer.key(at: position)
29822993
i += 1
2994+
guard i < count else { break }
29832995
}
29842996
}
29852997
}
@@ -2990,6 +3002,7 @@ final internal class _SwiftDeferredNSDictionary<Key: Hashable, Value>
29903002
if bridgedBuffer.isInitializedEntry(at: position) {
29913003
unmanagedObjects[i] = bridgedBuffer.value(at: position)
29923004
i += 1
3005+
guard i < count else { break }
29933006
}
29943007
}
29953008
} else {

stdlib/public/core/ShadowProtocols.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,12 @@ public protocol _NSDictionaryCore :
103103
@objc(copyWithZone:)
104104
func copy(with zone: _SwiftNSZone?) -> AnyObject
105105

106-
func getObjects(_ objects: UnsafeMutablePointer<AnyObject>?,
107-
andKeys keys: UnsafeMutablePointer<AnyObject>?)
106+
@objc(getObjects:andKeys:count:)
107+
func getObjects(
108+
_ objects: UnsafeMutablePointer<AnyObject>?,
109+
andKeys keys: UnsafeMutablePointer<AnyObject>?,
110+
count: Int
111+
)
108112

109113
@objc(countByEnumeratingWithState:objects:count:)
110114
func countByEnumerating(

0 commit comments

Comments
 (0)