Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/spaces.h

Issue 6088012: Separate markbits from heap object map words into bitmaps. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: profiler related code reenabled Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2006-2010 the V8 project authors. All rights reserved. 1 // Copyright 2006-2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 106
107 #define ASSERT_MAP_PAGE_INDEX(index) \ 107 #define ASSERT_MAP_PAGE_INDEX(index) \
108 ASSERT((0 <= index) && (index <= MapSpace::kMaxMapPageIndex)) 108 ASSERT((0 <= index) && (index <= MapSpace::kMaxMapPageIndex))
109 109
110 110
111 class PagedSpace; 111 class PagedSpace;
112 class MemoryAllocator; 112 class MemoryAllocator;
113 class AllocationInfo; 113 class AllocationInfo;
114 class Space; 114 class Space;
115 115
116
117 // Bitmap is a sequence of cells each containing fixed number of bits.
Erik Corry 2011/01/07 12:13:21 Perhaps add a comment with the word 'endian' since
118 template<typename StorageDescriptor>
119 class Bitmap {
120 public:
121 typedef uint32_t CellType;
122 static const uint32_t kBitsPerCell = 32;
123 static const uint32_t kBitsPerCellLog2 = 5;
124
125 static int CellsForLength(int length) {
126 return (length + kBitsPerCell - 1) >> kBitsPerCellLog2;
127 }
128
129 int CellsCount() {
130 return StorageDescriptor::CellsCount(this->address());
131 }
132
133 static int SizeFor(int cells_count) {
134 return sizeof(CellType)*cells_count;
135 }
136
137 INLINE(CellType* cells()) {
138 return reinterpret_cast<CellType*>(this);
139 }
140
141 INLINE(Address address()) {
142 return reinterpret_cast<Address>(this);
143 }
144
145 INLINE(static Bitmap* FromAddress(Address addr)) {
146 return reinterpret_cast<Bitmap*>(addr);
147 }
148
149 INLINE(static Bitmap* FromAddress(uint32_t* addr)) {
150 return reinterpret_cast<Bitmap*>(addr);
151 }
152
153 INLINE(bool TestAndSet(const uint32_t index)) {
154 const uint32_t mask = 1 << index;
155 if (cells()[index >> kBitsPerCellLog2] & mask) {
156 return true;
157 } else {
158 cells()[index >> kBitsPerCellLog2] |= mask;
159 return false;
160 }
161 }
162
163 INLINE(bool Get(uint32_t index)) {
164 uint32_t mask = 1 << index;
165 return (this->cells()[index >> kBitsPerCellLog2] & mask) != 0;
166 }
167
168 INLINE(void Set(uint32_t index, bool value)) {
Erik Corry 2011/01/07 12:13:21 I think it's nicer to have Set and Clear methods i
169 uint32_t mask = 1 << index;
170 if (value) {
171 this->cells()[index >> kBitsPerCellLog2] |= mask;
172 } else {
173 this->cells()[index >> kBitsPerCellLog2] &= ~mask;
174 }
175 }
176
177 INLINE(void ClearRange(uint32_t start, uint32_t size)) {
178 const uint32_t end = start + size;
179 const uint32_t start_cell = start >> kBitsPerCellLog2;
180 const uint32_t end_cell = end >> kBitsPerCellLog2;
181
182 const uint32_t start_mask = (-1) << start;
Erik Corry 2011/01/07 12:13:21 I think you are assuming here that the rhs of the
183 const uint32_t end_mask = (1 << end) - 1;
184
185 if (start_cell == end_cell) {
186 cells()[start_cell] &= ~(start_mask & end_mask);
187 } else {
188 cells()[start_cell] &= ~start_mask;
189 cells()[end_cell] &= ~end_mask;
Erik Corry 2011/01/07 12:13:21 I think this reads and writes (but doesn't change)
190
191 for(uint32_t cell = start_cell + 1, last_cell = end_cell - 1;
192 cell <= last_cell;
193 cell++) {
194 cells()[cell] = 0;
195 }
196 }
197 }
198
199
Erik Corry 2011/01/07 12:13:21 Why two blank lines?
200 INLINE(void Clear()) {
201 for (int i = 0; i < CellsCount(); i++) {
202 cells()[i] = 0;
203 }
204 }
205
206
207 static void PrintWord(const uint32_t& word, const char* sep = " ") {
208 for (uint32_t mask = 1; mask != 0; mask <<= 1) {
209 PrintF((mask & word) ? "1" : "0");
210 }
211 PrintF("%s", sep);
212 }
213
214
215 void Print() {
216 for (int i = 0; i < CellsCount(); i++) {
217 PrintWord(cells()[i]);
218 }
219 PrintF("\n");
220 }
221
222
223 bool IsClean() {
224 for (int i = 0; i < CellsCount(); i++) {
225 if (cells()[i] != 0) return false;
226 }
227 return true;
228 }
229 };
230
231
116 // MemoryChunk represents a memory region owned by a specific space. 232 // MemoryChunk represents a memory region owned by a specific space.
117 // It is divided into the header and the body. Chunk start is always 233 // It is divided into the header and the body. Chunk start is always
118 // 1MB aligned. Start of the body is aligned so it can accomodate 234 // 1MB aligned. Start of the body is aligned so it can accomodate
119 // any heap object. 235 // any heap object.
120 class MemoryChunk { 236 class MemoryChunk {
121 public: 237 public:
122 static MemoryChunk* FromAddress(Address a) { 238 static MemoryChunk* FromAddress(Address a) {
123 return reinterpret_cast<MemoryChunk*>(OffsetFrom(a) & ~kAlignmentMask); 239 return reinterpret_cast<MemoryChunk*>(OffsetFrom(a) & ~kAlignmentMask);
124 } 240 }
125 241
(...skipping 28 matching lines...) Expand all
154 return (flags_ & (1 << flag)) != 0; 270 return (flags_ & (1 << flag)) != 0;
155 } 271 }
156 272
157 static const intptr_t kAlignment = (1 << kPageSizeBits); 273 static const intptr_t kAlignment = (1 << kPageSizeBits);
158 274
159 static const intptr_t kAlignmentMask = kAlignment - 1; 275 static const intptr_t kAlignmentMask = kAlignment - 1;
160 276
161 static const size_t kHeaderSize = kPointerSize + kPointerSize + kPointerSize + 277 static const size_t kHeaderSize = kPointerSize + kPointerSize + kPointerSize +
162 kPointerSize + kPointerSize; 278 kPointerSize + kPointerSize;
163 279
280 static const size_t kBitsPerByteLog2 = 3;
Erik Corry 2011/01/07 12:13:21 This constant already exists in globals.h
281
282 static const size_t kMarksBitmapLength =
283 (1 << kPageSizeBits) >> (kPointerSizeLog2);
284
285 static const size_t kMarksBitmapSize =
286 (1 << kPageSizeBits) >> (kPointerSizeLog2 + kBitsPerByteLog2);
287
164 static const int kBodyOffset = 288 static const int kBodyOffset =
165 CODE_POINTER_ALIGN(MAP_POINTER_ALIGN(kHeaderSize)); 289 CODE_POINTER_ALIGN(MAP_POINTER_ALIGN(kHeaderSize + kMarksBitmapSize));
166 290
167 size_t size() const { return size_; } 291 size_t size() const { return size_; }
168 292
169 Executability executable() { 293 Executability executable() {
170 return IsFlagSet(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE; 294 return IsFlagSet(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE;
171 } 295 }
172 296
297 // ---------------------------------------------------------------------
298 // Markbits support
299 class BitmapStorageDescriptor {
300 public:
301 INLINE(static int CellsCount(Address addr)) {
302 return Bitmap<BitmapStorageDescriptor>::CellsForLength(
303 kMarksBitmapLength);
304 }
305 };
306
307 typedef Bitmap<BitmapStorageDescriptor> MarkbitsBitmap;
308
309 inline MarkbitsBitmap* markbits() {
310 return MarkbitsBitmap::FromAddress(address() + kHeaderSize);
311 }
312
313 // TODO [EVE] when do we need this crap?
Erik Corry 2011/01/07 12:13:21 Does this lint or pass the FCC?
314 inline uint32_t Address2Markbit(Address addr) {
315 return static_cast<uint32_t>(addr - this->address()) >> kPointerSizeLog2;
316 }
317
318 inline static uint32_t FastAddress2Markbit(Address addr) {
319 const intptr_t offset =
320 reinterpret_cast<intptr_t>(addr) & kAlignmentMask;
321
322 return static_cast<uint32_t>(offset) >> kPointerSizeLog2;
323 }
324
325 inline Address Markbit2Address(uint32_t index) {
326 return this->address() + (index << kPointerSizeLog2);
327 }
328
173 protected: 329 protected:
174 MemoryChunk* next_chunk_; 330 MemoryChunk* next_chunk_;
175 size_t size_; 331 size_t size_;
176 intptr_t flags_; 332 intptr_t flags_;
177 Space* owner_; 333 Space* owner_;
178 334
179 private: 335 private:
180 static MemoryChunk* Initialize(Address base, 336 static MemoryChunk* Initialize(Address base,
181 size_t size, 337 size_t size,
182 Executability executable, 338 Executability executable,
183 Space* owner) { 339 Space* owner) {
184 MemoryChunk* chunk = FromAddress(base); 340 MemoryChunk* chunk = FromAddress(base);
185 341
186 ASSERT(base == chunk->address()); 342 ASSERT(base == chunk->address());
187 343
188 chunk->next_chunk_ = NULL; 344 chunk->next_chunk_ = NULL;
189 chunk->size_ = size; 345 chunk->size_ = size;
190 chunk->flags_ = 0; 346 chunk->flags_ = 0;
191 chunk->owner_ = owner; 347 chunk->owner_ = owner;
348 chunk->markbits()->Clear();
192 349
193 if (executable == EXECUTABLE) chunk->SetFlag(IS_EXECUTABLE); 350 if (executable == EXECUTABLE) chunk->SetFlag(IS_EXECUTABLE);
194 351
195 return chunk; 352 return chunk;
196 } 353 }
197 354
198 friend class MemoryAllocator; 355 friend class MemoryAllocator;
199 }; 356 };
200 357
201 STATIC_CHECK(sizeof(MemoryChunk) <= MemoryChunk::kHeaderSize); 358 STATIC_CHECK(sizeof(MemoryChunk) <= MemoryChunk::kHeaderSize);
(...skipping 1205 matching lines...) Expand 10 before | Expand all | Expand 10 after
1407 // Get the age mark of the inactive semispace. 1564 // Get the age mark of the inactive semispace.
1408 Address age_mark() { return from_space_.age_mark(); } 1565 Address age_mark() { return from_space_.age_mark(); }
1409 // Set the age mark in the active semispace. 1566 // Set the age mark in the active semispace.
1410 void set_age_mark(Address mark) { to_space_.set_age_mark(mark); } 1567 void set_age_mark(Address mark) { to_space_.set_age_mark(mark); }
1411 1568
1412 // The start address of the space and a bit mask. Anding an address in the 1569 // The start address of the space and a bit mask. Anding an address in the
1413 // new space with the mask will result in the start address. 1570 // new space with the mask will result in the start address.
1414 Address start() { return start_; } 1571 Address start() { return start_; }
1415 uintptr_t mask() { return address_mask_; } 1572 uintptr_t mask() { return address_mask_; }
1416 1573
1574 INLINE(uint32_t Address2MarkbitIndex(Address addr)) {
1575 ASSERT(Contains(addr));
1576 ASSERT(IsAligned(OffsetFrom(addr), kPointerSize));
1577 return static_cast<uint32_t>(addr - start_) >> kPointerSizeLog2;
1578 }
1579
1580 INLINE(Address MarkbitIndex2Address(uint32_t index)) {
1581 return reinterpret_cast<Address>(index << kPointerSizeLog2);
1582 }
1583
1417 // The allocation top and limit addresses. 1584 // The allocation top and limit addresses.
1418 Address* allocation_top_address() { return &allocation_info_.top; } 1585 Address* allocation_top_address() { return &allocation_info_.top; }
1419 Address* allocation_limit_address() { return &allocation_info_.limit; } 1586 Address* allocation_limit_address() { return &allocation_info_.limit; }
1420 1587
1421 MUST_USE_RESULT MaybeObject* AllocateRaw(int size_in_bytes) { 1588 MUST_USE_RESULT MaybeObject* AllocateRaw(int size_in_bytes) {
1422 return AllocateRawInternal(size_in_bytes, &allocation_info_); 1589 return AllocateRawInternal(size_in_bytes, &allocation_info_);
1423 } 1590 }
1424 1591
1425 // Reset the allocation pointer to the beginning of the active semispace. 1592 // Reset the allocation pointer to the beginning of the active semispace.
1426 void ResetAllocationInfo(); 1593 void ResetAllocationInfo();
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after
2093 2260
2094 private: 2261 private:
2095 LargePage* current_; 2262 LargePage* current_;
2096 HeapObjectCallback size_func_; 2263 HeapObjectCallback size_func_;
2097 }; 2264 };
2098 2265
2099 2266
2100 } } // namespace v8::internal 2267 } } // namespace v8::internal
2101 2268
2102 #endif // V8_SPACES_H_ 2269 #endif // V8_SPACES_H_
OLDNEW
« src/mark-compact.cc ('K') | « src/objects-inl.h ('k') | src/spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698