Merge "Update to allow x86-atom build for FI on Gingerbread"
diff --git a/libdex/CmdUtils.c b/libdex/CmdUtils.c
index 35696f9..8ce0d4b 100644
--- a/libdex/CmdUtils.c
+++ b/libdex/CmdUtils.c
@@ -160,7 +160,7 @@
/*
* Pop open the (presumed) DEX file.
*/
- fd = open(fileName, O_RDONLY);
+ fd = open(fileName, O_RDONLY | O_BINARY);
if (fd < 0) {
if (!quiet) {
fprintf(stderr, "ERROR: unable to open '%s': %s\n",
diff --git a/libdex/ZipArchive.c b/libdex/ZipArchive.c
index 756f488..efe9f79 100644
--- a/libdex/ZipArchive.c
+++ b/libdex/ZipArchive.c
@@ -341,7 +341,7 @@
memset(pArchive, 0, sizeof(ZipArchive));
- fd = open(fileName, O_RDONLY, 0);
+ fd = open(fileName, O_RDONLY | O_BINARY, 0);
if (fd < 0) {
err = errno ? errno : -1;
LOGV("Unable to open '%s': %s\n", fileName, strerror(err));
diff --git a/vm/alloc/Alloc.c b/vm/alloc/Alloc.c
index 4dcd91c..7b56a35 100644
--- a/vm/alloc/Alloc.c
+++ b/vm/alloc/Alloc.c
@@ -305,11 +305,11 @@
typedef struct {
const ClassObject *clazz;
size_t count;
-} CountInstancesOfClassContext;
+} CountContext;
static void countInstancesOfClassCallback(void *ptr, void *arg)
{
- CountInstancesOfClassContext *ctx = arg;
+ CountContext *ctx = arg;
const Object *obj = ptr;
assert(ctx != NULL);
@@ -320,10 +320,31 @@
size_t dvmCountInstancesOfClass(const ClassObject *clazz)
{
- CountInstancesOfClassContext ctx = { clazz, 0 };
+ CountContext ctx = { clazz, 0 };
HeapBitmap *bitmap = dvmHeapSourceGetLiveBits();
dvmLockHeap();
dvmHeapBitmapWalk(bitmap, countInstancesOfClassCallback, &ctx);
dvmUnlockHeap();
return ctx.count;
}
+
+static void countAssignableInstancesOfClassCallback(void *ptr, void *arg)
+{
+ CountContext *ctx = arg;
+ const Object *obj = ptr;
+
+ assert(ctx != NULL);
+ if (dvmInstanceof(obj->clazz, ctx->clazz)) {
+ ctx->count += 1;
+ }
+}
+
+size_t dvmCountAssignableInstancesOfClass(const ClassObject *clazz)
+{
+ CountContext ctx = { clazz, 0 };
+ HeapBitmap *bitmap = dvmHeapSourceGetLiveBits();
+ dvmLockHeap();
+ dvmHeapBitmapWalk(bitmap, countAssignableInstancesOfClassCallback, &ctx);
+ dvmUnlockHeap();
+ return ctx.count;
+}
diff --git a/vm/alloc/Alloc.h b/vm/alloc/Alloc.h
index aeed9c3..fd9c633 100644
--- a/vm/alloc/Alloc.h
+++ b/vm/alloc/Alloc.h
@@ -180,8 +180,13 @@
size_t dvmGetExternalBytesAllocated(void);
/*
- * Returns a count of the extant instances of a class.
+ * Returns a count of the direct instances of a class.
*/
size_t dvmCountInstancesOfClass(const ClassObject *clazz);
+/*
+ * Returns a count of the instances of a class and its subclasses.
+ */
+size_t dvmCountAssignableInstancesOfClass(const ClassObject *clazz);
+
#endif /*_DALVIK_ALLOC_ALLOC*/
diff --git a/vm/alloc/MarkSweep.c b/vm/alloc/MarkSweep.c
index bde1b49..62a4ccc 100644
--- a/vm/alloc/MarkSweep.c
+++ b/vm/alloc/MarkSweep.c
@@ -722,7 +722,10 @@
while (*list != NULL) {
ref = dequeuePendingReference(list);
referent = dvmGetFieldObject(ref, referentOffset);
- assert(referent != NULL);
+ if (referent == NULL) {
+ /* Referent was cleared by the user during marking. */
+ continue;
+ }
marked = isMarked(referent, ctx);
if (!marked && ((++counter) & 1)) {
/* Referent is white and biased toward saving, mark it. */
@@ -760,8 +763,7 @@
while (*list != NULL) {
ref = dequeuePendingReference(list);
referent = dvmGetFieldObject(ref, referentOffset);
- assert(referent != NULL);
- if (!isMarked(referent, ctx)) {
+ if (referent != NULL && !isMarked(referent, ctx)) {
/* Referent is white, clear it. */
clearReference(ref);
if (isEnqueuable(ref)) {
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c
index 657533b..011679b 100644
--- a/vm/compiler/codegen/arm/CodegenDriver.c
+++ b/vm/compiler/codegen/arm/CodegenDriver.c
@@ -1219,7 +1219,6 @@
/* r0 = dalvik pc */
dvmCompilerFlushAllRegs(cUnit);
loadConstant(cUnit, r0, (int) (cUnit->method->insns + offset));
- loadWordDisp(cUnit, r0, offsetof(Object, clazz), r3);
loadWordDisp(cUnit, rGLUE, offsetof(InterpState,
jitToInterpEntries.dvmJitToInterpPunt), r1);
opReg(cUnit, kOpBlx, r1);
diff --git a/vm/native/dalvik_system_VMDebug.c b/vm/native/dalvik_system_VMDebug.c
index b9f3610..192a8f2 100644
--- a/vm/native/dalvik_system_VMDebug.c
+++ b/vm/native/dalvik_system_VMDebug.c
@@ -889,8 +889,13 @@
JValue* pResult)
{
ClassObject* clazz = (ClassObject*)args[0];
+ bool countAssignable = args[1];
if (clazz == NULL) {
RETURN_LONG(0);
+ }
+ if (countAssignable) {
+ size_t count = dvmCountAssignableInstancesOfClass(clazz);
+ RETURN_LONG((long long)count);
} else {
size_t count = dvmCountInstancesOfClass(clazz);
RETURN_LONG((long long)count);
@@ -954,7 +959,7 @@
Dalvik_dalvik_system_VMDebug_crash },
{ "infopoint", "(I)V",
Dalvik_dalvik_system_VMDebug_infopoint },
- { "countInstancesOfClass", "(Ljava/lang/Class;)J",
+ { "countInstancesOfClass", "(Ljava/lang/Class;Z)J",
Dalvik_dalvik_system_VMDebug_countInstancesOfClass },
{ NULL, NULL, NULL },
};
diff --git a/vm/native/java_lang_System.c b/vm/native/java_lang_System.c
index 96cc144..4af0dfa 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 @@
int srcPos, dstPos, length;
char srcType, dstType;
bool srcPrim, dstPrim;
+ bool sameArray;
srcArray = (ArrayObject*) args[0];
srcPos = args[1];
@@ -45,10 +72,7 @@
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 @@
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 @@
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 @@
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;",