Skip to content

Commit

Permalink
Support for 32-bit platforms (with AnyObject? for now) (swiftlang#15)
Browse files Browse the repository at this point in the history
* Restore support for 32-bit platforms

On 32-bit platforms, add an extra 32-bit word to both _StringObject and _StringGuts for padding and metadata bit storage.

Padding _StringObject rather than adding two extra words to _StringGuts makes for unattractively discontiguous inline storage. However, _StringObject needs 2 more metadata bits than are available in a 32-bit BridgeObject; shoving an extra word in there was easier than a full code reorganization.

To make use of all this luxurious extra space, on 32-bit platforms, _StringGuts._otherBits always contains the count for contiguous strings, while the new _StringGuts._extraBits stored property contains the start address. This makes extracting an unmanaged view a trivial operation.

* [runtime] SwiftObject, SwiftValue: Simplify -description implementation

Previously, these classes implemented -description and -debugDescription by
1) calling _getSummary in the stdlib to get the Swift String description corresponding to the value, and then
2) calling _convertStringToNSString in the Foundation overlay to convert the resulting String into an NSString.

To hold the Swift String value between the two calls, SwiftObject defined a dummy C++ struct whose layout is supposed match that of Swift Strings.

Instead of updating this struct to the new String representation, this commit collapses the two stages above into a single call into a new generic function, _getDescription (defined in the Foundation overlay), which gets rid of this maintenance chore.

* [runtime] Reflection: Update String representation to follow stdlib changes

* _StringObject: Replace _BridgeObject with AnyObject? on 32-bit platforms

Also, don't store any tagged value in _StringObject on 32-bit -- with AnyObject taking up a full word now, we only have 28 bits available (30 tops), which is not enough to store either a count nor a start address.

* LibcShims: Adjust _swift_stdlib_print_hex for 32-bit platforms.

* [test] Update 32-bit reflection tests

Previous (speculative) update missed a couple of offset/size changes.

* [test] IRGen/lazy_multi_file.swift: Allow for the possibility of an sret param before self.

String is 4 words long on 32 bit platforms, which gets returned via sret on i386.

* [test] DebugInfo/self.swift: Don't expect self to be alloca'd first

On i386, space for a String gets allocated before the self variable.

* _StringGuts: Add _RawBitPattern typealias

* _StringGuts: Fix an overlapping access warning

* _StringVariant: Remove IndexDistance condition

* [runtime] Update mangled symbol
  • Loading branch information
lorentey authored and milseman committed Jan 10, 2018
1 parent 2d4f8a9 commit 0f41fef
Show file tree
Hide file tree
Showing 14 changed files with 470 additions and 167 deletions.
4 changes: 2 additions & 2 deletions stdlib/public/SDK/Foundation/NSString.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ public class NSSimpleCString {}
public class NSConstantString {}

// Called by the SwiftObject implementation.
public func _convertStringToNSString(_ string: String) -> NSString {
return string._bridgeToObjectiveC()
public func _getDescription<T>(_ x: T) -> NSString {
return String(reflecting: x)._bridgeToObjectiveC()
}

extension NSString : ExpressibleByStringLiteral {
Expand Down
10 changes: 0 additions & 10 deletions stdlib/public/core/ReflectionLegacy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,6 @@ public protocol _Mirror {
var disposition: _MirrorDisposition { get }
}

/// An entry point that can be called from C++ code to get the summary string
/// for an arbitrary object. The memory pointed to by "out" is initialized with
/// the summary string.
@_inlineable // FIXME(sil-serialize-all)
@_silgen_name("swift_getSummary")
public // COMPILER_INTRINSIC
func _getSummary<T>(_ out: UnsafeMutablePointer<String>, x: T) {
out.initialize(to: String(reflecting: x))
}

/// Produce a mirror for any value. The runtime produces a mirror that
/// structurally reflects values of any type.
@_inlineable // FIXME(sil-serialize-all)
Expand Down
39 changes: 13 additions & 26 deletions stdlib/public/core/StringComparable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,33 +80,25 @@ extension _StringGuts {
@effects(readonly)
public
static func _compareDeterministicUnicodeCollation(
_leftUnsafeStringGutsBitPattern leftBits: (UInt, UInt),
_rightUnsafeStringGutsBitPattern rightBits: (UInt, UInt)
_leftUnsafeStringGutsBitPattern leftBits: _RawBitPattern,
_rightUnsafeStringGutsBitPattern rightBits: _RawBitPattern
) -> Int {
let left = _StringGuts(
object: _StringObject(rawBits: leftBits.0),
otherBits: leftBits.1)
let right = _StringGuts(
object: _StringObject(rawBits: rightBits.0),
otherBits: rightBits.1)
let left = _StringGuts(rawBits: leftBits)
let right = _StringGuts(rawBits: rightBits)
return _compareDeterministicUnicodeCollation(
left, 0..<left.count, to: right, 0..<right.count)
}
@inline(never)
@effects(readonly)
public
static func _compareDeterministicUnicodeCollation(
_leftUnsafeStringGutsBitPattern leftBits: (UInt, UInt),
_leftUnsafeStringGutsBitPattern leftBits: _RawBitPattern,
_ leftRange: Range<Int>,
_rightUnsafeStringGutsBitPattern rightBits: (UInt, UInt),
_rightUnsafeStringGutsBitPattern rightBits: _RawBitPattern,
_ rightRange: Range<Int>
) -> Int {
let left = _StringGuts(
object: _StringObject(rawBits: leftBits.0),
otherBits: leftBits.1)
let right = _StringGuts(
object: _StringObject(rawBits: rightBits.0),
otherBits: rightBits.1)
let left = _StringGuts(rawBits: leftBits)
let right = _StringGuts(rawBits: rightBits)
return _compareDeterministicUnicodeCollation(
left, leftRange, to: right, rightRange)
}
Expand Down Expand Up @@ -165,8 +157,7 @@ extension _StringGuts {
@inline(__always)
@_inlineable
public func _bitwiseEqualTo(_ other: _StringGuts) -> Bool {
return self._object.rawBits == other._object.rawBits
&& self._otherBits == other._otherBits
return self.rawBits == other.rawBits
}

@_inlineable
Expand Down Expand Up @@ -232,11 +223,9 @@ extension _StringGuts {
return result
}
#endif
let leftBits = (left._object.rawBits, left._otherBits)
let rightBits = (right._object.rawBits, right._otherBits)
return _compareDeterministicUnicodeCollation(
_leftUnsafeStringGutsBitPattern: leftBits, leftRange,
_rightUnsafeStringGutsBitPattern: rightBits, rightRange)
_leftUnsafeStringGutsBitPattern: left.rawBits, leftRange,
_rightUnsafeStringGutsBitPattern: right.rawBits, rightRange)
}

@_inlineable
Expand All @@ -259,11 +248,9 @@ extension _StringGuts {
return result
}
#endif
let leftBits = (left._object.rawBits, left._otherBits)
let rightBits = (right._object.rawBits, right._otherBits)
return _compareDeterministicUnicodeCollation(
_leftUnsafeStringGutsBitPattern: leftBits,
_rightUnsafeStringGutsBitPattern: rightBits)
_leftUnsafeStringGutsBitPattern: left.rawBits,
_rightUnsafeStringGutsBitPattern: right.rawBits)
}
}

Expand Down
Loading

0 comments on commit 0f41fef

Please sign in to comment.