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 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 // declaration), so that subclasses can use it. | 507 // declaration), so that subclasses can use it. |
508 const int ThreadedTesterBase::numberOfThreads; | 508 const int ThreadedTesterBase::numberOfThreads; |
509 | 509 |
510 class ThreadedHeapTester : public ThreadedTesterBase { | 510 class ThreadedHeapTester : public ThreadedTesterBase { |
511 public: | 511 public: |
512 static void test() | 512 static void test() |
513 { | 513 { |
514 ThreadedTesterBase::test(new ThreadedHeapTester); | 514 ThreadedTesterBase::test(new ThreadedHeapTester); |
515 } | 515 } |
516 | 516 |
| 517 ~ThreadedHeapTester() override |
| 518 { |
| 519 // Verify that the threads cleared their CTPs when |
| 520 // terminating, preventing access to a finalized heap. |
| 521 for (auto& globalIntWrapper : m_crossPersistents) { |
| 522 ASSERT(globalIntWrapper.get()); |
| 523 EXPECT_FALSE(globalIntWrapper.get()->get()); |
| 524 } |
| 525 } |
| 526 |
517 protected: | 527 protected: |
518 using GlobalIntWrapperPersistent = CrossThreadPersistent<IntWrapper>; | 528 using GlobalIntWrapperPersistent = CrossThreadPersistent<IntWrapper>; |
519 | 529 |
| 530 Mutex m_mutex; |
| 531 Vector<OwnPtr<GlobalIntWrapperPersistent>> m_crossPersistents; |
| 532 |
520 PassOwnPtr<GlobalIntWrapperPersistent> createGlobalPersistent(int value) | 533 PassOwnPtr<GlobalIntWrapperPersistent> createGlobalPersistent(int value) |
521 { | 534 { |
522 return adoptPtr(new GlobalIntWrapperPersistent(IntWrapper::create(value)
)); | 535 return adoptPtr(new GlobalIntWrapperPersistent(IntWrapper::create(value)
)); |
523 } | 536 } |
524 | 537 |
| 538 void addGlobalPersistent() |
| 539 { |
| 540 MutexLocker lock(m_mutex); |
| 541 m_crossPersistents.append(createGlobalPersistent(0x2a2a2a2a)); |
| 542 } |
| 543 |
525 void runThread() override | 544 void runThread() override |
526 { | 545 { |
527 OwnPtr<GlobalIntWrapperPersistent> longLivingPersistent; | |
528 ThreadState::attachCurrentThread(false); | 546 ThreadState::attachCurrentThread(false); |
529 | 547 |
530 longLivingPersistent = createGlobalPersistent(0x2a2a2a2a); | 548 // Add a cross-thread persistent from this thread; the test object |
| 549 // verifies that it will have been cleared out after the threads |
| 550 // have all detached, running their termination GCs while doing so. |
| 551 addGlobalPersistent(); |
| 552 |
531 int gcCount = 0; | 553 int gcCount = 0; |
532 while (!done()) { | 554 while (!done()) { |
533 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); | 555 ThreadState::current()->safePoint(BlinkGC::NoHeapPointersOnStack); |
534 { | 556 { |
535 Persistent<IntWrapper> wrapper; | 557 Persistent<IntWrapper> wrapper; |
536 | 558 |
537 OwnPtr<GlobalIntWrapperPersistent> globalPersistent = createGlob
alPersistent(0x0ed0cabb); | 559 OwnPtr<GlobalIntWrapperPersistent> globalPersistent = createGlob
alPersistent(0x0ed0cabb); |
538 | 560 |
539 for (int i = 0; i < numberOfAllocations; i++) { | 561 for (int i = 0; i < numberOfAllocations; i++) { |
540 wrapper = IntWrapper::create(0x0bbac0de); | 562 wrapper = IntWrapper::create(0x0bbac0de); |
(...skipping 15 matching lines...) Expand all Loading... |
556 // it at the moment. Fix the crash and enable it. | 578 // it at the moment. Fix the crash and enable it. |
557 // ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, Bl
inkGC::TakeSnapshot, BlinkGC::ForcedGC); | 579 // ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, Bl
inkGC::TakeSnapshot, BlinkGC::ForcedGC); |
558 preciselyCollectGarbage(); | 580 preciselyCollectGarbage(); |
559 EXPECT_EQ(wrapper->value(), 0x0bbac0de); | 581 EXPECT_EQ(wrapper->value(), 0x0bbac0de); |
560 EXPECT_EQ((*globalPersistent)->value(), 0x0ed0cabb); | 582 EXPECT_EQ((*globalPersistent)->value(), 0x0ed0cabb); |
561 } | 583 } |
562 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | 584 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); |
563 testing::yieldCurrentThread(); | 585 testing::yieldCurrentThread(); |
564 } | 586 } |
565 | 587 |
566 // Intentionally leak the cross-thread persistent so as to verify | |
567 // that later GCs correctly handle cross-thread persistents that | |
568 // refer to finalized objects after their heaps have been detached | |
569 // and freed. | |
570 EXPECT_TRUE(longLivingPersistent.leakPtr()); | |
571 | |
572 ThreadState::detachCurrentThread(); | 588 ThreadState::detachCurrentThread(); |
573 atomicDecrement(&m_threadsToFinish); | 589 atomicDecrement(&m_threadsToFinish); |
574 } | 590 } |
575 }; | 591 }; |
576 | 592 |
577 class ThreadedWeaknessTester : public ThreadedTesterBase { | 593 class ThreadedWeaknessTester : public ThreadedTesterBase { |
578 public: | 594 public: |
579 static void test() | 595 static void test() |
580 { | 596 { |
581 ThreadedTesterBase::test(new ThreadedWeaknessTester); | 597 ThreadedTesterBase::test(new ThreadedWeaknessTester); |
(...skipping 6054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6636 conservativelyCollectGarbage(); | 6652 conservativelyCollectGarbage(); |
6637 EXPECT_EQ(wrapper, weakWrapper->value()); | 6653 EXPECT_EQ(wrapper, weakWrapper->value()); |
6638 // Stub out any stack reference. | 6654 // Stub out any stack reference. |
6639 wrapper = nullptr; | 6655 wrapper = nullptr; |
6640 } | 6656 } |
6641 preciselyCollectGarbage(); | 6657 preciselyCollectGarbage(); |
6642 EXPECT_EQ(nullptr, weakWrapper->value()); | 6658 EXPECT_EQ(nullptr, weakWrapper->value()); |
6643 } | 6659 } |
6644 | 6660 |
6645 } // namespace blink | 6661 } // namespace blink |
OLD | NEW |