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

Side by Side Diff: src/spaces.h

Issue 8055029: Add experimental support for tracing the state of the VM heap to a file Base URL: http://v8.googlecode.com/svn/branches/experimental/heap-visualization/
Patch Set: Created 9 years, 2 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
« no previous file with comments | « src/mark-compact.cc ('k') | src/spaces.cc » ('j') | src/spaces.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 1279
1280 static inline bool IsFreeListNode(HeapObject* object); 1280 static inline bool IsFreeListNode(HeapObject* object);
1281 1281
1282 // Set the size in bytes, which can be read with HeapObject::Size(). This 1282 // Set the size in bytes, which can be read with HeapObject::Size(). This
1283 // function also writes a map to the first word of the block so that it 1283 // function also writes a map to the first word of the block so that it
1284 // looks like a heap object to the garbage collector and heap iteration 1284 // looks like a heap object to the garbage collector and heap iteration
1285 // functions. 1285 // functions.
1286 void set_size(Heap* heap, int size_in_bytes); 1286 void set_size(Heap* heap, int size_in_bytes);
1287 1287
1288 // Accessors for the next field. 1288 // Accessors for the next field.
1289 inline FreeListNode* next(); 1289 FreeListNode* next();
1290 inline FreeListNode** next_address(); 1290 inline FreeListNode** next_address();
1291 inline void set_next(FreeListNode* next); 1291 inline void set_next(FreeListNode* next);
1292 1292
1293 inline void Zap(); 1293 inline void Zap();
1294 1294
1295 private: 1295 private:
1296 static const int kNextOffset = POINTER_SIZE_ALIGN(FreeSpace::kHeaderSize); 1296 static const int kNextOffset = POINTER_SIZE_ALIGN(FreeSpace::kHeaderSize);
1297 1297
1298 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListNode); 1298 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListNode);
1299 }; 1299 };
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1344 // is unitialized. A failure is returned if no block is available. The 1344 // is unitialized. A failure is returned if no block is available. The
1345 // number of bytes lost to fragmentation is returned in the output parameter 1345 // number of bytes lost to fragmentation is returned in the output parameter
1346 // 'wasted_bytes'. The size should be a non-zero multiple of the word size. 1346 // 'wasted_bytes'. The size should be a non-zero multiple of the word size.
1347 MUST_USE_RESULT HeapObject* Allocate(int size_in_bytes); 1347 MUST_USE_RESULT HeapObject* Allocate(int size_in_bytes);
1348 1348
1349 void MarkNodes(); 1349 void MarkNodes();
1350 1350
1351 #ifdef DEBUG 1351 #ifdef DEBUG
1352 void Zap(); 1352 void Zap();
1353 static intptr_t SumFreeList(FreeListNode* node); 1353 static intptr_t SumFreeList(FreeListNode* node);
1354 static int FreeListLength(FreeListNode* cur);
1355 intptr_t SumFreeLists(); 1354 intptr_t SumFreeLists();
1356 bool IsVeryLong();
1357 #endif 1355 #endif
1358 1356
1357 static int FreeListLength(FreeListNode* cur);
1358 bool IsVeryLong();
1359 void CountFreeListItems(Page* p, intptr_t* sizes); 1359 void CountFreeListItems(Page* p, intptr_t* sizes);
1360 1360
1361 FreeListNode* get_chain(int i) {
Vyacheslav Egorov (Chromium) 2011/09/28 15:21:11 make enum!
1362 switch (i) {
1363 case 0: return small_list_;
1364 case 1: return medium_list_;
1365 case 2: return large_list_;
1366 case 3: return huge_list_;
1367 }
1368 UNREACHABLE();
1369 return NULL;
1370 }
1371 static const int kNumberOfChains = 4;
1372
1361 private: 1373 private:
1362 // The size range of blocks, in bytes. 1374 // The size range of blocks, in bytes.
1363 static const int kMinBlockSize = 3 * kPointerSize; 1375 static const int kMinBlockSize = 3 * kPointerSize;
1364 static const int kMaxBlockSize = Page::kMaxHeapObjectSize; 1376 static const int kMaxBlockSize = Page::kMaxHeapObjectSize;
1365 1377
1366 FreeListNode* PickNodeFromList(FreeListNode** list, int* node_size); 1378 FreeListNode* PickNodeFromList(FreeListNode** list, int* node_size);
1367 1379
1368 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); 1380 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size);
1369 1381
1370 PagedSpace* owner_; 1382 PagedSpace* owner_;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1479 // If add_to_freelist is false then just accounting stats are updated and 1491 // If add_to_freelist is false then just accounting stats are updated and
1480 // no attempt to add area to free list is made. 1492 // no attempt to add area to free list is made.
1481 int Free(Address start, int size_in_bytes) { 1493 int Free(Address start, int size_in_bytes) {
1482 int wasted = free_list_.Free(start, size_in_bytes); 1494 int wasted = free_list_.Free(start, size_in_bytes);
1483 accounting_stats_.DeallocateBytes(size_in_bytes - wasted); 1495 accounting_stats_.DeallocateBytes(size_in_bytes - wasted);
1484 return size_in_bytes - wasted; 1496 return size_in_bytes - wasted;
1485 } 1497 }
1486 1498
1487 int FreeOrUnmapPage(Page* page, Address start, int size_in_bytes); 1499 int FreeOrUnmapPage(Page* page, Address start, int size_in_bytes);
1488 1500
1501 void VisualizeTopChange(Address top);
1502
1489 // Set space allocation info. 1503 // Set space allocation info.
1490 void SetTop(Address top, Address limit) { 1504 inline void SetTop(Address top, Address limit);
1491 ASSERT(top == limit ||
1492 Page::FromAddress(top) == Page::FromAddress(limit - 1));
1493 allocation_info_.top = top;
1494 allocation_info_.limit = limit;
1495 }
1496 1505
1497 void Allocate(int bytes) { 1506 void Allocate(int bytes) {
1498 accounting_stats_.AllocateBytes(bytes); 1507 accounting_stats_.AllocateBytes(bytes);
1499 } 1508 }
1500 1509
1501 void IncreaseCapacity(int size) { 1510 void IncreaseCapacity(int size) {
1502 accounting_stats_.ExpandSpace(size); 1511 accounting_stats_.ExpandSpace(size);
1503 } 1512 }
1504 1513
1505 // Releases half of unused pages. 1514 // Releases half of unused pages.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1583 } 1592 }
1584 1593
1585 return (ratio > ratio_threshold) || 1594 return (ratio > ratio_threshold) ||
1586 (FLAG_always_compact && sizes[3] != Page::kObjectAreaSize); 1595 (FLAG_always_compact && sizes[3] != Page::kObjectAreaSize);
1587 } 1596 }
1588 1597
1589 void EvictEvacuationCandidatesFromFreeLists(); 1598 void EvictEvacuationCandidatesFromFreeLists();
1590 1599
1591 bool CanExpand(); 1600 bool CanExpand();
1592 1601
1602 FreeList* free_list() { return &free_list_; }
1603
1593 protected: 1604 protected:
1594 // Maximum capacity of this space. 1605 // Maximum capacity of this space.
1595 intptr_t max_capacity_; 1606 intptr_t max_capacity_;
1596 1607
1597 // Accounting information for this space. 1608 // Accounting information for this space.
1598 AllocationStats accounting_stats_; 1609 AllocationStats accounting_stats_;
1599 1610
1600 // The dummy page that anchors the double linked list of pages. 1611 // The dummy page that anchors the double linked list of pages.
1601 Page anchor_; 1612 Page anchor_;
1602 1613
1603 // The space's free list. 1614 // The space's free list.
1604 FreeList free_list_; 1615 FreeList free_list_;
1605 1616
1606 // Normal allocation information. 1617 // Normal allocation information.
1607 AllocationInfo allocation_info_; 1618 AllocationInfo allocation_info_;
1608 1619
1620 Address last_visualized_top_;
1621
1609 // Bytes of each page that cannot be allocated. Possibly non-zero 1622 // Bytes of each page that cannot be allocated. Possibly non-zero
1610 // for pages in spaces with only fixed-size objects. Always zero 1623 // for pages in spaces with only fixed-size objects. Always zero
1611 // for pages in spaces with variable sized objects (those pages are 1624 // for pages in spaces with variable sized objects (those pages are
1612 // padded with free-list nodes). 1625 // padded with free-list nodes).
1613 int page_extra_; 1626 int page_extra_;
1614 1627
1615 bool was_swept_conservatively_; 1628 bool was_swept_conservatively_;
1616 1629
1617 Page* first_unswept_page_; 1630 Page* first_unswept_page_;
1618 Page* last_unswept_page_; 1631 Page* last_unswept_page_;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1710 return reinterpret_cast<SemiSpace*>(owner()); 1723 return reinterpret_cast<SemiSpace*>(owner());
1711 } 1724 }
1712 1725
1713 bool is_anchor() { return !this->InNewSpace(); } 1726 bool is_anchor() { return !this->InNewSpace(); }
1714 1727
1715 static bool IsAtStart(Address addr) { 1728 static bool IsAtStart(Address addr) {
1716 return (reinterpret_cast<intptr_t>(addr) & Page::kPageAlignmentMask) 1729 return (reinterpret_cast<intptr_t>(addr) & Page::kPageAlignmentMask)
1717 == kObjectStartOffset; 1730 == kObjectStartOffset;
1718 } 1731 }
1719 1732
1733 Address ObjectAreaStart() {
1734 return address() + kObjectStartOffset;
1735 }
1736
1737 Address ObjectAreaEnd() {
1738 return address() + Page::kPageSize;
1739 }
1740
1720 static bool IsAtEnd(Address addr) { 1741 static bool IsAtEnd(Address addr) {
1721 return (reinterpret_cast<intptr_t>(addr) & Page::kPageAlignmentMask) == 0; 1742 return (reinterpret_cast<intptr_t>(addr) & Page::kPageAlignmentMask) == 0;
1722 } 1743 }
1723 1744
1724 Address address() { 1745 Address address() {
1725 return reinterpret_cast<Address>(this); 1746 return reinterpret_cast<Address>(this);
1726 } 1747 }
1727 1748
1728 // Finds the NewSpacePage containg the given address. 1749 // Finds the NewSpacePage containg the given address.
1729 static inline NewSpacePage* FromAddress(Address address_in_page) { 1750 static inline NewSpacePage* FromAddress(Address address_in_page) {
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
2018 // forwards most functions to the appropriate semispace. 2039 // forwards most functions to the appropriate semispace.
2019 2040
2020 class NewSpace : public Space { 2041 class NewSpace : public Space {
2021 public: 2042 public:
2022 // Constructor. 2043 // Constructor.
2023 explicit NewSpace(Heap* heap) 2044 explicit NewSpace(Heap* heap)
2024 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), 2045 : Space(heap, NEW_SPACE, NOT_EXECUTABLE),
2025 to_space_(heap, kToSpace), 2046 to_space_(heap, kToSpace),
2026 from_space_(heap, kFromSpace), 2047 from_space_(heap, kFromSpace),
2027 reservation_(), 2048 reservation_(),
2028 inline_allocation_limit_step_(0) {} 2049 inline_allocation_limit_step_(0),
2050 last_visualized_top_(NULL) {}
2029 2051
2030 // Sets up the new space using the given chunk. 2052 // Sets up the new space using the given chunk.
2031 bool Setup(int reserved_semispace_size_, int max_semispace_size); 2053 bool Setup(int reserved_semispace_size_, int max_semispace_size);
2032 2054
2033 // Tears down the space. Heap memory was not allocated by the space, so it 2055 // Tears down the space. Heap memory was not allocated by the space, so it
2034 // is not deallocated here. 2056 // is not deallocated here.
2035 void TearDown(); 2057 void TearDown();
2036 2058
2037 // True if the space has been set up but not torn down. 2059 // True if the space has been set up but not torn down.
2038 bool HasBeenSetup() { 2060 bool HasBeenSetup() {
2039 return to_space_.HasBeenSetup() && from_space_.HasBeenSetup(); 2061 return to_space_.HasBeenSetup() && from_space_.HasBeenSetup();
2040 } 2062 }
2041 2063
2042 // Flip the pair of spaces. 2064 // Flip the pair of spaces.
2043 void Flip(); 2065 void Flip();
2044 2066
2067 void VisualizeTop();
2068 void VisualizeUnallocation(SemiSpace* semispace);
2069
2045 // Grow the capacity of the semispaces. Assumes that they are not at 2070 // Grow the capacity of the semispaces. Assumes that they are not at
2046 // their maximum capacity. 2071 // their maximum capacity.
2047 void Grow(); 2072 void Grow();
2048 2073
2049 // Shrink the capacity of the semispaces. 2074 // Shrink the capacity of the semispaces.
2050 void Shrink(); 2075 void Shrink();
2051 2076
2052 // True if the address or object lies in the address range of either 2077 // True if the address or object lies in the address range of either
2053 // semispace (not necessarily below the allocation pointer). 2078 // semispace (not necessarily below the allocation pointer).
2054 bool Contains(Address a) { 2079 bool Contains(Address a) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2111 // Return the address of the allocation pointer in the active semispace. 2136 // Return the address of the allocation pointer in the active semispace.
2112 Address top() { 2137 Address top() {
2113 ASSERT(to_space_.current_page()->ContainsLimit(allocation_info_.top)); 2138 ASSERT(to_space_.current_page()->ContainsLimit(allocation_info_.top));
2114 return allocation_info_.top; 2139 return allocation_info_.top;
2115 } 2140 }
2116 // Return the address of the first object in the active semispace. 2141 // Return the address of the first object in the active semispace.
2117 Address bottom() { return to_space_.space_start(); } 2142 Address bottom() { return to_space_.space_start(); }
2118 2143
2119 // Get the age mark of the inactive semispace. 2144 // Get the age mark of the inactive semispace.
2120 Address age_mark() { return from_space_.age_mark(); } 2145 Address age_mark() { return from_space_.age_mark(); }
2146 // Get the age mark of the active semispace.
2147 Address to_space_age_mark() { return to_space_.age_mark(); }
2121 // Set the age mark in the active semispace. 2148 // Set the age mark in the active semispace.
2122 void set_age_mark(Address mark) { to_space_.set_age_mark(mark); } 2149 void set_age_mark(Address mark) { to_space_.set_age_mark(mark); }
2123 2150
2124 // The start address of the space and a bit mask. Anding an address in the 2151 // The start address of the space and a bit mask. Anding an address in the
2125 // new space with the mask will result in the start address. 2152 // new space with the mask will result in the start address.
2126 Address start() { return start_; } 2153 Address start() { return start_; }
2127 uintptr_t mask() { return address_mask_; } 2154 uintptr_t mask() { return address_mask_; }
2128 2155
2129 INLINE(uint32_t AddressToMarkbitIndex(Address addr)) { 2156 INLINE(uint32_t AddressToMarkbitIndex(Address addr)) {
2130 ASSERT(Contains(addr)); 2157 ASSERT(Contains(addr));
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
2262 // to be lower than actual limit and then will gradually increase it 2289 // to be lower than actual limit and then will gradually increase it
2263 // in steps to guarantee that we do incremental marking steps even 2290 // in steps to guarantee that we do incremental marking steps even
2264 // when all allocation is performed from inlined generated code. 2291 // when all allocation is performed from inlined generated code.
2265 intptr_t inline_allocation_limit_step_; 2292 intptr_t inline_allocation_limit_step_;
2266 2293
2267 Address top_on_previous_step_; 2294 Address top_on_previous_step_;
2268 2295
2269 HistogramInfo* allocated_histogram_; 2296 HistogramInfo* allocated_histogram_;
2270 HistogramInfo* promoted_histogram_; 2297 HistogramInfo* promoted_histogram_;
2271 2298
2299 Address last_visualized_top_;
2300
2272 // Implementation of AllocateRaw. 2301 // Implementation of AllocateRaw.
2273 MUST_USE_RESULT inline MaybeObject* AllocateRawInternal(int size_in_bytes); 2302 MUST_USE_RESULT inline MaybeObject* AllocateRawInternal(int size_in_bytes);
2274 2303
2275 friend class SemiSpaceIterator; 2304 friend class SemiSpaceIterator;
2276 2305
2277 public: 2306 public:
2278 TRACK_MEMORY("NewSpace") 2307 TRACK_MEMORY("NewSpace")
2279 }; 2308 };
2280 2309
2281 2310
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
2609 } 2638 }
2610 // Must be small, since an iteration is used for lookup. 2639 // Must be small, since an iteration is used for lookup.
2611 static const int kMaxComments = 64; 2640 static const int kMaxComments = 64;
2612 }; 2641 };
2613 #endif 2642 #endif
2614 2643
2615 2644
2616 } } // namespace v8::internal 2645 } } // namespace v8::internal
2617 2646
2618 #endif // V8_SPACES_H_ 2647 #endif // V8_SPACES_H_
OLDNEW
« no previous file with comments | « src/mark-compact.cc ('k') | src/spaces.cc » ('j') | src/spaces.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698