From 1058f300b117f809c1e0d42afd451cc558cc0afd Mon Sep 17 00:00:00 2001 From: "whesse@chromium.org" Date: Thu, 2 Jul 2009 07:48:05 +0000 Subject: [PATCH] X64: Move remembered set to a safe location on x64 platform. Review URL: http://codereview.chromium.org/151148 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2331 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/spaces-inl.h | 23 ++++++++++++----------- src/spaces.h | 19 ++++++++++++++----- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/spaces-inl.h b/src/spaces-inl.h index 2f01164f89..8b2eab0c45 100644 --- a/src/spaces-inl.h +++ b/src/spaces-inl.h @@ -93,17 +93,21 @@ Address Page::AllocationTop() { 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) { @@ -115,7 +119,7 @@ Address Page::ComputeRSetBitPosition(Address address, int offset, *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()) @@ -131,8 +135,10 @@ Address Page::ComputeRSetBitPosition(Address address, int offset, // 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)); } @@ -160,14 +166,9 @@ void Page::UnsetRSet(Address address, int offset) { 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 } diff --git a/src/spaces.h b/src/spaces.h index 8ce807fcd4..299a7644d2 100644 --- a/src/spaces.h +++ b/src/spaces.h @@ -93,13 +93,14 @@ class AllocationInfo; // 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 * @@ -217,16 +218,24 @@ class Page { // 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;