Change GC card making to use object head, bug fix for volatile sput obj
This CL changes the way we mark GC card to consistently use the object
head (previously, we marked somewhere in the object - often the head, but
not always). Also, previously a coding error caused us to skip the card
mark for OP_APUT_OBJECT_VOLATILES. Fixed here.
Change-Id: I133ef6395c51a0466c9708209b08e79c3083aff2
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c
index 0b6e433..7068662 100644
--- a/vm/compiler/codegen/arm/CodegenDriver.c
+++ b/vm/compiler/codegen/arm/CodegenDriver.c
@@ -1527,7 +1527,9 @@
case OP_SPUT: {
int valOffset = offsetof(StaticField, value);
int tReg = dvmCompilerAllocTemp(cUnit);
+ int objHead;
bool isVolatile;
+ bool isSputObject;
const Method *method = (mir->OptimizationFlags & MIR_CALLEE) ?
mir->meta.calleeMethod : cUnit->method;
void *fieldPtr = (void*)
@@ -1537,6 +1539,9 @@
(mir->dalvikInsn.opCode == OP_SPUT_OBJECT_VOLATILE) ||
dvmIsVolatileField(fieldPtr);
+ isSputObject = (mir->dalvikInsn.opCode == OP_SPUT_OBJECT) ||
+ (mir->dalvikInsn.opCode == OP_SPUT_OBJECT_VOLATILE);
+
if (fieldPtr == NULL) {
LOGE("Unexpected null static field");
dvmAbort();
@@ -1545,18 +1550,22 @@
rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
rlSrc = loadValue(cUnit, rlSrc, kAnyReg);
loadConstant(cUnit, tReg, (int) fieldPtr + valOffset);
-
+ if (isSputObject) {
+ objHead = dvmCompilerAllocTemp(cUnit);
+ loadConstant(cUnit, objHead, (intptr_t)method->clazz);
+ }
HEAP_ACCESS_SHADOW(true);
storeWordDisp(cUnit, tReg, 0 ,rlSrc.lowReg);
+ dvmCompilerFreeTemp(cUnit, tReg);
HEAP_ACCESS_SHADOW(false);
if (isVolatile) {
dvmCompilerGenMemBarrier(cUnit);
}
- if (mir->dalvikInsn.opCode == OP_SPUT_OBJECT) {
- /* NOTE: marking card based on field address */
- markCard(cUnit, rlSrc.lowReg, tReg);
+ if (isSputObject) {
+ /* NOTE: marking card based object head */
+ markCard(cUnit, rlSrc.lowReg, objHead);
+ dvmCompilerFreeTemp(cUnit, objHead);
}
- dvmCompilerFreeTemp(cUnit, tReg);
break;
}