1fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org// Copyright 2011 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 53e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#ifndef V8_HEAP_SPACES_H_ 63e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define V8_HEAP_SPACES_H_ 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/allocation.h" 91e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org#include "src/base/atomicops.h" 1021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org#include "src/base/bits.h" 115de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/platform/mutex.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hashmap.h" 13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/list.h" 14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/log.h" 15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/utils.h" 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 1871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 20ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgclass Isolate; 21ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------- 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Heap structures: 2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A JS heap consists of a young generation, an old generation, and a large 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// object space. The young generation is divided into two semispaces. A 2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// scavenger implements Cheney's copying algorithm. The old generation is 2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// separated into a map space and an old object space. The map space contains 2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// all (and only) map objects, the rest of old objects go into the old space. 3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The old generation is collected by a mark-sweep-compact collector. 3143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 3243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The semispaces of the young generation are contiguous. The old and map 3330ce411529579186181838984710b0b0980857aaricow@chromium.org// spaces consists of a list of pages. A page has a page header and an object 34c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// area. 3543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// There is a separate large object space for objects larger than 3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Page::kMaxHeapObjectSize, so that they do not have to move during 3830ce411529579186181838984710b0b0980857aaricow@chromium.org// collection. The large object space is paged. Pages in large object space 39c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// may be larger than the page size. 4030ce411529579186181838984710b0b0980857aaricow@chromium.org// 41c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// A store-buffer based write barrier is used to keep track of intergenerational 4231c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org// references. See heap/store-buffer.h. 4330ce411529579186181838984710b0b0980857aaricow@chromium.org// 44c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// During scavenges and mark-sweep collections we sometimes (after a store 45c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// buffer overflow) iterate intergenerational pointers without decoding heap 46c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// object maps so if the page belongs to old pointer space or large object 47c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// space it is essential to guarantee that the page does not contain any 48c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// garbage pointers to new space: every pointer aligned word which satisfies 49c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// the Heap::InNewSpace() predicate must be a pointer to a live heap object in 50c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// new space. Thus objects in old pointer and large object spaces should have a 51c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// special layout (e.g. no bare integer fields). This requirement does not 52c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// apply to map space which is iterated in a special fashion. However we still 53c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// require pointer fields of dead maps to be cleaned. 5430ce411529579186181838984710b0b0980857aaricow@chromium.org// 55c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// To enable lazy cleaning of old space pages we can mark chunks of the page 56c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// as being garbage. Garbage sections are marked with a special map. These 57c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// sections are skipped when scanning the page, even if we are otherwise 58c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// scanning without regard for object boundaries. Garbage sections are chained 59c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// together to form a free list after a GC. Garbage sections created outside 60c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// of GCs by object trunctation etc. may not be in the free list chain. Very 61c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// small free spaces are ignored, they need only be cleaned of bogus pointers 62c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// into new space. 6343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 64c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Each page may have up to one special garbage section. The start of this 65c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// section is denoted by the top field in the space. The end of the section 66c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// is denoted by the limit field in the space. This special garbage section 67c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// is not marked with a free space map in the data. The point of this section 68c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// is to enable linear allocation without having to constantly update the byte 69c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// array every time the top field is updated and a new object is created. The 70c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// special garbage section is not in the chain of garbage sections. 71c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// 72c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Since the top and limit fields are in the space, not the page, only one page 73c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// has a special garbage section, and if the top and limit are equal then there 74c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// is no special garbage section. 7543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 7643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Some assertion macros used in the debugging mode. 7743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define DCHECK_PAGE_ALIGNED(address) \ 79e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((OffsetFrom(address) & Page::kPageAlignmentMask) == 0) 8043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define DCHECK_OBJECT_ALIGNED(address) \ 82e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((OffsetFrom(address) & kObjectAlignmentMask) == 0) 8343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define DCHECK_OBJECT_SIZE(size) \ 85e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((0 < size) && (size <= Page::kMaxRegularHeapObjectSize)) 8643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 873e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define DCHECK_PAGE_OFFSET(offset) \ 883e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org DCHECK((Page::kObjectStartOffset <= offset) && (offset <= Page::kPageSize)) 8943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 903e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#define DCHECK_MAP_PAGE_INDEX(index) \ 91e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((0 <= index) && (index <= MapSpace::kMaxMapPageIndex)) 9243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 9343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 9443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass PagedSpace; 9543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass MemoryAllocator; 967276f14ca716596e0a0d17539516370c1f453847kasper.lundclass AllocationInfo; 97c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass Space; 98c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass FreeList; 99c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass MemoryChunk; 100c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 101c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass MarkBit { 102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 103c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com typedef uint32_t CellType; 104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 105c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline MarkBit(CellType* cell, CellType mask, bool data_only) 1063e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org : cell_(cell), mask_(mask), data_only_(data_only) {} 107c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 108c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline CellType* cell() { return cell_; } 109c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline CellType mask() { return mask_; } 110c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef DEBUG 112c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool operator==(const MarkBit& other) { 113c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return cell_ == other.cell_ && mask_ == other.mask_; 114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif 116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 117c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline void Set() { *cell_ |= mask_; } 118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline bool Get() { return (*cell_ & mask_) != 0; } 119c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline void Clear() { *cell_ &= ~mask_; } 120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline bool data_only() { return data_only_; } 122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline MarkBit Next() { 124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CellType new_mask = mask_ << 1; 125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (new_mask == 0) { 126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return MarkBit(cell_ + 1, 1, data_only_); 127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return MarkBit(cell_, new_mask, data_only_); 129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private: 133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CellType* cell_; 134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CellType mask_; 135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // This boolean indicates that the object is in a data-only space with no 136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // pointers. This enables some optimizations when marking. 137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // It is expected that this field is inlined and turned into control flow 138c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // at the place where the MarkBit object is created. 139c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool data_only_; 140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 142c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Bitmap is a sequence of cells each containing fixed number of bits. 144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass Bitmap { 145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const uint32_t kBitsPerCell = 32; 147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const uint32_t kBitsPerCellLog2 = 5; 148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const uint32_t kBitIndexMask = kBitsPerCell - 1; 149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const uint32_t kBytesPerCell = kBitsPerCell / kBitsPerByte; 150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const uint32_t kBytesPerCellLog2 = kBitsPerCellLog2 - kBitsPerByteLog2; 151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org static const size_t kLength = (1 << kPageSizeBits) >> (kPointerSizeLog2); 153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 154c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const size_t kSize = 1553e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org (1 << kPageSizeBits) >> (kPointerSizeLog2 + kBitsPerByteLog2); 156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static int CellsForLength(int length) { 159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return (length + kBitsPerCell - 1) >> kBitsPerCellLog2; 160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org int CellsCount() { return CellsForLength(kLength); } 163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static int SizeFor(int cells_count) { 165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return sizeof(MarkBit::CellType) * cells_count; 166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com INLINE(static uint32_t IndexToCell(uint32_t index)) { 169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return index >> kBitsPerCellLog2; 170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 172c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com INLINE(static uint32_t CellToIndex(uint32_t index)) { 173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return index << kBitsPerCellLog2; 174c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com INLINE(static uint32_t CellAlignIndex(uint32_t index)) { 177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return (index + kBitIndexMask) & ~kBitIndexMask; 178c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 180c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com INLINE(MarkBit::CellType* cells()) { 181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return reinterpret_cast<MarkBit::CellType*>(this); 182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org INLINE(Address address()) { return reinterpret_cast<Address>(this); } 185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 186c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com INLINE(static Bitmap* FromAddress(Address addr)) { 187c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return reinterpret_cast<Bitmap*>(addr); 188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 189c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 190c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline MarkBit MarkBitFromIndex(uint32_t index, bool data_only = false) { 191c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit::CellType mask = 1 << (index & kBitIndexMask); 192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MarkBit::CellType* cell = this->cells() + (index >> kBitsPerCellLog2); 193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return MarkBit(cell, mask, data_only); 194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static inline void Clear(MemoryChunk* chunk); 197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static void PrintWord(uint32_t word, uint32_t himask = 0) { 199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (uint32_t mask = 1; mask != 0; mask <<= 1) { 200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((mask & himask) != 0) PrintF("["); 201c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PrintF((mask & word) ? "1" : "0"); 202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((mask & himask) != 0) PrintF("]"); 203c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 204c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com class CellPrinter { 207c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 2083e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org CellPrinter() : seq_start(0), seq_type(0), seq_length(0) {} 209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void Print(uint32_t pos, uint32_t cell) { 211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (cell == seq_type) { 212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com seq_length++; 213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return; 214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Flush(); 217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (IsSeq(cell)) { 219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com seq_start = pos; 220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com seq_length = 0; 221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com seq_type = cell; 222c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return; 223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 224c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PrintF("%d: ", pos); 226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PrintWord(cell); 227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PrintF("\n"); 228c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void Flush() { 231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (seq_length > 0) { 2323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org PrintF("%d: %dx%d\n", seq_start, seq_type == 0 ? 0 : 1, 233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com seq_length * kBitsPerCell); 234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com seq_length = 0; 235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static bool IsSeq(uint32_t cell) { return cell == 0 || cell == 0xFFFFFFFF; } 239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private: 241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com uint32_t seq_start; 242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com uint32_t seq_type; 243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com uint32_t seq_length; 244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com }; 245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 246c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void Print() { 247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CellPrinter printer; 248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = 0; i < CellsCount(); i++) { 249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com printer.Print(i, cells()[i]); 250c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 251c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com printer.Flush(); 252c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PrintF("\n"); 253c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 255c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool IsClean() { 256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = 0; i < CellsCount(); i++) { 25733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org if (cells()[i] != 0) { 25833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org return false; 25933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } 260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return true; 262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 265c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 266c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass SkipList; 267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass SlotsBuffer; 268c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 269c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// MemoryChunk represents a memory region owned by a specific space. 270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// It is divided into the header and the body. Chunk start is always 2712efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// 1MB aligned. Start of the body is aligned so it can accommodate 272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// any heap object. 273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass MemoryChunk { 274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Only works if the pointer is in the first kPageSize of the MemoryChunk. 276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static MemoryChunk* FromAddress(Address a) { 277c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return reinterpret_cast<MemoryChunk*>(OffsetFrom(a) & ~kAlignmentMask); 278c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2794b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org static const MemoryChunk* FromAddress(const byte* a) { 2803e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org return reinterpret_cast<const MemoryChunk*>(OffsetFrom(a) & 2813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org ~kAlignmentMask); 2824b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org } 283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 284c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Only works for addresses in pointer spaces, not data or code spaces. 285c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org static inline MemoryChunk* FromAnyPointerAddress(Heap* heap, Address addr); 286c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 287c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address address() { return reinterpret_cast<Address>(this); } 288c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 289c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool is_valid() { return address() != NULL; } 290c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 291f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org MemoryChunk* next_chunk() const { 2921e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org return reinterpret_cast<MemoryChunk*>(base::Acquire_Load(&next_chunk_)); 293f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 294f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 295f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org MemoryChunk* prev_chunk() const { 2961e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org return reinterpret_cast<MemoryChunk*>(base::Acquire_Load(&prev_chunk_)); 297f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 2981e71c4d02b6ae995c57bf1f7f3ce99a4ef88eba5mstarzinger@chromium.org 299f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void set_next_chunk(MemoryChunk* next) { 3001e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org base::Release_Store(&next_chunk_, reinterpret_cast<base::AtomicWord>(next)); 301f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 302f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 303f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void set_prev_chunk(MemoryChunk* prev) { 3041e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org base::Release_Store(&prev_chunk_, reinterpret_cast<base::AtomicWord>(prev)); 305f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 306c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 307c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Space* owner() const { 3082b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org if ((reinterpret_cast<intptr_t>(owner_) & kPageHeaderTagMask) == 3092b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org kPageHeaderTag) { 310e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org return reinterpret_cast<Space*>(reinterpret_cast<intptr_t>(owner_) - 3112b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org kPageHeaderTag); 312c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 313c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return NULL; 314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 317c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void set_owner(Space* space) { 318e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((reinterpret_cast<intptr_t>(space) & kPageHeaderTagMask) == 0); 3192b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org owner_ = reinterpret_cast<Address>(space) + kPageHeaderTag; 320e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((reinterpret_cast<intptr_t>(owner_) & kPageHeaderTagMask) == 3212b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org kPageHeaderTag); 322c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org base::VirtualMemory* reserved_memory() { return &reservation_; } 325c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3263e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org void InitializeReservedMemory() { reservation_.Reset(); } 327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3285de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org void set_reserved_memory(base::VirtualMemory* reservation) { 329e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_NOT_NULL(reservation); 330c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com reservation_.TakeControl(reservation); 331c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 332c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 333c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool scan_on_scavenge() { return IsFlagSet(SCAN_ON_SCAVENGE); } 334c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void initialize_scan_on_scavenge(bool scan) { 335c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (scan) { 336c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SetFlag(SCAN_ON_SCAVENGE); 337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ClearFlag(SCAN_ON_SCAVENGE); 339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 341c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline void set_scan_on_scavenge(bool scan); 342c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 343c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int store_buffer_counter() { return store_buffer_counter_; } 344c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void set_store_buffer_counter(int counter) { 345c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com store_buffer_counter_ = counter; 346c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 347c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 348c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool Contains(Address addr) { 349ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org return addr >= area_start() && addr < area_end(); 350c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 351c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 352c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Checks whether addr can be a limit of addresses in this page. 353c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // It's a limit if it's in the page, or if it's just after the 354c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // last byte of the page. 355c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool ContainsLimit(Address addr) { 356ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org return addr >= area_start() && addr <= area_end(); 357c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 358c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 35933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org // Every n write barrier invocations we go to runtime even though 36033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org // we could have handled it in generated code. This lets us check 36133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org // whether we have hit the limit and should do some more marking. 36233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org static const int kWriteBarrierCounterGranularity = 500; 36333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org 364c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com enum MemoryChunkFlags { 365c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com IS_EXECUTABLE, 366c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ABOUT_TO_BE_FREED, 367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com POINTERS_TO_HERE_ARE_INTERESTING, 368c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com POINTERS_FROM_HERE_ARE_INTERESTING, 369c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SCAN_ON_SCAVENGE, 370c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com IN_FROM_SPACE, // Mutually exclusive with IN_TO_SPACE. 371c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com IN_TO_SPACE, // All pages in new space has one of these two set. 372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NEW_SPACE_BELOW_AGE_MARK, 373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CONTAINS_ONLY_DATA, 374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com EVACUATION_CANDIDATE, 375c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RESCAN_ON_EVACUATION, 376c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 377a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org // WAS_SWEPT indicates that marking bits have been cleared by the sweeper, 378a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org // otherwise marking bits are still intact. 379a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org WAS_SWEPT, 380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 381fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Large objects can have a progress bar in their page header. These object 382fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // are scanned in increments and will be kept black while being scanned. 383fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Even if the mutator writes to them they will be kept black and a white 384fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // to grey transition is performed in the value. 385fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org HAS_PROGRESS_BAR, 386fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 387c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Last flag, keep at bottom. 388c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NUM_MEMORY_CHUNK_FLAGS 389c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com }; 390c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 392c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const int kPointersToHereAreInterestingMask = 393c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1 << POINTERS_TO_HERE_ARE_INTERESTING; 394c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 395c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const int kPointersFromHereAreInterestingMask = 396c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1 << POINTERS_FROM_HERE_ARE_INTERESTING; 397c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org static const int kEvacuationCandidateMask = 1 << EVACUATION_CANDIDATE; 399c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 400c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const int kSkipEvacuationSlotsRecordingMask = 4013e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org (1 << EVACUATION_CANDIDATE) | (1 << RESCAN_ON_EVACUATION) | 4023e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org (1 << IN_FROM_SPACE) | (1 << IN_TO_SPACE); 403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4053e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org void SetFlag(int flag) { flags_ |= static_cast<uintptr_t>(1) << flag; } 406c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4073e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org void ClearFlag(int flag) { flags_ &= ~(static_cast<uintptr_t>(1) << flag); } 408c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 409c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void SetFlagTo(int flag, bool value) { 410c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (value) { 411c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SetFlag(flag); 412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 413c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ClearFlag(flag); 414c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 415c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 416c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 417c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool IsFlagSet(int flag) { 418c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return (flags_ & (static_cast<uintptr_t>(1) << flag)) != 0; 419c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 420c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 421c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Set or clear multiple flags at a time. The flags in the mask 422c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // are set to the value in "flags", the rest retain the current value 423c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // in flags_. 424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void SetFlags(intptr_t flags, intptr_t mask) { 425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com flags_ = (flags_ & ~mask) | (flags & mask); 426c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 427c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 428c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Return all current flags. 429c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com intptr_t GetFlags() { return flags_; } 430c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 431f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 432474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // SWEEPING_DONE - The page state when sweeping is complete or sweeping must 433474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // not be performed on that page. 434474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // SWEEPING_FINALIZE - A sweeper thread is done sweeping this page and will 435474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // not touch the page memory anymore. 436474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // SWEEPING_IN_PROGRESS - This page is currently swept by a sweeper thread. 437474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // SWEEPING_PENDING - This page is ready for parallel sweeping. 438f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org enum ParallelSweepingState { 439474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org SWEEPING_DONE, 440474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org SWEEPING_FINALIZE, 441474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org SWEEPING_IN_PROGRESS, 442474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org SWEEPING_PENDING 443f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org }; 444f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 445f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ParallelSweepingState parallel_sweeping() { 446f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return static_cast<ParallelSweepingState>( 4471e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org base::Acquire_Load(¶llel_sweeping_)); 448e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org } 449e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 450f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void set_parallel_sweeping(ParallelSweepingState state) { 4511e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org base::Release_Store(¶llel_sweeping_, state); 452e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org } 453e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 454e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org bool TryParallelSweeping() { 4553e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org return base::Acquire_CompareAndSwap(¶llel_sweeping_, SWEEPING_PENDING, 4563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org SWEEPING_IN_PROGRESS) == 4573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org SWEEPING_PENDING; 458e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org } 459e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 4602b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org bool SweepingCompleted() { return parallel_sweeping() <= SWEEPING_FINALIZE; } 4612b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org 462c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Manage live byte count (count of bytes known to be live, 463c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // because they are marked black). 464c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void ResetLiveBytes() { 465b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org if (FLAG_gc_verbose) { 4663e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org PrintF("ResetLiveBytes:%p:%x->0\n", static_cast<void*>(this), 4673e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org live_byte_count_); 468c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 469c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com live_byte_count_ = 0; 470c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 471c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void IncrementLiveBytes(int by) { 472b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org if (FLAG_gc_verbose) { 4733e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org printf("UpdateLiveBytes:%p:%x%c=%x->%x\n", static_cast<void*>(this), 4743e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org live_byte_count_, ((by < 0) ? '-' : '+'), ((by < 0) ? -by : by), 475c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com live_byte_count_ + by); 476c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 477c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com live_byte_count_ += by; 478e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_LE(static_cast<unsigned>(live_byte_count_), size_); 479c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 480c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int LiveBytes() { 481e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(static_cast<unsigned>(live_byte_count_) <= size_); 482c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return live_byte_count_; 483c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 4842efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 48533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org int write_barrier_counter() { 48633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org return static_cast<int>(write_barrier_counter_); 48733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } 48833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org 48933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org void set_write_barrier_counter(int counter) { 49033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org write_barrier_counter_ = counter; 49133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } 49233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org 493fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org int progress_bar() { 494e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsFlagSet(HAS_PROGRESS_BAR)); 495fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org return progress_bar_; 496fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 497fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 498fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org void set_progress_bar(int progress_bar) { 499e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsFlagSet(HAS_PROGRESS_BAR)); 500fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org progress_bar_ = progress_bar; 501fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 502fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 503fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org void ResetProgressBar() { 504fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR)) { 505fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org set_progress_bar(0); 506fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ClearFlag(MemoryChunk::HAS_PROGRESS_BAR); 507fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 508fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 509fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 51083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org bool IsLeftOfProgressBar(Object** slot) { 51183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org Address slot_address = reinterpret_cast<Address>(slot); 512e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(slot_address > this->address()); 51383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org return (slot_address - (this->address() + kObjectStartOffset)) < 51483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org progress_bar(); 51583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org } 51633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org 5172efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org static void IncrementLiveBytesFromGC(Address address, int by) { 518c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk::FromAddress(address)->IncrementLiveBytes(by); 519c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 520c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5212efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org static void IncrementLiveBytesFromMutator(Address address, int by); 5222efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 523c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const intptr_t kAlignment = 524c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com (static_cast<uintptr_t>(1) << kPageSizeBits); 525c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 526c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const intptr_t kAlignmentMask = kAlignment - 1; 527c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 528f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static const intptr_t kSizeOffset = 0; 529c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 530c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const intptr_t kLiveBytesOffset = 5313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org kSizeOffset + kPointerSize + kPointerSize + kPointerSize + kPointerSize + 5323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org kPointerSize + kPointerSize + kPointerSize + kPointerSize + kIntSize; 533c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 534c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const size_t kSlotsBufferOffset = kLiveBytesOffset + kIntSize; 535c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 53633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org static const size_t kWriteBarrierCounterOffset = 537c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kSlotsBufferOffset + kPointerSize + kPointerSize; 538c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5393e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org static const size_t kHeaderSize = 5403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org kWriteBarrierCounterOffset + kPointerSize + kIntSize + kIntSize + 5413e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org kPointerSize + 5 * kPointerSize + kPointerSize + kPointerSize; 54233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org 543c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const int kBodyOffset = 54489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org CODE_POINTER_ALIGN(kHeaderSize + Bitmap::kSize); 545c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 546c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The start offset of the object area in a page. Aligned to both maps and 547c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // code alignment to be suitable for both. Also aligned to 32 words because 548c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the marking bitmap is arranged in 32 bit chunks. 549c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const int kObjectStartAlignment = 32 * kPointerSize; 5503e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org static const int kObjectStartOffset = 5513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org kBodyOffset - 1 + 552c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com (kObjectStartAlignment - (kBodyOffset - 1) % kObjectStartAlignment); 553c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 554c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t size() const { return size_; } 555c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org void set_size(size_t size) { size_ = size; } 5572c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 5589a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org void SetArea(Address area_start, Address area_end) { 5599a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org area_start_ = area_start; 5609a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org area_end_ = area_end; 5619a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org } 5629a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 563c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Executability executable() { 564c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return IsFlagSet(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE; 565c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 566c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5673e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org bool ContainsOnlyData() { return IsFlagSet(CONTAINS_ONLY_DATA); } 568c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 569c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool InNewSpace() { 570c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return (flags_ & ((1 << IN_FROM_SPACE) | (1 << IN_TO_SPACE))) != 0; 571c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 572c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5733e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org bool InToSpace() { return IsFlagSet(IN_TO_SPACE); } 574c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5753e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org bool InFromSpace() { return IsFlagSet(IN_FROM_SPACE); } 576c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 577c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // --------------------------------------------------------------------- 578c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Markbits support 579c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 580c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline Bitmap* markbits() { 581c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return Bitmap::FromAddress(address() + kHeaderSize); 582c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 583c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 584c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void PrintMarkbits() { markbits()->Print(); } 585c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 586c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline uint32_t AddressToMarkbitIndex(Address addr) { 587c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return static_cast<uint32_t>(addr - this->address()) >> kPointerSizeLog2; 588c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 589c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 590c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline static uint32_t FastAddressToMarkbitIndex(Address addr) { 5913e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org const intptr_t offset = reinterpret_cast<intptr_t>(addr) & kAlignmentMask; 592c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 593c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return static_cast<uint32_t>(offset) >> kPointerSizeLog2; 594c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 595c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 596c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline Address MarkbitIndexToAddress(uint32_t index) { 597c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return this->address() + (index << kPointerSizeLog2); 598c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 599c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 600c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void InsertAfter(MemoryChunk* other); 601c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void Unlink(); 602c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 6034b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org inline Heap* heap() const { return heap_; } 604c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 605f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static const int kFlagsOffset = kPointerSize; 606c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 607c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool IsEvacuationCandidate() { return IsFlagSet(EVACUATION_CANDIDATE); } 608c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 609c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool ShouldSkipEvacuationSlotRecording() { 610c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return (flags_ & kSkipEvacuationSlotsRecordingMask) != 0; 611c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 612c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 6133e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org inline SkipList* skip_list() { return skip_list_; } 614c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 6153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org inline void set_skip_list(SkipList* skip_list) { skip_list_ = skip_list; } 616c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 6173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org inline SlotsBuffer* slots_buffer() { return slots_buffer_; } 618c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 6193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org inline SlotsBuffer** slots_buffer_address() { return &slots_buffer_; } 620c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 621c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void MarkEvacuationCandidate() { 622e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(slots_buffer_ == NULL); 623c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SetFlag(EVACUATION_CANDIDATE); 624c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 625c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 626c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void ClearEvacuationCandidate() { 627e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(slots_buffer_ == NULL); 628c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ClearFlag(EVACUATION_CANDIDATE); 629c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 630c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 631ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org Address area_start() { return area_start_; } 632ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org Address area_end() { return area_end_; } 6333e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org int area_size() { return static_cast<int>(area_end() - area_start()); } 634068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org bool CommitArea(size_t requested); 635c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 63672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // Approximate amount of physical memory committed for this chunk. 6373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org size_t CommittedPhysicalMemory() { return high_water_mark_; } 63872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org 63972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org static inline void UpdateHighWaterMark(Address mark); 64072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org 641c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com protected: 642c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t size_; 643c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com intptr_t flags_; 644ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org 645ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org // Start and end of allocatable memory on this chunk. 646ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org Address area_start_; 647ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org Address area_end_; 648ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org 649c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If the chunk needs to remember its memory reservation, it is stored here. 6505de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::VirtualMemory reservation_; 651c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The identity of the owning space. This is tagged as a failure pointer, but 652c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // no failure can be in an object, so this can be distinguished from any entry 653c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // in a fixed array. 654c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address owner_; 655c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Heap* heap_; 656c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Used by the store buffer to keep track of which pages to mark scan-on- 657c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // scavenge. 658c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int store_buffer_counter_; 659c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Count of bytes marked black on page. 660c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int live_byte_count_; 661c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SlotsBuffer* slots_buffer_; 662c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SkipList* skip_list_; 66333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org intptr_t write_barrier_counter_; 664fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Used by the incremental marker to keep track of the scanning progress in 665fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // large objects that have a progress bar and are scanned in increments. 666fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org int progress_bar_; 66772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // Assuming the initial allocation on a page is sequential, 66872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // count highest number of bytes ever allocated on the page. 66972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org int high_water_mark_; 670c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 6711e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org base::AtomicWord parallel_sweeping_; 672e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 673e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // PagedSpace free-list statistics. 674e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org intptr_t available_in_small_free_list_; 675e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org intptr_t available_in_medium_free_list_; 676e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org intptr_t available_in_large_free_list_; 677e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org intptr_t available_in_huge_free_list_; 678e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org intptr_t non_available_small_blocks_; 679e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 6803e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org static MemoryChunk* Initialize(Heap* heap, Address base, size_t size, 6813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Address area_start, Address area_end, 6823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Executability executable, Space* owner); 683c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 684f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org private: 685f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // next_chunk_ holds a pointer of type MemoryChunk 6861e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org base::AtomicWord next_chunk_; 687f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // prev_chunk_ holds a pointer of type MemoryChunk 6881e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org base::AtomicWord prev_chunk_; 689f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 690c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com friend class MemoryAllocator; 691c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 692c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 6937d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org 694d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgSTATIC_ASSERT(sizeof(MemoryChunk) <= MemoryChunk::kHeaderSize); 69543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 6967d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org 69743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------- 698c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// A page is a memory chunk of a size 1MB. Large object pages may be larger. 69943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 70043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The only way to get a page pointer is by calling factory methods: 70143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Page* p = Page::FromAddress(addr); or 70243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Page* p = Page::FromAllocationTop(top); 703c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass Page : public MemoryChunk { 70443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 70543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns the page containing a given address. The address ranges 70643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // from [page_addr .. page_addr + kPageSize[ 707c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // This only works if the object is in fact in a page. See also MemoryChunk:: 708c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // FromAddress() and FromAnyAddress(). 70943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen INLINE(static Page* FromAddress(Address a)) { 71043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return reinterpret_cast<Page*>(OffsetFrom(a) & ~kPageAlignmentMask); 71143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 71243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 71343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns the page containing an allocation top. Because an allocation 71443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // top address can be the upper bound of the page, we need to subtract 71543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // it with kPointerSize first. The address ranges from 71643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // [page_addr + kObjectStartOffset .. page_addr + kPageSize]. 71743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen INLINE(static Page* FromAllocationTop(Address top)) { 71843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Page* p = FromAddress(top - kPointerSize); 71943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return p; 72043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 72143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 722c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Returns the next page in the chain of pages owned by a space. 72343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen inline Page* next_page(); 724c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline Page* prev_page(); 725c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline void set_next_page(Page* page); 726c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline void set_prev_page(Page* page); 72730ce411529579186181838984710b0b0980857aaricow@chromium.org 72843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Checks whether an address is page aligned. 72943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static bool IsAlignedToPageSize(Address a) { 73043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 0 == (OffsetFrom(a) & kPageAlignmentMask); 73143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 73243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 73343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns the offset of a given address to this page. 73443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen INLINE(int Offset(Address a)) { 735c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org int offset = static_cast<int>(a - address()); 73643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return offset; 73743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 73843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 73943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns the address for a given offset to the this page. 74043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Address OffsetToAddress(int offset) { 741e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_PAGE_OFFSET(offset); 74243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return address() + offset; 74343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 74443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 74543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // --------------------------------------------------------------------- 74643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 7479258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // Page size in bytes. This must be a multiple of the OS page size. 74843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int kPageSize = 1 << kPageSizeBits; 74943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 75083fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org // Maximum object size that fits in a page. Objects larger than that size 75183fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org // are allocated in large object space and are never moved in memory. This 75283fa61bdece6aab611027f148c2075f07ce708b7hpayer@chromium.org // also applies to new space allocation, since objects are never migrated 753594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // from new space to large object space. Takes double alignment into account. 754ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org static const int kMaxRegularHeapObjectSize = kPageSize - kObjectStartOffset; 75530ce411529579186181838984710b0b0980857aaricow@chromium.org 756ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org // Page size mask. 757ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org static const intptr_t kPageAlignmentMask = (1 << kPageSizeBits) - 1; 75830ce411529579186181838984710b0b0980857aaricow@chromium.org 759c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline void ClearGCFields(); 76030ce411529579186181838984710b0b0980857aaricow@chromium.org 7613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org static inline Page* Initialize(Heap* heap, MemoryChunk* chunk, 7623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Executability executable, PagedSpace* owner); 76330ce411529579186181838984710b0b0980857aaricow@chromium.org 764c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void InitializeAsAnchor(PagedSpace* owner); 76530ce411529579186181838984710b0b0980857aaricow@chromium.org 766a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org bool WasSwept() { return IsFlagSet(WAS_SWEPT); } 767a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org void SetWasSwept() { SetFlag(WAS_SWEPT); } 768a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org void ClearWasSwept() { ClearFlag(WAS_SWEPT); } 76943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 770e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org void ResetFreeListStatistics(); 771e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 772e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#define FRAGMENTATION_STATS_ACCESSORS(type, name) \ 773e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org type name() { return name##_; } \ 774e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org void set_##name(type name) { name##_ = name; } \ 775e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org void add_##name(type name) { name##_ += name; } 776e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 777e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org FRAGMENTATION_STATS_ACCESSORS(intptr_t, non_available_small_blocks) 778e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_small_free_list) 779e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_medium_free_list) 780e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_large_free_list) 781e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_huge_free_list) 782e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 783e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#undef FRAGMENTATION_STATS_ACCESSORS 784e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 785c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef DEBUG 786c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void Print(); 787c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif // DEBUG 78843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 789c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com friend class MemoryAllocator; 790c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 79143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 792ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 793d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgSTATIC_ASSERT(sizeof(Page) <= MemoryChunk::kHeaderSize); 794c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 795c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 796c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass LargePage : public MemoryChunk { 797c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 7983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org HeapObject* GetObject() { return HeapObject::FromAddress(area_start()); } 799c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 800c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline LargePage* next_page() const { 801c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return static_cast<LargePage*>(next_chunk()); 802c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 803c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 8043e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org inline void set_next_page(LargePage* page) { set_next_chunk(page); } 8053e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 806c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private: 807c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static inline LargePage* Initialize(Heap* heap, MemoryChunk* chunk); 808c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 809c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com friend class MemoryAllocator; 81043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 81143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 812d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgSTATIC_ASSERT(sizeof(LargePage) <= MemoryChunk::kHeaderSize); 81343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 81443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 8157276f14ca716596e0a0d17539516370c1f453847kasper.lund// Space is the abstract superclass for all allocation spaces. 8167276f14ca716596e0a0d17539516370c1f453847kasper.lundclass Space : public Malloced { 8177276f14ca716596e0a0d17539516370c1f453847kasper.lund public: 818ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Space(Heap* heap, AllocationSpace id, Executability executable) 819ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org : heap_(heap), id_(id), executable_(executable) {} 820f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org 8219258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org virtual ~Space() {} 822f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org 823ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Heap* heap() const { return heap_; } 824ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 8257276f14ca716596e0a0d17539516370c1f453847kasper.lund // Does the space need executable memory? 8269258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org Executability executable() { return executable_; } 827f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org 8287276f14ca716596e0a0d17539516370c1f453847kasper.lund // Identity used in error reporting. 8297276f14ca716596e0a0d17539516370c1f453847kasper.lund AllocationSpace identity() { return id_; } 830f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org 8314a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Returns allocated size. 832f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org virtual intptr_t Size() = 0; 833f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org 8344a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Returns size of objects. Can differ from the allocated size 8354a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // (e.g. see LargeObjectSpace). 8364a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com virtual intptr_t SizeOfObjects() { return Size(); } 8374a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 838c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual int RoundSizeDownToObjectAlignment(int size) { 839c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (id_ == CODE_SPACE) { 840c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return RoundDown(size, kCodeAlignment); 841c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 842c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return RoundDown(size, kPointerSize); 843c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 844c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 845c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 8469258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org#ifdef DEBUG 8479258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org virtual void Print() = 0; 8489258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org#endif 849f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org 8507276f14ca716596e0a0d17539516370c1f453847kasper.lund private: 851ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Heap* heap_; 8527276f14ca716596e0a0d17539516370c1f453847kasper.lund AllocationSpace id_; 8539258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org Executability executable_; 8547276f14ca716596e0a0d17539516370c1f453847kasper.lund}; 8557276f14ca716596e0a0d17539516370c1f453847kasper.lund 8567276f14ca716596e0a0d17539516370c1f453847kasper.lund 8577276f14ca716596e0a0d17539516370c1f453847kasper.lund// ---------------------------------------------------------------------------- 858c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org// All heap objects containing executable code (code objects) must be allocated 859c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org// from a 2 GB range of memory, so that they can call each other using 32-bit 860c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org// displacements. This happens automatically on 32-bit platforms, where 32-bit 861c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org// displacements cover the entire 4GB virtual address space. On 64-bit 862c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org// platforms, we support this using the CodeRange object, which reserves and 863c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org// manages a range of virtual memory. 864ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgclass CodeRange { 865c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org public: 8667c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org explicit CodeRange(Isolate* isolate); 86728a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org ~CodeRange() { TearDown(); } 8687c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 869c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Reserves a range of virtual memory, but does not commit any of it. 870c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Can only be called once, at heap initialization time. 871c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Returns false on failure. 8725b080567cf135f6dbaf23973ba6b6fa1d6af83b3machenbach@chromium.org bool SetUp(size_t requested_size); 873c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 874c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Frees the range of virtual memory, and frees the data structures used to 875c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // manage it. 876ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org void TearDown(); 877c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 8781845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org bool valid() { return code_range_ != NULL; } 8796e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org Address start() { 880e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(valid()); 8816e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org return static_cast<Address>(code_range_->address()); 8826e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org } 883ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org bool contains(Address address) { 8841845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org if (!valid()) return false; 885c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org Address start = static_cast<Address>(code_range_->address()); 886c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org return start <= address && address < start + code_range_->size(); 887c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org } 888c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 889c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Allocates a chunk of memory from the large-object portion of 890c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // the code range. On platforms with no separate code range, should 891c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // not be called. 892068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org MUST_USE_RESULT Address AllocateRawMemory(const size_t requested_size, 893068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org const size_t commit_size, 894c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t* allocated); 895068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org bool CommitRawMemory(Address start, size_t length); 896068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org bool UncommitRawMemory(Address start, size_t length); 897c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void FreeRawMemory(Address buf, size_t length); 898c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 899c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org private: 9007c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org Isolate* isolate_; 901ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 902c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // The reserved range of virtual memory that all code objects are put in. 9035de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::VirtualMemory* code_range_; 904c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Plain old data class, just a struct plus a constructor. 905c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org class FreeBlock { 906c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org public: 907c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org FreeBlock(Address start_arg, size_t size_arg) 908c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com : start(start_arg), size(size_arg) { 909e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsAddressAligned(start, MemoryChunk::kAlignment)); 910e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(size >= static_cast<size_t>(Page::kPageSize)); 911c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 912c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org FreeBlock(void* start_arg, size_t size_arg) 913c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com : start(static_cast<Address>(start_arg)), size(size_arg) { 914e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsAddressAligned(start, MemoryChunk::kAlignment)); 915e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(size >= static_cast<size_t>(Page::kPageSize)); 916c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 917c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 918c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org Address start; 919c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org size_t size; 920c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org }; 921c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 922c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Freed blocks of memory are added to the free list. When the allocation 923c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // list is exhausted, the free list is sorted and merged to make the new 924c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // allocation list. 925ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org List<FreeBlock> free_list_; 926c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Memory is allocated from the free blocks on the allocation list. 927c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // The block at current_allocation_block_index_ is the current block. 928ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org List<FreeBlock> allocation_list_; 929ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int current_allocation_block_index_; 930c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 931c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Finds a block on the allocation list that contains at least the 932c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // requested amount of memory. If none is found, sorts and merges 933c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // the existing free memory blocks, and searches again. 934dc9f731404454341ef693636fc6e2fc4bc50888eulan@chromium.org // If none can be found, returns false. 935dc9f731404454341ef693636fc6e2fc4bc50888eulan@chromium.org bool GetNextAllocationBlock(size_t requested); 936c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Compares the start addresses of two free blocks. 937c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org static int CompareFreeBlockAddress(const FreeBlock* left, 938c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org const FreeBlock* right); 939ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 940ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org DISALLOW_COPY_AND_ASSIGN(CodeRange); 941c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org}; 942c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 943c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 944c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass SkipList { 945c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 9463e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org SkipList() { Clear(); } 947c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 948c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void Clear() { 949c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int idx = 0; idx < kSize; idx++) { 950c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com starts_[idx] = reinterpret_cast<Address>(-1); 951c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 952c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 953c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 9543e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Address StartFor(Address addr) { return starts_[RegionNumber(addr)]; } 955c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 956c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void AddObject(Address addr, int size) { 957c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int start_region = RegionNumber(addr); 958c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int end_region = RegionNumber(addr + size - kPointerSize); 959c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int idx = start_region; idx <= end_region; idx++) { 960c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (starts_[idx] > addr) starts_[idx] = addr; 961c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 962c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 963c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 964c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static inline int RegionNumber(Address addr) { 965c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return (OffsetFrom(addr) & Page::kPageAlignmentMask) >> kRegionSizeLog2; 966c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 967c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 968c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static void Update(Address addr, int size) { 969c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page* page = Page::FromAddress(addr); 970c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SkipList* list = page->skip_list(); 971c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (list == NULL) { 972c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com list = new SkipList(); 973c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com page->set_skip_list(list); 974c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 975c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 976c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com list->AddObject(addr, size); 977c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 978c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 979c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private: 980c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const int kRegionSizeLog2 = 13; 981c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const int kRegionSize = 1 << kRegionSizeLog2; 982c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const int kSize = Page::kPageSize / kRegionSize; 983c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 984c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(Page::kPageSize % kRegionSize == 0); 985c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 986c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address starts_[kSize]; 987c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 988c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 989c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 990c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org// ---------------------------------------------------------------------------- 99143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A space acquires chunks of memory from the operating system. The memory 992c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// allocator allocated and deallocates pages for the paged heap spaces and large 993c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// pages for large object space. 99443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 995c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Each space has to manage it's own pages. 99643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 997ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgclass MemoryAllocator { 99843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 9997c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org explicit MemoryAllocator(Isolate* isolate); 10007c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 100143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Initializes its internal bookkeeping structures. 100201fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org // Max capacity of the total space and executable memory limit. 1003f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com bool SetUp(intptr_t max_capacity, intptr_t capacity_executable); 100443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1005ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org void TearDown(); 100643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 10073e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Page* AllocatePage(intptr_t size, PagedSpace* owner, 10083e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Executability executable); 100943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 10103e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org LargePage* AllocateLargePage(intptr_t object_size, Space* owner, 10113e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Executability executable); 101243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1013c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void Free(MemoryChunk* chunk); 101443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 101543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns the maximum available bytes of heaps. 1016ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org intptr_t Available() { return capacity_ < size_ ? 0 : capacity_ - size_; } 101743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1018e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Returns allocated spaces in bytes. 1019ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org intptr_t Size() { return size_; } 1020e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 102101fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org // Returns the maximum available executable bytes of heaps. 1022ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org intptr_t AvailableExecutable() { 102301fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org if (capacity_executable_ < size_executable_) return 0; 102401fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org return capacity_executable_ - size_executable_; 102501fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org } 102601fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org 1027145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com // Returns allocated executable spaces in bytes. 1028ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org intptr_t SizeExecutable() { return size_executable_; } 1029145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com 10309258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // Returns maximum available bytes that the old space can have. 1031ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org intptr_t MaxAvailable() { 1032ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org return (Available() / Page::kPageSize) * Page::kMaxRegularHeapObjectSize; 10339258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org } 10349258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 10352c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org // Returns an indication of whether a pointer is in a space that has 10362c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org // been allocated by this MemoryAllocator. 10374a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org V8_INLINE bool IsOutsideAllocatedSpace(const void* address) const { 10382c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org return address < lowest_ever_allocated_ || 10393e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org address >= highest_ever_allocated_; 10402c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org } 10412c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org 1042c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef DEBUG 1043c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Reports statistic info of the space. 1044c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void ReportStatistics(); 1045c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif 104643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1047068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org // Returns a MemoryChunk in which the memory region from commit_area_size to 1048068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org // reserve_area_size of the chunk area is reserved but not committed, it 1049068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org // could be committed later by calling MemoryChunk::CommitArea. 1050068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org MemoryChunk* AllocateChunk(intptr_t reserve_area_size, 1051068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org intptr_t commit_area_size, 10523e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Executability executable, Space* space); 1053c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 10543e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Address ReserveAlignedMemory(size_t requested, size_t alignment, 10555de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::VirtualMemory* controller); 10563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Address AllocateAlignedMemory(size_t reserve_size, size_t commit_size, 10573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org size_t alignment, Executability executable, 10585de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::VirtualMemory* controller); 1059c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 10602c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org bool CommitMemory(Address addr, size_t size, Executability executable); 10612c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org 10625de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org void FreeMemory(base::VirtualMemory* reservation, Executability executable); 1063c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void FreeMemory(Address addr, size_t size, Executability executable); 1064c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1065c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Commit a contiguous block of memory from the initial chunk. Assumes that 1066c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the address is not NULL, the size is greater than zero, and that the 1067c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // block is contained in the initial chunk. Returns true if it succeeded 1068c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // and false otherwise. 1069c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool CommitBlock(Address start, size_t size, Executability executable); 107043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1071c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Uncommit a contiguous block of memory [start..(start+size)[. 1072c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // start is not NULL, the size is greater than zero, and the 1073c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // block is contained in the initial chunk. Returns true if it succeeded 1074c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // and false otherwise. 1075c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool UncommitBlock(Address start, size_t size); 107643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1077c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Zaps a contiguous block of memory [start..(start+size)[ thus 1078c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // filling it up with a recognizable non-NULL bit pattern. 1079c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void ZapBlock(Address start, size_t size); 108043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 10813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org void PerformAllocationCallback(ObjectSpace space, AllocationAction action, 1082c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t size); 108343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1084c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void AddMemoryAllocationCallback(MemoryAllocationCallback callback, 10853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org ObjectSpace space, AllocationAction action); 1086013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org 10873e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org void RemoveMemoryAllocationCallback(MemoryAllocationCallback callback); 108843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 10893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org bool MemoryAllocationCallbackRegistered(MemoryAllocationCallback callback); 109043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1091ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org static int CodePageGuardStartOffset(); 1092ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org 1093ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org static int CodePageGuardSize(); 1094ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org 1095ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org static int CodePageAreaStartOffset(); 1096ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org 1097ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org static int CodePageAreaEndOffset(); 1098ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org 1099ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org static int CodePageAreaSize() { 1100ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org return CodePageAreaEndOffset() - CodePageAreaStartOffset(); 1101ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org } 1102ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org 11035de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org MUST_USE_RESULT bool CommitExecutableMemory(base::VirtualMemory* vm, 11043e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Address start, size_t commit_size, 11052c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org size_t reserved_size); 1106ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org 110743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 11087c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org Isolate* isolate_; 11097c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 111043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Maximum space size in bytes. 1111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t capacity_; 111201fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org // Maximum subset of capacity_ that can be executable 1113c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t capacity_executable_; 1114a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 111543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Allocated space size in bytes. 1116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t size_; 1117145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com // Allocated executable space size in bytes. 1118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t size_executable_; 111943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 11202c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org // We keep the lowest and highest addresses allocated as a quick way 11212c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org // of determining that pointers are outside the heap. The estimate is 11222c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org // conservative, i.e. not all addrsses in 'allocated' space are allocated 11232c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org // to our heap. The range is [lowest, highest[, inclusive on the low end 11242c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org // and exclusive on the high end. 11252c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org void* lowest_ever_allocated_; 11262c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org void* highest_ever_allocated_; 11272c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org 11283cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org struct MemoryAllocationCallbackRegistration { 11293cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org MemoryAllocationCallbackRegistration(MemoryAllocationCallback callback, 11303cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org ObjectSpace space, 11313cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org AllocationAction action) 11323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org : callback(callback), space(space), action(action) {} 11333cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org MemoryAllocationCallback callback; 11343cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org ObjectSpace space; 11353cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org AllocationAction action; 11363cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org }; 1137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 11383cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org // A List of callback that are triggered when memory is allocated or free'd 11393e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org List<MemoryAllocationCallbackRegistration> memory_allocation_callbacks_; 11403cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org 114143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Initializes pages in a chunk. Returns the first page address. 114243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // This function and GetChunkId() are provided for the mark-compact 114343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // collector to rebuild page headers in the from space, which is 114443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // used as a marking stack and its page headers are destroyed. 1145ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Page* InitializePagesInChunk(int chunk_id, int pages_in_chunk, 1146ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org PagedSpace* owner); 1147013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org 11482c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org void UpdateAllocatedSpaceLimits(void* low, void* high) { 11492c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org lowest_ever_allocated_ = Min(lowest_ever_allocated_, low); 11502c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org highest_ever_allocated_ = Max(highest_ever_allocated_, high); 11512c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org } 11522c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org 1153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DISALLOW_IMPLICIT_CONSTRUCTORS(MemoryAllocator); 115443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 115543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 115643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 115743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------- 115843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Interface for heap object iterator to be implemented by all object space 115943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// object iterators. 116043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1161b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// NOTE: The space specific object iterators also implements the own next() 1162b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// method which is used to avoid using virtual functions 116343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// iterating a specific space. 116443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 116543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass ObjectIterator : public Malloced { 116643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 11673e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org virtual ~ObjectIterator() {} 116843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 116943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen virtual HeapObject* next_object() = 0; 117043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 117143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 117243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 117343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------- 117443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Heap object iterator in new/old/map spaces. 117543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// A HeapObjectIterator iterates objects from the bottom of the given space 1177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// to its top or from the bottom of the given page to its top. 1178b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org// 1179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// If objects are allocated in the page during iteration the iterator may 1180c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// or may not iterate over those objects. The caller must create a new 1181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// iterator in order to be sure to visit these new objects. 11823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgclass HeapObjectIterator : public ObjectIterator { 118343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 1184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Creates a new object iterator in a given space. 118543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If the size function is not given, the iterator calls the default 118643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Object::Size(). 118743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen explicit HeapObjectIterator(PagedSpace* space); 118843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HeapObjectIterator(PagedSpace* space, HeapObjectCallback size_func); 1189d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org HeapObjectIterator(Page* page, HeapObjectCallback size_func); 119043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1191c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Advance to the next object, skipping free spaces and other fillers and 1192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // skipping the special garbage section of which there is one per space. 1193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Returns NULL when the iteration has ended. 1194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline HeapObject* Next() { 1195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com do { 1196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* next_obj = FromCurrentPage(); 1197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (next_obj != NULL) return next_obj; 1198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } while (AdvanceToNextPage()); 1199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return NULL; 1200b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 120143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12023e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org virtual HeapObject* next_object() { return Next(); } 120343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 120443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 1205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com enum PageMode { kOnePageOnly, kAllPagesInSpace }; 1206b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 12073e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Address cur_addr_; // Current iteration point. 12083e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Address cur_end_; // End iteration point. 1209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObjectCallback size_func_; // Size function or NULL. 1210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PagedSpace* space_; 1211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PageMode page_mode_; 1212b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Fast (inlined) path of next(). 1214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline HeapObject* FromCurrentPage(); 1215b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Slow path of next(), goes into the next page. Returns false if the 1217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // iteration has ended. 1218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool AdvanceToNextPage(); 121943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 122043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Initializes fields. 12213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org inline void Initialize(PagedSpace* owner, Address start, Address end, 12223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org PageMode mode, HeapObjectCallback size_func); 122343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 122443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 122543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 122643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------- 1227b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org// A PageIterator iterates the pages in a paged space. 122843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 122943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass PageIterator BASE_EMBEDDED { 123043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 1231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com explicit inline PageIterator(PagedSpace* space); 123243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 123343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen inline bool has_next(); 123443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen inline Page* next(); 123543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 123643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 1237b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org PagedSpace* space_; 1238b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org Page* prev_page_; // Previous page returned. 1239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Next page that will be returned. Cached here so that we can use this 1240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // iterator for operations that deallocate pages. 1241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page* next_page_; 124243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 124343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 124443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 124543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------- 1246c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// A space has a circular list of pages. The next page can be accessed via 1247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Page::next_page() call. 124843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 124943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// An abstraction of allocation and relocation pointers in a page-structured 125043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// space. 12517276f14ca716596e0a0d17539516370c1f453847kasper.lundclass AllocationInfo { 12527276f14ca716596e0a0d17539516370c1f453847kasper.lund public: 12533e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org AllocationInfo() : top_(NULL), limit_(NULL) {} 1254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1255ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org INLINE(void set_top(Address top)) { 1256e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org SLOW_DCHECK(top == NULL || 12573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org (reinterpret_cast<intptr_t>(top) & HeapObjectTagMask()) == 0); 1258ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org top_ = top; 1259ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org } 1260ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 1261ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org INLINE(Address top()) const { 1262e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org SLOW_DCHECK(top_ == NULL || 12633e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org (reinterpret_cast<intptr_t>(top_) & HeapObjectTagMask()) == 0); 1264ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org return top_; 1265ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org } 1266ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 12673e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Address* top_address() { return &top_; } 1268ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 1269ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org INLINE(void set_limit(Address limit)) { 1270e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org SLOW_DCHECK(limit == NULL || 12713e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org (reinterpret_cast<intptr_t>(limit) & HeapObjectTagMask()) == 0); 1272ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org limit_ = limit; 1273ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org } 1274ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 1275ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org INLINE(Address limit()) const { 1276e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org SLOW_DCHECK(limit_ == NULL || 12773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org (reinterpret_cast<intptr_t>(limit_) & HeapObjectTagMask()) == 12783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 0); 1279ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org return limit_; 1280ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org } 1281ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 12823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Address* limit_address() { return &limit_; } 12837276f14ca716596e0a0d17539516370c1f453847kasper.lund 12847276f14ca716596e0a0d17539516370c1f453847kasper.lund#ifdef DEBUG 12857276f14ca716596e0a0d17539516370c1f453847kasper.lund bool VerifyPagedAllocation() { 12863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org return (Page::FromAllocationTop(top_) == Page::FromAllocationTop(limit_)) && 12873e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org (top_ <= limit_); 12887276f14ca716596e0a0d17539516370c1f453847kasper.lund } 12897276f14ca716596e0a0d17539516370c1f453847kasper.lund#endif 1290ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 1291ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org private: 1292ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org // Current allocation top. 1293ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org Address top_; 1294ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org // Current allocation limit. 1295ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org Address limit_; 129643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 129743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 129843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 129943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// An abstraction of the accounting statistics of a page-structured space. 13002efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// The 'capacity' of a space is the number of object-area bytes (i.e., not 130143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// including page bookkeeping structures) currently in the space. The 'size' 130243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// of a space is the number of allocated bytes, the 'waste' in the space is 130343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the number of bytes that are not allocated and not available to 13042efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// allocation without reorganizing the space via a GC (e.g. small blocks due 130543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// to internal fragmentation, top of page areas in map space), and the bytes 130643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 'available' is the number of unallocated bytes that are not waste. The 130743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// capacity is the sum of size, waste, and available. 130843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 130943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The stats are only set by functions that ensure they stay balanced. These 131043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// functions increase or decrease one of the non-capacity stats in 131143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// conjunction with capacity, or else they always balance increases and 131243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// decreases to the non-capacity stats. 131343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass AllocationStats BASE_EMBEDDED { 131443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 131543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AllocationStats() { Clear(); } 131643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 13172efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Zero out all the allocation statistics (i.e., no capacity). 131843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void Clear() { 131943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen capacity_ = 0; 1320057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org max_capacity_ = 0; 132143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen size_ = 0; 132243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen waste_ = 0; 132343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 132443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1325c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void ClearSizeWaste() { 1326c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_ = capacity_; 1327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com waste_ = 0; 1328c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1329c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 13302efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Reset the allocation statistics (i.e., available = capacity with no 133143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // wasted or allocated bytes). 133243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void Reset() { 133343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen size_ = 0; 133443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen waste_ = 0; 133543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 133643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 133743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Accessors for the allocation statistics. 1338f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org intptr_t Capacity() { return capacity_; } 1339057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org intptr_t MaxCapacity() { return max_capacity_; } 1340f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org intptr_t Size() { return size_; } 1341f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org intptr_t Waste() { return waste_; } 134243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1343c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Grow the space by adding available bytes. They are initially marked as 1344c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // being in use (part of the size), but will normally be immediately freed, 1345c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // putting them on the free list and removing them from size_. 134643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void ExpandSpace(int size_in_bytes) { 134743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen capacity_ += size_in_bytes; 1348c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_ += size_in_bytes; 1349057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org if (capacity_ > max_capacity_) { 1350057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org max_capacity_ = capacity_; 1351057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org } 1352e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(size_ >= 0); 135343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 135443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1355c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Shrink the space by removing available bytes. Since shrinking is done 1356c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // during sweeping, bytes have been marked as being in use (part of the size) 1357c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // and are hereby freed. 135843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void ShrinkSpace(int size_in_bytes) { 135943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen capacity_ -= size_in_bytes; 1360c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_ -= size_in_bytes; 1361e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(size_ >= 0); 136243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 136343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 136443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Allocate from available bytes (available -> size). 1365f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org void AllocateBytes(intptr_t size_in_bytes) { 136643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen size_ += size_in_bytes; 1367e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(size_ >= 0); 136843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 136943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 137043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Free allocated bytes, making them available (size -> available). 1371f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org void DeallocateBytes(intptr_t size_in_bytes) { 137243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen size_ -= size_in_bytes; 1373e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(size_ >= 0); 137443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 137543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 137643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Waste free bytes (available -> waste). 137743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void WasteBytes(int size_in_bytes) { 1378e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(size_in_bytes >= 0); 137943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen waste_ += size_in_bytes; 138043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 138143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 138243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 1383f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org intptr_t capacity_; 1384057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org intptr_t max_capacity_; 1385f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org intptr_t size_; 1386f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org intptr_t waste_; 138743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 138843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 138943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1390c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// ----------------------------------------------------------------------------- 1391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Free lists for old object spaces 1392c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// 1393c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Free-list nodes are free blocks in the heap. They look like heap objects 1394c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// (free-list node pointers have the heap object tag, and they have a map like 1395c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// a heap object). They have a size and a next pointer. The next pointer is 1396c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// the raw address of the next free list node (or NULL). 13973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgclass FreeListNode : public HeapObject { 1398c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 1399c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Obtain a free-list node from a raw address. This is not a cast because 1400c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // it does not check nor require that the first word at the address is a map 1401c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // pointer. 1402c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static FreeListNode* FromAddress(Address address) { 1403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return reinterpret_cast<FreeListNode*>(HeapObject::FromAddress(address)); 1404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1405c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1406c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static inline bool IsFreeListNode(HeapObject* object); 1407c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1408c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Set the size in bytes, which can be read with HeapObject::Size(). This 1409c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // function also writes a map to the first word of the block so that it 1410c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // looks like a heap object to the garbage collector and heap iteration 1411c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // functions. 1412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void set_size(Heap* heap, int size_in_bytes); 1413c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1414c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Accessors for the next field. 1415c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline FreeListNode* next(); 1416c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline FreeListNode** next_address(); 1417c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline void set_next(FreeListNode* next); 1418c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1419c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline void Zap(); 1420c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1421a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org static inline FreeListNode* cast(Object* object) { 1422a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org return reinterpret_cast<FreeListNode*>(object); 142356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org } 142456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org 1425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private: 1426c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const int kNextOffset = POINTER_SIZE_ALIGN(FreeSpace::kHeaderSize); 1427c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1428c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListNode); 1429c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 1430c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1431c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1432a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org// The free list category holds a pointer to the top element and a pointer to 1433a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org// the end element of the linked list of free memory blocks. 1434a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass FreeListCategory { 1435a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org public: 14363e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org FreeListCategory() : top_(0), end_(NULL), available_(0) {} 1437e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 1438e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org intptr_t Concatenate(FreeListCategory* category); 1439a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 1440a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org void Reset(); 1441a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 1442a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org void Free(FreeListNode* node, int size_in_bytes); 1443a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 14443e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org FreeListNode* PickNodeFromList(int* node_size); 14453e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org FreeListNode* PickNodeFromList(int size_in_bytes, int* node_size); 1446a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 1447a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org intptr_t EvictFreeListItemsInList(Page* p); 14486d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org bool ContainsPageFreeListItemsInList(Page* p); 1449a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 1450a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org void RepairFreeList(Heap* heap); 1451a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 1452f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org FreeListNode* top() const { 14531e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org return reinterpret_cast<FreeListNode*>(base::NoBarrier_Load(&top_)); 1454f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 1455f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 1456f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void set_top(FreeListNode* top) { 14571e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org base::NoBarrier_Store(&top_, reinterpret_cast<base::AtomicWord>(top)); 1458f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 1459a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 1460a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org FreeListNode** GetEndAddress() { return &end_; } 1461a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org FreeListNode* end() const { return end_; } 1462a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org void set_end(FreeListNode* end) { end_ = end; } 1463a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 1464a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int* GetAvailableAddress() { return &available_; } 1465a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int available() const { return available_; } 1466a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org void set_available(int available) { available_ = available; } 1467a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 14685de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::Mutex* mutex() { return &mutex_; } 1469e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 14703e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org bool IsEmpty() { return top() == 0; } 14716d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org 1472a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#ifdef DEBUG 1473a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org intptr_t SumFreeList(); 1474a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int FreeListLength(); 1475a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#endif 1476a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 1477a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org private: 1478f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // top_ points to the top FreeListNode* in the free list category. 14791e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org base::AtomicWord top_; 1480a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org FreeListNode* end_; 14815de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::Mutex mutex_; 1482a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 1483a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Total available bytes in all blocks of this free list category. 1484a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org int available_; 1485a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}; 1486a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 1487a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 1488c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// The free list for the old space. The free list is organized in such a way 1489c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// as to encourage objects allocated around the same time to be near each 1490c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// other. The normal way to allocate is intended to be by bumping a 'top' 1491c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// pointer until it hits a 'limit' pointer. When the limit is hit we need to 1492c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// find a new space to allocate from. This is done with the free list, which 1493c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// is divided up into rough categories to cut down on waste. Having finer 1494c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// categories would scatter allocation more. 1495c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1496c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// The old space free list is organized in categories. 1497c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// 1-31 words: Such small free areas are discarded for efficiency reasons. 1498c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// They can be reclaimed by the compactor. However the distance between top 1499c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// and limit may be this small. 1500c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// 32-255 words: There is a list of spaces this large. It is used for top and 1501c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// limit when the object we need to allocate is 1-31 words in size. These 1502c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// spaces are called small. 1503c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// 256-2047 words: There is a list of spaces this large. It is used for top and 1504c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// limit when the object we need to allocate is 32-255 words in size. These 1505c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// spaces are called medium. 1506c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// 1048-16383 words: There is a list of spaces this large. It is used for top 1507c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// and limit when the object we need to allocate is 256-2047 words in size. 1508c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// These spaces are call large. 1509c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// At least 16384 words. This list is for objects of 2048 words or larger. 1510c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Empty pages are added to this list. These spaces are called huge. 15116d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.orgclass FreeList { 1512c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 1513c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com explicit FreeList(PagedSpace* owner); 1514c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1515e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org intptr_t Concatenate(FreeList* free_list); 1516e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 1517c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clear the free list. 1518c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void Reset(); 1519c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1520c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Return the number of bytes available on the free list. 1521a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org intptr_t available() { 1522a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return small_list_.available() + medium_list_.available() + 1523a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org large_list_.available() + huge_list_.available(); 1524a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 1525c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1526c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Place a node on the free list. The block of size 'size_in_bytes' 1527c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // starting at 'start' is placed on the free list. The return value is the 1528c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // number of bytes that have been lost due to internal fragmentation by 1529c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // freeing the block. Bookkeeping information will be written to the block, 15302efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // i.e., its contents will be destroyed. The start address should be word 1531c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // aligned, and the size should be a non-zero multiple of the word size. 1532c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int Free(Address start, int size_in_bytes); 1533c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1534d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org // This method returns how much memory can be allocated after freeing 1535d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org // maximum_freed memory. 1536d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org static inline int GuaranteedAllocatable(int maximum_freed) { 1537d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org if (maximum_freed < kSmallListMin) { 1538d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org return 0; 1539d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org } else if (maximum_freed <= kSmallListMax) { 1540d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org return kSmallAllocationMax; 1541d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org } else if (maximum_freed <= kMediumListMax) { 1542d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org return kMediumAllocationMax; 1543d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org } else if (maximum_freed <= kLargeListMax) { 1544d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org return kLargeAllocationMax; 1545d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org } 1546d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org return maximum_freed; 1547d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org } 1548d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org 1549c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Allocate a block of size 'size_in_bytes' from the free list. The block 1550c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // is unitialized. A failure is returned if no block is available. The 1551c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // number of bytes lost to fragmentation is returned in the output parameter 1552c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // 'wasted_bytes'. The size should be a non-zero multiple of the word size. 1553c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MUST_USE_RESULT HeapObject* Allocate(int size_in_bytes); 1554c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 15556d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org bool IsEmpty() { 15566d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org return small_list_.IsEmpty() && medium_list_.IsEmpty() && 15576d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org large_list_.IsEmpty() && huge_list_.IsEmpty(); 15586d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org } 15596d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org 1560c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef DEBUG 1561c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void Zap(); 1562c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com intptr_t SumFreeLists(); 1563c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool IsVeryLong(); 1564c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif 1565c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 156656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // Used after booting the VM. 156756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org void RepairLists(Heap* heap); 156856c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org 15692c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org intptr_t EvictFreeListItems(Page* p); 15706d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org bool ContainsPageFreeListItems(Page* p); 1571c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1572e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org FreeListCategory* small_list() { return &small_list_; } 1573e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org FreeListCategory* medium_list() { return &medium_list_; } 1574e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org FreeListCategory* large_list() { return &large_list_; } 1575e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org FreeListCategory* huge_list() { return &huge_list_; } 1576e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 1577c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private: 1578c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The size range of blocks, in bytes. 1579c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const int kMinBlockSize = 3 * kPointerSize; 1580ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org static const int kMaxBlockSize = Page::kMaxRegularHeapObjectSize; 1581c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1582c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); 1583c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1584c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PagedSpace* owner_; 1585c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Heap* heap_; 1586c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1587c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const int kSmallListMin = 0x20 * kPointerSize; 1588c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const int kSmallListMax = 0xff * kPointerSize; 1589c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const int kMediumListMax = 0x7ff * kPointerSize; 1590c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const int kLargeListMax = 0x3fff * kPointerSize; 1591c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const int kSmallAllocationMax = kSmallListMin - kPointerSize; 1592c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const int kMediumAllocationMax = kSmallListMax; 1593c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const int kLargeAllocationMax = kMediumListMax; 1594a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org FreeListCategory small_list_; 1595a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org FreeListCategory medium_list_; 1596a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org FreeListCategory large_list_; 1597a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org FreeListCategory huge_list_; 1598c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1599c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DISALLOW_IMPLICIT_CONSTRUCTORS(FreeList); 1600c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 1601c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1602c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1603a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgclass AllocationResult { 1604a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org public: 1605a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // Implicit constructor from Object*. 16063e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org AllocationResult(Object* object) // NOLINT 16073e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org : object_(object), 16083e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org retry_space_(INVALID_SPACE) {} 1609a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 16103e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org AllocationResult() : object_(NULL), retry_space_(INVALID_SPACE) {} 1611a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 1612a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org static inline AllocationResult Retry(AllocationSpace space = NEW_SPACE) { 1613a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org return AllocationResult(space); 1614a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 1615a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 1616a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org inline bool IsRetry() { return retry_space_ != INVALID_SPACE; } 1617a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 1618a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org template <typename T> 1619a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org bool To(T** obj) { 1620a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (IsRetry()) return false; 1621a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org *obj = T::cast(object_); 1622a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org return true; 1623a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 1624a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 1625a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Object* ToObjectChecked() { 1626a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org CHECK(!IsRetry()); 1627a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org return object_; 1628a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 1629a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 1630a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org AllocationSpace RetrySpace() { 1631e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsRetry()); 1632a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org return retry_space_; 1633a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 1634a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 1635a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org private: 16363e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org explicit AllocationResult(AllocationSpace space) 16373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org : object_(NULL), retry_space_(space) {} 1638a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 1639a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Object* object_; 1640a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org AllocationSpace retry_space_; 1641a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org}; 1642a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 1643a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 16447276f14ca716596e0a0d17539516370c1f453847kasper.lundclass PagedSpace : public Space { 164543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 164643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Creates a space with a maximum capacity, and an id. 16473e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org PagedSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id, 1648f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org Executability executable); 16497276f14ca716596e0a0d17539516370c1f453847kasper.lund 16507276f14ca716596e0a0d17539516370c1f453847kasper.lund virtual ~PagedSpace() {} 165143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 165243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Set up the space using the given address range of virtual memory (from 165343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // the memory allocator's initial chunk) if possible. If the block of 165443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // addresses is not big enough to contain a single page-aligned page, a 165543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // fresh chunk will be allocated. 1656f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com bool SetUp(); 165743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 165843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns true if the space has been successfully set up and not 165943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // subsequently torn down. 1660f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com bool HasBeenSetUp(); 166143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 166243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Cleans up the space, frees all pages in this space except those belonging 166343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // to the initial chunk, uncommits addresses in the initial chunk. 166443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void TearDown(); 166543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 166643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Checks whether an object/address is in this space. 166743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen inline bool Contains(Address a); 166843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool Contains(HeapObject* o) { return Contains(o->address()); } 166943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 16707276f14ca716596e0a0d17539516370c1f453847kasper.lund // Given an address occupied by a live object, return that object if it is 1671b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org // in this space, or a Smi if it is not. The implementation iterates over 1672b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org // objects in the page containing the address, the cost is linear in the 1673b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org // number of objects in the page. It may be slow. 1674b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org Object* FindObject(Address addr); 167543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 167656c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // During boot the free_space_map is created, and afterwards we may need 167756c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org // to write it into the free list nodes that were already created. 16780cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org void RepairFreeListsAfterBoot(); 167956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org 16809258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // Prepares for a mark-compact GC. 16810cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org void PrepareForMarkCompact(); 1682013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org 1683c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Current capacity without growing (Size() + Available()). 1684f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org intptr_t Capacity() { return accounting_stats_.Capacity(); } 168543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 16863811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Total amount of memory committed for this space. For paged 16873811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // spaces this equals the capacity. 1688f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org intptr_t CommittedMemory() { return Capacity(); } 16893811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1690057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org // The maximum amount of memory ever committed for this space. 1691057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org intptr_t MaximumCommittedMemory() { return accounting_stats_.MaxCapacity(); } 1692057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org 169372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // Approximate amount of physical memory committed for this space. 169472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org size_t CommittedPhysicalMemory(); 169572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org 1696e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org struct SizeStats { 1697e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org intptr_t Total() { 1698e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return small_size_ + medium_size_ + large_size_ + huge_size_; 1699e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 1700e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 1701e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org intptr_t small_size_; 1702e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org intptr_t medium_size_; 1703e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org intptr_t large_size_; 1704e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org intptr_t huge_size_; 1705e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org }; 1706e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 1707e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org void ObtainFreeListStatistics(Page* p, SizeStats* sizes); 1708e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org void ResetFreeListStatistics(); 1709e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 1710c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Sets the capacity, the available space and the wasted space to zero. 1711c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The stats are rebuilt during sweeping by adding each page to the 1712c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // capacity and the size when it is encountered. As free spaces are 1713c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // discovered during the sweeping they are subtracted from the size and added 1714c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // to the available and wasted totals. 1715c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void ClearStats() { 1716c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com accounting_stats_.ClearSizeWaste(); 1717e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ResetFreeListStatistics(); 1718c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1719c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 17208432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org // Increases the number of available bytes of that space. 17218432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org void AddToAccountingStats(intptr_t bytes) { 17228432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org accounting_stats_.DeallocateBytes(bytes); 17238432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org } 17248432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org 1725c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Available bytes without growing. These are the bytes on the free list. 1726c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The bytes in the linear allocation area are not included in this total 1727c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // because updating the stats would slow down allocation. New pages are 1728c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // immediately added to the free list so they show up here. 1729c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com intptr_t Available() { return free_list_.available(); } 173043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1731c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Allocated bytes in this space. Garbage bytes that were not found due to 1732865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org // concurrent sweeping are counted as being allocated! The bytes in the 1733865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org // current linear allocation area (between top and limit) are also counted 1734865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org // here. 1735f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org virtual intptr_t Size() { return accounting_stats_.Size(); } 173643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1737f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // As size, but the bytes in lazily swept pages are estimated and the bytes 1738f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // in the current linear allocation area are not included. 1739750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org virtual intptr_t SizeOfObjects(); 174043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1741c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Wasted bytes in this space. These are just the bytes that were thrown away 1742c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // due to being too small to use for allocation. They do not include the 1743c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // free bytes that were not found at all due to lazy sweeping. 1744c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual intptr_t Waste() { return accounting_stats_.Waste(); } 174543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 174643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns the allocation pointer in this space. 1747ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org Address top() { return allocation_info_.top(); } 1748ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org Address limit() { return allocation_info_.limit(); } 1749ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 1750ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org // The allocation top address. 17513e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Address* allocation_top_address() { return allocation_info_.top_address(); } 175243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1753ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org // The allocation limit address. 1754ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org Address* allocation_limit_address() { 1755ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org return allocation_info_.limit_address(); 1756ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org } 17572bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 17587276f14ca716596e0a0d17539516370c1f453847kasper.lund // Allocate the requested number of bytes in the space if possible, return a 17597276f14ca716596e0a0d17539516370c1f453847kasper.lund // failure object if not. 1760a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org MUST_USE_RESULT inline AllocationResult AllocateRaw(int size_in_bytes); 17617276f14ca716596e0a0d17539516370c1f453847kasper.lund 1762c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Give a block of memory to the space's free list. It might be added to 1763c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the free list or accounted as waste. 1764c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If add_to_freelist is false then just accounting stats are updated and 1765c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // no attempt to add area to free list is made. 1766c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int Free(Address start, int size_in_bytes) { 1767c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int wasted = free_list_.Free(start, size_in_bytes); 17684c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org accounting_stats_.DeallocateBytes(size_in_bytes); 17694c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org accounting_stats_.WasteBytes(wasted); 1770c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return size_in_bytes - wasted; 1771c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1772d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 17733e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org void ResetFreeList() { free_list_.Reset(); } 177428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 1775013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org // Set space allocation info. 1776b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org void SetTopAndLimit(Address top, Address limit) { 1777e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(top == limit || 1778c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page::FromAddress(top) == Page::FromAddress(limit - 1)); 1779ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); 1780ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org allocation_info_.set_top(top); 1781ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org allocation_info_.set_limit(limit); 1782013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org } 1783013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org 1784b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // Empty space allocation info, returning unused area to free list. 1785b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org void EmptyAllocationInfo() { 1786b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // Mark the old linear allocation area with a free space map so it can be 1787b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // skipped when scanning the heap. 1788b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org int old_linear_size = static_cast<int>(limit() - top()); 1789b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Free(top(), old_linear_size); 1790b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org SetTopAndLimit(NULL, NULL); 1791b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 1792b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 17933e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org void Allocate(int bytes) { accounting_stats_.AllocateBytes(bytes); } 179443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1795057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org void IncreaseCapacity(int size); 179643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1797c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Releases an unused page and shrinks the space. 17983484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org void ReleasePage(Page* page); 17999258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 1800c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The dummy page that anchors the linked list of pages. 1801c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page* anchor() { return &anchor_; } 180243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1803c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP 1804defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org // Verify integrity of this space. 1805defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org virtual void Verify(ObjectVisitor* visitor); 1806defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org 1807defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org // Overridden by subclasses to verify space-specific object 1808defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org // properties (e.g., only maps or free-list nodes are in map space). 1809defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org virtual void VerifyObject(HeapObject* obj) {} 1810c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif 1811c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org 1812c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef DEBUG 1813c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org // Print meta info and objects in this space. 1814c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org virtual void Print(); 1815c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org 1816c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org // Reports statistics for the space 1817c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org void ReportStatistics(); 1818defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org 181943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Report code object related statistics 182043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void CollectCodeStatistics(); 18213d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org static void ReportCodeStatistics(Isolate* isolate); 18223d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org static void ResetCodeStatistics(Isolate* isolate); 182343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 182443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1825c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Evacuation candidates are swept by evacuator. Needs to return a valid 1826c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // result before _and_ after evacuation has finished. 1827865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org static bool ShouldBeSweptBySweeperThreads(Page* p) { 1828c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return !p->IsEvacuationCandidate() && 1829a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org !p->IsFlagSet(Page::RESCAN_ON_EVACUATION) && !p->WasSwept(); 1830c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1831c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 18323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org void IncrementUnsweptFreeBytes(intptr_t by) { unswept_free_bytes_ += by; } 18332efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 18342efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org void IncreaseUnsweptFreeBytes(Page* p) { 1835e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ShouldBeSweptBySweeperThreads(p)); 1836ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org unswept_free_bytes_ += (p->area_size() - p->LiveBytes()); 1837f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com } 1838f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 18393e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org void DecrementUnsweptFreeBytes(intptr_t by) { unswept_free_bytes_ -= by; } 18408432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org 18412efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org void DecreaseUnsweptFreeBytes(Page* p) { 1842e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ShouldBeSweptBySweeperThreads(p)); 1843ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org unswept_free_bytes_ -= (p->area_size() - p->LiveBytes()); 18442efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 18452efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 18463e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org void ResetUnsweptFreeBytes() { unswept_free_bytes_ = 0; } 18478432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org 18483484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org // This function tries to steal size_in_bytes memory from the sweeper threads 18493484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org // free-lists. If it does not succeed stealing enough memory, it will wait 18503484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org // for the sweeper threads to finish sweeping. 18513484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org // It returns true when sweeping is completed and false otherwise. 18523484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org bool EnsureSweeperProgress(intptr_t size_in_bytes); 18533484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org 18543e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org void set_end_of_unswept_pages(Page* page) { end_of_unswept_pages_ = page; } 18553484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org 18563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Page* end_of_unswept_pages() { return end_of_unswept_pages_; } 18573484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org 1858c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page* FirstPage() { return anchor_.next_page(); } 1859c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page* LastPage() { return anchor_.prev_page(); } 1860c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1861c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void EvictEvacuationCandidatesFromFreeLists(); 1862c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1863c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool CanExpand(); 1864d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 18651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Returns the number of total pages in this space. 18661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int CountTotalPages(); 18671b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 1868ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org // Return size of allocatable area on a page in this space. 18693e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org inline int AreaSize() { return area_size_; } 1870ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org 1871f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org void CreateEmergencyMemory(); 1872f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org void FreeEmergencyMemory(); 1873f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org void UseEmergencyMemory(); 1874f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org 1875f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org bool HasEmergencyMemory() { return emergency_memory_ != NULL; } 1876f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org 187743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen protected: 1878e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org FreeList* free_list() { return &free_list_; } 1879e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 1880ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org int area_size_; 1881ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org 188243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Maximum capacity of this space. 1883f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org intptr_t max_capacity_; 188443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 18857d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org intptr_t SizeOfFirstPage(); 18867d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org 188743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Accounting information for this space. 188843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AllocationStats accounting_stats_; 188943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1890c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The dummy page that anchors the double linked list of pages. 1891c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Page anchor_; 189243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1893c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The space's free list. 1894c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FreeList free_list_; 1895013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org 189643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Normal allocation information. 189743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AllocationInfo allocation_info_; 189843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1899f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // The number of free bytes which could be reclaimed by advancing the 1900a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org // concurrent sweeper threads. 1901f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com intptr_t unswept_free_bytes_; 1902f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 19033484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org // The sweeper threads iterate over the list of pointer and data space pages 19043484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org // and sweep these pages concurrently. They will stop sweeping after the 19053484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org // end_of_unswept_pages_ page. 19063484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org Page* end_of_unswept_pages_; 19073484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org 1908f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org // Emergency memory is the memory of a full page for a given space, allocated 1909f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org // conservatively before evacuating a page. If compaction fails due to out 1910f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org // of memory error the emergency memory can be used to complete compaction. 1911f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org // If not used, the emergency memory is released after compaction. 1912f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org MemoryChunk* emergency_memory_; 1913f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org 191443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Expands the space by allocating a fixed number of pages. Returns false if 1915ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org // it cannot allocate requested number of pages from OS, or if the hard heap 1916ecb9dd69014d1d8aad1a08bd8b593fbf94107324svenpanne@chromium.org // size limit has been hit. 1917c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool Expand(); 191843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1919c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Generic fast case allocation function that tries linear allocation at the 1920c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // address denoted by top in allocation_info_. 1921c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline HeapObject* AllocateLinearly(int size_in_bytes); 19227276f14ca716596e0a0d17539516370c1f453847kasper.lund 192370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org // If sweeping is still in progress try to sweep unswept pages. If that is 192470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org // not successful, wait for the sweeper threads and re-try free-list 192570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org // allocation. 1926d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org MUST_USE_RESULT HeapObject* WaitForSweeperThreadsAndRetryAllocation( 1927d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org int size_in_bytes); 19285de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org 19297276f14ca716596e0a0d17539516370c1f453847kasper.lund // Slow path of AllocateRaw. This function is space-dependent. 19305de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org MUST_USE_RESULT HeapObject* SlowAllocateRaw(int size_in_bytes); 19317276f14ca716596e0a0d17539516370c1f453847kasper.lund 1932f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org friend class PageIterator; 19336d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org friend class MarkCompactCollector; 193443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 193543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 193643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 19370b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.orgclass NumberAndSizeInfo BASE_EMBEDDED { 193843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 19390b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org NumberAndSizeInfo() : number_(0), bytes_(0) {} 194043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 19410b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org int number() const { return number_; } 194243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void increment_number(int num) { number_ += num; } 194343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 19440b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org int bytes() const { return bytes_; } 194543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void increment_bytes(int size) { bytes_ += size; } 194643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 194743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void clear() { 194843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen number_ = 0; 194943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bytes_ = 0; 195043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 195143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 195243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 195343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int number_; 195443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int bytes_; 195543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 19560b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 19570b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 19580b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org// HistogramInfo class for recording a single "bar" of a histogram. This 1959030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org// class is used for collecting statistics to print to the log file. 19603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgclass HistogramInfo : public NumberAndSizeInfo { 19610b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org public: 19620b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org HistogramInfo() : NumberAndSizeInfo() {} 19630b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 19640b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org const char* name() { return name_; } 19650b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org void set_name(const char* name) { name_ = name; } 19660b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 19670b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org private: 19680b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org const char* name_; 19690b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org}; 197043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 197143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 19723e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgenum SemiSpaceId { kFromSpace = 0, kToSpace = 1 }; 1973c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1974c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1975c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass SemiSpace; 1976c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1977c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1978c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass NewSpacePage : public MemoryChunk { 1979c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 1980c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // GC related flags copied from from-space to to-space when 1981c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // flipping semispaces. 1982c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const intptr_t kCopyOnFlipFlagsMask = 19833e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org (1 << MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING) | 19843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org (1 << MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING) | 19853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org (1 << MemoryChunk::SCAN_ON_SCAVENGE); 1986c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1987ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org static const int kAreaSize = Page::kMaxRegularHeapObjectSize; 1988ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org 1989c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline NewSpacePage* next_page() const { 1990c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return static_cast<NewSpacePage*>(next_chunk()); 1991c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1992c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 19933e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org inline void set_next_page(NewSpacePage* page) { set_next_chunk(page); } 1994c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1995c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline NewSpacePage* prev_page() const { 1996c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return static_cast<NewSpacePage*>(prev_chunk()); 1997c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1998c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 19993e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org inline void set_prev_page(NewSpacePage* page) { set_prev_chunk(page); } 2000c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 20013e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org SemiSpace* semi_space() { return reinterpret_cast<SemiSpace*>(owner()); } 2002c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2003c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool is_anchor() { return !this->InNewSpace(); } 2004c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2005c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static bool IsAtStart(Address addr) { 20063e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org return (reinterpret_cast<intptr_t>(addr) & Page::kPageAlignmentMask) == 20073e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org kObjectStartOffset; 2008c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2009c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2010c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static bool IsAtEnd(Address addr) { 2011c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return (reinterpret_cast<intptr_t>(addr) & Page::kPageAlignmentMask) == 0; 2012c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2013c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 20143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Address address() { return reinterpret_cast<Address>(this); } 2015c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2016d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org // Finds the NewSpacePage containing the given address. 2017c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static inline NewSpacePage* FromAddress(Address address_in_page) { 2018c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address page_start = 2019c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address_in_page) & 2020c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ~Page::kPageAlignmentMask); 2021c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NewSpacePage* page = reinterpret_cast<NewSpacePage*>(page_start); 2022c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return page; 2023c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2024c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2025c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Find the page for a limit address. A limit address is either an address 2026c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // inside a page, or the address right after the last byte of a page. 2027c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static inline NewSpacePage* FromLimit(Address address_limit) { 2028c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return NewSpacePage::FromAddress(address_limit - 1); 2029c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2030c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2031b2498e12b28a19563de5c70c51cba52f180c1dfehpayer@chromium.org // Checks if address1 and address2 are on the same new space page. 2032b2498e12b28a19563de5c70c51cba52f180c1dfehpayer@chromium.org static inline bool OnSamePage(Address address1, Address address2) { 2033b2498e12b28a19563de5c70c51cba52f180c1dfehpayer@chromium.org return NewSpacePage::FromAddress(address1) == 2034b2498e12b28a19563de5c70c51cba52f180c1dfehpayer@chromium.org NewSpacePage::FromAddress(address2); 2035b2498e12b28a19563de5c70c51cba52f180c1dfehpayer@chromium.org } 2036b2498e12b28a19563de5c70c51cba52f180c1dfehpayer@chromium.org 2037c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private: 2038c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Create a NewSpacePage object that is only used as anchor 2039c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // for the doubly-linked list of real pages. 20403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org explicit NewSpacePage(SemiSpace* owner) { InitializeAsAnchor(owner); } 2041c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 20423e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org static NewSpacePage* Initialize(Heap* heap, Address start, 2043c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SemiSpace* semi_space); 2044c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2045c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Intialize a fake NewSpacePage used as sentinel at the ends 2046c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // of a doubly-linked list of real NewSpacePages. 2047c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Only uses the prev/next links, and sets flags to not be in new-space. 2048c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void InitializeAsAnchor(SemiSpace* owner); 2049c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2050c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com friend class SemiSpace; 2051c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com friend class SemiSpaceIterator; 2052c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 2053c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2054c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 205543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------- 205643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SemiSpace in young generation 205743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 2058c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// A semispace is a contiguous chunk of memory holding page-like memory 2059c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// chunks. The mark-compact collector uses the memory of the first page in 2060c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// the from space as a marking stack when tracing live objects. 206143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 20627276f14ca716596e0a0d17539516370c1f453847kasper.lundclass SemiSpace : public Space { 206343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 20645a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // Constructor. 2065c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SemiSpace(Heap* heap, SemiSpaceId semispace) 20663e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org : Space(heap, NEW_SPACE, NOT_EXECUTABLE), 20673e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org start_(NULL), 20683e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org age_mark_(NULL), 20693e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org id_(semispace), 20703e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org anchor_(this), 20713e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org current_page_(NULL) {} 207243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 207343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Sets up the semispace using the given chunk. 2074659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org void SetUp(Address start, int initial_capacity, int maximum_capacity); 207543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 207643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Tear down the space. Heap memory was not allocated by the space, so it 207743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is not deallocated here. 207843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void TearDown(); 207943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 208043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // True if the space has been set up but not torn down. 2081f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com bool HasBeenSetUp() { return start_ != NULL; } 208243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2083ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org // Grow the semispace to the new capacity. The new capacity 2084c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // requested must be larger than the current capacity and less than 2085c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the maximum capacity. 2086ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org bool GrowTo(int new_capacity); 2087ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org 2088ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org // Shrinks the semispace to the new capacity. The new capacity 2089ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org // requested must be more than the amount of used memory in the 2090ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org // semispace and less than the current capacity. 2091ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org bool ShrinkTo(int new_capacity); 2092ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org 2093c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Returns the start address of the first page of the space. 2094c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address space_start() { 2095e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(anchor_.next_page() != &anchor_); 2096ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org return anchor_.next_page()->area_start(); 2097c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2098c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2099c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Returns the start address of the current page of the space. 21003e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Address page_low() { return current_page_->area_start(); } 2101c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 210243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns one past the end address of the space. 21033e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Address space_end() { return anchor_.prev_page()->area_end(); } 2104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2105c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Returns one past the end address of the current page of the space. 21063e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Address page_high() { return current_page_->area_end(); } 2107c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2108c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool AdvancePage() { 2109c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NewSpacePage* next_page = current_page_->next_page(); 2110c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (next_page == anchor()) return false; 2111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com current_page_ = next_page; 2112c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return true; 2113c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Resets the space to using the first page. 2116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void Reset(); 211743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 211843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Age mark accessors. 211943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Address age_mark() { return age_mark_; } 2120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void set_age_mark(Address mark); 212143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 212243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // True if the address is in the address range of this semispace (not 212343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // necessarily below the allocation pointer). 212443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool Contains(Address a) { 21253e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org return (reinterpret_cast<uintptr_t>(a) & address_mask_) == 21263e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org reinterpret_cast<uintptr_t>(start_); 212743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 212843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 212943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // True if the object is a heap object in the address range of this 213043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // semispace (not necessarily below the allocation pointer). 213143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool Contains(Object* o) { 21325ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org return (reinterpret_cast<uintptr_t>(o) & object_mask_) == object_expected_; 213343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 213443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 21350c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // If we don't have these here then SemiSpace will be abstract. However 21360c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // they should never be called. 2137f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org virtual intptr_t Size() { 21389258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org UNREACHABLE(); 21399258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org return 0; 21409258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org } 21419258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 2142add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org bool is_committed() { return committed_; } 2143add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org bool Commit(); 2144add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org bool Uncommit(); 2145add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org 2146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NewSpacePage* first_page() { return anchor_.next_page(); } 2147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NewSpacePage* current_page() { return current_page_; } 2148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2149c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP 2150c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org virtual void Verify(); 2151c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif 2152c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org 215343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG 21549258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org virtual void Print(); 2155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Validate a range of of addresses in a SemiSpace. 2156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The "from" address must be on a page prior to the "to" address, 2157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // in the linked page order, or it must be earlier on the same page. 2158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static void AssertValidRange(Address from, Address to); 2159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#else 2160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Do nothing. 2161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline static void AssertValidRange(Address from, Address to) {} 216243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 216343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2164a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // Returns the current total capacity of the semispace. 2165a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org int TotalCapacity() { return total_capacity_; } 21665a6af92a1549c81fb61855518f43b712e4c0e469christian.plesner.hansen@gmail.com 2167a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // Returns the maximum total capacity of the semispace. 2168a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org int MaximumTotalCapacity() { return maximum_total_capacity_; } 2169911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 2170a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // Returns the initial capacity of the semispace. 2171a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org int InitialTotalCapacity() { return initial_total_capacity_; } 2172911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 2173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SemiSpaceId id() { return id_; } 2174c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static void Swap(SemiSpace* from, SemiSpace* to); 2176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2177057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org // Returns the maximum amount of memory ever committed by the semi space. 2178057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org size_t MaximumCommittedMemory() { return maximum_committed_; } 2179057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org 218072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // Approximate amount of physical memory committed for this space. 218172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org size_t CommittedPhysicalMemory(); 218272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org 218343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 2184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Flips the semispace between being from-space and to-space. 2185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Copies the flags into the masked positions on all pages in the space. 2186c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void FlipPages(intptr_t flags, intptr_t flag_mask); 2187c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2188057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org // Updates Capacity and MaximumCommitted based on new capacity. 2189057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org void SetCapacity(int new_capacity); 2190057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org 2191c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NewSpacePage* anchor() { return &anchor_; } 2192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2193a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // The current and maximum total capacity of the space. 2194a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org int total_capacity_; 2195a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org int maximum_total_capacity_; 2196a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org int initial_total_capacity_; 219743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2198057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org intptr_t maximum_committed_; 2199057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org 220043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The start address of the space. 220143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Address start_; 220243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Used to govern object promotion during mark-compact collection. 220343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Address age_mark_; 220443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 220543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Masks and comparison values to test for containment in this semispace. 22065ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org uintptr_t address_mask_; 22075ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org uintptr_t object_mask_; 22085ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org uintptr_t object_expected_; 220943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2210add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org bool committed_; 2211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SemiSpaceId id_; 2212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NewSpacePage anchor_; 2214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NewSpacePage* current_page_; 2215add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org 2216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com friend class SemiSpaceIterator; 2217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com friend class NewSpacePageIterator; 22183e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 221943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 222043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TRACK_MEMORY("SemiSpace") 222143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 222243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 222343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 222443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A SemiSpaceIterator is an ObjectIterator that iterates over the active 222543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// semispace of the heap's new space. It iterates over the objects in the 222643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// semispace from a given start address (defaulting to the bottom of the 222743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// semispace) to the top of the semispace. New objects allocated after the 222843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// iterator is created are not iterated. 222943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass SemiSpaceIterator : public ObjectIterator { 223043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 223143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create an iterator over the objects in the given space. If no start 223243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // address is given, the iterator starts from the bottom of the space. If 223343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // no size function is given, the iterator calls Object::Size(). 2234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Iterate over all of allocated to-space. 223643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen explicit SemiSpaceIterator(NewSpace* space); 2237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Iterate over all of allocated to-space, with a custome size function. 223843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SemiSpaceIterator(NewSpace* space, HeapObjectCallback size_func); 2239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Iterate over part of allocated to-space, from start to the end 2240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // of allocation. 224143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SemiSpaceIterator(NewSpace* space, Address start); 2242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Iterate from one address to another in the same semi-space. 2243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SemiSpaceIterator(Address from, Address to); 224443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* Next() { 2246b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (current_ == limit_) return NULL; 2247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (NewSpacePage::IsAtEnd(current_)) { 2248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NewSpacePage* page = NewSpacePage::FromLimit(current_); 2249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com page = page->next_page(); 2250e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!page->is_anchor()); 2251ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org current_ = page->area_start(); 2252c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (current_ == limit_) return NULL; 2253c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 225443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 225543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HeapObject* object = HeapObject::FromAddress(current_); 225643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int size = (size_func_ == NULL) ? object->Size() : size_func_(object); 225743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 225843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen current_ += size; 225943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return object; 226043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 226143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 226243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Implementation of the ObjectIterator functions. 2263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual HeapObject* next_object() { return Next(); } 226443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 226543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 22663e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org void Initialize(Address start, Address end, HeapObjectCallback size_func); 226743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 226843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The current iteration point. 226943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Address current_; 227043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The end of iteration. 227143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Address limit_; 227243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The callback function. 227343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HeapObjectCallback size_func_; 227443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 227543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 227643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 227743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------- 2278c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// A PageIterator iterates the pages in a semi-space. 2279c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass NewSpacePageIterator BASE_EMBEDDED { 2280c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 2281c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Make an iterator that runs over all pages in to-space. 2282c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com explicit inline NewSpacePageIterator(NewSpace* space); 2283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2284c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Make an iterator that runs over all pages in the given semispace, 2285c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // even those not used in allocation. 2286c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com explicit inline NewSpacePageIterator(SemiSpace* space); 2287c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2288c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Make iterator that iterates from the page containing start 2289c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // to the page that contains limit in the same semispace. 2290c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline NewSpacePageIterator(Address start, Address limit); 2291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline bool has_next(); 2293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline NewSpacePage* next(); 2294c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2295c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private: 2296c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NewSpacePage* prev_page_; // Previous page returned. 2297c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Next page that will be returned. Cached here so that we can use this 2298c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // iterator for operations that deallocate pages. 2299c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NewSpacePage* next_page_; 2300c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Last page returned. 2301c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NewSpacePage* last_page_; 2302c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 2303c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2304c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// ----------------------------------------------------------------------------- 230643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The young generation space. 230743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 230843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The new space consists of a contiguous pair of semispaces. It simply 230943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// forwards most functions to the appropriate semispace. 231043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 23117276f14ca716596e0a0d17539516370c1f453847kasper.lundclass NewSpace : public Space { 231243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 23135a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org // Constructor. 2314ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org explicit NewSpace(Heap* heap) 23153e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org : Space(heap, NEW_SPACE, NOT_EXECUTABLE), 23163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org to_space_(heap, kToSpace), 23173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org from_space_(heap, kFromSpace), 23183e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org reservation_(), 23193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org inline_allocation_limit_step_(0) {} 232043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 232143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Sets up the new space using the given chunk. 23223c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org bool SetUp(int reserved_semispace_size_, int max_semi_space_size); 232343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 232443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Tears down the space. Heap memory was not allocated by the space, so it 232543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is not deallocated here. 232643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void TearDown(); 232743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 232843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // True if the space has been set up but not torn down. 2329f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com bool HasBeenSetUp() { 2330f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com return to_space_.HasBeenSetUp() && from_space_.HasBeenSetUp(); 233143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 233243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 233343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Flip the pair of spaces. 233443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void Flip(); 233543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 23365a6af92a1549c81fb61855518f43b712e4c0e469christian.plesner.hansen@gmail.com // Grow the capacity of the semispaces. Assumes that they are not at 2337ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org // their maximum capacity. 2338ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org void Grow(); 2339ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org 2340ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org // Shrink the capacity of the semispaces. 2341ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org void Shrink(); 234243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 234343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // True if the address or object lies in the address range of either 234443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // semispace (not necessarily below the allocation pointer). 234543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool Contains(Address a) { 23463e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org return (reinterpret_cast<uintptr_t>(a) & address_mask_) == 23473e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org reinterpret_cast<uintptr_t>(start_); 234843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 2349c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 235043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool Contains(Object* o) { 2351c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address a = reinterpret_cast<Address>(o); 2352c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return (reinterpret_cast<uintptr_t>(a) & object_mask_) == object_expected_; 235343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 235443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 235543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Return the allocated bytes in the active semispace. 2356c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual intptr_t Size() { 2357ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org return pages_used_ * NewSpacePage::kAreaSize + 23583e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org static_cast<int>(top() - to_space_.page_low()); 2359c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2360c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2361f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org // The same, but returning an int. We have to have the one that returns 2362f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org // intptr_t because it is inherited, but if we know we are dealing with the 2363f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org // new space, which can't get as big as the other spaces then this is useful: 2364f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org int SizeAsInt() { return static_cast<int>(Size()); } 23653811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 2366a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // Return the allocatable capacity of a semispace. 2367a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org intptr_t Capacity() { 2368a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org SLOW_DCHECK(to_space_.TotalCapacity() == from_space_.TotalCapacity()); 2369a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org return (to_space_.TotalCapacity() / Page::kPageSize) * 2370a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org NewSpacePage::kAreaSize; 2371c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2373a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // Return the current size of a semispace, allocatable and non-allocatable 2374a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // memory. 2375a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org intptr_t TotalCapacity() { 2376a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org DCHECK(to_space_.TotalCapacity() == from_space_.TotalCapacity()); 2377a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org return to_space_.TotalCapacity(); 2378911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 23793811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 23803811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Return the total amount of memory committed for new space. 2381f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org intptr_t CommittedMemory() { 23823811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org if (from_space_.is_committed()) return 2 * Capacity(); 2383a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org return TotalCapacity(); 23843811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 23853811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 2386057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org // Return the total amount of memory committed for new space. 2387057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org intptr_t MaximumCommittedMemory() { 2388057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org return to_space_.MaximumCommittedMemory() + 23893e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org from_space_.MaximumCommittedMemory(); 2390057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org } 2391057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org 239272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // Approximate amount of physical memory committed for this space. 239372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org size_t CommittedPhysicalMemory(); 239472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org 2395394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Return the available bytes without growing. 23963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org intptr_t Available() { return Capacity() - Size(); } 239743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 239843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Return the maximum capacity of a semispace. 2399911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org int MaximumCapacity() { 2400a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org DCHECK(to_space_.MaximumTotalCapacity() == 2401a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org from_space_.MaximumTotalCapacity()); 2402a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org return to_space_.MaximumTotalCapacity(); 2403911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 240443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2405a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org bool IsAtMaximumCapacity() { return TotalCapacity() == MaximumCapacity(); } 2406196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 2407ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org // Returns the initial capacity of a semispace. 2408a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org int InitialTotalCapacity() { 2409a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org DCHECK(to_space_.InitialTotalCapacity() == 2410a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org from_space_.InitialTotalCapacity()); 2411a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org return to_space_.InitialTotalCapacity(); 2412ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org } 2413ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org 241443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Return the address of the allocation pointer in the active semispace. 2415c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address top() { 2416e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(to_space_.current_page()->ContainsLimit(allocation_info_.top())); 2417ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org return allocation_info_.top(); 2418c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2419ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 2420ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org void set_top(Address top) { 2421e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(to_space_.current_page()->ContainsLimit(top)); 2422ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org allocation_info_.set_top(top); 2423ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org } 2424ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 2425b2498e12b28a19563de5c70c51cba52f180c1dfehpayer@chromium.org // Return the address of the allocation pointer limit in the active semispace. 2426b2498e12b28a19563de5c70c51cba52f180c1dfehpayer@chromium.org Address limit() { 2427e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(to_space_.current_page()->ContainsLimit(allocation_info_.limit())); 2428b2498e12b28a19563de5c70c51cba52f180c1dfehpayer@chromium.org return allocation_info_.limit(); 2429b2498e12b28a19563de5c70c51cba52f180c1dfehpayer@chromium.org } 2430b2498e12b28a19563de5c70c51cba52f180c1dfehpayer@chromium.org 243143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Return the address of the first object in the active semispace. 2432c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address bottom() { return to_space_.space_start(); } 243343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 243443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the age mark of the inactive semispace. 24355a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org Address age_mark() { return from_space_.age_mark(); } 243643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Set the age mark in the active semispace. 24375a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org void set_age_mark(Address mark) { to_space_.set_age_mark(mark); } 243843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 243943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The start address of the space and a bit mask. Anding an address in the 244043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // new space with the mask will result in the start address. 244143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Address start() { return start_; } 2442b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org uintptr_t mask() { return address_mask_; } 244343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2444c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com INLINE(uint32_t AddressToMarkbitIndex(Address addr)) { 2445e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(Contains(addr)); 2446e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsAligned(OffsetFrom(addr), kPointerSize) || 2447c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com IsAligned(OffsetFrom(addr) - 1, kPointerSize)); 2448c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return static_cast<uint32_t>(addr - start_) >> kPointerSizeLog2; 2449c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2450c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2451c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com INLINE(Address MarkbitIndexToAddress(uint32_t index)) { 2452c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return reinterpret_cast<Address>(index << kPointerSizeLog2); 2453c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2454c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2455ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org // The allocation top and limit address. 24563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Address* allocation_top_address() { return allocation_info_.top_address(); } 2457ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 2458ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org // The allocation limit address. 2459ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org Address* allocation_limit_address() { 2460ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org return allocation_info_.limit_address(); 2461ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org } 246243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2463a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org MUST_USE_RESULT INLINE(AllocationResult AllocateRaw(int size_in_bytes)); 246443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 246543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Reset the allocation pointer to the beginning of the active semispace. 246643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void ResetAllocationInfo(); 246743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2468b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org void UpdateInlineAllocationLimit(int size_in_bytes); 2469c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void LowerInlineAllocationLimit(intptr_t step) { 2470c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline_allocation_limit_step_ = step; 2471b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org UpdateInlineAllocationLimit(0); 2472ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org top_on_previous_step_ = allocation_info_.top(); 2473c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 247443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2475c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Get the extent of the inactive semispace (for use as a marking stack, 2476c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // or to zap it). Notice: space-addresses are not necessarily on the 2477c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // same page, so FromSpaceStart() might be above FromSpaceEnd(). 2478c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address FromSpacePageLow() { return from_space_.page_low(); } 2479c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address FromSpacePageHigh() { return from_space_.page_high(); } 2480c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address FromSpaceStart() { return from_space_.space_start(); } 2481c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address FromSpaceEnd() { return from_space_.space_end(); } 248243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2483c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Get the extent of the active semispace's pages' memory. 2484c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address ToSpaceStart() { return to_space_.space_start(); } 2485c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address ToSpaceEnd() { return to_space_.space_end(); } 2486c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2487c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline bool ToSpaceContains(Address address) { 2488c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return to_space_.Contains(address); 248943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 2490c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline bool FromSpaceContains(Address address) { 2491c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return from_space_.Contains(address); 249243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 249343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 249443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // True if the object is a heap object in the address range of the 249543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // respective semispace (not necessarily below the allocation pointer of the 249643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // semispace). 2497c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline bool ToSpaceContains(Object* o) { return to_space_.Contains(o); } 2498c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline bool FromSpaceContains(Object* o) { return from_space_.Contains(o); } 249943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2500c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Try to switch the active semispace to a new, empty, page. 2501c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Returns false if this isn't possible or reasonable (i.e., there 2502c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // are no pages, or the current page is already empty), or true 2503c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // if successful. 2504c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool AddFreshPage(); 250543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2506c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP 250743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Verify the active semispace. 25089258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org virtual void Verify(); 2509c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif 2510c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org 2511c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef DEBUG 251243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Print the active semispace. 25135a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org virtual void Print() { to_space_.Print(); } 251443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 251543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 251643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Iterates the active semispace to collect statistics. 251743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void CollectStatistics(); 251843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Reports previously collected statistics of the active semispace. 251943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void ReportStatistics(); 252043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Clears previously collected statistics. 252143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void ClearHistograms(); 252243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 252343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Record the allocation or promotion of a heap object. Note that we don't 252443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // record every single allocation, but only those that happen in the 252543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // to space during a scavenge GC. 252643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void RecordAllocation(HeapObject* obj); 252743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void RecordPromotion(HeapObject* obj); 252843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2529add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org // Return whether the operation succeded. 2530add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org bool CommitFromSpaceIfNeeded() { 2531add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org if (from_space_.is_committed()) return true; 2532add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org return from_space_.Commit(); 2533add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org } 2534add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org 2535add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org bool UncommitFromSpace() { 2536add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org if (!from_space_.is_committed()) return true; 2537add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org return from_space_.Uncommit(); 2538add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org } 2539add848f7b25aaacf2ebb523696c074d8be15e215ager@chromium.org 2540c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline intptr_t inline_allocation_limit_step() { 2541c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return inline_allocation_limit_step_; 2542c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2543c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2544c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SemiSpace* active_space() { return &to_space_; } 2545c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 254643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 2547c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Update allocation info to match the current to-space page. 2548c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void UpdateAllocationInfo(); 2549c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2550c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address chunk_base_; 2551c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com uintptr_t chunk_size_; 2552c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 255343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The semispaces. 25545a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org SemiSpace to_space_; 25555a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org SemiSpace from_space_; 25565de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::VirtualMemory reservation_; 2557c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int pages_used_; 255843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 255943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Start address and bit mask for containment testing. 256043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Address start_; 25619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org uintptr_t address_mask_; 25629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org uintptr_t object_mask_; 25639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org uintptr_t object_expected_; 256443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 256543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Allocation pointer and limit for normal allocation and allocation during 256643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // mark-compact collection. 256743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AllocationInfo allocation_info_; 2568c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2569c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // When incremental marking is active we will set allocation_info_.limit 2570c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // to be lower than actual limit and then will gradually increase it 2571c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // in steps to guarantee that we do incremental marking steps even 2572c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // when all allocation is performed from inlined generated code. 2573c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com intptr_t inline_allocation_limit_step_; 2574c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2575c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address top_on_previous_step_; 257643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 257743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HistogramInfo* allocated_histogram_; 257843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HistogramInfo* promoted_histogram_; 257943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2580a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org MUST_USE_RESULT AllocationResult SlowAllocateRaw(int size_in_bytes); 258143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 258243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen friend class SemiSpaceIterator; 258343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 258443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 258543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TRACK_MEMORY("NewSpace") 258643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 258743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 258843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 258943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------- 259043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Old object space (excluding map objects) 259143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 259243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass OldSpace : public PagedSpace { 259343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 259443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Creates an old space object with a given maximum capacity. 259543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The constructor does not allocate pages from OS. 25963e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org OldSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id, 2597ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Executability executable) 25983e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org : PagedSpace(heap, max_capacity, id, executable) {} 259943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 260043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 260143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TRACK_MEMORY("OldSpace") 260243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 260343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 260443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2605c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// For contiguous spaces, top should be in the space (or at the end) and limit 2606c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// should be the end of the space. 2607e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org#define DCHECK_SEMISPACE_ALLOCATION_INFO(info, space) \ 26083e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org SLOW_DCHECK((space).page_low() <= (info).top() && \ 26093e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org (info).top() <= (space).page_high() && \ 26103e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org (info).limit() <= (space).page_high()) 2611c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2612c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 261343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------- 2614defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org// Old space for all map objects 2615defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org 26160cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.orgclass MapSpace : public PagedSpace { 2617defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org public: 2618defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org // Creates a map space object with a maximum capacity. 261978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org MapSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id) 26200cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE), 26213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org max_map_space_pages_(kMaxMapPageIndex - 1) {} 2622defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org 2623defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org // Given an index, returns the page address. 2624c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // TODO(1600): this limit is artifical just to keep code compilable 2625c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static const int kMaxMapPageIndex = 1 << 16; 2626c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2627c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual int RoundSizeDownToObjectAlignment(int size) { 262821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org if (base::bits::IsPowerOfTwo32(Map::kSize)) { 2629c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return RoundDown(size, Map::kSize); 2630c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 2631c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return (size / Map::kSize) * Map::kSize; 26320c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 26330c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 26340c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 2635defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org protected: 2636defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org virtual void VerifyObject(HeapObject* obj); 2637defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org 2638defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org private: 2639ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org static const int kMapsPerPage = Page::kMaxRegularHeapObjectSize / Map::kSize; 26400c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 26410c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Do map space compaction if there is a page gap. 2642eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org int CompactionThreshold() { 2643eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org return kMapsPerPage * (max_map_space_pages_ - 1); 2644eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org } 2645eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org 2646eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org const int max_map_space_pages_; 26470c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 264843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 264943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TRACK_MEMORY("MapSpace") 265043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 265143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 265243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 265343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------- 265441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org// Old space for simple property cell objects 2655defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org 26560cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.orgclass CellSpace : public PagedSpace { 2657defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org public: 2658defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org // Creates a property cell space object with a maximum capacity. 2659ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org CellSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id) 26603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE) {} 266141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 266241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org virtual int RoundSizeDownToObjectAlignment(int size) { 266321d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org if (base::bits::IsPowerOfTwo32(Cell::kSize)) { 266441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org return RoundDown(size, Cell::kSize); 266541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org } else { 266641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org return (size / Cell::kSize) * Cell::kSize; 266741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org } 266841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org } 266941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 267041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org protected: 267141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org virtual void VerifyObject(HeapObject* obj); 267241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 267341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org public: 267441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org TRACK_MEMORY("CellSpace") 267541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org}; 267641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 267741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 267841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org// ----------------------------------------------------------------------------- 267941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org// Old space for all global object property cell objects 268041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 26810cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.orgclass PropertyCellSpace : public PagedSpace { 268241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org public: 268341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org // Creates a property cell space object with a maximum capacity. 26843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org PropertyCellSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id) 26853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE) {} 2686defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org 2687c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual int RoundSizeDownToObjectAlignment(int size) { 268821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org if (base::bits::IsPowerOfTwo32(PropertyCell::kSize)) { 2689b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org return RoundDown(size, PropertyCell::kSize); 2690c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 2691b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org return (size / PropertyCell::kSize) * PropertyCell::kSize; 2692c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2693c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2694c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2695defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org protected: 2696defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org virtual void VerifyObject(HeapObject* obj); 2697defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org 2698defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org public: 269941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org TRACK_MEMORY("PropertyCellSpace") 2700defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org}; 2701defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org 2702defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org 2703defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org// ----------------------------------------------------------------------------- 270443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Large objects ( > Page::kMaxHeapObjectSize ) are allocated and managed by 270543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the large object space. A large object is allocated from OS heap with 270643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// extra padding bytes (Page::kPageSize + Page::kObjectStartOffset). 270743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A large object always starts at Page::kObjectStartOffset to a page. 270843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Large objects do not move during garbage collections. 270943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 27107276f14ca716596e0a0d17539516370c1f453847kasper.lundclass LargeObjectSpace : public Space { 271143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 2712394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com LargeObjectSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id); 27139258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org virtual ~LargeObjectSpace() {} 271443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 271543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Initializes internal data structures. 2716f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com bool SetUp(); 271743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 271843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Releases internal resources, frees objects in this space. 271943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void TearDown(); 272043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2721c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static intptr_t ObjectSizeFor(intptr_t chunk_size) { 2722c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (chunk_size <= (Page::kPageSize + Page::kObjectStartOffset)) return 0; 2723c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return chunk_size - Page::kPageSize - Page::kObjectStartOffset; 2724c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2725c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2726c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Shared implementation of AllocateRaw, AllocateRawCode and 2727c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // AllocateRawFixedArray. 27283e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org MUST_USE_RESULT AllocationResult 27293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org AllocateRaw(int object_size, Executability executable); 273043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 273130ce411529579186181838984710b0b0980857aaricow@chromium.org // Available bytes for objects in this space. 2732ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org inline intptr_t Available(); 273343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 27343e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org virtual intptr_t Size() { return size_; } 273543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 27363e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org virtual intptr_t SizeOfObjects() { return objects_size_; } 27374a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 27383e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org intptr_t MaximumCommittedMemory() { return maximum_committed_; } 2739057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org 27403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org intptr_t CommittedMemory() { return Size(); } 27417a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 274272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // Approximate amount of physical memory committed for this space. 274372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org size_t CommittedPhysicalMemory(); 274472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org 27453e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org int PageCount() { return page_count_; } 274643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2747b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org // Finds an object for a given address, returns a Smi if it is not found. 2748b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org // The function iterates through all objects in this space, may be slow. 2749b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org Object* FindObject(Address a); 275043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2751531dfe85209e15c3e292569c285a5be54910da7cjkummerow@chromium.org // Finds a large object page containing the given address, returns NULL 2752d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // if such a page doesn't exist. 2753531dfe85209e15c3e292569c285a5be54910da7cjkummerow@chromium.org LargePage* FindPage(Address a); 275443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 275543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Frees unmarked objects. 275643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void FreeUnmarkedObjects(); 275743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 275843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Checks whether a heap object is in this space; O(1). 275943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool Contains(HeapObject* obj); 276043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 276143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Checks whether the space is empty. 2762c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool IsEmpty() { return first_page_ == NULL; } 276343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2764c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com LargePage* first_page() { return first_page_; } 2765c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2766c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP 27679258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org virtual void Verify(); 2768c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#endif 2769c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org 2770c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef DEBUG 27719258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org virtual void Print(); 277243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void ReportStatistics(); 277343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void CollectCodeStatistics(); 277443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 277543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Checks whether an address is in the object area in this space. It 277643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // iterates all objects in the space. May be slow. 2777b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org bool SlowContains(Address addr) { return FindObject(addr)->IsHeapObject(); } 277843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 277943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 2780394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com intptr_t max_capacity_; 2781057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org intptr_t maximum_committed_; 278243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The head of the linked list of large object chunks. 2783c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com LargePage* first_page_; 27843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org intptr_t size_; // allocated bytes 27853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org int page_count_; // number of chunks 27864a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com intptr_t objects_size_; // size of objects 2787531dfe85209e15c3e292569c285a5be54910da7cjkummerow@chromium.org // Map MemoryChunk::kAlignment-aligned chunks to large pages covering them 2788531dfe85209e15c3e292569c285a5be54910da7cjkummerow@chromium.org HashMap chunk_map_; 278943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2790f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org friend class LargeObjectIterator; 2791f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org 279243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 279343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TRACK_MEMORY("LargeObjectSpace") 279443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 279543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 279643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 27973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgclass LargeObjectIterator : public ObjectIterator { 279843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 279943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen explicit LargeObjectIterator(LargeObjectSpace* space); 280043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen LargeObjectIterator(LargeObjectSpace* space, HeapObjectCallback size_func); 280143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2802c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* Next(); 280343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 280443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // implementation of ObjectIterator. 2805c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual HeapObject* next_object() { return Next(); } 280643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 280743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 2808c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com LargePage* current_; 280943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HeapObjectCallback size_func_; 281043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 281143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 281243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2813c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Iterates over the chunks (pages and large object pages) that can contain 2814c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// pointers to new space. 2815c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass PointerChunkIterator BASE_EMBEDDED { 2816c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 2817c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline explicit PointerChunkIterator(Heap* heap); 2818c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2819c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Return NULL when the iterator is done. 2820c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk* next() { 2821c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com switch (state_) { 2822c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case kOldPointerState: { 2823c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (old_pointer_iterator_.has_next()) { 2824c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return old_pointer_iterator_.next(); 2825c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2826c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com state_ = kMapState; 2827c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Fall through. 2828c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2829c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case kMapState: { 2830c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (map_iterator_.has_next()) { 2831c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return map_iterator_.next(); 2832c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2833c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com state_ = kLargeObjectState; 2834c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Fall through. 2835c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2836c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case kLargeObjectState: { 2837c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com HeapObject* heap_object; 2838c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com do { 2839c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com heap_object = lo_iterator_.Next(); 2840c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (heap_object == NULL) { 2841c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com state_ = kFinishedState; 2842c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return NULL; 2843c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2844c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Fixed arrays are the only pointer-containing objects in large 2845c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // object space. 2846c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } while (!heap_object->IsFixedArray()); 2847c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk* answer = MemoryChunk::FromAddress(heap_object->address()); 2848c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return answer; 2849c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2850c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case kFinishedState: 2851c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return NULL; 2852c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com default: 2853c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com break; 2854c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2855c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com UNREACHABLE(); 2856c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return NULL; 2857c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2858c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2859c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2860c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private: 28613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org enum State { kOldPointerState, kMapState, kLargeObjectState, kFinishedState }; 2862c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com State state_; 2863c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PageIterator old_pointer_iterator_; 2864c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PageIterator map_iterator_; 2865c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com LargeObjectIterator lo_iterator_; 2866c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 2867c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2868c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2869ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#ifdef DEBUG 2870ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstruct CommentStatistic { 2871ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org const char* comment; 2872ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int size; 2873ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int count; 2874ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org void Clear() { 2875ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org comment = NULL; 2876ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org size = 0; 2877ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org count = 0; 2878ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 2879ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Must be small, since an iteration is used for lookup. 2880ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org static const int kMaxComments = 64; 2881ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}; 2882ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#endif 28833e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org} 28843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org} // namespace v8::internal 2885ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 28863e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#endif // V8_HEAP_SPACES_H_ 2887