Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 252 | 252 |
| 253 ASSERT(!m_firstUnsweptPage); | 253 ASSERT(!m_firstUnsweptPage); |
| 254 // Add the BaseHeap's pages to the orphanedPagePool. | 254 // Add the BaseHeap's pages to the orphanedPagePool. |
| 255 for (BasePage* page = m_firstPage; page; page = page->next()) { | 255 for (BasePage* page = m_firstPage; page; page = page->next()) { |
| 256 Heap::decreaseAllocatedSpace(page->size()); | 256 Heap::decreaseAllocatedSpace(page->size()); |
| 257 Heap::orphanedPagePool()->addOrphanedPage(heapIndex(), page); | 257 Heap::orphanedPagePool()->addOrphanedPage(heapIndex(), page); |
| 258 } | 258 } |
| 259 m_firstPage = nullptr; | 259 m_firstPage = nullptr; |
| 260 } | 260 } |
| 261 | 261 |
| 262 void BaseHeap::takeSnapshot(const String& dumpBaseName) | 262 void BaseHeap::takeSnapshot(const String& dumpBaseName, ThreadState::GCSnapshotI nfo& info) |
| 263 { | 263 { |
| 264 size_t pageCount = 0; | 264 WebMemoryAllocatorDump* allocatorDump = BlinkGCMemoryDumpProvider::instance( )->createMemoryAllocatorDumpForCurrentGC(dumpBaseName); |
| 265 size_t pageIndex = 0; | |
| 265 for (BasePage* page = m_firstUnsweptPage; page; page = page->next()) { | 266 for (BasePage* page = m_firstUnsweptPage; page; page = page->next()) { |
| 266 pageCount++; | 267 page->takeSnapshot(dumpBaseName, pageIndex, info); |
| 268 pageIndex++; | |
| 267 } | 269 } |
| 268 WebMemoryAllocatorDump* allocatorDump = BlinkGCMemoryDumpProvider::instance( )->createMemoryAllocatorDumpForCurrentGC(dumpBaseName); | 270 allocatorDump->AddScalar("blink_page_count", "objects", pageIndex); |
| 269 allocatorDump->AddScalar("blink_page_count", "objects", pageCount); | |
| 270 } | 271 } |
| 271 | 272 |
| 272 #if ENABLE(ASSERT) || ENABLE(GC_PROFILING) | 273 #if ENABLE(ASSERT) || ENABLE(GC_PROFILING) |
| 273 BasePage* BaseHeap::findPageFromAddress(Address address) | 274 BasePage* BaseHeap::findPageFromAddress(Address address) |
| 274 { | 275 { |
| 275 for (BasePage* page = m_firstPage; page; page = page->next()) { | 276 for (BasePage* page = m_firstPage; page; page = page->next()) { |
| 276 if (page->contains(address)) | 277 if (page->contains(address)) |
| 277 return page; | 278 return page; |
| 278 } | 279 } |
| 279 for (BasePage* page = m_firstUnsweptPage; page; page = page->next()) { | 280 for (BasePage* page = m_firstUnsweptPage; page; page = page->next()) { |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 561 bool NormalPageHeap::pagesToBeSweptContains(Address address) | 562 bool NormalPageHeap::pagesToBeSweptContains(Address address) |
| 562 { | 563 { |
| 563 for (BasePage* page = m_firstUnsweptPage; page; page = page->next()) { | 564 for (BasePage* page = m_firstUnsweptPage; page; page = page->next()) { |
| 564 if (page->contains(address)) | 565 if (page->contains(address)) |
| 565 return true; | 566 return true; |
| 566 } | 567 } |
| 567 return false; | 568 return false; |
| 568 } | 569 } |
| 569 #endif | 570 #endif |
| 570 | 571 |
| 572 void NormalPageHeap::takeFreelistSnapshot(const String& dumpName) | |
| 573 { | |
| 574 m_freeList.takeSnapshot(dumpName); | |
| 575 } | |
| 576 | |
| 571 #if ENABLE(GC_PROFILING) | 577 #if ENABLE(GC_PROFILING) |
| 572 void NormalPageHeap::snapshotFreeList(TracedValue& json) | 578 void NormalPageHeap::snapshotFreeList(TracedValue& json) |
| 573 { | 579 { |
| 574 json.setInteger("cumulativeAllocationSize", m_cumulativeAllocationSize); | 580 json.setInteger("cumulativeAllocationSize", m_cumulativeAllocationSize); |
| 575 json.setDouble("inlineAllocationRate", static_cast<double>(m_inlineAllocatio nCount) / m_allocationCount); | 581 json.setDouble("inlineAllocationRate", static_cast<double>(m_inlineAllocatio nCount) / m_allocationCount); |
| 576 json.setInteger("inlineAllocationCount", m_inlineAllocationCount); | 582 json.setInteger("inlineAllocationCount", m_inlineAllocationCount); |
| 577 json.setInteger("allocationCount", m_allocationCount); | 583 json.setInteger("allocationCount", m_allocationCount); |
| 578 size_t pageCount = 0; | 584 size_t pageCount = 0; |
| 579 size_t totalPageSize = 0; | 585 size_t totalPageSize = 0; |
| 580 for (NormalPage* page = static_cast<NormalPage*>(m_firstPage); page; page = static_cast<NormalPage*>(page->next())) { | 586 for (NormalPage* page = static_cast<NormalPage*>(m_firstPage); page; page = static_cast<NormalPage*>(page->next())) { |
| (...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1119 { | 1125 { |
| 1120 ASSERT(size > 0); | 1126 ASSERT(size > 0); |
| 1121 int index = -1; | 1127 int index = -1; |
| 1122 while (size) { | 1128 while (size) { |
| 1123 size >>= 1; | 1129 size >>= 1; |
| 1124 index++; | 1130 index++; |
| 1125 } | 1131 } |
| 1126 return index; | 1132 return index; |
| 1127 } | 1133 } |
| 1128 | 1134 |
| 1135 void FreeList::takeSnapshot(const String& dumpBaseName) | |
| 1136 { | |
| 1137 for (size_t i = 0; i < blinkPageSizeLog2; ++i) { | |
| 1138 size_t entryCount = 0; | |
| 1139 size_t freeSize = 0; | |
| 1140 for (FreeListEntry* entry = m_freeLists[i]; entry; entry = entry->next() ) { | |
| 1141 ++entryCount; | |
| 1142 freeSize += entry->size(); | |
| 1143 } | |
| 1144 | |
| 1145 String dumpName = dumpBaseName + String::format("/buckets/bucket_%lu", s tatic_cast<unsigned long>(1 << i)); | |
| 1146 WebMemoryAllocatorDump* bucketDump = BlinkGCMemoryDumpProvider::instance ()->createMemoryAllocatorDumpForCurrentGC(dumpName); | |
| 1147 bucketDump->AddScalar("freelist_entry_count", "objects", entryCount); | |
| 1148 bucketDump->AddScalar("free_size", "bytes", freeSize); | |
| 1149 } | |
| 1150 } | |
| 1151 | |
| 1129 #if ENABLE(GC_PROFILING) | 1152 #if ENABLE(GC_PROFILING) |
| 1130 void FreeList::getFreeSizeStats(PerBucketFreeListStats bucketStats[], size_t& to talFreeSize) const | 1153 void FreeList::getFreeSizeStats(PerBucketFreeListStats bucketStats[], size_t& to talFreeSize) const |
| 1131 { | 1154 { |
| 1132 totalFreeSize = 0; | 1155 totalFreeSize = 0; |
| 1133 for (size_t i = 0; i < blinkPageSizeLog2; i++) { | 1156 for (size_t i = 0; i < blinkPageSizeLog2; i++) { |
| 1134 size_t& entryCount = bucketStats[i].entryCount; | 1157 size_t& entryCount = bucketStats[i].entryCount; |
| 1135 size_t& freeSize = bucketStats[i].freeSize; | 1158 size_t& freeSize = bucketStats[i].freeSize; |
| 1136 for (FreeListEntry* entry = m_freeLists[i]; entry; entry = entry->next() ) { | 1159 for (FreeListEntry* entry = m_freeLists[i]; entry; entry = entry->next() ) { |
| 1137 ++entryCount; | 1160 ++entryCount; |
| 1138 freeSize += entry->size(); | 1161 freeSize += entry->size(); |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1450 // cross thread pointer usage. | 1473 // cross thread pointer usage. |
| 1451 #if defined(ADDRESS_SANITIZER) | 1474 #if defined(ADDRESS_SANITIZER) |
| 1452 // This needs to zap poisoned memory as well. | 1475 // This needs to zap poisoned memory as well. |
| 1453 // Force unpoison memory before memset. | 1476 // Force unpoison memory before memset. |
| 1454 ASAN_UNPOISON_MEMORY_REGION(payload(), payloadSize()); | 1477 ASAN_UNPOISON_MEMORY_REGION(payload(), payloadSize()); |
| 1455 #endif | 1478 #endif |
| 1456 memset(payload(), orphanedZapValue, payloadSize()); | 1479 memset(payload(), orphanedZapValue, payloadSize()); |
| 1457 BasePage::markOrphaned(); | 1480 BasePage::markOrphaned(); |
| 1458 } | 1481 } |
| 1459 | 1482 |
| 1483 void NormalPage::takeSnapshot(String dumpName, size_t pageIndex, ThreadState::GC SnapshotInfo& info) | |
| 1484 { | |
| 1485 dumpName.append(String::format("/pages/page_%lu", static_cast<unsigned long> (pageIndex))); | |
| 1486 WebMemoryAllocatorDump* pageDump = BlinkGCMemoryDumpProvider::instance()->cr eateMemoryAllocatorDumpForCurrentGC(dumpName); | |
| 1487 | |
| 1488 HeapObjectHeader* header = nullptr; | |
| 1489 size_t liveCount = 0; | |
| 1490 size_t deadCount = 0; | |
| 1491 size_t freeCount = 0; | |
| 1492 size_t liveSize = 0; | |
| 1493 size_t deadSize = 0; | |
| 1494 size_t freeSize = 0; | |
| 1495 for (Address headerAddress = payload(); headerAddress < payloadEnd(); header Address += header->size()) { | |
| 1496 header = reinterpret_cast<HeapObjectHeader*>(headerAddress); | |
| 1497 size_t tag = info.getClassTag(Heap::gcInfo(header->gcInfoIndex())); | |
|
haraken
2015/06/23 12:59:47
header->gcInfoIndex() is available only when the h
ssid
2015/06/23 19:40:02
Ah, I see. Thanks :)
| |
| 1498 | |
| 1499 if (header->isFree()) { | |
| 1500 freeCount++; | |
| 1501 freeSize += header->size(); | |
| 1502 } else if (header->isMarked()) { | |
| 1503 liveCount++; | |
| 1504 liveSize += header->size(); | |
| 1505 info.liveCount[tag]++; | |
| 1506 info.liveSize[tag] += header->size(); | |
| 1507 } else { | |
| 1508 deadCount++; | |
| 1509 deadSize += header->size(); | |
| 1510 info.deadCount[tag]++; | |
| 1511 info.deadSize[tag] += header->size(); | |
| 1512 } | |
| 1513 } | |
| 1514 | |
| 1515 pageDump->AddScalar("live_count", "objects", liveCount); | |
| 1516 pageDump->AddScalar("dead_count", "objects", deadCount); | |
| 1517 pageDump->AddScalar("free_count", "objects", freeCount); | |
| 1518 pageDump->AddScalar("live_size", "bytes", liveSize); | |
| 1519 pageDump->AddScalar("dead_size", "bytes", deadSize); | |
| 1520 pageDump->AddScalar("free_size", "bytes", freeSize); | |
| 1521 | |
| 1522 } | |
| 1523 | |
| 1460 #if ENABLE(GC_PROFILING) | 1524 #if ENABLE(GC_PROFILING) |
| 1461 const GCInfo* NormalPage::findGCInfo(Address address) | 1525 const GCInfo* NormalPage::findGCInfo(Address address) |
| 1462 { | 1526 { |
| 1463 if (address < payload()) | 1527 if (address < payload()) |
| 1464 return nullptr; | 1528 return nullptr; |
| 1465 | 1529 |
| 1466 HeapObjectHeader* header = findHeaderFromAddress(address); | 1530 HeapObjectHeader* header = findHeaderFromAddress(address); |
| 1467 if (!header) | 1531 if (!header) |
| 1468 return nullptr; | 1532 return nullptr; |
| 1469 | 1533 |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1625 } | 1689 } |
| 1626 | 1690 |
| 1627 void LargeObjectPage::markOrphaned() | 1691 void LargeObjectPage::markOrphaned() |
| 1628 { | 1692 { |
| 1629 // Zap the payload with a recognizable value to detect any incorrect | 1693 // Zap the payload with a recognizable value to detect any incorrect |
| 1630 // cross thread pointer usage. | 1694 // cross thread pointer usage. |
| 1631 memset(payload(), orphanedZapValue, payloadSize()); | 1695 memset(payload(), orphanedZapValue, payloadSize()); |
| 1632 BasePage::markOrphaned(); | 1696 BasePage::markOrphaned(); |
| 1633 } | 1697 } |
| 1634 | 1698 |
| 1699 void LargeObjectPage::takeSnapshot(String dumpName, size_t pageIndex, ThreadStat e::GCSnapshotInfo& info) | |
| 1700 { | |
| 1701 dumpName.append(String::format("/pages/page_%lu", static_cast<unsigned long> (pageIndex))); | |
| 1702 WebMemoryAllocatorDump* pageDump = BlinkGCMemoryDumpProvider::instance()->cr eateMemoryAllocatorDumpForCurrentGC(dumpName); | |
| 1703 | |
| 1704 size_t liveSize = 0; | |
| 1705 size_t deadSize = 0; | |
| 1706 size_t liveCount = 0; | |
| 1707 size_t deadCount = 0; | |
| 1708 HeapObjectHeader* header = heapObjectHeader(); | |
| 1709 size_t tag = info.getClassTag(Heap::gcInfo(header->gcInfoIndex())); | |
| 1710 if (header->isMarked()) { | |
| 1711 liveCount = 1; | |
| 1712 liveSize += header->size(); | |
| 1713 info.liveCount[tag]++; | |
| 1714 info.liveSize[tag] += header->size(); | |
| 1715 } else { | |
| 1716 deadCount = 1; | |
| 1717 deadSize += header->size(); | |
| 1718 info.deadCount[tag]++; | |
| 1719 info.deadSize[tag] += header->size(); | |
| 1720 } | |
| 1721 | |
| 1722 pageDump->AddScalar("live_count", "objects", liveCount); | |
| 1723 pageDump->AddScalar("dead_count", "objects", deadCount); | |
| 1724 pageDump->AddScalar("live_size", "bytes", liveSize); | |
| 1725 pageDump->AddScalar("dead_size", "bytes", deadSize); | |
| 1726 } | |
| 1727 | |
| 1635 #if ENABLE(GC_PROFILING) | 1728 #if ENABLE(GC_PROFILING) |
| 1636 const GCInfo* LargeObjectPage::findGCInfo(Address address) | 1729 const GCInfo* LargeObjectPage::findGCInfo(Address address) |
| 1637 { | 1730 { |
| 1638 if (!containedInObjectPayload(address)) | 1731 if (!containedInObjectPayload(address)) |
| 1639 return nullptr; | 1732 return nullptr; |
| 1640 HeapObjectHeader* header = heapObjectHeader(); | 1733 HeapObjectHeader* header = heapObjectHeader(); |
| 1641 return Heap::gcInfo(header->gcInfoIndex()); | 1734 return Heap::gcInfo(header->gcInfoIndex()); |
| 1642 } | 1735 } |
| 1643 | 1736 |
| 1644 void LargeObjectPage::snapshot(TracedValue* json, ThreadState::SnapshotInfo* inf o) | 1737 void LargeObjectPage::snapshot(TracedValue* json, ThreadState::SnapshotInfo* inf o) |
| (...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2355 size_t Heap::s_allocatedObjectSize = 0; | 2448 size_t Heap::s_allocatedObjectSize = 0; |
| 2356 size_t Heap::s_allocatedSpace = 0; | 2449 size_t Heap::s_allocatedSpace = 0; |
| 2357 size_t Heap::s_markedObjectSize = 0; | 2450 size_t Heap::s_markedObjectSize = 0; |
| 2358 // We don't want to use 0 KB for the initial value because it may end up | 2451 // We don't want to use 0 KB for the initial value because it may end up |
| 2359 // triggering the first GC of some thread too prematurely. | 2452 // triggering the first GC of some thread too prematurely. |
| 2360 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; | 2453 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; |
| 2361 size_t Heap::s_externalObjectSizeAtLastGC = 0; | 2454 size_t Heap::s_externalObjectSizeAtLastGC = 0; |
| 2362 double Heap::s_estimatedMarkingTimePerByte = 0.0; | 2455 double Heap::s_estimatedMarkingTimePerByte = 0.0; |
| 2363 | 2456 |
| 2364 } // namespace blink | 2457 } // namespace blink |
| OLD | NEW |