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 21 matching lines...) Expand all Loading... |
32 #include "platform/heap/Heap.h" | 32 #include "platform/heap/Heap.h" |
33 | 33 |
34 #include "platform/ScriptForbiddenScope.h" | 34 #include "platform/ScriptForbiddenScope.h" |
35 #include "platform/TraceEvent.h" | 35 #include "platform/TraceEvent.h" |
36 #include "platform/heap/ThreadState.h" | 36 #include "platform/heap/ThreadState.h" |
37 #include "public/platform/Platform.h" | 37 #include "public/platform/Platform.h" |
38 #include "wtf/AddressSpaceRandomization.h" | 38 #include "wtf/AddressSpaceRandomization.h" |
39 #include "wtf/Assertions.h" | 39 #include "wtf/Assertions.h" |
40 #include "wtf/LeakAnnotations.h" | 40 #include "wtf/LeakAnnotations.h" |
41 #include "wtf/PassOwnPtr.h" | 41 #include "wtf/PassOwnPtr.h" |
42 #if ENABLE(GC_TRACING) | 42 #if GC_PROFILE_MARKING |
43 #include "wtf/HashMap.h" | 43 #include "wtf/HashMap.h" |
44 #include "wtf/HashSet.h" | 44 #include "wtf/HashSet.h" |
45 #include "wtf/text/StringBuilder.h" | 45 #include "wtf/text/StringBuilder.h" |
46 #include "wtf/text/StringHash.h" | 46 #include "wtf/text/StringHash.h" |
47 #include <stdio.h> | 47 #include <stdio.h> |
48 #include <utility> | 48 #include <utility> |
49 #endif | 49 #endif |
| 50 #if GC_PROFILE_HEAP |
| 51 #include "platform/TracedValue.h" |
| 52 #endif |
50 | 53 |
51 #if OS(POSIX) | 54 #if OS(POSIX) |
52 #include <sys/mman.h> | 55 #include <sys/mman.h> |
53 #include <unistd.h> | 56 #include <unistd.h> |
54 #elif OS(WIN) | 57 #elif OS(WIN) |
55 #include <windows.h> | 58 #include <windows.h> |
56 #endif | 59 #endif |
57 | 60 |
58 namespace WebCore { | 61 namespace WebCore { |
59 | 62 |
60 #if ENABLE(GC_TRACING) | 63 #if GC_PROFILE_MARKING |
61 static String classOf(const void* object) | 64 static String classOf(const void* object) |
62 { | 65 { |
63 const GCInfo* gcInfo = Heap::findGCInfo(reinterpret_cast<Address>(const_cast
<void*>(object))); | 66 const GCInfo* gcInfo = Heap::findGCInfo(reinterpret_cast<Address>(const_cast
<void*>(object))); |
64 if (gcInfo) | 67 if (gcInfo) |
65 return gcInfo->m_className; | 68 return gcInfo->m_className; |
66 | 69 |
67 return "unknown"; | 70 return "unknown"; |
68 } | 71 } |
69 #endif | 72 #endif |
70 | 73 |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 { | 501 { |
499 return heapObjectHeader()->isMarked(); | 502 return heapObjectHeader()->isMarked(); |
500 } | 503 } |
501 | 504 |
502 template<typename Header> | 505 template<typename Header> |
503 void LargeHeapObject<Header>::checkAndMarkPointer(Visitor* visitor, Address addr
ess) | 506 void LargeHeapObject<Header>::checkAndMarkPointer(Visitor* visitor, Address addr
ess) |
504 { | 507 { |
505 ASSERT(contains(address)); | 508 ASSERT(contains(address)); |
506 if (!objectContains(address)) | 509 if (!objectContains(address)) |
507 return; | 510 return; |
508 #if ENABLE(GC_TRACING) | 511 #if GC_PROFILE_MARKING |
509 visitor->setHostInfo(&address, "stack"); | 512 visitor->setHostInfo(&address, "stack"); |
510 #endif | 513 #endif |
511 mark(visitor); | 514 mark(visitor); |
512 } | 515 } |
513 | 516 |
514 template<> | 517 template<> |
515 void LargeHeapObject<FinalizedHeapObjectHeader>::mark(Visitor* visitor) | 518 void LargeHeapObject<FinalizedHeapObjectHeader>::mark(Visitor* visitor) |
516 { | 519 { |
517 if (heapObjectHeader()->hasVTable() && !vTableInitialized(payload())) | 520 if (heapObjectHeader()->hasVTable() && !vTableInitialized(payload())) |
518 visitor->markConservatively(heapObjectHeader()); | 521 visitor->markConservatively(heapObjectHeader()); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
634 for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current; cur
rent = current->next()) { | 637 for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current; cur
rent = current->next()) { |
635 // Check that large pages are blinkPageSize aligned (modulo the | 638 // Check that large pages are blinkPageSize aligned (modulo the |
636 // osPageSize for the guard page). | 639 // osPageSize for the guard page). |
637 ASSERT(reinterpret_cast<Address>(current) - osPageSize() == roundToBlink
PageStart(reinterpret_cast<Address>(current))); | 640 ASSERT(reinterpret_cast<Address>(current) - osPageSize() == roundToBlink
PageStart(reinterpret_cast<Address>(current))); |
638 if (current->contains(address)) | 641 if (current->contains(address)) |
639 return current; | 642 return current; |
640 } | 643 } |
641 return 0; | 644 return 0; |
642 } | 645 } |
643 | 646 |
644 #if ENABLE(GC_TRACING) | 647 #if GC_PROFILE_MARKING |
645 template<typename Header> | 648 template<typename Header> |
646 const GCInfo* ThreadHeap<Header>::findGCInfoOfLargeHeapObject(Address address) | 649 const GCInfo* ThreadHeap<Header>::findGCInfoOfLargeHeapObject(Address address) |
647 { | 650 { |
648 for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current; cur
rent = current->next()) { | 651 for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current; cur
rent = current->next()) { |
649 if (current->contains(address)) | 652 if (current->contains(address)) |
650 return current->gcInfo(); | 653 return current->gcInfo(); |
651 } | 654 } |
652 return 0; | 655 return 0; |
653 } | 656 } |
654 #endif | 657 #endif |
655 | 658 |
| 659 #if GC_PROFILE_HEAP |
| 660 template<typename Header> |
| 661 void ThreadHeap<Header>::snapshot(TracedDictionaryBase* json, ThreadState::Snaps
hotInfo* info) |
| 662 { |
| 663 size_t previousPageCount = info->pageCount; |
| 664 |
| 665 TracedArrayBase& pages = json->beginArray("pages"); |
| 666 for (HeapPage<Header>* page = m_firstPage; page; page = page->next(), ++info
->pageCount) { |
| 667 // FIXME: To limit the size of the snapshot we only output "threshold" m
any page snapshots. |
| 668 TracedArrayBase* jsonPage = 0; |
| 669 if (info->pageCount < GC_PROFILE_HEAP_PAGE_DUMP_THRESHOLD) { |
| 670 jsonPage = &pages.beginArray(); |
| 671 jsonPage->pushInteger(reinterpret_cast<intptr_t>(page)); |
| 672 } |
| 673 page->snapshot(jsonPage, info); |
| 674 if (jsonPage) |
| 675 jsonPage->endArray(); |
| 676 } |
| 677 pages.endArray(); |
| 678 |
| 679 TracedArrayBase& largeObjects = json->beginArray("largeObjects"); |
| 680 for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current; cur
rent = current->next()) { |
| 681 TracedDictionaryBase& jsonCurrent = largeObjects.beginDictionary(); |
| 682 current->snapshot(&jsonCurrent, info); |
| 683 jsonCurrent.endDictionary(); |
| 684 } |
| 685 largeObjects.endArray(); |
| 686 |
| 687 size_t pagePoolSize = 0; |
| 688 for (PagePoolEntry* page = m_pagePool; page; page = page->next()) |
| 689 ++pagePoolSize; |
| 690 |
| 691 json->setInteger("pagePoolSize", pagePoolSize) |
| 692 .setInteger("pageCount", info->pageCount - previousPageCount); |
| 693 } |
| 694 #endif |
| 695 |
656 template<typename Header> | 696 template<typename Header> |
657 void ThreadHeap<Header>::addToFreeList(Address address, size_t size) | 697 void ThreadHeap<Header>::addToFreeList(Address address, size_t size) |
658 { | 698 { |
659 ASSERT(heapPageFromAddress(address)); | 699 ASSERT(heapPageFromAddress(address)); |
660 ASSERT(heapPageFromAddress(address + size - 1)); | 700 ASSERT(heapPageFromAddress(address + size - 1)); |
661 ASSERT(size < blinkPagePayloadSize()); | 701 ASSERT(size < blinkPagePayloadSize()); |
662 // The free list entries are only pointer aligned (but when we allocate | 702 // The free list entries are only pointer aligned (but when we allocate |
663 // from them we are 8 byte aligned due to the header size). | 703 // from them we are 8 byte aligned due to the header size). |
664 ASSERT(!((reinterpret_cast<uintptr_t>(address) + sizeof(Header)) & allocatio
nMask)); | 704 ASSERT(!((reinterpret_cast<uintptr_t>(address) + sizeof(Header)) & allocatio
nMask)); |
665 ASSERT(!(size & allocationMask)); | 705 ASSERT(!(size & allocationMask)); |
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1194 } | 1234 } |
1195 | 1235 |
1196 template<typename Header> | 1236 template<typename Header> |
1197 void HeapPage<Header>::checkAndMarkPointer(Visitor* visitor, Address address) | 1237 void HeapPage<Header>::checkAndMarkPointer(Visitor* visitor, Address address) |
1198 { | 1238 { |
1199 ASSERT(contains(address)); | 1239 ASSERT(contains(address)); |
1200 Header* header = findHeaderFromAddress(address); | 1240 Header* header = findHeaderFromAddress(address); |
1201 if (!header) | 1241 if (!header) |
1202 return; | 1242 return; |
1203 | 1243 |
1204 #if ENABLE(GC_TRACING) | 1244 #if GC_PROFILE_MARKING |
1205 visitor->setHostInfo(&address, "stack"); | 1245 visitor->setHostInfo(&address, "stack"); |
1206 #endif | 1246 #endif |
1207 if (hasVTable(header) && !vTableInitialized(header->payload())) | 1247 if (hasVTable(header) && !vTableInitialized(header->payload())) |
1208 visitor->markConservatively(header); | 1248 visitor->markConservatively(header); |
1209 else | 1249 else |
1210 visitor->mark(header, traceCallback(header)); | 1250 visitor->mark(header, traceCallback(header)); |
1211 } | 1251 } |
1212 | 1252 |
1213 #if ENABLE(GC_TRACING) | 1253 #if GC_PROFILE_MARKING |
1214 template<typename Header> | 1254 template<typename Header> |
1215 const GCInfo* HeapPage<Header>::findGCInfo(Address address) | 1255 const GCInfo* HeapPage<Header>::findGCInfo(Address address) |
1216 { | 1256 { |
1217 if (address < payload()) | 1257 if (address < payload()) |
1218 return 0; | 1258 return 0; |
1219 | 1259 |
1220 if (gcInfo()) // for non FinalizedObjectHeader | 1260 if (gcInfo()) // for non FinalizedObjectHeader |
1221 return gcInfo(); | 1261 return gcInfo(); |
1222 | 1262 |
1223 Header* header = findHeaderFromAddress(address); | 1263 Header* header = findHeaderFromAddress(address); |
1224 if (!header) | 1264 if (!header) |
1225 return 0; | 1265 return 0; |
1226 | 1266 |
1227 return header->gcInfo(); | 1267 return header->gcInfo(); |
1228 } | 1268 } |
1229 #endif | 1269 #endif |
1230 | 1270 |
| 1271 #if GC_PROFILE_HEAP |
| 1272 template<typename Header> |
| 1273 void HeapPage<Header>::snapshot(TracedArrayBase* json, ThreadState::SnapshotInfo
* info) |
| 1274 { |
| 1275 Header* header = 0; |
| 1276 for (Address addr = payload(); addr < end(); addr += header->size()) { |
| 1277 header = reinterpret_cast<Header*>(addr); |
| 1278 if (json) |
| 1279 json->pushInteger(header->encodedSize()); |
| 1280 if (header->isFree()) { |
| 1281 info->freeSize += header->size(); |
| 1282 continue; |
| 1283 } |
| 1284 |
| 1285 size_t tag = info->getClassTag(header->gcInfo()); |
| 1286 size_t age = header->age(); |
| 1287 if (json) |
| 1288 json->pushInteger(tag); |
| 1289 if (header->isMarked()) { |
| 1290 info->liveCount[tag] += 1; |
| 1291 info->liveSize += header->size(); |
| 1292 // Count objects that are live when promoted to the final generation
. |
| 1293 if (age == maxHeapObjectAge - 1) |
| 1294 info->generations[tag][maxHeapObjectAge] += 1; |
| 1295 header->incAge(); |
| 1296 } else { |
| 1297 info->deadCount[tag] += 1; |
| 1298 info->deadSize += header->size(); |
| 1299 // Count objects that are dead before the final generation. |
| 1300 if (age < maxHeapObjectAge) |
| 1301 info->generations[tag][age] += 1; |
| 1302 } |
| 1303 } |
| 1304 } |
| 1305 #endif |
| 1306 |
1231 #if defined(ADDRESS_SANITIZER) | 1307 #if defined(ADDRESS_SANITIZER) |
1232 template<typename Header> | 1308 template<typename Header> |
1233 void HeapPage<Header>::poisonUnmarkedObjects() | 1309 void HeapPage<Header>::poisonUnmarkedObjects() |
1234 { | 1310 { |
1235 for (Address headerAddress = payload(); headerAddress < end(); ) { | 1311 for (Address headerAddress = payload(); headerAddress < end(); ) { |
1236 Header* header = reinterpret_cast<Header*>(headerAddress); | 1312 Header* header = reinterpret_cast<Header*>(headerAddress); |
1237 ASSERT(header->size() < blinkPagePayloadSize()); | 1313 ASSERT(header->size() < blinkPagePayloadSize()); |
1238 | 1314 |
1239 if (!header->isFree() && !header->isMarked()) | 1315 if (!header->isFree() && !header->isMarked()) |
1240 ASAN_POISON_MEMORY_REGION(header->payload(), header->payloadSize()); | 1316 ASAN_POISON_MEMORY_REGION(header->payload(), header->payloadSize()); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1282 return header->hasVTable(); | 1358 return header->hasVTable(); |
1283 } | 1359 } |
1284 | 1360 |
1285 template<typename Header> | 1361 template<typename Header> |
1286 void LargeHeapObject<Header>::getStats(HeapStats& stats) | 1362 void LargeHeapObject<Header>::getStats(HeapStats& stats) |
1287 { | 1363 { |
1288 stats.increaseAllocatedSpace(size()); | 1364 stats.increaseAllocatedSpace(size()); |
1289 stats.increaseObjectSpace(payloadSize()); | 1365 stats.increaseObjectSpace(payloadSize()); |
1290 } | 1366 } |
1291 | 1367 |
| 1368 #if GC_PROFILE_HEAP |
| 1369 template<typename Header> |
| 1370 void LargeHeapObject<Header>::snapshot(TracedDictionaryBase* json, ThreadState::
SnapshotInfo* info) |
| 1371 { |
| 1372 Header* header = heapObjectHeader(); |
| 1373 size_t tag = info->getClassTag(header->gcInfo()); |
| 1374 size_t age = header->age(); |
| 1375 if (isMarked()) { |
| 1376 info->liveCount[tag] += 1; |
| 1377 info->liveSize += header->size(); |
| 1378 // Count objects that are live when promoted to the final generation. |
| 1379 if (age == maxHeapObjectAge - 1) |
| 1380 info->generations[tag][maxHeapObjectAge] += 1; |
| 1381 header->incAge(); |
| 1382 } else { |
| 1383 info->deadCount[tag] += 1; |
| 1384 info->deadSize += header->size(); |
| 1385 // Count objects that are live when promoted to the final generation. |
| 1386 if (age == maxHeapObjectAge - 1) |
| 1387 info->generations[tag][maxHeapObjectAge] += 1; |
| 1388 header->incAge(); |
| 1389 } |
| 1390 |
| 1391 if (json) { |
| 1392 json->setInteger("class", tag) |
| 1393 .setInteger("size", header->size()) |
| 1394 .setInteger("isMarked", isMarked()); |
| 1395 } |
| 1396 } |
| 1397 #endif |
| 1398 |
1292 template<typename Entry> | 1399 template<typename Entry> |
1293 void HeapExtentCache<Entry>::flush() | 1400 void HeapExtentCache<Entry>::flush() |
1294 { | 1401 { |
1295 if (m_hasEntries) { | 1402 if (m_hasEntries) { |
1296 for (int i = 0; i < numberOfEntries; i++) | 1403 for (int i = 0; i < numberOfEntries; i++) |
1297 m_entries[i] = Entry(); | 1404 m_entries[i] = Entry(); |
1298 m_hasEntries = false; | 1405 m_hasEntries = false; |
1299 } | 1406 } |
1300 } | 1407 } |
1301 | 1408 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1396 return false; | 1503 return false; |
1397 } | 1504 } |
1398 CallbackStack* nextStack = m_next; | 1505 CallbackStack* nextStack = m_next; |
1399 *first = nextStack; | 1506 *first = nextStack; |
1400 delete this; | 1507 delete this; |
1401 return nextStack->popAndInvokeCallback(first, visitor); | 1508 return nextStack->popAndInvokeCallback(first, visitor); |
1402 } | 1509 } |
1403 Item* item = --m_current; | 1510 Item* item = --m_current; |
1404 | 1511 |
1405 VisitorCallback callback = item->callback(); | 1512 VisitorCallback callback = item->callback(); |
1406 #if ENABLE(GC_TRACING) | 1513 #if GC_PROFILE_MARKING |
1407 if (ThreadState::isAnyThreadInGC()) // weak-processing will also use popAndI
nvokeCallback | 1514 if (ThreadState::isAnyThreadInGC()) // weak-processing will also use popAndI
nvokeCallback |
1408 visitor->setHostInfo(item->object(), classOf(item->object())); | 1515 visitor->setHostInfo(item->object(), classOf(item->object())); |
1409 #endif | 1516 #endif |
1410 callback(visitor, item->object()); | 1517 callback(visitor, item->object()); |
1411 | 1518 |
1412 return true; | 1519 return true; |
1413 } | 1520 } |
1414 | 1521 |
1415 void CallbackStack::invokeCallbacks(CallbackStack** first, Visitor* visitor) | 1522 void CallbackStack::invokeCallbacks(CallbackStack** first, Visitor* visitor) |
1416 { | 1523 { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1454 } | 1561 } |
1455 if (m_next) | 1562 if (m_next) |
1456 return m_next->hasCallbackForObject(object); | 1563 return m_next->hasCallbackForObject(object); |
1457 | 1564 |
1458 return false; | 1565 return false; |
1459 } | 1566 } |
1460 #endif | 1567 #endif |
1461 | 1568 |
1462 class MarkingVisitor : public Visitor { | 1569 class MarkingVisitor : public Visitor { |
1463 public: | 1570 public: |
1464 #if ENABLE(GC_TRACING) | 1571 #if GC_PROFILE_MARKING |
1465 typedef HashSet<uintptr_t> LiveObjectSet; | 1572 typedef HashSet<uintptr_t> LiveObjectSet; |
1466 typedef HashMap<String, LiveObjectSet> LiveObjectMap; | 1573 typedef HashMap<String, LiveObjectSet> LiveObjectMap; |
1467 typedef HashMap<uintptr_t, std::pair<uintptr_t, String> > ObjectGraph; | 1574 typedef HashMap<uintptr_t, std::pair<uintptr_t, String> > ObjectGraph; |
1468 #endif | 1575 #endif |
1469 | 1576 |
1470 inline void visitHeader(HeapObjectHeader* header, const void* objectPointer,
TraceCallback callback) | 1577 inline void visitHeader(HeapObjectHeader* header, const void* objectPointer,
TraceCallback callback) |
1471 { | 1578 { |
1472 ASSERT(header); | 1579 ASSERT(header); |
1473 ASSERT(objectPointer); | 1580 ASSERT(objectPointer); |
1474 if (header->isMarked()) | 1581 if (header->isMarked()) |
1475 return; | 1582 return; |
1476 header->mark(); | 1583 header->mark(); |
1477 #if ENABLE(GC_TRACING) | 1584 #if GC_PROFILE_MARKING |
1478 MutexLocker locker(objectGraphMutex()); | 1585 MutexLocker locker(objectGraphMutex()); |
1479 String className(classOf(objectPointer)); | 1586 String className(classOf(objectPointer)); |
1480 { | 1587 { |
1481 LiveObjectMap::AddResult result = currentlyLive().add(className, Liv
eObjectSet()); | 1588 LiveObjectMap::AddResult result = currentlyLive().add(className, Liv
eObjectSet()); |
1482 result.storedValue->value.add(reinterpret_cast<uintptr_t>(objectPoin
ter)); | 1589 result.storedValue->value.add(reinterpret_cast<uintptr_t>(objectPoin
ter)); |
1483 } | 1590 } |
1484 ObjectGraph::AddResult result = objectGraph().add(reinterpret_cast<uintp
tr_t>(objectPointer), std::make_pair(reinterpret_cast<uintptr_t>(m_hostObject),
m_hostName)); | 1591 ObjectGraph::AddResult result = objectGraph().add(reinterpret_cast<uintp
tr_t>(objectPointer), std::make_pair(reinterpret_cast<uintptr_t>(m_hostObject),
m_hostName)); |
1485 ASSERT(result.isNewEntry); | 1592 ASSERT(result.isNewEntry); |
1486 // fprintf(stderr, "%s[%p] -> %s[%p]\n", m_hostName.ascii().data(), m_ho
stObject, className.ascii().data(), objectPointer); | 1593 // fprintf(stderr, "%s[%p] -> %s[%p]\n", m_hostName.ascii().data(), m_ho
stObject, className.ascii().data(), objectPointer); |
1487 #endif | 1594 #endif |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1573 visitHeader(header, header->payload(), callback);
\ | 1680 visitHeader(header, header->payload(), callback);
\ |
1574 }
\ | 1681 }
\ |
1575 virtual bool isMarked(const Type* objectPointer) OVERRIDE
\ | 1682 virtual bool isMarked(const Type* objectPointer) OVERRIDE
\ |
1576 {
\ | 1683 {
\ |
1577 return HeapObjectHeader::fromPayload(objectPointer)->isMarked();
\ | 1684 return HeapObjectHeader::fromPayload(objectPointer)->isMarked();
\ |
1578 } | 1685 } |
1579 | 1686 |
1580 FOR_EACH_TYPED_HEAP(DEFINE_VISITOR_METHODS) | 1687 FOR_EACH_TYPED_HEAP(DEFINE_VISITOR_METHODS) |
1581 #undef DEFINE_VISITOR_METHODS | 1688 #undef DEFINE_VISITOR_METHODS |
1582 | 1689 |
1583 #if ENABLE(GC_TRACING) | 1690 #if GC_PROFILE_MARKING |
1584 void reportStats() | 1691 void reportStats() |
1585 { | 1692 { |
1586 fprintf(stderr, "\n---------- AFTER MARKING -------------------\n"); | 1693 fprintf(stderr, "\n---------- AFTER MARKING -------------------\n"); |
1587 for (LiveObjectMap::iterator it = currentlyLive().begin(), end = current
lyLive().end(); it != end; ++it) { | 1694 for (LiveObjectMap::iterator it = currentlyLive().begin(), end = current
lyLive().end(); it != end; ++it) { |
1588 fprintf(stderr, "%s %u", it->key.ascii().data(), it->value.size()); | 1695 fprintf(stderr, "%s %u", it->key.ascii().data(), it->value.size()); |
1589 | 1696 |
1590 if (it->key == "WebCore::Document") | 1697 if (it->key == "WebCore::Document") |
1591 reportStillAlive(it->value, previouslyLive().get(it->key)); | 1698 reportStillAlive(it->value, previouslyLive().get(it->key)); |
1592 | 1699 |
1593 fprintf(stderr, "\n"); | 1700 fprintf(stderr, "\n"); |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1751 | 1858 |
1752 #ifdef NDEBUG | 1859 #ifdef NDEBUG |
1753 s_heapDoesNotContainCache->addEntry(address, true); | 1860 s_heapDoesNotContainCache->addEntry(address, true); |
1754 #else | 1861 #else |
1755 if (!s_heapDoesNotContainCache->lookup(address)) | 1862 if (!s_heapDoesNotContainCache->lookup(address)) |
1756 s_heapDoesNotContainCache->addEntry(address, true); | 1863 s_heapDoesNotContainCache->addEntry(address, true); |
1757 #endif | 1864 #endif |
1758 return 0; | 1865 return 0; |
1759 } | 1866 } |
1760 | 1867 |
1761 #if ENABLE(GC_TRACING) | 1868 #if GC_PROFILE_MARKING |
1762 const GCInfo* Heap::findGCInfo(Address address) | 1869 const GCInfo* Heap::findGCInfo(Address address) |
1763 { | 1870 { |
1764 return ThreadState::findGCInfoFromAllThreads(address); | 1871 return ThreadState::findGCInfoFromAllThreads(address); |
1765 } | 1872 } |
| 1873 #endif |
1766 | 1874 |
| 1875 #if GC_PROFILE_MARKING |
1767 void Heap::dumpPathToObjectOnNextGC(void* p) | 1876 void Heap::dumpPathToObjectOnNextGC(void* p) |
1768 { | 1877 { |
1769 static_cast<MarkingVisitor*>(s_markingVisitor)->dumpPathToObjectOnNextGC(p); | 1878 static_cast<MarkingVisitor*>(s_markingVisitor)->dumpPathToObjectOnNextGC(p); |
1770 } | 1879 } |
1771 | 1880 |
1772 String Heap::createBacktraceString() | 1881 String Heap::createBacktraceString() |
1773 { | 1882 { |
1774 int framesToShow = 3; | 1883 int framesToShow = 3; |
1775 int stackFrameSize = 16; | 1884 int stackFrameSize = 16; |
1776 ASSERT(stackFrameSize >= framesToShow); | 1885 ASSERT(stackFrameSize >= framesToShow); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1873 GCScope gcScope(stackState); | 1982 GCScope gcScope(stackState); |
1874 // Check if we successfully parked the other threads. If not we bail out of
the GC. | 1983 // Check if we successfully parked the other threads. If not we bail out of
the GC. |
1875 if (!gcScope.allThreadsParked()) { | 1984 if (!gcScope.allThreadsParked()) { |
1876 ThreadState::current()->setGCRequested(); | 1985 ThreadState::current()->setGCRequested(); |
1877 return; | 1986 return; |
1878 } | 1987 } |
1879 | 1988 |
1880 ScriptForbiddenScope forbiddenScope; | 1989 ScriptForbiddenScope forbiddenScope; |
1881 s_lastGCWasConservative = false; | 1990 s_lastGCWasConservative = false; |
1882 | 1991 |
1883 TRACE_EVENT0("blink", "Heap::collectGarbage"); | 1992 TRACE_EVENT0(GC_PROFILE_GROUP, "Heap::collectGarbage"); |
1884 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "BlinkGC"); | 1993 TRACE_EVENT_SCOPED_SAMPLING_STATE(GC_PROFILE_GROUP, "BlinkGC"); |
1885 double timeStamp = WTF::currentTimeMS(); | 1994 double timeStamp = WTF::currentTimeMS(); |
1886 #if ENABLE(GC_TRACING) | 1995 #if GC_PROFILE_MARKING |
1887 static_cast<MarkingVisitor*>(s_markingVisitor)->objectGraph().clear(); | 1996 static_cast<MarkingVisitor*>(s_markingVisitor)->objectGraph().clear(); |
1888 #endif | 1997 #endif |
1889 | 1998 |
1890 // Disallow allocation during garbage collection (but not | 1999 // Disallow allocation during garbage collection (but not |
1891 // during the finalization that happens when the gcScope is | 2000 // during the finalization that happens when the gcScope is |
1892 // torn down). | 2001 // torn down). |
1893 NoAllocationScope<AnyThread> noAllocationScope; | 2002 NoAllocationScope<AnyThread> noAllocationScope; |
1894 | 2003 |
1895 prepareForGC(); | 2004 prepareForGC(); |
1896 | 2005 |
(...skipping 16 matching lines...) Expand all Loading... |
1913 // to do cleanup (specifically clear the queued bits for weak hash | 2022 // to do cleanup (specifically clear the queued bits for weak hash |
1914 // tables). | 2023 // tables). |
1915 while (popAndInvokeWeakPointerCallback(s_markingVisitor)) { } | 2024 while (popAndInvokeWeakPointerCallback(s_markingVisitor)) { } |
1916 | 2025 |
1917 CallbackStack::clear(&s_ephemeronStack); | 2026 CallbackStack::clear(&s_ephemeronStack); |
1918 | 2027 |
1919 // It is not permitted to trace pointers of live objects in the weak | 2028 // It is not permitted to trace pointers of live objects in the weak |
1920 // callback phase, so the marking stack should still be empty here. | 2029 // callback phase, so the marking stack should still be empty here. |
1921 ASSERT(s_markingStack->isEmpty()); | 2030 ASSERT(s_markingStack->isEmpty()); |
1922 | 2031 |
1923 #if ENABLE(GC_TRACING) | 2032 #if GC_PROFILE_MARKING |
1924 static_cast<MarkingVisitor*>(s_markingVisitor)->reportStats(); | 2033 static_cast<MarkingVisitor*>(s_markingVisitor)->reportStats(); |
1925 #endif | 2034 #endif |
1926 | 2035 |
1927 if (blink::Platform::current()) { | 2036 if (blink::Platform::current()) { |
1928 uint64_t objectSpaceSize; | 2037 uint64_t objectSpaceSize; |
1929 uint64_t allocatedSpaceSize; | 2038 uint64_t allocatedSpaceSize; |
1930 getHeapSpaceSize(&objectSpaceSize, &allocatedSpaceSize); | 2039 getHeapSpaceSize(&objectSpaceSize, &allocatedSpaceSize); |
1931 blink::Platform::current()->histogramCustomCounts("BlinkGC.CollectGarbag
e", WTF::currentTimeMS() - timeStamp, 0, 10 * 1000, 50); | 2040 blink::Platform::current()->histogramCustomCounts("BlinkGC.CollectGarbag
e", WTF::currentTimeMS() - timeStamp, 0, 10 * 1000, 50); |
1932 blink::Platform::current()->histogramCustomCounts("BlinkGC.TotalObjectSp
ace", objectSpaceSize / 1024, 0, 4 * 1024 * 1024, 50); | 2041 blink::Platform::current()->histogramCustomCounts("BlinkGC.TotalObjectSp
ace", objectSpaceSize / 1024, 0, 4 * 1024 * 1024, 50); |
1933 blink::Platform::current()->histogramCustomCounts("BlinkGC.TotalAllocate
dSpace", allocatedSpaceSize / 1024, 0, 4 * 1024 * 1024, 50); | 2042 blink::Platform::current()->histogramCustomCounts("BlinkGC.TotalAllocate
dSpace", allocatedSpaceSize / 1024, 0, 4 * 1024 * 1024, 50); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2002 template class ThreadHeap<HeapObjectHeader>; | 2111 template class ThreadHeap<HeapObjectHeader>; |
2003 | 2112 |
2004 Visitor* Heap::s_markingVisitor; | 2113 Visitor* Heap::s_markingVisitor; |
2005 CallbackStack* Heap::s_markingStack; | 2114 CallbackStack* Heap::s_markingStack; |
2006 CallbackStack* Heap::s_weakCallbackStack; | 2115 CallbackStack* Heap::s_weakCallbackStack; |
2007 CallbackStack* Heap::s_ephemeronStack; | 2116 CallbackStack* Heap::s_ephemeronStack; |
2008 HeapDoesNotContainCache* Heap::s_heapDoesNotContainCache; | 2117 HeapDoesNotContainCache* Heap::s_heapDoesNotContainCache; |
2009 bool Heap::s_shutdownCalled = false; | 2118 bool Heap::s_shutdownCalled = false; |
2010 bool Heap::s_lastGCWasConservative = false; | 2119 bool Heap::s_lastGCWasConservative = false; |
2011 } | 2120 } |
OLD | NEW |