| 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 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 // instantiated while running the termination GC. | 205 // instantiated while running the termination GC. |
| 206 ReleaseStaticPersistentNodes(); | 206 ReleaseStaticPersistentNodes(); |
| 207 old_count = current_count; | 207 old_count = current_count; |
| 208 current_count = GetPersistentRegion()->NumberOfPersistents(); | 208 current_count = GetPersistentRegion()->NumberOfPersistents(); |
| 209 } | 209 } |
| 210 // We should not have any persistents left when getting to this point, | 210 // We should not have any persistents left when getting to this point, |
| 211 // if we have it is probably a bug so adding a debug ASSERT to catch this. | 211 // if we have it is probably a bug so adding a debug ASSERT to catch this. |
| 212 ASSERT(!current_count); | 212 ASSERT(!current_count); |
| 213 // All of pre-finalizers should be consumed. | 213 // All of pre-finalizers should be consumed. |
| 214 ASSERT(ordered_pre_finalizers_.IsEmpty()); | 214 ASSERT(ordered_pre_finalizers_.IsEmpty()); |
| 215 RELEASE_ASSERT(GcState() == kNoGCScheduled); | 215 CHECK_EQ(GcState(), kNoGCScheduled); |
| 216 | 216 |
| 217 RemoveAllPages(); | 217 RemoveAllPages(); |
| 218 } | 218 } |
| 219 | 219 |
| 220 NO_SANITIZE_ADDRESS | 220 NO_SANITIZE_ADDRESS |
| 221 void ThreadState::VisitAsanFakeStackForPointer(Visitor* visitor, Address ptr) { | 221 void ThreadState::VisitAsanFakeStackForPointer(Visitor* visitor, Address ptr) { |
| 222 #if defined(ADDRESS_SANITIZER) | 222 #if defined(ADDRESS_SANITIZER) |
| 223 Address* start = reinterpret_cast<Address*>(start_of_stack_); | 223 Address* start = reinterpret_cast<Address*>(start_of_stack_); |
| 224 Address* end = reinterpret_cast<Address*>(end_of_stack_); | 224 Address* end = reinterpret_cast<Address*>(end_of_stack_); |
| 225 Address* fake_frame_start = nullptr; | 225 Address* fake_frame_start = nullptr; |
| (...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 694 switch (gc_state) { | 694 switch (gc_state) { |
| 695 UNEXPECTED_GCSTATE(kNoGCScheduled); | 695 UNEXPECTED_GCSTATE(kNoGCScheduled); |
| 696 UNEXPECTED_GCSTATE(kIdleGCScheduled); | 696 UNEXPECTED_GCSTATE(kIdleGCScheduled); |
| 697 UNEXPECTED_GCSTATE(kPreciseGCScheduled); | 697 UNEXPECTED_GCSTATE(kPreciseGCScheduled); |
| 698 UNEXPECTED_GCSTATE(kFullGCScheduled); | 698 UNEXPECTED_GCSTATE(kFullGCScheduled); |
| 699 UNEXPECTED_GCSTATE(kGCRunning); | 699 UNEXPECTED_GCSTATE(kGCRunning); |
| 700 UNEXPECTED_GCSTATE(kSweeping); | 700 UNEXPECTED_GCSTATE(kSweeping); |
| 701 UNEXPECTED_GCSTATE(kSweepingAndIdleGCScheduled); | 701 UNEXPECTED_GCSTATE(kSweepingAndIdleGCScheduled); |
| 702 UNEXPECTED_GCSTATE(kSweepingAndPreciseGCScheduled); | 702 UNEXPECTED_GCSTATE(kSweepingAndPreciseGCScheduled); |
| 703 default: | 703 default: |
| 704 ASSERT_NOT_REACHED(); | 704 NOTREACHED(); |
| 705 return; | 705 return; |
| 706 } | 706 } |
| 707 } | 707 } |
| 708 | 708 |
| 709 #undef UNEXPECTED_GCSTATE | 709 #undef UNEXPECTED_GCSTATE |
| 710 | 710 |
| 711 } // namespace | 711 } // namespace |
| 712 | 712 |
| 713 #define VERIFY_STATE_TRANSITION(condition) \ | 713 #define VERIFY_STATE_TRANSITION(condition) \ |
| 714 if (UNLIKELY(!(condition))) \ | 714 if (UNLIKELY(!(condition))) \ |
| (...skipping 29 matching lines...) Expand all Loading... |
| 744 VERIFY_STATE_TRANSITION(gc_state_ == kGCRunning); | 744 VERIFY_STATE_TRANSITION(gc_state_ == kGCRunning); |
| 745 break; | 745 break; |
| 746 case kSweepingAndIdleGCScheduled: | 746 case kSweepingAndIdleGCScheduled: |
| 747 case kSweepingAndPreciseGCScheduled: | 747 case kSweepingAndPreciseGCScheduled: |
| 748 ASSERT(CheckThread()); | 748 ASSERT(CheckThread()); |
| 749 VERIFY_STATE_TRANSITION(gc_state_ == kSweeping || | 749 VERIFY_STATE_TRANSITION(gc_state_ == kSweeping || |
| 750 gc_state_ == kSweepingAndIdleGCScheduled || | 750 gc_state_ == kSweepingAndIdleGCScheduled || |
| 751 gc_state_ == kSweepingAndPreciseGCScheduled); | 751 gc_state_ == kSweepingAndPreciseGCScheduled); |
| 752 break; | 752 break; |
| 753 default: | 753 default: |
| 754 ASSERT_NOT_REACHED(); | 754 NOTREACHED(); |
| 755 } | 755 } |
| 756 gc_state_ = gc_state; | 756 gc_state_ = gc_state; |
| 757 } | 757 } |
| 758 | 758 |
| 759 #undef VERIFY_STATE_TRANSITION | 759 #undef VERIFY_STATE_TRANSITION |
| 760 | 760 |
| 761 void ThreadState::RunScheduledGC(BlinkGC::StackState stack_state) { | 761 void ThreadState::RunScheduledGC(BlinkGC::StackState stack_state) { |
| 762 ASSERT(CheckThread()); | 762 ASSERT(CheckThread()); |
| 763 if (stack_state != BlinkGC::kNoHeapPointersOnStack) | 763 if (stack_state != BlinkGC::kNoHeapPointersOnStack) |
| 764 return; | 764 return; |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1060 SetGCState(kNoGCScheduled); | 1060 SetGCState(kNoGCScheduled); |
| 1061 break; | 1061 break; |
| 1062 case kSweepingAndPreciseGCScheduled: | 1062 case kSweepingAndPreciseGCScheduled: |
| 1063 SetGCState(kPreciseGCScheduled); | 1063 SetGCState(kPreciseGCScheduled); |
| 1064 break; | 1064 break; |
| 1065 case kSweepingAndIdleGCScheduled: | 1065 case kSweepingAndIdleGCScheduled: |
| 1066 SetGCState(kNoGCScheduled); | 1066 SetGCState(kNoGCScheduled); |
| 1067 ScheduleIdleGC(); | 1067 ScheduleIdleGC(); |
| 1068 break; | 1068 break; |
| 1069 default: | 1069 default: |
| 1070 ASSERT_NOT_REACHED(); | 1070 NOTREACHED(); |
| 1071 } | 1071 } |
| 1072 } | 1072 } |
| 1073 | 1073 |
| 1074 #if DCHECK_IS_ON() | 1074 #if DCHECK_IS_ON() |
| 1075 BasePage* ThreadState::FindPageFromAddress(Address address) { | 1075 BasePage* ThreadState::FindPageFromAddress(Address address) { |
| 1076 for (int i = 0; i < BlinkGC::kNumberOfArenas; ++i) { | 1076 for (int i = 0; i < BlinkGC::kNumberOfArenas; ++i) { |
| 1077 if (BasePage* page = arenas_[i]->FindPageFromAddress(address)) | 1077 if (BasePage* page = arenas_[i]->FindPageFromAddress(address)) |
| 1078 return page; | 1078 return page; |
| 1079 } | 1079 } |
| 1080 return nullptr; | 1080 return nullptr; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1109 // When we are running under AddressSanitizer with | 1109 // When we are running under AddressSanitizer with |
| 1110 // detect_stack_use_after_return=1 then stack marker obtained from | 1110 // detect_stack_use_after_return=1 then stack marker obtained from |
| 1111 // SafePointScope will point into a fake stack. Detect this case by checking if | 1111 // SafePointScope will point into a fake stack. Detect this case by checking if |
| 1112 // it falls in between current stack frame and stack start and use an arbitrary | 1112 // it falls in between current stack frame and stack start and use an arbitrary |
| 1113 // high enough value for it. Don't adjust stack marker in any other case to | 1113 // high enough value for it. Don't adjust stack marker in any other case to |
| 1114 // match behavior of code running without AddressSanitizer. | 1114 // match behavior of code running without AddressSanitizer. |
| 1115 NO_SANITIZE_ADDRESS static void* AdjustScopeMarkerForAdressSanitizer( | 1115 NO_SANITIZE_ADDRESS static void* AdjustScopeMarkerForAdressSanitizer( |
| 1116 void* scope_marker) { | 1116 void* scope_marker) { |
| 1117 Address start = reinterpret_cast<Address>(WTF::GetStackStart()); | 1117 Address start = reinterpret_cast<Address>(WTF::GetStackStart()); |
| 1118 Address end = reinterpret_cast<Address>(&start); | 1118 Address end = reinterpret_cast<Address>(&start); |
| 1119 RELEASE_ASSERT(end < start); | 1119 CHECK_LT(end, start); |
| 1120 | 1120 |
| 1121 if (end <= scope_marker && scope_marker < start) | 1121 if (end <= scope_marker && scope_marker < start) |
| 1122 return scope_marker; | 1122 return scope_marker; |
| 1123 | 1123 |
| 1124 // 256 is as good an approximation as any else. | 1124 // 256 is as good an approximation as any else. |
| 1125 const size_t kBytesToCopy = sizeof(Address) * 256; | 1125 const size_t kBytesToCopy = sizeof(Address) * 256; |
| 1126 if (static_cast<size_t>(start - end) < kBytesToCopy) | 1126 if (static_cast<size_t>(start - end) < kBytesToCopy) |
| 1127 return start; | 1127 return start; |
| 1128 | 1128 |
| 1129 return end + kBytesToCopy; | 1129 return end + kBytesToCopy; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1192 heap_->HeapStats().IncreaseMarkedObjectSize(delta); | 1192 heap_->HeapStats().IncreaseMarkedObjectSize(delta); |
| 1193 } | 1193 } |
| 1194 | 1194 |
| 1195 void ThreadState::CopyStackUntilSafePointScope() { | 1195 void ThreadState::CopyStackUntilSafePointScope() { |
| 1196 if (!safe_point_scope_marker_ || | 1196 if (!safe_point_scope_marker_ || |
| 1197 stack_state_ == BlinkGC::kNoHeapPointersOnStack) | 1197 stack_state_ == BlinkGC::kNoHeapPointersOnStack) |
| 1198 return; | 1198 return; |
| 1199 | 1199 |
| 1200 Address* to = reinterpret_cast<Address*>(safe_point_scope_marker_); | 1200 Address* to = reinterpret_cast<Address*>(safe_point_scope_marker_); |
| 1201 Address* from = reinterpret_cast<Address*>(end_of_stack_); | 1201 Address* from = reinterpret_cast<Address*>(end_of_stack_); |
| 1202 RELEASE_ASSERT(from < to); | 1202 CHECK_LT(from, to); |
| 1203 RELEASE_ASSERT(to <= reinterpret_cast<Address*>(start_of_stack_)); | 1203 CHECK_LE(to, reinterpret_cast<Address*>(start_of_stack_)); |
| 1204 size_t slot_count = static_cast<size_t>(to - from); | 1204 size_t slot_count = static_cast<size_t>(to - from); |
| 1205 // Catch potential performance issues. | 1205 // Catch potential performance issues. |
| 1206 #if defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) | 1206 #if defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) |
| 1207 // ASan/LSan use more space on the stack and we therefore | 1207 // ASan/LSan use more space on the stack and we therefore |
| 1208 // increase the allowed stack copying for those builds. | 1208 // increase the allowed stack copying for those builds. |
| 1209 ASSERT(slot_count < 2048); | 1209 ASSERT(slot_count < 2048); |
| 1210 #else | 1210 #else |
| 1211 ASSERT(slot_count < 1024); | 1211 ASSERT(slot_count < 1024); |
| 1212 #endif | 1212 #endif |
| 1213 | 1213 |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1367 switch (type) { \ | 1367 switch (type) { \ |
| 1368 case SnapshotType::kHeapSnapshot: \ | 1368 case SnapshotType::kHeapSnapshot: \ |
| 1369 arenas_[BlinkGC::k##ArenaType##ArenaIndex]->TakeSnapshot( \ | 1369 arenas_[BlinkGC::k##ArenaType##ArenaIndex]->TakeSnapshot( \ |
| 1370 heaps_dump_name + "/" #ArenaType, info); \ | 1370 heaps_dump_name + "/" #ArenaType, info); \ |
| 1371 break; \ | 1371 break; \ |
| 1372 case SnapshotType::kFreelistSnapshot: \ | 1372 case SnapshotType::kFreelistSnapshot: \ |
| 1373 arenas_[BlinkGC::k##ArenaType##ArenaIndex]->TakeFreelistSnapshot( \ | 1373 arenas_[BlinkGC::k##ArenaType##ArenaIndex]->TakeFreelistSnapshot( \ |
| 1374 heaps_dump_name + "/" #ArenaType); \ | 1374 heaps_dump_name + "/" #ArenaType); \ |
| 1375 break; \ | 1375 break; \ |
| 1376 default: \ | 1376 default: \ |
| 1377 ASSERT_NOT_REACHED(); \ | 1377 NOTREACHED(); \ |
| 1378 } \ | 1378 } \ |
| 1379 } | 1379 } |
| 1380 | 1380 |
| 1381 SNAPSHOT_HEAP(NormalPage1); | 1381 SNAPSHOT_HEAP(NormalPage1); |
| 1382 SNAPSHOT_HEAP(NormalPage2); | 1382 SNAPSHOT_HEAP(NormalPage2); |
| 1383 SNAPSHOT_HEAP(NormalPage3); | 1383 SNAPSHOT_HEAP(NormalPage3); |
| 1384 SNAPSHOT_HEAP(NormalPage4); | 1384 SNAPSHOT_HEAP(NormalPage4); |
| 1385 SNAPSHOT_HEAP(EagerSweep); | 1385 SNAPSHOT_HEAP(EagerSweep); |
| 1386 SNAPSHOT_HEAP(Vector1); | 1386 SNAPSHOT_HEAP(Vector1); |
| 1387 SNAPSHOT_HEAP(Vector2); | 1387 SNAPSHOT_HEAP(Vector2); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1427 ->CreateMemoryAllocatorDumpForCurrentGC(classes_dump_name); | 1427 ->CreateMemoryAllocatorDumpForCurrentGC(classes_dump_name); |
| 1428 BlinkGCMemoryDumpProvider::Instance() | 1428 BlinkGCMemoryDumpProvider::Instance() |
| 1429 ->CurrentProcessMemoryDump() | 1429 ->CurrentProcessMemoryDump() |
| 1430 ->AddOwnershipEdge(classes_dump->guid(), heaps_dump->guid()); | 1430 ->AddOwnershipEdge(classes_dump->guid(), heaps_dump->guid()); |
| 1431 } | 1431 } |
| 1432 | 1432 |
| 1433 void ThreadState::CollectGarbage(BlinkGC::StackState stack_state, | 1433 void ThreadState::CollectGarbage(BlinkGC::StackState stack_state, |
| 1434 BlinkGC::GCType gc_type, | 1434 BlinkGC::GCType gc_type, |
| 1435 BlinkGC::GCReason reason) { | 1435 BlinkGC::GCReason reason) { |
| 1436 // Nested collectGarbage() invocations aren't supported. | 1436 // Nested collectGarbage() invocations aren't supported. |
| 1437 RELEASE_ASSERT(!IsGCForbidden()); | 1437 CHECK(!IsGCForbidden()); |
| 1438 CompleteSweep(); | 1438 CompleteSweep(); |
| 1439 | 1439 |
| 1440 GCForbiddenScope gc_forbidden_scope(this); | 1440 GCForbiddenScope gc_forbidden_scope(this); |
| 1441 | 1441 |
| 1442 { | 1442 { |
| 1443 // Access to the CrossThreadPersistentRegion has to be prevented while in | 1443 // Access to the CrossThreadPersistentRegion has to be prevented while in |
| 1444 // the marking phase because otherwise other threads may allocate or free | 1444 // the marking phase because otherwise other threads may allocate or free |
| 1445 // PersistentNodes and we can't handle that. | 1445 // PersistentNodes and we can't handle that. |
| 1446 CrossThreadPersistentRegion::LockScope persistent_lock( | 1446 CrossThreadPersistentRegion::LockScope persistent_lock( |
| 1447 ProcessHeap::GetCrossThreadPersistentRegion()); | 1447 ProcessHeap::GetCrossThreadPersistentRegion()); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1559 CollectGarbage(BlinkGC::kNoHeapPointersOnStack, BlinkGC::kGCWithSweep, | 1559 CollectGarbage(BlinkGC::kNoHeapPointersOnStack, BlinkGC::kGCWithSweep, |
| 1560 BlinkGC::kForcedGC); | 1560 BlinkGC::kForcedGC); |
| 1561 size_t live_objects = Heap().HeapStats().MarkedObjectSize(); | 1561 size_t live_objects = Heap().HeapStats().MarkedObjectSize(); |
| 1562 if (live_objects == previous_live_objects) | 1562 if (live_objects == previous_live_objects) |
| 1563 break; | 1563 break; |
| 1564 previous_live_objects = live_objects; | 1564 previous_live_objects = live_objects; |
| 1565 } | 1565 } |
| 1566 } | 1566 } |
| 1567 | 1567 |
| 1568 } // namespace blink | 1568 } // namespace blink |
| OLD | NEW |