diff --git a/common/src/main/java/io/netty/util/internal/CleanerJava6.java b/common/src/main/java/io/netty/util/internal/CleanerJava6.java deleted file mode 100644 index dd280fcea5..0000000000 --- a/common/src/main/java/io/netty/util/internal/CleanerJava6.java +++ /dev/null @@ -1,149 +0,0 @@ -/* -* Copyright 2014 The Netty Project -* -* The Netty Project licenses this file to you under the Apache License, -* version 2.0 (the "License"); you may not use this file except in compliance -* with the License. You may obtain a copy of the License at: -* -* https://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -* License for the specific language governing permissions and limitations -* under the License. -*/ -package io.netty.util.internal; - -import io.netty.util.internal.logging.InternalLogger; -import io.netty.util.internal.logging.InternalLoggerFactory; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.lang.reflect.Field; -import java.nio.ByteBuffer; -import java.security.AccessController; -import java.security.PrivilegedAction; - - -/** - * Allows to free direct {@link ByteBuffer} by using Cleaner. This is encapsulated in an extra class to be able - * to use {@link PlatformDependent0} on Android without problems. - * - * For more details see #2604. - */ -final class CleanerJava6 implements Cleaner { - private static final long CLEANER_FIELD_OFFSET; - private static final MethodHandle CLEAN_HANDLE; - private static final MethodHandle CLEANER_FIELD_HANDLE; - - private static final InternalLogger logger = InternalLoggerFactory.getInstance(CleanerJava6.class); - - static { - long fieldOffset; - MethodHandle cleanHandle = null; - MethodHandle cleanerFieldHandle = null; - Throwable error = null; - final ByteBuffer direct = ByteBuffer.allocateDirect(1); - try { - Object mayBeCleanerField = AccessController.doPrivileged((PrivilegedAction) () -> { - try { - Field cleanerField1 = direct.getClass().getDeclaredField("cleaner"); - if (!PlatformDependent.hasUnsafe()) { - // We need to make it accessible if we do not use Unsafe as we will access it via - // reflection. - cleanerField1.setAccessible(true); - } - return cleanerField1; - } catch (Throwable cause) { - return cause; - } - }); - if (mayBeCleanerField instanceof Throwable) { - throw (Throwable) mayBeCleanerField; - } - - Field cleanerField = (Field) mayBeCleanerField; - MethodHandles.Lookup lookup = MethodHandles.lookup(); - - final Object cleaner; - - // If we have sun.misc.Unsafe we will use it as its faster then using reflection, - // otherwise let us try reflection as last resort. - if (PlatformDependent.hasUnsafe()) { - fieldOffset = PlatformDependent0.objectFieldOffset(cleanerField); - cleaner = PlatformDependent0.getObject(direct, fieldOffset); - } else { - fieldOffset = -1; - cleaner = cleanerField.get(direct); - cleanerFieldHandle = lookup.unreflectGetter(cleanerField); - } - cleanHandle = lookup.findVirtual(cleaner.getClass(), "clean", MethodType.methodType(void.class)); - cleanHandle.invoke(cleaner); - } catch (Throwable t) { - // We don't have ByteBuffer.cleaner(). - fieldOffset = -1; - cleanerFieldHandle = null; - cleanHandle = null; - error = t; - } - - if (error == null) { - logger.debug("java.nio.ByteBuffer.cleaner(): available"); - } else { - logger.debug("java.nio.ByteBuffer.cleaner(): unavailable", error); - } - CLEANER_FIELD_HANDLE = cleanerFieldHandle; - CLEANER_FIELD_OFFSET = fieldOffset; - CLEAN_HANDLE = cleanHandle; - } - - static boolean isSupported() { - return CLEANER_FIELD_OFFSET != -1 || CLEANER_FIELD_HANDLE != null; - } - - @Override - public void freeDirectBuffer(ByteBuffer buffer) { - if (!buffer.isDirect()) { - return; - } - if (System.getSecurityManager() == null) { - try { - freeDirectBuffer0(buffer); - } catch (Throwable cause) { - PlatformDependent.throwException(cause); - } - } else { - freeDirectBufferPrivileged(buffer); - } - } - - private static void freeDirectBufferPrivileged(final ByteBuffer buffer) { - Throwable cause = AccessController.doPrivileged((PrivilegedAction) () -> { - try { - freeDirectBuffer0(buffer); - return null; - } catch (Throwable throwable) { - return throwable; - } - }); - if (cause != null) { - PlatformDependent.throwException(cause); - } - } - - private static void freeDirectBuffer0(ByteBuffer buffer) throws Throwable { - final Object cleaner; - // If CLEANER_FIELD_OFFSET == -1 we need to use reflection to access the cleaner, otherwise we can use - // sun.misc.Unsafe. - if (CLEANER_FIELD_OFFSET == -1) { - cleaner = CLEANER_FIELD_HANDLE.invoke(buffer); - } else { - cleaner = PlatformDependent0.getObject(buffer, CLEANER_FIELD_OFFSET); - } - if (cleaner != null) { - CLEAN_HANDLE.invoke(cleaner); - } - } -} diff --git a/common/src/main/java/io/netty/util/internal/PlatformDependent.java b/common/src/main/java/io/netty/util/internal/PlatformDependent.java index 1f1ab92ccb..4cbe06d02d 100644 --- a/common/src/main/java/io/netty/util/internal/PlatformDependent.java +++ b/common/src/main/java/io/netty/util/internal/PlatformDependent.java @@ -162,11 +162,7 @@ public final class PlatformDependent { if (!isAndroid()) { // only direct to method if we are not running on android. // See https://github.com/netty/netty/issues/2604 - if (javaVersion() >= 9) { - CLEANER = CleanerJava9.isSupported() ? new CleanerJava9() : NOOP; - } else { - CLEANER = CleanerJava6.isSupported() ? new CleanerJava6() : NOOP; - } + CLEANER = CleanerJava9.isSupported() ? new CleanerJava9() : NOOP; } else { CLEANER = NOOP; } diff --git a/common/src/main/java/io/netty/util/internal/svm/CleanerJava6Substitution.java b/common/src/main/java/io/netty/util/internal/svm/CleanerJava6Substitution.java deleted file mode 100644 index aed4777a0d..0000000000 --- a/common/src/main/java/io/netty/util/internal/svm/CleanerJava6Substitution.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2019 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package io.netty.util.internal.svm; - -import com.oracle.svm.core.annotate.Alias; -import com.oracle.svm.core.annotate.RecomputeFieldValue; -import com.oracle.svm.core.annotate.TargetClass; - -@TargetClass(className = "io.netty.util.internal.CleanerJava6") -final class CleanerJava6Substitution { - private CleanerJava6Substitution() { - } - - @Alias - @RecomputeFieldValue( - kind = RecomputeFieldValue.Kind.FieldOffset, - declClassName = "java.nio.DirectByteBuffer", - name = "cleaner") - private static long CLEANER_FIELD_OFFSET; -}