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();
}