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
     {


Reply via email to