Author: mturk
Date: Mon Jul 18 18:36:29 2011
New Revision: 1147999
URL: http://svn.apache.org/viewvc?rev=1147999&view=rev
Log:
Add more unsafe object put/get wrappers
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Unsafe.java
commons/sandbox/runtime/trunk/src/main/native/shared/unsafe.c
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestUnsafe.java
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Unsafe.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Unsafe.java?rev=1147999&r1=1147998&r2=1147999&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Unsafe.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Unsafe.java
Mon Jul 18 18:36:29 2011
@@ -37,6 +37,9 @@ public final class Unsafe
private static native int getOffset1(Field f);
private static native int getBase0(Field f);
private static native Object getObject0(Object o, int off);
+ private static native Object getObject1(Object o, int off);
+ private static native void putObject0(Object o, int off, Object
v);
+ private static native void putObject1(Object o, int off, Object
v);
private static native int peek0(long ptr);
private static native long peek1(long ptr);
@@ -129,6 +132,59 @@ public final class Unsafe
return getObject0(o, offset);
}
+ /**
+ * Fetches a reference value from a given Java variable with volatile
+ * load semantics.
+ */
+ public static Object getObjectVolatile(Object o, int offset)
+ throws UnsupportedOperationException, IllegalArgumentException
+ {
+ if (unsafe == null)
+ throw new UnsupportedOperationException();
+ if (o == null || offset < 0)
+ throw new IllegalArgumentException();
+ return getObject0(o, offset);
+ }
+
+ /**
+ * Stores a reference value into a given Java variable.
+ * <p>
+ * Unless the reference {@code x} being stored is either null
+ * or matches the field type, the results are undefined.
+ * If the reference {@code o} is non-null, car marks or
+ * other store barriers for that object (if the VM requires them)
+ * are updated.
+ */
+ public static void putObject(Object o, int offset, Object x)
+ throws UnsupportedOperationException, IllegalArgumentException
+ {
+ if (unsafe == null)
+ throw new UnsupportedOperationException();
+ if (o == null || offset < 0)
+ throw new IllegalArgumentException();
+ putObject0(o, offset, x);
+ }
+
+ /**
+ * Stores a reference value into a given Java variable
+ * with a volatile sementics.
+ * <p>
+ * Unless the reference {@code x} being stored is either null
+ * or matches the field type, the results are undefined.
+ * If the reference {@code o} is non-null, car marks or
+ * other store barriers for that object (if the VM requires them)
+ * are updated.
+ */
+ public static void putObjectVolatile(Object o, int offset, Object x)
+ throws UnsupportedOperationException, IllegalArgumentException
+ {
+ if (unsafe == null)
+ throw new UnsupportedOperationException();
+ if (o == null || offset < 0)
+ throw new IllegalArgumentException();
+ putObject0(o, offset, x);
+ }
+
private static native char[] getchr0(String str);
/**
* Get the {@code str} private character array.
Modified: commons/sandbox/runtime/trunk/src/main/native/shared/unsafe.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/unsafe.c?rev=1147999&r1=1147998&r2=1147999&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/unsafe.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/unsafe.c Mon Jul 18
18:36:29 2011
@@ -43,29 +43,41 @@ J_DECLARE_M_ID(0000) = {
J_DECLARE_M_ID(0001) = {
0,
+ "getObjectVolatile",
+ "(Ljava/lang/Object;J)Ljava/lang/Object;"
+};
+
+J_DECLARE_M_ID(0002) = {
+ 0,
"putObject",
"(Ljava/lang/Object;JLjava/lang/Object;)V"
};
-J_DECLARE_M_ID(0002) = {
+J_DECLARE_M_ID(0003) = {
+ 0,
+ "putObjectVolatile",
+ "(Ljava/lang/Object;JLjava/lang/Object;)V"
+};
+
+
+J_DECLARE_M_ID(0004) = {
0,
"objectFieldOffset",
"(Ljava/lang/reflect/Field;)J"
};
-J_DECLARE_M_ID(0003) = {
+J_DECLARE_M_ID(0005) = {
0,
"staticFieldBase",
"(Ljava/lang/reflect/Field;)Ljava/lang/Object;"
};
-J_DECLARE_M_ID(0004) = {
+J_DECLARE_M_ID(0006) = {
0,
"staticFieldOffset",
"(Ljava/lang/reflect/Field;)J"
};
-
ACR_CLASS_CTOR(Unsafe)
{
if (AcrLoadClass(env, &_clazzn, 0) == JNI_FALSE)
@@ -77,6 +89,8 @@ ACR_CLASS_CTOR(Unsafe)
J_LOAD_METHOD(0002);
J_LOAD_METHOD(0003);
J_LOAD_METHOD(0004);
+ J_LOAD_METHOD(0005);
+ J_LOAD_METHOD(0006);
_clazzn.u = 1;
return JNI_TRUE;
@@ -111,7 +125,7 @@ AcrUnsafeObjectFieldOffset(JNI_STDARGS)
if (_get_unsafe(env) == 0) {
return INVALID_FIELD_OFFSET;
}
- fo = CALL_METHOD1(Long, 0002, _unsafe_instance, obj);
+ fo = CALL_METHOD1(Long, 0004, _unsafe_instance, obj);
if (fo > 0 && fo < INT_MAX)
return (jint)fo;
else
@@ -126,7 +140,7 @@ AcrUnsafeStaticFieldBase(JNI_STDARGS)
if (_get_unsafe(env) == 0) {
return INVALID_FIELD_OFFSET;
}
- fo = CALL_METHOD1(Long, 0003, _unsafe_instance, obj);
+ fo = CALL_METHOD1(Long, 0005, _unsafe_instance, obj);
if (fo > 0 && fo < INT_MAX)
return (jint)fo;
else
@@ -141,7 +155,7 @@ AcrUnsafeStaticFieldOffset(JNI_STDARGS)
if (_get_unsafe(env) == 0) {
return INVALID_FIELD_OFFSET;
}
- fo = CALL_METHOD1(Long, 0004, _unsafe_instance, obj);
+ fo = CALL_METHOD1(Long, 0006, _unsafe_instance, obj);
if (fo > 0 && fo < INT_MAX)
return (jint)fo;
else
@@ -205,7 +219,27 @@ ACR_JNI_EXPORT(jobject, Unsafe, getObjec
if (!CLAZZ_LOADED)
return 0;
else
- return CALL_METHOD2(Object, 0000, _unsafe_instance, o, off);
+ return CALL_METHOD2(Object, 0000, _unsafe_instance, o, (jlong)off);
+}
+
+ACR_JNI_EXPORT(jobject, Unsafe, getObject1)(JNI_STDARGS, jobject o, jint off)
+{
+ if (!CLAZZ_LOADED)
+ return 0;
+ else
+ return CALL_METHOD2(Object, 0001, _unsafe_instance, o, P2J(off));
+}
+
+ACR_JNI_EXPORT(void, Unsafe, putObject0)(JNI_STDARGS, jobject o, jint off,
jobject v)
+{
+ if (CLAZZ_LOADED)
+ CALL_VMETHOD3(0002, _unsafe_instance, o, P2J(off), v);
+}
+
+ACR_JNI_EXPORT(void, Unsafe, putObject1)(JNI_STDARGS, jobject o, jint off,
jobject v)
+{
+ if (CLAZZ_LOADED)
+ CALL_VMETHOD3(0003, _unsafe_instance, o, P2J(off), v);
}
ACR_JNI_EXPORT(jint, Unsafe, peek0)(JNI_STDARGS, jlong ptr)
Modified:
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestUnsafe.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestUnsafe.java?rev=1147999&r1=1147998&r2=1147999&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestUnsafe.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestUnsafe.java
Mon Jul 18 18:36:29 2011
@@ -26,6 +26,7 @@ public class TestUnsafe extends Assert
{
private int i = 12345;
private String s = "hello world";
+ private static String S = "hello world";
private static native int test0(Object o, int off);
private static native Object test1(Object o, int off);
@@ -63,6 +64,23 @@ public class TestUnsafe extends Assert
}
@Test(groups = { "private" })
+ public void getDirectObjectVolatile()
+ throws Exception
+ {
+ int off =
Unsafe.objectFieldOffset(TestUnsafe.class.getDeclaredField("s"));
+ assertEquals((String)Unsafe.getObjectVolatile(this, off), "hello
world");
+ }
+
+ @Test(groups = { "private" })
+ public void putDirectObject()
+ throws Exception
+ {
+ int off =
Unsafe.objectFieldOffset(TestUnsafe.class.getDeclaredField("s"));
+ Unsafe.putObject(this, off, "HELLO WORLD");
+ assertEquals(s, "HELLO WORLD");
+ }
+
+ @Test(groups = { "private" })
public void nativeFileDescriptor()
throws Exception
{