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 1003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1014 static void increaseAllocatedObjectSize(size_t delta) { atomicAdd(&s_allocat
edObjectSize, static_cast<long>(delta)); } | 1014 static void increaseAllocatedObjectSize(size_t delta) { atomicAdd(&s_allocat
edObjectSize, static_cast<long>(delta)); } |
1015 static void decreaseAllocatedObjectSize(size_t delta) { atomicSubtract(&s_al
locatedObjectSize, static_cast<long>(delta)); } | 1015 static void decreaseAllocatedObjectSize(size_t delta) { atomicSubtract(&s_al
locatedObjectSize, static_cast<long>(delta)); } |
1016 static size_t allocatedObjectSize() { return acquireLoad(&s_allocatedObjectS
ize); } | 1016 static size_t allocatedObjectSize() { return acquireLoad(&s_allocatedObjectS
ize); } |
1017 static void increaseMarkedObjectSize(size_t delta) { atomicAdd(&s_markedObje
ctSize, static_cast<long>(delta)); } | 1017 static void increaseMarkedObjectSize(size_t delta) { atomicAdd(&s_markedObje
ctSize, static_cast<long>(delta)); } |
1018 static size_t markedObjectSize() { return acquireLoad(&s_markedObjectSize);
} | 1018 static size_t markedObjectSize() { return acquireLoad(&s_markedObjectSize);
} |
1019 static void increaseAllocatedSpace(size_t delta) { atomicAdd(&s_allocatedSpa
ce, static_cast<long>(delta)); } | 1019 static void increaseAllocatedSpace(size_t delta) { atomicAdd(&s_allocatedSpa
ce, static_cast<long>(delta)); } |
1020 static void decreaseAllocatedSpace(size_t delta) { atomicSubtract(&s_allocat
edSpace, static_cast<long>(delta)); } | 1020 static void decreaseAllocatedSpace(size_t delta) { atomicSubtract(&s_allocat
edSpace, static_cast<long>(delta)); } |
1021 static size_t allocatedSpace() { return acquireLoad(&s_allocatedSpace); } | 1021 static size_t allocatedSpace() { return acquireLoad(&s_allocatedSpace); } |
1022 static size_t estimatedLiveObjectSize() { return acquireLoad(&s_estimatedLiv
eObjectSize); } | 1022 static size_t estimatedLiveObjectSize() { return acquireLoad(&s_estimatedLiv
eObjectSize); } |
1023 static void setEstimatedLiveObjectSize(size_t size) { releaseStore(&s_estima
tedLiveObjectSize, size); } | 1023 static void setEstimatedLiveObjectSize(size_t size) { releaseStore(&s_estima
tedLiveObjectSize, size); } |
| 1024 static size_t externalObjectSizeAtLastGC() { return acquireLoad(&s_externalO
bjectSizeAtLastGC); } |
1024 | 1025 |
1025 static double estimatedMarkingTime(); | 1026 static double estimatedMarkingTime(); |
1026 static void reportMemoryUsageHistogram(); | 1027 static void reportMemoryUsageHistogram(); |
1027 | 1028 |
1028 // On object allocation, register the object's externally allocated memory. | |
1029 static void increaseExternallyAllocatedBytes(size_t); | |
1030 static size_t externallyAllocatedBytes() { return acquireLoad(&s_externallyA
llocatedBytes); } | |
1031 | |
1032 // On object tracing, register the object's externally allocated memory (as
still live.) | |
1033 static void increaseExternallyAllocatedBytesAlive(size_t delta) | |
1034 { | |
1035 ASSERT(ThreadState::current()->isInGC()); | |
1036 s_externallyAllocatedBytesAlive += delta; | |
1037 } | |
1038 static size_t externallyAllocatedBytesAlive() { return s_externallyAllocated
BytesAlive; } | |
1039 | |
1040 static void requestUrgentGC(); | |
1041 static void clearUrgentGC() { releaseStore(&s_requestedUrgentGC, 0); } | |
1042 static bool isUrgentGCRequested() { return acquireLoad(&s_requestedUrgentGC)
; } | |
1043 | |
1044 private: | 1029 private: |
1045 // A RegionTree is a simple binary search tree of PageMemoryRegions sorted | 1030 // A RegionTree is a simple binary search tree of PageMemoryRegions sorted |
1046 // by base addresses. | 1031 // by base addresses. |
1047 class RegionTree { | 1032 class RegionTree { |
1048 public: | 1033 public: |
1049 explicit RegionTree(PageMemoryRegion* region) : m_region(region), m_left
(nullptr), m_right(nullptr) { } | 1034 explicit RegionTree(PageMemoryRegion* region) : m_region(region), m_left
(nullptr), m_right(nullptr) { } |
1050 ~RegionTree() | 1035 ~RegionTree() |
1051 { | 1036 { |
1052 delete m_left; | 1037 delete m_left; |
1053 delete m_right; | 1038 delete m_right; |
(...skipping 18 matching lines...) Expand all Loading... |
1072 static HeapDoesNotContainCache* s_heapDoesNotContainCache; | 1057 static HeapDoesNotContainCache* s_heapDoesNotContainCache; |
1073 static bool s_shutdownCalled; | 1058 static bool s_shutdownCalled; |
1074 static bool s_lastGCWasConservative; | 1059 static bool s_lastGCWasConservative; |
1075 static FreePagePool* s_freePagePool; | 1060 static FreePagePool* s_freePagePool; |
1076 static OrphanedPagePool* s_orphanedPagePool; | 1061 static OrphanedPagePool* s_orphanedPagePool; |
1077 static RegionTree* s_regionTree; | 1062 static RegionTree* s_regionTree; |
1078 static size_t s_allocatedSpace; | 1063 static size_t s_allocatedSpace; |
1079 static size_t s_allocatedObjectSize; | 1064 static size_t s_allocatedObjectSize; |
1080 static size_t s_markedObjectSize; | 1065 static size_t s_markedObjectSize; |
1081 static size_t s_estimatedLiveObjectSize; | 1066 static size_t s_estimatedLiveObjectSize; |
1082 static size_t s_externallyAllocatedBytes; | 1067 static size_t s_externalObjectSizeAtLastGC; |
1083 static size_t s_externallyAllocatedBytesAlive; | |
1084 static unsigned s_requestedUrgentGC; | |
1085 static double s_estimatedMarkingTimePerByte; | 1068 static double s_estimatedMarkingTimePerByte; |
1086 | 1069 |
1087 friend class ThreadState; | 1070 friend class ThreadState; |
1088 }; | 1071 }; |
1089 | 1072 |
1090 // We use sized heaps for normal pages to improve memory locality. | 1073 // We use sized heaps for normal pages to improve memory locality. |
1091 // It seems that the same type of objects are likely to be accessed together, | 1074 // It seems that the same type of objects are likely to be accessed together, |
1092 // which means that we want to group objects by type. That's why we provide | 1075 // which means that we want to group objects by type. That's why we provide |
1093 // dedicated heaps for popular types (e.g., Node, CSSValue), but it's not | 1076 // dedicated heaps for popular types (e.g., Node, CSSValue), but it's not |
1094 // practical to prepare dedicated heaps for all types. Thus we group objects | 1077 // practical to prepare dedicated heaps for all types. Thus we group objects |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1471 // TODO(haraken): We don't support reallocate() for finalizable objects. | 1454 // TODO(haraken): We don't support reallocate() for finalizable objects. |
1472 ASSERT(!Heap::gcInfo(previousHeader->gcInfoIndex())->hasFinalizer()); | 1455 ASSERT(!Heap::gcInfo(previousHeader->gcInfoIndex())->hasFinalizer()); |
1473 ASSERT(previousHeader->gcInfoIndex() == GCInfoTrait<T>::index()); | 1456 ASSERT(previousHeader->gcInfoIndex() == GCInfoTrait<T>::index()); |
1474 size_t copySize = previousHeader->payloadSize(); | 1457 size_t copySize = previousHeader->payloadSize(); |
1475 if (copySize > size) | 1458 if (copySize > size) |
1476 copySize = size; | 1459 copySize = size; |
1477 memcpy(address, previous, copySize); | 1460 memcpy(address, previous, copySize); |
1478 return address; | 1461 return address; |
1479 } | 1462 } |
1480 | 1463 |
1481 inline void Heap::increaseExternallyAllocatedBytes(size_t delta) | |
1482 { | |
1483 // Flag GC urgency on a 50% increase in external allocation | |
1484 // since the last GC, but not for less than 100M. | |
1485 // | |
1486 // FIXME: consider other, 'better' policies (e.g., have the count of | |
1487 // heap objects with external allocations be taken into | |
1488 // account, ...) The overall goal here is to trigger a | |
1489 // GC such that it considerably lessens memory pressure | |
1490 // for a renderer process, when absolutely needed. | |
1491 size_t externalBytesAllocatedSinceLastGC = atomicAdd(&s_externallyAllocatedB
ytes, static_cast<long>(delta)); | |
1492 if (LIKELY(externalBytesAllocatedSinceLastGC < 100 * 1024 * 1024)) | |
1493 return; | |
1494 | |
1495 if (UNLIKELY(isUrgentGCRequested())) | |
1496 return; | |
1497 | |
1498 size_t externalBytesAliveAtLastGC = externallyAllocatedBytesAlive(); | |
1499 if (UNLIKELY(externalBytesAllocatedSinceLastGC > externalBytesAliveAtLastGC
/ 2)) | |
1500 Heap::requestUrgentGC(); | |
1501 } | |
1502 | |
1503 template<bool needsTracing, WTF::WeakHandlingFlag weakHandlingFlag, WTF::ShouldW
eakPointersBeMarkedStrongly strongify, typename T, typename Traits> struct Colle
ctionBackingTraceTrait; | 1464 template<bool needsTracing, WTF::WeakHandlingFlag weakHandlingFlag, WTF::ShouldW
eakPointersBeMarkedStrongly strongify, typename T, typename Traits> struct Colle
ctionBackingTraceTrait; |
1504 template<typename T, typename Traits = WTF::VectorTraits<T>> class HeapVectorBac
king; | 1465 template<typename T, typename Traits = WTF::VectorTraits<T>> class HeapVectorBac
king; |
1505 template<typename Table> class HeapHashTableBacking { | 1466 template<typename Table> class HeapHashTableBacking { |
1506 public: | 1467 public: |
1507 static void finalize(void* pointer); | 1468 static void finalize(void* pointer); |
1508 void finalizeGarbageCollectedObject() { finalize(this); } | 1469 void finalizeGarbageCollectedObject() { finalize(this); } |
1509 }; | 1470 }; |
1510 | 1471 |
1511 class HeapAllocatorQuantizer { | 1472 class HeapAllocatorQuantizer { |
1512 public: | 1473 public: |
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2223 Value* table = reinterpret_cast<Value*>(pointer); | 2184 Value* table = reinterpret_cast<Value*>(pointer); |
2224 for (unsigned i = 0; i < length; ++i) { | 2185 for (unsigned i = 0; i < length; ++i) { |
2225 if (!Table::isEmptyOrDeletedBucket(table[i])) | 2186 if (!Table::isEmptyOrDeletedBucket(table[i])) |
2226 table[i].~Value(); | 2187 table[i].~Value(); |
2227 } | 2188 } |
2228 } | 2189 } |
2229 | 2190 |
2230 } // namespace blink | 2191 } // namespace blink |
2231 | 2192 |
2232 #endif // Heap_h | 2193 #endif // Heap_h |
OLD | NEW |