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 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 : m_currentAllocationPoint(nullptr) | 541 : m_currentAllocationPoint(nullptr) |
542 , m_remainingAllocationSize(0) | 542 , m_remainingAllocationSize(0) |
543 , m_lastRemainingAllocationSize(0) | 543 , m_lastRemainingAllocationSize(0) |
544 , m_firstPage(nullptr) | 544 , m_firstPage(nullptr) |
545 , m_firstLargeObject(nullptr) | 545 , m_firstLargeObject(nullptr) |
546 , m_firstUnsweptPage(nullptr) | 546 , m_firstUnsweptPage(nullptr) |
547 , m_firstUnsweptLargeObject(nullptr) | 547 , m_firstUnsweptLargeObject(nullptr) |
548 , m_threadState(state) | 548 , m_threadState(state) |
549 , m_index(index) | 549 , m_index(index) |
550 , m_promptlyFreedSize(0) | 550 , m_promptlyFreedSize(0) |
| 551 #if ENABLE(GC_PROFILING) |
| 552 , m_cumulativeAllocationSize(0) |
| 553 , m_allocationCount(0) |
| 554 , m_inlineAllocationCount(0) |
| 555 #endif |
551 { | 556 { |
552 clearFreeLists(); | 557 clearFreeLists(); |
553 } | 558 } |
554 | 559 |
555 FreeList::FreeList() | 560 FreeList::FreeList() |
556 : m_biggestFreeListIndex(0) | 561 : m_biggestFreeListIndex(0) |
557 { | 562 { |
558 } | 563 } |
559 | 564 |
560 ThreadHeap::~ThreadHeap() | 565 ThreadHeap::~ThreadHeap() |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 updateRemainingAllocationSize(); | 614 updateRemainingAllocationSize(); |
610 m_currentAllocationPoint = point; | 615 m_currentAllocationPoint = point; |
611 m_lastRemainingAllocationSize = m_remainingAllocationSize = size; | 616 m_lastRemainingAllocationSize = m_remainingAllocationSize = size; |
612 } | 617 } |
613 | 618 |
614 Address ThreadHeap::outOfLineAllocate(size_t allocationSize, size_t gcInfoIndex) | 619 Address ThreadHeap::outOfLineAllocate(size_t allocationSize, size_t gcInfoIndex) |
615 { | 620 { |
616 ASSERT(allocationSize > remainingAllocationSize()); | 621 ASSERT(allocationSize > remainingAllocationSize()); |
617 ASSERT(allocationSize >= allocationGranularity); | 622 ASSERT(allocationSize >= allocationGranularity); |
618 | 623 |
| 624 #if ENABLE(GC_PROFILING) |
| 625 m_threadState->snapshotFreeListIfNecessary(); |
| 626 #endif |
| 627 |
619 // 1. If this allocation is big enough, allocate a large object. | 628 // 1. If this allocation is big enough, allocate a large object. |
620 if (allocationSize >= largeObjectSizeThreshold) | 629 if (allocationSize >= largeObjectSizeThreshold) |
621 return allocateLargeObject(allocationSize, gcInfoIndex); | 630 return allocateLargeObject(allocationSize, gcInfoIndex); |
622 | 631 |
623 // 2. Check if we should trigger a GC. | 632 // 2. Check if we should trigger a GC. |
624 updateRemainingAllocationSize(); | 633 updateRemainingAllocationSize(); |
625 threadState()->scheduleGCOrForceConservativeGCIfNeeded(); | 634 threadState()->scheduleGCOrForceConservativeGCIfNeeded(); |
626 | 635 |
627 // 3. Try to allocate from a free list. | 636 // 3. Try to allocate from a free list. |
628 Address result = allocateFromFreeList(allocationSize, gcInfoIndex); | 637 Address result = allocateFromFreeList(allocationSize, gcInfoIndex); |
(...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1486 m_firstUnsweptLargeObject = nullptr; | 1495 m_firstUnsweptLargeObject = nullptr; |
1487 } | 1496 } |
1488 ASSERT(!m_firstUnsweptLargeObject); | 1497 ASSERT(!m_firstUnsweptLargeObject); |
1489 } | 1498 } |
1490 | 1499 |
1491 void ThreadHeap::clearFreeLists() | 1500 void ThreadHeap::clearFreeLists() |
1492 { | 1501 { |
1493 m_freeList.clear(); | 1502 m_freeList.clear(); |
1494 } | 1503 } |
1495 | 1504 |
| 1505 #if ENABLE(GC_PROFILING) |
| 1506 void ThreadHeap::snapshotFreeList(TracedValue& json) |
| 1507 { |
| 1508 json.setInteger("cumulativeAllocationSize", m_cumulativeAllocationSize); |
| 1509 json.setDouble("inlineAllocationRate", static_cast<double>(m_inlineAllocatio
nCount) / m_allocationCount); |
| 1510 json.setInteger("inlineAllocationCount", m_inlineAllocationCount); |
| 1511 json.setInteger("allocationCount", m_allocationCount); |
| 1512 size_t pageCount = 0; |
| 1513 size_t totalPageSize = 0; |
| 1514 for (HeapPage* page = m_firstPage; page; page = page->next()) { |
| 1515 ++pageCount; |
| 1516 totalPageSize += page->payloadSize(); |
| 1517 } |
| 1518 json.setInteger("pageCount", pageCount); |
| 1519 json.setInteger("totalPageSize", totalPageSize); |
| 1520 |
| 1521 FreeList::PerBucketFreeListStats bucketStats[blinkPageSizeLog2]; |
| 1522 size_t totalFreeSize; |
| 1523 m_freeList.getFreeSizeStats(bucketStats, totalFreeSize); |
| 1524 json.setInteger("totalFreeSize", totalFreeSize); |
| 1525 |
| 1526 json.beginArray("perBucketEntryCount"); |
| 1527 for (size_t i = 0; i < blinkPageSizeLog2; ++i) |
| 1528 json.pushInteger(bucketStats[i].entryCount); |
| 1529 json.endArray(); |
| 1530 |
| 1531 json.beginArray("perBucketFreeSize"); |
| 1532 for (size_t i = 0; i < blinkPageSizeLog2; ++i) |
| 1533 json.pushInteger(bucketStats[i].freeSize); |
| 1534 json.endArray(); |
| 1535 } |
| 1536 #endif |
| 1537 |
1496 void FreeList::clear() | 1538 void FreeList::clear() |
1497 { | 1539 { |
1498 m_biggestFreeListIndex = 0; | 1540 m_biggestFreeListIndex = 0; |
1499 for (size_t i = 0; i < blinkPageSizeLog2; ++i) | 1541 for (size_t i = 0; i < blinkPageSizeLog2; ++i) |
1500 m_freeLists[i] = nullptr; | 1542 m_freeLists[i] = nullptr; |
1501 } | 1543 } |
1502 | 1544 |
1503 int FreeList::bucketIndexForSize(size_t size) | 1545 int FreeList::bucketIndexForSize(size_t size) |
1504 { | 1546 { |
1505 ASSERT(size > 0); | 1547 ASSERT(size > 0); |
1506 int index = -1; | 1548 int index = -1; |
1507 while (size) { | 1549 while (size) { |
1508 size >>= 1; | 1550 size >>= 1; |
1509 index++; | 1551 index++; |
1510 } | 1552 } |
1511 return index; | 1553 return index; |
1512 } | 1554 } |
1513 | 1555 |
| 1556 #if ENABLE(GC_PROFILING) |
| 1557 void FreeList::getFreeSizeStats(PerBucketFreeListStats bucketStats[], size_t& to
talFreeSize) const |
| 1558 { |
| 1559 totalFreeSize = 0; |
| 1560 for (size_t i = 0; i < blinkPageSizeLog2; i++) { |
| 1561 size_t& entryCount = bucketStats[i].entryCount; |
| 1562 size_t& freeSize = bucketStats[i].freeSize; |
| 1563 for (FreeListEntry* entry = m_freeLists[i]; entry; entry = entry->next()
) { |
| 1564 ++entryCount; |
| 1565 freeSize += entry->size(); |
| 1566 } |
| 1567 totalFreeSize += freeSize; |
| 1568 } |
| 1569 } |
| 1570 #endif |
| 1571 |
1514 HeapPage::HeapPage(PageMemory* storage, ThreadHeap* heap) | 1572 HeapPage::HeapPage(PageMemory* storage, ThreadHeap* heap) |
1515 : BaseHeapPage(storage, heap) | 1573 : BaseHeapPage(storage, heap) |
1516 , m_next(nullptr) | 1574 , m_next(nullptr) |
1517 { | 1575 { |
1518 m_objectStartBitMapComputed = false; | 1576 m_objectStartBitMapComputed = false; |
1519 ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this))); | 1577 ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this))); |
1520 } | 1578 } |
1521 | 1579 |
1522 size_t HeapPage::objectPayloadSizeForTesting() | 1580 size_t HeapPage::objectPayloadSizeForTesting() |
1523 { | 1581 { |
(...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2714 bool Heap::s_shutdownCalled = false; | 2772 bool Heap::s_shutdownCalled = false; |
2715 bool Heap::s_lastGCWasConservative = false; | 2773 bool Heap::s_lastGCWasConservative = false; |
2716 FreePagePool* Heap::s_freePagePool; | 2774 FreePagePool* Heap::s_freePagePool; |
2717 OrphanedPagePool* Heap::s_orphanedPagePool; | 2775 OrphanedPagePool* Heap::s_orphanedPagePool; |
2718 Heap::RegionTree* Heap::s_regionTree = nullptr; | 2776 Heap::RegionTree* Heap::s_regionTree = nullptr; |
2719 size_t Heap::s_allocatedObjectSize = 0; | 2777 size_t Heap::s_allocatedObjectSize = 0; |
2720 size_t Heap::s_allocatedSpace = 0; | 2778 size_t Heap::s_allocatedSpace = 0; |
2721 size_t Heap::s_markedObjectSize = 0; | 2779 size_t Heap::s_markedObjectSize = 0; |
2722 | 2780 |
2723 } // namespace blink | 2781 } // namespace blink |
OLD | NEW |