From cc8ca5b6a5478b40546d4206392eb1471454460d Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Mon, 19 Sep 2016 13:45:07 -0700 Subject: Integrate internal changes --- .../main/java/com/google/protobuf/UnsafeUtil.java | 119 ++++++++++++++++++--- 1 file changed, 102 insertions(+), 17 deletions(-) (limited to 'java/core/src/main/java/com/google/protobuf/UnsafeUtil.java') diff --git a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java index 6a4787d1..5f7bafd6 100644 --- a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java +++ b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java @@ -30,17 +30,14 @@ package com.google.protobuf; -import sun.misc.Unsafe; - import java.lang.reflect.Field; import java.nio.Buffer; import java.nio.ByteBuffer; import java.security.AccessController; import java.security.PrivilegedExceptionAction; +import sun.misc.Unsafe; -/** - * Utility class for working with unsafe operations. - */ +/** Utility class for working with unsafe operations. */ // TODO(nathanmittler): Add support for Android Memory/MemoryBlock final class UnsafeUtil { private static final sun.misc.Unsafe UNSAFE = getUnsafe(); @@ -50,8 +47,7 @@ final class UnsafeUtil { private static final long ARRAY_BASE_OFFSET = byteArrayBaseOffset(); private static final long BUFFER_ADDRESS_OFFSET = fieldOffset(field(Buffer.class, "address")); - private UnsafeUtil() { - } + private UnsafeUtil() {} static boolean hasUnsafeArrayOperations() { return HAS_UNSAFE_ARRAY_OPERATIONS; @@ -61,27 +57,83 @@ final class UnsafeUtil { return HAS_UNSAFE_BYTEBUFFER_OPERATIONS; } + static Object allocateInstance(Class clazz) { + try { + return UNSAFE.allocateInstance(clazz); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } + } + + static long objectFieldOffset(Field field) { + return UNSAFE.objectFieldOffset(field); + } + static long getArrayBaseOffset() { return ARRAY_BASE_OFFSET; } - static byte getByte(byte[] target, long offset) { + static byte getByte(Object target, long offset) { return UNSAFE.getByte(target, offset); } - static void putByte(byte[] target, long offset, byte value) { + static void putByte(Object target, long offset, byte value) { UNSAFE.putByte(target, offset, value); } - static void copyMemory( - byte[] src, long srcOffset, byte[] target, long targetOffset, long length) { - UNSAFE.copyMemory(src, srcOffset, target, targetOffset, length); + static int getInt(Object target, long offset) { + return UNSAFE.getInt(target, offset); } - static long getLong(byte[] target, long offset) { + static void putInt(Object target, long offset, int value) { + UNSAFE.putInt(target, offset, value); + } + + static long getLong(Object target, long offset) { return UNSAFE.getLong(target, offset); } + static void putLong(Object target, long offset, long value) { + UNSAFE.putLong(target, offset, value); + } + + static boolean getBoolean(Object target, long offset) { + return UNSAFE.getBoolean(target, offset); + } + + static void putBoolean(Object target, long offset, boolean value) { + UNSAFE.putBoolean(target, offset, value); + } + + static float getFloat(Object target, long offset) { + return UNSAFE.getFloat(target, offset); + } + + static void putFloat(Object target, long offset, float value) { + UNSAFE.putFloat(target, offset, value); + } + + static double getDouble(Object target, long offset) { + return UNSAFE.getDouble(target, offset); + } + + static void putDouble(Object target, long offset, double value) { + UNSAFE.putDouble(target, offset, value); + } + + static Object getObject(Object target, long offset) { + return UNSAFE.getObject(target, offset); + } + + static void putObject(Object target, long offset, Object value) { + UNSAFE.putObject(target, offset, value); + } + + static void copyMemory( + Object src, long srcOffset, Object target, long targetOffset, long length) { + UNSAFE.copyMemory(src, srcOffset, target, targetOffset, length); + } + static byte getByte(long address) { return UNSAFE.getByte(address); } @@ -90,14 +142,30 @@ final class UnsafeUtil { UNSAFE.putByte(address, value); } + static int getInt(long address) { + return UNSAFE.getInt(address); + } + + static void putInt(long address, int value) { + UNSAFE.putInt(address, value); + } + static long getLong(long address) { return UNSAFE.getLong(address); } + static void putLong(long address, long value) { + UNSAFE.putLong(address, value); + } + static void copyMemory(long srcAddress, long targetAddress, long length) { UNSAFE.copyMemory(srcAddress, targetAddress, length); } + static void setMemory(long address, long numBytes, byte value) { + UNSAFE.setMemory(address, numBytes, value); + } + /** * Gets the offset of the {@code address} field of the given direct {@link ByteBuffer}. */ @@ -136,18 +204,29 @@ final class UnsafeUtil { return unsafe; } - /** - * Indicates whether or not unsafe array operations are supported on this platform. - */ + /** Indicates whether or not unsafe array operations are supported on this platform. */ private static boolean supportsUnsafeArrayOperations() { boolean supported = false; if (UNSAFE != null) { try { Class clazz = UNSAFE.getClass(); + clazz.getMethod("objectFieldOffset", Field.class); + clazz.getMethod("allocateInstance", Class.class); clazz.getMethod("arrayBaseOffset", Class.class); clazz.getMethod("getByte", Object.class, long.class); clazz.getMethod("putByte", Object.class, long.class, byte.class); + clazz.getMethod("getBoolean", Object.class, long.class); + clazz.getMethod("putBoolean", Object.class, long.class, boolean.class); + clazz.getMethod("getInt", Object.class, long.class); + clazz.getMethod("putInt", Object.class, long.class, int.class); clazz.getMethod("getLong", Object.class, long.class); + clazz.getMethod("putLong", Object.class, long.class, long.class); + clazz.getMethod("getFloat", Object.class, long.class); + clazz.getMethod("putFloat", Object.class, long.class, float.class); + clazz.getMethod("getDouble", Object.class, long.class); + clazz.getMethod("putDouble", Object.class, long.class, double.class); + clazz.getMethod("getObject", Object.class, long.class); + clazz.getMethod("putObject", Object.class, long.class, Object.class); clazz.getMethod( "copyMemory", Object.class, long.class, Object.class, long.class, long.class); supported = true; @@ -163,11 +242,17 @@ final class UnsafeUtil { if (UNSAFE != null) { try { Class clazz = UNSAFE.getClass(); + // Methods for getting direct buffer address. clazz.getMethod("objectFieldOffset", Field.class); - clazz.getMethod("getByte", long.class); clazz.getMethod("getLong", Object.class, long.class); + + clazz.getMethod("getByte", long.class); clazz.getMethod("putByte", long.class, byte.class); + clazz.getMethod("getInt", long.class); + clazz.getMethod("putInt", long.class, int.class); clazz.getMethod("getLong", long.class); + clazz.getMethod("putLong", long.class, long.class); + clazz.getMethod("setMemory", long.class, long.class, byte.class); clazz.getMethod("copyMemory", long.class, long.class, long.class); supported = true; } catch (Throwable e) { -- cgit v1.2.3