This is done by xoring the base address of the hash table storage to the hash seed.
In deterministic mode, we perturb the seed by the bucket count instead, so that we ordering within hashed collections remains repeatable (as long as the capacity doesn't change).
Fixes https://bugs.swift.org/browse/SR-3268
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.
SIL functions might be associated with decls from other source files whose symbols we can't necessarily locally link to. The module should be associated with the SourceFile that was compiled.
Dictionary and Set currently exhibit O(n^2) behavior for certain operations involving copying elements in bulk. Add benchmarks to verify an upcoming fix and to catch regressions later.
https://bugs.swift.org/browse/SR-3268