43 static final boolean DEBUG;
50 private static final Object theUnsafe;
51 private static final Method unsafeCleanBB;
52 private static volatile boolean hasUnsafeCleanBBError;
54 private static final Method staticFieldOffset;
55 private static final Method getObjectVolatile;
56 private static final Method putObjectVolatile;
57 private static volatile boolean hasGetPutObjectVolatile;
59 private static final Class<?> illegalAccessLoggerClass;
60 private static final Long illegalAccessLoggerOffset;
61 private static final Object illegalAccessLoggerSync =
new Object();
62 private static volatile boolean hasIllegalAccessError;
65 final Object[] _theUnsafe = {
null };
66 final Method[] _cleanBB = {
null };
67 final Method[] _staticFieldOffset = {
null };
68 final Method[] _objectVolatile = {
null,
null };
69 final Class<?>[] _illegalAccessLoggerClass = {
null };
70 final Long[] _loggerOffset = {
null };
72 SecurityUtil.doPrivileged(
new PrivilegedAction<Object>() {
75 Class<?> unsafeClass =
null;
78 unsafeClass = Class.forName(
"sun.misc.Unsafe");
80 final Field f = unsafeClass.getDeclaredField(
"theUnsafe");
81 f.setAccessible(
true);
82 _theUnsafe[0] = f.get(
null);
84 _cleanBB[0] = unsafeClass.getMethod(
"invokeCleaner", java.nio.ByteBuffer.class);
85 _cleanBB[0].setAccessible(
true);
86 }
catch(
final Throwable t) {
88 ExceptionUtils.dumpThrowable(
"UnsafeUtil", t);
91 if(
null != _theUnsafe[0] && PlatformProps.JAVA_9 ) {
93 _staticFieldOffset[0] = unsafeClass.getDeclaredMethod(
"staticFieldOffset", Field.class);
94 _objectVolatile[0] = unsafeClass.getDeclaredMethod(
"getObjectVolatile", Object.class,
long.class);
95 _objectVolatile[1] = unsafeClass.getDeclaredMethod(
"putObjectVolatile", Object.class,
long.class, Object.class);
97 if( PlatformProps.JAVA_9 ) {
98 _illegalAccessLoggerClass[0] = Class.forName(
"jdk.internal.module.IllegalAccessLogger");
99 final Field loggerField = _illegalAccessLoggerClass[0].getDeclaredField(
"logger");
100 _loggerOffset[0] = (Long) _staticFieldOffset[0].invoke(_theUnsafe[0], loggerField);
102 }
catch(
final Throwable t) {
104 ExceptionUtils.dumpThrowable(
"UnsafeUtil", t);
110 theUnsafe = _theUnsafe[0];
111 unsafeCleanBB = _cleanBB[0];
112 hasUnsafeCleanBBError =
null == theUnsafe ||
null == unsafeCleanBB;
114 System.err.println(
"UnsafeUtil.init: hasTheUnsafe: "+(
null!=theUnsafe)+
", hasInvokeCleaner: "+!hasUnsafeCleanBBError);
117 staticFieldOffset = _staticFieldOffset[0];
118 getObjectVolatile = _objectVolatile[0];
119 putObjectVolatile = _objectVolatile[1];
120 hasGetPutObjectVolatile =
null != staticFieldOffset &&
null != getObjectVolatile &&
null != putObjectVolatile;
121 illegalAccessLoggerClass = _illegalAccessLoggerClass[0];
122 illegalAccessLoggerOffset = _loggerOffset[0];
123 hasIllegalAccessError = !hasGetPutObjectVolatile ||
null == illegalAccessLoggerClass ||
null == illegalAccessLoggerOffset;
125 System.err.println(
"UnsafeUtil.init: hasUnsafeGetPutObjectVolatile: "+hasGetPutObjectVolatile+
", hasUnsafeIllegalAccessLogger: "+!hasIllegalAccessError);
146 if( hasUnsafeCleanBBError || !bb.isDirect() ) {
150 unsafeCleanBB.invoke(theUnsafe, bb);
152 }
catch(
final Throwable t) {
153 hasUnsafeCleanBBError =
true;
182 if( !hasIllegalAccessError ) {
183 synchronized(illegalAccessLoggerSync) {
184 final Object newLogger =
null;
185 Object oldLogger =
null;
187 oldLogger = getObjectVolatile.invoke(theUnsafe, illegalAccessLoggerClass, illegalAccessLoggerOffset);
188 putObjectVolatile.invoke(theUnsafe, illegalAccessLoggerClass, illegalAccessLoggerOffset, newLogger);
189 }
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
191 hasIllegalAccessError =
true;
199 }
catch (
final Throwable t) {
203 throw new RuntimeException(t);
206 putObjectVolatile.invoke(theUnsafe, illegalAccessLoggerClass, illegalAccessLoggerOffset, oldLogger);
207 }
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
209 hasIllegalAccessError =
true;
210 throw new InternalError(e);