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