Skip to content

Commit ba4e6e5

Browse files
committed
---
yaml --- r: 348667 b: refs/heads/master c: d30d333 h: refs/heads/master i: 348665: ad64827 348663: a8ee905
1 parent 4b6d0ce commit ba4e6e5

File tree

6 files changed

+113
-103
lines changed

6 files changed

+113
-103
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 170a84c5bdc2322395c8746b70c34ffeb16c021d
2+
refs/heads/master: d30d3334dbc87aeadbf88be929ad187fc7be76d7
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/stdlib/private/OSLog/OSLog.swift

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,18 @@ internal func osLog(
7373

7474
let arguments = message.interpolation.arguments
7575

76-
// Ideally, we could stack allocate the buffer as it is local to this
77-
// function and also its size is a compile-time constant.
78-
let bufferMemory =
79-
UnsafeMutablePointer<UInt8>.allocate(capacity: bufferSize)
80-
var builder = OSLogByteBufferBuilder(bufferMemory)
76+
// Allocate a byte buffer to store the arguments. The buffer could be stack
77+
// allocated as it is local to this function and also its size is a
78+
// compile-time constant.
79+
let bufferMemory = UnsafeMutablePointer<UInt8>.allocate(capacity: bufferSize)
80+
// Array of references to auxiliary storage created during serialization of
81+
// strings. This array can be stack allocated.
82+
var stringStorageObjects: [AnyObject] = []
8183

82-
builder.serialize(preamble)
83-
builder.serialize(argumentCount)
84-
arguments.serialize(into: &builder)
84+
var currentBufferPosition = bufferMemory
85+
serialize(preamble, at: &currentBufferPosition)
86+
serialize(argumentCount, at: &currentBufferPosition)
87+
arguments.serializeAt(&currentBufferPosition, using: &stringStorageObjects)
8588

8689
___os_log_impl(UnsafeMutableRawPointer(mutating: #dsohandle),
8790
logObject,
@@ -90,7 +93,9 @@ internal func osLog(
9093
bufferMemory,
9194
UInt32(bufferSize))
9295

93-
builder.destroy()
96+
// The following operation extends the lifetime of stringStorageObjects
97+
// and also of the objects stored in it till this point.
98+
stringStorageObjects.removeAll()
9499
bufferMemory.deallocate()
95100
}
96101

@@ -118,15 +123,19 @@ func _checkFormatStringAndBuffer(
118123

119124
// Code that will execute at runtime.
120125
let bufferMemory = UnsafeMutablePointer<UInt8>.allocate(capacity: bufferSize)
121-
var builder = OSLogByteBufferBuilder(bufferMemory)
126+
var stringStorageObjects: [AnyObject] = []
122127

123-
builder.serialize(preamble)
124-
builder.serialize(argumentCount)
125-
message.interpolation.arguments.serialize(into: &builder)
128+
var currentBufferPosition = bufferMemory
129+
serialize(preamble, at: &currentBufferPosition)
130+
serialize(argumentCount, at: &currentBufferPosition)
131+
message.interpolation.arguments.serializeAt(
132+
&currentBufferPosition,
133+
using: &stringStorageObjects)
126134

127135
assertion(
128136
formatString,
129137
UnsafeBufferPointer(start: UnsafePointer(bufferMemory), count: bufferSize))
130138

139+
stringStorageObjects.removeAll()
131140
bufferMemory.deallocate()
132141
}

trunk/stdlib/private/OSLog/OSLogIntegerTypes.swift

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,9 @@ extension OSLogArguments {
143143
internal mutating func append<T>(
144144
_ value: @escaping () -> T
145145
) where T: FixedWidthInteger {
146-
argumentClosures!.append({ $0.serialize(value()) })
146+
argumentClosures.append({ (position, _) in
147+
serialize(value(), at: &position)
148+
})
147149
}
148150
}
149151

@@ -159,15 +161,17 @@ internal func sizeForEncoding<T>(
159161
return type.bitWidth &>> logBitsPerByte
160162
}
161163

162-
extension OSLogByteBufferBuilder {
163-
/// Serialize an integer at the buffer location pointed to by `position`.
164-
@usableFromInline
165-
internal mutating func serialize<T>(
166-
_ value: T
167-
) where T : FixedWidthInteger {
168-
let byteCount = sizeForEncoding(T.self)
169-
let dest = UnsafeMutableRawBufferPointer(start: position, count: byteCount)
170-
withUnsafeBytes(of: value) { dest.copyMemory(from: $0) }
171-
position += byteCount
172-
}
164+
/// Serialize an integer at the buffer location that `position` points to and
165+
/// increment `position` by the byte size of `T`.
166+
@usableFromInline
167+
@_alwaysEmitIntoClient
168+
internal func serialize<T>(
169+
_ value: T,
170+
at bufferPosition: inout ByteBufferPointer
171+
) where T : FixedWidthInteger {
172+
let byteCount = sizeForEncoding(T.self)
173+
let dest =
174+
UnsafeMutableRawBufferPointer(start: bufferPosition, count: byteCount)
175+
withUnsafeBytes(of: value) { dest.copyMemory(from: $0) }
176+
bufferPosition += byteCount
173177
}

trunk/stdlib/private/OSLog/OSLogMessage.swift

Lines changed: 35 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,8 @@ public struct OSLogMessage :
320320
}
321321
}
322322

323+
public typealias ByteBufferPointer = UnsafeMutablePointer<UInt8>
324+
public typealias StorageObjects = [AnyObject]
323325

324326
/// A representation of a sequence of arguments and headers (of possibly
325327
/// different types) that have to be serialized to a byte buffer. The arguments
@@ -330,73 +332,64 @@ public struct OSLogMessage :
330332
@usableFromInline
331333
internal struct OSLogArguments {
332334
/// An array of closures that captures arguments of possibly different types.
335+
/// Each closure accepts a pointer into a byte buffer and serializes the
336+
/// captured arguments at the pointed location. The closures also accept an
337+
/// array of AnyObject to store references to auxiliary storage created during
338+
/// serialization.
333339
@usableFromInline
334-
internal var argumentClosures: [(inout OSLogByteBufferBuilder) -> ()]?
340+
internal var argumentClosures: [(inout ByteBufferPointer,
341+
inout StorageObjects) -> ()]
335342

336343
/// This function must be constant evaluable.
337344
@inlinable
338345
@_semantics("constant_evaluable")
339346
@_optimize(none)
340347
internal init() {
341-
argumentClosures = nil
348+
argumentClosures = []
342349
}
343350

344351
@usableFromInline
345352
internal init(capacity: Int) {
346353
argumentClosures = []
347-
argumentClosures!.reserveCapacity(capacity)
354+
argumentClosures.reserveCapacity(capacity)
348355
}
349356

350357
/// Append a byte-sized header, constructed by
351358
/// `OSLogMessage.appendInterpolation`, to the tracked array of closures.
352359
@usableFromInline
353360
internal mutating func append(_ header: UInt8) {
354-
argumentClosures!.append({ $0.serialize(header) })
361+
argumentClosures.append({ (position, _) in
362+
serialize(header, at: &position)
363+
})
355364
}
356365

357366
/// `append` for other types must be implemented by extensions.
358367

368+
/// Serialize the arguments tracked by self in a byte buffer.
369+
/// - Parameters:
370+
/// - bufferPosition: the pointer to a location within a byte buffer where
371+
/// the argument must be serialized. This will be incremented by the number
372+
/// of bytes used up to serialize the arguments.
373+
/// - storageObjects: An array to store references to objects representing
374+
/// auxiliary storage created during serialization. This is only used while
375+
/// serializing strings.
359376
@usableFromInline
360-
internal func serialize(into bufferBuilder: inout OSLogByteBufferBuilder) {
361-
argumentClosures?.forEach { $0(&bufferBuilder) }
377+
internal func serializeAt(
378+
_ bufferPosition: inout ByteBufferPointer,
379+
using storageObjects: inout StorageObjects
380+
) {
381+
argumentClosures.forEach { $0(&bufferPosition, &storageObjects) }
362382
}
363383
}
364384

365-
/// A struct that manages serialization of instances of specific types to a
366-
/// byte buffer. The byte buffer is provided as an argument to the initializer
367-
/// so that its lifetime can be managed by the caller.
385+
/// Serialize a UInt8 value at the buffer location pointed to by `bufferPosition`,
386+
/// and increment the `bufferPosition` with the byte size of the serialized value.
368387
@usableFromInline
369-
internal struct OSLogByteBufferBuilder {
370-
internal var position: UnsafeMutablePointer<UInt8>
371-
372-
/// Objects denoting storage created by the serialize methods. Such storage
373-
/// is created while serializing strings as os_log requires stable pointers to
374-
/// Swift strings, which may require copying them to a in-memory buffer.
375-
/// The lifetime of this auxiliary storage is same as the lifetime of `self`.
376-
internal var auxiliaryStorage: [AnyObject]
377-
378-
/// Initializer that accepts a pointer to a preexisting buffer.
379-
/// - Parameter bufferStart: the starting pointer to a byte buffer
380-
/// that must contain the serialized bytes.
381-
@usableFromInline
382-
internal init(_ bufferStart: UnsafeMutablePointer<UInt8>) {
383-
position = bufferStart
384-
auxiliaryStorage = []
385-
}
386-
387-
/// Serialize a UInt8 value at the buffer location pointed to by `position`.
388-
@usableFromInline
389-
internal mutating func serialize(_ value: UInt8) {
390-
position[0] = value
391-
position += 1
392-
}
393-
394-
/// `serialize` for other other types must be implemented by extensions.
395-
396-
/// This function exists so that clients can control the lifetime of a stack-
397-
/// allocated instance of OSLogByteBufferBuilder.
398-
@usableFromInline
399-
internal mutating func destroy() {
400-
auxiliaryStorage = []
401-
}
388+
@_alwaysEmitIntoClient
389+
internal func serialize(
390+
_ value: UInt8,
391+
at bufferPosition: inout ByteBufferPointer)
392+
{
393+
bufferPosition[0] = value
394+
bufferPosition += 1
402395
}

trunk/stdlib/private/OSLog/OSLogStringTypes.swift

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ extension OSLogArguments {
8989
/// by this instance.
9090
@usableFromInline
9191
internal mutating func append(_ value: @escaping () -> String) {
92-
argumentClosures!.append({ $0.serialize(value()) })
92+
argumentClosures.append({ serialize(value(), at: &$0, using: &$1) })
9393
}
9494
}
9595

@@ -107,24 +107,28 @@ internal func sizeForEncoding() -> Int {
107107
return Int.bitWidth &>> logBitsPerByte
108108
}
109109

110-
extension OSLogByteBufferBuilder {
111-
/// Serialize a string at the buffer location pointed to by `position`.
112-
/// Record any auxiliary storage created for getting a stable pointer to the
113-
/// parameter string in the `self.auxiliaryStorage` property, so that the
114-
/// storage is alive for the lifetime of `self`.
115-
@usableFromInline
116-
internal mutating func serialize(_ stringValue: String) {
117-
let (optionalStorage, bytePointer): (AnyObject?, UnsafeRawPointer) =
118-
_convertConstStringToUTF8PointerArgument(
119-
stringValue)
120-
121-
if let storage = optionalStorage {
122-
auxiliaryStorage.append(storage)
123-
}
110+
/// Serialize a stable pointer to the string `stringValue` at the buffer location
111+
/// pointed by `bufferPosition`. When necessary, this function would copy the
112+
/// string contents to a storage with a stable pointer. If that happens, a reference
113+
/// to the storage will be added to `storageObjects`.
114+
@usableFromInline
115+
@_alwaysEmitIntoClient
116+
internal func serialize(
117+
_ stringValue: String,
118+
at bufferPosition: inout ByteBufferPointer,
119+
using storageObjects: inout StorageObjects
120+
) {
121+
let (optionalStorage, bytePointer): (AnyObject?, UnsafeRawPointer) =
122+
_convertConstStringToUTF8PointerArgument(
123+
stringValue)
124124

125-
let byteCount = sizeForEncoding()
126-
let dest = UnsafeMutableRawBufferPointer(start: position, count: byteCount)
127-
withUnsafeBytes(of: bytePointer) { dest.copyMemory(from: $0) }
128-
position += byteCount
125+
if let storage = optionalStorage {
126+
storageObjects.append(storage)
129127
}
128+
129+
let byteCount = sizeForEncoding()
130+
let dest =
131+
UnsafeMutableRawBufferPointer(start: bufferPosition, count: byteCount)
132+
withUnsafeBytes(of: bytePointer) { dest.copyMemory(from: $0) }
133+
bufferPosition += byteCount
130134
}

0 commit comments

Comments
 (0)