I realized that as long as we implement `UpbTypeConversions` for enums, we can
easily get the blanket implementation for messages to work for enums as well.
Luckily the blanket implementation also happens to work for non-generated
types, so this gets us down to just one ProxiedInMapValue implementation for
upb.
PiperOrigin-RevId: 673927343
This avoids allocating a backing array of size 10 when we are adding >10 elements.
- If we are adding objects one at a time, inflate a Object[10] and continue.
- If we are adding objects from a Collection, assume this is the only collection we are adding, and inflate a `Object[collection.size()]`
- If the existing array is non-empty, resize the array by 1.5x exponential growth as usual.
There's another small change where if we're addAll(<10 elements), we allocate an exact-sized backing array (e.g. size=3), rather than rounding up to size 10. See android/LiteAllocationTest. I think this is good: this will save memory in the common case of just calling .addAll() once, and if we call addAll twice, we grow still exponentially. But we could decide to avoid this or split it out into its own change.
This change involves moving some logic out of GeneratedMessageLite. I think the default size of the backing array is better handled inside ProtobufArrayList than inside GeneratedMessageLite's wrapper function.
PiperOrigin-RevId: 673612155
But check that the given byte size is within the bounds of the byte[] first, otherwise we might get OutOfMemoryErrors on bitflipped input that tries to allocate huge arrays.
Add some tests that would have otherwise OutOfMemoryError'd in order to have some confidence that we won't OOM.
PiperOrigin-RevId: 673597245
I'm just about to edit this code, and I want these tests for my peace of mind.
Also update the other callers to use assertThrows for consistency.
PiperOrigin-RevId: 673590917
This has twofold goals:
1. Correctness: if position overruns the array, checking space left may return a negative number. I'm not sure how bad that is, but let's avoid it.
2. Performance. This generates more optimal assembly code which can combine bounds checks, particularly on Android (I haven't looked at the generated assembly on the server JVM; it's possible the server JVM can already performance this hoist).
The `position` field is stored on the object, so Android ART generates assembly codes for `this.position++` like "load, add, store":
```
ldr w3, [x1, #12]
add w4, w3, #0x1 (1)
str w4, [x1, #12]
```
There can be a lot of these loads/stores executed each step of a loop (e.g. writeFixed64NoTag updates position 8 times, and varint encoding could do it even more). It's faster if we can hoist these so we load once at the start of the function, and store once at the end of the function. This also has the nice benefit that it won't store if we've thrown an exception.
See before/after in Compiler Explorer: https://godbolt.org/z/bWWYqsxK4. I'm not an assembly expert, but it seems clear that the increment instructions like `add w4, w0, #0x1 (1)` are no longer always surrounded by loads and stores in the new version.
And in Compiler Explorer, you also see `bufferFixed64NoTag` has reduced from 98 lines of assembly to 57 lines of assembly in the hoisted version. This is because we don't need to re-check the array bounds each time we reload `position`. I imagine this also makes any other method with a fixed number of increments like `writeFixed32NoTag` faster too.
PiperOrigin-RevId: 673588324
This reduces the total number of instantiations and reduces binary size costs.
It puts an hard upper bound on the total number of instantiations of the template.
PiperOrigin-RevId: 673452657
In the worst case, the source object is a constant (eg a global default instance) and modifying them has undefined behavior.
PiperOrigin-RevId: 673402981
The `retention` and `target` options have been functional for a long time, so
we can delete these stale comments saying that they do not work yet.
PiperOrigin-RevId: 673401292
- Add overloads that take `absl::Cord` and `std::string&&` as inputs, putting
the burden in the implementation instead of users.
- Hide the APIs that return `std::string*` when the breaking change is
enabled (via `-DPROTOBUF_TEMPORARY_ENABLE_STRING_VIEW_RETURN_TYPE`)....
PiperOrigin-RevId: 673397581
`ClassData`. This reduces code size bloat and runtime costs when using the
custom vtable. It has no significant change for normal mode.
PiperOrigin-RevId: 673010897
This enables enforcement of lifetime specifications on individual enum values for features. It will allow us to add new values to existing features, as well as deprecate/and remove existing values. By default, each value will be scoped to the lifetime spec of its corresponding feature field. However, individual lifetime boundaries can be overridden at the value-level for finer grained control.
In the near-term, this will allow us to deprecate/remove required field presence, and add a stricter utf8 validation feature.
PiperOrigin-RevId: 672710484