Skip to content

Commit ef69732

Browse files
authored
Correctly calculate the elementSize when cache alignment is configured (#11987)
Motivation: We need to take the cache alignment into account when we pre-calculate the ementSize otherwise we fail later. Modifications: - Fix pre-calculation - Add unit test - Fix incorrect unit test Result: Fixes #11955
1 parent bd7e0f7 commit ef69732

File tree

7 files changed

+45
-7
lines changed

7 files changed

+45
-7
lines changed

buffer/src/main/java/io/netty/buffer/PoolArena.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -557,9 +557,9 @@ private void destroyPoolChunkLists(PoolChunkList<T>... chunkLists) {
557557
static final class HeapArena extends PoolArena<byte[]> {
558558

559559
HeapArena(PooledByteBufAllocator parent, int pageSize, int pageShifts,
560-
int chunkSize, int directMemoryCacheAlignment) {
560+
int chunkSize) {
561561
super(parent, pageSize, pageShifts, chunkSize,
562-
directMemoryCacheAlignment);
562+
0);
563563
}
564564

565565
private static byte[] newByteArray(int size) {

buffer/src/main/java/io/netty/buffer/PoolChunk.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ void initBufWithSubpage(PooledByteBuf<T> buf, ByteBuffer nioBuffer, long handle,
571571

572572
PoolSubpage<T> s = subpages[runOffset];
573573
assert s.doNotDestroy;
574-
assert reqCapacity <= s.elemSize;
574+
assert reqCapacity <= s.elemSize : reqCapacity + "<=" + s.elemSize;
575575

576576
int offset = (runOffset << pageShifts) + bitmapIdx * s.elemSize;
577577
buf.init(this, nioBuffer, handle, offset, reqCapacity, s.elemSize, threadCache);

buffer/src/main/java/io/netty/buffer/PoolSubpage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
final class PoolSubpage<T> implements PoolSubpageMetric {
2626

2727
final PoolChunk<T> chunk;
28+
final int elemSize;
2829
private final int pageShifts;
2930
private final int runOffset;
3031
private final int runSize;
@@ -34,7 +35,6 @@ final class PoolSubpage<T> implements PoolSubpageMetric {
3435
PoolSubpage<T> next;
3536

3637
boolean doNotDestroy;
37-
int elemSize;
3838
private int maxNumElems;
3939
private int bitmapLength;
4040
private int nextAvail;

buffer/src/main/java/io/netty/buffer/PooledByteBufAllocator.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,7 @@ public PooledByteBufAllocator(boolean preferDirect, int nHeapArena, int nDirectA
300300
List<PoolArenaMetric> metrics = new ArrayList<PoolArenaMetric>(heapArenas.length);
301301
for (int i = 0; i < heapArenas.length; i ++) {
302302
PoolArena.HeapArena arena = new PoolArena.HeapArena(this,
303-
pageSize, pageShifts, chunkSize,
304-
directMemoryCacheAlignment);
303+
pageSize, pageShifts, chunkSize);
305304
heapArenas[i] = arena;
306305
metrics.add(arena);
307306
}

buffer/src/main/java/io/netty/buffer/SizeClasses.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,12 @@ private void idx2SizeTab(int[] sizeIdx2sizeTab, int[] pageIdx2sizeTab) {
237237
int nDelta = sizeClass[NDELTA_IDX];
238238

239239
int size = (1 << log2Group) + (nDelta << log2Delta);
240+
if (directMemoryCacheAlignment > 0) {
241+
// We need to ensure we align the size before storing it as otherwise we will use the incorrect element
242+
// size when creating the PoolSubPage
243+
size = alignSize(size);
244+
}
245+
240246
sizeIdx2sizeTab[i] = size;
241247

242248
if (sizeClass[PAGESIZE_IDX] == yes) {

buffer/src/test/java/io/netty/buffer/AlignedPooledByteBufAllocatorTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515
*/
1616
package io.netty.buffer;
1717

18+
import org.junit.jupiter.api.Test;
19+
20+
import static org.junit.jupiter.api.Assertions.assertEquals;
21+
import static org.junit.jupiter.api.Assertions.assertTrue;
22+
1823
public class AlignedPooledByteBufAllocatorTest extends PooledByteBufAllocatorTest {
1924
@Override
2025
protected PooledByteBufAllocator newAllocator(boolean preferDirect) {
@@ -30,4 +35,32 @@ protected PooledByteBufAllocator newAllocator(boolean preferDirect) {
3035
PooledByteBufAllocator.defaultUseCacheForAllThreads(),
3136
directMemoryCacheAlignment);
3237
}
38+
39+
// https://github.com/netty/netty/issues/11955
40+
@Test
41+
public void testCorrectElementSize() {
42+
ByteBufAllocator allocator = new PooledByteBufAllocator(
43+
true,
44+
PooledByteBufAllocator.defaultNumHeapArena(),
45+
PooledByteBufAllocator.defaultNumDirectArena(),
46+
PooledByteBufAllocator.defaultPageSize(),
47+
11,
48+
PooledByteBufAllocator.defaultSmallCacheSize(),
49+
64,
50+
PooledByteBufAllocator.defaultUseCacheForAllThreads(),
51+
64);
52+
53+
ByteBuf a = allocator.directBuffer(0, 16384);
54+
ByteBuf b = allocator.directBuffer(0, 16384);
55+
a.capacity(16);
56+
assertEquals(16, a.capacity());
57+
b.capacity(16);
58+
assertEquals(16, b.capacity());
59+
a.capacity(17);
60+
assertEquals(17, a.capacity());
61+
b.capacity(18);
62+
assertEquals(18, b.capacity());
63+
assertTrue(a.release());
64+
assertTrue(b.release());
65+
}
3366
}

buffer/src/test/java/io/netty/buffer/PoolArenaTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public void testNormalizeCapacity() {
4545
public void testNormalizeAlignedCapacity() {
4646
PoolArena<ByteBuffer> arena = new PoolArena.DirectArena(null, PAGE_SIZE, PAGE_SHIFTS, CHUNK_SIZE, 64);
4747
int[] reqCapacities = {0, 15, 510, 1024, 1023, 1025};
48-
int[] expectedResult = {16, 64, 512, 1024, 1024, 1280};
48+
int[] expectedResult = {64, 64, 512, 1024, 1024, 1280};
4949
for (int i = 0; i < reqCapacities.length; i ++) {
5050
assertEquals(expectedResult[i], arena.sizeIdx2size(arena.size2SizeIdx(reqCapacities[i])));
5151
}

0 commit comments

Comments
 (0)