From 7252934f9b133e3c120bc0f9480e09bd03f83ce5 Mon Sep 17 00:00:00 2001 From: Trustin Lee Date: Tue, 20 May 2014 17:16:15 +0900 Subject: [PATCH] Limit the number of bytes to copy per Unsafe.copyMemory() Motivation: During a large memory copy, safepoint polling is diabled, hindering accurate profiling. Modifications: Only copy up to 1 MiB per Unsafe.copyMemory() Result: Potentially more reliable performance --- .../util/internal/PlatformDependent0.java | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/common/src/main/java/io/netty/util/internal/PlatformDependent0.java b/common/src/main/java/io/netty/util/internal/PlatformDependent0.java index 9c4ca1cf72..ad22ace2a7 100644 --- a/common/src/main/java/io/netty/util/internal/PlatformDependent0.java +++ b/common/src/main/java/io/netty/util/internal/PlatformDependent0.java @@ -42,6 +42,13 @@ final class PlatformDependent0 { private static final boolean BIG_ENDIAN = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; private static final long ADDRESS_FIELD_OFFSET; + /** + * Limits the number of bytes to copy per {@link Unsafe#copyMemory(long, long, long)} to allow safepoint polling + * during a large copy. + */ + private static final long UNSAFE_COPY_THRESHOLD = 1024L * 1024L; + + /** * {@code true} if and only if the platform supports unaligned access. * @@ -155,11 +162,9 @@ final class PlatformDependent0 { } try { Cleaner cleaner = ((DirectBuffer) buffer).cleaner(); - if (cleaner == null) { - throw new IllegalArgumentException( - "attempted to deallocate the buffer which was allocated via JNIEnv->NewDirectByteBuffer()"); + if (cleaner != null) { + cleaner.clean(); } - cleaner.clean(); } catch (Throwable t) { // Nothing we can do here. } @@ -308,11 +313,25 @@ final class PlatformDependent0 { } static void copyMemory(long srcAddr, long dstAddr, long length) { - UNSAFE.copyMemory(srcAddr, dstAddr, length); + //UNSAFE.copyMemory(srcAddr, dstAddr, length); + while (length > 0) { + long size = Math.min(length, UNSAFE_COPY_THRESHOLD); + UNSAFE.copyMemory(srcAddr, dstAddr, size); + length -= size; + srcAddr += size; + dstAddr += size; + } } static void copyMemory(Object src, long srcOffset, Object dst, long dstOffset, long length) { - UNSAFE.copyMemory(src, srcOffset, dst, dstOffset, length); + //UNSAFE.copyMemory(src, srcOffset, dst, dstOffset, length); + while (length > 0) { + long size = Math.min(length, UNSAFE_COPY_THRESHOLD); + UNSAFE.copyMemory(src, srcOffset, dst, dstOffset, size); + length -= size; + srcOffset += size; + dstOffset += size; + } } static AtomicReferenceFieldUpdater newAtomicReferenceFieldUpdater(