@Override public void run() { if (!hasWorkingJavac()) { ClassWriter w = new ClassWriter(0); w.visit(Opcodes.V1_8, Opcodes.ACC_ABSTRACT | Opcodes.ACC_PUBLIC, "com/sun/tools/javac/code/Scope$WriteableScope", null, "com/sun/tools/javac/code/Scope", null); byte[] classData = w.toByteArray(); try { Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafe.setAccessible(true); Unsafe unsafe = (Unsafe) theUnsafe.get(null); Class scopeClass = Class.forName("com.sun.tools.javac.code.Scope"); unsafe.defineClass("com.sun.tools.javac.code.Scope$WriteableScope", classData, 0, classData.length, scopeClass.getClassLoader(), scopeClass.getProtectionDomain()); } catch (Throwable t) { //ignore... Logger.getLogger(NoJavacHelper.class.getName()).log(Level.FINE, null, t); } } }
private static void testCopyByteArrayToByteArray(Unsafe unsafe) throws Exception { System.out.println("Testing copyMemory() for byte[] to byte[]..."); byte[] b1 = new byte[BUFFER_SIZE]; byte[] b2 = new byte[BUFFER_SIZE]; for (int i = 0; i < N; i++) { set(b1, 0, BUFFER_SIZE, FILLER); set(b2, 0, BUFFER_SIZE, FILLER2); int ofs = random.nextInt(BUFFER_SIZE / 2); int len = random.nextInt(BUFFER_SIZE / 2); int val = random.nextInt(256); set(b1, ofs, len, val); int ofs2 = random.nextInt(BUFFER_SIZE / 2); unsafe.copyMemory(b1, Unsafe.ARRAY_BYTE_BASE_OFFSET + ofs, b2, Unsafe.ARRAY_BYTE_BASE_OFFSET + ofs2, len); check(b2, 0, ofs2 - 1, FILLER2); check(b2, ofs2, len, val); check(b2, ofs2 + len, BUFFER_SIZE - (ofs2 + len), FILLER2); } }
/** * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package. * Replace with a simple call to Unsafe.getUnsafe when integrating * into a jdk. * * @return a sun.misc.Unsafe */ private static sun.misc.Unsafe getUnsafe() { try { return sun.misc.Unsafe.getUnsafe(); } catch (SecurityException tryReflectionInstead) {} try { return java.security.AccessController.doPrivileged (new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() { public sun.misc.Unsafe run() throws Exception { Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class; for (java.lang.reflect.Field f : k.getDeclaredFields()) { f.setAccessible(true); Object x = f.get(null); if (k.isInstance(x)) return k.cast(x); } throw new NoSuchFieldError("the Unsafe"); }}); } catch (java.security.PrivilegedActionException e) { throw new RuntimeException("Could not initialize intrinsics", e.getCause()); } }
/** * Loads this buffer's content into physical memory. * * <p> This method makes a best effort to ensure that, when it returns, * this buffer's content is resident in physical memory. Invoking this * method may cause some number of page faults and I/O operations to * occur. </p> * * @return This buffer */ public final MappedByteBuffer load() { checkMapped(); if ((address == 0) || (capacity() == 0)) return this; long offset = mappingOffset(); long length = mappingLength(offset); load0(mappingAddress(offset), length); // Read a byte from each page to bring it into memory. A checksum // is computed as we go along to prevent the compiler from otherwise // considering the loop as dead code. Unsafe unsafe = Unsafe.getUnsafe(); int ps = Bits.pageSize(); int count = Bits.pageCount(length); long a = mappingAddress(offset); byte x = 0; for (int i=0; i<count; i++) { x ^= unsafe.getByte(a); a += ps; } if (unused != 0) unused = x; return this; }
static NativeBuffer asNativeBuffer(String s) { int stringLengthInBytes = s.length() << 1; int sizeInBytes = stringLengthInBytes + 2; // char terminator // get a native buffer of sufficient size NativeBuffer buffer = NativeBuffers.getNativeBufferFromCache(sizeInBytes); if (buffer == null) { buffer = NativeBuffers.allocNativeBuffer(sizeInBytes); } else { // buffer already contains the string contents if (buffer.owner() == s) return buffer; } // copy into buffer and zero terminate char[] chars = s.toCharArray(); unsafe.copyMemory(chars, Unsafe.ARRAY_CHAR_BASE_OFFSET, null, buffer.address(), (long)stringLengthInBytes); unsafe.putChar(buffer.address() + stringLengthInBytes, (char)0); buffer.setOwner(s); return buffer; }
private List<String> asList(long address, int size) { List<String> list = new ArrayList<>(); int start = 0; int pos = 0; while (pos < size) { if (unsafe.getByte(address + pos) == 0) { int len = pos - start; byte[] value = new byte[len]; unsafe.copyMemory(null, address+start, value, Unsafe.ARRAY_BYTE_BASE_OFFSET, len); String s = Util.toString(value); if (s.startsWith(USER_NAMESPACE)) { s = s.substring(USER_NAMESPACE.length()); list.add(s); } start = pos + 1; } pos++; } return list; }
static boolean verifyGet(long referent_offset, Unsafe unsafe) throws Exception { // Access verification System.out.println("referent: " + str); Object obj = getRef0(ref); if (obj != str) { System.out.println("FAILED: weakRef.get() " + obj + " != " + str); return false; } obj = getRef1(unsafe, ref, referent_offset); if (obj != str) { System.out.println("FAILED: unsafe.getObject(weakRef, " + referent_offset + ") " + obj + " != " + str); return false; } obj = getRef2(unsafe, ref, referent_offset); if (obj != str) { System.out.println("FAILED: unsafe.getObject(abstRef, " + referent_offset + ") " + obj + " != " + str); return false; } obj = getRef3(unsafe, ref, referent_offset); if (obj != str) { System.out.println("FAILED: unsafe.getObject(Object, " + referent_offset + ") " + obj + " != " + str); return false; } return true; }
private static void testCopyRawMemoryToRawMemory(Unsafe unsafe) throws Exception { System.out.println("Testing copyMemory() for raw memory to raw memory..."); long b1 = getMemory(BUFFER_SIZE); long b2 = getMemory(BUFFER_SIZE); for (int i = 0; i < N; i++) { set(unsafe, b1, 0, BUFFER_SIZE, FILLER); set(unsafe, b2, 0, BUFFER_SIZE, FILLER2); int ofs = random.nextInt(BUFFER_SIZE / 2); int len = random.nextInt(BUFFER_SIZE / 2); int val = random.nextInt(256); set(unsafe, b1, ofs, len, val); int ofs2 = random.nextInt(BUFFER_SIZE / 2); unsafe.copyMemory(null, b1 + ofs, null, b2 + ofs2, len); check(unsafe, b2, 0, ofs2 - 1, FILLER2); check(unsafe, b2, ofs2, len, val); check(unsafe, b2, ofs2 + len, BUFFER_SIZE - (ofs2 + len), FILLER2); } }
private static void testCopyByteArrayToRawMemory(Unsafe unsafe) throws Exception { System.out.println("Testing copyMemory() for byte[] to raw memory..."); byte[] b1 = new byte[BUFFER_SIZE]; long b2 = getMemory(BUFFER_SIZE); for (int i = 0; i < N; i++) { set(b1, 0, BUFFER_SIZE, FILLER); set(unsafe, b2, 0, BUFFER_SIZE, FILLER2); int ofs = random.nextInt(BUFFER_SIZE / 2); int len = random.nextInt(BUFFER_SIZE / 2); int val = random.nextInt(256); set(b1, ofs, len, val); int ofs2 = random.nextInt(BUFFER_SIZE / 2); unsafe.copyMemory(b1, Unsafe.ARRAY_BYTE_BASE_OFFSET + ofs, null, b2 + ofs2, len); check(unsafe, b2, 0, ofs2 - 1, FILLER2); check(unsafe, b2, ofs2, len, val); check(unsafe, b2, ofs2 + len, BUFFER_SIZE - (ofs2 + len), FILLER2); } }
/** * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package. Replace with a simple * call to Unsafe.getUnsafe when integrating into a jdk. * * @return a sun.misc.Unsafe instance if successful */ private static sun.misc.Unsafe getUnsafe() { try { return sun.misc.Unsafe.getUnsafe(); } catch (SecurityException tryReflectionInstead) { // We'll try reflection instead. } try { return java.security.AccessController.doPrivileged( new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() { @Override public sun.misc.Unsafe run() throws Exception { Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class; for (java.lang.reflect.Field f : k.getDeclaredFields()) { f.setAccessible(true); Object x = f.get(null); if (k.isInstance(x)) { return k.cast(x); } } throw new NoSuchFieldError("the Unsafe"); } }); } catch (java.security.PrivilegedActionException e) { throw new RuntimeException("Could not initialize intrinsics", e.getCause()); } }
/** * 通过反射Constructor获得Unsafe的实例对象 * * @throws Exception */ @Test public void test1() throws Exception { Constructor<Unsafe> constructor = Unsafe.class.getDeclaredConstructor(); constructor.setAccessible(true); Unsafe unsafe = constructor.newInstance(); System.out.println(unsafe); }
private static Unsafe initUnsafe() { try { return Unsafe.getUnsafe(); } catch (SecurityException se) { try { Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafe.setAccessible(true); return (Unsafe) theUnsafe.get(Unsafe.class); } catch (Exception e) { throw new RuntimeException("exception while trying to get Unsafe", e); } } }
public CustomAtomicInteger() { try { //获得Unsafe的构造器 Constructor<Unsafe> constructor = Unsafe.class.getDeclaredConstructor(); //突破私有访问权限 constructor.setAccessible(true); //创建示例 this.unsafe = constructor.newInstance(); //获得value变量的内存偏移量即内存地址 offset = unsafe.objectFieldOffset(CustomAtomicInteger.class.getDeclaredField("value")); } catch (Exception e) { e.printStackTrace(); } }
public UnsafeLock() { try { //获得Unsafe的构造器 Constructor<Unsafe> constructor = Unsafe.class.getDeclaredConstructor(); //突破私有访问权限 constructor.setAccessible(true); //创建示例 this.unsafe = constructor.newInstance(); } catch (Exception e) { e.printStackTrace(); } }
private static Unsafe getUnsafe() { if (System.getSecurityManager() != null) { return new PrivilegedAction<Unsafe>() { public Unsafe run() { return getUnsafe0(); } }.run(); } return getUnsafe0(); }
@SuppressWarnings("all") public static int unsafePutByte(Unsafe unsafe, Object obj, long offset, byte value) { int res = 1; unsafe.putByte(obj, offset, (byte) (value + 1)); res += unsafe.getByte(obj, offset); unsafe.putByteVolatile(obj, offset, (byte) (value + 2)); res += unsafe.getByte(obj, offset); return res; }
@Override public Object run() { try { Field f = Unsafe.class.getDeclaredField("theUnsafe"); f.setAccessible(true); return f.get(null); } catch (NoSuchFieldException | IllegalAccessException e) { // It doesn't matter what we throw; // it's swallowed in getBest(). throw new Error(); } }
static Unsafe getUnsafe() { try { Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafeField.setAccessible(true); return (Unsafe) theUnsafeField.get(null); } catch (IllegalAccessException | NoSuchFieldException e) { throw new Error(e); } }
/** * Constructs FieldReflector capable of setting/getting values from the * subset of fields whose ObjectStreamFields contain non-null * reflective Field objects. ObjectStreamFields with null Fields are * treated as filler, for which get operations return default values * and set operations discard given values. */ FieldReflector(ObjectStreamField[] fields) { this.fields = fields; int nfields = fields.length; readKeys = new long[nfields]; writeKeys = new long[nfields]; offsets = new int[nfields]; typeCodes = new char[nfields]; ArrayList<Class<?>> typeList = new ArrayList<>(); Set<Long> usedKeys = new HashSet<>(); for (int i = 0; i < nfields; i++) { ObjectStreamField f = fields[i]; Field rf = f.getField(); long key = (rf != null) ? unsafe.objectFieldOffset(rf) : Unsafe.INVALID_FIELD_OFFSET; readKeys[i] = key; writeKeys[i] = usedKeys.add(key) ? key : Unsafe.INVALID_FIELD_OFFSET; offsets[i] = f.getOffset(); typeCodes[i] = f.getTypeCode(); if (!f.isPrimitive()) { typeList.add((rf != null) ? rf.getType() : null); } } types = typeList.toArray(new Class<?>[typeList.size()]); numPrimFields = nfields - types.length; }
/** * Sets the serializable object fields of object obj using values from * array vals starting at offset 0. The caller is responsible for * ensuring that obj is of the proper type; however, attempts to set a * field with a value of the wrong type will trigger an appropriate * ClassCastException. */ void setObjFieldValues(Object obj, Object[] vals) { if (obj == null) { throw new NullPointerException(); } for (int i = numPrimFields; i < fields.length; i++) { long key = writeKeys[i]; if (key == Unsafe.INVALID_FIELD_OFFSET) { continue; // discard value } switch (typeCodes[i]) { case 'L': case '[': Object val = vals[offsets[i]]; if (val != null && !types[i - numPrimFields].isInstance(val)) { Field f = fields[i].getField(); throw new ClassCastException( "cannot assign instance of " + val.getClass().getName() + " to field " + f.getDeclaringClass().getName() + "." + f.getName() + " of type " + f.getType().getName() + " in instance of " + obj.getClass().getName()); } unsafe.putObject(obj, key, val); break; default: throw new InternalError(); } } }
@SuppressWarnings("all") public static float unsafePutFloat(Unsafe unsafe, Object obj, long offset, float value) { float res = 1; unsafe.putFloat(obj, offset, value + 1.0F); res += unsafe.getFloat(obj, offset); unsafe.putFloatVolatile(obj, offset, value + 2.0F); res += unsafe.getFloat(obj, offset); return res; }
public RenderBuffer put(short[] x, int offset, int length) { // assert (position() % SIZEOF_SHORT == 0); if (length > COPY_FROM_ARRAY_THRESHOLD) { long offsetInBytes = offset * SIZEOF_SHORT + Unsafe.ARRAY_SHORT_BASE_OFFSET; long lengthInBytes = length * SIZEOF_SHORT; unsafe.copyMemory(x, offsetInBytes, null, curAddress, lengthInBytes); position(position() + lengthInBytes); } else { int end = offset + length; for (int i = offset; i < end; i++) { putShort(x[i]); } } return this; }
public RenderBuffer put(int[] x, int offset, int length) { // assert (position() % SIZEOF_INT == 0); if (length > COPY_FROM_ARRAY_THRESHOLD) { long offsetInBytes = offset * SIZEOF_INT + Unsafe.ARRAY_INT_BASE_OFFSET; long lengthInBytes = length * SIZEOF_INT; unsafe.copyMemory(x, offsetInBytes, null, curAddress, lengthInBytes); position(position() + lengthInBytes); } else { int end = offset + length; for (int i = offset; i < end; i++) { putInt(x[i]); } } return this; }
public RenderBuffer put(long[] x, int offset, int length) { // assert (position() % SIZEOF_LONG == 0); if (length > COPY_FROM_ARRAY_THRESHOLD) { long offsetInBytes = offset * SIZEOF_LONG + Unsafe.ARRAY_LONG_BASE_OFFSET; long lengthInBytes = length * SIZEOF_LONG; unsafe.copyMemory(x, offsetInBytes, null, curAddress, lengthInBytes); position(position() + lengthInBytes); } else { int end = offset + length; for (int i = offset; i < end; i++) { putLong(x[i]); } } return this; }
private void processEvents(WindowsWatchKey key, int size) { long address = key.buffer().address(); int nextOffset; do { int action = unsafe.getInt(address + OFFSETOF_ACTION); // map action to event WatchEvent.Kind<?> kind = translateActionToEvent(action); if (key.events().contains(kind)) { // copy the name int nameLengthInBytes = unsafe.getInt(address + OFFSETOF_FILENAMELENGTH); if ((nameLengthInBytes % 2) != 0) { throw new AssertionError("FileNameLength.FileNameLength is not a multiple of 2"); } char[] nameAsArray = new char[nameLengthInBytes/2]; unsafe.copyMemory(null, address + OFFSETOF_FILENAME, nameAsArray, Unsafe.ARRAY_CHAR_BASE_OFFSET, nameLengthInBytes); // create FileName and queue event WindowsPath name = WindowsPath .createFromNormalizedPath(fs, new String(nameAsArray)); key.signalEvent(kind, name); } // next event nextOffset = unsafe.getInt(address + OFFSETOF_NEXTENTRYOFFSET); address += (long)nextOffset; } while (nextOffset != 0); }
/** * Calls port_associate to register the given path. * Returns pointer to fileobj structure that is allocated for * the registration. */ long registerImpl(UnixPath dir, int events) throws UnixException { // allocate memory for the path (file_obj->fo_name field) byte[] path = dir.getByteArrayForSysCalls(); int len = path.length; long name = unsafe.allocateMemory(len+1); unsafe.copyMemory(path, Unsafe.ARRAY_BYTE_BASE_OFFSET, null, name, (long)len); unsafe.putByte(name + len, (byte)0); // allocate memory for filedatanode structure - this is the object // to port_associate long object = unsafe.allocateMemory(SIZEOF_FILEOBJ); unsafe.setMemory(null, object, SIZEOF_FILEOBJ, (byte)0); unsafe.putAddress(object + OFFSET_FO_NAME, name); // associate the object with the port try { portAssociate(port, PORT_SOURCE_FILE, object, events); } catch (UnixException x) { // debugging if (x.errno() == EAGAIN) { System.err.println("The maximum number of objects associated "+ "with the port has been reached"); } unsafe.freeMemory(name); unsafe.freeMemory(object); throw x; } return object; }
/** * Sets the serializable object fields of object obj using values from * array vals starting at offset 0. The caller is responsible for * ensuring that obj is of the proper type; however, attempts to set a * field with a value of the wrong type will trigger an appropriate * ClassCastException. */ public void setObjFieldValues(Object obj, Object[] vals) { if (obj == null) { throw new NullPointerException(); } for (int i = numPrimFields; i < fields.length; i++) { long key = writeKeys[i]; if (key == Unsafe.INVALID_FIELD_OFFSET) { continue; // discard value } switch (typeCodes[i]) { case 'L': case '[': Object val = vals[offsets[i]]; if (val != null && !types[i - numPrimFields].isInstance(val)) { Field f = fields[i].getField(); throw new ClassCastException( "cannot assign instance of " + val.getClass().getName() + " to field " + f.getDeclaringClass().getName() + "." + f.getName() + " of type " + f.getType().getName() + " in instance of " + obj.getClass().getName()); } unsafe.putObject(obj, key, val); break; default: throw new InternalError(); } } }
public static long test1Snippet(double a) { final Object m = Memory; if (a > 0) { UNSAFE.putDouble(m, (long) Unsafe.ARRAY_LONG_BASE_OFFSET, a); } else { SideEffectL = UNSAFE.getLong(m, (long) Unsafe.ARRAY_LONG_BASE_OFFSET); } return UNSAFE.getLong(m, (long) Unsafe.ARRAY_LONG_BASE_OFFSET); }
public static void recursiveLoopMethodUnsafeLoad(int a) { if (UNSAFE.getInt(Memory, (long) Unsafe.ARRAY_INT_BASE_OFFSET) == 0) { return; } for (int i = 0; i < a; i++) { recursiveLoopMethodUnsafeLoad(i); } }
@Test public void testGetAndSetInt() throws Exception { Foo f1 = new Foo(); Foo f2 = new Foo(); long offset = off(f1, "i"); Class<?>[] parameterTypes = new Class<?>[]{Object.class, long.class, int.class}; for (int delta = Integer.MAX_VALUE - 10; delta < Integer.MAX_VALUE; delta++) { Object[] args1 = new Object[]{f1, offset, delta}; Object[] args2 = new Object[]{f2, offset, delta}; testSubstitution("getAndSetInt", Unsafe.class, "getAndSetInt", parameterTypes, UNSAFE, args1, args2); } }
public static void main(String[] args) throws Exception { Class c = Test6968348.class.getClassLoader().loadClass("sun.misc.Unsafe"); Field f = c.getDeclaredField("theUnsafe"); f.setAccessible(true); unsafe = (Unsafe)f.get(c); array_long_base_offset = unsafe.arrayBaseOffset(long[].class); for (int n = 0; n < 100000; n++) { test(); } }
@SuppressWarnings("all") public static long unsafePutAddress(Unsafe unsafe, long offset, long value) { long res = 1; unsafe.putAddress(offset, value); res += unsafe.getAddress(offset); return res; }
private static Unsafe safetyDance() { try { Field f = Unsafe.class.getDeclaredField("theUnsafe"); f.setAccessible(true); return (Unsafe)f.get(null); } catch (Throwable e) { LOG.error("failed to load misc.Unsafe", e); } return null; }
/** * @return the operating system's page size. */ static long getOperatingSystemPageSize() { try { Field f = Unsafe.class.getDeclaredField("theUnsafe"); f.setAccessible(true); Unsafe unsafe = (Unsafe)f.get(null); return unsafe.pageSize(); } catch (Throwable e) { LOG.warn("Unable to get operating system page size. Guessing 4096.", e); return 4096; } }
public static void main(String[] args) throws Exception { Unsafe unsafe = getUnsafe(); testSetByteArray(unsafe); testSetRawMemory(unsafe); testCopyByteArrayToByteArray(unsafe); testCopyByteArrayToRawMemory(unsafe); testCopyRawMemoryToByteArray(unsafe); testCopyRawMemoryToRawMemory(unsafe); System.out.println("OK"); }