@@ -360,11 +360,7 @@ public class KeyPath<Root, Value>: PartialKeyPath<Root> {
360360 )
361361 }
362362
363- let bufferPtr = buffer. data. baseAddress. _unsafelyUnwrappedUnchecked
364- let endOfBuffer = MemoryLayout< Int> . _roundingUpToAlignment(
365- bufferPtr + buffer. data. count
366- )
367- let maxSize = endOfBuffer. load ( as: Int . self)
363+ let maxSize = buffer. maxSize
368364 let roundedMaxSize = 1 &<< ( Int . bitWidth &- maxSize. leadingZeroBitCount)
369365
370366 // 16 is the max alignment allowed on practically every platform we deploy
@@ -542,11 +538,7 @@ public class ReferenceWritableKeyPath<
542538
543539 // Project out the reference prefix.
544540
545- let bufferPtr = buffer. data. baseAddress. _unsafelyUnwrappedUnchecked
546- let endOfBuffer = MemoryLayout< Int> . _roundingUpToAlignment(
547- bufferPtr + buffer. data. count
548- )
549- let maxSize = endOfBuffer. load ( as: Int . self)
541+ let maxSize = buffer. maxSize
550542 let roundedMaxSize = 1 &<< ( Int . bitWidth &- maxSize. leadingZeroBitCount)
551543
552544 // 16 is the max alignment allowed on practically every platform we deploy
@@ -2043,6 +2035,15 @@ internal struct KeyPathBuffer {
20432035 return UnsafeMutableRawBufferPointer ( mutating: data)
20442036 }
20452037
2038+ internal var maxSize : Int {
2039+ let bufferPtr = data. baseAddress. _unsafelyUnwrappedUnchecked
2040+ let endOfBuffer = MemoryLayout< Int> . _roundingUpToAlignment(
2041+ bufferPtr + data. count
2042+ )
2043+
2044+ return endOfBuffer. load ( as: Int . self)
2045+ }
2046+
20462047 internal struct Builder {
20472048 internal var buffer : UnsafeMutableRawBufferPointer
20482049 internal init ( _ buffer: UnsafeMutableRawBufferPointer ) {
@@ -2695,11 +2696,7 @@ internal func _appendingKeyPaths<
26952696
26962697 let leafHasReferencePrefix = leafBuffer. hasReferencePrefix
26972698
2698- let rootBufferPtr = rootBuffer. data. baseAddress. _unsafelyUnwrappedUnchecked
2699- let rootEndOfBuffer = MemoryLayout< Int> . _roundingUpToAlignment(
2700- rootBufferPtr + rootBuffer. data. count
2701- )
2702- let rootMaxSize = rootEndOfBuffer. load ( as: Int . self)
2699+ let rootMaxSize = rootBuffer. maxSize
27032700
27042701 // Clone the root components into the buffer.
27052702 while true {
@@ -2728,11 +2725,7 @@ internal func _appendingKeyPaths<
27282725 }
27292726 }
27302727
2731- let leafBufferPtr = leafBuffer. data. baseAddress. _unsafelyUnwrappedUnchecked
2732- let leafEndOfBuffer = MemoryLayout< Int> . _roundingUpToAlignment(
2733- leafBufferPtr + leafBuffer. data. count
2734- )
2735- let leafMaxSize = leafEndOfBuffer. load ( as: Int . self)
2728+ let leafMaxSize = leafBuffer. maxSize
27362729
27372730 // Clone the leaf components into the buffer.
27382731 while true {
@@ -4283,9 +4276,18 @@ public func _rerootKeyPath<NewRoot>(
42834276
42844277 let newKpTy = _openExistential ( existingKpTy. rootType, do: openedRoot ( _: ) )
42854278
4279+ // Buffer header + padding (if needed)
4280+ var capacity = MemoryLayout< Int> . size
4281+
4282+ // Size of components
4283+ capacity += componentSize
4284+
4285+ // Max size at the end of the buffer
4286+ capacity = MemoryLayout< Int> . _roundingUpToAlignment( capacity)
4287+ capacity += MemoryLayout< Int> . size
4288+
42864289 return newKpTy. _create (
4287- // This is the buffer header + padding (if needed) + size of components
4288- capacityInBytes: MemoryLayout < Int > . size + componentSize
4290+ capacityInBytes: capacity
42894291 ) {
42904292 var builder = KeyPathBuffer . Builder ( $0)
42914293 let header = KeyPathBuffer . Header (
@@ -4312,6 +4314,10 @@ public func _rerootKeyPath<NewRoot>(
43124314 break
43134315 }
43144316 }
4317+
4318+ // Append the max size at the end of the existing keypath's buffer to the
4319+ // end of the new keypath's buffer.
4320+ builder. push ( existingBuffer. maxSize)
43154321 }
43164322 } as! PartialKeyPath < NewRoot >
43174323}
0 commit comments