@@ -2153,9 +2153,11 @@ extension Dictionary {
2153
2153
get {
2154
2154
return _variantBuffer.maybeGet(key) ?? defaultValue()
2155
2155
}
2156
- set(newValue) {
2157
- // FIXME(performance): this loads and discards the old value.
2158
- _variantBuffer.updateValue(newValue, forKey: key)
2156
+ mutableAddressWithNativeOwner {
2157
+ let (_, address) = _variantBuffer
2158
+ .pointerToValue(forKey: key, insertingDefault: defaultValue)
2159
+ return (address, Builtin.castToNativeObject(
2160
+ _variantBuffer.asNative._storage))
2159
2161
}
2160
2162
}
2161
2163
@@ -4865,6 +4867,17 @@ internal enum _Variant${Self}Buffer<${TypeParametersDecl}> : _HashBuffer {
4865
4867
}
4866
4868
}
4867
4869
4870
+ @_inlineable // FIXME(sil-serialize-all)
4871
+ @_versioned // FIXME(sil-serialize-all)
4872
+ internal mutating func ensureNativeBuffer() {
4873
+ #if _runtime(_ObjC)
4874
+ if _fastPath(guaranteedNative) { return }
4875
+ if case .cocoa(let cocoaBuffer) = self {
4876
+ migrateDataToNativeBuffer(cocoaBuffer)
4877
+ }
4878
+ #endif
4879
+ }
4880
+
4868
4881
#if _runtime(_ObjC)
4869
4882
@_inlineable // FIXME(sil-serialize-all)
4870
4883
@_versioned // FIXME(sil-serialize-all)
@@ -5314,6 +5327,42 @@ internal enum _Variant${Self}Buffer<${TypeParametersDecl}> : _HashBuffer {
5314
5327
#endif
5315
5328
}
5316
5329
}
5330
+
5331
+ @_inlineable // FIXME(sil-serialize-all)
5332
+ @_versioned // FIXME(sil-serialize-all)
5333
+ internal mutating func nativePointerToValue(
5334
+ forKey key: Key, insertingDefault defaultValue: () -> Value
5335
+ ) -> (inserted: Bool, pointer: UnsafeMutablePointer<Value>) {
5336
+
5337
+ var (i, found) = asNative._find(key, startBucket: asNative._bucket(key))
5338
+ if found {
5339
+ let pointer = nativePointerToValue(at: ._native(i))
5340
+ return (inserted: false, pointer: pointer)
5341
+ }
5342
+
5343
+ let minCapacity = NativeBuffer.minimumCapacity(
5344
+ minimumCount: asNative.count + 1,
5345
+ maxLoadFactorInverse: _hashContainerDefaultMaxLoadFactorInverse)
5346
+
5347
+ let (_, capacityChanged) = ensureUniqueNativeBuffer(minCapacity)
5348
+
5349
+ if capacityChanged {
5350
+ i = asNative._find(key, startBucket: asNative._bucket(key)).pos
5351
+ }
5352
+
5353
+ asNative.initializeKey(key, value: defaultValue(), at: i.offset)
5354
+ asNative.count += 1
5355
+ return (inserted: true, pointer: asNative.values + i.offset)
5356
+ }
5357
+
5358
+ @_inlineable // FIXME(sil-serialize-all)
5359
+ @_versioned // FIXME(sil-serialize-all)
5360
+ internal mutating func pointerToValue(
5361
+ forKey key: Key, insertingDefault defaultValue: () -> Value
5362
+ ) -> (inserted: Bool, pointer: UnsafeMutablePointer<Value>) {
5363
+ ensureNativeBuffer()
5364
+ return nativePointerToValue(forKey: key, insertingDefault: defaultValue)
5365
+ }
5317
5366
%end
5318
5367
5319
5368
@_inlineable // FIXME(sil-serialize-all)
@@ -5358,20 +5407,8 @@ internal enum _Variant${Self}Buffer<${TypeParametersDecl}> : _HashBuffer {
5358
5407
internal mutating func insert(
5359
5408
_ value: Value, forKey key: Key
5360
5409
) -> (inserted: Bool, memberAfterInsert: Value) {
5361
-
5362
- if _fastPath(guaranteedNative) {
5363
- return nativeInsert(value, forKey: key)
5364
- }
5365
-
5366
- switch self {
5367
- case .native:
5368
- return nativeInsert(value, forKey: key)
5369
- #if _runtime(_ObjC)
5370
- case .cocoa(let cocoaBuffer):
5371
- migrateDataToNativeBuffer(cocoaBuffer)
5372
- return nativeInsert(value, forKey: key)
5373
- #endif
5374
- }
5410
+ ensureNativeBuffer()
5411
+ return nativeInsert(value, forKey: key)
5375
5412
}
5376
5413
5377
5414
%if Self == 'Dictionary':
@@ -5475,20 +5512,8 @@ internal enum _Variant${Self}Buffer<${TypeParametersDecl}> : _HashBuffer {
5475
5512
_ keysAndValues: S,
5476
5513
uniquingKeysWith combine: (Value, Value) throws -> Value
5477
5514
) rethrows where S.Element == (Key, Value) {
5478
- if _fastPath(guaranteedNative) {
5479
- try nativeMerge(keysAndValues, uniquingKeysWith: combine)
5480
- return
5481
- }
5482
-
5483
- switch self {
5484
- case .native:
5485
- try nativeMerge(keysAndValues, uniquingKeysWith: combine)
5486
- #if _runtime(_ObjC)
5487
- case .cocoa(let cocoaStorage):
5488
- migrateDataToNativeBuffer(cocoaStorage)
5489
- try nativeMerge(keysAndValues, uniquingKeysWith: combine)
5490
- #endif
5491
- }
5515
+ ensureNativeBuffer()
5516
+ try nativeMerge(keysAndValues, uniquingKeysWith: combine)
5492
5517
}
5493
5518
5494
5519
@_inlineable // FIXME(sil-serialize-all)
0 commit comments