Skip to content

Commit f7d110d

Browse files
committed
stdlib: Dictionary: abstract away some of the address calculations in _roundUp()
1 parent 78b60fb commit f7d110d

File tree

3 files changed

+50
-29
lines changed

3 files changed

+50
-29
lines changed

stdlib/public/core/Builtin.swift

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,45 @@ public func strideofValue<T>(_:T) -> Int {
6161
return strideof(T.self)
6262
}
6363

64+
// This function is the implementation of the `_roundUp` overload set. It is
65+
// marked `@inline(__always)` to make primary `_roundUp` entry points seem
66+
// cheap enough for the inliner.
6467
@_versioned
65-
internal func _roundUp(_ offset: Int, toAlignment alignment: Int) -> Int {
66-
_sanityCheck(offset >= 0)
68+
@inline(__always)
69+
internal func _roundUpImpl(_ offset: UInt, toAlignment alignment: Int) -> UInt {
6770
_sanityCheck(alignment > 0)
6871
_sanityCheck(_isPowerOf2(alignment))
6972
// Note, given that offset is >= 0, and alignment > 0, we don't
7073
// need to underflow check the -1, as it can never underflow.
71-
let x = (offset + alignment &- 1)
74+
let x = offset + UInt(bitPattern: alignment) &- 1
7275
// Note, as alignment is a power of 2, we'll use masking to efficiently
7376
// get the aligned value
74-
return x & ~(alignment &- 1)
77+
return x & ~(UInt(bitPattern: alignment) &- 1)
78+
}
79+
80+
@_versioned
81+
internal func _roundUp(_ offset: UInt, toAlignment alignment: Int) -> UInt {
82+
return _roundUpImpl(offset, toAlignment: alignment)
83+
}
84+
85+
@_versioned
86+
internal func _roundUp(_ offset: Int, toAlignment alignment: Int) -> Int {
87+
_sanityCheck(offset >= 0)
88+
return Int(_roundUpImpl(UInt(bitPattern: offset), toAlignment: alignment))
89+
}
90+
91+
@_versioned
92+
internal func _roundUp<T, DestinationType>(
93+
_ pointer: UnsafeMutablePointer<T>,
94+
toAlignmentOf destinationType: DestinationType.Type
95+
) -> UnsafeMutablePointer<DestinationType> {
96+
// Note: unsafe unwrap is safe because this operation can only increase the
97+
// value, and can not produce a null pointer.
98+
return UnsafeMutablePointer<DestinationType>(
99+
bitPattern: _roundUpImpl(
100+
UInt(bitPattern: pointer),
101+
toAlignment: alignof(DestinationType))
102+
).unsafelyUnwrapped
75103
}
76104

77105
/// Returns a tri-state of 0 = no, 1 = yes, 2 = maybe.

stdlib/public/core/FixedPoint.swift.gyb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,14 @@ internal func _unsafeMinus(_ lhs: Int, _ rhs: Int) -> Int {
701701
#endif
702702
}
703703

704+
internal func _unsafeMultiply(_ lhs: Int, _ rhs: Int) -> Int {
705+
#if INTERNAL_CHECKS_ENABLED
706+
return lhs * rhs
707+
#else
708+
return lhs &* rhs
709+
#endif
710+
}
711+
704712
@available(*, unavailable, renamed: "Integer")
705713
public typealias IntegerType = Integer
706714

stdlib/public/core/HashedCollections.swift.gyb

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2605,38 +2605,23 @@ final internal class _Native${Self}StorageImpl<${TypeParameters}> :
26052605

26062606
internal
26072607
var _initializedHashtableEntriesBitMapStorage: UnsafeMutablePointer<UInt> {
2608-
get {
2609-
let start = UInt(Builtin.ptrtoint_Word(buffer._elementPointer._rawValue))
2610-
let alignment = UInt(alignof(UInt))
2611-
let alignMask = alignment &- UInt(1)
2612-
return UnsafeMutablePointer<UInt>(
2613-
bitPattern:(start &+ alignMask) & ~alignMask)!
2614-
}
2608+
return _roundUp(buffer._elementPointer, toAlignmentOf: UInt.self)
26152609
}
26162610

26172611
internal var _keys: UnsafeMutablePointer<Key> {
2618-
get {
2619-
let start =
2620-
UInt(Builtin.ptrtoint_Word(
2621-
_initializedHashtableEntriesBitMapStorage._rawValue)) &+
2622-
UInt(_BitMap.wordsFor(_capacity)) &* UInt(strideof(UInt))
2623-
let alignment = UInt(alignof(Key))
2624-
let alignMask = alignment &- UInt(1)
2625-
return UnsafeMutablePointer<Key>(
2626-
bitPattern:(start &+ alignMask) & ~alignMask)!
2627-
}
2612+
let bitMapSizeInBytes =
2613+
_unsafeMultiply(_BitMap.wordsFor(_capacity), strideof(UInt))
2614+
let start =
2615+
UnsafeMutablePointer<UInt8>(_initializedHashtableEntriesBitMapStorage)
2616+
+ bitMapSizeInBytes
2617+
return _roundUp(start, toAlignmentOf: Key.self)
26282618
}
26292619

26302620
%if Self == 'Dictionary':
26312621
internal var _values: UnsafeMutablePointer<Value> {
2632-
get {
2633-
let start = UInt(Builtin.ptrtoint_Word(_keys._rawValue)) &+
2634-
UInt(_capacity) &* UInt(strideof(Key.self))
2635-
let alignment = UInt(alignof(Value))
2636-
let alignMask = alignment &- UInt(1)
2637-
return UnsafeMutablePointer<Value>(
2638-
bitPattern:(start &+ alignMask) & ~alignMask)!
2639-
}
2622+
let keysSizeInBytes = _unsafeMultiply(_capacity, strideof(Key.self))
2623+
let start = UnsafeMutablePointer<UInt8>(_keys) + keysSizeInBytes
2624+
return _roundUp(start, toAlignmentOf: Value.self)
26402625
}
26412626
%end
26422627

0 commit comments

Comments
 (0)