Skip to content

Commit a51f98c

Browse files
mhansencopybara-github
authored andcommitted
Optimise CodedOutputStream.ArrayEncoder.writeFixed32NoTag/writeFixed64NoTag
On Android, this generates better assembly code, bounds-checking through all the used indices upfront, and branching to deoptimise if it's not true, avoiding doing 4x bounds checks. We also don't generate 4 different `pThrowArrayBounds` code sections. https://godbolt.org/z/Kbhvcdvbd Code size Comparison: - `void X.writeFixed32NoTag__before(int) [292 bytes]` - `void X.writeFixed32NoTag__after(int) [180 bytes]` This starts by throwing a more meaningful length (4bytes or 8bytes for fixed64), which makes sure the value of position in the catch clause isn't dependent on which line threw the exception. PiperOrigin-RevId: 678543462
1 parent b404010 commit a51f98c

File tree

1 file changed

+18
-16
lines changed

1 file changed

+18
-16
lines changed

java/core/src/main/java/com/google/protobuf/CodedOutputStream.java

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,15 +1348,16 @@ public final void writeUInt32NoTag(int value) throws IOException {
13481348
public final void writeFixed32NoTag(int value) throws IOException {
13491349
int position = this.position; // Perf: hoist field to register to avoid load/stores.
13501350
try {
1351-
buffer[position++] = (byte) (value & 0xFF);
1352-
buffer[position++] = (byte) ((value >> 8) & 0xFF);
1353-
buffer[position++] = (byte) ((value >> 16) & 0xFF);
1354-
buffer[position++] = (byte) ((value >> 24) & 0xFF);
1351+
buffer[position] = (byte) (value & 0xFF);
1352+
buffer[position + 1] = (byte) ((value >> 8) & 0xFF);
1353+
buffer[position + 2] = (byte) ((value >> 16) & 0xFF);
1354+
buffer[position + 3] = (byte) ((value >> 24) & 0xFF);
13551355
} catch (IndexOutOfBoundsException e) {
13561356
throw new OutOfSpaceException(
1357-
String.format("Pos: %d, limit: %d, len: %d", position, limit, 1), e);
1357+
String.format("Pos: %d, limit: %d, len: %d", position, limit, FIXED32_SIZE), e);
13581358
}
1359-
this.position = position; // Only update position if we stayed within the array bounds.
1359+
// Only update position if we stayed within the array bounds.
1360+
this.position = position + FIXED32_SIZE;
13601361
}
13611362

13621363
@Override
@@ -1393,19 +1394,20 @@ public final void writeUInt64NoTag(long value) throws IOException {
13931394
public final void writeFixed64NoTag(long value) throws IOException {
13941395
int position = this.position; // Perf: hoist field to register to avoid load/stores.
13951396
try {
1396-
buffer[position++] = (byte) ((int) (value) & 0xFF);
1397-
buffer[position++] = (byte) ((int) (value >> 8) & 0xFF);
1398-
buffer[position++] = (byte) ((int) (value >> 16) & 0xFF);
1399-
buffer[position++] = (byte) ((int) (value >> 24) & 0xFF);
1400-
buffer[position++] = (byte) ((int) (value >> 32) & 0xFF);
1401-
buffer[position++] = (byte) ((int) (value >> 40) & 0xFF);
1402-
buffer[position++] = (byte) ((int) (value >> 48) & 0xFF);
1403-
buffer[position++] = (byte) ((int) (value >> 56) & 0xFF);
1397+
buffer[position] = (byte) ((int) (value) & 0xFF);
1398+
buffer[position + 1] = (byte) ((int) (value >> 8) & 0xFF);
1399+
buffer[position + 2] = (byte) ((int) (value >> 16) & 0xFF);
1400+
buffer[position + 3] = (byte) ((int) (value >> 24) & 0xFF);
1401+
buffer[position + 4] = (byte) ((int) (value >> 32) & 0xFF);
1402+
buffer[position + 5] = (byte) ((int) (value >> 40) & 0xFF);
1403+
buffer[position + 6] = (byte) ((int) (value >> 48) & 0xFF);
1404+
buffer[position + 7] = (byte) ((int) (value >> 56) & 0xFF);
14041405
} catch (IndexOutOfBoundsException e) {
14051406
throw new OutOfSpaceException(
1406-
String.format("Pos: %d, limit: %d, len: %d", position, limit, 1), e);
1407+
String.format("Pos: %d, limit: %d, len: %d", position, limit, FIXED64_SIZE), e);
14071408
}
1408-
this.position = position; // Only update position if we stayed within the array bounds.
1409+
// Only update position if we stayed within the array bounds.
1410+
this.position = position + FIXED64_SIZE;
14091411
}
14101412

14111413
@Override

0 commit comments

Comments
 (0)