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 15 matching lines...) Expand all Loading... |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #include "config.h" | 31 #include "config.h" |
32 #include "platform/heap/ThreadState.h" | 32 #include "platform/heap/ThreadState.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/BlinkGCMemoryDumpProvider.h" |
36 #include "platform/heap/CallbackStack.h" | 37 #include "platform/heap/CallbackStack.h" |
37 #include "platform/heap/Handle.h" | 38 #include "platform/heap/Handle.h" |
38 #include "platform/heap/Heap.h" | 39 #include "platform/heap/Heap.h" |
39 #include "platform/heap/MarkingVisitor.h" | 40 #include "platform/heap/MarkingVisitor.h" |
40 #include "platform/heap/SafePoint.h" | 41 #include "platform/heap/SafePoint.h" |
41 #include "public/platform/Platform.h" | 42 #include "public/platform/Platform.h" |
| 43 #include "public/platform/WebMemoryAllocatorDump.h" |
| 44 #include "public/platform/WebProcessMemoryDump.h" |
42 #include "public/platform/WebScheduler.h" | 45 #include "public/platform/WebScheduler.h" |
43 #include "public/platform/WebThread.h" | 46 #include "public/platform/WebThread.h" |
44 #include "public/platform/WebTraceLocation.h" | 47 #include "public/platform/WebTraceLocation.h" |
45 #include "wtf/Partitions.h" | 48 #include "wtf/Partitions.h" |
46 #include "wtf/ThreadingPrimitives.h" | 49 #include "wtf/ThreadingPrimitives.h" |
47 #if ENABLE(GC_PROFILING) | 50 #if ENABLE(GC_PROFILING) |
48 #include "platform/TracedValue.h" | 51 #include "platform/TracedValue.h" |
49 #include "wtf/text/StringHash.h" | 52 #include "wtf/text/StringHash.h" |
50 #endif | 53 #endif |
51 | 54 |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 | 376 |
374 void ThreadState::visitPersistents(Visitor* visitor) | 377 void ThreadState::visitPersistents(Visitor* visitor) |
375 { | 378 { |
376 m_persistents->tracePersistentNodes(visitor); | 379 m_persistents->tracePersistentNodes(visitor); |
377 if (m_traceDOMWrappers) { | 380 if (m_traceDOMWrappers) { |
378 TRACE_EVENT0("blink_gc", "V8GCController::traceDOMWrappers"); | 381 TRACE_EVENT0("blink_gc", "V8GCController::traceDOMWrappers"); |
379 m_traceDOMWrappers(m_isolate, visitor); | 382 m_traceDOMWrappers(m_isolate, visitor); |
380 } | 383 } |
381 } | 384 } |
382 | 385 |
| 386 size_t ThreadState::GCSnapshotInfo::getClassTag(const size_t gcInfoIndex) |
| 387 { |
| 388 ClassTagMap::AddResult result = classTags.add(gcInfoIndex, classTags.size())
; |
| 389 if (result.isNewEntry) { |
| 390 liveCount.append(0); |
| 391 deadCount.append(0); |
| 392 liveSize.append(0); |
| 393 deadSize.append(0); |
| 394 } |
| 395 return result.storedValue->value; |
| 396 } |
| 397 |
383 #if ENABLE(GC_PROFILING) | 398 #if ENABLE(GC_PROFILING) |
384 const GCInfo* ThreadState::findGCInfo(Address address) | 399 const GCInfo* ThreadState::findGCInfo(Address address) |
385 { | 400 { |
386 if (BasePage* page = findPageFromAddress(address)) | 401 if (BasePage* page = findPageFromAddress(address)) |
387 return page->findGCInfo(address); | 402 return page->findGCInfo(address); |
388 return nullptr; | 403 return nullptr; |
389 } | 404 } |
390 | 405 |
391 size_t ThreadState::SnapshotInfo::getClassTag(const GCInfo* gcInfo) | 406 size_t ThreadState::SnapshotInfo::getClassTag(const GCInfo* gcInfo) |
392 { | 407 { |
(...skipping 981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1374 size_t entryIndex = gcInfoIndex & likelyToBePromptlyFreedArrayMask; | 1389 size_t entryIndex = gcInfoIndex & likelyToBePromptlyFreedArrayMask; |
1375 // See the comment in vectorBackingHeap() for why this is +3. | 1390 // See the comment in vectorBackingHeap() for why this is +3. |
1376 m_likelyToBePromptlyFreed[entryIndex] += 3; | 1391 m_likelyToBePromptlyFreed[entryIndex] += 3; |
1377 } | 1392 } |
1378 | 1393 |
1379 void ThreadState::takeSnapshot(SnapshotType type) | 1394 void ThreadState::takeSnapshot(SnapshotType type) |
1380 { | 1395 { |
1381 ASSERT(isInGC()); | 1396 ASSERT(isInGC()); |
1382 | 1397 |
1383 GCSnapshotInfo info; | 1398 GCSnapshotInfo info; |
| 1399 String threadDumpName = String::format("blink_gc/thread_%lu", (unsigned long
)m_thread); |
| 1400 String heapsDumpName = threadDumpName + "/heaps"; |
| 1401 String classesDumpName = threadDumpName + "/classes"; |
| 1402 |
1384 int numberOfHeapsReported = 0; | 1403 int numberOfHeapsReported = 0; |
1385 #define SNAPSHOT_HEAP(HeapType)
\ | 1404 #define SNAPSHOT_HEAP(HeapType)
\ |
1386 {
\ | 1405 {
\ |
1387 numberOfHeapsReported++;
\ | 1406 numberOfHeapsReported++;
\ |
1388 String allocatorBaseName;
\ | 1407 switch (type) {
\ |
1389 allocatorBaseName = String::format("blink_gc/thread_%lu/heaps/" #HeapTyp
e, (unsigned long)(m_thread)); \ | 1408 case SnapshotType::HeapSnapshot:
\ |
1390 switch (type) {
\ | 1409 case SnapshotType::HeapSnapshotWithClasses:
\ |
1391 case SnapshotType::HeapSnapshot:
\ | 1410 m_heaps[HeapType##HeapIndex]->takeSnapshot(heapsDumpName + "/" #Heap
Type, info); \ |
1392 m_heaps[HeapType##HeapIndex]->takeSnapshot(allocatorBaseName, info);
\ | 1411 break;
\ |
1393 break;
\ | 1412 case SnapshotType::FreelistSnapshot:
\ |
1394 case SnapshotType::FreelistSnapshot:
\ | 1413 m_heaps[HeapType##HeapIndex]->takeFreelistSnapshot(heapsDumpName + "
/" #HeapType); \ |
1395 m_heaps[HeapType##HeapIndex]->takeFreelistSnapshot(allocatorBaseName
); \ | 1414 break;
\ |
1396 break;
\ | 1415 default:
\ |
1397 default:
\ | 1416 ASSERT_NOT_REACHED();
\ |
1398 ASSERT_NOT_REACHED();
\ | 1417 }
\ |
1399 }
\ | |
1400 } | 1418 } |
1401 | 1419 |
1402 SNAPSHOT_HEAP(NormalPage1); | 1420 SNAPSHOT_HEAP(NormalPage1); |
1403 SNAPSHOT_HEAP(NormalPage2); | 1421 SNAPSHOT_HEAP(NormalPage2); |
1404 SNAPSHOT_HEAP(NormalPage3); | 1422 SNAPSHOT_HEAP(NormalPage3); |
1405 SNAPSHOT_HEAP(NormalPage4); | 1423 SNAPSHOT_HEAP(NormalPage4); |
1406 SNAPSHOT_HEAP(EagerSweep); | 1424 SNAPSHOT_HEAP(EagerSweep); |
1407 SNAPSHOT_HEAP(Vector1); | 1425 SNAPSHOT_HEAP(Vector1); |
1408 SNAPSHOT_HEAP(Vector2); | 1426 SNAPSHOT_HEAP(Vector2); |
1409 SNAPSHOT_HEAP(Vector3); | 1427 SNAPSHOT_HEAP(Vector3); |
1410 SNAPSHOT_HEAP(Vector4); | 1428 SNAPSHOT_HEAP(Vector4); |
1411 SNAPSHOT_HEAP(InlineVector); | 1429 SNAPSHOT_HEAP(InlineVector); |
1412 SNAPSHOT_HEAP(HashTable); | 1430 SNAPSHOT_HEAP(HashTable); |
1413 SNAPSHOT_HEAP(LargeObject); | 1431 SNAPSHOT_HEAP(LargeObject); |
1414 FOR_EACH_TYPED_HEAP(SNAPSHOT_HEAP); | 1432 FOR_EACH_TYPED_HEAP(SNAPSHOT_HEAP); |
1415 | 1433 |
1416 ASSERT(numberOfHeapsReported == NumberOfHeaps); | 1434 ASSERT(numberOfHeapsReported == NumberOfHeaps); |
1417 | 1435 |
1418 #undef SNAPSHOT_HEAP | 1436 #undef SNAPSHOT_HEAP |
| 1437 |
| 1438 if (type != SnapshotType::HeapSnapshotWithClasses) |
| 1439 return; |
| 1440 |
| 1441 if (!info.classTags.size()) |
| 1442 return; |
| 1443 |
| 1444 Vector<String> classNameVector(info.classTags.size()); |
| 1445 for (GCSnapshotInfo::ClassTagMap::iterator it = info.classTags.begin(); it !
= info.classTags.end(); ++it) |
| 1446 classNameVector[it->value] = Heap::gcInfo(it->key)->m_className; |
| 1447 |
| 1448 size_t totalLiveCount = 0; |
| 1449 size_t totalDeadCount = 0; |
| 1450 size_t totalLiveSize = 0; |
| 1451 size_t totalDeadSize = 0; |
| 1452 for (size_t i = 0; i < classNameVector.size(); ++i) { |
| 1453 String dumpName = classesDumpName + "/" + classNameVector[i]; |
| 1454 WebMemoryAllocatorDump* classDump = BlinkGCMemoryDumpProvider::instance(
)->createMemoryAllocatorDumpForCurrentGC(dumpName); |
| 1455 classDump->AddScalar("live_count", "objects", info.liveCount[i]); |
| 1456 classDump->AddScalar("dead_count", "objects", info.deadCount[i]); |
| 1457 classDump->AddScalar("live_size", "bytes", info.liveSize[i]); |
| 1458 classDump->AddScalar("dead_size", "bytes", info.deadSize[i]); |
| 1459 |
| 1460 totalLiveCount += info.liveCount[i]; |
| 1461 totalDeadCount += info.deadCount[i]; |
| 1462 totalLiveSize += info.liveSize[i]; |
| 1463 totalDeadSize += info.deadSize[i]; |
| 1464 } |
| 1465 |
| 1466 WebMemoryAllocatorDump* threadDump = BlinkGCMemoryDumpProvider::instance()->
createMemoryAllocatorDumpForCurrentGC(threadDumpName); |
| 1467 threadDump->AddScalar("live_count", "objects", totalLiveCount); |
| 1468 threadDump->AddScalar("dead_count", "objects", totalDeadCount); |
| 1469 threadDump->AddScalar("live_size", "bytes", totalLiveSize); |
| 1470 threadDump->AddScalar("dead_size", "bytes", totalDeadSize); |
| 1471 |
| 1472 WebMemoryAllocatorDump* heapsDump = BlinkGCMemoryDumpProvider::instance()->c
reateMemoryAllocatorDumpForCurrentGC(heapsDumpName); |
| 1473 WebMemoryAllocatorDump* classesDump = BlinkGCMemoryDumpProvider::instance()-
>createMemoryAllocatorDumpForCurrentGC(classesDumpName); |
| 1474 BlinkGCMemoryDumpProvider::instance()->currentProcessMemoryDump()->AddOwners
hipEdge(classesDump->guid(), heapsDump->guid()); |
1419 } | 1475 } |
1420 | 1476 |
1421 #if ENABLE(GC_PROFILING) | 1477 #if ENABLE(GC_PROFILING) |
1422 const GCInfo* ThreadState::findGCInfoFromAllThreads(Address address) | 1478 const GCInfo* ThreadState::findGCInfoFromAllThreads(Address address) |
1423 { | 1479 { |
1424 bool needLockForIteration = !ThreadState::current()->isInGC(); | 1480 bool needLockForIteration = !ThreadState::current()->isInGC(); |
1425 if (needLockForIteration) | 1481 if (needLockForIteration) |
1426 threadAttachMutex().lock(); | 1482 threadAttachMutex().lock(); |
1427 | 1483 |
1428 for (ThreadState* state : attachedThreads()) { | 1484 for (ThreadState* state : attachedThreads()) { |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1508 json->beginArray(it->key.ascii().data()); | 1564 json->beginArray(it->key.ascii().data()); |
1509 for (size_t age = 0; age <= maxHeapObjectAge; ++age) | 1565 for (size_t age = 0; age <= maxHeapObjectAge; ++age) |
1510 json->pushInteger(it->value.ages[age]); | 1566 json->pushInteger(it->value.ages[age]); |
1511 json->endArray(); | 1567 json->endArray(); |
1512 } | 1568 } |
1513 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(TRACE_DISABLED_BY_DEFAULT("blink_gc"), s
tatsName, this, json.release()); | 1569 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(TRACE_DISABLED_BY_DEFAULT("blink_gc"), s
tatsName, this, json.release()); |
1514 } | 1570 } |
1515 #endif | 1571 #endif |
1516 | 1572 |
1517 } // namespace blink | 1573 } // namespace blink |
OLD | NEW |