@@ -81,6 +81,7 @@ public final class _DataStorage {
8181 public var _length : Int
8282 public var _capacity : Int
8383 public var _needToZero : Bool
84+ public var _deallocator : ( ( UnsafeMutableRawPointer , Int ) -> Void ) ? = nil
8485 public var _backing : Backing = . swift
8586
8687 public var bytes : UnsafeRawPointer ? {
@@ -152,11 +153,14 @@ public final class _DataStorage {
152153
153154 public func _freeBytes( ) {
154155 if let bytes = _bytes {
155- free ( bytes)
156+ if let dealloc = _deallocator {
157+ dealloc ( bytes, length)
158+ } else {
159+ free ( bytes)
160+ }
156161 }
157162 }
158163
159-
160164 public func enumerateBytes( _ block: ( _ buffer: UnsafeBufferPointer < UInt8 > , _ byteIndex: Data . Index , _ stop: inout Bool ) -> Void ) {
161165 var stop : Bool = false
162166 switch _backing {
@@ -222,7 +226,16 @@ public final class _DataStorage {
222226 /* Where calloc/memmove/free fails, realloc might succeed */
223227 if newBytes == nil {
224228 allocateCleared = false
225- newBytes = realloc ( _bytes!, newCapacity)
229+ if _deallocator != nil {
230+ newBytes = _DataStorage. allocate ( newCapacity, true )
231+ if newBytes != nil {
232+ _DataStorage. move ( newBytes!, _bytes!, origLength)
233+ _freeBytes ( )
234+ _deallocator = nil
235+ }
236+ } else {
237+ newBytes = realloc ( _bytes!, newCapacity)
238+ }
226239 }
227240
228241 /* Try again with minimum length */
@@ -571,16 +584,46 @@ public final class _DataStorage {
571584 }
572585
573586
574- public convenience init( bytes: UnsafeMutableRawPointer? , length: Int, copy: Bool, deallocator: ( ( UnsafeMutableRawPointer, Int) - > Void) ? ) {
587+ public init( bytes: UnsafeMutableRawPointer? , length: Int, copy: Bool, deallocator: ( ( UnsafeMutableRawPointer, Int) - > Void) ? ) {
575588 precondition ( length < _DataStorage. maxSize)
576- self . init ( capacity: length)
577- _DataStorage. move ( _bytes!, bytes, length)
578- if length > 0 {
589+ if length == 0 {
590+ _capacity = 0
591+ _length = 0
592+ _needToZero = false
593+ _bytes = nil
594+ if let dealloc = deallocator,
595+ let bytes_ = bytes {
596+ dealloc ( bytes_, length)
597+ }
598+ } else if !copy {
599+ _capacity = length
600+ _length = length
601+ _needToZero = false
602+ _bytes = bytes
603+ _deallocator = deallocator
604+ } else if _DataStorage. vmOpsThreshold <= length {
605+ _capacity = length
606+ _length = length
607+ _needToZero = true
608+ _bytes = _DataStorage. allocate ( length, false ) !
609+ _DataStorage. move ( _bytes!, bytes, length)
610+ if let dealloc = deallocator {
611+ dealloc ( bytes!, length)
612+ }
613+ } else {
614+ var capacity = length
615+ if ( _DataStorage. vmOpsThreshold <= capacity) {
616+ capacity = NSRoundUpToMultipleOfPageSize ( capacity)
617+ }
618+ _length = length
619+ _bytes = _DataStorage. allocate ( capacity, false ) !
620+ _capacity = capacity
621+ _needToZero = true
622+ _DataStorage. move ( _bytes!, bytes, length)
579623 if let dealloc = deallocator {
580624 dealloc ( bytes!, length)
581625 }
582626 }
583- _length = length
584627 }
585628
586629 public init( immutableReference: NSData) {
0 commit comments