@effects is too low a level, and not meant for general usage outside
the standard library. Therefore it deserves to be underscored like
other such attributes.
_StringGuts is not meant to be an abstraction across all the forms a
String may take. It's meant to abstract the book-keeping and the
visitor is a parameterization over operations.
Extract slow paths into non-inlinable functions so that fast-paths can
be faster and we don't pay the large code bloat for the Unicode
parsers.
Some tests proactively extended to highlight UTF8View of multiple
kinds of Strings.
Drop append-related @inlinable annotations for String, StringGuts,
StringStorage, and the Views. Drop several for larger operations, such
as case conversion. Drop as many as we can from StringGuts for now.
Beside the general goal to remove inlinable functions, this reduces code size and also improves performance for several benchmarks.
The performance problem was that by inlining top-level String API functions into client code (like String.count) it ended up calling non-inlinable internal String functions eventually.
This is much slower than to make a single call at the top-level API boundary into the library. Inside the library all the internal String functions can be specialized and inlined.
rdar://problem/39921548
StringStorage.create is the primary means of allocating storage for a
string, so drop inlinability to allow for future evolution.
StringStorage also exposes some .appendInPlace methods, which we
currently need to keep inlinable for benchmark performance. We'd
really like to drop inlinability for these for evolution purposes
(e.g. imagine a future version that adjusts nul-termination or changes
in coordination with create). These are flagged with:
` // TODO(inlinability): @usableFromInline - P3`
Where "P3" reflects urgency on a scale from 1 (stop the presses) to 5
(whatevs).
Switch StringObject and StringGuts from opaquely storing tagged cocoa
strings into storing small strings. Plumb small string support
throughout the standard library's routines.
Streamline internal String creation. Previously, everything funneled
into a single generic function, however, every single call of the
generic funnel had relevant specific information that could be used
for a more efficient algorithm.
In preparation for efficiently forming small strings, refactor this
logic into a handful of more specialized subroutines to preserve more
specific information from the callers.
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.
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.
[string] Clean up StringObject; Clarify its tagged BridgeObjects.
Bifurcate StringObjects raw bit-pattern initializers to expose whether
the caller is passing a value rather than a reference. This way,
StringObject can call the approprite BridgeObject helper and
participate in upcoming peephole optimizations like retains of
known-values. This is all meant to be a NOP.
Additionally, do some cleanup while we're at it.
This is a temporary workaround for some situations where the empty
singleton is not being formed correctly (and this seems to be highly
configuration dependent). Work around that for now for also checking
for empty non-storage-backed Strings.
This is probably too expensive a check for us to do long-term, but it
works for now.
Include the initial implementation of _StringGuts, a 2-word
replacement for _LegacyStringCore. 64-bit Darwin supported, 32-bit and
Linux support in subsequent commits.