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: I53eb333b9bd0b770201af0dc617d9a8f38afa699
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c
index f6f2ad9..44f47b7 100644
--- a/vm/compiler/codegen/arm/CodegenDriver.c
+++ b/vm/compiler/codegen/arm/CodegenDriver.c
@@ -1522,7 +1522,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*)
@@ -1532,6 +1534,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();
@@ -1540,18 +1545,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;
         }