Skip to content

Commit b1d2d1a

Browse files
authored
Merge pull request #5153 from eeckstein/managedbuffer
stdlib: Use new built-ins for tail-allocated arrays in ManagedBuffer
2 parents 370697f + 0aa023a commit b1d2d1a

File tree

1 file changed

+29
-34
lines changed

1 file changed

+29
-34
lines changed

stdlib/public/core/ManagedBuffer.swift

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,17 @@ open class ManagedBuffer<Header, Element> {
3434
ManagedBuffer<Header, Element>) throws -> Header
3535
) rethrows -> ManagedBuffer<Header, Element> {
3636

37-
let p = try ManagedBufferPointer<Header, Element>(
38-
bufferClass: self,
39-
minimumCapacity: minimumCapacity,
40-
makingHeaderWith: { buffer, _ in
41-
try factory(
42-
unsafeDowncast(buffer, to: ManagedBuffer<Header, Element>.self))
43-
})
44-
45-
return unsafeDowncast(p.buffer, to: ManagedBuffer<Header, Element>.self)
46-
}
37+
let p = Builtin.allocWithTailElems_1(
38+
self,
39+
minimumCapacity._builtinWordValue, Element.self)
4740

48-
/// Destroy the stored Header.
49-
deinit {
50-
ManagedBufferPointer(self).withUnsafeMutablePointerToHeader {
51-
_ = $0.deinitialize()
52-
}
41+
let initHeaderVal = try factory(p)
42+
p.headerAddress.initialize(to: initHeaderVal)
43+
// The _fixLifetime is not really needed, because p is used afterwards.
44+
// But let's be conservative and fix the lifetime after we use the
45+
// headerAddress.
46+
_fixLifetime(p)
47+
return p
5348
}
5449

5550
/// The actual number of elements that can be stored in this object.
@@ -58,8 +53,20 @@ open class ManagedBuffer<Header, Element> {
5853
/// idea to store this information in the "header" area when
5954
/// an instance is created.
6055
public final var capacity: Int {
61-
let p = ManagedBufferPointer<Header, Element>(self)
62-
return p.capacity
56+
let storageAddr = UnsafeMutableRawPointer(Builtin.bridgeToRawPointer(self))
57+
let endAddr = storageAddr + _swift_stdlib_malloc_size(storageAddr)
58+
let realCapacity = endAddr.assumingMemoryBound(to: Element.self) -
59+
firstElementAddress
60+
return realCapacity
61+
}
62+
63+
internal final var firstElementAddress: UnsafeMutablePointer<Element> {
64+
return UnsafeMutablePointer(Builtin.projectTailElems(self,
65+
Element.self))
66+
}
67+
68+
internal final var headerAddress: UnsafeMutablePointer<Header> {
69+
return UnsafeMutablePointer<Header>(Builtin.addressof(&header))
6370
}
6471

6572
/// Call `body` with an `UnsafeMutablePointer` to the stored
@@ -92,7 +99,8 @@ open class ManagedBuffer<Header, Element> {
9299
public final func withUnsafeMutablePointers<R>(
93100
_ body: (UnsafeMutablePointer<Header>, UnsafeMutablePointer<Element>) throws -> R
94101
) rethrows -> R {
95-
return try ManagedBufferPointer(self).withUnsafeMutablePointers(body)
102+
defer { _fixLifetime(self) }
103+
return try body(headerAddress, firstElementAddress)
96104
}
97105

98106
/// The stored `Header` instance.
@@ -101,20 +109,7 @@ open class ManagedBuffer<Header, Element> {
101109
/// `ManagedBuffer.create`'s call to initialize, `ManagedBuffer`'s
102110
/// `header` property is as-yet uninitialized, and therefore
103111
/// reading the `header` property during `ManagedBuffer.create` is undefined.
104-
public final var header: Header {
105-
addressWithNativeOwner {
106-
return (
107-
ManagedBufferPointer(self).withUnsafeMutablePointerToHeader {
108-
UnsafePointer($0)
109-
},
110-
Builtin.castToNativeObject(self))
111-
}
112-
mutableAddressWithNativeOwner {
113-
return (
114-
ManagedBufferPointer(self).withUnsafeMutablePointerToHeader { $0 },
115-
Builtin.castToNativeObject(self))
116-
}
117-
}
112+
public final var header: Header
118113

119114
//===--- internal/private API -------------------------------------------===//
120115

@@ -354,7 +349,7 @@ public struct ManagedBufferPointer<Header, Element> : Equatable {
354349
_debugPrecondition(
355350
_class_getInstancePositiveExtentSize(bufferClass) == MemoryLayout<_HeapObject>.size
356351
|| (
357-
!creating
352+
(!creating || bufferClass is ManagedBuffer<Header, Element>.Type)
358353
&& _class_getInstancePositiveExtentSize(bufferClass)
359354
== _headerOffset + MemoryLayout<Header>.size),
360355
"ManagedBufferPointer buffer class has illegal stored properties"
@@ -371,7 +366,7 @@ public struct ManagedBufferPointer<Header, Element> : Equatable {
371366
_sanityCheck(
372367
_class_getInstancePositiveExtentSize(bufferClass) == MemoryLayout<_HeapObject>.size
373368
|| (
374-
!creating
369+
(!creating || bufferClass is ManagedBuffer<Header, Element>.Type)
375370
&& _class_getInstancePositiveExtentSize(bufferClass)
376371
== _headerOffset + MemoryLayout<Header>.size),
377372
"ManagedBufferPointer buffer class has illegal stored properties"

0 commit comments

Comments
 (0)