Remove CleanerJava6 (#10746)
Motivation: Netty 5 will require Java 11 at a minimum, so this pre-Java 9 specific code will never be used. Modification: Removed the dead code. Result: Less code to maintain.
This commit is contained in:
parent
38adfd8316
commit
d804e34cf0
@ -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 <a href="https://github.com/netty/netty/issues/2604">#2604</a>.
|
||||
*/
|
||||
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<Object>) () -> {
|
||||
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<Throwable>) () -> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user