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 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 | 228 |
229 ThreadState::ThreadState() | 229 ThreadState::ThreadState() |
230 : m_thread(currentThread()) | 230 : m_thread(currentThread()) |
231 , m_persistents(adoptPtr(new PersistentAnchor())) | 231 , m_persistents(adoptPtr(new PersistentAnchor())) |
232 , m_startOfStack(reinterpret_cast<intptr_t*>(getStackStart())) | 232 , m_startOfStack(reinterpret_cast<intptr_t*>(getStackStart())) |
233 , m_endOfStack(reinterpret_cast<intptr_t*>(getStackStart())) | 233 , m_endOfStack(reinterpret_cast<intptr_t*>(getStackStart())) |
234 , m_safePointScopeMarker(0) | 234 , m_safePointScopeMarker(0) |
235 , m_atSafePoint(false) | 235 , m_atSafePoint(false) |
236 , m_interruptors() | 236 , m_interruptors() |
237 , m_gcRequested(false) | 237 , m_gcRequested(false) |
| 238 , m_forcedForTesting(false) |
238 , m_sweepRequested(0) | 239 , m_sweepRequested(0) |
239 , m_sweepInProgress(false) | 240 , m_sweepInProgress(false) |
240 , m_noAllocationCount(0) | 241 , m_noAllocationCount(0) |
241 , m_inGC(false) | 242 , m_inGC(false) |
242 , m_heapContainsCache(adoptPtr(new HeapContainsCache())) | 243 , m_heapContainsCache(adoptPtr(new HeapContainsCache())) |
243 , m_isCleaningUp(false) | 244 , m_isCleaningUp(false) |
244 { | 245 { |
245 ASSERT(!**s_threadSpecific); | 246 ASSERT(!**s_threadSpecific); |
246 **s_threadSpecific = this; | 247 **s_threadSpecific = this; |
247 | 248 |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 checkThread(); | 491 checkThread(); |
491 m_gcRequested = true; | 492 m_gcRequested = true; |
492 } | 493 } |
493 | 494 |
494 void ThreadState::clearGCRequested() | 495 void ThreadState::clearGCRequested() |
495 { | 496 { |
496 checkThread(); | 497 checkThread(); |
497 m_gcRequested = false; | 498 m_gcRequested = false; |
498 } | 499 } |
499 | 500 |
| 501 void ThreadState::performPendingGC(StackState stackState) |
| 502 { |
| 503 if (stackState == NoHeapPointersOnStack && (gcRequested() || forcedForTestin
g())) { |
| 504 setForcedForTesting(false); |
| 505 Heap::collectGarbage(NoHeapPointersOnStack); |
| 506 } |
| 507 } |
| 508 |
| 509 void ThreadState::setForcedForTesting(bool value) |
| 510 { |
| 511 checkThread(); |
| 512 m_forcedForTesting = value; |
| 513 } |
| 514 |
| 515 bool ThreadState::forcedForTesting() |
| 516 { |
| 517 checkThread(); |
| 518 return m_forcedForTesting; |
| 519 } |
| 520 |
500 bool ThreadState::isConsistentForGC() | 521 bool ThreadState::isConsistentForGC() |
501 { | 522 { |
502 for (int i = 0; i < NumberOfHeaps; i++) { | 523 for (int i = 0; i < NumberOfHeaps; i++) { |
503 if (!m_heaps[i]->isConsistentForGC()) | 524 if (!m_heaps[i]->isConsistentForGC()) |
504 return false; | 525 return false; |
505 } | 526 } |
506 return true; | 527 return true; |
507 } | 528 } |
508 | 529 |
509 void ThreadState::makeConsistentForGC() | 530 void ThreadState::makeConsistentForGC() |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 } | 603 } |
583 | 604 |
584 void ThreadState::resumeThreads() | 605 void ThreadState::resumeThreads() |
585 { | 606 { |
586 s_safePointBarrier->resumeOthers(); | 607 s_safePointBarrier->resumeOthers(); |
587 } | 608 } |
588 | 609 |
589 void ThreadState::safePoint(StackState stackState) | 610 void ThreadState::safePoint(StackState stackState) |
590 { | 611 { |
591 checkThread(); | 612 checkThread(); |
592 if (stackState == NoHeapPointersOnStack && gcRequested()) | 613 performPendingGC(stackState); |
593 Heap::collectGarbage(NoHeapPointersOnStack); | |
594 m_stackState = stackState; | 614 m_stackState = stackState; |
595 s_safePointBarrier->checkAndPark(this); | 615 s_safePointBarrier->checkAndPark(this); |
596 m_stackState = HeapPointersOnStack; | 616 m_stackState = HeapPointersOnStack; |
597 } | 617 } |
598 | 618 |
599 #ifdef ADDRESS_SANITIZER | 619 #ifdef ADDRESS_SANITIZER |
600 // When we are running under AddressSanitizer with detect_stack_use_after_return
=1 | 620 // When we are running under AddressSanitizer with detect_stack_use_after_return
=1 |
601 // then stack marker obtained from SafePointScope will point into a fake stack. | 621 // then stack marker obtained from SafePointScope will point into a fake stack. |
602 // Detect this case by checking if it falls in between current stack frame | 622 // Detect this case by checking if it falls in between current stack frame |
603 // and stack start and use an arbitrary high enough value for it. | 623 // and stack start and use an arbitrary high enough value for it. |
(...skipping 17 matching lines...) Expand all Loading... |
621 } | 641 } |
622 #endif | 642 #endif |
623 | 643 |
624 void ThreadState::enterSafePoint(StackState stackState, void* scopeMarker) | 644 void ThreadState::enterSafePoint(StackState stackState, void* scopeMarker) |
625 { | 645 { |
626 #ifdef ADDRESS_SANITIZER | 646 #ifdef ADDRESS_SANITIZER |
627 if (stackState == HeapPointersOnStack) | 647 if (stackState == HeapPointersOnStack) |
628 scopeMarker = adjustScopeMarkerForAdressSanitizer(scopeMarker); | 648 scopeMarker = adjustScopeMarkerForAdressSanitizer(scopeMarker); |
629 #endif | 649 #endif |
630 ASSERT(stackState == NoHeapPointersOnStack || scopeMarker); | 650 ASSERT(stackState == NoHeapPointersOnStack || scopeMarker); |
631 if (stackState == NoHeapPointersOnStack && gcRequested()) | 651 performPendingGC(stackState); |
632 Heap::collectGarbage(NoHeapPointersOnStack); | |
633 checkThread(); | 652 checkThread(); |
634 ASSERT(!m_atSafePoint); | 653 ASSERT(!m_atSafePoint); |
635 m_atSafePoint = true; | 654 m_atSafePoint = true; |
636 m_stackState = stackState; | 655 m_stackState = stackState; |
637 m_safePointScopeMarker = scopeMarker; | 656 m_safePointScopeMarker = scopeMarker; |
638 s_safePointBarrier->enterSafePoint(this); | 657 s_safePointBarrier->enterSafePoint(this); |
639 } | 658 } |
640 | 659 |
641 void ThreadState::leaveSafePoint() | 660 void ThreadState::leaveSafePoint() |
642 { | 661 { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 state->safePoint(HeapPointersOnStack); | 737 state->safePoint(HeapPointersOnStack); |
719 } | 738 } |
720 | 739 |
721 ThreadState::AttachedThreadStateSet& ThreadState::attachedThreads() | 740 ThreadState::AttachedThreadStateSet& ThreadState::attachedThreads() |
722 { | 741 { |
723 DEFINE_STATIC_LOCAL(AttachedThreadStateSet, threads, ()); | 742 DEFINE_STATIC_LOCAL(AttachedThreadStateSet, threads, ()); |
724 return threads; | 743 return threads; |
725 } | 744 } |
726 | 745 |
727 } | 746 } |
OLD | NEW |