diff options
author | Dan Bornstein <danfuzz@android.com> | 2011-01-27 11:38:37 -0800 |
---|---|---|
committer | Dan Bornstein <danfuzz@android.com> | 2011-01-27 14:17:58 -0800 |
commit | 81058aaf92c188cc20273edd0275329fc304aca2 (patch) | |
tree | d87a7efd683aa1074f5338741ad93ee2b450dca6 | |
parent | 6ad1992b311937963d44be68f3ec0255a87d82b8 (diff) | |
download | dalvik-linaro_android_2.3.3.tar.gz |
Use bcopy() to move object refs around within an array. DO NOT MERGE.android-sdk-2.3.4_r1android-cts-2.3_r5android-cts-2.3_r4android-cts-2.3_r3android-cts-2.3_r2android-2.3.7_r1android-2.3.6_r1android-2.3.6_r0.9android-2.3.5_r1android-2.3.4_r1android-2.3.4_r0.9android-2.3.3_r1aandroid-2.3.3_r1.1android-2.3.3_r1linaro_android_2.3.3gingerbread-releasegingerbread-mr4-release
bcopy() guarantees that pointer-size words are stored atomically, and
so this prevents the gc from seeing a pointer in mid-change.
Bug: 3399673
Change-Id: Ic7d795e5d397548e9d6d8c11a585d86838cf8a44
-rw-r--r-- | vm/native/java_lang_System.c | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/vm/native/java_lang_System.c b/vm/native/java_lang_System.c index 96cc144a6..4af0dfa42 100644 --- a/vm/native/java_lang_System.c +++ b/vm/native/java_lang_System.c @@ -20,6 +20,33 @@ #include "Dalvik.h" #include "native/InternalNativePriv.h" +/* + * Call the appropriate copy function given the circumstances. + */ +static void copy(void *dest, const void *src, size_t n, bool sameArray, + size_t elemSize) +{ + if (sameArray) { + /* Might overlap. */ + if (elemSize == sizeof(Object*)) { + /* + * In addition to handling overlap properly, bcopy() + * guarantees atomic treatment of words. This is needed so + * that concurrent threads never see half-formed pointers + * or ints. The former is required for proper gc behavior, + * and the latter is also required for proper high-level + * language support. + * + * Note: bcopy()'s argument order is different than memcpy(). + */ + bcopy(src, dest, n); + } else { + memmove(dest, src, n); + } + } else { + memcpy(dest, src, n); /* Can't overlap; use faster function. */ + } +} /* * public static void arraycopy(Object src, int srcPos, Object dest, @@ -30,7 +57,6 @@ */ static void Dalvik_java_lang_System_arraycopy(const u4* args, JValue* pResult) { - void* (*copyFunc)(void *dest, const void *src, size_t n); ArrayObject* srcArray; ArrayObject* dstArray; ClassObject* srcClass; @@ -38,6 +64,7 @@ static void Dalvik_java_lang_System_arraycopy(const u4* args, JValue* pResult) int srcPos, dstPos, length; char srcType, dstType; bool srcPrim, dstPrim; + bool sameArray; srcArray = (ArrayObject*) args[0]; srcPos = args[1]; @@ -45,10 +72,7 @@ static void Dalvik_java_lang_System_arraycopy(const u4* args, JValue* pResult) dstPos = args[3]; length = args[4]; - if (srcArray == dstArray) - copyFunc = memmove; /* might overlap */ - else - copyFunc = memcpy; /* can't overlap, use faster func */ + sameArray = (srcArray == dstArray); /* check for null or bad pointer */ if (!dvmValidateObject((Object*)srcArray) || @@ -126,9 +150,10 @@ static void Dalvik_java_lang_System_arraycopy(const u4* args, JValue* pResult) dstArray->contents, dstPos * width, srcArray->contents, srcPos * width, length * width); - (*copyFunc)((u1*)dstArray->contents + dstPos * width, + copy((u1*)dstArray->contents + dstPos * width, (const u1*)srcArray->contents + srcPos * width, - length * width); + length * width, + sameArray, width); } else { /* * Neither class is primitive. See if elements in "src" are instances @@ -147,9 +172,10 @@ static void Dalvik_java_lang_System_arraycopy(const u4* args, JValue* pResult) dstArray->contents, dstPos * width, srcArray->contents, srcPos * width, length * width); - (*copyFunc)((u1*)dstArray->contents + dstPos * width, + copy((u1*)dstArray->contents + dstPos * width, (const u1*)srcArray->contents + srcPos * width, - length * width); + length * width, + sameArray, width); dvmWriteBarrierArray(dstArray, dstPos, dstPos+length); } else { /* @@ -194,9 +220,10 @@ static void Dalvik_java_lang_System_arraycopy(const u4* args, JValue* pResult) dstArray->contents, dstPos * width, srcArray->contents, srcPos * width, copyCount, length); - (*copyFunc)((u1*)dstArray->contents + dstPos * width, + copy((u1*)dstArray->contents + dstPos * width, (const u1*)srcArray->contents + srcPos * width, - copyCount * width); + copyCount * width, + sameArray, width); dvmWriteBarrierArray(dstArray, 0, copyCount); if (copyCount != length) { dvmThrowExceptionFmt("Ljava/lang/ArrayStoreException;", |