diff --git a/buffer/src/main/java/io/netty/buffer/PoolThreadCache.java b/buffer/src/main/java/io/netty/buffer/PoolThreadCache.java index 68953a1a4e..af6ac24e89 100644 --- a/buffer/src/main/java/io/netty/buffer/PoolThreadCache.java +++ b/buffer/src/main/java/io/netty/buffer/PoolThreadCache.java @@ -369,7 +369,7 @@ final class PoolThreadCache { private int allocations; MemoryRegionCache(int size, SizeClass sizeClass) { - this.size = MathUtil.findNextPositivePowerOfTwo(size); + this.size = MathUtil.safeFindNextPositivePowerOfTwo(size); queue = PlatformDependent.newFixedMpscQueue(this.size); this.sizeClass = sizeClass; } diff --git a/common/src/main/java/io/netty/util/Recycler.java b/common/src/main/java/io/netty/util/Recycler.java index 65a16c13ae..a5403edccf 100644 --- a/common/src/main/java/io/netty/util/Recycler.java +++ b/common/src/main/java/io/netty/util/Recycler.java @@ -27,7 +27,7 @@ import java.util.Map; import java.util.WeakHashMap; import java.util.concurrent.atomic.AtomicInteger; -import static io.netty.util.internal.MathUtil.findNextPositivePowerOfTwo; +import static io.netty.util.internal.MathUtil.safeFindNextPositivePowerOfTwo; import static java.lang.Math.max; import static java.lang.Math.min; @@ -66,14 +66,13 @@ public abstract class Recycler { SystemPropertyUtil.getInt("io.netty.recycler.maxSharedCapacityFactor", 2)); - LINK_CAPACITY = findNextPositivePowerOfTwo( + LINK_CAPACITY = safeFindNextPositivePowerOfTwo( max(SystemPropertyUtil.getInt("io.netty.recycler.linkCapacity", 16), 16)); // By default we allow one push to a Recycler for each 8th try on handles that were never recycled before. // This should help to slowly increase the capacity of the recycler while not be too sensitive to allocation // bursts. - RATIO = min(findNextPositivePowerOfTwo( - max(SystemPropertyUtil.getInt("io.netty.recycler.ratio", 8), 2)), 0x40000000); + RATIO = safeFindNextPositivePowerOfTwo(SystemPropertyUtil.getInt("io.netty.recycler.ratio", 8)); if (logger.isDebugEnabled()) { if (DEFAULT_MAX_CAPACITY == 0) { @@ -116,10 +115,7 @@ public abstract class Recycler { } protected Recycler(int maxCapacity, int maxSharedCapacityFactor, int ratio) { - if (ratio > 0x40000000) { - throw new IllegalArgumentException(ratio + ": " + ratio + " (expected: < 0x40000000)"); - } - ratioMask = findNextPositivePowerOfTwo(ratio) - 1; + ratioMask = safeFindNextPositivePowerOfTwo(ratio) - 1; if (maxCapacity <= 0) { this.maxCapacity = 0; this.maxSharedCapacityFactor = 1; diff --git a/common/src/main/java/io/netty/util/ResourceLeakDetector.java b/common/src/main/java/io/netty/util/ResourceLeakDetector.java index a6e126d79d..81e9f3edfb 100644 --- a/common/src/main/java/io/netty/util/ResourceLeakDetector.java +++ b/common/src/main/java/io/netty/util/ResourceLeakDetector.java @@ -193,15 +193,12 @@ public class ResourceLeakDetector { if (resourceType == null) { throw new NullPointerException("resourceType"); } - if (samplingInterval <= 0) { - throw new IllegalArgumentException("samplingInterval: " + samplingInterval + " (expected: 1+)"); - } if (maxActive <= 0) { throw new IllegalArgumentException("maxActive: " + maxActive + " (expected: 1+)"); } this.resourceType = resourceType; - this.samplingInterval = MathUtil.findNextPositivePowerOfTwo(samplingInterval); + this.samplingInterval = MathUtil.safeFindNextPositivePowerOfTwo(samplingInterval); // samplingInterval is a power of two so we calculate a mask that we can use to // check if we need to do any leak detection or not. mask = this.samplingInterval - 1; diff --git a/common/src/main/java/io/netty/util/collection/IntObjectHashMap.java b/common/src/main/java/io/netty/util/collection/IntObjectHashMap.java index c60e9bdda8..1da9c9fcea 100644 --- a/common/src/main/java/io/netty/util/collection/IntObjectHashMap.java +++ b/common/src/main/java/io/netty/util/collection/IntObjectHashMap.java @@ -67,6 +67,7 @@ public class IntObjectHashMap implements IntObjectMap, Iterable= 1"); } + if (loadFactor <= 0.0f || loadFactor > 1.0f) { // Cannot exceed 1 because we can never store more than capacity elements; // using a bigger loadFactor would trigger rehashing before the desired load is reached. diff --git a/common/src/main/java/io/netty/util/internal/MathUtil.java b/common/src/main/java/io/netty/util/internal/MathUtil.java index a578bffea9..80c7d75486 100644 --- a/common/src/main/java/io/netty/util/internal/MathUtil.java +++ b/common/src/main/java/io/netty/util/internal/MathUtil.java @@ -24,9 +24,7 @@ public final class MathUtil { /** * Fast method of finding the next power of 2 greater than or equal to the supplied value. - * - * If the value is {@code <= 0} then 1 will be returned. - * + *

If the value is {@code <= 0} then 1 will be returned. * This method is not suitable for {@link Integer#MIN_VALUE} or numbers greater than 2^30. * * @param value from which to search for next power of 2 @@ -37,6 +35,22 @@ public final class MathUtil { return 1 << (32 - Integer.numberOfLeadingZeros(value - 1)); } + /** + * Fast method of finding the next power of 2 greater than or equal to the supplied value. + *

This method will do runtime bounds checking and call {@link #findNextPositivePowerOfTwo(int)} if within a + * valid range. + * @param value from which to search for next power of 2 + * @return The next power of 2 or the value itself if it is a power of 2. + *

Special cases for return values are as follows: + *

    + *
  • {@code <= 0} -> 1
  • + *
  • {@code >= 2^30} -> 2^30
  • + *
+ */ + public static int safeFindNextPositivePowerOfTwo(final int value) { + return value <= 0 ? 1 : value >= 0x40000000 ? 0x40000000 : findNextPositivePowerOfTwo(value); + } + /** * Determine if the requested {@code index} and {@code length} will fit within {@code capacity}. * @param index The starting index.