StringStorage tried to adopt the visitor pattern, but it regressed
benchmarks too much. We'd like to come up with a mutation story
anyways, and StringStorage was sort of cheating that by being a class.
Restores perf-regressions of Join etc.
Adds some comments for sections of code that doesn't adopt the
visitation pattern, or have inefficiencies discovered as part of this
work. Additionally, mutating methods generally do not use the visitor
scheme.
Use the visitor pattern in most of the opaque-by-hand call
sites. Inspecting the compiler output does not show excessive and
unanticipated ARC, but there may need to be further tweaks.
One downside of the visitor pattern as written is that there's extra
shuffling around of registers for the closure CC. Hopefully this will
also be fixed soon.
Add a visitor-like function which will inspect the bitpattern of
_StringGuts and dispatch to the appropriate mechanism. This allows us
to keep the core usage pattern in one spot, and tweak the branching
scheme as the ABI finalizes.
It also reduces the bug surface area by allowing us to maintain
resilience in the visitor, instead of by-hand at every use site. It
also prevents expression-drift, which the by-hand opaque pattern is
susceptible to.
Current implementation is very carefully written to avoid excess
ARC. Uses need to be very careful about not capturing, or else there
will be non-trivial closure contexts and performance will blow
up. Both of these aspects will hopefully be fixed soon.
Stop inlining _asOpaque into user code. Inlining it bloats user code
as there's a bit-test-and-branch to a block containing the _asOpaque
call, followed up some operations to e.g. manipulate the range or
re-align the calling convention, etc., followed by a final branch to
opaque stdlib code.
Instead, branch directly into opaque stdlib code. In theory, this
means that supporting all opaque patterns can be done with minimal
bloat. On ARM, this is a single tbnz instruction.
In preparation for small strings optimizations, bifurcate StringGuts's
inits to denote when the caller is choosing to skip any checks for is
small. In the majority of cases, the caller has more local information
to guide the decision.
Adds todos and comments as well:
* TODO(SSO) denotes any task that should be done simultaneously with
the introduction of small strings.
* TODO(TODO: JIRA) denotes tasks that should eventually happen
later (and will have corresponding JIRAs filed for).
* TODO(Comparison) denotes tasks when the new string comparison
lands.
- Hash seed randomization can now be disabled by defining the SWIFT_DETERMINISTIC_HASHING environment value with a value of "1".
- The random hash seed is now generated using arc4random, where available. On platforms where it isn't, don't construct std::random_device twice.
- _Hasher._secretKey is renamed _Hashing._seed, with no setter.
- _Hasher._isDeterministic is a new property exposing whether we're running with non-random hashes. (Set/Dictionary will need this information to decide if they're allowed to use per-instance seeding.)
Switch to a resilient hashing interface, currently implementing SipHash-1-3.
Compiler-synthesized Hashable conformances still use the old _combineHashValues interface for now.
Beyond switching hashing algorithms, this also enables per-execution hash seeds, fulfilling a long-standing prophecy in Hashable’s documentation.
To reduce the possibility of random test failures, StdlibUnittest’s TestSuite overrides the random hash seed on initialization.
rdar://problem/24109692
rdar://problem/35052153
Introduce _Hasher, representing an opaque hash compression function.
Add the method _hash(into:) as a Hashable requirement, decoupling the choice of hash function from Hashable's implementation. The default implementation of _hash(into:) has a default implementation that simply feeds hashValue to the hasher.
Add _hash(into:) implementations for the default integer types. Note that Int.hashValue does not return self anymore.
Add struct _LegacyHasher, emulating Swift 4.1 hashes in the new interface.
Implements the minimum specified by the SE-proposal.
* Add the CaseIterable protocol with AllCases associatedtype and
allCases requirement
* Automatic synthesis occurs for "simple" enums
- Caveat: Availability attributes suppress synthesis. This can be
lifted in the future
- Caveat: Conformance must be stated on the original type
declaration (just like synthesizing Equatable/Hashable)
- Caveat: Synthesis generates an [T]. A more efficient collection
- possibly even a lazy one - should be put here.
* First pass at implementing support for mapping between long double and Float80.
* Only define CLongDouble on platforms where I know what it is.
* remove some hacks that are no longer necessary.