spaces-inl.h revision 85b71799222b55eb5dd74ea26efe0c64ab655c8c
185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch// Copyright 2006-2010 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_SPACES_INL_H_ 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_SPACES_INL_H_ 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "isolate.h" 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "spaces.h" 3344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "v8memory.h" 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 4085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch// PageIterator 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochbool PageIterator::has_next() { 4385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return prev_page_ != stop_page_; 4485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 4585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 4685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 4785b71799222b55eb5dd74ea26efe0c64ab655c8cBen MurdochPage* PageIterator::next() { 4885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ASSERT(has_next()); 4985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch prev_page_ = (prev_page_ == NULL) 5085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ? space_->first_page_ 5185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch : prev_page_->next_page(); 5285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return prev_page_; 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 5785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch// Page 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5985b71799222b55eb5dd74ea26efe0c64ab655c8cBen MurdochPage* Page::next_page() { 6085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return heap_->isolate()->memory_allocator()->GetNextPage(this); 6185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6485b71799222b55eb5dd74ea26efe0c64ab655c8cBen MurdochAddress Page::AllocationTop() { 6585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch PagedSpace* owner = heap_->isolate()->memory_allocator()->PageOwner(this); 6685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return owner->PageAllocationTop(this); 6785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 7085b71799222b55eb5dd74ea26efe0c64ab655c8cBen MurdochAddress Page::AllocationWatermark() { 7185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch PagedSpace* owner = heap_->isolate()->memory_allocator()->PageOwner(this); 7285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (this == owner->AllocationTopPage()) { 7385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return owner->top(); 7485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 7585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return address() + AllocationWatermarkOffset(); 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochuint32_t Page::AllocationWatermarkOffset() { 8085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return static_cast<uint32_t>((flags_ & kAllocationWatermarkOffsetMask) >> 8185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch kAllocationWatermarkOffsetShift); 827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 8585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochvoid Page::SetAllocationWatermark(Address allocation_watermark) { 8685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if ((heap_->gc_state() == Heap::SCAVENGE) && IsWatermarkValid()) { 8785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // When iterating intergenerational references during scavenge 8885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // we might decide to promote an encountered young object. 8985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // We will allocate a space for such an object and put it 9085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // into the promotion queue to process it later. 9185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // If space for object was allocated somewhere beyond allocation 9285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // watermark this might cause garbage pointers to appear under allocation 9385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // watermark. To avoid visiting them during dirty regions iteration 9485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // which might be still in progress we store a valid allocation watermark 9585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // value and mark this page as having an invalid watermark. 9685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch SetCachedAllocationWatermark(AllocationWatermark()); 9785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch InvalidateWatermark(true); 9885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 9985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 10085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch flags_ = (flags_ & kFlagsMask) | 10185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch Offset(allocation_watermark) << kAllocationWatermarkOffsetShift; 10285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ASSERT(AllocationWatermarkOffset() 10385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch == static_cast<uint32_t>(Offset(allocation_watermark))); 10485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 1057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 10785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochvoid Page::SetCachedAllocationWatermark(Address allocation_watermark) { 10885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch mc_first_forwarded = allocation_watermark; 10985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 1107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 11285b71799222b55eb5dd74ea26efe0c64ab655c8cBen MurdochAddress Page::CachedAllocationWatermark() { 11385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return mc_first_forwarded; 1147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 11785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochuint32_t Page::GetRegionMarks() { 11885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return dirty_regions_; 1197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 12285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochvoid Page::SetRegionMarks(uint32_t marks) { 12385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch dirty_regions_ = marks; 1247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 12785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochint Page::GetRegionNumberForAddress(Address addr) { 12885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // Each page is divided into 256 byte regions. Each region has a corresponding 12985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // dirty mark bit in the page header. Region can contain intergenerational 13085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // references iff its dirty mark is set. 13185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // A normal 8K page contains exactly 32 regions so all region marks fit 13285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // into 32-bit integer field. To calculate a region number we just divide 13385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // offset inside page by region size. 13485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // A large page can contain more then 32 regions. But we want to avoid 13585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // additional write barrier code for distinguishing between large and normal 13685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // pages so we just ignore the fact that addr points into a large page and 13785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // calculate region number as if addr pointed into a normal 8K page. This way 13885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // we get a region number modulo 32 so for large pages several regions might 13985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // be mapped to a single dirty mark. 14085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ASSERT_PAGE_ALIGNED(this->address()); 14185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch STATIC_ASSERT((kPageAlignmentMask >> kRegionSizeLog2) < kBitsPerInt); 14285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 14385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // We are using masking with kPageAlignmentMask instead of Page::Offset() 14485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // to get an offset to the beginning of 8K page containing addr not to the 14585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // beginning of actual page which can be bigger then 8K. 14685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch intptr_t offset_inside_normal_page = OffsetFrom(addr) & kPageAlignmentMask; 14785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return static_cast<int>(offset_inside_normal_page >> kRegionSizeLog2); 14885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 14985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 15085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 15185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochuint32_t Page::GetRegionMaskForAddress(Address addr) { 15285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return 1 << GetRegionNumberForAddress(addr); 15385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 15485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 15585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 15685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochuint32_t Page::GetRegionMaskForSpan(Address start, int length_in_bytes) { 15785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch uint32_t result = 0; 15885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch static const intptr_t kRegionMask = (1 << kRegionSizeLog2) - 1; 15985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (length_in_bytes + (OffsetFrom(start) & kRegionMask) >= kPageSize) { 16085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch result = kAllRegionsDirtyMarks; 16185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } else if (length_in_bytes > 0) { 16285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch int start_region = GetRegionNumberForAddress(start); 16385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch int end_region = 16485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch GetRegionNumberForAddress(start + length_in_bytes - kPointerSize); 16585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch uint32_t start_mask = (~0) << start_region; 16685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch uint32_t end_mask = ~((~1) << end_region); 16785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch result = start_mask & end_mask; 16885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // if end_region < start_region, the mask is ored. 16985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (result == 0) result = start_mask | end_mask; 17085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 17185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch#ifdef DEBUG 17285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (FLAG_enable_slow_asserts) { 17385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch uint32_t expected = 0; 17485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch for (Address a = start; a < start + length_in_bytes; a += kPointerSize) { 17585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch expected |= GetRegionMaskForAddress(a); 1767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 17785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ASSERT(expected == result); 1787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 17985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch#endif 18085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return result; 1817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 18485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochvoid Page::MarkRegionDirty(Address address) { 18585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch SetRegionMarks(GetRegionMarks() | GetRegionMaskForAddress(address)); 18685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 1877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 18985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochbool Page::IsRegionDirty(Address address) { 19085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return GetRegionMarks() & GetRegionMaskForAddress(address); 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 19485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochvoid Page::ClearRegionMarks(Address start, Address end, bool reaches_limit) { 19585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch int rstart = GetRegionNumberForAddress(start); 19685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch int rend = GetRegionNumberForAddress(end); 19785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 19885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (reaches_limit) { 19985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch end += 1; 20085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 2017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 20285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if ((rend - rstart) == 0) { 20385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return; 20485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 2057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 20685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch uint32_t bitmask = 0; 20785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 20885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if ((OffsetFrom(start) & kRegionAlignmentMask) == 0 20985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch || (start == ObjectAreaStart())) { 21085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // First region is fully covered 21185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch bitmask = 1 << rstart; 21285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 21385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 21485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch while (++rstart < rend) { 21585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch bitmask |= 1 << rstart; 21685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 21785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 21885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (bitmask) { 21985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch SetRegionMarks(GetRegionMarks() & ~bitmask); 22085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 2217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 22485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochvoid Page::FlipMeaningOfInvalidatedWatermarkFlag(Heap* heap) { 22585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch heap->page_watermark_invalidated_mark_ ^= 1 << WATERMARK_INVALIDATED; 2267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 22985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochbool Page::IsWatermarkValid() { 23085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return (flags_ & (1 << WATERMARK_INVALIDATED)) != 23185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch heap_->page_watermark_invalidated_mark_; 23285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 2337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 23585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochvoid Page::InvalidateWatermark(bool value) { 23685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (value) { 23785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch flags_ = (flags_ & ~(1 << WATERMARK_INVALIDATED)) | 23885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch heap_->page_watermark_invalidated_mark_; 23985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } else { 24085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch flags_ = 24185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch (flags_ & ~(1 << WATERMARK_INVALIDATED)) | 24285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch (heap_->page_watermark_invalidated_mark_ ^ 24385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch (1 << WATERMARK_INVALIDATED)); 24485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 2457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 24685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ASSERT(IsWatermarkValid() == !value); 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 25085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochbool Page::GetPageFlag(PageFlag flag) { 25185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return (flags_ & static_cast<intptr_t>(1 << flag)) != 0; 2526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 2536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 25585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochvoid Page::SetPageFlag(PageFlag flag, bool value) { 25685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (value) { 25785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch flags_ |= static_cast<intptr_t>(1 << flag); 2586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 25985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch flags_ &= ~static_cast<intptr_t>(1 << flag); 2606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 26185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 26285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 26385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 26485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochvoid Page::ClearPageFlags() { 26585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch flags_ = 0; 26685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 26785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 26885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 26985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochvoid Page::ClearGCFields() { 27085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch InvalidateWatermark(true); 27185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch SetAllocationWatermark(ObjectAreaStart()); 27285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (heap_->gc_state() == Heap::SCAVENGE) { 27385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch SetCachedAllocationWatermark(ObjectAreaStart()); 2747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 27585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch SetRegionMarks(kAllRegionsCleanMarks); 2767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 27985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochbool Page::WasInUseBeforeMC() { 28085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return GetPageFlag(WAS_IN_USE_BEFORE_MC); 28185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 2826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 28485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochvoid Page::SetWasInUseBeforeMC(bool was_in_use) { 28585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch SetPageFlag(WAS_IN_USE_BEFORE_MC, was_in_use); 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochbool Page::IsLargeObjectPage() { 29085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return !GetPageFlag(IS_NORMAL_PAGE); 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 29485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochvoid Page::SetIsLargeObjectPage(bool is_large_object_page) { 29585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch SetPageFlag(IS_NORMAL_PAGE, !is_large_object_page); 29685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 29785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 29885b71799222b55eb5dd74ea26efe0c64ab655c8cBen MurdochExecutability Page::PageExecutability() { 29985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return GetPageFlag(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE; 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochvoid Page::SetPageExecutability(Executability executable) { 30485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch SetPageFlag(IS_EXECUTABLE, executable == EXECUTABLE); 30585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 30685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 30785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 30885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch// ----------------------------------------------------------------------------- 30985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch// MemoryAllocator 31085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 31185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochvoid MemoryAllocator::ChunkInfo::init(Address a, size_t s, PagedSpace* o) { 31285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch address_ = a; 31385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch size_ = s; 31485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch owner_ = o; 31585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch executable_ = (o == NULL) ? NOT_EXECUTABLE : o->executable(); 31685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch owner_identity_ = (o == NULL) ? FIRST_SPACE : o->identity(); 31785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 31885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 31985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 32085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochbool MemoryAllocator::IsValidChunk(int chunk_id) { 32185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (!IsValidChunkId(chunk_id)) return false; 32285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 32385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ChunkInfo& c = chunks_[chunk_id]; 32485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return (c.address() != NULL) && (c.size() != 0) && (c.owner() != NULL); 32585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 32685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 32785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 32885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochbool MemoryAllocator::IsValidChunkId(int chunk_id) { 32985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return (0 <= chunk_id) && (chunk_id < max_nof_chunks_); 33085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 33185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 33285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 33385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochbool MemoryAllocator::IsPageInSpace(Page* p, PagedSpace* space) { 33485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ASSERT(p->is_valid()); 33585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 33685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch int chunk_id = GetChunkId(p); 33785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (!IsValidChunkId(chunk_id)) return false; 33885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 33985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ChunkInfo& c = chunks_[chunk_id]; 34085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return (c.address() <= p->address()) && 34185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch (p->address() < c.address() + c.size()) && 34285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch (space == c.owner()); 34385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 34485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 34585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 34685b71799222b55eb5dd74ea26efe0c64ab655c8cBen MurdochPage* MemoryAllocator::GetNextPage(Page* p) { 34785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ASSERT(p->is_valid()); 34885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch intptr_t raw_addr = p->opaque_header & ~Page::kPageAlignmentMask; 34985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return Page::FromAddress(AddressFrom<Address>(raw_addr)); 35085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 35185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 35285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 35385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochint MemoryAllocator::GetChunkId(Page* p) { 35485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ASSERT(p->is_valid()); 35585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return static_cast<int>(p->opaque_header & Page::kPageAlignmentMask); 35685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 35785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 35885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 35985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochvoid MemoryAllocator::SetNextPage(Page* prev, Page* next) { 36085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ASSERT(prev->is_valid()); 36185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch int chunk_id = GetChunkId(prev); 36285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ASSERT_PAGE_ALIGNED(next->address()); 36385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch prev->opaque_header = OffsetFrom(next->address()) | chunk_id; 36485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 36585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 36685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 36785b71799222b55eb5dd74ea26efe0c64ab655c8cBen MurdochPagedSpace* MemoryAllocator::PageOwner(Page* page) { 36885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch int chunk_id = GetChunkId(page); 36985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ASSERT(IsValidChunk(chunk_id)); 37085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return chunks_[chunk_id].owner(); 37185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 37285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 37385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 37485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochbool MemoryAllocator::InInitialChunk(Address address) { 37585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (initial_chunk_ == NULL) return false; 37685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 37785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch Address start = static_cast<Address>(initial_chunk_->address()); 37885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return (start <= address) && (address < start + initial_chunk_->size()); 37985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch} 38085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 38185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 38285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch// -------------------------------------------------------------------------- 38385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch// PagedSpace 38485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 38585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochbool PagedSpace::Contains(Address addr) { 38685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch Page* p = Page::FromAddress(addr); 38785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (!p->is_valid()) return false; 38885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return heap()->isolate()->memory_allocator()->IsPageInSpace(p, this); 389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Try linear allocation in the page of alloc_info's allocation top. Does 39385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch// not contain slow case logic (eg, move to the next page or try free list 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// allocation) so it can be used by all the allocation functions and for all 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the paged spaces. 39685b71799222b55eb5dd74ea26efe0c64ab655c8cBen MurdochHeapObject* PagedSpace::AllocateLinearly(AllocationInfo* alloc_info, 39785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch int size_in_bytes) { 39885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch Address current_top = alloc_info->top; 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address new_top = current_top + size_in_bytes; 40085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (new_top > alloc_info->limit) return NULL; 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch alloc_info->top = new_top; 40385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ASSERT(alloc_info->VerifyPagedAllocation()); 40485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch accounting_stats_.AllocateBytes(size_in_bytes); 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return HeapObject::FromAddress(current_top); 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Raw allocation. 4105913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* PagedSpace::AllocateRaw(int size_in_bytes) { 41185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ASSERT(HasBeenSetup()); 41285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ASSERT_OBJECT_SIZE(size_in_bytes); 41385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch HeapObject* object = AllocateLinearly(&allocation_info_, size_in_bytes); 41485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (object != NULL) return object; 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block object = SlowAllocateRaw(size_in_bytes); 41785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (object != NULL) return object; 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 419f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return Failure::RetryAfterGC(identity()); 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 42385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch// Reallocating (and promoting) objects during a compacting collection. 42485b71799222b55eb5dd74ea26efe0c64ab655c8cBen MurdochMaybeObject* PagedSpace::MCAllocateRaw(int size_in_bytes) { 42585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ASSERT(HasBeenSetup()); 42685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ASSERT_OBJECT_SIZE(size_in_bytes); 42785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch HeapObject* object = AllocateLinearly(&mc_forwarding_info_, size_in_bytes); 42885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (object != NULL) return object; 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 43085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch object = SlowMCAllocateRaw(size_in_bytes); 43185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (object != NULL) return object; 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 43385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return Failure::RetryAfterGC(identity()); 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 43785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch// ----------------------------------------------------------------------------- 43885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch// NewSpace 43985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 44085b71799222b55eb5dd74ea26efe0c64ab655c8cBen MurdochMaybeObject* NewSpace::AllocateRawInternal(int size_in_bytes, 44185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch AllocationInfo* alloc_info) { 44285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch Address new_top = alloc_info->top + size_in_bytes; 44385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch if (new_top > alloc_info->limit) return Failure::RetryAfterGC(); 44485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 44585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch Object* obj = HeapObject::FromAddress(alloc_info->top); 44685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch alloc_info->top = new_top; 44785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch#ifdef DEBUG 44885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch SemiSpace* space = 44985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch (alloc_info == &allocation_info_) ? &to_space_ : &from_space_; 45085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ASSERT(space->low() <= alloc_info->top 45185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch && alloc_info->top <= space->high() 45285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch && alloc_info->limit == space->high()); 45385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch#endif 45485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return obj; 455592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 456592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 457592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 45844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockintptr_t LargeObjectSpace::Available() { 45985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return LargeObjectChunk::ObjectSizeFor( 46085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch heap()->isolate()->memory_allocator()->Available()); 46144f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 46244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 46344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochtemplate <typename StringType> 465b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid NewSpace::ShrinkStringAtAllocationBoundary(String* string, int length) { 466b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(length <= string->length()); 467b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(string->IsSeqString()); 468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(string->address() + StringType::SizeFor(string->length()) == 469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch allocation_info_.top); 470b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch allocation_info_.top = 471b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch string->address() + StringType::SizeFor(length); 472b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch string->set_length(length); 473b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 474b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 475b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockbool FreeListNode::IsFreeListNode(HeapObject* object) { 47785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch return object->map() == HEAP->raw_unchecked_byte_array_map() 47885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch || object->map() == HEAP->raw_unchecked_one_pointer_filler_map() 47985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch || object->map() == HEAP->raw_unchecked_two_pointer_filler_map(); 4803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 4813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_SPACES_INL_H_ 485