Index: src/arm/macro-assembler-arm.cc |
=================================================================== |
--- src/arm/macro-assembler-arm.cc (revision 4722) |
+++ src/arm/macro-assembler-arm.cc (working copy) |
@@ -252,21 +252,63 @@ |
bind(¬_in_new_space); |
} |
- mov(ip, Operand(Page::kPageAlignmentMask)); // Load mask only once. |
+ // This is how much we shift the remembered set bit offset to get the |
+ // offset of the word in the remembered set. We divide by kBitsPerInt (32, |
+ // shift right 5) and then multiply by kIntSize (4, shift left 2). |
+ const int kRSetWordShift = 3; |
- // Calculate region number. |
- add(offset, object, Operand(offset)); // Add offset into the object. |
- and_(offset, offset, Operand(ip)); // Offset into page of the object. |
- mov(offset, Operand(offset, LSR, Page::kRegionSizeLog2)); |
+ Label fast; |
- // Calculate page address. |
+ // Compute the bit offset in the remembered set. |
+ // object: heap object pointer (with tag) |
+ // offset: offset to store location from the object |
+ mov(ip, Operand(Page::kPageAlignmentMask)); // load mask only once |
+ and_(scratch, object, Operand(ip)); // offset into page of the object |
+ add(offset, scratch, Operand(offset)); // add offset into the object |
+ mov(offset, Operand(offset, LSR, kObjectAlignmentBits)); |
+ |
+ // Compute the page address from the heap object pointer. |
+ // object: heap object pointer (with tag) |
+ // offset: bit offset of store position in the remembered set |
bic(object, object, Operand(ip)); |
- // Mark region dirty. |
- ldr(scratch, MemOperand(object, Page::kDirtyFlagOffset)); |
+ // If the bit offset lies beyond the normal remembered set range, it is in |
+ // the extra remembered set area of a large object. |
+ // object: page start |
+ // offset: bit offset of store position in the remembered set |
+ cmp(offset, Operand(Page::kPageSize / kPointerSize)); |
+ b(lt, &fast); |
+ |
+ // Adjust the bit offset to be relative to the start of the extra |
+ // remembered set and the start address to be the address of the extra |
+ // remembered set. |
+ sub(offset, offset, Operand(Page::kPageSize / kPointerSize)); |
+ // Load the array length into 'scratch' and multiply by four to get the |
+ // size in bytes of the elements. |
+ ldr(scratch, MemOperand(object, Page::kObjectStartOffset |
+ + FixedArray::kLengthOffset)); |
+ mov(scratch, Operand(scratch, LSL, kObjectAlignmentBits)); |
+ // Add the page header (including remembered set), array header, and array |
+ // body size to the page address. |
+ add(object, object, Operand(Page::kObjectStartOffset |
+ + FixedArray::kHeaderSize)); |
+ add(object, object, Operand(scratch)); |
+ |
+ bind(&fast); |
+ // Get address of the rset word. |
+ // object: start of the remembered set (page start for the fast case) |
+ // offset: bit offset of store position in the remembered set |
+ bic(scratch, offset, Operand(kBitsPerInt - 1)); // clear the bit offset |
+ add(object, object, Operand(scratch, LSR, kRSetWordShift)); |
+ // Get bit offset in the rset word. |
+ // object: address of remembered set word |
+ // offset: bit offset of store position |
+ and_(offset, offset, Operand(kBitsPerInt - 1)); |
+ |
+ ldr(scratch, MemOperand(object)); |
mov(ip, Operand(1)); |
orr(scratch, scratch, Operand(ip, LSL, offset)); |
- str(scratch, MemOperand(object, Page::kDirtyFlagOffset)); |
+ str(scratch, MemOperand(object)); |
} |
@@ -294,7 +336,7 @@ |
Label done; |
// First, test that the object is not in the new space. We cannot set |
- // region marks for new space pages. |
+ // remembered set bits in the new space. |
InNewSpace(object, scratch, eq, &done); |
// Record the actual write. |
@@ -577,7 +619,6 @@ |
ldr(expected_reg, |
FieldMemOperand(code_reg, |
SharedFunctionInfo::kFormalParameterCountOffset)); |
- mov(expected_reg, Operand(expected_reg, ASR, kSmiTagSize)); |
ldr(code_reg, |
MemOperand(code_reg, SharedFunctionInfo::kCodeOffset - kHeapObjectTag)); |
add(code_reg, code_reg, Operand(Code::kHeaderSize - kHeapObjectTag)); |