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

Side by Side Diff: src/spaces.h

Issue 6745033: On store buffer overflow we mark individidual pages for... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 8 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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 } 296 }
297 }; 297 };
298 298
299 299
300 // MemoryChunk represents a memory region owned by a specific space. 300 // MemoryChunk represents a memory region owned by a specific space.
301 // It is divided into the header and the body. Chunk start is always 301 // It is divided into the header and the body. Chunk start is always
302 // 1MB aligned. Start of the body is aligned so it can accomodate 302 // 1MB aligned. Start of the body is aligned so it can accomodate
303 // any heap object. 303 // any heap object.
304 class MemoryChunk { 304 class MemoryChunk {
305 public: 305 public:
306 // Only works if the pointer is in the first kPageSize of the MemoryChunk.
306 static MemoryChunk* FromAddress(Address a) { 307 static MemoryChunk* FromAddress(Address a) {
307 return reinterpret_cast<MemoryChunk*>(OffsetFrom(a) & ~kAlignmentMask); 308 return reinterpret_cast<MemoryChunk*>(OffsetFrom(a) & ~kAlignmentMask);
308 } 309 }
309 310
311 // Only works for addresses in pointer spaces, not data or code spaces.
312 static inline MemoryChunk* FromAnyPointerAddress(Address addr);
313
310 Address address() { return reinterpret_cast<Address>(this); } 314 Address address() { return reinterpret_cast<Address>(this); }
311 315
312 bool is_valid() { return address() != NULL; } 316 bool is_valid() { return address() != NULL; }
313 317
314 MemoryChunk* next_chunk() const { return next_chunk_; } 318 MemoryChunk* next_chunk() const { return next_chunk_; }
315 MemoryChunk* prev_chunk() const { return prev_chunk_; } 319 MemoryChunk* prev_chunk() const { return prev_chunk_; }
316 320
317 void set_next_chunk(MemoryChunk* next) { next_chunk_ = next; } 321 void set_next_chunk(MemoryChunk* next) { next_chunk_ = next; }
318 void set_prev_chunk(MemoryChunk* prev) { prev_chunk_ = prev; } 322 void set_prev_chunk(MemoryChunk* prev) { prev_chunk_ = prev; }
319 323
320 Space* owner() const { return owner_; } 324 Space* owner() const {
325 if ((reinterpret_cast<intptr_t>(owner_) & kFailureTagMask) ==
326 kFailureTag) {
327 return reinterpret_cast<Space*>(owner_ - kFailureTag);
328 } else {
329 return NULL;
330 }
331 }
332
333 void set_owner(Space* space) {
334 owner_ = reinterpret_cast<Address>(space) + kFailureTag;
Vyacheslav Egorov (Chromium) 2011/03/28 15:13:19 add assertion that checks that space was properly
Erik Corry 2011/03/28 15:56:07 Done.
335 ASSERT((reinterpret_cast<intptr_t>(owner_) & kFailureTagMask) ==
336 kFailureTag);
337 }
338
339 bool scan_on_scavenge() { return scan_on_scavenge_; }
340 void set_scan_on_scavenge(bool scan) { scan_on_scavenge_ = scan; }
341
342 int store_buffer_counter() { return store_buffer_counter_; }
343 void set_store_buffer_counter(int counter) {
344 store_buffer_counter_ = counter;
345 }
321 346
322 Address body() { return address() + kObjectStartOffset; } 347 Address body() { return address() + kObjectStartOffset; }
323 348
324 int body_size() { return size() - kObjectStartOffset; } 349 int body_size() { return size() - kObjectStartOffset; }
325 350
326 bool Contains(Address addr) { 351 bool Contains(Address addr) {
327 return addr >= body() && addr < address() + size(); 352 return addr >= body() && addr < address() + size();
328 } 353 }
329 354
330 enum MemoryChunkFlags { 355 enum MemoryChunkFlags {
(...skipping 13 matching lines...) Expand all
344 369
345 bool IsFlagSet(int flag) { 370 bool IsFlagSet(int flag) {
346 return (flags_ & (1 << flag)) != 0; 371 return (flags_ & (1 << flag)) != 0;
347 } 372 }
348 373
349 static const intptr_t kAlignment = (1 << kPageSizeBits); 374 static const intptr_t kAlignment = (1 << kPageSizeBits);
350 375
351 static const intptr_t kAlignmentMask = kAlignment - 1; 376 static const intptr_t kAlignmentMask = kAlignment - 1;
352 377
353 static const size_t kHeaderSize = kPointerSize + kPointerSize + kPointerSize + 378 static const size_t kHeaderSize = kPointerSize + kPointerSize + kPointerSize +
354 kPointerSize + kPointerSize + kPointerSize; 379 kPointerSize + kPointerSize + kPointerSize + kPointerSize;
355 380
356 static const size_t kMarksBitmapLength = 381 static const size_t kMarksBitmapLength =
357 (1 << kPageSizeBits) >> (kPointerSizeLog2); 382 (1 << kPageSizeBits) >> (kPointerSizeLog2);
358 383
359 static const size_t kMarksBitmapSize = 384 static const size_t kMarksBitmapSize =
360 (1 << kPageSizeBits) >> (kPointerSizeLog2 + kBitsPerByteLog2); 385 (1 << kPageSizeBits) >> (kPointerSizeLog2 + kBitsPerByteLog2);
361 386
362 static const int kBodyOffset = 387 static const int kBodyOffset =
363 CODE_POINTER_ALIGN(MAP_POINTER_ALIGN(kHeaderSize + kMarksBitmapSize)); 388 CODE_POINTER_ALIGN(MAP_POINTER_ALIGN(kHeaderSize + kMarksBitmapSize));
364 389
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 } 439 }
415 440
416 void InsertAfter(MemoryChunk* other); 441 void InsertAfter(MemoryChunk* other);
417 void Unlink(); 442 void Unlink();
418 443
419 protected: 444 protected:
420 MemoryChunk* next_chunk_; 445 MemoryChunk* next_chunk_;
421 MemoryChunk* prev_chunk_; 446 MemoryChunk* prev_chunk_;
422 size_t size_; 447 size_t size_;
423 intptr_t flags_; 448 intptr_t flags_;
424 Space* owner_; 449 // The identity of the owning space. This is tagged as a heap pointer, but
Vyacheslav Egorov (Chromium) 2011/03/28 15:13:19 Update comment. Now this is tagged as a failure an
Erik Corry 2011/03/28 15:56:07 Done.
450 // no heap object can reside at this address, therefore it can be
451 // distinguished from any entry in a fixed array.
452 Address owner_;
453 // This flag indicates that the page is not being tracked by the store buffer.
Vyacheslav Egorov (Chromium) 2011/03/28 15:13:19 Why are we using bool instead of built-in flags?
Erik Corry 2011/03/28 15:56:07 Because my next step will be to read it from gener
454 // At any point where we have to iterate over pointers to new space, we must
455 // search this page for pointers to new space.
456 bool scan_on_scavenge_;
457 // Used by the store buffer to keep track of which pages to mark scan-on-
458 // scavenge.
459 int store_buffer_counter_;
Vyacheslav Egorov (Chromium) 2011/03/28 15:13:19 You added 2 fields but kHeaderSize was increased o
Erik Corry 2011/03/28 15:56:07 There is a static assert that checks that the size
425 460
426 static MemoryChunk* Initialize(Address base, 461 static MemoryChunk* Initialize(Address base,
427 size_t size, 462 size_t size,
428 Executability executable, 463 Executability executable,
429 Space* owner); 464 Space* owner);
430 465
431 friend class MemoryAllocator; 466 friend class MemoryAllocator;
432 }; 467 };
433 468
434 STATIC_CHECK(sizeof(MemoryChunk) <= MemoryChunk::kHeaderSize); 469 STATIC_CHECK(sizeof(MemoryChunk) <= MemoryChunk::kHeaderSize);
435 470
436 // ----------------------------------------------------------------------------- 471 // -----------------------------------------------------------------------------
437 // A page is a memory chunk of a size 1MB. Large object pages may be larger. 472 // A page is a memory chunk of a size 1MB. Large object pages may be larger.
438 // 473 //
439 // The only way to get a page pointer is by calling factory methods: 474 // The only way to get a page pointer is by calling factory methods:
440 // Page* p = Page::FromAddress(addr); or 475 // Page* p = Page::FromAddress(addr); or
441 // Page* p = Page::FromAllocationTop(top); 476 // Page* p = Page::FromAllocationTop(top);
442 class Page : public MemoryChunk { 477 class Page : public MemoryChunk {
443 public: 478 public:
444 // Returns the page containing a given address. The address ranges 479 // Returns the page containing a given address. The address ranges
445 // from [page_addr .. page_addr + kPageSize[ 480 // from [page_addr .. page_addr + kPageSize[
446 // 481 // This only works if the object is in fact in a page. See also MemoryChunk::
447 // Note that this function only works for addresses in normal paged 482 // FromAddress() and FromAnyAddress().
448 // spaces and addresses in the first 1Mbyte of large object pages (i.e.,
449 // the start of large objects but not necessarily derived pointers
450 // within them).
451 INLINE(static Page* FromAddress(Address a)) { 483 INLINE(static Page* FromAddress(Address a)) {
452 return reinterpret_cast<Page*>(OffsetFrom(a) & ~kPageAlignmentMask); 484 return reinterpret_cast<Page*>(OffsetFrom(a) & ~kPageAlignmentMask);
453 } 485 }
454 486
455 // Returns the page containing an allocation top. Because an allocation 487 // Returns the page containing an allocation top. Because an allocation
456 // top address can be the upper bound of the page, we need to subtract 488 // top address can be the upper bound of the page, we need to subtract
457 // it with kPointerSize first. The address ranges from 489 // it with kPointerSize first. The address ranges from
458 // [page_addr + kObjectStartOffset .. page_addr + kPageSize]. 490 // [page_addr + kObjectStartOffset .. page_addr + kPageSize].
459 INLINE(static Page* FromAllocationTop(Address top)) { 491 INLINE(static Page* FromAllocationTop(Address top)) {
460 Page* p = FromAddress(top - kPointerSize); 492 Page* p = FromAddress(top - kPointerSize);
461 ASSERT_PAGE_OFFSET(p->Offset(top)); 493 ASSERT_PAGE_OFFSET(p->Offset(top));
462 return p; 494 return p;
463 } 495 }
464 496
465 // Returns the next page in the chain of pages owned by a space. 497 // Returns the next page in the chain of pages owned by a space.
466 inline Page* next_page(); 498 inline Page* next_page();
467 inline Page* prev_page(); 499 inline Page* prev_page();
468 inline void set_next_page(Page* page); 500 inline void set_next_page(Page* page);
469 inline void set_prev_page(Page* page); 501 inline void set_prev_page(Page* page);
470 502
471 PagedSpace* owner() const { return reinterpret_cast<PagedSpace*>(owner_); }
472
473 // Returns the start address of the object area in this page. 503 // Returns the start address of the object area in this page.
474 Address ObjectAreaStart() { return address() + kObjectStartOffset; } 504 Address ObjectAreaStart() { return address() + kObjectStartOffset; }
475 505
476 // Returns the end address (exclusive) of the object area in this page. 506 // Returns the end address (exclusive) of the object area in this page.
477 Address ObjectAreaEnd() { return address() + Page::kPageSize; } 507 Address ObjectAreaEnd() { return address() + Page::kPageSize; }
478 508
479 // Checks whether an address is page aligned. 509 // Checks whether an address is page aligned.
480 static bool IsAlignedToPageSize(Address a) { 510 static bool IsAlignedToPageSize(Address a) {
481 return 0 == (OffsetFrom(a) & kPageAlignmentMask); 511 return 0 == (OffsetFrom(a) & kPageAlignmentMask);
482 } 512 }
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 void Zap(); 1125 void Zap();
1096 static intptr_t SumFreeList(FreeListNode* node); 1126 static intptr_t SumFreeList(FreeListNode* node);
1097 intptr_t SumFreeLists(); 1127 intptr_t SumFreeLists();
1098 #endif 1128 #endif
1099 1129
1100 private: 1130 private:
1101 // The size range of blocks, in bytes. 1131 // The size range of blocks, in bytes.
1102 static const int kMinBlockSize = 3 * kPointerSize; 1132 static const int kMinBlockSize = 3 * kPointerSize;
1103 static const int kMaxBlockSize = Page::kMaxHeapObjectSize; 1133 static const int kMaxBlockSize = Page::kMaxHeapObjectSize;
1104 1134
1105 // The identity of the owning space.
1106 PagedSpace* owner_; 1135 PagedSpace* owner_;
1107 1136
1108 // Total available bytes in all blocks on this free list. 1137 // Total available bytes in all blocks on this free list.
1109 int available_; 1138 int available_;
1110 1139
1111 static const int kSmallListMin = 0x20 * kPointerSize; 1140 static const int kSmallListMin = 0x20 * kPointerSize;
1112 static const int kSmallListMax = 0xff * kPointerSize; 1141 static const int kSmallListMax = 0xff * kPointerSize;
1113 static const int kMediumListMax = 0x7ff * kPointerSize; 1142 static const int kMediumListMax = 0x7ff * kPointerSize;
1114 static const int kLargeListMax = 0x3fff * kPointerSize; 1143 static const int kLargeListMax = 0x3fff * kPointerSize;
1115 static const int kSmallAllocationMax = kSmallListMin - kPointerSize; 1144 static const int kSmallAllocationMax = kSmallListMin - kPointerSize;
(...skipping 882 matching lines...) Expand 10 before | Expand all | Expand 10 after
1998 2027
1999 // implementation of ObjectIterator. 2028 // implementation of ObjectIterator.
2000 virtual HeapObject* next_object() { return next(); } 2029 virtual HeapObject* next_object() { return next(); }
2001 2030
2002 private: 2031 private:
2003 LargePage* current_; 2032 LargePage* current_;
2004 HeapObjectCallback size_func_; 2033 HeapObjectCallback size_func_;
2005 }; 2034 };
2006 2035
2007 2036
2037 // Iterates over the chunks (pages and large object pages) that can contain
2038 // pointers to new space.
2039 class PointerChunkIterator BASE_EMBEDDED {
2040 public:
2041 inline PointerChunkIterator();
2042
2043 // Return NULL when the iterator is done.
2044 MemoryChunk* next() {
2045 switch (state_) {
2046 case kOldPointerState: {
2047 if (old_pointer_iterator_.has_next()) {
2048 return old_pointer_iterator_.next();
2049 }
2050 state_ = kMapState;
2051 // FALL THROUGH!
Vyacheslav Egorov (Chromium) 2011/03/28 15:13:19 this comment does not look like something we usual
Erik Corry 2011/03/28 15:56:07 lowercaseified.
2052 }
2053 case kMapState: {
2054 if (map_iterator_.has_next()) {
2055 return map_iterator_.next();
2056 }
2057 state_ = kLargeObjectState;
2058 // FALL THROUGH!
2059 }
2060 case kLargeObjectState: {
2061 HeapObject* heap_object;
2062 do {
2063 heap_object = lo_iterator_.next();
2064 if (heap_object == NULL) {
2065 state_ = kFinishedState;
2066 return NULL;
2067 }
2068 // Fixed arrays are the only pointer-containing objects in large
2069 // object space.
2070 } while (!heap_object->IsFixedArray());
2071 MemoryChunk* answer = MemoryChunk::FromAddress(heap_object->address());
2072 return answer;
2073 }
2074 case kFinishedState:
2075 return NULL;
2076 default:
2077 break;
2078 }
2079 UNREACHABLE();
2080 return NULL;
2081 }
2082
2083
2084 private:
2085 enum State {
2086 kOldPointerState,
2087 kMapState,
2088 kLargeObjectState,
2089 kFinishedState
2090 };
2091 State state_;
2092 PageIterator old_pointer_iterator_;
2093 PageIterator map_iterator_;
2094 LargeObjectIterator lo_iterator_;
2095 };
2096
2097
2008 } } // namespace v8::internal 2098 } } // namespace v8::internal
2009 2099
2010 #endif // V8_SPACES_H_ 2100 #endif // V8_SPACES_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698