Skip to content

Commit d98a022

Browse files
committed
[stdlib] Re-enable assertions on malloc size
Round up our malloc requests and assert that breadcrumbs are aligned and where we think they should be. This is necessary because ASAN doesn't give us pointer-rounded sizes.
1 parent adbf8da commit d98a022

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

stdlib/public/core/StringStorage.swift

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,12 +181,14 @@ fileprivate func _allocate<T: AnyObject>(
181181
) -> (T, realNumTailBytes: Int) {
182182
_internalInvariant(getSwiftClassInstanceExtents(T.self).1 == numHeaderBytes)
183183

184+
func roundUp(_ x: Int) -> Int { (x + 15) & ~15 }
185+
184186
let numBytes = numHeaderBytes + numTailBytes
185187

186188
let linearBucketThreshold = 128
187189
if _fastPath(numBytes < linearBucketThreshold) {
188190
// Allocate up to the nearest bucket of 16
189-
let realNumBytes = (numBytes+15) & ~15
191+
let realNumBytes = roundUp(numBytes)
190192
let realNumTailBytes = realNumBytes - numHeaderBytes
191193
_internalInvariant(realNumTailBytes >= numTailBytes)
192194
let object = tailAllocator(realNumTailBytes)
@@ -200,9 +202,14 @@ fileprivate func _allocate<T: AnyObject>(
200202
growTailBytes = numTailBytes
201203
}
202204

203-
let object = tailAllocator(growTailBytes)
205+
let total = roundUp(numHeaderBytes + growTailBytes)
206+
let totalTailBytes = total - numHeaderBytes
207+
208+
let object = tailAllocator(totalTailBytes)
204209
let mallocSize = _swift_stdlib_malloc_size(
205210
UnsafeRawPointer(Builtin.bridgeToRawPointer(object)))
211+
_internalInvariant(mallocSize % MemoryLayout<Int>.stride == 0)
212+
206213
let realNumTailBytes = mallocSize - numHeaderBytes
207214
_internalInvariant(realNumTailBytes >= numTailBytes)
208215
return (object, realNumTailBytes)
@@ -447,6 +454,8 @@ extension __StringStorage {
447454
// required nul-terminator.
448455
//
449456
// NOTE: Callers who wish to mutate this storage should enfore nul-termination
457+
//
458+
// TODO: Refactoring or removing. Excluding the last byte is awkward.
450459
@inline(__always)
451460
private var unusedStorage: UnsafeMutableBufferPointer<UInt8> {
452461
UnsafeMutableBufferPointer(
@@ -485,8 +494,8 @@ extension __StringStorage {
485494

486495
// Check that capacity end matches our notion of unused storage, and also
487496
// checks that breadcrumbs were dutifully aligned.
488-
// _internalInvariant(UnsafeMutablePointer<UInt8>(_realCapacityEnd)
489-
// == unusedStorage.baseAddress! + (unusedStorage.count + 1))
497+
_internalInvariant(UnsafeMutablePointer<UInt8>(_realCapacityEnd)
498+
== unusedStorage.baseAddress! + (unusedStorage.count + 1))
490499
}
491500
#endif // INTERNAL_CHECKS_ENABLED
492501
}

0 commit comments

Comments
 (0)