| 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 |