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;
}
diff --git a/vm/mterp/armv5te/OP_APUT_OBJECT.S b/vm/mterp/armv5te/OP_APUT_OBJECT.S
index e926db6..9e98784 100644
--- a/vm/mterp/armv5te/OP_APUT_OBJECT.S
+++ b/vm/mterp/armv5te/OP_APUT_OBJECT.S
@@ -10,13 +10,13 @@
mov r9, rINST, lsr #8 @ r9<- AA
and r2, r0, #255 @ r2<- BB
mov r3, r0, lsr #8 @ r3<- CC
- GET_VREG(r1, r2) @ r1<- vBB (array object)
+ GET_VREG(rINST, r2) @ rINST<- vBB (array object)
GET_VREG(r0, r3) @ r0<- vCC (requested index)
- cmp r1, #0 @ null array object?
+ cmp rINST, #0 @ null array object?
GET_VREG(r9, r9) @ r9<- vAA
beq common_errNullObject @ yes, bail
- ldr r3, [r1, #offArrayObject_length] @ r3<- arrayObj->length
- add r10, r1, r0, lsl #2 @ r10<- arrayObj + index*width
+ ldr r3, [rINST, #offArrayObject_length] @ r3<- arrayObj->length
+ add r10, rINST, r0, lsl #2 @ r10<- arrayObj + index*width
cmp r0, r3 @ compare unsigned index, length
bcc .L${opcode}_finish @ we're okay, continue on
b common_errArrayIndex @ index >= length, bail
@@ -24,7 +24,7 @@
%break
/*
* On entry:
- * r1 = vBB (arrayObj)
+ * rINST = vBB (arrayObj)
* r9 = vAA (obj)
* r10 = offset into array (vBB + vCC * width)
*/
@@ -32,16 +32,17 @@
cmp r9, #0 @ storing null reference?
beq .L${opcode}_skip_check @ yes, skip type checks
ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz
- ldr r1, [r1, #offObject_clazz] @ r1<- arrayObj->clazz
+ ldr r1, [rINST, #offObject_clazz] @ r1<- arrayObj->clazz
bl dvmCanPutArrayElement @ test object type vs. array type
cmp r0, #0 @ okay?
beq common_errArrayStore @ no
+ mov r1, rINST @ r1<- arrayObj
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
ldr r2, [rGLUE, #offGlue_cardTable] @ get biased CT base
add r10, #offArrayObject_contents @ r0<- pointer to slot
GET_INST_OPCODE(ip) @ extract opcode from rINST
str r9, [r10] @ vBB[vCC]<- vAA
- strb r2, [r2, r10, lsr #GC_CARD_SHIFT] @ mark card
+ strb r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head
GOTO_OPCODE(ip) @ jump to next instruction
.L${opcode}_skip_check:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
diff --git a/vm/mterp/armv5te/OP_FILLED_NEW_ARRAY.S b/vm/mterp/armv5te/OP_FILLED_NEW_ARRAY.S
index b9abe5a..5bb2d43 100644
--- a/vm/mterp/armv5te/OP_FILLED_NEW_ARRAY.S
+++ b/vm/mterp/armv5te/OP_FILLED_NEW_ARRAY.S
@@ -87,7 +87,7 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
GET_INST_OPCODE(ip) @ ip<- opcode from rINST
cmp r1, #'I' @ Is int array?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card if not
+ strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
GOTO_OPCODE(ip) @ execute it
/*
diff --git a/vm/mterp/armv5te/OP_IPUT_OBJECT.S b/vm/mterp/armv5te/OP_IPUT_OBJECT.S
index 5e0fe83..079094e 100644
--- a/vm/mterp/armv5te/OP_IPUT_OBJECT.S
+++ b/vm/mterp/armv5te/OP_IPUT_OBJECT.S
@@ -42,10 +42,9 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
- add r9, r3 @ r9<- direct ptr to target location
GET_INST_OPCODE(ip) @ extract opcode from rINST
$barrier @ releasing store
- str r0, [r9] @ obj.field (8/16/32 bits)<- r0
+ str r0, [r9, r3] @ obj.field (32 bits)<- r0
cmp r0, #0 @ stored a null reference?
strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not
GOTO_OPCODE(ip) @ jump to next instruction
diff --git a/vm/mterp/armv5te/OP_IPUT_OBJECT_QUICK.S b/vm/mterp/armv5te/OP_IPUT_OBJECT_QUICK.S
index 648a69c..7e7144a 100644
--- a/vm/mterp/armv5te/OP_IPUT_OBJECT_QUICK.S
+++ b/vm/mterp/armv5te/OP_IPUT_OBJECT_QUICK.S
@@ -14,6 +14,6 @@
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
str r0, [r3, r1] @ obj.field (always 32 bits)<- r0
cmp r0, #0
- strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card on non-null store
+ strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head
GET_INST_OPCODE(ip) @ extract opcode from rINST
GOTO_OPCODE(ip) @ jump to next instruction
diff --git a/vm/mterp/armv5te/OP_SPUT_OBJECT.S b/vm/mterp/armv5te/OP_SPUT_OBJECT.S
index 54a04fc..5d9baec 100644
--- a/vm/mterp/armv5te/OP_SPUT_OBJECT.S
+++ b/vm/mterp/armv5te/OP_SPUT_OBJECT.S
@@ -14,25 +14,26 @@
ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
cmp r0, #0 @ is resolved entry null?
+ ldr r9, [rGLUE, #offGlue_method] @ r9<- current method
bne .L${opcode}_finish @ no, continue
- ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
EXPORT_PC() @ resolve() could throw, so export now
- ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz
bl dvmResolveStaticField @ r0<- resolved StaticField ptr
cmp r0, #0 @ success?
bne .L${opcode}_finish @ yes, finish
b common_exceptionThrown @ no, handle exception
%break
-.L${opcode}_finish: @ field ptr in r0
+.L${opcode}_finish: @ field ptr in r0, method in r9
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
+ ldr r9, [r9, #offMethod_clazz] @ r9<- obj head
GET_INST_OPCODE(ip) @ extract opcode from rINST
add r0, #offStaticField_value @ r0<- pointer to store target
$barrier @ releasing store
str r1, [r0] @ field<- vAA
cmp r1, #0 @ stored a null object?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ mark card if not
+ strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head
GOTO_OPCODE(ip) @ jump to next instruction
diff --git a/vm/mterp/out/InterpAsm-armv4t.S b/vm/mterp/out/InterpAsm-armv4t.S
index 0fb8a1c..b944a4b 100644
--- a/vm/mterp/out/InterpAsm-armv4t.S
+++ b/vm/mterp/out/InterpAsm-armv4t.S
@@ -2290,13 +2290,13 @@
mov r9, rINST, lsr #8 @ r9<- AA
and r2, r0, #255 @ r2<- BB
mov r3, r0, lsr #8 @ r3<- CC
- GET_VREG(r1, r2) @ r1<- vBB (array object)
+ GET_VREG(rINST, r2) @ rINST<- vBB (array object)
GET_VREG(r0, r3) @ r0<- vCC (requested index)
- cmp r1, #0 @ null array object?
+ cmp rINST, #0 @ null array object?
GET_VREG(r9, r9) @ r9<- vAA
beq common_errNullObject @ yes, bail
- ldr r3, [r1, #offArrayObject_length] @ r3<- arrayObj->length
- add r10, r1, r0, lsl #2 @ r10<- arrayObj + index*width
+ ldr r3, [rINST, #offArrayObject_length] @ r3<- arrayObj->length
+ add r10, rINST, r0, lsl #2 @ r10<- arrayObj + index*width
cmp r0, r3 @ compare unsigned index, length
bcc .LOP_APUT_OBJECT_finish @ we're okay, continue on
b common_errArrayIndex @ index >= length, bail
@@ -3069,10 +3069,10 @@
ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
cmp r0, #0 @ is resolved entry null?
+ ldr r9, [rGLUE, #offGlue_method] @ r9<- current method
bne .LOP_SPUT_OBJECT_finish @ no, continue
- ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
EXPORT_PC() @ resolve() could throw, so export now
- ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz
bl dvmResolveStaticField @ r0<- resolved StaticField ptr
cmp r0, #0 @ success?
bne .LOP_SPUT_OBJECT_finish @ yes, finish
@@ -7900,7 +7900,7 @@
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
str r0, [r3, r1] @ obj.field (always 32 bits)<- r0
cmp r0, #0
- strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card on non-null store
+ strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head
GET_INST_OPCODE(ip) @ extract opcode from rINST
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8083,10 +8083,10 @@
ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
cmp r0, #0 @ is resolved entry null?
+ ldr r9, [rGLUE, #offGlue_method] @ r9<- current method
bne .LOP_SPUT_OBJECT_VOLATILE_finish @ no, continue
- ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
EXPORT_PC() @ resolve() could throw, so export now
- ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz
bl dvmResolveStaticField @ r0<- resolved StaticField ptr
cmp r0, #0 @ success?
bne .LOP_SPUT_OBJECT_VOLATILE_finish @ yes, finish
@@ -8421,7 +8421,7 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
GET_INST_OPCODE(ip) @ ip<- opcode from rINST
cmp r1, #'I' @ Is int array?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card if not
+ strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
GOTO_OPCODE(ip) @ execute it
/*
@@ -8505,7 +8505,7 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
GET_INST_OPCODE(ip) @ ip<- opcode from rINST
cmp r1, #'I' @ Is int array?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card if not
+ strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
GOTO_OPCODE(ip) @ execute it
/*
@@ -8726,7 +8726,7 @@
/* continuation for OP_APUT_OBJECT */
/*
* On entry:
- * r1 = vBB (arrayObj)
+ * rINST = vBB (arrayObj)
* r9 = vAA (obj)
* r10 = offset into array (vBB + vCC * width)
*/
@@ -8734,16 +8734,17 @@
cmp r9, #0 @ storing null reference?
beq .LOP_APUT_OBJECT_skip_check @ yes, skip type checks
ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz
- ldr r1, [r1, #offObject_clazz] @ r1<- arrayObj->clazz
+ ldr r1, [rINST, #offObject_clazz] @ r1<- arrayObj->clazz
bl dvmCanPutArrayElement @ test object type vs. array type
cmp r0, #0 @ okay?
beq common_errArrayStore @ no
+ mov r1, rINST @ r1<- arrayObj
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
ldr r2, [rGLUE, #offGlue_cardTable] @ get biased CT base
add r10, #offArrayObject_contents @ r0<- pointer to slot
GET_INST_OPCODE(ip) @ extract opcode from rINST
str r9, [r10] @ vBB[vCC]<- vAA
- strb r2, [r2, r10, lsr #GC_CARD_SHIFT] @ mark card
+ strb r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head
GOTO_OPCODE(ip) @ jump to next instruction
.LOP_APUT_OBJECT_skip_check:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
@@ -8966,10 +8967,9 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
- add r9, r3 @ r9<- direct ptr to target location
GET_INST_OPCODE(ip) @ extract opcode from rINST
@ no-op @ releasing store
- str r0, [r9] @ obj.field (8/16/32 bits)<- r0
+ str r0, [r9,r3] @ obj.field (32 bits)<- r0
cmp r0, #0 @ stored a null reference?
strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not
GOTO_OPCODE(ip) @ jump to next instruction
@@ -9200,17 +9200,18 @@
b common_exceptionThrown @ no, handle exception
/* continuation for OP_SPUT_OBJECT */
-.LOP_SPUT_OBJECT_finish: @ field ptr in r0
+.LOP_SPUT_OBJECT_finish: @ field ptr in r0, method in r9
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
+ ldr r9, [r9, #offMethod_clazz] @ r9<- obj head
GET_INST_OPCODE(ip) @ extract opcode from rINST
add r0, #offStaticField_value @ r0<- pointer to store target
@ no-op @ releasing store
str r1, [r0] @ field<- vAA
cmp r1, #0 @ stored a null object?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ mark card if not
+ strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head
GOTO_OPCODE(ip) @ jump to next instruction
/* continuation for OP_SPUT_BOOLEAN */
@@ -9809,10 +9810,9 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
- add r9, r3 @ r9<- direct ptr to target location
GET_INST_OPCODE(ip) @ extract opcode from rINST
SMP_DMB @ releasing store
- str r0, [r9] @ obj.field (8/16/32 bits)<- r0
+ str r0, [r9,r3] @ obj.field (32 bits)<- r0
cmp r0, #0 @ stored a null reference?
strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not
GOTO_OPCODE(ip) @ jump to next instruction
@@ -9833,17 +9833,18 @@
b common_exceptionThrown @ no, handle exception
/* continuation for OP_SPUT_OBJECT_VOLATILE */
-.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0
+.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0, method in r9
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
+ ldr r9, [r9, #offMethod_clazz] @ r9<- obj head
GET_INST_OPCODE(ip) @ extract opcode from rINST
add r0, #offStaticField_value @ r0<- pointer to store target
SMP_DMB @ releasing store
str r1, [r0] @ field<- vAA
cmp r1, #0 @ stored a null object?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ mark card if not
+ strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head
GOTO_OPCODE(ip) @ jump to next instruction
.size dvmAsmSisterStart, .-dvmAsmSisterStart
diff --git a/vm/mterp/out/InterpAsm-armv5te-vfp.S b/vm/mterp/out/InterpAsm-armv5te-vfp.S
index 88dc89c..ba4f5c3 100644
--- a/vm/mterp/out/InterpAsm-armv5te-vfp.S
+++ b/vm/mterp/out/InterpAsm-armv5te-vfp.S
@@ -2270,13 +2270,13 @@
mov r9, rINST, lsr #8 @ r9<- AA
and r2, r0, #255 @ r2<- BB
mov r3, r0, lsr #8 @ r3<- CC
- GET_VREG(r1, r2) @ r1<- vBB (array object)
+ GET_VREG(rINST, r2) @ rINST<- vBB (array object)
GET_VREG(r0, r3) @ r0<- vCC (requested index)
- cmp r1, #0 @ null array object?
+ cmp rINST, #0 @ null array object?
GET_VREG(r9, r9) @ r9<- vAA
beq common_errNullObject @ yes, bail
- ldr r3, [r1, #offArrayObject_length] @ r3<- arrayObj->length
- add r10, r1, r0, lsl #2 @ r10<- arrayObj + index*width
+ ldr r3, [rINST, #offArrayObject_length] @ r3<- arrayObj->length
+ add r10, rINST, r0, lsl #2 @ r10<- arrayObj + index*width
cmp r0, r3 @ compare unsigned index, length
bcc .LOP_APUT_OBJECT_finish @ we're okay, continue on
b common_errArrayIndex @ index >= length, bail
@@ -3049,10 +3049,10 @@
ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
cmp r0, #0 @ is resolved entry null?
+ ldr r9, [rGLUE, #offGlue_method] @ r9<- current method
bne .LOP_SPUT_OBJECT_finish @ no, continue
- ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
EXPORT_PC() @ resolve() could throw, so export now
- ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz
bl dvmResolveStaticField @ r0<- resolved StaticField ptr
cmp r0, #0 @ success?
bne .LOP_SPUT_OBJECT_finish @ yes, finish
@@ -7578,7 +7578,7 @@
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
str r0, [r3, r1] @ obj.field (always 32 bits)<- r0
cmp r0, #0
- strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card on non-null store
+ strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head
GET_INST_OPCODE(ip) @ extract opcode from rINST
GOTO_OPCODE(ip) @ jump to next instruction
@@ -7761,10 +7761,10 @@
ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
cmp r0, #0 @ is resolved entry null?
+ ldr r9, [rGLUE, #offGlue_method] @ r9<- current method
bne .LOP_SPUT_OBJECT_VOLATILE_finish @ no, continue
- ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
EXPORT_PC() @ resolve() could throw, so export now
- ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz
bl dvmResolveStaticField @ r0<- resolved StaticField ptr
cmp r0, #0 @ success?
bne .LOP_SPUT_OBJECT_VOLATILE_finish @ yes, finish
@@ -8099,7 +8099,7 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
GET_INST_OPCODE(ip) @ ip<- opcode from rINST
cmp r1, #'I' @ Is int array?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card if not
+ strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
GOTO_OPCODE(ip) @ execute it
/*
@@ -8183,7 +8183,7 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
GET_INST_OPCODE(ip) @ ip<- opcode from rINST
cmp r1, #'I' @ Is int array?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card if not
+ strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
GOTO_OPCODE(ip) @ execute it
/*
@@ -8266,7 +8266,7 @@
/* continuation for OP_APUT_OBJECT */
/*
* On entry:
- * r1 = vBB (arrayObj)
+ * rINST = vBB (arrayObj)
* r9 = vAA (obj)
* r10 = offset into array (vBB + vCC * width)
*/
@@ -8274,16 +8274,17 @@
cmp r9, #0 @ storing null reference?
beq .LOP_APUT_OBJECT_skip_check @ yes, skip type checks
ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz
- ldr r1, [r1, #offObject_clazz] @ r1<- arrayObj->clazz
+ ldr r1, [rINST, #offObject_clazz] @ r1<- arrayObj->clazz
bl dvmCanPutArrayElement @ test object type vs. array type
cmp r0, #0 @ okay?
beq common_errArrayStore @ no
+ mov r1, rINST @ r1<- arrayObj
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
ldr r2, [rGLUE, #offGlue_cardTable] @ get biased CT base
add r10, #offArrayObject_contents @ r0<- pointer to slot
GET_INST_OPCODE(ip) @ extract opcode from rINST
str r9, [r10] @ vBB[vCC]<- vAA
- strb r2, [r2, r10, lsr #GC_CARD_SHIFT] @ mark card
+ strb r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head
GOTO_OPCODE(ip) @ jump to next instruction
.LOP_APUT_OBJECT_skip_check:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
@@ -8505,10 +8506,9 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
- add r9, r3 @ r9<- direct ptr to target location
GET_INST_OPCODE(ip) @ extract opcode from rINST
@ no-op @ releasing store
- str r0, [r9] @ obj.field (8/16/32 bits)<- r0
+ str r0, [r9,r3] @ obj.field (32 bits)<- r0
cmp r0, #0 @ stored a null reference?
strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8739,17 +8739,18 @@
b common_exceptionThrown @ no, handle exception
/* continuation for OP_SPUT_OBJECT */
-.LOP_SPUT_OBJECT_finish: @ field ptr in r0
+.LOP_SPUT_OBJECT_finish: @ field ptr in r0, method in r9
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
+ ldr r9, [r9, #offMethod_clazz] @ r9<- obj head
GET_INST_OPCODE(ip) @ extract opcode from rINST
add r0, #offStaticField_value @ r0<- pointer to store target
@ no-op @ releasing store
str r1, [r0] @ field<- vAA
cmp r1, #0 @ stored a null object?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ mark card if not
+ strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head
GOTO_OPCODE(ip) @ jump to next instruction
/* continuation for OP_SPUT_BOOLEAN */
@@ -9347,10 +9348,9 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
- add r9, r3 @ r9<- direct ptr to target location
GET_INST_OPCODE(ip) @ extract opcode from rINST
SMP_DMB @ releasing store
- str r0, [r9] @ obj.field (8/16/32 bits)<- r0
+ str r0, [r9,r3] @ obj.field (32 bits)<- r0
cmp r0, #0 @ stored a null reference?
strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not
GOTO_OPCODE(ip) @ jump to next instruction
@@ -9371,17 +9371,18 @@
b common_exceptionThrown @ no, handle exception
/* continuation for OP_SPUT_OBJECT_VOLATILE */
-.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0
+.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0, method in r9
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
+ ldr r9, [r9, #offMethod_clazz] @ r9<- obj head
GET_INST_OPCODE(ip) @ extract opcode from rINST
add r0, #offStaticField_value @ r0<- pointer to store target
SMP_DMB @ releasing store
str r1, [r0] @ field<- vAA
cmp r1, #0 @ stored a null object?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ mark card if not
+ strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head
GOTO_OPCODE(ip) @ jump to next instruction
.size dvmAsmSisterStart, .-dvmAsmSisterStart
diff --git a/vm/mterp/out/InterpAsm-armv5te.S b/vm/mterp/out/InterpAsm-armv5te.S
index 47c8002..ad38849 100644
--- a/vm/mterp/out/InterpAsm-armv5te.S
+++ b/vm/mterp/out/InterpAsm-armv5te.S
@@ -2292,13 +2292,13 @@
mov r9, rINST, lsr #8 @ r9<- AA
and r2, r0, #255 @ r2<- BB
mov r3, r0, lsr #8 @ r3<- CC
- GET_VREG(r1, r2) @ r1<- vBB (array object)
+ GET_VREG(rINST, r2) @ rINST<- vBB (array object)
GET_VREG(r0, r3) @ r0<- vCC (requested index)
- cmp r1, #0 @ null array object?
+ cmp rINST, #0 @ null array object?
GET_VREG(r9, r9) @ r9<- vAA
beq common_errNullObject @ yes, bail
- ldr r3, [r1, #offArrayObject_length] @ r3<- arrayObj->length
- add r10, r1, r0, lsl #2 @ r10<- arrayObj + index*width
+ ldr r3, [rINST, #offArrayObject_length] @ r3<- arrayObj->length
+ add r10, rINST, r0, lsl #2 @ r10<- arrayObj + index*width
cmp r0, r3 @ compare unsigned index, length
bcc .LOP_APUT_OBJECT_finish @ we're okay, continue on
b common_errArrayIndex @ index >= length, bail
@@ -3071,10 +3071,10 @@
ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
cmp r0, #0 @ is resolved entry null?
+ ldr r9, [rGLUE, #offGlue_method] @ r9<- current method
bne .LOP_SPUT_OBJECT_finish @ no, continue
- ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
EXPORT_PC() @ resolve() could throw, so export now
- ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz
bl dvmResolveStaticField @ r0<- resolved StaticField ptr
cmp r0, #0 @ success?
bne .LOP_SPUT_OBJECT_finish @ yes, finish
@@ -7900,7 +7900,7 @@
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
str r0, [r3, r1] @ obj.field (always 32 bits)<- r0
cmp r0, #0
- strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card on non-null store
+ strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head
GET_INST_OPCODE(ip) @ extract opcode from rINST
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8083,10 +8083,10 @@
ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
cmp r0, #0 @ is resolved entry null?
+ ldr r9, [rGLUE, #offGlue_method] @ r9<- current method
bne .LOP_SPUT_OBJECT_VOLATILE_finish @ no, continue
- ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
EXPORT_PC() @ resolve() could throw, so export now
- ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz
bl dvmResolveStaticField @ r0<- resolved StaticField ptr
cmp r0, #0 @ success?
bne .LOP_SPUT_OBJECT_VOLATILE_finish @ yes, finish
@@ -8421,7 +8421,7 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
GET_INST_OPCODE(ip) @ ip<- opcode from rINST
cmp r1, #'I' @ Is int array?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card if not
+ strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
GOTO_OPCODE(ip) @ execute it
/*
@@ -8505,7 +8505,7 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
GET_INST_OPCODE(ip) @ ip<- opcode from rINST
cmp r1, #'I' @ Is int array?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card if not
+ strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
GOTO_OPCODE(ip) @ execute it
/*
@@ -8724,7 +8724,7 @@
/* continuation for OP_APUT_OBJECT */
/*
* On entry:
- * r1 = vBB (arrayObj)
+ * rINST = vBB (arrayObj)
* r9 = vAA (obj)
* r10 = offset into array (vBB + vCC * width)
*/
@@ -8732,16 +8732,17 @@
cmp r9, #0 @ storing null reference?
beq .LOP_APUT_OBJECT_skip_check @ yes, skip type checks
ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz
- ldr r1, [r1, #offObject_clazz] @ r1<- arrayObj->clazz
+ ldr r1, [rINST, #offObject_clazz] @ r1<- arrayObj->clazz
bl dvmCanPutArrayElement @ test object type vs. array type
cmp r0, #0 @ okay?
beq common_errArrayStore @ no
+ mov r1, rINST @ r1<- arrayObj
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
ldr r2, [rGLUE, #offGlue_cardTable] @ get biased CT base
add r10, #offArrayObject_contents @ r0<- pointer to slot
GET_INST_OPCODE(ip) @ extract opcode from rINST
str r9, [r10] @ vBB[vCC]<- vAA
- strb r2, [r2, r10, lsr #GC_CARD_SHIFT] @ mark card
+ strb r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head
GOTO_OPCODE(ip) @ jump to next instruction
.LOP_APUT_OBJECT_skip_check:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
@@ -8963,10 +8964,9 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
- add r9, r3 @ r9<- direct ptr to target location
GET_INST_OPCODE(ip) @ extract opcode from rINST
@ no-op @ releasing store
- str r0, [r9] @ obj.field (8/16/32 bits)<- r0
+ str r0, [r9,r3] @ obj.field (32 bits)<- r0
cmp r0, #0 @ stored a null reference?
strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not
GOTO_OPCODE(ip) @ jump to next instruction
@@ -9197,17 +9197,18 @@
b common_exceptionThrown @ no, handle exception
/* continuation for OP_SPUT_OBJECT */
-.LOP_SPUT_OBJECT_finish: @ field ptr in r0
+.LOP_SPUT_OBJECT_finish: @ field ptr in r0, method in r9
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
+ ldr r9, [r9, #offMethod_clazz] @ r9<- obj head
GET_INST_OPCODE(ip) @ extract opcode from rINST
add r0, #offStaticField_value @ r0<- pointer to store target
@ no-op @ releasing store
str r1, [r0] @ field<- vAA
cmp r1, #0 @ stored a null object?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ mark card if not
+ strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head
GOTO_OPCODE(ip) @ jump to next instruction
/* continuation for OP_SPUT_BOOLEAN */
@@ -9805,10 +9806,9 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
- add r9, r3 @ r9<- direct ptr to target location
GET_INST_OPCODE(ip) @ extract opcode from rINST
SMP_DMB @ releasing store
- str r0, [r9] @ obj.field (8/16/32 bits)<- r0
+ str r0, [r9,r3] @ obj.field (32 bits)<- r0
cmp r0, #0 @ stored a null reference?
strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not
GOTO_OPCODE(ip) @ jump to next instruction
@@ -9829,17 +9829,18 @@
b common_exceptionThrown @ no, handle exception
/* continuation for OP_SPUT_OBJECT_VOLATILE */
-.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0
+.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0, method in r9
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
+ ldr r9, [r9, #offMethod_clazz] @ r9<- obj head
GET_INST_OPCODE(ip) @ extract opcode from rINST
add r0, #offStaticField_value @ r0<- pointer to store target
SMP_DMB @ releasing store
str r1, [r0] @ field<- vAA
cmp r1, #0 @ stored a null object?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ mark card if not
+ strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head
GOTO_OPCODE(ip) @ jump to next instruction
.size dvmAsmSisterStart, .-dvmAsmSisterStart
diff --git a/vm/mterp/out/InterpAsm-armv7-a-neon.S b/vm/mterp/out/InterpAsm-armv7-a-neon.S
index 46e6b63..4d1c234 100644
--- a/vm/mterp/out/InterpAsm-armv7-a-neon.S
+++ b/vm/mterp/out/InterpAsm-armv7-a-neon.S
@@ -2274,13 +2274,13 @@
mov r9, rINST, lsr #8 @ r9<- AA
and r2, r0, #255 @ r2<- BB
mov r3, r0, lsr #8 @ r3<- CC
- GET_VREG(r1, r2) @ r1<- vBB (array object)
+ GET_VREG(rINST, r2) @ rINST<- vBB (array object)
GET_VREG(r0, r3) @ r0<- vCC (requested index)
- cmp r1, #0 @ null array object?
+ cmp rINST, #0 @ null array object?
GET_VREG(r9, r9) @ r9<- vAA
beq common_errNullObject @ yes, bail
- ldr r3, [r1, #offArrayObject_length] @ r3<- arrayObj->length
- add r10, r1, r0, lsl #2 @ r10<- arrayObj + index*width
+ ldr r3, [rINST, #offArrayObject_length] @ r3<- arrayObj->length
+ add r10, rINST, r0, lsl #2 @ r10<- arrayObj + index*width
cmp r0, r3 @ compare unsigned index, length
bcc .LOP_APUT_OBJECT_finish @ we're okay, continue on
b common_errArrayIndex @ index >= length, bail
@@ -3053,10 +3053,10 @@
ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
cmp r0, #0 @ is resolved entry null?
+ ldr r9, [rGLUE, #offGlue_method] @ r9<- current method
bne .LOP_SPUT_OBJECT_finish @ no, continue
- ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
EXPORT_PC() @ resolve() could throw, so export now
- ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz
bl dvmResolveStaticField @ r0<- resolved StaticField ptr
cmp r0, #0 @ success?
bne .LOP_SPUT_OBJECT_finish @ yes, finish
@@ -7532,7 +7532,7 @@
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
str r0, [r3, r1] @ obj.field (always 32 bits)<- r0
cmp r0, #0
- strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card on non-null store
+ strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head
GET_INST_OPCODE(ip) @ extract opcode from rINST
GOTO_OPCODE(ip) @ jump to next instruction
@@ -7715,10 +7715,10 @@
ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
cmp r0, #0 @ is resolved entry null?
+ ldr r9, [rGLUE, #offGlue_method] @ r9<- current method
bne .LOP_SPUT_OBJECT_VOLATILE_finish @ no, continue
- ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
EXPORT_PC() @ resolve() could throw, so export now
- ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz
bl dvmResolveStaticField @ r0<- resolved StaticField ptr
cmp r0, #0 @ success?
bne .LOP_SPUT_OBJECT_VOLATILE_finish @ yes, finish
@@ -8053,7 +8053,7 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
GET_INST_OPCODE(ip) @ ip<- opcode from rINST
cmp r1, #'I' @ Is int array?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card if not
+ strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
GOTO_OPCODE(ip) @ execute it
/*
@@ -8137,7 +8137,7 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
GET_INST_OPCODE(ip) @ ip<- opcode from rINST
cmp r1, #'I' @ Is int array?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card if not
+ strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
GOTO_OPCODE(ip) @ execute it
/*
@@ -8220,7 +8220,7 @@
/* continuation for OP_APUT_OBJECT */
/*
* On entry:
- * r1 = vBB (arrayObj)
+ * rINST = vBB (arrayObj)
* r9 = vAA (obj)
* r10 = offset into array (vBB + vCC * width)
*/
@@ -8228,16 +8228,17 @@
cmp r9, #0 @ storing null reference?
beq .LOP_APUT_OBJECT_skip_check @ yes, skip type checks
ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz
- ldr r1, [r1, #offObject_clazz] @ r1<- arrayObj->clazz
+ ldr r1, [rINST, #offObject_clazz] @ r1<- arrayObj->clazz
bl dvmCanPutArrayElement @ test object type vs. array type
cmp r0, #0 @ okay?
beq common_errArrayStore @ no
+ mov r1, rINST @ r1<- arrayObj
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
ldr r2, [rGLUE, #offGlue_cardTable] @ get biased CT base
add r10, #offArrayObject_contents @ r0<- pointer to slot
GET_INST_OPCODE(ip) @ extract opcode from rINST
str r9, [r10] @ vBB[vCC]<- vAA
- strb r2, [r2, r10, lsr #GC_CARD_SHIFT] @ mark card
+ strb r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head
GOTO_OPCODE(ip) @ jump to next instruction
.LOP_APUT_OBJECT_skip_check:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
@@ -8443,10 +8444,9 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
- add r9, r3 @ r9<- direct ptr to target location
GET_INST_OPCODE(ip) @ extract opcode from rINST
@ no-op @ releasing store
- str r0, [r9] @ obj.field (8/16/32 bits)<- r0
+ str r0, [r9,r3] @ obj.field (32 bits)<- r0
cmp r0, #0 @ stored a null reference?
strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8677,17 +8677,18 @@
b common_exceptionThrown @ no, handle exception
/* continuation for OP_SPUT_OBJECT */
-.LOP_SPUT_OBJECT_finish: @ field ptr in r0
+.LOP_SPUT_OBJECT_finish: @ field ptr in r0, method in r9
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
+ ldr r9, [r9, #offMethod_clazz] @ r9<- obj head
GET_INST_OPCODE(ip) @ extract opcode from rINST
add r0, #offStaticField_value @ r0<- pointer to store target
@ no-op @ releasing store
str r1, [r0] @ field<- vAA
cmp r1, #0 @ stored a null object?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ mark card if not
+ strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head
GOTO_OPCODE(ip) @ jump to next instruction
/* continuation for OP_SPUT_BOOLEAN */
@@ -9285,10 +9286,9 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
- add r9, r3 @ r9<- direct ptr to target location
GET_INST_OPCODE(ip) @ extract opcode from rINST
SMP_DMB @ releasing store
- str r0, [r9] @ obj.field (8/16/32 bits)<- r0
+ str r0, [r9,r3] @ obj.field (32 bits)<- r0
cmp r0, #0 @ stored a null reference?
strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not
GOTO_OPCODE(ip) @ jump to next instruction
@@ -9309,17 +9309,18 @@
b common_exceptionThrown @ no, handle exception
/* continuation for OP_SPUT_OBJECT_VOLATILE */
-.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0
+.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0, method in r9
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
+ ldr r9, [r9, #offMethod_clazz] @ r9<- obj head
GET_INST_OPCODE(ip) @ extract opcode from rINST
add r0, #offStaticField_value @ r0<- pointer to store target
SMP_DMB @ releasing store
str r1, [r0] @ field<- vAA
cmp r1, #0 @ stored a null object?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ mark card if not
+ strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head
GOTO_OPCODE(ip) @ jump to next instruction
.size dvmAsmSisterStart, .-dvmAsmSisterStart
diff --git a/vm/mterp/out/InterpAsm-armv7-a.S b/vm/mterp/out/InterpAsm-armv7-a.S
index c092019..b3fd662 100644
--- a/vm/mterp/out/InterpAsm-armv7-a.S
+++ b/vm/mterp/out/InterpAsm-armv7-a.S
@@ -2274,13 +2274,13 @@
mov r9, rINST, lsr #8 @ r9<- AA
and r2, r0, #255 @ r2<- BB
mov r3, r0, lsr #8 @ r3<- CC
- GET_VREG(r1, r2) @ r1<- vBB (array object)
+ GET_VREG(rINST, r2) @ rINST<- vBB (array object)
GET_VREG(r0, r3) @ r0<- vCC (requested index)
- cmp r1, #0 @ null array object?
+ cmp rINST, #0 @ null array object?
GET_VREG(r9, r9) @ r9<- vAA
beq common_errNullObject @ yes, bail
- ldr r3, [r1, #offArrayObject_length] @ r3<- arrayObj->length
- add r10, r1, r0, lsl #2 @ r10<- arrayObj + index*width
+ ldr r3, [rINST, #offArrayObject_length] @ r3<- arrayObj->length
+ add r10, rINST, r0, lsl #2 @ r10<- arrayObj + index*width
cmp r0, r3 @ compare unsigned index, length
bcc .LOP_APUT_OBJECT_finish @ we're okay, continue on
b common_errArrayIndex @ index >= length, bail
@@ -3053,10 +3053,10 @@
ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
cmp r0, #0 @ is resolved entry null?
+ ldr r9, [rGLUE, #offGlue_method] @ r9<- current method
bne .LOP_SPUT_OBJECT_finish @ no, continue
- ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
EXPORT_PC() @ resolve() could throw, so export now
- ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz
bl dvmResolveStaticField @ r0<- resolved StaticField ptr
cmp r0, #0 @ success?
bne .LOP_SPUT_OBJECT_finish @ yes, finish
@@ -7532,7 +7532,7 @@
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
str r0, [r3, r1] @ obj.field (always 32 bits)<- r0
cmp r0, #0
- strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card on non-null store
+ strneb r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head
GET_INST_OPCODE(ip) @ extract opcode from rINST
GOTO_OPCODE(ip) @ jump to next instruction
@@ -7715,10 +7715,10 @@
ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
cmp r0, #0 @ is resolved entry null?
+ ldr r9, [rGLUE, #offGlue_method] @ r9<- current method
bne .LOP_SPUT_OBJECT_VOLATILE_finish @ no, continue
- ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
EXPORT_PC() @ resolve() could throw, so export now
- ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ ldr r0, [r9, #offMethod_clazz] @ r0<- method->clazz
bl dvmResolveStaticField @ r0<- resolved StaticField ptr
cmp r0, #0 @ success?
bne .LOP_SPUT_OBJECT_VOLATILE_finish @ yes, finish
@@ -8053,7 +8053,7 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
GET_INST_OPCODE(ip) @ ip<- opcode from rINST
cmp r1, #'I' @ Is int array?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card if not
+ strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
GOTO_OPCODE(ip) @ execute it
/*
@@ -8137,7 +8137,7 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
GET_INST_OPCODE(ip) @ ip<- opcode from rINST
cmp r1, #'I' @ Is int array?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card if not
+ strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
GOTO_OPCODE(ip) @ execute it
/*
@@ -8220,7 +8220,7 @@
/* continuation for OP_APUT_OBJECT */
/*
* On entry:
- * r1 = vBB (arrayObj)
+ * rINST = vBB (arrayObj)
* r9 = vAA (obj)
* r10 = offset into array (vBB + vCC * width)
*/
@@ -8228,16 +8228,17 @@
cmp r9, #0 @ storing null reference?
beq .LOP_APUT_OBJECT_skip_check @ yes, skip type checks
ldr r0, [r9, #offObject_clazz] @ r0<- obj->clazz
- ldr r1, [r1, #offObject_clazz] @ r1<- arrayObj->clazz
+ ldr r1, [rINST, #offObject_clazz] @ r1<- arrayObj->clazz
bl dvmCanPutArrayElement @ test object type vs. array type
cmp r0, #0 @ okay?
beq common_errArrayStore @ no
+ mov r1, rINST @ r1<- arrayObj
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
ldr r2, [rGLUE, #offGlue_cardTable] @ get biased CT base
add r10, #offArrayObject_contents @ r0<- pointer to slot
GET_INST_OPCODE(ip) @ extract opcode from rINST
str r9, [r10] @ vBB[vCC]<- vAA
- strb r2, [r2, r10, lsr #GC_CARD_SHIFT] @ mark card
+ strb r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head
GOTO_OPCODE(ip) @ jump to next instruction
.LOP_APUT_OBJECT_skip_check:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
@@ -8443,10 +8444,9 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
- add r9, r3 @ r9<- direct ptr to target location
GET_INST_OPCODE(ip) @ extract opcode from rINST
@ no-op @ releasing store
- str r0, [r9] @ obj.field (8/16/32 bits)<- r0
+ str r0, [r9,r3] @ obj.field (32 bits)<- r0
cmp r0, #0 @ stored a null reference?
strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8677,17 +8677,18 @@
b common_exceptionThrown @ no, handle exception
/* continuation for OP_SPUT_OBJECT */
-.LOP_SPUT_OBJECT_finish: @ field ptr in r0
+.LOP_SPUT_OBJECT_finish: @ field ptr in r0, method in r9
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
+ ldr r9, [r9, #offMethod_clazz] @ r9<- obj head
GET_INST_OPCODE(ip) @ extract opcode from rINST
add r0, #offStaticField_value @ r0<- pointer to store target
@ no-op @ releasing store
str r1, [r0] @ field<- vAA
cmp r1, #0 @ stored a null object?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ mark card if not
+ strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head
GOTO_OPCODE(ip) @ jump to next instruction
/* continuation for OP_SPUT_BOOLEAN */
@@ -9285,10 +9286,9 @@
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
- add r9, r3 @ r9<- direct ptr to target location
GET_INST_OPCODE(ip) @ extract opcode from rINST
SMP_DMB @ releasing store
- str r0, [r9] @ obj.field (8/16/32 bits)<- r0
+ str r0, [r9,r3] @ obj.field (32 bits)<- r0
cmp r0, #0 @ stored a null reference?
strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card if not
GOTO_OPCODE(ip) @ jump to next instruction
@@ -9309,17 +9309,18 @@
b common_exceptionThrown @ no, handle exception
/* continuation for OP_SPUT_OBJECT_VOLATILE */
-.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0
+.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0, method in r9
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
ldr r2, [rGLUE, #offGlue_cardTable] @ r2<- card table base
+ ldr r9, [r9, #offMethod_clazz] @ r9<- obj head
GET_INST_OPCODE(ip) @ extract opcode from rINST
add r0, #offStaticField_value @ r0<- pointer to store target
SMP_DMB @ releasing store
str r1, [r0] @ field<- vAA
cmp r1, #0 @ stored a null object?
- strneb r2, [r2, r0, lsr #GC_CARD_SHIFT] @ mark card if not
+ strneb r2, [r2, r9, lsr #GC_CARD_SHIFT] @ mark card based on obj head
GOTO_OPCODE(ip) @ jump to next instruction
.size dvmAsmSisterStart, .-dvmAsmSisterStart
diff --git a/vm/mterp/out/InterpAsm-x86.S b/vm/mterp/out/InterpAsm-x86.S
index 324258f..f256ac1 100644
--- a/vm/mterp/out/InterpAsm-x86.S
+++ b/vm/mterp/out/InterpAsm-x86.S
@@ -2894,7 +2894,7 @@
movl (%ecx,%eax,4),%eax # eax<- resolved StaticField
testl %eax,%eax # resolved entry null?
je .LOP_SPUT_OBJECT_resolve # if not, make it so
-.LOP_SPUT_OBJECT_finish: # field ptr in eax
+.LOP_SPUT_OBJECT_finish: # field ptr in eax
movzbl rINSTbl,%ecx # ecx<- AA
GET_VREG_R %ecx %ecx
jmp .LOP_SPUT_OBJECT_continue
@@ -6395,7 +6395,7 @@
movl (%ecx,%eax,4),%eax # eax<- resolved StaticField
testl %eax,%eax # resolved entry null?
je .LOP_SPUT_OBJECT_VOLATILE_resolve # if not, make it so
-.LOP_SPUT_OBJECT_VOLATILE_finish: # field ptr in eax
+.LOP_SPUT_OBJECT_VOLATILE_finish: # field ptr in eax
movzbl rINSTbl,%ecx # ecx<- AA
GET_VREG_R %ecx %ecx
jmp .LOP_SPUT_OBJECT_VOLATILE_continue
@@ -6826,7 +6826,7 @@
movl offGlue_retval(%ecx),%eax # eax<- object head
movl offGlue_cardTable(%ecx),%ecx # card table base
shrl $GC_CARD_SHIFT,%eax # convert to card num
- movb %cl,(%ecx,%eax) # mark card
+ movb %cl,(%ecx,%eax) # mark card based on object head
5:
ADVANCE_PC 3
GOTO_NEXT_R %edx
@@ -6936,7 +6936,7 @@
movl offGlue_retval(%ecx),%eax # eax<- object head
movl offGlue_cardTable(%ecx),%ecx # card table base
shrl $GC_CARD_SHIFT,%eax # convert to card num
- movb %cl,(%ecx,%eax) # mark card
+ movb %cl,(%ecx,%eax) # mark card based on object head
5:
ADVANCE_PC 3
GOTO_NEXT_R %edx
@@ -7024,23 +7024,25 @@
*/
.LOP_APUT_OBJECT_continue:
leal offArrayObject_contents(%eax,%ecx,4),%ecx
- testl rINST,rINST # storing null reference?
+ testl rINST,rINST # storing null reference?
je .LOP_APUT_OBJECT_skip_check
- SPILL_TMP1(%ecx)
- movl offObject_clazz(%eax),%eax # eax<- arrayObj->clazz
- movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz
+ SPILL_TMP1(%ecx) # save target address
+ SPILL_TMP2(%eax) # save object head
+ movl offObject_clazz(%eax),%eax # eax<- arrayObj->clazz
+ movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz
movl %eax,OUT_ARG1(%esp)
movl %ecx,OUT_ARG0(%esp)
- call dvmCanPutArrayElement # test object type vs. array type
- UNSPILL_TMP1(%ecx)
+ call dvmCanPutArrayElement # test object type vs. array type
+ UNSPILL_TMP1(%ecx) # recover target address
testl %eax,%eax
movl rGLUE,%eax
je common_errArrayStore
movl offGlue_cardTable(%eax),%eax # get card table base
- movl rINST,(%ecx)
+ movl rINST,(%ecx) # store into array
+ UNSPILL_TMP2(%ecx) # recover object head
FETCH_INST_OPCODE 2 %edx
- shrl $GC_CARD_SHIFT,%ecx # convert addr to card number
- movb %al,(%eax,%ecx) # mark card
+ shrl $GC_CARD_SHIFT,%ecx # object head to card number
+ movb %al,(%eax,%ecx) # mark card using object head
ADVANCE_PC 2
GOTO_NEXT_R %edx
@@ -7376,7 +7378,7 @@
FETCH_INST_OPCODE 2 %edx
je 1f # skip card mark if null store
shrl $GC_CARD_SHIFT,%ecx # object head to card number
- movb %al,(%eax,%ecx) # mark card
+ movb %al,(%eax,%ecx) # mark card using object head
1:
ADVANCE_PC 2
GOTO_NEXT_R %edx
@@ -7671,11 +7673,13 @@
.LOP_SPUT_OBJECT_continue:
- movl %ecx,offStaticField_value(%eax)
- testl %ecx,%ecx
+ movl %ecx,offStaticField_value(%eax) # do the store
+ testl %ecx,%ecx # stored null object ptr?
movl rGLUE,%ecx
FETCH_INST_OPCODE 2 %edx
- je 1f
+ movl offGlue_method(%ecx),%eax # eax<- current method
+ je 1f # skip card mark if null
+ movl offMethod_clazz(%eax),%eax # eax<- method->clazz
movl offGlue_cardTable(%ecx),%ecx # get card table base
shrl $GC_CARD_SHIFT,%eax # head to card number
movb %cl,(%ecx,%eax) # mark card
@@ -8584,7 +8588,7 @@
movl offGlue_cardTable(%eax),%eax # get card table base
je 1f # skip card mark if null store
shrl $GC_CARD_SHIFT,%ecx # object head to card number
- movb %al,(%eax,%ecx) # mark card
+ movb %al,(%eax,%ecx) # mark card based on object head
1:
ADVANCE_PC 2
GOTO_NEXT_R %edx
@@ -8623,7 +8627,7 @@
FETCH_INST_OPCODE 2 %edx
je 1f # skip card mark if null store
shrl $GC_CARD_SHIFT,%ecx # object head to card number
- movb %al,(%eax,%ecx) # mark card
+ movb %al,(%eax,%ecx) # mark card using object head
1:
ADVANCE_PC 2
GOTO_NEXT_R %edx
@@ -8650,11 +8654,13 @@
.LOP_SPUT_OBJECT_VOLATILE_continue:
- movl %ecx,offStaticField_value(%eax)
- testl %ecx,%ecx
+ movl %ecx,offStaticField_value(%eax) # do the store
+ testl %ecx,%ecx # stored null object ptr?
movl rGLUE,%ecx
FETCH_INST_OPCODE 2 %edx
- je 1f
+ movl offGlue_method(%ecx),%eax # eax<- current method
+ je 1f # skip card mark if null
+ movl offMethod_clazz(%eax),%eax # eax<- method->clazz
movl offGlue_cardTable(%ecx),%ecx # get card table base
shrl $GC_CARD_SHIFT,%eax # head to card number
movb %cl,(%ecx,%eax) # mark card
diff --git a/vm/mterp/x86/OP_APUT_OBJECT.S b/vm/mterp/x86/OP_APUT_OBJECT.S
index 8ffbb03..f9af064 100644
--- a/vm/mterp/x86/OP_APUT_OBJECT.S
+++ b/vm/mterp/x86/OP_APUT_OBJECT.S
@@ -24,23 +24,25 @@
*/
.L${opcode}_continue:
leal offArrayObject_contents(%eax,%ecx,4),%ecx
- testl rINST,rINST # storing null reference?
+ testl rINST,rINST # storing null reference?
je .L${opcode}_skip_check
- SPILL_TMP1(%ecx)
- movl offObject_clazz(%eax),%eax # eax<- arrayObj->clazz
- movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz
+ SPILL_TMP1(%ecx) # save target address
+ SPILL_TMP2(%eax) # save object head
+ movl offObject_clazz(%eax),%eax # eax<- arrayObj->clazz
+ movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz
movl %eax,OUT_ARG1(%esp)
movl %ecx,OUT_ARG0(%esp)
- call dvmCanPutArrayElement # test object type vs. array type
- UNSPILL_TMP1(%ecx)
+ call dvmCanPutArrayElement # test object type vs. array type
+ UNSPILL_TMP1(%ecx) # recover target address
testl %eax,%eax
movl rGLUE,%eax
je common_errArrayStore
movl offGlue_cardTable(%eax),%eax # get card table base
- movl rINST,(%ecx)
+ movl rINST,(%ecx) # store into array
+ UNSPILL_TMP2(%ecx) # recover object head
FETCH_INST_OPCODE 2 %edx
- shrl $$GC_CARD_SHIFT,%ecx # convert addr to card number
- movb %al,(%eax,%ecx) # mark card
+ shrl $$GC_CARD_SHIFT,%ecx # object head to card number
+ movb %al,(%eax,%ecx) # mark card using object head
ADVANCE_PC 2
GOTO_NEXT_R %edx
diff --git a/vm/mterp/x86/OP_FILLED_NEW_ARRAY.S b/vm/mterp/x86/OP_FILLED_NEW_ARRAY.S
index 60974ac..dc11dd2 100644
--- a/vm/mterp/x86/OP_FILLED_NEW_ARRAY.S
+++ b/vm/mterp/x86/OP_FILLED_NEW_ARRAY.S
@@ -114,7 +114,7 @@
movl offGlue_retval(%ecx),%eax # eax<- object head
movl offGlue_cardTable(%ecx),%ecx # card table base
shrl $$GC_CARD_SHIFT,%eax # convert to card num
- movb %cl,(%ecx,%eax) # mark card
+ movb %cl,(%ecx,%eax) # mark card based on object head
5:
ADVANCE_PC 3
GOTO_NEXT_R %edx
diff --git a/vm/mterp/x86/OP_IPUT_OBJECT.S b/vm/mterp/x86/OP_IPUT_OBJECT.S
index a9a99ea..03dcb08 100644
--- a/vm/mterp/x86/OP_IPUT_OBJECT.S
+++ b/vm/mterp/x86/OP_IPUT_OBJECT.S
@@ -58,7 +58,7 @@
FETCH_INST_OPCODE 2 %edx
je 1f # skip card mark if null store
shrl $$GC_CARD_SHIFT,%ecx # object head to card number
- movb %al,(%eax,%ecx) # mark card
+ movb %al,(%eax,%ecx) # mark card using object head
1:
ADVANCE_PC 2
GOTO_NEXT_R %edx
diff --git a/vm/mterp/x86/OP_IPUT_OBJECT_QUICK.S b/vm/mterp/x86/OP_IPUT_OBJECT_QUICK.S
index 8e8c47d..7fa99a8 100644
--- a/vm/mterp/x86/OP_IPUT_OBJECT_QUICK.S
+++ b/vm/mterp/x86/OP_IPUT_OBJECT_QUICK.S
@@ -21,7 +21,7 @@
movl offGlue_cardTable(%eax),%eax # get card table base
je 1f # skip card mark if null store
shrl $$GC_CARD_SHIFT,%ecx # object head to card number
- movb %al,(%eax,%ecx) # mark card
+ movb %al,(%eax,%ecx) # mark card based on object head
1:
ADVANCE_PC 2
GOTO_NEXT_R %edx
diff --git a/vm/mterp/x86/OP_SPUT_OBJECT.S b/vm/mterp/x86/OP_SPUT_OBJECT.S
index f9e0be1..f198cce 100644
--- a/vm/mterp/x86/OP_SPUT_OBJECT.S
+++ b/vm/mterp/x86/OP_SPUT_OBJECT.S
@@ -13,7 +13,7 @@
movl (%ecx,%eax,4),%eax # eax<- resolved StaticField
testl %eax,%eax # resolved entry null?
je .L${opcode}_resolve # if not, make it so
-.L${opcode}_finish: # field ptr in eax
+.L${opcode}_finish: # field ptr in eax
movzbl rINSTbl,%ecx # ecx<- AA
GET_VREG_R %ecx %ecx
jmp .L${opcode}_continue
@@ -21,11 +21,13 @@
.L${opcode}_continue:
- movl %ecx,offStaticField_value(%eax)
- testl %ecx,%ecx
+ movl %ecx,offStaticField_value(%eax) # do the store
+ testl %ecx,%ecx # stored null object ptr?
movl rGLUE,%ecx
FETCH_INST_OPCODE 2 %edx
- je 1f
+ movl offGlue_method(%ecx),%eax # eax<- current method
+ je 1f # skip card mark if null
+ movl offMethod_clazz(%eax),%eax # eax<- method->clazz
movl offGlue_cardTable(%ecx),%ecx # get card table base
shrl $$GC_CARD_SHIFT,%eax # head to card number
movb %cl,(%ecx,%eax) # mark card