13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2011 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_HEAP_SPACES_INL_H_
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_HEAP_SPACES_INL_H_
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/spaces.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap-profiler.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/isolate.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/msan.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8memory.h"
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Bitmap
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Bitmap::Clear(MemoryChunk* chunk) {
223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Bitmap* bitmap = chunk->markbits();
233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int i = 0; i < bitmap->CellsCount(); i++) bitmap->cells()[i] = 0;
243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  chunk->ResetLiveBytes();
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// PageIterator
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
323ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochPageIterator::PageIterator(PagedSpace* space)
333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    : space_(space),
343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      prev_page_(&space->anchor_),
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      next_page_(prev_page_->next_page()) {}
367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
3785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool PageIterator::has_next() { return next_page_ != &space_->anchor_; }
397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
413ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochPage* PageIterator::next() {
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(has_next());
433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  prev_page_ = next_page_;
443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  next_page_ = next_page_->next_page();
453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return prev_page_;
4685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch}
477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// -----------------------------------------------------------------------------
503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// NewSpacePageIterator
517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
533ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochNewSpacePageIterator::NewSpacePageIterator(NewSpace* space)
543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    : prev_page_(NewSpacePage::FromAddress(space->ToSpaceStart())->prev_page()),
553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      next_page_(NewSpacePage::FromAddress(space->ToSpaceStart())),
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      last_page_(NewSpacePage::FromLimit(space->ToSpaceEnd())) {}
577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
583ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochNewSpacePageIterator::NewSpacePageIterator(SemiSpace* space)
593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    : prev_page_(space->anchor()),
603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      next_page_(prev_page_->next_page()),
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      last_page_(prev_page_->prev_page()) {}
627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
633ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochNewSpacePageIterator::NewSpacePageIterator(Address start, Address limit)
643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    : prev_page_(NewSpacePage::FromAddress(start)->prev_page()),
653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      next_page_(NewSpacePage::FromAddress(start)),
663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      last_page_(NewSpacePage::FromLimit(limit)) {
673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  SemiSpace::AssertValidRange(start, limit);
687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool NewSpacePageIterator::has_next() { return prev_page_ != last_page_; }
7285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
7385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
743ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochNewSpacePage* NewSpacePageIterator::next() {
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(has_next());
763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  prev_page_ = next_page_;
773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  next_page_ = next_page_->next_page();
783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return prev_page_;
7985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch}
8085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
8185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// -----------------------------------------------------------------------------
833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// HeapObjectIterator
843ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHeapObject* HeapObjectIterator::FromCurrentPage() {
853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  while (cur_addr_ != cur_end_) {
863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (cur_addr_ == space_->top() && cur_addr_ != space_->limit()) {
873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      cur_addr_ = space_->limit();
883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      continue;
893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    HeapObject* obj = HeapObject::FromAddress(cur_addr_);
913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int obj_size = (size_func_ == NULL) ? obj->Size() : size_func_(obj);
923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    cur_addr_ += obj_size;
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(cur_addr_ <= cur_end_);
943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!obj->IsFiller()) {
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK_OBJECT_SIZE(obj_size);
963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return obj;
977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    }
987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return NULL;
1007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
1017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// -----------------------------------------------------------------------------
1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// MemoryAllocator
1057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef ENABLE_HEAP_PROTECTION
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MemoryAllocator::Protect(Address start, size_t size) {
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::OS::Protect(start, size);
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MemoryAllocator::Unprotect(Address start, size_t size,
1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                Executability executable) {
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::OS::Unprotect(start, size, executable);
1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
11785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
11885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MemoryAllocator::ProtectChunkFromPage(Page* page) {
1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int id = GetChunkId(page);
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::OS::Protect(chunks_[id].address(), chunks_[id].size());
1227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
1237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MemoryAllocator::UnprotectChunkFromPage(Page* page) {
1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int id = GetChunkId(page);
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::OS::Unprotect(chunks_[id].address(), chunks_[id].size(),
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      chunks_[id].owner()->executable() == EXECUTABLE);
1297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
1307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif
1327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// --------------------------------------------------------------------------
1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// PagedSpace
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochPage* Page::Initialize(Heap* heap, MemoryChunk* chunk, Executability executable,
1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       PagedSpace* owner) {
1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Page* page = reinterpret_cast<Page*>(chunk);
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(page->area_size() <= kMaxRegularHeapObjectSize);
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(chunk->owner() == owner);
1413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  owner->IncreaseCapacity(page->area_size());
1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  owner->Free(page->area_start(), page->area_size());
1437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  heap->incremental_marking()->SetOldSpacePageFlags(chunk);
1457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return page;
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool PagedSpace::Contains(Address addr) {
1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Page* p = Page::FromAddress(addr);
1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!p->is_valid()) return false;
1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return p->owner() == this;
1546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
1556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MemoryChunk::set_scan_on_scavenge(bool scan) {
1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (scan) {
1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!scan_on_scavenge()) heap_->increment_scan_on_scavenge_pages();
1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    SetFlag(SCAN_ON_SCAVENGE);
1616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  } else {
1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (scan_on_scavenge()) heap_->decrement_scan_on_scavenge_pages();
1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ClearFlag(SCAN_ON_SCAVENGE);
1646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  heap_->incremental_marking()->SetOldSpacePageFlags(this);
1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMemoryChunk* MemoryChunk::FromAnyPointerAddress(Heap* heap, Address addr) {
1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MemoryChunk* maybe = reinterpret_cast<MemoryChunk*>(
1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      OffsetFrom(addr) & ~Page::kPageAlignmentMask);
1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (maybe->owner() != NULL) return maybe;
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LargeObjectIterator iterator(heap->lo_space());
1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (HeapObject* o = iterator.Next(); o != NULL; o = iterator.Next()) {
1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Fixed arrays are the only pointer-containing objects in large object
1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // space.
1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (o->IsFixedArray()) {
1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      MemoryChunk* chunk = MemoryChunk::FromAddress(o->address());
1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (chunk->Contains(addr)) {
1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        return chunk;
1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
1837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  UNREACHABLE();
1853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return NULL;
1867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
1877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MemoryChunk::UpdateHighWaterMark(Address mark) {
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mark == NULL) return;
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Need to subtract one from the mark because when a chunk is full the
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // top points to the next address after the chunk, which effectively belongs
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to another chunk. See the comment to Page::FromAllocationTop.
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemoryChunk* chunk = MemoryChunk::FromAddress(mark - 1);
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int new_mark = static_cast<int>(mark - chunk->address());
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (new_mark > chunk->high_water_mark_) {
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    chunk->high_water_mark_ = new_mark;
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochPointerChunkIterator::PointerChunkIterator(Heap* heap)
2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    : state_(kOldPointerState),
2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      old_pointer_iterator_(heap->old_pointer_space()),
2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      map_iterator_(heap->map_space()),
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      lo_iterator_(heap->lo_space()) {}
2076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochPage* Page::next_page() {
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(next_chunk()->owner() == owner());
2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return static_cast<Page*>(next_chunk());
21285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch}
21385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
21485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
2153ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochPage* Page::prev_page() {
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(prev_chunk()->owner() == owner());
2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return static_cast<Page*>(prev_chunk());
21885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch}
21985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
22085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Page::set_next_page(Page* page) {
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(page->owner() == owner());
2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  set_next_chunk(page);
22485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch}
22585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
22685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Page::set_prev_page(Page* page) {
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(page->owner() == owner());
2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  set_prev_chunk(page);
230b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Try linear allocation in the page of alloc_info's allocation top.  Does
2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// not contain slow case logic (e.g. move to the next page or try free list
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// allocation) so it can be used by all the allocation functions and for all
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the paged spaces.
2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHeapObject* PagedSpace::AllocateLinearly(int size_in_bytes) {
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address current_top = allocation_info_.top();
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Address new_top = current_top + size_in_bytes;
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (new_top > allocation_info_.limit()) return NULL;
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  allocation_info_.set_top(new_top);
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return HeapObject::FromAddress(current_top);
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Raw allocation.
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult PagedSpace::AllocateRaw(int size_in_bytes) {
2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HeapObject* object = AllocateLinearly(size_in_bytes);
2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (object == NULL) {
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    object = free_list_.Allocate(size_in_bytes);
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (object == NULL) {
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      object = SlowAllocateRaw(size_in_bytes);
2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (object != NULL) {
2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (identity() == CODE_SPACE) {
2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SkipList::Update(object->address(), size_in_bytes);
2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MSAN_ALLOCATED_UNINITIALIZED_MEMORY(object->address(), size_in_bytes);
2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return object;
2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return AllocationResult::Retry(identity());
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// -----------------------------------------------------------------------------
2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// NewSpace
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAllocationResult NewSpace::AllocateRaw(int size_in_bytes) {
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address old_top = allocation_info_.top();
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (allocation_info_.limit() - old_top < size_in_bytes) {
2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return SlowAllocateRaw(size_in_bytes);
2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapObject* obj = HeapObject::FromAddress(old_top);
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  allocation_info_.set_top(allocation_info_.top() + size_in_bytes);
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The slow path above ultimately goes through AllocateRaw, so this suffices.
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MSAN_ALLOCATED_UNINITIALIZED_MEMORY(obj->address(), size_in_bytes);
28785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
28885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  return obj;
289592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch}
290592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
291592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochLargePage* LargePage::Initialize(Heap* heap, MemoryChunk* chunk) {
2933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  heap->incremental_marking()->SetOldSpacePageFlags(chunk);
2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return static_cast<LargePage*>(chunk);
2953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
2963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
29844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockintptr_t LargeObjectSpace::Available() {
2993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return ObjectSizeFor(heap()->isolate()->memory_allocator()->Available());
30044f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
30144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
30244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
3033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockbool FreeListNode::IsFreeListNode(HeapObject* object) {
3043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Map* map = object->map();
3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Heap* heap = object->GetHeap();
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return map == heap->raw_unchecked_free_space_map() ||
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         map == heap->raw_unchecked_one_pointer_filler_map() ||
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         map == heap->raw_unchecked_two_pointer_filler_map();
3093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8::internal
3123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_HEAP_SPACES_INL_H_
314