diff --git a/buffer/src/main/java/io/netty/buffer/PoolChunk.java b/buffer/src/main/java/io/netty/buffer/PoolChunk.java index a22421a9f9..25505d1226 100644 --- a/buffer/src/main/java/io/netty/buffer/PoolChunk.java +++ b/buffer/src/main/java/io/netty/buffer/PoolChunk.java @@ -20,11 +20,7 @@ final class PoolChunk { private static final int ST_UNUSED = 0; private static final int ST_BRANCH = 1; private static final int ST_ALLOCATED = 2; - private static final int ST_ALLOCATED_SUBPAGE = ST_ALLOCATED | 1; - - private static final long multiplier = 0x5DEECE66DL; - private static final long addend = 0xBL; - private static final long mask = (1L << 48) - 1; + private static final int ST_ALLOCATED_SUBPAGE = 3; final PoolArena arena; final T memory; @@ -40,8 +36,6 @@ final class PoolChunk { private final int chunkSize; private final int maxSubpageAllocs; - private long random = (System.nanoTime() ^ multiplier) & mask; - private int freeBytes; PoolChunkList parent; @@ -123,22 +117,13 @@ final class PoolChunk { case ST_UNUSED: return allocateRunSimple(normCapacity, curIdx, val); case ST_BRANCH: + // Try the right node first because it is more likely to be ST_UNUSED. + // It is because allocateRunSimple() always chooses the left node. final int nextIdxLeft = curIdx << 1; - final int nextValLeft = memoryMap[nextIdxLeft]; - final boolean recurseLeft; - switch (nextValLeft & 3) { - case ST_UNUSED: - return allocateRunSimple(normCapacity, nextIdxLeft, nextValLeft); - case ST_BRANCH: - recurseLeft = true; - break; - default: - recurseLeft = false; - } - final int nextIdxRight = nextIdxLeft ^ 1; final int nextValRight = memoryMap[nextIdxRight]; final boolean recurseRight; + switch (nextValRight & 3) { case ST_UNUSED: return allocateRunSimple(normCapacity, nextIdxRight, nextValRight); @@ -149,15 +134,28 @@ final class PoolChunk { recurseRight = false; } - if (recurseLeft) { - long res = branchRun(normCapacity, nextIdxLeft); + final int nextValLeft = memoryMap[nextIdxLeft]; + final boolean recurseLeft; + + switch (nextValLeft & 3) { + case ST_UNUSED: + return allocateRunSimple(normCapacity, nextIdxLeft, nextValLeft); + case ST_BRANCH: + recurseLeft = true; + break; + default: + recurseLeft = false; + } + + if (recurseRight) { + long res = branchRun(normCapacity, nextIdxRight); if (res > 0) { return res; } } - if (recurseRight) { - return branchRun(normCapacity, nextIdxRight); + if (recurseLeft) { + return branchRun(normCapacity, nextIdxLeft); } } @@ -193,7 +191,7 @@ final class PoolChunk { return curIdx; } - int nextIdx = curIdx << 1 ^ nextRandom(); + int nextIdx = curIdx << 1; int unusedIdx = nextIdx ^ 1; memoryMap[curIdx] = val & ~3 | ST_BRANCH; @@ -207,29 +205,29 @@ final class PoolChunk { } private long allocateSubpage(int normCapacity, int curIdx, int val) { - int state = val & 3; - if (state == ST_BRANCH) { - int nextIdx = curIdx << 1 ^ nextRandom(); - long res = branchSubpage(normCapacity, nextIdx); - if (res > 0) { - return res; - } + switch (val & 3) { + case ST_UNUSED: + return allocateSubpageSimple(normCapacity, curIdx, val); + case ST_BRANCH: + // Try the right node first because it is more likely to be ST_UNUSED. + // It is because allocateSubpageSimple() always chooses the left node. + final int nextIdxLeft = curIdx << 1; + final int nextIdxRight = nextIdxLeft ^ 1; - return branchSubpage(normCapacity, nextIdx ^ 1); - } + long res = branchSubpage(normCapacity, nextIdxRight); + if (res > 0) { + return res; + } - if (state == ST_UNUSED) { - return allocateSubpageSimple(normCapacity, curIdx, val); - } + return branchSubpage(normCapacity, nextIdxLeft); + case ST_ALLOCATED_SUBPAGE: + PoolSubpage subpage = subpages[subpageIdx(curIdx)]; + int elemSize = subpage.elemSize; + if (normCapacity != elemSize) { + return -1; + } - if (state == ST_ALLOCATED_SUBPAGE) { - PoolSubpage subpage = subpages[subpageIdx(curIdx)]; - int elemSize = subpage.elemSize; - if (normCapacity != elemSize) { - return -1; - } - - return subpage.allocate(); + return subpage.allocate(); } return -1; @@ -253,7 +251,7 @@ final class PoolChunk { return subpage.allocate(); } - int nextIdx = curIdx << 1 ^ nextRandom(); + int nextIdx = curIdx << 1; int unusedIdx = nextIdx ^ 1; memoryMap[curIdx] = val & ~3 | ST_BRANCH; @@ -363,11 +361,6 @@ final class PoolChunk { return memoryMapIdx - maxSubpageAllocs; } - private int nextRandom() { - random = random * multiplier + addend & mask; - return (int) (random >>> 47) & 1; - } - public String toString() { StringBuilder buf = new StringBuilder(); buf.append("Chunk(");