Changeset 97203 in webkit for trunk/Source/JavaScriptCore/heap
- Timestamp:
- Oct 11, 2011, 5:24:12 PM (14 years ago)
- Location:
- trunk/Source/JavaScriptCore/heap
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/heap/CardSet.h
r96372 r97203 48 48 uint8_t& cardForAtom(const void*); 49 49 bool isCardMarked(size_t); 50 void clearCard(size_t);50 bool testAndClear(size_t); 51 51 52 52 private: … … 79 79 } 80 80 81 template <size_t cardSize, size_t blockSize> void CardSet<cardSize, blockSize>::clearCard(size_t i)81 template <size_t cardSize, size_t blockSize> bool CardSet<cardSize, blockSize>::testAndClear(size_t i) 82 82 { 83 83 ASSERT(i < cardCount); 84 bool result = m_cards[i]; 84 85 m_cards[i] = 0; 86 return result; 85 87 } 86 88 -
trunk/Source/JavaScriptCore/heap/Heap.cpp
r96760 r97203 44 44 static const size_t largeHeapSize = 16 * 1024 * 1024; 45 45 static const size_t smallHeapSize = 512 * 1024; 46 46 #define ENABLE_GC_LOGGING 1 47 47 #if ENABLE(GC_LOGGING) 48 48 #if COMPILER(CLANG) 49 #define DEFINE_GC_LOGGING_GLOBAL(type, name, arguments) \ 50 _Pragma("clang diagnostic push") \ 51 _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") \ 52 _Pragma("clang diagnostic ignored \"-Wexit-time-destructors\"") \ 53 static type name arguments; \ 54 _Pragma("clang diagnostic pop") 55 #else 56 #define DEFINE_GC_LOGGING_GLOBAL(type, name, arguments) \ 57 static type name arguments; 58 #endif // COMPILER(CLANG) 59 49 60 struct GCTimer { 50 61 GCTimer(const char* name) … … 87 98 }; 88 99 89 #define GCPHASE(name) static GCTimer name##Timer(#name); GCTimerScope name##TimerScope(&name##Timer) 90 #define COND_GCPHASE(cond, name1, name2) static GCTimer name1##Timer(#name1); static GCTimer name2##Timer(#name2); GCTimerScope name1##CondTimerScope(cond ? &name1##Timer : &name2##Timer) 91 100 struct GCCounter { 101 GCCounter(const char* name) 102 : m_name(name) 103 , m_count(0) 104 , m_total(0) 105 , m_min(10000000) 106 , m_max(0) 107 { 108 } 109 110 void count(size_t amount) 111 { 112 m_count++; 113 m_total += amount; 114 if (amount < m_min) 115 m_min = amount; 116 if (amount > m_max) 117 m_max = amount; 118 } 119 ~GCCounter() 120 { 121 printf("%s: %zu values (avg. %zu, min. %zu, max. %zu)\n", m_name, m_total, m_total / m_count, m_min, m_max); 122 } 123 const char* m_name; 124 size_t m_count; 125 size_t m_total; 126 size_t m_min; 127 size_t m_max; 128 }; 129 130 #define GCPHASE(name) DEFINE_GC_LOGGING_GLOBAL(GCTimer, name##Timer, (#name)); GCTimerScope name##TimerScope(&name##Timer) 131 #define COND_GCPHASE(cond, name1, name2) DEFINE_GC_LOGGING_GLOBAL(GCTimer, name1##Timer, (#name1)); DEFINE_GC_LOGGING_GLOBAL(GCTimer, name2##Timer, (#name2)); GCTimerScope name1##CondTimerScope(cond ? &name1##Timer : &name2##Timer) 132 #define GCCOUNTER(name, value) do { DEFINE_GC_LOGGING_GLOBAL(GCCounter, name##Counter, (#name)); name##Counter.count(value); } while (false) 133 92 134 #else 93 135 94 136 #define GCPHASE(name) do { } while (false) 95 137 #define COND_GCPHASE(cond, name1, name2) do { } while (false) 96 138 #define GCCOUNTER(name, value) do { } while (false) 97 139 #endif 98 140 … … 549 591 550 592 #if ENABLE(GGC) 551 if (size_t dirtyCellCount = dirtyCells.size()) { 593 { 594 size_t dirtyCellCount = dirtyCells.size(); 552 595 GCPHASE(VisitDirtyCells); 596 GCCOUNTER(DirtyCellCount, dirtyCellCount); 553 597 for (size_t i = 0; i < dirtyCellCount; i++) { 554 598 heapRootVisitor.visitChildren(dirtyCells[i]); … … 622 666 } while (lastOpaqueRootCount != visitor.opaqueRootCount()); 623 667 } 668 GCCOUNTER(VisitedValueCount, visitor.visitCount()); 624 669 visitor.reset(); 625 670 -
trunk/Source/JavaScriptCore/heap/MarkStack.cpp
r96372 r97203 39 39 void MarkStack::reset() 40 40 { 41 m_visitCount = 0; 41 42 m_values.shrinkAllocation(pageSize()); 42 43 m_markSets.shrinkAllocation(pageSize()); -
trunk/Source/JavaScriptCore/heap/MarkStack.h
r95901 r97203 104 104 void reset(); 105 105 106 size_t visitCount() const { return m_visitCount; } 107 106 108 #if ENABLE(SIMPLE_HEAP_PROFILING) 107 109 VTableSpectrum m_visitedTypeCounts; … … 140 142 bool m_isDraining; 141 143 #endif 144 protected: 145 size_t m_visitCount; 142 146 }; 143 147 … … 149 153 , m_isDraining(false) 150 154 #endif 155 , m_visitCount(0) 151 156 { 152 157 } … … 265 270 if (!count) 266 271 return; 272 m_visitCount += count; 267 273 #if ENABLE(GC_VALIDATION) 268 274 validateSet(slot, count); -
trunk/Source/JavaScriptCore/heap/MarkedBlock.h
r96738 r97203 76 76 static const size_t atomsPerBlock = blockSize / atomSize; // ~0.4% overhead 77 77 static const size_t atomMask = atomsPerBlock - 1; 78 static const int cardShift = 10; // This is log2 of bytes per card.78 static const int cardShift = 8; // This is log2 of bytes per card. 79 79 static const size_t bytesPerCard = 1 << cardShift; 80 80 static const int cardCount = blockSize / bytesPerCard; … … 151 151 typedef Vector<JSCell*, 32> DirtyCellVector; 152 152 inline void gatherDirtyCells(DirtyCellVector&); 153 template <int size> inline void gatherDirtyCellsWithSize(DirtyCellVector&); 153 154 #endif 154 155 … … 317 318 318 319 #if ENABLE(GGC) 320 template <int _cellSize> void MarkedBlock::gatherDirtyCellsWithSize(DirtyCellVector& dirtyCells) 321 { 322 if (m_cards.testAndClear(0)) { 323 char* ptr = reinterpret_cast<char*>(&atoms()[firstAtom()]); 324 const char* end = reinterpret_cast<char*>(this) + bytesPerCard; 325 while (ptr < end) { 326 JSCell* cell = reinterpret_cast<JSCell*>(ptr); 327 if (isMarked(cell)) 328 dirtyCells.append(cell); 329 ptr += _cellSize; 330 } 331 } 332 333 const size_t cellOffset = firstAtom() * atomSize % _cellSize; 334 for (size_t i = 1; i < m_cards.cardCount; i++) { 335 if (!m_cards.testAndClear(i)) 336 continue; 337 char* ptr = reinterpret_cast<char*>(this) + i * bytesPerCard + cellOffset; 338 char* end = reinterpret_cast<char*>(this) + (i + 1) * bytesPerCard; 339 340 while (ptr < end) { 341 JSCell* cell = reinterpret_cast<JSCell*>(ptr); 342 if (isMarked(cell)) 343 dirtyCells.append(cell); 344 ptr += _cellSize; 345 } 346 } 347 } 348 319 349 void MarkedBlock::gatherDirtyCells(DirtyCellVector& dirtyCells) 320 350 { … … 331 361 332 362 size_t cellSize = this->cellSize(); 363 if (cellSize == 32) { 364 gatherDirtyCellsWithSize<32>(dirtyCells); 365 return; 366 } 367 if (cellSize == 64) { 368 gatherDirtyCellsWithSize<64>(dirtyCells); 369 return; 370 } 371 333 372 const size_t firstCellOffset = firstAtom() * atomSize % cellSize; 334 373 335 for (size_t i = 0; i < m_cards.cardCount; i++) { 336 if (!m_cards.isCardMarked(i)) 337 continue; 338 char* ptr = reinterpret_cast<char*>(this); 339 if (i) 340 ptr += firstCellOffset + cellSize * ((i * bytesPerCard + cellSize - 1 - firstCellOffset) / cellSize); 341 else 342 ptr += firstAtom() * atomSize; 343 char* end = reinterpret_cast<char*>(this) + std::min((i + 1) * bytesPerCard, m_endAtom * atomSize); 344 374 if (m_cards.testAndClear(0)) { 375 char* ptr = reinterpret_cast<char*>(this) + firstAtom() * atomSize; 376 char* end = reinterpret_cast<char*>(this) + bytesPerCard; 345 377 while (ptr < end) { 346 378 JSCell* cell = reinterpret_cast<JSCell*>(ptr); 347 ASSERT(*addressOfCardFor(cell));348 379 if (isMarked(cell)) 349 380 dirtyCells.append(cell); 350 381 ptr += cellSize; 351 382 } 352 m_cards.clearCard(i); 383 } 384 for (size_t i = 1; i < m_cards.cardCount; i++) { 385 if (!m_cards.testAndClear(i)) 386 continue; 387 char* ptr = reinterpret_cast<char*>(this) + firstCellOffset + cellSize * ((i * bytesPerCard + cellSize - 1 - firstCellOffset) / cellSize); 388 char* end = reinterpret_cast<char*>(this) + std::min((i + 1) * bytesPerCard, m_endAtom * atomSize); 389 390 while (ptr < end) { 391 JSCell* cell = reinterpret_cast<JSCell*>(ptr); 392 if (isMarked(cell)) 393 dirtyCells.append(cell); 394 ptr += cellSize; 395 } 353 396 } 354 397 }
Note:
See TracChangeset
for help on using the changeset viewer.