merge from open-source master
diff --git a/vm/alloc/HeapSource.c b/vm/alloc/HeapSource.c
index d97290f..830e5d7 100644
--- a/vm/alloc/HeapSource.c
+++ b/vm/alloc/HeapSource.c
@@ -787,6 +787,82 @@
}
/*
+ * Frees the first numPtrs objects in the ptrs list. The list must
+ * contain addresses all in the same mspace, and must be in increasing
+ * order. This implies that there are no duplicates, and no entries
+ * are NULL.
+ */
+void
+dvmHeapSourceFreeList(size_t numPtrs, void **ptrs)
+{
+ Heap *heap;
+
+ HS_BOILERPLATE();
+
+ if (numPtrs == 0) {
+ return;
+ }
+
+ assert(ptrs != NULL);
+ assert(*ptrs != NULL);
+ heap = ptr2heap(gHs, *ptrs);
+ if (heap != NULL) {
+ mspace *msp = heap->msp;
+ // Calling mspace_free on shared heaps disrupts sharing too
+ // much. For heap[0] -- the 'active heap' -- we call
+ // mspace_free, but on the other heaps we only do some
+ // accounting.
+ if (heap == gHs->heaps) {
+ // mspace_merge_objects takes two allocated objects, and
+ // if the second immediately follows the first, will merge
+ // them, returning a larger object occupying the same
+ // memory. This is a local operation, and doesn't require
+ // dlmalloc to manipulate any freelists. It's pretty
+ // inexpensive compared to free().
+
+ // ptrs is an array of objects all in memory order, and if
+ // client code has been allocating lots of short-lived
+ // objects, this is likely to contain runs of objects all
+ // now garbage, and thus highly amenable to this optimization.
+
+ // Unroll the 0th iteration around the loop below,
+ // countFree ptrs[0] and initializing merged.
+ assert(ptrs[0] != NULL);
+ assert(ptr2heap(gHs, ptrs[0]) == heap);
+ countFree(heap, ptrs[0], true);
+ void *merged = ptrs[0];
+
+ size_t i;
+ for (i = 1; i < numPtrs; i++) {
+ assert(merged != NULL);
+ assert(ptrs[i] != NULL);
+ assert((intptr_t)merged < (intptr_t)ptrs[i]);
+ assert(ptr2heap(gHs, ptrs[i]) == heap);
+ countFree(heap, ptrs[i], true);
+ // Try to merge. If it works, merged now includes the
+ // memory of ptrs[i]. If it doesn't, free merged, and
+ // see if ptrs[i] starts a new run of adjacent
+ // objects to merge.
+ if (mspace_merge_objects(msp, merged, ptrs[i]) == NULL) {
+ mspace_free(msp, merged);
+ merged = ptrs[i];
+ }
+ }
+ assert(merged != NULL);
+ mspace_free(msp, merged);
+ } else {
+ // This is not an 'active heap'. Only do the accounting.
+ size_t i;
+ for (i = 0; i < numPtrs; i++) {
+ assert(ptrs[i] != NULL);
+ assert(ptr2heap(gHs, ptrs[i]) == heap);
+ countFree(heap, ptrs[i], true);
+ }
+ }
+ }
+}
+
+/*
* Returns true iff <ptr> was allocated from the heap source.
*/
bool
diff --git a/vm/alloc/HeapSource.h b/vm/alloc/HeapSource.h
index 3007d4f..fdaf119 100644
--- a/vm/alloc/HeapSource.h
+++ b/vm/alloc/HeapSource.h
@@ -105,6 +105,14 @@
void dvmHeapSourceFree(void *ptr);
/*
+ * Frees the first numPtrs objects in the ptrs list. The list must
+ * contain addresses all in the same mspace, and must be in increasing
+ * order. This implies that there are no duplicates, and no entries
+ * are NULL.
+ */
+void dvmHeapSourceFreeList(size_t numPtrs, void **ptrs);
+
+/*
* Returns true iff <ptr> was allocated from the heap source.
*/
bool dvmHeapSourceContains(const void *ptr);
diff --git a/vm/alloc/MarkSweep.c b/vm/alloc/MarkSweep.c
index b8da3a3..09cc25f 100644
--- a/vm/alloc/MarkSweep.c
+++ b/vm/alloc/MarkSweep.c
@@ -15,6 +15,7 @@
*/
#include "Dalvik.h"
+#include "alloc/clz.h"
#include "alloc/HeapBitmap.h"
#include "alloc/HeapInternal.h"
#include "alloc/HeapSource.h"
@@ -435,30 +436,39 @@
static void scanInstanceFields(const DataObject *obj, ClassObject *clazz,
GcMarkContext *ctx)
{
-//TODO: Optimize this by avoiding walking the superclass chain
- while (clazz != NULL) {
- InstField *f;
- int i;
-
- /* All of the fields that contain object references
- * are guaranteed to be at the beginning of the ifields list.
- */
- f = clazz->ifields;
- for (i = 0; i < clazz->ifieldRefCount; i++) {
- /* Mark the array or object reference.
- * May be NULL.
- *
- * Note that, per the comment on struct InstField,
- * f->byteOffset is the offset from the beginning of
- * obj, not the offset into obj->instanceData.
- */
- markObject(dvmGetFieldObject((Object*)obj, f->byteOffset), ctx);
- f++;
+ if (false && clazz->refOffsets != CLASS_WALK_SUPER) {
+ unsigned int refOffsets = clazz->refOffsets;
+ while (refOffsets != 0) {
+ const int rshift = CLZ(refOffsets);
+ refOffsets &= ~(CLASS_HIGH_BIT >> rshift);
+ markObject(dvmGetFieldObject((Object*)obj,
+ CLASS_OFFSET_FROM_CLZ(rshift)), ctx);
}
+ } else {
+ while (clazz != NULL) {
+ InstField *f;
+ int i;
- /* This will be NULL when we hit java.lang.Object
- */
- clazz = clazz->super;
+ /* All of the fields that contain object references
+ * are guaranteed to be at the beginning of the ifields list.
+ */
+ f = clazz->ifields;
+ for (i = 0; i < clazz->ifieldRefCount; i++) {
+ /* Mark the array or object reference.
+ * May be NULL.
+ *
+ * Note that, per the comment on struct InstField,
+ * f->byteOffset is the offset from the beginning of
+ * obj, not the offset into obj->instanceData.
+ */
+ markObject(dvmGetFieldObject((Object*)obj, f->byteOffset), ctx);
+ f++;
+ }
+
+ /* This will be NULL when we hit java.lang.Object
+ */
+ clazz = clazz->super;
+ }
}
}
@@ -1203,6 +1213,7 @@
{
const ClassObject *const classJavaLangClass = gDvm.classJavaLangClass;
size_t i;
+ void **origPtrs = ptrs;
for (i = 0; i < numPtrs; i++) {
DvmHeapChunk *hc;
@@ -1265,11 +1276,10 @@
#endif
}
#endif
-
-//TODO: provide a heapsource function that takes a list of pointers to free
-// and call it outside of this loop.
- dvmHeapSourceFree(hc);
}
+ // TODO: dvmHeapSourceFreeList has a loop, just like the above
+ // does. Consider collapsing the two loops to save overhead.
+ dvmHeapSourceFreeList(numPtrs, origPtrs);
return true;
}
diff --git a/vm/mterp/armv5te/debug.c b/vm/mterp/armv5te/debug.c
index 400bc95..9d7413c 100644
--- a/vm/mterp/armv5te/debug.c
+++ b/vm/mterp/armv5te/debug.c
@@ -29,7 +29,7 @@
const Method* method = glue->method;
printf(" + self is %p\n", dvmThreadSelf());
//printf(" + currently in %s.%s %s\n",
- // method->clazz->descriptor, method->name, method->signature);
+ // method->clazz->descriptor, method->name, method->shorty);
//printf(" + dvmAsmInstructionStart = %p\n", dvmAsmInstructionStart);
//printf(" + next handler for 0x%02x = %p\n",
// rINST & 0xff, dvmAsmInstructionStart + (rINST & 0xff) * 64);
diff --git a/vm/mterp/c/gotoTargets.c b/vm/mterp/c/gotoTargets.c
index 37eaa20..5997c35 100644
--- a/vm/mterp/c/gotoTargets.c
+++ b/vm/mterp/c/gotoTargets.c
@@ -514,7 +514,7 @@
ILOGV("> retval=0x%llx (leaving %s.%s %s)",
retval.j, curMethod->clazz->descriptor, curMethod->name,
- curMethod->signature);
+ curMethod->shorty);
//DUMP_REGS(curMethod, fp);
saveArea = SAVEAREA_FROM_FP(fp);
@@ -542,7 +542,7 @@
methodClassDex = curMethod->clazz->pDvmDex;
pc = saveArea->savedPc;
ILOGD("> (return to %s.%s %s)", curMethod->clazz->descriptor,
- curMethod->name, curMethod->signature);
+ curMethod->name, curMethod->shorty);
/* use FINISH on the caller's invoke instruction */
//u2 invokeInstr = INST_INST(FETCH(0));
@@ -677,7 +677,7 @@
methodClassDex = curMethod->clazz->pDvmDex;
pc = curMethod->insns + catchRelPc;
ILOGV("> pc <-- %s.%s %s", curMethod->clazz->descriptor,
- curMethod->name, curMethod->signature);
+ curMethod->name, curMethod->shorty);
DUMP_REGS(curMethod, fp, false); // show all regs
/*
@@ -726,7 +726,7 @@
//printf("range=%d call=%p count=%d regs=0x%04x\n",
// methodCallRange, methodToCall, count, regs);
//printf(" --> %s.%s %s\n", methodToCall->clazz->descriptor,
- // methodToCall->name, methodToCall->signature);
+ // methodToCall->name, methodToCall->shorty);
u4* outs;
int i;
@@ -796,7 +796,7 @@
ILOGV("> %s%s.%s %s",
dvmIsNativeMethod(methodToCall) ? "(NATIVE) " : "",
methodToCall->clazz->descriptor, methodToCall->name,
- methodToCall->signature);
+ methodToCall->shorty);
newFp = (u4*) SAVEAREA_FROM_FP(fp) - methodToCall->registersSize;
newSaveArea = SAVEAREA_FROM_FP(newFp);
@@ -857,7 +857,7 @@
debugIsMethodEntry = true; // profiling, debugging
#endif
ILOGD("> pc <-- %s.%s %s", curMethod->clazz->descriptor,
- curMethod->name, curMethod->signature);
+ curMethod->name, curMethod->shorty);
DUMP_REGS(curMethod, fp, true); // show input args
FINISH(0); // jump to method start
} else {
@@ -879,7 +879,7 @@
#endif
ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor,
- methodToCall->name, methodToCall->signature);
+ methodToCall->name, methodToCall->shorty);
/*
* Jump through native call bridge. Because we leave no
@@ -916,7 +916,7 @@
ILOGD("> (return from native %s.%s to %s.%s %s)",
methodToCall->clazz->descriptor, methodToCall->name,
curMethod->clazz->descriptor, curMethod->name,
- curMethod->signature);
+ curMethod->shorty);
//u2 invokeInstr = INST_INST(FETCH(0));
if (true /*invokeInstr >= OP_INVOKE_VIRTUAL &&
diff --git a/vm/mterp/out/InterpC-allstubs.c b/vm/mterp/out/InterpC-allstubs.c
index 0769eeb..bb1d0ea 100644
--- a/vm/mterp/out/InterpC-allstubs.c
+++ b/vm/mterp/out/InterpC-allstubs.c
@@ -3547,7 +3547,7 @@
ILOGV("> retval=0x%llx (leaving %s.%s %s)",
retval.j, curMethod->clazz->descriptor, curMethod->name,
- curMethod->signature);
+ curMethod->shorty);
//DUMP_REGS(curMethod, fp);
saveArea = SAVEAREA_FROM_FP(fp);
@@ -3575,7 +3575,7 @@
methodClassDex = curMethod->clazz->pDvmDex;
pc = saveArea->savedPc;
ILOGD("> (return to %s.%s %s)", curMethod->clazz->descriptor,
- curMethod->name, curMethod->signature);
+ curMethod->name, curMethod->shorty);
/* use FINISH on the caller's invoke instruction */
//u2 invokeInstr = INST_INST(FETCH(0));
@@ -3710,7 +3710,7 @@
methodClassDex = curMethod->clazz->pDvmDex;
pc = curMethod->insns + catchRelPc;
ILOGV("> pc <-- %s.%s %s", curMethod->clazz->descriptor,
- curMethod->name, curMethod->signature);
+ curMethod->name, curMethod->shorty);
DUMP_REGS(curMethod, fp, false); // show all regs
/*
@@ -3759,7 +3759,7 @@
//printf("range=%d call=%p count=%d regs=0x%04x\n",
// methodCallRange, methodToCall, count, regs);
//printf(" --> %s.%s %s\n", methodToCall->clazz->descriptor,
- // methodToCall->name, methodToCall->signature);
+ // methodToCall->name, methodToCall->shorty);
u4* outs;
int i;
@@ -3829,7 +3829,7 @@
ILOGV("> %s%s.%s %s",
dvmIsNativeMethod(methodToCall) ? "(NATIVE) " : "",
methodToCall->clazz->descriptor, methodToCall->name,
- methodToCall->signature);
+ methodToCall->shorty);
newFp = (u4*) SAVEAREA_FROM_FP(fp) - methodToCall->registersSize;
newSaveArea = SAVEAREA_FROM_FP(newFp);
@@ -3890,7 +3890,7 @@
debugIsMethodEntry = true; // profiling, debugging
#endif
ILOGD("> pc <-- %s.%s %s", curMethod->clazz->descriptor,
- curMethod->name, curMethod->signature);
+ curMethod->name, curMethod->shorty);
DUMP_REGS(curMethod, fp, true); // show input args
FINISH(0); // jump to method start
} else {
@@ -3912,7 +3912,7 @@
#endif
ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor,
- methodToCall->name, methodToCall->signature);
+ methodToCall->name, methodToCall->shorty);
/*
* Jump through native call bridge. Because we leave no
@@ -3949,7 +3949,7 @@
ILOGD("> (return from native %s.%s to %s.%s %s)",
methodToCall->clazz->descriptor, methodToCall->name,
curMethod->clazz->descriptor, curMethod->name,
- curMethod->signature);
+ curMethod->shorty);
//u2 invokeInstr = INST_INST(FETCH(0));
if (true /*invokeInstr >= OP_INVOKE_VIRTUAL &&
diff --git a/vm/mterp/out/InterpC-armv4t.c b/vm/mterp/out/InterpC-armv4t.c
index bdfffe3..6b82bc8 100644
--- a/vm/mterp/out/InterpC-armv4t.c
+++ b/vm/mterp/out/InterpC-armv4t.c
@@ -1228,7 +1228,7 @@
const Method* method = glue->method;
printf(" + self is %p\n", dvmThreadSelf());
//printf(" + currently in %s.%s %s\n",
- // method->clazz->descriptor, method->name, method->signature);
+ // method->clazz->descriptor, method->name, method->shorty);
//printf(" + dvmAsmInstructionStart = %p\n", dvmAsmInstructionStart);
//printf(" + next handler for 0x%02x = %p\n",
// rINST & 0xff, dvmAsmInstructionStart + (rINST & 0xff) * 64);
diff --git a/vm/mterp/out/InterpC-armv5te-vfp.c b/vm/mterp/out/InterpC-armv5te-vfp.c
index 7840920..7312700 100644
--- a/vm/mterp/out/InterpC-armv5te-vfp.c
+++ b/vm/mterp/out/InterpC-armv5te-vfp.c
@@ -1228,7 +1228,7 @@
const Method* method = glue->method;
printf(" + self is %p\n", dvmThreadSelf());
//printf(" + currently in %s.%s %s\n",
- // method->clazz->descriptor, method->name, method->signature);
+ // method->clazz->descriptor, method->name, method->shorty);
//printf(" + dvmAsmInstructionStart = %p\n", dvmAsmInstructionStart);
//printf(" + next handler for 0x%02x = %p\n",
// rINST & 0xff, dvmAsmInstructionStart + (rINST & 0xff) * 64);
diff --git a/vm/mterp/out/InterpC-armv5te.c b/vm/mterp/out/InterpC-armv5te.c
index 4849423..ea11551 100644
--- a/vm/mterp/out/InterpC-armv5te.c
+++ b/vm/mterp/out/InterpC-armv5te.c
@@ -1228,7 +1228,7 @@
const Method* method = glue->method;
printf(" + self is %p\n", dvmThreadSelf());
//printf(" + currently in %s.%s %s\n",
- // method->clazz->descriptor, method->name, method->signature);
+ // method->clazz->descriptor, method->name, method->shorty);
//printf(" + dvmAsmInstructionStart = %p\n", dvmAsmInstructionStart);
//printf(" + next handler for 0x%02x = %p\n",
// rINST & 0xff, dvmAsmInstructionStart + (rINST & 0xff) * 64);
diff --git a/vm/mterp/out/InterpC-armv7-a.c b/vm/mterp/out/InterpC-armv7-a.c
index a4413bb..97799ec 100644
--- a/vm/mterp/out/InterpC-armv7-a.c
+++ b/vm/mterp/out/InterpC-armv7-a.c
@@ -1228,7 +1228,7 @@
const Method* method = glue->method;
printf(" + self is %p\n", dvmThreadSelf());
//printf(" + currently in %s.%s %s\n",
- // method->clazz->descriptor, method->name, method->signature);
+ // method->clazz->descriptor, method->name, method->shorty);
//printf(" + dvmAsmInstructionStart = %p\n", dvmAsmInstructionStart);
//printf(" + next handler for 0x%02x = %p\n",
// rINST & 0xff, dvmAsmInstructionStart + (rINST & 0xff) * 64);
diff --git a/vm/mterp/out/InterpC-portdbg.c b/vm/mterp/out/InterpC-portdbg.c
index c8f428c..90b2a75 100644
--- a/vm/mterp/out/InterpC-portdbg.c
+++ b/vm/mterp/out/InterpC-portdbg.c
@@ -1395,7 +1395,7 @@
if (/*gDvm.debuggerActive &&*/
strcmp(method->clazz->descriptor, cd) == 0 &&
strcmp(method->name, mn) == 0 &&
- strcmp(method->signature, sg) == 0)
+ strcmp(method->shorty, sg) == 0)
{
LOGW("Reached %s.%s, enabling verbose mode\n",
method->clazz->descriptor, method->name);
@@ -3838,7 +3838,7 @@
ILOGV("> retval=0x%llx (leaving %s.%s %s)",
retval.j, curMethod->clazz->descriptor, curMethod->name,
- curMethod->signature);
+ curMethod->shorty);
//DUMP_REGS(curMethod, fp);
saveArea = SAVEAREA_FROM_FP(fp);
@@ -3866,7 +3866,7 @@
methodClassDex = curMethod->clazz->pDvmDex;
pc = saveArea->savedPc;
ILOGD("> (return to %s.%s %s)", curMethod->clazz->descriptor,
- curMethod->name, curMethod->signature);
+ curMethod->name, curMethod->shorty);
/* use FINISH on the caller's invoke instruction */
//u2 invokeInstr = INST_INST(FETCH(0));
@@ -4001,7 +4001,7 @@
methodClassDex = curMethod->clazz->pDvmDex;
pc = curMethod->insns + catchRelPc;
ILOGV("> pc <-- %s.%s %s", curMethod->clazz->descriptor,
- curMethod->name, curMethod->signature);
+ curMethod->name, curMethod->shorty);
DUMP_REGS(curMethod, fp, false); // show all regs
/*
@@ -4050,7 +4050,7 @@
//printf("range=%d call=%p count=%d regs=0x%04x\n",
// methodCallRange, methodToCall, count, regs);
//printf(" --> %s.%s %s\n", methodToCall->clazz->descriptor,
- // methodToCall->name, methodToCall->signature);
+ // methodToCall->name, methodToCall->shorty);
u4* outs;
int i;
@@ -4120,7 +4120,7 @@
ILOGV("> %s%s.%s %s",
dvmIsNativeMethod(methodToCall) ? "(NATIVE) " : "",
methodToCall->clazz->descriptor, methodToCall->name,
- methodToCall->signature);
+ methodToCall->shorty);
newFp = (u4*) SAVEAREA_FROM_FP(fp) - methodToCall->registersSize;
newSaveArea = SAVEAREA_FROM_FP(newFp);
@@ -4181,7 +4181,7 @@
debugIsMethodEntry = true; // profiling, debugging
#endif
ILOGD("> pc <-- %s.%s %s", curMethod->clazz->descriptor,
- curMethod->name, curMethod->signature);
+ curMethod->name, curMethod->shorty);
DUMP_REGS(curMethod, fp, true); // show input args
FINISH(0); // jump to method start
} else {
@@ -4203,7 +4203,7 @@
#endif
ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor,
- methodToCall->name, methodToCall->signature);
+ methodToCall->name, methodToCall->shorty);
/*
* Jump through native call bridge. Because we leave no
@@ -4240,7 +4240,7 @@
ILOGD("> (return from native %s.%s to %s.%s %s)",
methodToCall->clazz->descriptor, methodToCall->name,
curMethod->clazz->descriptor, curMethod->name,
- curMethod->signature);
+ curMethod->shorty);
//u2 invokeInstr = INST_INST(FETCH(0));
if (true /*invokeInstr >= OP_INVOKE_VIRTUAL &&
diff --git a/vm/mterp/out/InterpC-portstd.c b/vm/mterp/out/InterpC-portstd.c
index baf7a86..c28bf5b 100644
--- a/vm/mterp/out/InterpC-portstd.c
+++ b/vm/mterp/out/InterpC-portstd.c
@@ -3552,7 +3552,7 @@
ILOGV("> retval=0x%llx (leaving %s.%s %s)",
retval.j, curMethod->clazz->descriptor, curMethod->name,
- curMethod->signature);
+ curMethod->shorty);
//DUMP_REGS(curMethod, fp);
saveArea = SAVEAREA_FROM_FP(fp);
@@ -3580,7 +3580,7 @@
methodClassDex = curMethod->clazz->pDvmDex;
pc = saveArea->savedPc;
ILOGD("> (return to %s.%s %s)", curMethod->clazz->descriptor,
- curMethod->name, curMethod->signature);
+ curMethod->name, curMethod->shorty);
/* use FINISH on the caller's invoke instruction */
//u2 invokeInstr = INST_INST(FETCH(0));
@@ -3715,7 +3715,7 @@
methodClassDex = curMethod->clazz->pDvmDex;
pc = curMethod->insns + catchRelPc;
ILOGV("> pc <-- %s.%s %s", curMethod->clazz->descriptor,
- curMethod->name, curMethod->signature);
+ curMethod->name, curMethod->shorty);
DUMP_REGS(curMethod, fp, false); // show all regs
/*
@@ -3764,7 +3764,7 @@
//printf("range=%d call=%p count=%d regs=0x%04x\n",
// methodCallRange, methodToCall, count, regs);
//printf(" --> %s.%s %s\n", methodToCall->clazz->descriptor,
- // methodToCall->name, methodToCall->signature);
+ // methodToCall->name, methodToCall->shorty);
u4* outs;
int i;
@@ -3834,7 +3834,7 @@
ILOGV("> %s%s.%s %s",
dvmIsNativeMethod(methodToCall) ? "(NATIVE) " : "",
methodToCall->clazz->descriptor, methodToCall->name,
- methodToCall->signature);
+ methodToCall->shorty);
newFp = (u4*) SAVEAREA_FROM_FP(fp) - methodToCall->registersSize;
newSaveArea = SAVEAREA_FROM_FP(newFp);
@@ -3895,7 +3895,7 @@
debugIsMethodEntry = true; // profiling, debugging
#endif
ILOGD("> pc <-- %s.%s %s", curMethod->clazz->descriptor,
- curMethod->name, curMethod->signature);
+ curMethod->name, curMethod->shorty);
DUMP_REGS(curMethod, fp, true); // show input args
FINISH(0); // jump to method start
} else {
@@ -3917,7 +3917,7 @@
#endif
ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor,
- methodToCall->name, methodToCall->signature);
+ methodToCall->name, methodToCall->shorty);
/*
* Jump through native call bridge. Because we leave no
@@ -3954,7 +3954,7 @@
ILOGD("> (return from native %s.%s to %s.%s %s)",
methodToCall->clazz->descriptor, methodToCall->name,
curMethod->clazz->descriptor, curMethod->name,
- curMethod->signature);
+ curMethod->shorty);
//u2 invokeInstr = INST_INST(FETCH(0));
if (true /*invokeInstr >= OP_INVOKE_VIRTUAL &&
diff --git a/vm/mterp/out/InterpC-x86.c b/vm/mterp/out/InterpC-x86.c
index fe261c7..9bb70d1 100644
--- a/vm/mterp/out/InterpC-x86.c
+++ b/vm/mterp/out/InterpC-x86.c
@@ -1702,7 +1702,7 @@
ILOGV("> retval=0x%llx (leaving %s.%s %s)",
retval.j, curMethod->clazz->descriptor, curMethod->name,
- curMethod->signature);
+ curMethod->shorty);
//DUMP_REGS(curMethod, fp);
saveArea = SAVEAREA_FROM_FP(fp);
@@ -1730,7 +1730,7 @@
methodClassDex = curMethod->clazz->pDvmDex;
pc = saveArea->savedPc;
ILOGD("> (return to %s.%s %s)", curMethod->clazz->descriptor,
- curMethod->name, curMethod->signature);
+ curMethod->name, curMethod->shorty);
/* use FINISH on the caller's invoke instruction */
//u2 invokeInstr = INST_INST(FETCH(0));
@@ -1865,7 +1865,7 @@
methodClassDex = curMethod->clazz->pDvmDex;
pc = curMethod->insns + catchRelPc;
ILOGV("> pc <-- %s.%s %s", curMethod->clazz->descriptor,
- curMethod->name, curMethod->signature);
+ curMethod->name, curMethod->shorty);
DUMP_REGS(curMethod, fp, false); // show all regs
/*
@@ -1914,7 +1914,7 @@
//printf("range=%d call=%p count=%d regs=0x%04x\n",
// methodCallRange, methodToCall, count, regs);
//printf(" --> %s.%s %s\n", methodToCall->clazz->descriptor,
- // methodToCall->name, methodToCall->signature);
+ // methodToCall->name, methodToCall->shorty);
u4* outs;
int i;
@@ -1984,7 +1984,7 @@
ILOGV("> %s%s.%s %s",
dvmIsNativeMethod(methodToCall) ? "(NATIVE) " : "",
methodToCall->clazz->descriptor, methodToCall->name,
- methodToCall->signature);
+ methodToCall->shorty);
newFp = (u4*) SAVEAREA_FROM_FP(fp) - methodToCall->registersSize;
newSaveArea = SAVEAREA_FROM_FP(newFp);
@@ -2045,7 +2045,7 @@
debugIsMethodEntry = true; // profiling, debugging
#endif
ILOGD("> pc <-- %s.%s %s", curMethod->clazz->descriptor,
- curMethod->name, curMethod->signature);
+ curMethod->name, curMethod->shorty);
DUMP_REGS(curMethod, fp, true); // show input args
FINISH(0); // jump to method start
} else {
@@ -2067,7 +2067,7 @@
#endif
ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor,
- methodToCall->name, methodToCall->signature);
+ methodToCall->name, methodToCall->shorty);
/*
* Jump through native call bridge. Because we leave no
@@ -2104,7 +2104,7 @@
ILOGD("> (return from native %s.%s to %s.%s %s)",
methodToCall->clazz->descriptor, methodToCall->name,
curMethod->clazz->descriptor, curMethod->name,
- curMethod->signature);
+ curMethod->shorty);
//u2 invokeInstr = INST_INST(FETCH(0));
if (true /*invokeInstr >= OP_INVOKE_VIRTUAL &&
diff --git a/vm/mterp/portable/debug.c b/vm/mterp/portable/debug.c
index 38b55ae..449d49b 100644
--- a/vm/mterp/portable/debug.c
+++ b/vm/mterp/portable/debug.c
@@ -223,7 +223,7 @@
if (/*gDvm.debuggerActive &&*/
strcmp(method->clazz->descriptor, cd) == 0 &&
strcmp(method->name, mn) == 0 &&
- strcmp(method->signature, sg) == 0)
+ strcmp(method->shorty, sg) == 0)
{
LOGW("Reached %s.%s, enabling verbose mode\n",
method->clazz->descriptor, method->name);
diff --git a/vm/oo/Class.c b/vm/oo/Class.c
index a2c485f..50ef961 100644
--- a/vm/oo/Class.c
+++ b/vm/oo/Class.c
@@ -4421,6 +4421,44 @@
dvmCallMethod(self, method, NULL, &unused);
}
+ /* Set the bitmap of reference offsets. Except for class Object,
+ * start with the superclass offsets.
+ */
+ if (clazz->super != NULL) {
+ clazz->refOffsets = clazz->super->refOffsets;
+ } else {
+ clazz->refOffsets = 0;
+ }
+ /*
+ * If our superclass overflowed, we don't stand a chance.
+ */
+ if (clazz->refOffsets != CLASS_WALK_SUPER) {
+ InstField *f;
+ int i;
+
+ /* All of the fields that contain object references
+ * are guaranteed to be at the beginning of the ifields list.
+ */
+ f = clazz->ifields;
+ for (i = 0; i < clazz->ifieldRefCount; i++) {
+ /*
+ * Note that, per the comment on struct InstField,
+ * f->byteOffset is the offset from the beginning of
+ * obj, not the offset into obj->instanceData.
+ */
+ assert(f->byteOffset >= CLASS_SMALLEST_OFFSET);
+ assert((f->byteOffset & (CLASS_OFFSET_ALIGNMENT - 1)) == 0);
+ u4 newBit = CLASS_BIT_FROM_OFFSET(f->byteOffset);
+ if (newBit != 0) {
+ clazz->refOffsets |= newBit;
+ } else {
+ clazz->refOffsets = CLASS_WALK_SUPER;
+ break;
+ }
+ f++;
+ }
+ }
+
if (dvmCheckException(self)) {
/*
* We've had an exception thrown during static initialization. We
diff --git a/vm/oo/Object.h b/vm/oo/Object.h
index b8236db..3e724f4 100644
--- a/vm/oo/Object.h
+++ b/vm/oo/Object.h
@@ -173,6 +173,34 @@
#define PRIM_TYPE_TO_LETTER "ZCFDBSIJV" /* must match order in enum */
/*
+ * Definitions for packing refOffsets in ClassObject.
+ */
+/*
+ * A magic value for refOffsets. Ignore the bits and walk the super
+ * chain when this is the value.
+ * [This is an unlikely "natural" value, since it would be 30 non-ref instance
+ * fields followed by 2 ref instance fields.]
+ */
+#define CLASS_WALK_SUPER ((unsigned int)(3))
+#define CLASS_SMALLEST_OFFSET (sizeof(struct Object))
+#define CLASS_BITS_PER_WORD (sizeof(unsigned long int) * 8)
+#define CLASS_OFFSET_ALIGNMENT 4
+#define CLASS_HIGH_BIT ((unsigned int)1 << (CLASS_BITS_PER_WORD - 1))
+/*
+ * Return a single bit, or zero if the encoding can't encode the offset.
+ */
+#define CLASS_BIT_FROM_OFFSET(byteOffset) \
+ (CLASS_HIGH_BIT >> \
+ (((unsigned int)(byteOffset) - CLASS_SMALLEST_OFFSET) / \
+ CLASS_OFFSET_ALIGNMENT))
+/*
+ * Return an offset, given a bit number as returned from CLZ.
+ */
+#define CLASS_OFFSET_FROM_CLZ(rshift) \
+ (((int)(rshift) * CLASS_OFFSET_ALIGNMENT) + CLASS_SMALLEST_OFFSET)
+
+
+/*
* Used for iftable in ClassObject.
*/
typedef struct InterfaceEntry {
@@ -423,6 +451,9 @@
int ifieldRefCount; // number of fields that are object refs
InstField* ifields;
+ /* bitmap of offsets of ifields */
+ u4 refOffsets;
+
/* source file name, if known */
const char* sourceFile;
};