void Page::ClearRSet() {
-#ifndef V8_HOST_ARCH_64_BIT
// This method can be called in all rset states.
memset(RSetStart(), 0, kRSetEndOffset - kRSetStartOffset);
-#endif
}
-// Give an address a (32-bits):
+// Given a 32-bit address, separate its bits into:
// | page address | words (6) | bit offset (5) | pointer alignment (2) |
-// The rset address is computed as:
+// The address of the rset word containing the bit for this word is computed as:
// page_address + words * 4
+// For a 64-bit address, if it is:
+// | page address | quadwords(5) | bit offset(5) | pointer alignment (3) |
+// The address of the rset word containing the bit for this word is computed as:
+// page_address + quadwords * 4 + kRSetOffset.
+// The rset is accessed as 32-bit words, and bit offsets in a 32-bit word,
+// even on the X64 architecture.
Address Page::ComputeRSetBitPosition(Address address, int offset,
uint32_t* bitmask) {
*bitmask = 1 << (bit_offset % kBitsPerInt);
Address rset_address =
- page->address() + (bit_offset / kBitsPerInt) * kIntSize;
+ page->address() + kRSetOffset + (bit_offset / kBitsPerInt) * kIntSize;
// The remembered set address is either in the normal remembered set range
// of a page or else we have a large object page.
ASSERT((page->RSetStart() <= rset_address && rset_address < page->RSetEnd())
// of the object:
// (rset_address - page->ObjectAreaStart()).
// Ie, we can just add the object size.
+ // In the X64 architecture, the remembered set ends before the object start,
+ // so we need to add an additional offset, from rset end to object start
ASSERT(HeapObject::FromAddress(address)->IsFixedArray());
- rset_address +=
+ rset_address += kObjectStartOffset - kRSetEndOffset +
FixedArray::SizeFor(Memory::int_at(page->ObjectAreaStart()
+ Array::kLengthOffset));
}
bool Page::IsRSetSet(Address address, int offset) {
-#ifdef V8_HOST_ARCH_64_BIT
- // TODO(X64): Reenable when RSet works.
- return true;
-#else // V8_HOST_ARCH_64_BIT
uint32_t bitmask = 0;
Address rset_address = ComputeRSetBitPosition(address, offset, &bitmask);
return (Memory::uint32_at(rset_address) & bitmask) != 0;
-#endif // V8_HOST_ARCH_64_BIT
}
// bytes are used as remembered set, and the rest of the page is the object
// area.
//
-// Pointers are aligned to the pointer size (4 bytes), only 1 bit is needed
+// Pointers are aligned to the pointer size (4), only 1 bit is needed
// for a pointer in the remembered set. Given an address, its remembered set
// bit position (offset from the start of the page) is calculated by dividing
// its page offset by 32. Therefore, the object area in a page starts at the
// 256th byte (8K/32). Bytes 0 to 255 do not need the remembered set, so that
// the first two words (64 bits) in a page can be used for other purposes.
// TODO(X64): This description only represents the 32-bit layout.
+// On the 64-bit platform, we add an offset to the start of the remembered set.
//
// The mark-compact collector transforms a map pointer into a page index and a
// page offset. The map space can have up to 1024 pages, and 8M bytes (1024 *
// Page size mask.
static const intptr_t kPageAlignmentMask = (1 << kPageSizeBits) - 1;
+ // The offset of the remembered set in a page, in addition to the empty words
+ // formed as the remembered bits of the remembered set itself.
+#ifdef V8_TARGET_ARCH_X64
+ static const int kRSetOffset = 4 * kPointerSize; // Room for four pointers.
+#else
+ static const int kRSetOffset = 0;
+#endif
// The end offset of the remembered set in a page
// (heaps are aligned to pointer size).
- static const int kRSetEndOffset= kPageSize / kBitsPerPointer;
-
- // The start offset of the remembered set in a page.
- static const int kRSetStartOffset = kRSetEndOffset / kBitsPerPointer;
+ static const int kRSetEndOffset = kRSetOffset + kPageSize / kBitsPerPointer;
// The start offset of the object area in a page.
static const int kObjectStartOffset = kRSetEndOffset;
+ // The start offset of the remembered set in a page.
+ static const int kRSetStartOffset = kRSetOffset +
+ kObjectStartOffset / kBitsPerPointer;
+
// Object area size in bytes.
static const int kObjectAreaSize = kPageSize - kObjectStartOffset;