Dalvik SMP update

Fix some SMP correctness issues in the VM:

 - Correct AtomicCache implementation, inserting barriers where needed
   and correcting existing usage.
 - Emphasize that String startup isn't expected to be reentrant, and
   use atomic ops to ensure that we explode if anybody tries it.
 - Use 64-bit quasiatomic ops to manage the "last activity" timer in
   JDWP.  (Also, provide some documented but unimplemented behavior.)
 - Updated the volatile operations in sun.misc.Unsafe to include
   appropriate barriers.

(This does not purport to correct all SMP issues, just some of the
more obvious ones.)

Change-Id: I06957ebcf2724fe7a228b30d00194b9b4808fae0
diff --git a/vm/native/sun_misc_Unsafe.c b/vm/native/sun_misc_Unsafe.c
index 5294368..b3c7141 100644
--- a/vm/native/sun_misc_Unsafe.c
+++ b/vm/native/sun_misc_Unsafe.c
@@ -84,8 +84,8 @@
     s4 newValue = args[5];
     volatile int32_t* address = (volatile int32_t*) (((u1*) obj) + offset);
 
-    // Note: android_atomic_cmpxchg() returns 0 on success, not failure.
-    int result = android_atomic_cmpxchg(expectedValue, newValue, address);
+    // Note: android_atomic_release_cas() returns 0 on success, not failure.
+    int result = android_atomic_release_cas(expectedValue, newValue, address);
 
     RETURN_BOOLEAN(result == 0);
 }
@@ -126,7 +126,7 @@
     int32_t* address = (int32_t*) (((u1*) obj) + offset);
 
     // Note: android_atomic_cmpxchg() returns 0 on success, not failure.
-    int result = android_atomic_cmpxchg((int32_t) expectedValue,
+    int result = android_atomic_release_cas((int32_t) expectedValue,
             (int32_t) newValue, address);
 
     RETURN_BOOLEAN(result == 0);
@@ -141,9 +141,10 @@
     // We ignore the this pointer in args[0].
     Object* obj = (Object*) args[1];
     s8 offset = GET_ARG_LONG(args, 2);
-    volatile s4* address = (volatile s4*) (((u1*) obj) + offset);
+    volatile int32_t* address = (volatile int32_t*) (((u1*) obj) + offset);
 
-    RETURN_INT(*address);
+    int32_t value = android_atomic_acquire_load(address);
+    RETURN_INT(value);
 }
 
 /*
@@ -156,9 +157,9 @@
     Object* obj = (Object*) args[1];
     s8 offset = GET_ARG_LONG(args, 2);
     s4 value = (s4) args[4];
-    volatile s4* address = (volatile s4*) (((u1*) obj) + offset);
+    volatile int32_t* address = (volatile int32_t*) (((u1*) obj) + offset);
 
-    *address = value;
+    android_atomic_release_store(value, address);
     RETURN_VOID();
 }
 
@@ -171,7 +172,7 @@
     // We ignore the this pointer in args[0].
     Object* obj = (Object*) args[1];
     s8 offset = GET_ARG_LONG(args, 2);
-    volatile s8* address = (volatile s8*) (((u1*) obj) + offset);
+    volatile int64_t* address = (volatile int64_t*) (((u1*) obj) + offset);
 
     RETURN_LONG(dvmQuasiAtomicRead64(address));
 }
@@ -186,7 +187,7 @@
     Object* obj = (Object*) args[1];
     s8 offset = GET_ARG_LONG(args, 2);
     s8 value = GET_ARG_LONG(args, 4);
-    volatile s8* address = (volatile s8*) (((u1*) obj) + offset);
+    volatile int64_t* address = (volatile int64_t*) (((u1*) obj) + offset);
 
     dvmQuasiAtomicSwap64(value, address);
     RETURN_VOID();
@@ -201,9 +202,9 @@
     // We ignore the this pointer in args[0].
     Object* obj = (Object*) args[1];
     s8 offset = GET_ARG_LONG(args, 2);
-    volatile Object** address = (volatile Object**) (((u1*) obj) + offset);
+    volatile int32_t* address = (volatile int32_t*) (((u1*) obj) + offset);
 
-    RETURN_PTR((void*) *address);
+    RETURN_PTR((Object*) android_atomic_acquire_load(address));
 }
 
 /*
@@ -217,9 +218,9 @@
     Object* obj = (Object*) args[1];
     s8 offset = GET_ARG_LONG(args, 2);
     Object* value = (Object*) args[4];
-    volatile Object** address = (volatile Object**) (((u1*) obj) + offset);
+    volatile int32_t* address = (volatile int32_t*) (((u1*) obj) + offset);
 
-    *address = value;
+    android_atomic_release_store((int32_t)value, address);
     RETURN_VOID();
 }