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 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 static const int s_arraySize = 1000; | 371 static const int s_arraySize = 1000; |
372 int8_t m_array[s_arraySize]; | 372 int8_t m_array[s_arraySize]; |
373 }; | 373 }; |
374 | 374 |
375 // Do several GCs to make sure that later GCs don't free up old memory from | 375 // Do several GCs to make sure that later GCs don't free up old memory from |
376 // previously run tests in this process. | 376 // previously run tests in this process. |
377 static void clearOutOldGarbage() | 377 static void clearOutOldGarbage() |
378 { | 378 { |
379 while (true) { | 379 while (true) { |
380 size_t used = Heap::objectPayloadSizeForTesting(); | 380 size_t used = Heap::objectPayloadSizeForTesting(); |
381 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 381 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
382 if (Heap::objectPayloadSizeForTesting() >= used) | 382 if (Heap::objectPayloadSizeForTesting() >= used) |
383 break; | 383 break; |
384 } | 384 } |
385 } | 385 } |
386 | 386 |
387 class OffHeapInt : public RefCounted<OffHeapInt> { | 387 class OffHeapInt : public RefCounted<OffHeapInt> { |
388 public: | 388 public: |
389 static RefPtr<OffHeapInt> create(int x) | 389 static RefPtr<OffHeapInt> create(int x) |
390 { | 390 { |
391 return adoptRef(new OffHeapInt(x)); | 391 return adoptRef(new OffHeapInt(x)); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 for (int i = 0; i < numberOfAllocations; i++) { | 483 for (int i = 0; i < numberOfAllocations; i++) { |
484 wrapper = IntWrapper::create(0x0bbac0de); | 484 wrapper = IntWrapper::create(0x0bbac0de); |
485 if (!(i % 10)) { | 485 if (!(i % 10)) { |
486 globalPersistent = adoptPtr(new GlobalIntWrapperPersiste
nt(IntWrapper::create(0x0ed0cabb))); | 486 globalPersistent = adoptPtr(new GlobalIntWrapperPersiste
nt(IntWrapper::create(0x0ed0cabb))); |
487 } | 487 } |
488 SafePointScope scope(ThreadState::NoHeapPointersOnStack); | 488 SafePointScope scope(ThreadState::NoHeapPointersOnStack); |
489 Platform::current()->yieldCurrentThread(); | 489 Platform::current()->yieldCurrentThread(); |
490 } | 490 } |
491 | 491 |
492 if (gcCount < gcPerThread) { | 492 if (gcCount < gcPerThread) { |
493 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, Thr
eadState::GCWithSweep, Heap::ForcedGCForTesting); | 493 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, Thr
eadState::GCWithSweep, Heap::ForcedGC); |
494 gcCount++; | 494 gcCount++; |
495 atomicIncrement(&m_gcCount); | 495 atomicIncrement(&m_gcCount); |
496 } | 496 } |
497 | 497 |
498 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadS
tate::GCWithSweep, Heap::ForcedGCForTesting); | 498 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadS
tate::GCWithSweep, Heap::ForcedGC); |
499 EXPECT_EQ(wrapper->value(), 0x0bbac0de); | 499 EXPECT_EQ(wrapper->value(), 0x0bbac0de); |
500 EXPECT_EQ((*globalPersistent)->value(), 0x0ed0cabb); | 500 EXPECT_EQ((*globalPersistent)->value(), 0x0ed0cabb); |
501 } | 501 } |
502 SafePointScope scope(ThreadState::NoHeapPointersOnStack); | 502 SafePointScope scope(ThreadState::NoHeapPointersOnStack); |
503 Platform::current()->yieldCurrentThread(); | 503 Platform::current()->yieldCurrentThread(); |
504 } | 504 } |
505 ThreadState::detach(); | 505 ThreadState::detach(); |
506 atomicDecrement(&m_threadsToFinish); | 506 atomicDecrement(&m_threadsToFinish); |
507 } | 507 } |
508 }; | 508 }; |
(...skipping 18 matching lines...) Expand all Loading... |
527 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weak
Map2; | 527 PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weak
Map2; |
528 | 528 |
529 for (int i = 0; i < numberOfAllocations; i++) { | 529 for (int i = 0; i < numberOfAllocations; i++) { |
530 weakMap->add(static_cast<unsigned>(i), IntWrapper::create(0)
); | 530 weakMap->add(static_cast<unsigned>(i), IntWrapper::create(0)
); |
531 weakMap2.add(static_cast<unsigned>(i), IntWrapper::create(0)
); | 531 weakMap2.add(static_cast<unsigned>(i), IntWrapper::create(0)
); |
532 SafePointScope scope(ThreadState::NoHeapPointersOnStack); | 532 SafePointScope scope(ThreadState::NoHeapPointersOnStack); |
533 Platform::current()->yieldCurrentThread(); | 533 Platform::current()->yieldCurrentThread(); |
534 } | 534 } |
535 | 535 |
536 if (gcCount < gcPerThread) { | 536 if (gcCount < gcPerThread) { |
537 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, Thr
eadState::GCWithSweep, Heap::ForcedGCForTesting); | 537 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, Thr
eadState::GCWithSweep, Heap::ForcedGC); |
538 gcCount++; | 538 gcCount++; |
539 atomicIncrement(&m_gcCount); | 539 atomicIncrement(&m_gcCount); |
540 } | 540 } |
541 | 541 |
542 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadS
tate::GCWithSweep, Heap::ForcedGCForTesting); | 542 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadS
tate::GCWithSweep, Heap::ForcedGC); |
543 EXPECT_TRUE(weakMap->isEmpty()); | 543 EXPECT_TRUE(weakMap->isEmpty()); |
544 EXPECT_TRUE(weakMap2.isEmpty()); | 544 EXPECT_TRUE(weakMap2.isEmpty()); |
545 } | 545 } |
546 SafePointScope scope(ThreadState::NoHeapPointersOnStack); | 546 SafePointScope scope(ThreadState::NoHeapPointersOnStack); |
547 Platform::current()->yieldCurrentThread(); | 547 Platform::current()->yieldCurrentThread(); |
548 } | 548 } |
549 ThreadState::detach(); | 549 ThreadState::detach(); |
550 atomicDecrement(&m_threadsToFinish); | 550 atomicDecrement(&m_threadsToFinish); |
551 } | 551 } |
552 }; | 552 }; |
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1302 { | 1302 { |
1303 #if !ENABLE(OILPAN) | 1303 #if !ENABLE(OILPAN) |
1304 m_pointsBack->setBackPointer(0); | 1304 m_pointsBack->setBackPointer(0); |
1305 #endif | 1305 #endif |
1306 --s_aliveCount; | 1306 --s_aliveCount; |
1307 } | 1307 } |
1308 | 1308 |
1309 void doStuff(PassRefPtrWillBeRawPtr<SuperClass> targetPass, PointsBack* poin
tsBack, int superClassCount) | 1309 void doStuff(PassRefPtrWillBeRawPtr<SuperClass> targetPass, PointsBack* poin
tsBack, int superClassCount) |
1310 { | 1310 { |
1311 RefPtrWillBeRawPtr<SuperClass> target = targetPass; | 1311 RefPtrWillBeRawPtr<SuperClass> target = targetPass; |
1312 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGCForTesting); | 1312 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); |
1313 EXPECT_EQ(pointsBack, target->pointsBack()); | 1313 EXPECT_EQ(pointsBack, target->pointsBack()); |
1314 EXPECT_EQ(superClassCount, SuperClass::s_aliveCount); | 1314 EXPECT_EQ(superClassCount, SuperClass::s_aliveCount); |
1315 } | 1315 } |
1316 | 1316 |
1317 DEFINE_INLINE_VIRTUAL_TRACE() | 1317 DEFINE_INLINE_VIRTUAL_TRACE() |
1318 { | 1318 { |
1319 visitor->trace(m_pointsBack); | 1319 visitor->trace(m_pointsBack); |
1320 } | 1320 } |
1321 | 1321 |
1322 PointsBack* pointsBack() const { return m_pointsBack.get(); } | 1322 PointsBack* pointsBack() const { return m_pointsBack.get(); } |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1555 | 1555 |
1556 private: | 1556 private: |
1557 Persistent<IntWrapper>* m_wrapper; | 1557 Persistent<IntWrapper>* m_wrapper; |
1558 }; | 1558 }; |
1559 | 1559 |
1560 TEST(HeapTest, Transition) | 1560 TEST(HeapTest, Transition) |
1561 { | 1561 { |
1562 { | 1562 { |
1563 RefPtrWillBePersistent<TransitionRefCounted> refCounted = TransitionRefC
ounted::create(); | 1563 RefPtrWillBePersistent<TransitionRefCounted> refCounted = TransitionRefC
ounted::create(); |
1564 EXPECT_EQ(1, TransitionRefCounted::s_aliveCount); | 1564 EXPECT_EQ(1, TransitionRefCounted::s_aliveCount); |
1565 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 1565 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
1566 EXPECT_EQ(1, TransitionRefCounted::s_aliveCount); | 1566 EXPECT_EQ(1, TransitionRefCounted::s_aliveCount); |
1567 } | 1567 } |
1568 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 1568 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
1569 EXPECT_EQ(0, TransitionRefCounted::s_aliveCount); | 1569 EXPECT_EQ(0, TransitionRefCounted::s_aliveCount); |
1570 | 1570 |
1571 RefPtrWillBePersistent<PointsBack> pointsBack1 = PointsBack::create(); | 1571 RefPtrWillBePersistent<PointsBack> pointsBack1 = PointsBack::create(); |
1572 RefPtrWillBePersistent<PointsBack> pointsBack2 = PointsBack::create(); | 1572 RefPtrWillBePersistent<PointsBack> pointsBack2 = PointsBack::create(); |
1573 RefPtrWillBePersistent<SuperClass> superClass = SuperClass::create(pointsBac
k1); | 1573 RefPtrWillBePersistent<SuperClass> superClass = SuperClass::create(pointsBac
k1); |
1574 RefPtrWillBePersistent<SubClass> subClass = SubClass::create(pointsBack2); | 1574 RefPtrWillBePersistent<SubClass> subClass = SubClass::create(pointsBack2); |
1575 EXPECT_EQ(2, PointsBack::s_aliveCount); | 1575 EXPECT_EQ(2, PointsBack::s_aliveCount); |
1576 EXPECT_EQ(2, SuperClass::s_aliveCount); | 1576 EXPECT_EQ(2, SuperClass::s_aliveCount); |
1577 EXPECT_EQ(1, SubClass::s_aliveCount); | 1577 EXPECT_EQ(1, SubClass::s_aliveCount); |
1578 EXPECT_EQ(1, SubData::s_aliveCount); | 1578 EXPECT_EQ(1, SubData::s_aliveCount); |
1579 | 1579 |
1580 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 1580 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
1581 EXPECT_EQ(0, TransitionRefCounted::s_aliveCount); | 1581 EXPECT_EQ(0, TransitionRefCounted::s_aliveCount); |
1582 EXPECT_EQ(2, PointsBack::s_aliveCount); | 1582 EXPECT_EQ(2, PointsBack::s_aliveCount); |
1583 EXPECT_EQ(2, SuperClass::s_aliveCount); | 1583 EXPECT_EQ(2, SuperClass::s_aliveCount); |
1584 EXPECT_EQ(1, SubClass::s_aliveCount); | 1584 EXPECT_EQ(1, SubClass::s_aliveCount); |
1585 EXPECT_EQ(1, SubData::s_aliveCount); | 1585 EXPECT_EQ(1, SubData::s_aliveCount); |
1586 | 1586 |
1587 superClass->doStuff(superClass.release(), pointsBack1.get(), 2); | 1587 superClass->doStuff(superClass.release(), pointsBack1.get(), 2); |
1588 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 1588 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
1589 EXPECT_EQ(2, PointsBack::s_aliveCount); | 1589 EXPECT_EQ(2, PointsBack::s_aliveCount); |
1590 EXPECT_EQ(1, SuperClass::s_aliveCount); | 1590 EXPECT_EQ(1, SuperClass::s_aliveCount); |
1591 EXPECT_EQ(1, SubClass::s_aliveCount); | 1591 EXPECT_EQ(1, SubClass::s_aliveCount); |
1592 EXPECT_EQ(1, SubData::s_aliveCount); | 1592 EXPECT_EQ(1, SubData::s_aliveCount); |
1593 EXPECT_EQ(0, pointsBack1->backPointer()); | 1593 EXPECT_EQ(0, pointsBack1->backPointer()); |
1594 | 1594 |
1595 pointsBack1.release(); | 1595 pointsBack1.release(); |
1596 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 1596 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
1597 EXPECT_EQ(1, PointsBack::s_aliveCount); | 1597 EXPECT_EQ(1, PointsBack::s_aliveCount); |
1598 EXPECT_EQ(1, SuperClass::s_aliveCount); | 1598 EXPECT_EQ(1, SuperClass::s_aliveCount); |
1599 EXPECT_EQ(1, SubClass::s_aliveCount); | 1599 EXPECT_EQ(1, SubClass::s_aliveCount); |
1600 EXPECT_EQ(1, SubData::s_aliveCount); | 1600 EXPECT_EQ(1, SubData::s_aliveCount); |
1601 | 1601 |
1602 subClass->doStuff(subClass.release(), pointsBack2.get(), 1); | 1602 subClass->doStuff(subClass.release(), pointsBack2.get(), 1); |
1603 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 1603 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
1604 EXPECT_EQ(1, PointsBack::s_aliveCount); | 1604 EXPECT_EQ(1, PointsBack::s_aliveCount); |
1605 EXPECT_EQ(0, SuperClass::s_aliveCount); | 1605 EXPECT_EQ(0, SuperClass::s_aliveCount); |
1606 EXPECT_EQ(0, SubClass::s_aliveCount); | 1606 EXPECT_EQ(0, SubClass::s_aliveCount); |
1607 EXPECT_EQ(0, SubData::s_aliveCount); | 1607 EXPECT_EQ(0, SubData::s_aliveCount); |
1608 EXPECT_EQ(0, pointsBack2->backPointer()); | 1608 EXPECT_EQ(0, pointsBack2->backPointer()); |
1609 | 1609 |
1610 pointsBack2.release(); | 1610 pointsBack2.release(); |
1611 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 1611 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
1612 EXPECT_EQ(0, PointsBack::s_aliveCount); | 1612 EXPECT_EQ(0, PointsBack::s_aliveCount); |
1613 EXPECT_EQ(0, SuperClass::s_aliveCount); | 1613 EXPECT_EQ(0, SuperClass::s_aliveCount); |
1614 EXPECT_EQ(0, SubClass::s_aliveCount); | 1614 EXPECT_EQ(0, SubClass::s_aliveCount); |
1615 EXPECT_EQ(0, SubData::s_aliveCount); | 1615 EXPECT_EQ(0, SubData::s_aliveCount); |
1616 | 1616 |
1617 EXPECT_TRUE(superClass == subClass); | 1617 EXPECT_TRUE(superClass == subClass); |
1618 } | 1618 } |
1619 | 1619 |
1620 TEST(HeapTest, Threading) | 1620 TEST(HeapTest, Threading) |
1621 { | 1621 { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1658 | 1658 |
1659 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), s
lack); | 1659 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), s
lack); |
1660 if (testPagesAllocated) | 1660 if (testPagesAllocated) |
1661 EXPECT_EQ(Heap::allocatedSpace(), blinkPageSize * 2); | 1661 EXPECT_EQ(Heap::allocatedSpace(), blinkPageSize * 2); |
1662 | 1662 |
1663 EXPECT_EQ(alloc32->get(0), 40); | 1663 EXPECT_EQ(alloc32->get(0), 40); |
1664 EXPECT_EQ(alloc32->get(31), 40); | 1664 EXPECT_EQ(alloc32->get(31), 40); |
1665 EXPECT_EQ(alloc64->get(0), 27); | 1665 EXPECT_EQ(alloc64->get(0), 27); |
1666 EXPECT_EQ(alloc64->get(63), 27); | 1666 EXPECT_EQ(alloc64->get(63), 27); |
1667 | 1667 |
1668 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGCForTesting); | 1668 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); |
1669 | 1669 |
1670 EXPECT_EQ(alloc32->get(0), 40); | 1670 EXPECT_EQ(alloc32->get(0), 40); |
1671 EXPECT_EQ(alloc32->get(31), 40); | 1671 EXPECT_EQ(alloc32->get(31), 40); |
1672 EXPECT_EQ(alloc64->get(0), 27); | 1672 EXPECT_EQ(alloc64->get(0), 27); |
1673 EXPECT_EQ(alloc64->get(63), 27); | 1673 EXPECT_EQ(alloc64->get(63), 27); |
1674 } | 1674 } |
1675 | 1675 |
1676 clearOutOldGarbage(); | 1676 clearOutOldGarbage(); |
1677 size_t total = 0; | 1677 size_t total = 0; |
1678 size_t slack = 0; | 1678 size_t slack = 0; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1769 EXPECT_EQ(42, array->at(42)); | 1769 EXPECT_EQ(42, array->at(42)); |
1770 EXPECT_EQ(0, array->at(128)); | 1770 EXPECT_EQ(0, array->at(128)); |
1771 EXPECT_EQ(999 % 128, array->at(999)); | 1771 EXPECT_EQ(999 % 128, array->at(999)); |
1772 } | 1772 } |
1773 | 1773 |
1774 TEST(HeapTest, SimplePersistent) | 1774 TEST(HeapTest, SimplePersistent) |
1775 { | 1775 { |
1776 Persistent<TraceCounter> traceCounter = TraceCounter::create(); | 1776 Persistent<TraceCounter> traceCounter = TraceCounter::create(); |
1777 EXPECT_EQ(0, traceCounter->traceCount()); | 1777 EXPECT_EQ(0, traceCounter->traceCount()); |
1778 | 1778 |
1779 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 1779 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
1780 EXPECT_EQ(1, traceCounter->traceCount()); | 1780 EXPECT_EQ(1, traceCounter->traceCount()); |
1781 | 1781 |
1782 Persistent<ClassWithMember> classWithMember = ClassWithMember::create(); | 1782 Persistent<ClassWithMember> classWithMember = ClassWithMember::create(); |
1783 EXPECT_EQ(0, classWithMember->traceCount()); | 1783 EXPECT_EQ(0, classWithMember->traceCount()); |
1784 | 1784 |
1785 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 1785 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
1786 EXPECT_EQ(1, classWithMember->traceCount()); | 1786 EXPECT_EQ(1, classWithMember->traceCount()); |
1787 EXPECT_EQ(2, traceCounter->traceCount()); | 1787 EXPECT_EQ(2, traceCounter->traceCount()); |
1788 } | 1788 } |
1789 | 1789 |
1790 TEST(HeapTest, SimpleFinalization) | 1790 TEST(HeapTest, SimpleFinalization) |
1791 { | 1791 { |
1792 { | 1792 { |
1793 Persistent<SimpleFinalizedObject> finalized = SimpleFinalizedObject::cre
ate(); | 1793 Persistent<SimpleFinalizedObject> finalized = SimpleFinalizedObject::cre
ate(); |
1794 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 1794 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |
1795 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 1795 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
1796 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 1796 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |
1797 } | 1797 } |
1798 | 1798 |
1799 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 1799 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
1800 EXPECT_EQ(1, SimpleFinalizedObject::s_destructorCalls); | 1800 EXPECT_EQ(1, SimpleFinalizedObject::s_destructorCalls); |
1801 } | 1801 } |
1802 | 1802 |
1803 // FIXME: Lazy sweeping is disabled in non-oilpan builds. | 1803 // FIXME: Lazy sweeping is disabled in non-oilpan builds. |
1804 #if ENABLE(OILPAN) | 1804 #if ENABLE(OILPAN) |
1805 TEST(HeapTest, LazySweepingPages) | 1805 TEST(HeapTest, LazySweepingPages) |
1806 { | 1806 { |
1807 clearOutOldGarbage(); | 1807 clearOutOldGarbage(); |
1808 | 1808 |
1809 SimpleFinalizedObject::s_destructorCalls = 0; | 1809 SimpleFinalizedObject::s_destructorCalls = 0; |
1810 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 1810 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |
1811 for (int i = 0; i < 1000; i++) | 1811 for (int i = 0; i < 1000; i++) |
1812 SimpleFinalizedObject::create(); | 1812 SimpleFinalizedObject::create(); |
1813 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
outSweep, Heap::ForcedGCForTesting); | 1813 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
outSweep, Heap::ForcedGC); |
1814 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 1814 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |
1815 for (int i = 0; i < 10000; i++) | 1815 for (int i = 0; i < 10000; i++) |
1816 SimpleFinalizedObject::create(); | 1816 SimpleFinalizedObject::create(); |
1817 EXPECT_EQ(1000, SimpleFinalizedObject::s_destructorCalls); | 1817 EXPECT_EQ(1000, SimpleFinalizedObject::s_destructorCalls); |
1818 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 1818 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
1819 EXPECT_EQ(11000, SimpleFinalizedObject::s_destructorCalls); | 1819 EXPECT_EQ(11000, SimpleFinalizedObject::s_destructorCalls); |
1820 } | 1820 } |
1821 | 1821 |
1822 TEST(HeapTest, LazySweepingLargeObjectPages) | 1822 TEST(HeapTest, LazySweepingLargeObjectPages) |
1823 { | 1823 { |
1824 clearOutOldGarbage(); | 1824 clearOutOldGarbage(); |
1825 | 1825 |
1826 LargeHeapObject::s_destructorCalls = 0; | 1826 LargeHeapObject::s_destructorCalls = 0; |
1827 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); | 1827 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); |
1828 for (int i = 0; i < 10; i++) | 1828 for (int i = 0; i < 10; i++) |
1829 LargeHeapObject::create(); | 1829 LargeHeapObject::create(); |
1830 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
outSweep, Heap::ForcedGCForTesting); | 1830 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
outSweep, Heap::ForcedGC); |
1831 for (int i = 0; i < 10; i++) { | 1831 for (int i = 0; i < 10; i++) { |
1832 LargeHeapObject::create(); | 1832 LargeHeapObject::create(); |
1833 EXPECT_EQ(i + 1, LargeHeapObject::s_destructorCalls); | 1833 EXPECT_EQ(i + 1, LargeHeapObject::s_destructorCalls); |
1834 } | 1834 } |
1835 LargeHeapObject::create(); | 1835 LargeHeapObject::create(); |
1836 LargeHeapObject::create(); | 1836 LargeHeapObject::create(); |
1837 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); | 1837 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); |
1838 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
outSweep, Heap::ForcedGCForTesting); | 1838 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
outSweep, Heap::ForcedGC); |
1839 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); | 1839 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); |
1840 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 1840 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
1841 EXPECT_EQ(22, LargeHeapObject::s_destructorCalls); | 1841 EXPECT_EQ(22, LargeHeapObject::s_destructorCalls); |
1842 } | 1842 } |
1843 #endif | 1843 #endif |
1844 | 1844 |
1845 TEST(HeapTest, Finalization) | 1845 TEST(HeapTest, Finalization) |
1846 { | 1846 { |
1847 { | 1847 { |
1848 HeapTestSubClass* t1 = HeapTestSubClass::create(); | 1848 HeapTestSubClass* t1 = HeapTestSubClass::create(); |
1849 HeapTestSubClass* t2 = HeapTestSubClass::create(); | 1849 HeapTestSubClass* t2 = HeapTestSubClass::create(); |
1850 HeapTestSuperClass* t3 = HeapTestSuperClass::create(); | 1850 HeapTestSuperClass* t3 = HeapTestSuperClass::create(); |
1851 // FIXME(oilpan): Ignore unused variables. | 1851 // FIXME(oilpan): Ignore unused variables. |
1852 (void)t1; | 1852 (void)t1; |
1853 (void)t2; | 1853 (void)t2; |
1854 (void)t3; | 1854 (void)t3; |
1855 } | 1855 } |
1856 // Nothing is marked so the GC should free everything and call | 1856 // Nothing is marked so the GC should free everything and call |
1857 // the finalizer on all three objects. | 1857 // the finalizer on all three objects. |
1858 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 1858 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
1859 EXPECT_EQ(2, HeapTestSubClass::s_destructorCalls); | 1859 EXPECT_EQ(2, HeapTestSubClass::s_destructorCalls); |
1860 EXPECT_EQ(3, HeapTestSuperClass::s_destructorCalls); | 1860 EXPECT_EQ(3, HeapTestSuperClass::s_destructorCalls); |
1861 // Destructors not called again when GCing again. | 1861 // Destructors not called again when GCing again. |
1862 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 1862 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
1863 EXPECT_EQ(2, HeapTestSubClass::s_destructorCalls); | 1863 EXPECT_EQ(2, HeapTestSubClass::s_destructorCalls); |
1864 EXPECT_EQ(3, HeapTestSuperClass::s_destructorCalls); | 1864 EXPECT_EQ(3, HeapTestSuperClass::s_destructorCalls); |
1865 } | 1865 } |
1866 | 1866 |
1867 TEST(HeapTest, TypedHeapSanity) | 1867 TEST(HeapTest, TypedHeapSanity) |
1868 { | 1868 { |
1869 // We use TraceCounter for allocating an object on the general heap. | 1869 // We use TraceCounter for allocating an object on the general heap. |
1870 Persistent<TraceCounter> generalHeapObject = TraceCounter::create(); | 1870 Persistent<TraceCounter> generalHeapObject = TraceCounter::create(); |
1871 Persistent<IntNode> typedHeapObject = IntNode::create(0); | 1871 Persistent<IntNode> typedHeapObject = IntNode::create(0); |
1872 EXPECT_NE(pageFromObject(generalHeapObject.get()), | 1872 EXPECT_NE(pageFromObject(generalHeapObject.get()), |
(...skipping 13 matching lines...) Expand all Loading... |
1886 } | 1886 } |
1887 | 1887 |
1888 TEST(HeapTest, Members) | 1888 TEST(HeapTest, Members) |
1889 { | 1889 { |
1890 Bar::s_live = 0; | 1890 Bar::s_live = 0; |
1891 { | 1891 { |
1892 Persistent<Baz> h1; | 1892 Persistent<Baz> h1; |
1893 Persistent<Baz> h2; | 1893 Persistent<Baz> h2; |
1894 { | 1894 { |
1895 h1 = Baz::create(Bar::create()); | 1895 h1 = Baz::create(Bar::create()); |
1896 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGCForTesting); | 1896 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); |
1897 EXPECT_EQ(1u, Bar::s_live); | 1897 EXPECT_EQ(1u, Bar::s_live); |
1898 h2 = Baz::create(Bar::create()); | 1898 h2 = Baz::create(Bar::create()); |
1899 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGCForTesting); | 1899 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); |
1900 EXPECT_EQ(2u, Bar::s_live); | 1900 EXPECT_EQ(2u, Bar::s_live); |
1901 } | 1901 } |
1902 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 1902 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
1903 EXPECT_EQ(2u, Bar::s_live); | 1903 EXPECT_EQ(2u, Bar::s_live); |
1904 h1->clear(); | 1904 h1->clear(); |
1905 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 1905 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
1906 EXPECT_EQ(1u, Bar::s_live); | 1906 EXPECT_EQ(1u, Bar::s_live); |
1907 } | 1907 } |
1908 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 1908 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
1909 EXPECT_EQ(0u, Bar::s_live); | 1909 EXPECT_EQ(0u, Bar::s_live); |
1910 } | 1910 } |
1911 | 1911 |
1912 TEST(HeapTest, MarkTest) | 1912 TEST(HeapTest, MarkTest) |
1913 { | 1913 { |
1914 { | 1914 { |
1915 Bar::s_live = 0; | 1915 Bar::s_live = 0; |
1916 Persistent<Bar> bar = Bar::create(); | 1916 Persistent<Bar> bar = Bar::create(); |
1917 ASSERT(ThreadState::current()->findPageFromAddress(bar)); | 1917 ASSERT(ThreadState::current()->findPageFromAddress(bar)); |
1918 EXPECT_EQ(1u, Bar::s_live); | 1918 EXPECT_EQ(1u, Bar::s_live); |
1919 { | 1919 { |
1920 Foo* foo = Foo::create(bar); | 1920 Foo* foo = Foo::create(bar); |
1921 ASSERT(ThreadState::current()->findPageFromAddress(foo)); | 1921 ASSERT(ThreadState::current()->findPageFromAddress(foo)); |
1922 EXPECT_EQ(2u, Bar::s_live); | 1922 EXPECT_EQ(2u, Bar::s_live); |
1923 EXPECT_TRUE(reinterpret_cast<Address>(foo) != reinterpret_cast<Addre
ss>(bar.get())); | 1923 EXPECT_TRUE(reinterpret_cast<Address>(foo) != reinterpret_cast<Addre
ss>(bar.get())); |
1924 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::
GCWithSweep, Heap::ForcedGCForTesting); | 1924 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::
GCWithSweep, Heap::ForcedGC); |
1925 EXPECT_TRUE(foo != bar); // To make sure foo is kept alive. | 1925 EXPECT_TRUE(foo != bar); // To make sure foo is kept alive. |
1926 EXPECT_EQ(2u, Bar::s_live); | 1926 EXPECT_EQ(2u, Bar::s_live); |
1927 } | 1927 } |
1928 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 1928 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
1929 EXPECT_EQ(1u, Bar::s_live); | 1929 EXPECT_EQ(1u, Bar::s_live); |
1930 } | 1930 } |
1931 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 1931 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
1932 EXPECT_EQ(0u, Bar::s_live); | 1932 EXPECT_EQ(0u, Bar::s_live); |
1933 } | 1933 } |
1934 | 1934 |
1935 TEST(HeapTest, DeepTest) | 1935 TEST(HeapTest, DeepTest) |
1936 { | 1936 { |
1937 const unsigned depth = 100000; | 1937 const unsigned depth = 100000; |
1938 Bar::s_live = 0; | 1938 Bar::s_live = 0; |
1939 { | 1939 { |
1940 Bar* bar = Bar::create(); | 1940 Bar* bar = Bar::create(); |
1941 ASSERT(ThreadState::current()->findPageFromAddress(bar)); | 1941 ASSERT(ThreadState::current()->findPageFromAddress(bar)); |
1942 Foo* foo = Foo::create(bar); | 1942 Foo* foo = Foo::create(bar); |
1943 ASSERT(ThreadState::current()->findPageFromAddress(foo)); | 1943 ASSERT(ThreadState::current()->findPageFromAddress(foo)); |
1944 EXPECT_EQ(2u, Bar::s_live); | 1944 EXPECT_EQ(2u, Bar::s_live); |
1945 for (unsigned i = 0; i < depth; i++) { | 1945 for (unsigned i = 0; i < depth; i++) { |
1946 Foo* foo2 = Foo::create(foo); | 1946 Foo* foo2 = Foo::create(foo); |
1947 foo = foo2; | 1947 foo = foo2; |
1948 ASSERT(ThreadState::current()->findPageFromAddress(foo)); | 1948 ASSERT(ThreadState::current()->findPageFromAddress(foo)); |
1949 } | 1949 } |
1950 EXPECT_EQ(depth + 2, Bar::s_live); | 1950 EXPECT_EQ(depth + 2, Bar::s_live); |
1951 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGCForTesting); | 1951 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); |
1952 EXPECT_TRUE(foo != bar); // To make sure foo and bar are kept alive. | 1952 EXPECT_TRUE(foo != bar); // To make sure foo and bar are kept alive. |
1953 EXPECT_EQ(depth + 2, Bar::s_live); | 1953 EXPECT_EQ(depth + 2, Bar::s_live); |
1954 } | 1954 } |
1955 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 1955 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
1956 EXPECT_EQ(0u, Bar::s_live); | 1956 EXPECT_EQ(0u, Bar::s_live); |
1957 } | 1957 } |
1958 | 1958 |
1959 TEST(HeapTest, WideTest) | 1959 TEST(HeapTest, WideTest) |
1960 { | 1960 { |
1961 Bar::s_live = 0; | 1961 Bar::s_live = 0; |
1962 { | 1962 { |
1963 Bars* bars = Bars::create(); | 1963 Bars* bars = Bars::create(); |
1964 unsigned width = Bars::width; | 1964 unsigned width = Bars::width; |
1965 EXPECT_EQ(width + 1, Bar::s_live); | 1965 EXPECT_EQ(width + 1, Bar::s_live); |
1966 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGCForTesting); | 1966 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); |
1967 EXPECT_EQ(width + 1, Bar::s_live); | 1967 EXPECT_EQ(width + 1, Bar::s_live); |
1968 // Use bars here to make sure that it will be on the stack | 1968 // Use bars here to make sure that it will be on the stack |
1969 // for the conservative stack scan to find. | 1969 // for the conservative stack scan to find. |
1970 EXPECT_EQ(width, bars->getWidth()); | 1970 EXPECT_EQ(width, bars->getWidth()); |
1971 } | 1971 } |
1972 EXPECT_EQ(Bars::width + 1, Bar::s_live); | 1972 EXPECT_EQ(Bars::width + 1, Bar::s_live); |
1973 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 1973 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
1974 EXPECT_EQ(0u, Bar::s_live); | 1974 EXPECT_EQ(0u, Bar::s_live); |
1975 } | 1975 } |
1976 | 1976 |
1977 TEST(HeapTest, HashMapOfMembers) | 1977 TEST(HeapTest, HashMapOfMembers) |
1978 { | 1978 { |
1979 IntWrapper::s_destructorCalls = 0; | 1979 IntWrapper::s_destructorCalls = 0; |
1980 | 1980 |
1981 clearOutOldGarbage(); | 1981 clearOutOldGarbage(); |
1982 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); | 1982 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); |
1983 { | 1983 { |
1984 typedef HeapHashMap< | 1984 typedef HeapHashMap< |
1985 Member<IntWrapper>, | 1985 Member<IntWrapper>, |
1986 Member<IntWrapper>, | 1986 Member<IntWrapper>, |
1987 DefaultHash<Member<IntWrapper>>::Hash, | 1987 DefaultHash<Member<IntWrapper>>::Hash, |
1988 HashTraits<Member<IntWrapper>>, | 1988 HashTraits<Member<IntWrapper>>, |
1989 HashTraits<Member<IntWrapper>>> HeapObjectIdentityMap; | 1989 HashTraits<Member<IntWrapper>>> HeapObjectIdentityMap; |
1990 | 1990 |
1991 Persistent<HeapObjectIdentityMap> map = new HeapObjectIdentityMap(); | 1991 Persistent<HeapObjectIdentityMap> map = new HeapObjectIdentityMap(); |
1992 | 1992 |
1993 map->clear(); | 1993 map->clear(); |
1994 size_t afterSetWasCreated = Heap::objectPayloadSizeForTesting(); | 1994 size_t afterSetWasCreated = Heap::objectPayloadSizeForTesting(); |
1995 EXPECT_TRUE(afterSetWasCreated > initialObjectPayloadSize); | 1995 EXPECT_TRUE(afterSetWasCreated > initialObjectPayloadSize); |
1996 | 1996 |
1997 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 1997 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
1998 size_t afterGC = Heap::objectPayloadSizeForTesting(); | 1998 size_t afterGC = Heap::objectPayloadSizeForTesting(); |
1999 EXPECT_EQ(afterGC, afterSetWasCreated); | 1999 EXPECT_EQ(afterGC, afterSetWasCreated); |
2000 | 2000 |
2001 // If the additions below cause garbage collections, these | 2001 // If the additions below cause garbage collections, these |
2002 // pointers should be found by conservative stack scanning. | 2002 // pointers should be found by conservative stack scanning. |
2003 IntWrapper* one(IntWrapper::create(1)); | 2003 IntWrapper* one(IntWrapper::create(1)); |
2004 IntWrapper* anotherOne(IntWrapper::create(1)); | 2004 IntWrapper* anotherOne(IntWrapper::create(1)); |
2005 | 2005 |
2006 map->add(one, one); | 2006 map->add(one, one); |
2007 | 2007 |
2008 size_t afterOneAdd = Heap::objectPayloadSizeForTesting(); | 2008 size_t afterOneAdd = Heap::objectPayloadSizeForTesting(); |
2009 EXPECT_TRUE(afterOneAdd > afterGC); | 2009 EXPECT_TRUE(afterOneAdd > afterGC); |
2010 | 2010 |
2011 HeapObjectIdentityMap::iterator it(map->begin()); | 2011 HeapObjectIdentityMap::iterator it(map->begin()); |
2012 HeapObjectIdentityMap::iterator it2(map->begin()); | 2012 HeapObjectIdentityMap::iterator it2(map->begin()); |
2013 ++it; | 2013 ++it; |
2014 ++it2; | 2014 ++it2; |
2015 | 2015 |
2016 map->add(anotherOne, one); | 2016 map->add(anotherOne, one); |
2017 | 2017 |
2018 // The addition above can cause an allocation of a new | 2018 // The addition above can cause an allocation of a new |
2019 // backing store. We therefore garbage collect before | 2019 // backing store. We therefore garbage collect before |
2020 // taking the heap stats in order to get rid of the old | 2020 // taking the heap stats in order to get rid of the old |
2021 // backing store. We make sure to not use conservative | 2021 // backing store. We make sure to not use conservative |
2022 // stack scanning as that could find a pointer to the | 2022 // stack scanning as that could find a pointer to the |
2023 // old backing. | 2023 // old backing. |
2024 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 2024 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
2025 size_t afterAddAndGC = Heap::objectPayloadSizeForTesting(); | 2025 size_t afterAddAndGC = Heap::objectPayloadSizeForTesting(); |
2026 EXPECT_TRUE(afterAddAndGC >= afterOneAdd); | 2026 EXPECT_TRUE(afterAddAndGC >= afterOneAdd); |
2027 | 2027 |
2028 EXPECT_EQ(map->size(), 2u); // Two different wrappings of '1' are distin
ct. | 2028 EXPECT_EQ(map->size(), 2u); // Two different wrappings of '1' are distin
ct. |
2029 | 2029 |
2030 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 2030 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
2031 EXPECT_TRUE(map->contains(one)); | 2031 EXPECT_TRUE(map->contains(one)); |
2032 EXPECT_TRUE(map->contains(anotherOne)); | 2032 EXPECT_TRUE(map->contains(anotherOne)); |
2033 | 2033 |
2034 IntWrapper* gotten(map->get(one)); | 2034 IntWrapper* gotten(map->get(one)); |
2035 EXPECT_EQ(gotten->value(), one->value()); | 2035 EXPECT_EQ(gotten->value(), one->value()); |
2036 EXPECT_EQ(gotten, one); | 2036 EXPECT_EQ(gotten, one); |
2037 | 2037 |
2038 size_t afterGC2 = Heap::objectPayloadSizeForTesting(); | 2038 size_t afterGC2 = Heap::objectPayloadSizeForTesting(); |
2039 EXPECT_EQ(afterGC2, afterAddAndGC); | 2039 EXPECT_EQ(afterGC2, afterAddAndGC); |
2040 | 2040 |
2041 IntWrapper* dozen = 0; | 2041 IntWrapper* dozen = 0; |
2042 | 2042 |
2043 for (int i = 1; i < 1000; i++) { // 999 iterations. | 2043 for (int i = 1; i < 1000; i++) { // 999 iterations. |
2044 IntWrapper* iWrapper(IntWrapper::create(i)); | 2044 IntWrapper* iWrapper(IntWrapper::create(i)); |
2045 IntWrapper* iSquared(IntWrapper::create(i * i)); | 2045 IntWrapper* iSquared(IntWrapper::create(i * i)); |
2046 map->add(iWrapper, iSquared); | 2046 map->add(iWrapper, iSquared); |
2047 if (i == 12) | 2047 if (i == 12) |
2048 dozen = iWrapper; | 2048 dozen = iWrapper; |
2049 } | 2049 } |
2050 size_t afterAdding1000 = Heap::objectPayloadSizeForTesting(); | 2050 size_t afterAdding1000 = Heap::objectPayloadSizeForTesting(); |
2051 EXPECT_TRUE(afterAdding1000 > afterGC2); | 2051 EXPECT_TRUE(afterAdding1000 > afterGC2); |
2052 | 2052 |
2053 IntWrapper* gross(map->get(dozen)); | 2053 IntWrapper* gross(map->get(dozen)); |
2054 EXPECT_EQ(gross->value(), 144); | 2054 EXPECT_EQ(gross->value(), 144); |
2055 | 2055 |
2056 // This should clear out any junk backings created by all the adds. | 2056 // This should clear out any junk backings created by all the adds. |
2057 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 2057 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
2058 size_t afterGC3 = Heap::objectPayloadSizeForTesting(); | 2058 size_t afterGC3 = Heap::objectPayloadSizeForTesting(); |
2059 EXPECT_TRUE(afterGC3 <= afterAdding1000); | 2059 EXPECT_TRUE(afterGC3 <= afterAdding1000); |
2060 } | 2060 } |
2061 | 2061 |
2062 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 2062 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
2063 // The objects 'one', anotherOne, and the 999 other pairs. | 2063 // The objects 'one', anotherOne, and the 999 other pairs. |
2064 EXPECT_EQ(IntWrapper::s_destructorCalls, 2000); | 2064 EXPECT_EQ(IntWrapper::s_destructorCalls, 2000); |
2065 size_t afterGC4 = Heap::objectPayloadSizeForTesting(); | 2065 size_t afterGC4 = Heap::objectPayloadSizeForTesting(); |
2066 EXPECT_EQ(afterGC4, initialObjectPayloadSize); | 2066 EXPECT_EQ(afterGC4, initialObjectPayloadSize); |
2067 } | 2067 } |
2068 | 2068 |
2069 TEST(HeapTest, NestedAllocation) | 2069 TEST(HeapTest, NestedAllocation) |
2070 { | 2070 { |
2071 clearOutOldGarbage(); | 2071 clearOutOldGarbage(); |
2072 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); | 2072 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2124 clearOutOldGarbage(); | 2124 clearOutOldGarbage(); |
2125 EXPECT_TRUE(Heap::allocatedSpace() == afterAllocation); | 2125 EXPECT_TRUE(Heap::allocatedSpace() == afterAllocation); |
2126 EXPECT_EQ(10, IntWrapper::s_destructorCalls); | 2126 EXPECT_EQ(10, IntWrapper::s_destructorCalls); |
2127 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); | 2127 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); |
2128 } | 2128 } |
2129 clearOutOldGarbage(); | 2129 clearOutOldGarbage(); |
2130 EXPECT_TRUE(initialObjectPayloadSize == Heap::objectPayloadSizeForTesting())
; | 2130 EXPECT_TRUE(initialObjectPayloadSize == Heap::objectPayloadSizeForTesting())
; |
2131 EXPECT_TRUE(initialAllocatedSpace == Heap::allocatedSpace()); | 2131 EXPECT_TRUE(initialAllocatedSpace == Heap::allocatedSpace()); |
2132 EXPECT_EQ(11, IntWrapper::s_destructorCalls); | 2132 EXPECT_EQ(11, IntWrapper::s_destructorCalls); |
2133 EXPECT_EQ(11, LargeHeapObject::s_destructorCalls); | 2133 EXPECT_EQ(11, LargeHeapObject::s_destructorCalls); |
2134 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 2134 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
2135 } | 2135 } |
2136 | 2136 |
2137 typedef std::pair<Member<IntWrapper>, int> PairWrappedUnwrapped; | 2137 typedef std::pair<Member<IntWrapper>, int> PairWrappedUnwrapped; |
2138 typedef std::pair<int, Member<IntWrapper>> PairUnwrappedWrapped; | 2138 typedef std::pair<int, Member<IntWrapper>> PairUnwrappedWrapped; |
2139 typedef std::pair<WeakMember<IntWrapper>, Member<IntWrapper>> PairWeakStrong; | 2139 typedef std::pair<WeakMember<IntWrapper>, Member<IntWrapper>> PairWeakStrong; |
2140 typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper>> PairStrongWeak; | 2140 typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper>> PairStrongWeak; |
2141 typedef std::pair<WeakMember<IntWrapper>, int> PairWeakUnwrapped; | 2141 typedef std::pair<WeakMember<IntWrapper>, int> PairWeakUnwrapped; |
2142 typedef std::pair<int, WeakMember<IntWrapper>> PairUnwrappedWeak; | 2142 typedef std::pair<int, WeakMember<IntWrapper>> PairUnwrappedWeak; |
2143 | 2143 |
2144 class Container : public GarbageCollected<Container> { | 2144 class Container : public GarbageCollected<Container> { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2242 IntWrapper* one = IntWrapper::create(1); | 2242 IntWrapper* one = IntWrapper::create(1); |
2243 IntWrapper* two = IntWrapper::create(2); | 2243 IntWrapper* two = IntWrapper::create(2); |
2244 IntWrapper* three = IntWrapper::create(3); | 2244 IntWrapper* three = IntWrapper::create(3); |
2245 IntWrapper* four = IntWrapper::create(4); | 2245 IntWrapper* four = IntWrapper::create(4); |
2246 IntWrapper* five = IntWrapper::create(5); | 2246 IntWrapper* five = IntWrapper::create(5); |
2247 IntWrapper* six = IntWrapper::create(6); | 2247 IntWrapper* six = IntWrapper::create(6); |
2248 { | 2248 { |
2249 HeapVector<Member<IntWrapper>, 2> vector; | 2249 HeapVector<Member<IntWrapper>, 2> vector; |
2250 vector.append(one); | 2250 vector.append(one); |
2251 vector.append(two); | 2251 vector.append(two); |
2252 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGCForTesting); | 2252 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); |
2253 EXPECT_TRUE(vector.contains(one)); | 2253 EXPECT_TRUE(vector.contains(one)); |
2254 EXPECT_TRUE(vector.contains(two)); | 2254 EXPECT_TRUE(vector.contains(two)); |
2255 | 2255 |
2256 vector.append(three); | 2256 vector.append(three); |
2257 vector.append(four); | 2257 vector.append(four); |
2258 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGCForTesting); | 2258 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); |
2259 EXPECT_TRUE(vector.contains(one)); | 2259 EXPECT_TRUE(vector.contains(one)); |
2260 EXPECT_TRUE(vector.contains(two)); | 2260 EXPECT_TRUE(vector.contains(two)); |
2261 EXPECT_TRUE(vector.contains(three)); | 2261 EXPECT_TRUE(vector.contains(three)); |
2262 EXPECT_TRUE(vector.contains(four)); | 2262 EXPECT_TRUE(vector.contains(four)); |
2263 | 2263 |
2264 vector.shrink(1); | 2264 vector.shrink(1); |
2265 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGCForTesting); | 2265 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); |
2266 EXPECT_TRUE(vector.contains(one)); | 2266 EXPECT_TRUE(vector.contains(one)); |
2267 EXPECT_FALSE(vector.contains(two)); | 2267 EXPECT_FALSE(vector.contains(two)); |
2268 EXPECT_FALSE(vector.contains(three)); | 2268 EXPECT_FALSE(vector.contains(three)); |
2269 EXPECT_FALSE(vector.contains(four)); | 2269 EXPECT_FALSE(vector.contains(four)); |
2270 } | 2270 } |
2271 { | 2271 { |
2272 HeapVector<Member<IntWrapper>, 2> vector1; | 2272 HeapVector<Member<IntWrapper>, 2> vector1; |
2273 HeapVector<Member<IntWrapper>, 2> vector2; | 2273 HeapVector<Member<IntWrapper>, 2> vector2; |
2274 | 2274 |
2275 vector1.append(one); | 2275 vector1.append(one); |
2276 vector2.append(two); | 2276 vector2.append(two); |
2277 vector1.swap(vector2); | 2277 vector1.swap(vector2); |
2278 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGCForTesting); | 2278 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); |
2279 EXPECT_TRUE(vector1.contains(two)); | 2279 EXPECT_TRUE(vector1.contains(two)); |
2280 EXPECT_TRUE(vector2.contains(one)); | 2280 EXPECT_TRUE(vector2.contains(one)); |
2281 } | 2281 } |
2282 { | 2282 { |
2283 HeapVector<Member<IntWrapper>, 2> vector1; | 2283 HeapVector<Member<IntWrapper>, 2> vector1; |
2284 HeapVector<Member<IntWrapper>, 2> vector2; | 2284 HeapVector<Member<IntWrapper>, 2> vector2; |
2285 | 2285 |
2286 vector1.append(one); | 2286 vector1.append(one); |
2287 vector1.append(two); | 2287 vector1.append(two); |
2288 vector2.append(three); | 2288 vector2.append(three); |
2289 vector2.append(four); | 2289 vector2.append(four); |
2290 vector2.append(five); | 2290 vector2.append(five); |
2291 vector2.append(six); | 2291 vector2.append(six); |
2292 vector1.swap(vector2); | 2292 vector1.swap(vector2); |
2293 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGCForTesting); | 2293 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); |
2294 EXPECT_TRUE(vector1.contains(three)); | 2294 EXPECT_TRUE(vector1.contains(three)); |
2295 EXPECT_TRUE(vector1.contains(four)); | 2295 EXPECT_TRUE(vector1.contains(four)); |
2296 EXPECT_TRUE(vector1.contains(five)); | 2296 EXPECT_TRUE(vector1.contains(five)); |
2297 EXPECT_TRUE(vector1.contains(six)); | 2297 EXPECT_TRUE(vector1.contains(six)); |
2298 EXPECT_TRUE(vector2.contains(one)); | 2298 EXPECT_TRUE(vector2.contains(one)); |
2299 EXPECT_TRUE(vector2.contains(two)); | 2299 EXPECT_TRUE(vector2.contains(two)); |
2300 } | 2300 } |
2301 } | 2301 } |
2302 | 2302 |
2303 TEST(HeapTest, HeapVectorShrinkCapacity) | 2303 TEST(HeapTest, HeapVectorShrinkCapacity) |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2470 vectorUW2->append(PairUnwrappedWrapped(105, &*fiveD)); | 2470 vectorUW2->append(PairUnwrappedWrapped(105, &*fiveD)); |
2471 dequeUW->append(PairUnwrappedWrapped(1, &*oneF)); | 2471 dequeUW->append(PairUnwrappedWrapped(1, &*oneF)); |
2472 dequeUW2->append(PairUnwrappedWrapped(103, &*threeF)); | 2472 dequeUW2->append(PairUnwrappedWrapped(103, &*threeF)); |
2473 dequeUW2->append(PairUnwrappedWrapped(104, &*fourF)); | 2473 dequeUW2->append(PairUnwrappedWrapped(104, &*fourF)); |
2474 dequeUW2->append(PairUnwrappedWrapped(105, &*fiveF)); | 2474 dequeUW2->append(PairUnwrappedWrapped(105, &*fiveF)); |
2475 | 2475 |
2476 EXPECT_TRUE(dequeContains(*deque, oneB)); | 2476 EXPECT_TRUE(dequeContains(*deque, oneB)); |
2477 | 2477 |
2478 // Collect garbage. This should change nothing since we are keeping | 2478 // Collect garbage. This should change nothing since we are keeping |
2479 // alive the IntWrapper objects with on-stack pointers. | 2479 // alive the IntWrapper objects with on-stack pointers. |
2480 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::
GCWithSweep, Heap::ForcedGCForTesting); | 2480 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::
GCWithSweep, Heap::ForcedGC); |
2481 | 2481 |
2482 EXPECT_TRUE(dequeContains(*deque, oneB)); | 2482 EXPECT_TRUE(dequeContains(*deque, oneB)); |
2483 | 2483 |
2484 EXPECT_EQ(0u, memberMember->size()); | 2484 EXPECT_EQ(0u, memberMember->size()); |
2485 EXPECT_EQ(4u, memberMember2->size()); | 2485 EXPECT_EQ(4u, memberMember2->size()); |
2486 EXPECT_EQ(4u, primitiveMember->size()); | 2486 EXPECT_EQ(4u, primitiveMember->size()); |
2487 EXPECT_EQ(4u, memberPrimitive->size()); | 2487 EXPECT_EQ(4u, memberPrimitive->size()); |
2488 EXPECT_EQ(1u, set->size()); | 2488 EXPECT_EQ(1u, set->size()); |
2489 EXPECT_EQ(4u, set2->size()); | 2489 EXPECT_EQ(4u, set2->size()); |
2490 EXPECT_EQ(1u, set3->size()); | 2490 EXPECT_EQ(1u, set3->size()); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2592 EXPECT_TRUE(dequeContains(*dequeWU, PairWrappedUnwrapped(&*fiveE, 45
))); | 2592 EXPECT_TRUE(dequeContains(*dequeWU, PairWrappedUnwrapped(&*fiveE, 45
))); |
2593 EXPECT_TRUE(dequeContains(*dequeWU2, PairWrappedUnwrapped(&*oneE, 42
))); | 2593 EXPECT_TRUE(dequeContains(*dequeWU2, PairWrappedUnwrapped(&*oneE, 42
))); |
2594 EXPECT_FALSE(dequeContains(*dequeWU2, PairWrappedUnwrapped(&*threeE,
43))); | 2594 EXPECT_FALSE(dequeContains(*dequeWU2, PairWrappedUnwrapped(&*threeE,
43))); |
2595 EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(103, &*thre
eF))); | 2595 EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(103, &*thre
eF))); |
2596 EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(104, &*four
F))); | 2596 EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(104, &*four
F))); |
2597 EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(105, &*five
F))); | 2597 EXPECT_TRUE(dequeContains(*dequeUW, PairUnwrappedWrapped(105, &*five
F))); |
2598 EXPECT_TRUE(dequeContains(*dequeUW2, PairUnwrappedWrapped(1, &*oneF)
)); | 2598 EXPECT_TRUE(dequeContains(*dequeUW2, PairUnwrappedWrapped(1, &*oneF)
)); |
2599 EXPECT_FALSE(dequeContains(*dequeUW2, PairUnwrappedWrapped(103, &*th
reeF))); | 2599 EXPECT_FALSE(dequeContains(*dequeUW2, PairUnwrappedWrapped(103, &*th
reeF))); |
2600 } | 2600 } |
2601 | 2601 |
2602 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 2602 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
2603 | 2603 |
2604 EXPECT_EQ(4u, memberMember->size()); | 2604 EXPECT_EQ(4u, memberMember->size()); |
2605 EXPECT_EQ(0u, memberMember2->size()); | 2605 EXPECT_EQ(0u, memberMember2->size()); |
2606 EXPECT_EQ(4u, primitiveMember->size()); | 2606 EXPECT_EQ(4u, primitiveMember->size()); |
2607 EXPECT_EQ(4u, memberPrimitive->size()); | 2607 EXPECT_EQ(4u, memberPrimitive->size()); |
2608 EXPECT_EQ(4u, set->size()); | 2608 EXPECT_EQ(4u, set->size()); |
2609 EXPECT_EQ(1u, set2->size()); | 2609 EXPECT_EQ(1u, set2->size()); |
2610 EXPECT_EQ(1u, set3->size()); | 2610 EXPECT_EQ(1u, set3->size()); |
2611 EXPECT_EQ(2u, vector->size()); | 2611 EXPECT_EQ(2u, vector->size()); |
2612 EXPECT_EQ(1u, vector2->size()); | 2612 EXPECT_EQ(1u, vector2->size()); |
(...skipping 13 matching lines...) Expand all Loading... |
2626 EXPECT_TRUE(set->contains(two)); | 2626 EXPECT_TRUE(set->contains(two)); |
2627 EXPECT_FALSE(set->contains(oneB)); | 2627 EXPECT_FALSE(set->contains(oneB)); |
2628 EXPECT_TRUE(set2->contains(oneB)); | 2628 EXPECT_TRUE(set2->contains(oneB)); |
2629 EXPECT_TRUE(set3->contains(oneB)); | 2629 EXPECT_TRUE(set3->contains(oneB)); |
2630 EXPECT_EQ(2u, set3->find(oneB)->value); | 2630 EXPECT_EQ(2u, set3->find(oneB)->value); |
2631 EXPECT_EQ(3, vector->at(0)->value()); | 2631 EXPECT_EQ(3, vector->at(0)->value()); |
2632 EXPECT_EQ(4, vector->at(1)->value()); | 2632 EXPECT_EQ(4, vector->at(1)->value()); |
2633 EXPECT_EQ(3, deque->begin()->get()->value()); | 2633 EXPECT_EQ(3, deque->begin()->get()->value()); |
2634 } | 2634 } |
2635 | 2635 |
2636 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 2636 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
2637 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 2637 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
2638 | 2638 |
2639 EXPECT_EQ(4u, memberMember->size()); | 2639 EXPECT_EQ(4u, memberMember->size()); |
2640 EXPECT_EQ(4u, primitiveMember->size()); | 2640 EXPECT_EQ(4u, primitiveMember->size()); |
2641 EXPECT_EQ(4u, memberPrimitive->size()); | 2641 EXPECT_EQ(4u, memberPrimitive->size()); |
2642 EXPECT_EQ(4u, set->size()); | 2642 EXPECT_EQ(4u, set->size()); |
2643 EXPECT_EQ(1u, set2->size()); | 2643 EXPECT_EQ(1u, set2->size()); |
2644 EXPECT_EQ(2u, vector->size()); | 2644 EXPECT_EQ(2u, vector->size()); |
2645 EXPECT_EQ(1u, vector2->size()); | 2645 EXPECT_EQ(1u, vector2->size()); |
2646 EXPECT_EQ(3u, vectorWU->size()); | 2646 EXPECT_EQ(3u, vectorWU->size()); |
2647 EXPECT_EQ(1u, vectorWU2->size()); | 2647 EXPECT_EQ(1u, vectorWU2->size()); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2727 EXPECT_EQ(2u, weakWeak->size()); | 2727 EXPECT_EQ(2u, weakWeak->size()); |
2728 EXPECT_EQ(4u, weakSet->size()); | 2728 EXPECT_EQ(4u, weakSet->size()); |
2729 EXPECT_EQ(4u, weakCountedSet->size()); | 2729 EXPECT_EQ(4u, weakCountedSet->size()); |
2730 EXPECT_EQ(3u, weakCountedSet->find(two)->value); | 2730 EXPECT_EQ(3u, weakCountedSet->find(two)->value); |
2731 weakCountedSet->remove(two); | 2731 weakCountedSet->remove(two); |
2732 EXPECT_EQ(2u, weakCountedSet->find(two)->value); | 2732 EXPECT_EQ(2u, weakCountedSet->find(two)->value); |
2733 } | 2733 } |
2734 | 2734 |
2735 keepNumbersAlive[0] = nullptr; | 2735 keepNumbersAlive[0] = nullptr; |
2736 | 2736 |
2737 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 2737 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
2738 | 2738 |
2739 EXPECT_EQ(0u, weakStrong->size()); | 2739 EXPECT_EQ(0u, weakStrong->size()); |
2740 EXPECT_EQ(0u, strongWeak->size()); | 2740 EXPECT_EQ(0u, strongWeak->size()); |
2741 EXPECT_EQ(0u, weakWeak->size()); | 2741 EXPECT_EQ(0u, weakWeak->size()); |
2742 EXPECT_EQ(2u, weakSet->size()); | 2742 EXPECT_EQ(2u, weakSet->size()); |
2743 EXPECT_EQ(2u, weakCountedSet->size()); | 2743 EXPECT_EQ(2u, weakCountedSet->size()); |
2744 } | 2744 } |
2745 | 2745 |
2746 template<typename Set> | 2746 template<typename Set> |
2747 void orderedSetHelper(bool strong) | 2747 void orderedSetHelper(bool strong) |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2827 EXPECT_EQ(constSet.rend(), creverse); | 2827 EXPECT_EQ(constSet.rend(), creverse); |
2828 | 2828 |
2829 typename Set::iterator iX(set2->begin()); | 2829 typename Set::iterator iX(set2->begin()); |
2830 EXPECT_EQ(set2->end(), iX); | 2830 EXPECT_EQ(set2->end(), iX); |
2831 | 2831 |
2832 if (strong) | 2832 if (strong) |
2833 set1->remove(keepNumbersAlive[0]); | 2833 set1->remove(keepNumbersAlive[0]); |
2834 | 2834 |
2835 keepNumbersAlive[0] = nullptr; | 2835 keepNumbersAlive[0] = nullptr; |
2836 | 2836 |
2837 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 2837 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
2838 | 2838 |
2839 EXPECT_EQ(2u + (strong ? 1u : 0u), set1->size()); | 2839 EXPECT_EQ(2u + (strong ? 1u : 0u), set1->size()); |
2840 | 2840 |
2841 EXPECT_EQ(2 + (strong ? 0 : 1), IntWrapper::s_destructorCalls); | 2841 EXPECT_EQ(2 + (strong ? 0 : 1), IntWrapper::s_destructorCalls); |
2842 | 2842 |
2843 typename Set::iterator i2(set1->begin()); | 2843 typename Set::iterator i2(set1->begin()); |
2844 if (strong) { | 2844 if (strong) { |
2845 EXPECT_EQ(0, (*i2)->value()); | 2845 EXPECT_EQ(0, (*i2)->value()); |
2846 ++i2; | 2846 ++i2; |
2847 EXPECT_NE(set1->end(), i2); | 2847 EXPECT_NE(set1->end(), i2); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2916 Persistent<RefMap> refMap(new RefMap()); | 2916 Persistent<RefMap> refMap(new RefMap()); |
2917 | 2917 |
2918 Persistent<IntWrapper> luck(IntWrapper::create(103)); | 2918 Persistent<IntWrapper> luck(IntWrapper::create(103)); |
2919 | 2919 |
2920 int baseLine, refBaseLine; | 2920 int baseLine, refBaseLine; |
2921 | 2921 |
2922 { | 2922 { |
2923 Map stackMap; | 2923 Map stackMap; |
2924 RefMap stackRefMap; | 2924 RefMap stackRefMap; |
2925 | 2925 |
2926 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 2926 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
2927 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 2927 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
2928 | 2928 |
2929 stackMap.add(IntWrapper::create(42), ThingWithDestructor(1729)); | 2929 stackMap.add(IntWrapper::create(42), ThingWithDestructor(1729)); |
2930 stackMap.add(luck, ThingWithDestructor(8128)); | 2930 stackMap.add(luck, ThingWithDestructor(8128)); |
2931 stackRefMap.add(IntWrapper::create(42), RefCountedAndGarbageCollected::c
reate()); | 2931 stackRefMap.add(IntWrapper::create(42), RefCountedAndGarbageCollected::c
reate()); |
2932 stackRefMap.add(luck, RefCountedAndGarbageCollected::create()); | 2932 stackRefMap.add(luck, RefCountedAndGarbageCollected::create()); |
2933 | 2933 |
2934 baseLine = ThingWithDestructor::s_liveThingsWithDestructor; | 2934 baseLine = ThingWithDestructor::s_liveThingsWithDestructor; |
2935 refBaseLine = RefCountedAndGarbageCollected::s_destructorCalls; | 2935 refBaseLine = RefCountedAndGarbageCollected::s_destructorCalls; |
2936 | 2936 |
2937 // Although the heap maps are on-stack, we can't expect prompt | 2937 // Although the heap maps are on-stack, we can't expect prompt |
2938 // finalization of the elements, so when they go out of scope here we | 2938 // finalization of the elements, so when they go out of scope here we |
2939 // will not necessarily have called the relevant destructors. | 2939 // will not necessarily have called the relevant destructors. |
2940 } | 2940 } |
2941 | 2941 |
2942 // The RefCountedAndGarbageCollected things need an extra GC to discover | 2942 // The RefCountedAndGarbageCollected things need an extra GC to discover |
2943 // that they are no longer ref counted. | 2943 // that they are no longer ref counted. |
2944 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 2944 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
2945 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 2945 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
2946 EXPECT_EQ(baseLine - 2, ThingWithDestructor::s_liveThingsWithDestructor); | 2946 EXPECT_EQ(baseLine - 2, ThingWithDestructor::s_liveThingsWithDestructor); |
2947 EXPECT_EQ(refBaseLine + 2, RefCountedAndGarbageCollected::s_destructorCalls)
; | 2947 EXPECT_EQ(refBaseLine + 2, RefCountedAndGarbageCollected::s_destructorCalls)
; |
2948 | 2948 |
2949 // Now use maps kept alive with persistents. Here we don't expect any | 2949 // Now use maps kept alive with persistents. Here we don't expect any |
2950 // destructors to be called before there have been GCs. | 2950 // destructors to be called before there have been GCs. |
2951 | 2951 |
2952 map->add(IntWrapper::create(42), ThingWithDestructor(1729)); | 2952 map->add(IntWrapper::create(42), ThingWithDestructor(1729)); |
2953 map->add(luck, ThingWithDestructor(8128)); | 2953 map->add(luck, ThingWithDestructor(8128)); |
2954 refMap->add(IntWrapper::create(42), RefCountedAndGarbageCollected::create())
; | 2954 refMap->add(IntWrapper::create(42), RefCountedAndGarbageCollected::create())
; |
2955 refMap->add(luck, RefCountedAndGarbageCollected::create()); | 2955 refMap->add(luck, RefCountedAndGarbageCollected::create()); |
2956 | 2956 |
2957 baseLine = ThingWithDestructor::s_liveThingsWithDestructor; | 2957 baseLine = ThingWithDestructor::s_liveThingsWithDestructor; |
2958 refBaseLine = RefCountedAndGarbageCollected::s_destructorCalls; | 2958 refBaseLine = RefCountedAndGarbageCollected::s_destructorCalls; |
2959 | 2959 |
2960 luck.clear(); | 2960 luck.clear(); |
2961 if (clearMaps) { | 2961 if (clearMaps) { |
2962 map->clear(); // Clear map. | 2962 map->clear(); // Clear map. |
2963 refMap->clear(); // Clear map. | 2963 refMap->clear(); // Clear map. |
2964 } else { | 2964 } else { |
2965 map.clear(); // Clear Persistent handle, not map. | 2965 map.clear(); // Clear Persistent handle, not map. |
2966 refMap.clear(); // Clear Persistent handle, not map. | 2966 refMap.clear(); // Clear Persistent handle, not map. |
2967 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 2967 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
2968 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 2968 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
2969 } | 2969 } |
2970 | 2970 |
2971 EXPECT_EQ(baseLine - 2, ThingWithDestructor::s_liveThingsWithDestructor); | 2971 EXPECT_EQ(baseLine - 2, ThingWithDestructor::s_liveThingsWithDestructor); |
2972 | 2972 |
2973 // Need a GC to make sure that the RefCountedAndGarbageCollected thing | 2973 // Need a GC to make sure that the RefCountedAndGarbageCollected thing |
2974 // noticies it's been decremented to zero. | 2974 // noticies it's been decremented to zero. |
2975 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 2975 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
2976 EXPECT_EQ(refBaseLine + 2, RefCountedAndGarbageCollected::s_destructorCalls)
; | 2976 EXPECT_EQ(refBaseLine + 2, RefCountedAndGarbageCollected::s_destructorCalls)
; |
2977 } | 2977 } |
2978 | 2978 |
2979 TEST(HeapTest, HeapMapDestructor) | 2979 TEST(HeapTest, HeapMapDestructor) |
2980 { | 2980 { |
2981 heapMapDestructorHelper(true); | 2981 heapMapDestructorHelper(true); |
2982 heapMapDestructorHelper(false); | 2982 heapMapDestructorHelper(false); |
2983 } | 2983 } |
2984 | 2984 |
2985 typedef HeapHashSet<PairWeakStrong> WeakStrongSet; | 2985 typedef HeapHashSet<PairWeakStrong> WeakStrongSet; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3084 weakStrong->add(PairWeakStrong(&*two, &*two)); | 3084 weakStrong->add(PairWeakStrong(&*two, &*two)); |
3085 strongWeak->add(PairStrongWeak(&*two, IntWrapper::create(1))); | 3085 strongWeak->add(PairStrongWeak(&*two, IntWrapper::create(1))); |
3086 strongWeak->add(PairStrongWeak(&*two, &*two)); | 3086 strongWeak->add(PairStrongWeak(&*two, &*two)); |
3087 weakUnwrapped->add(PairWeakUnwrapped(IntWrapper::create(1), 2)); | 3087 weakUnwrapped->add(PairWeakUnwrapped(IntWrapper::create(1), 2)); |
3088 weakUnwrapped->add(PairWeakUnwrapped(&*two, 2)); | 3088 weakUnwrapped->add(PairWeakUnwrapped(&*two, 2)); |
3089 unwrappedWeak->add(PairUnwrappedWeak(2, IntWrapper::create(1))); | 3089 unwrappedWeak->add(PairUnwrappedWeak(2, IntWrapper::create(1))); |
3090 unwrappedWeak->add(PairUnwrappedWeak(2, &*two)); | 3090 unwrappedWeak->add(PairUnwrappedWeak(2, &*two)); |
3091 | 3091 |
3092 checkPairSets<WSSet, SWSet, WUSet, UWSet>(weakStrong, strongWeak, weakUnwrap
ped, unwrappedWeak, true, two); | 3092 checkPairSets<WSSet, SWSet, WUSet, UWSet>(weakStrong, strongWeak, weakUnwrap
ped, unwrappedWeak, true, two); |
3093 | 3093 |
3094 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3094 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3095 checkPairSets<WSSet, SWSet, WUSet, UWSet>(weakStrong, strongWeak, weakUnwrap
ped, unwrappedWeak, false, two); | 3095 checkPairSets<WSSet, SWSet, WUSet, UWSet>(weakStrong, strongWeak, weakUnwrap
ped, unwrappedWeak, false, two); |
3096 } | 3096 } |
3097 | 3097 |
3098 TEST(HeapTest, HeapWeakPairs) | 3098 TEST(HeapTest, HeapWeakPairs) |
3099 { | 3099 { |
3100 { | 3100 { |
3101 typedef HeapHashSet<PairWeakStrong> WeakStrongSet; | 3101 typedef HeapHashSet<PairWeakStrong> WeakStrongSet; |
3102 typedef HeapHashSet<PairWeakUnwrapped> WeakUnwrappedSet; | 3102 typedef HeapHashSet<PairWeakUnwrapped> WeakUnwrappedSet; |
3103 typedef HeapHashSet<PairStrongWeak> StrongWeakSet; | 3103 typedef HeapHashSet<PairStrongWeak> StrongWeakSet; |
3104 typedef HeapHashSet<PairUnwrappedWeak> UnwrappedWeakSet; | 3104 typedef HeapHashSet<PairUnwrappedWeak> UnwrappedWeakSet; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3176 } | 3176 } |
3177 | 3177 |
3178 EXPECT_EQ(64u, weakStrong->size()); | 3178 EXPECT_EQ(64u, weakStrong->size()); |
3179 EXPECT_EQ(64u, strongWeak->size()); | 3179 EXPECT_EQ(64u, strongWeak->size()); |
3180 EXPECT_EQ(64u, weakWeak->size()); | 3180 EXPECT_EQ(64u, weakWeak->size()); |
3181 EXPECT_EQ(64u, weakSet->size()); | 3181 EXPECT_EQ(64u, weakSet->size()); |
3182 EXPECT_EQ(64u, weakOrderedSet->size()); | 3182 EXPECT_EQ(64u, weakOrderedSet->size()); |
3183 | 3183 |
3184 // Collect garbage. This should change nothing since we are keeping | 3184 // Collect garbage. This should change nothing since we are keeping |
3185 // alive the IntWrapper objects. | 3185 // alive the IntWrapper objects. |
3186 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGCForTesting); | 3186 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); |
3187 | 3187 |
3188 EXPECT_EQ(64u, weakStrong->size()); | 3188 EXPECT_EQ(64u, weakStrong->size()); |
3189 EXPECT_EQ(64u, strongWeak->size()); | 3189 EXPECT_EQ(64u, strongWeak->size()); |
3190 EXPECT_EQ(64u, weakWeak->size()); | 3190 EXPECT_EQ(64u, weakWeak->size()); |
3191 EXPECT_EQ(64u, weakSet->size()); | 3191 EXPECT_EQ(64u, weakSet->size()); |
3192 EXPECT_EQ(64u, weakOrderedSet->size()); | 3192 EXPECT_EQ(64u, weakOrderedSet->size()); |
3193 | 3193 |
3194 for (int i = 0; i < 128; i += 2) { | 3194 for (int i = 0; i < 128; i += 2) { |
3195 IntWrapper* wrapped = keepNumbersAlive[i]; | 3195 IntWrapper* wrapped = keepNumbersAlive[i]; |
3196 IntWrapper* wrapped2 = keepNumbersAlive[i + 1]; | 3196 IntWrapper* wrapped2 = keepNumbersAlive[i + 1]; |
(...skipping 19 matching lines...) Expand all Loading... |
3216 weakOrderedSet->clear(); | 3216 weakOrderedSet->clear(); |
3217 | 3217 |
3218 if (testThatIteratorsMakeStrong) { | 3218 if (testThatIteratorsMakeStrong) { |
3219 WeakStrong::iterator it1 = weakStrong->begin(); | 3219 WeakStrong::iterator it1 = weakStrong->begin(); |
3220 StrongWeak::iterator it2 = strongWeak->begin(); | 3220 StrongWeak::iterator it2 = strongWeak->begin(); |
3221 WeakWeak::iterator it3 = weakWeak->begin(); | 3221 WeakWeak::iterator it3 = weakWeak->begin(); |
3222 WeakSet::iterator it4 = weakSet->begin(); | 3222 WeakSet::iterator it4 = weakSet->begin(); |
3223 WeakOrderedSet::iterator it5 = weakOrderedSet->begin(); | 3223 WeakOrderedSet::iterator it5 = weakOrderedSet->begin(); |
3224 // Collect garbage. This should change nothing since the | 3224 // Collect garbage. This should change nothing since the |
3225 // iterators make the collections strong. | 3225 // iterators make the collections strong. |
3226 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadSta
te::GCWithSweep, Heap::ForcedGCForTesting); | 3226 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadSta
te::GCWithSweep, Heap::ForcedGC); |
3227 if (collectionNumber == weakStrongIndex) { | 3227 if (collectionNumber == weakStrongIndex) { |
3228 EXPECT_EQ(64u, weakStrong->size()); | 3228 EXPECT_EQ(64u, weakStrong->size()); |
3229 MapIteratorCheck(it1, weakStrong->end(), 64); | 3229 MapIteratorCheck(it1, weakStrong->end(), 64); |
3230 } else if (collectionNumber == strongWeakIndex) { | 3230 } else if (collectionNumber == strongWeakIndex) { |
3231 EXPECT_EQ(64u, strongWeak->size()); | 3231 EXPECT_EQ(64u, strongWeak->size()); |
3232 MapIteratorCheck(it2, strongWeak->end(), 64); | 3232 MapIteratorCheck(it2, strongWeak->end(), 64); |
3233 } else if (collectionNumber == weakWeakIndex) { | 3233 } else if (collectionNumber == weakWeakIndex) { |
3234 EXPECT_EQ(64u, weakWeak->size()); | 3234 EXPECT_EQ(64u, weakWeak->size()); |
3235 MapIteratorCheck(it3, weakWeak->end(), 64); | 3235 MapIteratorCheck(it3, weakWeak->end(), 64); |
3236 } else if (collectionNumber == weakSetIndex) { | 3236 } else if (collectionNumber == weakSetIndex) { |
3237 EXPECT_EQ(64u, weakSet->size()); | 3237 EXPECT_EQ(64u, weakSet->size()); |
3238 SetIteratorCheck(it4, weakSet->end(), 64); | 3238 SetIteratorCheck(it4, weakSet->end(), 64); |
3239 } else if (collectionNumber == weakOrderedSetIndex) { | 3239 } else if (collectionNumber == weakOrderedSetIndex) { |
3240 EXPECT_EQ(64u, weakOrderedSet->size()); | 3240 EXPECT_EQ(64u, weakOrderedSet->size()); |
3241 SetIteratorCheck(it5, weakOrderedSet->end(), 64); | 3241 SetIteratorCheck(it5, weakOrderedSet->end(), 64); |
3242 } | 3242 } |
3243 } else { | 3243 } else { |
3244 // Collect garbage. This causes weak processing to remove | 3244 // Collect garbage. This causes weak processing to remove |
3245 // things from the collections. | 3245 // things from the collections. |
3246 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadS
tate::GCWithSweep, Heap::ForcedGCForTesting); | 3246 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadS
tate::GCWithSweep, Heap::ForcedGC); |
3247 unsigned count = 0; | 3247 unsigned count = 0; |
3248 for (int i = 0; i < 128; i += 2) { | 3248 for (int i = 0; i < 128; i += 2) { |
3249 bool firstAlive = keepNumbersAlive[i]; | 3249 bool firstAlive = keepNumbersAlive[i]; |
3250 bool secondAlive = keepNumbersAlive[i + 1]; | 3250 bool secondAlive = keepNumbersAlive[i + 1]; |
3251 if (firstAlive && (collectionNumber == weakStrongIndex || co
llectionNumber == strongWeakIndex)) | 3251 if (firstAlive && (collectionNumber == weakStrongIndex || co
llectionNumber == strongWeakIndex)) |
3252 secondAlive = true; | 3252 secondAlive = true; |
3253 if (firstAlive && secondAlive && collectionNumber < numberOf
MapIndices) { | 3253 if (firstAlive && secondAlive && collectionNumber < numberOf
MapIndices) { |
3254 if (collectionNumber == weakStrongIndex) { | 3254 if (collectionNumber == weakStrongIndex) { |
3255 if (deleteAfterwards) | 3255 if (deleteAfterwards) |
3256 EXPECT_EQ(i + 1, weakStrong->take(keepNumbersAli
ve[i])->value()); | 3256 EXPECT_EQ(i + 1, weakStrong->take(keepNumbersAli
ve[i])->value()); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3304 WeakSet::iterator it4 = weakSet->begin(); | 3304 WeakSet::iterator it4 = weakSet->begin(); |
3305 WeakOrderedSet::iterator it5 = weakOrderedSet->begin(); | 3305 WeakOrderedSet::iterator it5 = weakOrderedSet->begin(); |
3306 MapIteratorCheck(it1, weakStrong->end(), (collectionNumber == we
akStrongIndex ? count : 0) + added); | 3306 MapIteratorCheck(it1, weakStrong->end(), (collectionNumber == we
akStrongIndex ? count : 0) + added); |
3307 MapIteratorCheck(it2, strongWeak->end(), (collectionNumber == st
rongWeakIndex ? count : 0) + added); | 3307 MapIteratorCheck(it2, strongWeak->end(), (collectionNumber == st
rongWeakIndex ? count : 0) + added); |
3308 MapIteratorCheck(it3, weakWeak->end(), (collectionNumber == weak
WeakIndex ? count : 0) + added); | 3308 MapIteratorCheck(it3, weakWeak->end(), (collectionNumber == weak
WeakIndex ? count : 0) + added); |
3309 SetIteratorCheck(it4, weakSet->end(), (collectionNumber == weakS
etIndex ? count : 0) + added); | 3309 SetIteratorCheck(it4, weakSet->end(), (collectionNumber == weakS
etIndex ? count : 0) + added); |
3310 SetIteratorCheck(it5, weakOrderedSet->end(), (collectionNumber =
= weakOrderedSetIndex ? count : 0) + added); | 3310 SetIteratorCheck(it5, weakOrderedSet->end(), (collectionNumber =
= weakOrderedSetIndex ? count : 0) + added); |
3311 } | 3311 } |
3312 for (unsigned i = 0; i < 128 + added; i++) | 3312 for (unsigned i = 0; i < 128 + added; i++) |
3313 keepNumbersAlive[i] = nullptr; | 3313 keepNumbersAlive[i] = nullptr; |
3314 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGCForTesting); | 3314 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); |
3315 EXPECT_EQ(0u, weakStrong->size()); | 3315 EXPECT_EQ(0u, weakStrong->size()); |
3316 EXPECT_EQ(0u, strongWeak->size()); | 3316 EXPECT_EQ(0u, strongWeak->size()); |
3317 EXPECT_EQ(0u, weakWeak->size()); | 3317 EXPECT_EQ(0u, weakWeak->size()); |
3318 EXPECT_EQ(0u, weakSet->size()); | 3318 EXPECT_EQ(0u, weakSet->size()); |
3319 EXPECT_EQ(0u, weakOrderedSet->size()); | 3319 EXPECT_EQ(0u, weakOrderedSet->size()); |
3320 } | 3320 } |
3321 } | 3321 } |
3322 } | 3322 } |
3323 | 3323 |
3324 TEST(HeapTest, RefCountedGarbageCollected) | 3324 TEST(HeapTest, RefCountedGarbageCollected) |
3325 { | 3325 { |
3326 RefCountedAndGarbageCollected::s_destructorCalls = 0; | 3326 RefCountedAndGarbageCollected::s_destructorCalls = 0; |
3327 { | 3327 { |
3328 RefPtr<RefCountedAndGarbageCollected> refPtr3; | 3328 RefPtr<RefCountedAndGarbageCollected> refPtr3; |
3329 { | 3329 { |
3330 Persistent<RefCountedAndGarbageCollected> persistent; | 3330 Persistent<RefCountedAndGarbageCollected> persistent; |
3331 { | 3331 { |
3332 Persistent<RefCountedAndGarbageCollected> refPtr1 = RefCountedAn
dGarbageCollected::create(); | 3332 Persistent<RefCountedAndGarbageCollected> refPtr1 = RefCountedAn
dGarbageCollected::create(); |
3333 Persistent<RefCountedAndGarbageCollected> refPtr2 = RefCountedAn
dGarbageCollected::create(); | 3333 Persistent<RefCountedAndGarbageCollected> refPtr2 = RefCountedAn
dGarbageCollected::create(); |
3334 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadS
tate::GCWithSweep, Heap::ForcedGCForTesting); | 3334 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadS
tate::GCWithSweep, Heap::ForcedGC); |
3335 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); | 3335 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
3336 persistent = refPtr1.get(); | 3336 persistent = refPtr1.get(); |
3337 } | 3337 } |
3338 // Reference count is zero for both objects but one of | 3338 // Reference count is zero for both objects but one of |
3339 // them is kept alive by a persistent handle. | 3339 // them is kept alive by a persistent handle. |
3340 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGCForTesting); | 3340 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); |
3341 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls); | 3341 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls); |
3342 refPtr3 = persistent.get(); | 3342 refPtr3 = persistent.get(); |
3343 } | 3343 } |
3344 // The persistent handle is gone but the ref count has been | 3344 // The persistent handle is gone but the ref count has been |
3345 // increased to 1. | 3345 // increased to 1. |
3346 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 3346 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
3347 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls); | 3347 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls); |
3348 } | 3348 } |
3349 // Both persistent handle is gone and ref count is zero so the | 3349 // Both persistent handle is gone and ref count is zero so the |
3350 // object can be collected. | 3350 // object can be collected. |
3351 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3351 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3352 EXPECT_EQ(2, RefCountedAndGarbageCollected::s_destructorCalls); | 3352 EXPECT_EQ(2, RefCountedAndGarbageCollected::s_destructorCalls); |
3353 } | 3353 } |
3354 | 3354 |
3355 TEST(HeapTest, RefCountedGarbageCollectedWithStackPointers) | 3355 TEST(HeapTest, RefCountedGarbageCollectedWithStackPointers) |
3356 { | 3356 { |
3357 RefCountedAndGarbageCollected::s_destructorCalls = 0; | 3357 RefCountedAndGarbageCollected::s_destructorCalls = 0; |
3358 RefCountedAndGarbageCollected2::s_destructorCalls = 0; | 3358 RefCountedAndGarbageCollected2::s_destructorCalls = 0; |
3359 { | 3359 { |
3360 RefCountedAndGarbageCollected* pointer1 = 0; | 3360 RefCountedAndGarbageCollected* pointer1 = 0; |
3361 RefCountedAndGarbageCollected2* pointer2 = 0; | 3361 RefCountedAndGarbageCollected2* pointer2 = 0; |
3362 { | 3362 { |
3363 Persistent<RefCountedAndGarbageCollected> object1 = RefCountedAndGar
bageCollected::create(); | 3363 Persistent<RefCountedAndGarbageCollected> object1 = RefCountedAndGar
bageCollected::create(); |
3364 Persistent<RefCountedAndGarbageCollected2> object2 = RefCountedAndGa
rbageCollected2::create(); | 3364 Persistent<RefCountedAndGarbageCollected2> object2 = RefCountedAndGa
rbageCollected2::create(); |
3365 pointer1 = object1.get(); | 3365 pointer1 = object1.get(); |
3366 pointer2 = object2.get(); | 3366 pointer2 = object2.get(); |
3367 void* objects[2] = { object1.get(), object2.get() }; | 3367 void* objects[2] = { object1.get(), object2.get() }; |
3368 RefCountedGarbageCollectedVisitor visitor(2, objects); | 3368 RefCountedGarbageCollectedVisitor visitor(2, objects); |
3369 ThreadState::current()->visitPersistents(&visitor); | 3369 ThreadState::current()->visitPersistents(&visitor); |
3370 EXPECT_TRUE(visitor.validate()); | 3370 EXPECT_TRUE(visitor.validate()); |
3371 | 3371 |
3372 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::
GCWithSweep, Heap::ForcedGCForTesting); | 3372 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::
GCWithSweep, Heap::ForcedGC); |
3373 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); | 3373 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
3374 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); | 3374 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); |
3375 } | 3375 } |
3376 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGCForTesting); | 3376 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); |
3377 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); | 3377 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
3378 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); | 3378 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); |
3379 | 3379 |
3380 // At this point, the reference counts of object1 and object2 are 0. | 3380 // At this point, the reference counts of object1 and object2 are 0. |
3381 // Only pointer1 and pointer2 keep references to object1 and object2. | 3381 // Only pointer1 and pointer2 keep references to object1 and object2. |
3382 void* objects[] = { 0 }; | 3382 void* objects[] = { 0 }; |
3383 RefCountedGarbageCollectedVisitor visitor(0, objects); | 3383 RefCountedGarbageCollectedVisitor visitor(0, objects); |
3384 ThreadState::current()->visitPersistents(&visitor); | 3384 ThreadState::current()->visitPersistents(&visitor); |
3385 EXPECT_TRUE(visitor.validate()); | 3385 EXPECT_TRUE(visitor.validate()); |
3386 | 3386 |
3387 { | 3387 { |
3388 Persistent<RefCountedAndGarbageCollected> object1(pointer1); | 3388 Persistent<RefCountedAndGarbageCollected> object1(pointer1); |
3389 Persistent<RefCountedAndGarbageCollected2> object2(pointer2); | 3389 Persistent<RefCountedAndGarbageCollected2> object2(pointer2); |
3390 void* objects[2] = { object1.get(), object2.get() }; | 3390 void* objects[2] = { object1.get(), object2.get() }; |
3391 RefCountedGarbageCollectedVisitor visitor(2, objects); | 3391 RefCountedGarbageCollectedVisitor visitor(2, objects); |
3392 ThreadState::current()->visitPersistents(&visitor); | 3392 ThreadState::current()->visitPersistents(&visitor); |
3393 EXPECT_TRUE(visitor.validate()); | 3393 EXPECT_TRUE(visitor.validate()); |
3394 | 3394 |
3395 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::
GCWithSweep, Heap::ForcedGCForTesting); | 3395 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::
GCWithSweep, Heap::ForcedGC); |
3396 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); | 3396 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
3397 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); | 3397 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); |
3398 } | 3398 } |
3399 | 3399 |
3400 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGCForTesting); | 3400 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); |
3401 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); | 3401 EXPECT_EQ(0, RefCountedAndGarbageCollected::s_destructorCalls); |
3402 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); | 3402 EXPECT_EQ(0, RefCountedAndGarbageCollected2::s_destructorCalls); |
3403 } | 3403 } |
3404 | 3404 |
3405 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3405 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3406 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls); | 3406 EXPECT_EQ(1, RefCountedAndGarbageCollected::s_destructorCalls); |
3407 EXPECT_EQ(1, RefCountedAndGarbageCollected2::s_destructorCalls); | 3407 EXPECT_EQ(1, RefCountedAndGarbageCollected2::s_destructorCalls); |
3408 } | 3408 } |
3409 | 3409 |
3410 TEST(HeapTest, WeakMembers) | 3410 TEST(HeapTest, WeakMembers) |
3411 { | 3411 { |
3412 Bar::s_live = 0; | 3412 Bar::s_live = 0; |
3413 { | 3413 { |
3414 Persistent<Bar> h1 = Bar::create(); | 3414 Persistent<Bar> h1 = Bar::create(); |
3415 Persistent<Weak> h4; | 3415 Persistent<Weak> h4; |
3416 Persistent<WithWeakMember> h5; | 3416 Persistent<WithWeakMember> h5; |
3417 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 3417 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
3418 ASSERT_EQ(1u, Bar::s_live); // h1 is live. | 3418 ASSERT_EQ(1u, Bar::s_live); // h1 is live. |
3419 { | 3419 { |
3420 Bar* h2 = Bar::create(); | 3420 Bar* h2 = Bar::create(); |
3421 Bar* h3 = Bar::create(); | 3421 Bar* h3 = Bar::create(); |
3422 h4 = Weak::create(h2, h3); | 3422 h4 = Weak::create(h2, h3); |
3423 h5 = WithWeakMember::create(h2, h3); | 3423 h5 = WithWeakMember::create(h2, h3); |
3424 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::
GCWithSweep, Heap::ForcedGCForTesting); | 3424 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::
GCWithSweep, Heap::ForcedGC); |
3425 EXPECT_EQ(5u, Bar::s_live); // The on-stack pointer keeps h3 alive. | 3425 EXPECT_EQ(5u, Bar::s_live); // The on-stack pointer keeps h3 alive. |
3426 EXPECT_TRUE(h4->strongIsThere()); | 3426 EXPECT_TRUE(h4->strongIsThere()); |
3427 EXPECT_TRUE(h4->weakIsThere()); | 3427 EXPECT_TRUE(h4->weakIsThere()); |
3428 EXPECT_TRUE(h5->strongIsThere()); | 3428 EXPECT_TRUE(h5->strongIsThere()); |
3429 EXPECT_TRUE(h5->weakIsThere()); | 3429 EXPECT_TRUE(h5->weakIsThere()); |
3430 } | 3430 } |
3431 // h3 is collected, weak pointers from h4 and h5 don't keep it alive. | 3431 // h3 is collected, weak pointers from h4 and h5 don't keep it alive. |
3432 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 3432 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
3433 EXPECT_EQ(4u, Bar::s_live); | 3433 EXPECT_EQ(4u, Bar::s_live); |
3434 EXPECT_TRUE(h4->strongIsThere()); | 3434 EXPECT_TRUE(h4->strongIsThere()); |
3435 EXPECT_FALSE(h4->weakIsThere()); // h3 is gone from weak pointer. | 3435 EXPECT_FALSE(h4->weakIsThere()); // h3 is gone from weak pointer. |
3436 EXPECT_TRUE(h5->strongIsThere()); | 3436 EXPECT_TRUE(h5->strongIsThere()); |
3437 EXPECT_FALSE(h5->weakIsThere()); // h3 is gone from weak pointer. | 3437 EXPECT_FALSE(h5->weakIsThere()); // h3 is gone from weak pointer. |
3438 h1.release(); // Zero out h1. | 3438 h1.release(); // Zero out h1. |
3439 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 3439 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
3440 EXPECT_EQ(3u, Bar::s_live); // Only h4, h5 and h2 are left. | 3440 EXPECT_EQ(3u, Bar::s_live); // Only h4, h5 and h2 are left. |
3441 EXPECT_TRUE(h4->strongIsThere()); // h2 is still pointed to from h4. | 3441 EXPECT_TRUE(h4->strongIsThere()); // h2 is still pointed to from h4. |
3442 EXPECT_TRUE(h5->strongIsThere()); // h2 is still pointed to from h5. | 3442 EXPECT_TRUE(h5->strongIsThere()); // h2 is still pointed to from h5. |
3443 } | 3443 } |
3444 // h4 and h5 have gone out of scope now and they were keeping h2 alive. | 3444 // h4 and h5 have gone out of scope now and they were keeping h2 alive. |
3445 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3445 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3446 EXPECT_EQ(0u, Bar::s_live); // All gone. | 3446 EXPECT_EQ(0u, Bar::s_live); // All gone. |
3447 } | 3447 } |
3448 | 3448 |
3449 TEST(HeapTest, FinalizationObserver) | 3449 TEST(HeapTest, FinalizationObserver) |
3450 { | 3450 { |
3451 Persistent<FinalizationObserver<Observable>> o; | 3451 Persistent<FinalizationObserver<Observable>> o; |
3452 { | 3452 { |
3453 Observable* foo = Observable::create(Bar::create()); | 3453 Observable* foo = Observable::create(Bar::create()); |
3454 // |o| observes |foo|. | 3454 // |o| observes |foo|. |
3455 o = FinalizationObserver<Observable>::create(foo); | 3455 o = FinalizationObserver<Observable>::create(foo); |
3456 } | 3456 } |
3457 // FinalizationObserver doesn't have a strong reference to |foo|. So |foo| | 3457 // FinalizationObserver doesn't have a strong reference to |foo|. So |foo| |
3458 // and its member will be collected. | 3458 // and its member will be collected. |
3459 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3459 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3460 EXPECT_EQ(0u, Bar::s_live); | 3460 EXPECT_EQ(0u, Bar::s_live); |
3461 EXPECT_TRUE(o->didCallWillFinalize()); | 3461 EXPECT_TRUE(o->didCallWillFinalize()); |
3462 | 3462 |
3463 FinalizationObserverWithHashMap::s_didCallWillFinalize = false; | 3463 FinalizationObserverWithHashMap::s_didCallWillFinalize = false; |
3464 Observable* foo = Observable::create(Bar::create()); | 3464 Observable* foo = Observable::create(Bar::create()); |
3465 FinalizationObserverWithHashMap::ObserverMap& map = FinalizationObserverWith
HashMap::observe(*foo); | 3465 FinalizationObserverWithHashMap::ObserverMap& map = FinalizationObserverWith
HashMap::observe(*foo); |
3466 EXPECT_EQ(1u, map.size()); | 3466 EXPECT_EQ(1u, map.size()); |
3467 foo = 0; | 3467 foo = 0; |
3468 // FinalizationObserverWithHashMap doesn't have a strong reference to | 3468 // FinalizationObserverWithHashMap doesn't have a strong reference to |
3469 // |foo|. So |foo| and its member will be collected. | 3469 // |foo|. So |foo| and its member will be collected. |
3470 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3470 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3471 EXPECT_EQ(0u, Bar::s_live); | 3471 EXPECT_EQ(0u, Bar::s_live); |
3472 EXPECT_EQ(0u, map.size()); | 3472 EXPECT_EQ(0u, map.size()); |
3473 EXPECT_TRUE(FinalizationObserverWithHashMap::s_didCallWillFinalize); | 3473 EXPECT_TRUE(FinalizationObserverWithHashMap::s_didCallWillFinalize); |
3474 | 3474 |
3475 FinalizationObserverWithHashMap::clearObservers(); | 3475 FinalizationObserverWithHashMap::clearObservers(); |
3476 } | 3476 } |
3477 | 3477 |
3478 TEST(HeapTest, PreFinalizer) | 3478 TEST(HeapTest, PreFinalizer) |
3479 { | 3479 { |
3480 Observable::s_willFinalizeWasCalled = false; | 3480 Observable::s_willFinalizeWasCalled = false; |
3481 { | 3481 { |
3482 Observable* foo = Observable::create(Bar::create()); | 3482 Observable* foo = Observable::create(Bar::create()); |
3483 ThreadState::current()->registerPreFinalizer(*foo); | 3483 ThreadState::current()->registerPreFinalizer(*foo); |
3484 } | 3484 } |
3485 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3485 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3486 EXPECT_TRUE(Observable::s_willFinalizeWasCalled); | 3486 EXPECT_TRUE(Observable::s_willFinalizeWasCalled); |
3487 } | 3487 } |
3488 | 3488 |
3489 TEST(HeapTest, PreFinalizerIsNotCalledIfUnregistered) | 3489 TEST(HeapTest, PreFinalizerIsNotCalledIfUnregistered) |
3490 { | 3490 { |
3491 Observable::s_willFinalizeWasCalled = false; | 3491 Observable::s_willFinalizeWasCalled = false; |
3492 { | 3492 { |
3493 Observable* foo = Observable::create(Bar::create()); | 3493 Observable* foo = Observable::create(Bar::create()); |
3494 ThreadState::current()->registerPreFinalizer(*foo); | 3494 ThreadState::current()->registerPreFinalizer(*foo); |
3495 ThreadState::current()->unregisterPreFinalizer(*foo); | 3495 ThreadState::current()->unregisterPreFinalizer(*foo); |
3496 } | 3496 } |
3497 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3497 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3498 EXPECT_FALSE(Observable::s_willFinalizeWasCalled); | 3498 EXPECT_FALSE(Observable::s_willFinalizeWasCalled); |
3499 } | 3499 } |
3500 | 3500 |
3501 TEST(HeapTest, PreFinalizerUnregistersItself) | 3501 TEST(HeapTest, PreFinalizerUnregistersItself) |
3502 { | 3502 { |
3503 ObservableWithPreFinalizer::s_disposeWasCalled = false; | 3503 ObservableWithPreFinalizer::s_disposeWasCalled = false; |
3504 ObservableWithPreFinalizer::create(); | 3504 ObservableWithPreFinalizer::create(); |
3505 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3505 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3506 EXPECT_TRUE(ObservableWithPreFinalizer::s_disposeWasCalled); | 3506 EXPECT_TRUE(ObservableWithPreFinalizer::s_disposeWasCalled); |
3507 // Don't crash, and assertions don't fail. | 3507 // Don't crash, and assertions don't fail. |
3508 } | 3508 } |
3509 | 3509 |
3510 TEST(HeapTest, Comparisons) | 3510 TEST(HeapTest, Comparisons) |
3511 { | 3511 { |
3512 Persistent<Bar> barPersistent = Bar::create(); | 3512 Persistent<Bar> barPersistent = Bar::create(); |
3513 Persistent<Foo> fooPersistent = Foo::create(barPersistent); | 3513 Persistent<Foo> fooPersistent = Foo::create(barPersistent); |
3514 EXPECT_TRUE(barPersistent != fooPersistent); | 3514 EXPECT_TRUE(barPersistent != fooPersistent); |
3515 barPersistent = fooPersistent; | 3515 barPersistent = fooPersistent; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3584 // This round of GC is important to make sure that the object start | 3584 // This round of GC is important to make sure that the object start |
3585 // bitmap are cleared out and that the free lists are rebuild. | 3585 // bitmap are cleared out and that the free lists are rebuild. |
3586 clearOutOldGarbage(); | 3586 clearOutOldGarbage(); |
3587 } | 3587 } |
3588 | 3588 |
3589 TEST(HeapTest, VisitOffHeapCollections) | 3589 TEST(HeapTest, VisitOffHeapCollections) |
3590 { | 3590 { |
3591 clearOutOldGarbage(); | 3591 clearOutOldGarbage(); |
3592 IntWrapper::s_destructorCalls = 0; | 3592 IntWrapper::s_destructorCalls = 0; |
3593 Persistent<OffHeapContainer> container = OffHeapContainer::create(); | 3593 Persistent<OffHeapContainer> container = OffHeapContainer::create(); |
3594 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3594 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3595 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 3595 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
3596 container = nullptr; | 3596 container = nullptr; |
3597 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3597 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3598 EXPECT_EQ(OffHeapContainer::deadWrappers, IntWrapper::s_destructorCalls); | 3598 EXPECT_EQ(OffHeapContainer::deadWrappers, IntWrapper::s_destructorCalls); |
3599 } | 3599 } |
3600 | 3600 |
3601 TEST(HeapTest, PersistentHeapCollectionTypes) | 3601 TEST(HeapTest, PersistentHeapCollectionTypes) |
3602 { | 3602 { |
3603 IntWrapper::s_destructorCalls = 0; | 3603 IntWrapper::s_destructorCalls = 0; |
3604 | 3604 |
3605 typedef HeapVector<Member<IntWrapper>> Vec; | 3605 typedef HeapVector<Member<IntWrapper>> Vec; |
3606 typedef PersistentHeapVector<Member<IntWrapper>> PVec; | 3606 typedef PersistentHeapVector<Member<IntWrapper>> PVec; |
3607 typedef PersistentHeapHashSet<Member<IntWrapper>> PSet; | 3607 typedef PersistentHeapHashSet<Member<IntWrapper>> PSet; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3646 pVec.append(three); | 3646 pVec.append(three); |
3647 | 3647 |
3648 pSet.add(four); | 3648 pSet.add(four); |
3649 pListSet.add(eight); | 3649 pListSet.add(eight); |
3650 pLinkedSet.add(nine); | 3650 pLinkedSet.add(nine); |
3651 pMap.add(five, six); | 3651 pMap.add(five, six); |
3652 wpMap.add(ten, eleven); | 3652 wpMap.add(ten, eleven); |
3653 | 3653 |
3654 // Collect |vec| and |one|. | 3654 // Collect |vec| and |one|. |
3655 vec = 0; | 3655 vec = 0; |
3656 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 3656 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
3657 EXPECT_EQ(1, IntWrapper::s_destructorCalls); | 3657 EXPECT_EQ(1, IntWrapper::s_destructorCalls); |
3658 | 3658 |
3659 EXPECT_EQ(2u, pVec.size()); | 3659 EXPECT_EQ(2u, pVec.size()); |
3660 EXPECT_EQ(two, pVec.at(0)); | 3660 EXPECT_EQ(two, pVec.at(0)); |
3661 EXPECT_EQ(three, pVec.at(1)); | 3661 EXPECT_EQ(three, pVec.at(1)); |
3662 | 3662 |
3663 EXPECT_EQ(2u, pDeque.size()); | 3663 EXPECT_EQ(2u, pDeque.size()); |
3664 EXPECT_EQ(seven, pDeque.first()); | 3664 EXPECT_EQ(seven, pDeque.first()); |
3665 EXPECT_EQ(seven, pDeque.takeFirst()); | 3665 EXPECT_EQ(seven, pDeque.takeFirst()); |
3666 EXPECT_EQ(two, pDeque.first()); | 3666 EXPECT_EQ(two, pDeque.first()); |
3667 | 3667 |
3668 EXPECT_EQ(1u, pDeque.size()); | 3668 EXPECT_EQ(1u, pDeque.size()); |
3669 | 3669 |
3670 EXPECT_EQ(1u, pSet.size()); | 3670 EXPECT_EQ(1u, pSet.size()); |
3671 EXPECT_TRUE(pSet.contains(four)); | 3671 EXPECT_TRUE(pSet.contains(four)); |
3672 | 3672 |
3673 EXPECT_EQ(1u, pListSet.size()); | 3673 EXPECT_EQ(1u, pListSet.size()); |
3674 EXPECT_TRUE(pListSet.contains(eight)); | 3674 EXPECT_TRUE(pListSet.contains(eight)); |
3675 | 3675 |
3676 EXPECT_EQ(1u, pLinkedSet.size()); | 3676 EXPECT_EQ(1u, pLinkedSet.size()); |
3677 EXPECT_TRUE(pLinkedSet.contains(nine)); | 3677 EXPECT_TRUE(pLinkedSet.contains(nine)); |
3678 | 3678 |
3679 EXPECT_EQ(1u, pMap.size()); | 3679 EXPECT_EQ(1u, pMap.size()); |
3680 EXPECT_EQ(six, pMap.get(five)); | 3680 EXPECT_EQ(six, pMap.get(five)); |
3681 | 3681 |
3682 EXPECT_EQ(1u, wpMap.size()); | 3682 EXPECT_EQ(1u, wpMap.size()); |
3683 EXPECT_EQ(eleven, wpMap.get(ten)); | 3683 EXPECT_EQ(eleven, wpMap.get(ten)); |
3684 ten.clear(); | 3684 ten.clear(); |
3685 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 3685 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
3686 EXPECT_EQ(0u, wpMap.size()); | 3686 EXPECT_EQ(0u, wpMap.size()); |
3687 } | 3687 } |
3688 | 3688 |
3689 // Collect previous roots. | 3689 // Collect previous roots. |
3690 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3690 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3691 EXPECT_EQ(11, IntWrapper::s_destructorCalls); | 3691 EXPECT_EQ(11, IntWrapper::s_destructorCalls); |
3692 } | 3692 } |
3693 | 3693 |
3694 TEST(HeapTest, CollectionNesting) | 3694 TEST(HeapTest, CollectionNesting) |
3695 { | 3695 { |
3696 clearOutOldGarbage(); | 3696 clearOutOldGarbage(); |
3697 int* key = &IntWrapper::s_destructorCalls; | 3697 int* key = &IntWrapper::s_destructorCalls; |
3698 IntWrapper::s_destructorCalls = 0; | 3698 IntWrapper::s_destructorCalls = 0; |
3699 typedef HeapVector<Member<IntWrapper>> IntVector; | 3699 typedef HeapVector<Member<IntWrapper>> IntVector; |
3700 typedef HeapDeque<Member<IntWrapper>> IntDeque; | 3700 typedef HeapDeque<Member<IntWrapper>> IntDeque; |
(...skipping 18 matching lines...) Expand all Loading... |
3719 EXPECT_EQ(1u, map2->get(key).size()); | 3719 EXPECT_EQ(1u, map2->get(key).size()); |
3720 | 3720 |
3721 Persistent<HeapHashMap<void*, IntVector>> keepAlive(map); | 3721 Persistent<HeapHashMap<void*, IntVector>> keepAlive(map); |
3722 Persistent<HeapHashMap<void*, IntDeque>> keepAlive2(map2); | 3722 Persistent<HeapHashMap<void*, IntDeque>> keepAlive2(map2); |
3723 | 3723 |
3724 for (int i = 0; i < 100; i++) { | 3724 for (int i = 0; i < 100; i++) { |
3725 map->add(key + 1 + i, IntVector()); | 3725 map->add(key + 1 + i, IntVector()); |
3726 map2->add(key + 1 + i, IntDeque()); | 3726 map2->add(key + 1 + i, IntDeque()); |
3727 } | 3727 } |
3728 | 3728 |
3729 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3729 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3730 | 3730 |
3731 EXPECT_EQ(1u, map->get(key).size()); | 3731 EXPECT_EQ(1u, map->get(key).size()); |
3732 EXPECT_EQ(1u, map2->get(key).size()); | 3732 EXPECT_EQ(1u, map2->get(key).size()); |
3733 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 3733 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
3734 | 3734 |
3735 keepAlive = nullptr; | 3735 keepAlive = nullptr; |
3736 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3736 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3737 EXPECT_EQ(1, IntWrapper::s_destructorCalls); | 3737 EXPECT_EQ(1, IntWrapper::s_destructorCalls); |
3738 } | 3738 } |
3739 | 3739 |
3740 TEST(HeapTest, GarbageCollectedMixin) | 3740 TEST(HeapTest, GarbageCollectedMixin) |
3741 { | 3741 { |
3742 clearOutOldGarbage(); | 3742 clearOutOldGarbage(); |
3743 | 3743 |
3744 Persistent<UseMixin> usemixin = UseMixin::create(); | 3744 Persistent<UseMixin> usemixin = UseMixin::create(); |
3745 EXPECT_EQ(0, UseMixin::s_traceCount); | 3745 EXPECT_EQ(0, UseMixin::s_traceCount); |
3746 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3746 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3747 EXPECT_EQ(1, UseMixin::s_traceCount); | 3747 EXPECT_EQ(1, UseMixin::s_traceCount); |
3748 | 3748 |
3749 Persistent<Mixin> mixin = usemixin; | 3749 Persistent<Mixin> mixin = usemixin; |
3750 usemixin = nullptr; | 3750 usemixin = nullptr; |
3751 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3751 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3752 EXPECT_EQ(2, UseMixin::s_traceCount); | 3752 EXPECT_EQ(2, UseMixin::s_traceCount); |
3753 | 3753 |
3754 PersistentHeapHashSet<WeakMember<Mixin>> weakMap; | 3754 PersistentHeapHashSet<WeakMember<Mixin>> weakMap; |
3755 weakMap.add(UseMixin::create()); | 3755 weakMap.add(UseMixin::create()); |
3756 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3756 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3757 EXPECT_EQ(0u, weakMap.size()); | 3757 EXPECT_EQ(0u, weakMap.size()); |
3758 } | 3758 } |
3759 | 3759 |
3760 TEST(HeapTest, CollectionNesting2) | 3760 TEST(HeapTest, CollectionNesting2) |
3761 { | 3761 { |
3762 clearOutOldGarbage(); | 3762 clearOutOldGarbage(); |
3763 void* key = &IntWrapper::s_destructorCalls; | 3763 void* key = &IntWrapper::s_destructorCalls; |
3764 IntWrapper::s_destructorCalls = 0; | 3764 IntWrapper::s_destructorCalls = 0; |
3765 typedef HeapHashSet<Member<IntWrapper>> IntSet; | 3765 typedef HeapHashSet<Member<IntWrapper>> IntSet; |
3766 HeapHashMap<void*, IntSet>* map = new HeapHashMap<void*, IntSet>(); | 3766 HeapHashMap<void*, IntSet>* map = new HeapHashMap<void*, IntSet>(); |
3767 | 3767 |
3768 map->add(key, IntSet()); | 3768 map->add(key, IntSet()); |
3769 | 3769 |
3770 HeapHashMap<void*, IntSet>::iterator it = map->find(key); | 3770 HeapHashMap<void*, IntSet>::iterator it = map->find(key); |
3771 EXPECT_EQ(0u, map->get(key).size()); | 3771 EXPECT_EQ(0u, map->get(key).size()); |
3772 | 3772 |
3773 it->value.add(IntWrapper::create(42)); | 3773 it->value.add(IntWrapper::create(42)); |
3774 EXPECT_EQ(1u, map->get(key).size()); | 3774 EXPECT_EQ(1u, map->get(key).size()); |
3775 | 3775 |
3776 Persistent<HeapHashMap<void*, IntSet>> keepAlive(map); | 3776 Persistent<HeapHashMap<void*, IntSet>> keepAlive(map); |
3777 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3777 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3778 EXPECT_EQ(1u, map->get(key).size()); | 3778 EXPECT_EQ(1u, map->get(key).size()); |
3779 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 3779 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
3780 } | 3780 } |
3781 | 3781 |
3782 TEST(HeapTest, CollectionNesting3) | 3782 TEST(HeapTest, CollectionNesting3) |
3783 { | 3783 { |
3784 clearOutOldGarbage(); | 3784 clearOutOldGarbage(); |
3785 IntWrapper::s_destructorCalls = 0; | 3785 IntWrapper::s_destructorCalls = 0; |
3786 typedef HeapVector<Member<IntWrapper>> IntVector; | 3786 typedef HeapVector<Member<IntWrapper>> IntVector; |
3787 typedef HeapDeque<Member<IntWrapper>> IntDeque; | 3787 typedef HeapDeque<Member<IntWrapper>> IntDeque; |
3788 HeapVector<IntVector>* vector = new HeapVector<IntVector>(); | 3788 HeapVector<IntVector>* vector = new HeapVector<IntVector>(); |
3789 HeapDeque<IntDeque>* deque = new HeapDeque<IntDeque>(); | 3789 HeapDeque<IntDeque>* deque = new HeapDeque<IntDeque>(); |
3790 | 3790 |
3791 vector->append(IntVector()); | 3791 vector->append(IntVector()); |
3792 deque->append(IntDeque()); | 3792 deque->append(IntDeque()); |
3793 | 3793 |
3794 HeapVector<IntVector>::iterator it = vector->begin(); | 3794 HeapVector<IntVector>::iterator it = vector->begin(); |
3795 HeapDeque<IntDeque>::iterator it2 = deque->begin(); | 3795 HeapDeque<IntDeque>::iterator it2 = deque->begin(); |
3796 EXPECT_EQ(0u, it->size()); | 3796 EXPECT_EQ(0u, it->size()); |
3797 EXPECT_EQ(0u, it2->size()); | 3797 EXPECT_EQ(0u, it2->size()); |
3798 | 3798 |
3799 it->append(IntWrapper::create(42)); | 3799 it->append(IntWrapper::create(42)); |
3800 it2->append(IntWrapper::create(42)); | 3800 it2->append(IntWrapper::create(42)); |
3801 EXPECT_EQ(1u, it->size()); | 3801 EXPECT_EQ(1u, it->size()); |
3802 EXPECT_EQ(1u, it2->size()); | 3802 EXPECT_EQ(1u, it2->size()); |
3803 | 3803 |
3804 Persistent<HeapVector<IntVector>> keepAlive(vector); | 3804 Persistent<HeapVector<IntVector>> keepAlive(vector); |
3805 Persistent<HeapDeque<IntDeque>> keepAlive2(deque); | 3805 Persistent<HeapDeque<IntDeque>> keepAlive2(deque); |
3806 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3806 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3807 EXPECT_EQ(1u, it->size()); | 3807 EXPECT_EQ(1u, it->size()); |
3808 EXPECT_EQ(1u, it2->size()); | 3808 EXPECT_EQ(1u, it2->size()); |
3809 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 3809 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
3810 } | 3810 } |
3811 | 3811 |
3812 TEST(HeapTest, EmbeddedInVector) | 3812 TEST(HeapTest, EmbeddedInVector) |
3813 { | 3813 { |
3814 clearOutOldGarbage(); | 3814 clearOutOldGarbage(); |
3815 SimpleFinalizedObject::s_destructorCalls = 0; | 3815 SimpleFinalizedObject::s_destructorCalls = 0; |
3816 { | 3816 { |
3817 PersistentHeapVector<VectorObject, 2> inlineVector; | 3817 PersistentHeapVector<VectorObject, 2> inlineVector; |
3818 PersistentHeapVector<VectorObject> outlineVector; | 3818 PersistentHeapVector<VectorObject> outlineVector; |
3819 VectorObject i1, i2; | 3819 VectorObject i1, i2; |
3820 inlineVector.append(i1); | 3820 inlineVector.append(i1); |
3821 inlineVector.append(i2); | 3821 inlineVector.append(i2); |
3822 | 3822 |
3823 VectorObject o1, o2; | 3823 VectorObject o1, o2; |
3824 outlineVector.append(o1); | 3824 outlineVector.append(o1); |
3825 outlineVector.append(o2); | 3825 outlineVector.append(o2); |
3826 | 3826 |
3827 PersistentHeapVector<VectorObjectInheritedTrace> vectorInheritedTrace; | 3827 PersistentHeapVector<VectorObjectInheritedTrace> vectorInheritedTrace; |
3828 VectorObjectInheritedTrace it1, it2; | 3828 VectorObjectInheritedTrace it1, it2; |
3829 vectorInheritedTrace.append(it1); | 3829 vectorInheritedTrace.append(it1); |
3830 vectorInheritedTrace.append(it2); | 3830 vectorInheritedTrace.append(it2); |
3831 | 3831 |
3832 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 3832 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
3833 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 3833 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |
3834 | 3834 |
3835 // Since VectorObjectNoTrace has no trace method it will | 3835 // Since VectorObjectNoTrace has no trace method it will |
3836 // not be traced and hence be collected when doing GC. | 3836 // not be traced and hence be collected when doing GC. |
3837 // We trace items in a collection braced on the item's | 3837 // We trace items in a collection braced on the item's |
3838 // having a trace method. This is determined via the | 3838 // having a trace method. This is determined via the |
3839 // NeedsTracing trait in wtf/TypeTraits.h. | 3839 // NeedsTracing trait in wtf/TypeTraits.h. |
3840 PersistentHeapVector<VectorObjectNoTrace> vectorNoTrace; | 3840 PersistentHeapVector<VectorObjectNoTrace> vectorNoTrace; |
3841 VectorObjectNoTrace n1, n2; | 3841 VectorObjectNoTrace n1, n2; |
3842 vectorNoTrace.append(n1); | 3842 vectorNoTrace.append(n1); |
3843 vectorNoTrace.append(n2); | 3843 vectorNoTrace.append(n2); |
3844 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 3844 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
3845 EXPECT_EQ(2, SimpleFinalizedObject::s_destructorCalls); | 3845 EXPECT_EQ(2, SimpleFinalizedObject::s_destructorCalls); |
3846 } | 3846 } |
3847 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3847 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3848 EXPECT_EQ(8, SimpleFinalizedObject::s_destructorCalls); | 3848 EXPECT_EQ(8, SimpleFinalizedObject::s_destructorCalls); |
3849 } | 3849 } |
3850 | 3850 |
3851 TEST(HeapTest, EmbeddedInDeque) | 3851 TEST(HeapTest, EmbeddedInDeque) |
3852 { | 3852 { |
3853 clearOutOldGarbage(); | 3853 clearOutOldGarbage(); |
3854 SimpleFinalizedObject::s_destructorCalls = 0; | 3854 SimpleFinalizedObject::s_destructorCalls = 0; |
3855 { | 3855 { |
3856 PersistentHeapDeque<VectorObject, 2> inlineDeque; | 3856 PersistentHeapDeque<VectorObject, 2> inlineDeque; |
3857 PersistentHeapDeque<VectorObject> outlineDeque; | 3857 PersistentHeapDeque<VectorObject> outlineDeque; |
3858 VectorObject i1, i2; | 3858 VectorObject i1, i2; |
3859 inlineDeque.append(i1); | 3859 inlineDeque.append(i1); |
3860 inlineDeque.append(i2); | 3860 inlineDeque.append(i2); |
3861 | 3861 |
3862 VectorObject o1, o2; | 3862 VectorObject o1, o2; |
3863 outlineDeque.append(o1); | 3863 outlineDeque.append(o1); |
3864 outlineDeque.append(o2); | 3864 outlineDeque.append(o2); |
3865 | 3865 |
3866 PersistentHeapDeque<VectorObjectInheritedTrace> dequeInheritedTrace; | 3866 PersistentHeapDeque<VectorObjectInheritedTrace> dequeInheritedTrace; |
3867 VectorObjectInheritedTrace it1, it2; | 3867 VectorObjectInheritedTrace it1, it2; |
3868 dequeInheritedTrace.append(it1); | 3868 dequeInheritedTrace.append(it1); |
3869 dequeInheritedTrace.append(it2); | 3869 dequeInheritedTrace.append(it2); |
3870 | 3870 |
3871 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 3871 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
3872 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 3872 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |
3873 | 3873 |
3874 // Since VectorObjectNoTrace has no trace method it will | 3874 // Since VectorObjectNoTrace has no trace method it will |
3875 // not be traced and hence be collected when doing GC. | 3875 // not be traced and hence be collected when doing GC. |
3876 // We trace items in a collection braced on the item's | 3876 // We trace items in a collection braced on the item's |
3877 // having a trace method. This is determined via the | 3877 // having a trace method. This is determined via the |
3878 // NeedsTracing trait in wtf/TypeTraits.h. | 3878 // NeedsTracing trait in wtf/TypeTraits.h. |
3879 PersistentHeapDeque<VectorObjectNoTrace> dequeNoTrace; | 3879 PersistentHeapDeque<VectorObjectNoTrace> dequeNoTrace; |
3880 VectorObjectNoTrace n1, n2; | 3880 VectorObjectNoTrace n1, n2; |
3881 dequeNoTrace.append(n1); | 3881 dequeNoTrace.append(n1); |
3882 dequeNoTrace.append(n2); | 3882 dequeNoTrace.append(n2); |
3883 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 3883 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
3884 EXPECT_EQ(2, SimpleFinalizedObject::s_destructorCalls); | 3884 EXPECT_EQ(2, SimpleFinalizedObject::s_destructorCalls); |
3885 } | 3885 } |
3886 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3886 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3887 EXPECT_EQ(8, SimpleFinalizedObject::s_destructorCalls); | 3887 EXPECT_EQ(8, SimpleFinalizedObject::s_destructorCalls); |
3888 } | 3888 } |
3889 | 3889 |
3890 template<typename Set> | 3890 template<typename Set> |
3891 void rawPtrInHashHelper() | 3891 void rawPtrInHashHelper() |
3892 { | 3892 { |
3893 Set set; | 3893 Set set; |
3894 set.add(new int(42)); | 3894 set.add(new int(42)); |
3895 set.add(new int(42)); | 3895 set.add(new int(42)); |
3896 EXPECT_EQ(2u, set.size()); | 3896 EXPECT_EQ(2u, set.size()); |
(...skipping 21 matching lines...) Expand all Loading... |
3918 const size_t suffixSize = 4; | 3918 const size_t suffixSize = 4; |
3919 | 3919 |
3920 { | 3920 { |
3921 HeapTerminatedArrayBuilder<TerminatedArrayItem> builder(arr); | 3921 HeapTerminatedArrayBuilder<TerminatedArrayItem> builder(arr); |
3922 builder.grow(prefixSize); | 3922 builder.grow(prefixSize); |
3923 for (size_t i = 0; i < prefixSize; i++) | 3923 for (size_t i = 0; i < prefixSize; i++) |
3924 builder.append(TerminatedArrayItem(IntWrapper::create(i))); | 3924 builder.append(TerminatedArrayItem(IntWrapper::create(i))); |
3925 arr = builder.release(); | 3925 arr = builder.release(); |
3926 } | 3926 } |
3927 | 3927 |
3928 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWithSw
eep, Heap::ForcedGCForTesting); | 3928 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWithSw
eep, Heap::ForcedGC); |
3929 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 3929 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
3930 EXPECT_EQ(prefixSize, arr->size()); | 3930 EXPECT_EQ(prefixSize, arr->size()); |
3931 for (size_t i = 0; i < prefixSize; i++) | 3931 for (size_t i = 0; i < prefixSize; i++) |
3932 EXPECT_EQ(i, static_cast<size_t>(arr->at(i).payload()->value())); | 3932 EXPECT_EQ(i, static_cast<size_t>(arr->at(i).payload()->value())); |
3933 | 3933 |
3934 { | 3934 { |
3935 HeapTerminatedArrayBuilder<TerminatedArrayItem> builder(arr); | 3935 HeapTerminatedArrayBuilder<TerminatedArrayItem> builder(arr); |
3936 builder.grow(suffixSize); | 3936 builder.grow(suffixSize); |
3937 for (size_t i = 0; i < suffixSize; i++) | 3937 for (size_t i = 0; i < suffixSize; i++) |
3938 builder.append(TerminatedArrayItem(IntWrapper::create(prefixSize + i
))); | 3938 builder.append(TerminatedArrayItem(IntWrapper::create(prefixSize + i
))); |
3939 arr = builder.release(); | 3939 arr = builder.release(); |
3940 } | 3940 } |
3941 | 3941 |
3942 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWithSw
eep, Heap::ForcedGCForTesting); | 3942 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWithSw
eep, Heap::ForcedGC); |
3943 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 3943 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
3944 EXPECT_EQ(prefixSize + suffixSize, arr->size()); | 3944 EXPECT_EQ(prefixSize + suffixSize, arr->size()); |
3945 for (size_t i = 0; i < prefixSize + suffixSize; i++) | 3945 for (size_t i = 0; i < prefixSize + suffixSize; i++) |
3946 EXPECT_EQ(i, static_cast<size_t>(arr->at(i).payload()->value())); | 3946 EXPECT_EQ(i, static_cast<size_t>(arr->at(i).payload()->value())); |
3947 | 3947 |
3948 { | 3948 { |
3949 Persistent<HeapTerminatedArray<TerminatedArrayItem>> persistentArr = arr
; | 3949 Persistent<HeapTerminatedArray<TerminatedArrayItem>> persistentArr = arr
; |
3950 arr = 0; | 3950 arr = 0; |
3951 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 3951 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
3952 arr = persistentArr.get(); | 3952 arr = persistentArr.get(); |
3953 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 3953 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
3954 EXPECT_EQ(prefixSize + suffixSize, arr->size()); | 3954 EXPECT_EQ(prefixSize + suffixSize, arr->size()); |
3955 for (size_t i = 0; i < prefixSize + suffixSize; i++) | 3955 for (size_t i = 0; i < prefixSize + suffixSize; i++) |
3956 EXPECT_EQ(i, static_cast<size_t>(arr->at(i).payload()->value())); | 3956 EXPECT_EQ(i, static_cast<size_t>(arr->at(i).payload()->value())); |
3957 } | 3957 } |
3958 | 3958 |
3959 arr = 0; | 3959 arr = 0; |
3960 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3960 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3961 EXPECT_EQ(8, IntWrapper::s_destructorCalls); | 3961 EXPECT_EQ(8, IntWrapper::s_destructorCalls); |
3962 } | 3962 } |
3963 | 3963 |
3964 TEST(HeapTest, HeapLinkedStack) | 3964 TEST(HeapTest, HeapLinkedStack) |
3965 { | 3965 { |
3966 clearOutOldGarbage(); | 3966 clearOutOldGarbage(); |
3967 IntWrapper::s_destructorCalls = 0; | 3967 IntWrapper::s_destructorCalls = 0; |
3968 | 3968 |
3969 HeapLinkedStack<TerminatedArrayItem>* stack = new HeapLinkedStack<Terminated
ArrayItem>(); | 3969 HeapLinkedStack<TerminatedArrayItem>* stack = new HeapLinkedStack<Terminated
ArrayItem>(); |
3970 | 3970 |
3971 const size_t stackSize = 10; | 3971 const size_t stackSize = 10; |
3972 | 3972 |
3973 for (size_t i = 0; i < stackSize; i++) | 3973 for (size_t i = 0; i < stackSize; i++) |
3974 stack->push(TerminatedArrayItem(IntWrapper::create(i))); | 3974 stack->push(TerminatedArrayItem(IntWrapper::create(i))); |
3975 | 3975 |
3976 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWithSw
eep, Heap::ForcedGCForTesting); | 3976 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWithSw
eep, Heap::ForcedGC); |
3977 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 3977 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
3978 EXPECT_EQ(stackSize, stack->size()); | 3978 EXPECT_EQ(stackSize, stack->size()); |
3979 while (!stack->isEmpty()) { | 3979 while (!stack->isEmpty()) { |
3980 EXPECT_EQ(stack->size() - 1, static_cast<size_t>(stack->peek().payload()
->value())); | 3980 EXPECT_EQ(stack->size() - 1, static_cast<size_t>(stack->peek().payload()
->value())); |
3981 stack->pop(); | 3981 stack->pop(); |
3982 } | 3982 } |
3983 | 3983 |
3984 Persistent<HeapLinkedStack<TerminatedArrayItem>> pStack = stack; | 3984 Persistent<HeapLinkedStack<TerminatedArrayItem>> pStack = stack; |
3985 | 3985 |
3986 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 3986 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
3987 EXPECT_EQ(stackSize, static_cast<size_t>(IntWrapper::s_destructorCalls)); | 3987 EXPECT_EQ(stackSize, static_cast<size_t>(IntWrapper::s_destructorCalls)); |
3988 EXPECT_EQ(0u, pStack->size()); | 3988 EXPECT_EQ(0u, pStack->size()); |
3989 } | 3989 } |
3990 | 3990 |
3991 TEST(HeapTest, AllocationDuringFinalization) | 3991 TEST(HeapTest, AllocationDuringFinalization) |
3992 { | 3992 { |
3993 clearOutOldGarbage(); | 3993 clearOutOldGarbage(); |
3994 IntWrapper::s_destructorCalls = 0; | 3994 IntWrapper::s_destructorCalls = 0; |
3995 OneKiloByteObject::s_destructorCalls = 0; | 3995 OneKiloByteObject::s_destructorCalls = 0; |
3996 LargeHeapObject::s_destructorCalls = 0; | 3996 LargeHeapObject::s_destructorCalls = 0; |
3997 | 3997 |
3998 Persistent<IntWrapper> wrapper; | 3998 Persistent<IntWrapper> wrapper; |
3999 new FinalizationAllocator(&wrapper); | 3999 new FinalizationAllocator(&wrapper); |
4000 | 4000 |
4001 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4001 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4002 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 4002 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
4003 EXPECT_EQ(0, OneKiloByteObject::s_destructorCalls); | 4003 EXPECT_EQ(0, OneKiloByteObject::s_destructorCalls); |
4004 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); | 4004 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); |
4005 // Check that the wrapper allocated during finalization is not | 4005 // Check that the wrapper allocated during finalization is not |
4006 // swept away and zapped later in the same sweeping phase. | 4006 // swept away and zapped later in the same sweeping phase. |
4007 EXPECT_EQ(42, wrapper->value()); | 4007 EXPECT_EQ(42, wrapper->value()); |
4008 | 4008 |
4009 wrapper.clear(); | 4009 wrapper.clear(); |
4010 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4010 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4011 EXPECT_EQ(42, IntWrapper::s_destructorCalls); | 4011 EXPECT_EQ(42, IntWrapper::s_destructorCalls); |
4012 EXPECT_EQ(512, OneKiloByteObject::s_destructorCalls); | 4012 EXPECT_EQ(512, OneKiloByteObject::s_destructorCalls); |
4013 EXPECT_EQ(32, LargeHeapObject::s_destructorCalls); | 4013 EXPECT_EQ(32, LargeHeapObject::s_destructorCalls); |
4014 } | 4014 } |
4015 | 4015 |
4016 class SimpleClassWithDestructor { | 4016 class SimpleClassWithDestructor { |
4017 public: | 4017 public: |
4018 SimpleClassWithDestructor() { } | 4018 SimpleClassWithDestructor() { } |
4019 ~SimpleClassWithDestructor() | 4019 ~SimpleClassWithDestructor() |
4020 { | 4020 { |
(...skipping 26 matching lines...) Expand all Loading... |
4047 set.add(adoptRef(hasDestructor)); | 4047 set.add(adoptRef(hasDestructor)); |
4048 EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed); | 4048 EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed); |
4049 | 4049 |
4050 if (addLots) { | 4050 if (addLots) { |
4051 for (int i = 0; i < 1000; i++) { | 4051 for (int i = 0; i < 1000; i++) { |
4052 set.add(adoptRef(new RefCountedWithDestructor())); | 4052 set.add(adoptRef(new RefCountedWithDestructor())); |
4053 } | 4053 } |
4054 } | 4054 } |
4055 | 4055 |
4056 EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed); | 4056 EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed); |
4057 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGCForTesting); | 4057 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); |
4058 EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed); | 4058 EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed); |
4059 } | 4059 } |
4060 // The destructors of the sets don't call the destructors of the elements | 4060 // The destructors of the sets don't call the destructors of the elements |
4061 // in the heap sets. You have to actually remove the elments, call clear() | 4061 // in the heap sets. You have to actually remove the elments, call clear() |
4062 // or have a GC to get the destructors called. | 4062 // or have a GC to get the destructors called. |
4063 EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed); | 4063 EXPECT_FALSE(RefCountedWithDestructor::s_wasDestructed); |
4064 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4064 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4065 EXPECT_TRUE(RefCountedWithDestructor::s_wasDestructed); | 4065 EXPECT_TRUE(RefCountedWithDestructor::s_wasDestructed); |
4066 } | 4066 } |
4067 | 4067 |
4068 template<typename Set> | 4068 template<typename Set> |
4069 void destructorsCalledOnClear(bool addLots) | 4069 void destructorsCalledOnClear(bool addLots) |
4070 { | 4070 { |
4071 RefCountedWithDestructor::s_wasDestructed = false; | 4071 RefCountedWithDestructor::s_wasDestructed = false; |
4072 Set set; | 4072 Set set; |
4073 RefCountedWithDestructor* hasDestructor = new RefCountedWithDestructor(); | 4073 RefCountedWithDestructor* hasDestructor = new RefCountedWithDestructor(); |
4074 set.add(adoptRef(hasDestructor)); | 4074 set.add(adoptRef(hasDestructor)); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4148 TEST(HeapTest, MultipleMixins) | 4148 TEST(HeapTest, MultipleMixins) |
4149 { | 4149 { |
4150 EXPECT_TRUE(s_isMixinTrue); | 4150 EXPECT_TRUE(s_isMixinTrue); |
4151 EXPECT_FALSE(s_isMixinFalse); | 4151 EXPECT_FALSE(s_isMixinFalse); |
4152 | 4152 |
4153 clearOutOldGarbage(); | 4153 clearOutOldGarbage(); |
4154 IntWrapper::s_destructorCalls = 0; | 4154 IntWrapper::s_destructorCalls = 0; |
4155 MultipleMixins* obj = new MultipleMixins(); | 4155 MultipleMixins* obj = new MultipleMixins(); |
4156 { | 4156 { |
4157 Persistent<MixinA> a = obj; | 4157 Persistent<MixinA> a = obj; |
4158 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 4158 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
4159 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 4159 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
4160 } | 4160 } |
4161 { | 4161 { |
4162 Persistent<MixinB> b = obj; | 4162 Persistent<MixinB> b = obj; |
4163 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 4163 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
4164 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 4164 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
4165 } | 4165 } |
4166 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4166 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4167 EXPECT_EQ(3, IntWrapper::s_destructorCalls); | 4167 EXPECT_EQ(3, IntWrapper::s_destructorCalls); |
4168 } | 4168 } |
4169 | 4169 |
4170 class GCParkingThreadTester { | 4170 class GCParkingThreadTester { |
4171 public: | 4171 public: |
4172 static void test() | 4172 static void test() |
4173 { | 4173 { |
4174 OwnPtr<WebThread> sleepingThread = adoptPtr(Platform::current()->createT
hread("SleepingThread")); | 4174 OwnPtr<WebThread> sleepingThread = adoptPtr(Platform::current()->createT
hread("SleepingThread")); |
4175 sleepingThread->postTask(FROM_HERE, new Task(WTF::bind(sleeperMainFunc))
); | 4175 sleepingThread->postTask(FROM_HERE, new Task(WTF::bind(sleeperMainFunc))
); |
4176 | 4176 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4249 { | 4249 { |
4250 typedef typename Set::iterator Iterator; | 4250 typedef typename Set::iterator Iterator; |
4251 Persistent<IntWrapper> livingInt(IntWrapper::create(42)); | 4251 Persistent<IntWrapper> livingInt(IntWrapper::create(42)); |
4252 Persistent<Set> set1(new Set()); | 4252 Persistent<Set> set1(new Set()); |
4253 { | 4253 { |
4254 Set set2; | 4254 Set set2; |
4255 Set* set3 = new Set(); | 4255 Set* set3 = new Set(); |
4256 set2.add(PairWithWeakHandling(IntWrapper::create(0), IntWrapper::create(
1))); | 4256 set2.add(PairWithWeakHandling(IntWrapper::create(0), IntWrapper::create(
1))); |
4257 set3->add(PairWithWeakHandling(IntWrapper::create(2), IntWrapper::create
(3))); | 4257 set3->add(PairWithWeakHandling(IntWrapper::create(2), IntWrapper::create
(3))); |
4258 set1->add(PairWithWeakHandling(IntWrapper::create(4), IntWrapper::create
(5))); | 4258 set1->add(PairWithWeakHandling(IntWrapper::create(4), IntWrapper::create
(5))); |
4259 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGCForTesting); | 4259 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); |
4260 // The first set is pointed to from a persistent, so it's referenced, bu
t | 4260 // The first set is pointed to from a persistent, so it's referenced, bu
t |
4261 // the weak processing may have taken place. | 4261 // the weak processing may have taken place. |
4262 if (set1->size()) { | 4262 if (set1->size()) { |
4263 Iterator i1 = set1->begin(); | 4263 Iterator i1 = set1->begin(); |
4264 EXPECT_EQ(4, i1->first->value()); | 4264 EXPECT_EQ(4, i1->first->value()); |
4265 EXPECT_EQ(5, i1->second->value()); | 4265 EXPECT_EQ(5, i1->second->value()); |
4266 } | 4266 } |
4267 // The second set is on-stack, so its backing store must be referenced f
rom | 4267 // The second set is on-stack, so its backing store must be referenced f
rom |
4268 // the stack. That makes the weak references strong. | 4268 // the stack. That makes the weak references strong. |
4269 Iterator i2 = set2.begin(); | 4269 Iterator i2 = set2.begin(); |
4270 EXPECT_EQ(0, i2->first->value()); | 4270 EXPECT_EQ(0, i2->first->value()); |
4271 EXPECT_EQ(1, i2->second->value()); | 4271 EXPECT_EQ(1, i2->second->value()); |
4272 // The third set is pointed to from the stack, so it's referenced, but t
he | 4272 // The third set is pointed to from the stack, so it's referenced, but t
he |
4273 // weak processing may have taken place. | 4273 // weak processing may have taken place. |
4274 if (set3->size()) { | 4274 if (set3->size()) { |
4275 Iterator i3 = set3->begin(); | 4275 Iterator i3 = set3->begin(); |
4276 EXPECT_EQ(2, i3->first->value()); | 4276 EXPECT_EQ(2, i3->first->value()); |
4277 EXPECT_EQ(3, i3->second->value()); | 4277 EXPECT_EQ(3, i3->second->value()); |
4278 } | 4278 } |
4279 } | 4279 } |
4280 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4280 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4281 EXPECT_EQ(0u, set1->size()); | 4281 EXPECT_EQ(0u, set1->size()); |
4282 set1->add(PairWithWeakHandling(IntWrapper::create(103), livingInt)); | 4282 set1->add(PairWithWeakHandling(IntWrapper::create(103), livingInt)); |
4283 set1->add(PairWithWeakHandling(livingInt, IntWrapper::create(103))); // This
one gets zapped at GC time because nothing holds the 103 alive. | 4283 set1->add(PairWithWeakHandling(livingInt, IntWrapper::create(103))); // This
one gets zapped at GC time because nothing holds the 103 alive. |
4284 set1->add(PairWithWeakHandling(IntWrapper::create(103), IntWrapper::create(1
03))); // This one gets zapped too. | 4284 set1->add(PairWithWeakHandling(IntWrapper::create(103), IntWrapper::create(1
03))); // This one gets zapped too. |
4285 set1->add(PairWithWeakHandling(livingInt, livingInt)); | 4285 set1->add(PairWithWeakHandling(livingInt, livingInt)); |
4286 set1->add(PairWithWeakHandling(livingInt, livingInt)); // This one is identi
cal to the previous and doesn't add anything. | 4286 set1->add(PairWithWeakHandling(livingInt, livingInt)); // This one is identi
cal to the previous and doesn't add anything. |
4287 EXPECT_EQ(4u, set1->size()); | 4287 EXPECT_EQ(4u, set1->size()); |
4288 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4288 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4289 EXPECT_EQ(2u, set1->size()); | 4289 EXPECT_EQ(2u, set1->size()); |
4290 Iterator i1 = set1->begin(); | 4290 Iterator i1 = set1->begin(); |
4291 EXPECT_TRUE(i1->first->value() == 103 || i1->first == livingInt); | 4291 EXPECT_TRUE(i1->first->value() == 103 || i1->first == livingInt); |
4292 EXPECT_EQ(livingInt, i1->second); | 4292 EXPECT_EQ(livingInt, i1->second); |
4293 ++i1; | 4293 ++i1; |
4294 EXPECT_TRUE(i1->first->value() == 103 || i1->first == livingInt); | 4294 EXPECT_TRUE(i1->first->value() == 103 || i1->first == livingInt); |
4295 EXPECT_EQ(livingInt, i1->second); | 4295 EXPECT_EQ(livingInt, i1->second); |
4296 } | 4296 } |
4297 | 4297 |
4298 TEST(HeapTest, SetWithCustomWeaknessHandling) | 4298 TEST(HeapTest, SetWithCustomWeaknessHandling) |
(...skipping 12 matching lines...) Expand all Loading... |
4311 Persistent<Map> map1(new Map()); | 4311 Persistent<Map> map1(new Map()); |
4312 Persistent<IntWrapper> livingInt(IntWrapper::create(42)); | 4312 Persistent<IntWrapper> livingInt(IntWrapper::create(42)); |
4313 { | 4313 { |
4314 Map map2; | 4314 Map map2; |
4315 Map* map3 = new Map(); | 4315 Map* map3 = new Map(); |
4316 map2.add(PairWithWeakHandling(IntWrapper::create(0), IntWrapper::create(
1)), OffHeapInt::create(1001)); | 4316 map2.add(PairWithWeakHandling(IntWrapper::create(0), IntWrapper::create(
1)), OffHeapInt::create(1001)); |
4317 map3->add(PairWithWeakHandling(IntWrapper::create(2), IntWrapper::create
(3)), OffHeapInt::create(1002)); | 4317 map3->add(PairWithWeakHandling(IntWrapper::create(2), IntWrapper::create
(3)), OffHeapInt::create(1002)); |
4318 map1->add(PairWithWeakHandling(IntWrapper::create(4), IntWrapper::create
(5)), OffHeapInt::create(1003)); | 4318 map1->add(PairWithWeakHandling(IntWrapper::create(4), IntWrapper::create
(5)), OffHeapInt::create(1003)); |
4319 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); | 4319 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); |
4320 | 4320 |
4321 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGCForTesting); | 4321 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); |
4322 // The first map2 is pointed to from a persistent, so it's referenced, b
ut | 4322 // The first map2 is pointed to from a persistent, so it's referenced, b
ut |
4323 // the weak processing may have taken place. | 4323 // the weak processing may have taken place. |
4324 if (map1->size()) { | 4324 if (map1->size()) { |
4325 Iterator i1 = map1->begin(); | 4325 Iterator i1 = map1->begin(); |
4326 EXPECT_EQ(4, i1->key.first->value()); | 4326 EXPECT_EQ(4, i1->key.first->value()); |
4327 EXPECT_EQ(5, i1->key.second->value()); | 4327 EXPECT_EQ(5, i1->key.second->value()); |
4328 EXPECT_EQ(1003, i1->value->value()); | 4328 EXPECT_EQ(1003, i1->value->value()); |
4329 } | 4329 } |
4330 // The second map2 is on-stack, so its backing store must be referenced
from | 4330 // The second map2 is on-stack, so its backing store must be referenced
from |
4331 // the stack. That makes the weak references strong. | 4331 // the stack. That makes the weak references strong. |
4332 Iterator i2 = map2.begin(); | 4332 Iterator i2 = map2.begin(); |
4333 EXPECT_EQ(0, i2->key.first->value()); | 4333 EXPECT_EQ(0, i2->key.first->value()); |
4334 EXPECT_EQ(1, i2->key.second->value()); | 4334 EXPECT_EQ(1, i2->key.second->value()); |
4335 EXPECT_EQ(1001, i2->value->value()); | 4335 EXPECT_EQ(1001, i2->value->value()); |
4336 // The third map2 is pointed to from the stack, so it's referenced, but
the | 4336 // The third map2 is pointed to from the stack, so it's referenced, but
the |
4337 // weak processing may have taken place. | 4337 // weak processing may have taken place. |
4338 if (map3->size()) { | 4338 if (map3->size()) { |
4339 Iterator i3 = map3->begin(); | 4339 Iterator i3 = map3->begin(); |
4340 EXPECT_EQ(2, i3->key.first->value()); | 4340 EXPECT_EQ(2, i3->key.first->value()); |
4341 EXPECT_EQ(3, i3->key.second->value()); | 4341 EXPECT_EQ(3, i3->key.second->value()); |
4342 EXPECT_EQ(1002, i3->value->value()); | 4342 EXPECT_EQ(1002, i3->value->value()); |
4343 } | 4343 } |
4344 } | 4344 } |
4345 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4345 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4346 | 4346 |
4347 EXPECT_EQ(0u, map1->size()); | 4347 EXPECT_EQ(0u, map1->size()); |
4348 EXPECT_EQ(3, OffHeapInt::s_destructorCalls); | 4348 EXPECT_EQ(3, OffHeapInt::s_destructorCalls); |
4349 | 4349 |
4350 OffHeapInt::s_destructorCalls = 0; | 4350 OffHeapInt::s_destructorCalls = 0; |
4351 | 4351 |
4352 map1->add(PairWithWeakHandling(IntWrapper::create(103), livingInt), OffHeapI
nt::create(2000)); | 4352 map1->add(PairWithWeakHandling(IntWrapper::create(103), livingInt), OffHeapI
nt::create(2000)); |
4353 map1->add(PairWithWeakHandling(livingInt, IntWrapper::create(103)), OffHeapI
nt::create(2001)); // This one gets zapped at GC time because nothing holds the
103 alive. | 4353 map1->add(PairWithWeakHandling(livingInt, IntWrapper::create(103)), OffHeapI
nt::create(2001)); // This one gets zapped at GC time because nothing holds the
103 alive. |
4354 map1->add(PairWithWeakHandling(IntWrapper::create(103), IntWrapper::create(1
03)), OffHeapInt::create(2002)); // This one gets zapped too. | 4354 map1->add(PairWithWeakHandling(IntWrapper::create(103), IntWrapper::create(1
03)), OffHeapInt::create(2002)); // This one gets zapped too. |
4355 RefPtr<OffHeapInt> dupeInt(OffHeapInt::create(2003)); | 4355 RefPtr<OffHeapInt> dupeInt(OffHeapInt::create(2003)); |
4356 map1->add(PairWithWeakHandling(livingInt, livingInt), dupeInt); | 4356 map1->add(PairWithWeakHandling(livingInt, livingInt), dupeInt); |
4357 map1->add(PairWithWeakHandling(livingInt, livingInt), dupeInt); // This one
is identical to the previous and doesn't add anything. | 4357 map1->add(PairWithWeakHandling(livingInt, livingInt), dupeInt); // This one
is identical to the previous and doesn't add anything. |
4358 dupeInt.clear(); | 4358 dupeInt.clear(); |
4359 | 4359 |
4360 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); | 4360 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); |
4361 EXPECT_EQ(4u, map1->size()); | 4361 EXPECT_EQ(4u, map1->size()); |
4362 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4362 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4363 EXPECT_EQ(2, OffHeapInt::s_destructorCalls); | 4363 EXPECT_EQ(2, OffHeapInt::s_destructorCalls); |
4364 EXPECT_EQ(2u, map1->size()); | 4364 EXPECT_EQ(2u, map1->size()); |
4365 Iterator i1 = map1->begin(); | 4365 Iterator i1 = map1->begin(); |
4366 EXPECT_TRUE(i1->key.first->value() == 103 || i1->key.first == livingInt); | 4366 EXPECT_TRUE(i1->key.first->value() == 103 || i1->key.first == livingInt); |
4367 EXPECT_EQ(livingInt, i1->key.second); | 4367 EXPECT_EQ(livingInt, i1->key.second); |
4368 ++i1; | 4368 ++i1; |
4369 EXPECT_TRUE(i1->key.first->value() == 103 || i1->key.first == livingInt); | 4369 EXPECT_TRUE(i1->key.first->value() == 103 || i1->key.first == livingInt); |
4370 EXPECT_EQ(livingInt, i1->key.second); | 4370 EXPECT_EQ(livingInt, i1->key.second); |
4371 } | 4371 } |
4372 | 4372 |
4373 TEST(HeapTest, MapWithCustomWeaknessHandling2) | 4373 TEST(HeapTest, MapWithCustomWeaknessHandling2) |
4374 { | 4374 { |
4375 typedef HeapHashMap<RefPtr<OffHeapInt>, PairWithWeakHandling> Map; | 4375 typedef HeapHashMap<RefPtr<OffHeapInt>, PairWithWeakHandling> Map; |
4376 typedef Map::iterator Iterator; | 4376 typedef Map::iterator Iterator; |
4377 clearOutOldGarbage(); | 4377 clearOutOldGarbage(); |
4378 OffHeapInt::s_destructorCalls = 0; | 4378 OffHeapInt::s_destructorCalls = 0; |
4379 | 4379 |
4380 Persistent<Map> map1(new Map()); | 4380 Persistent<Map> map1(new Map()); |
4381 Persistent<IntWrapper> livingInt(IntWrapper::create(42)); | 4381 Persistent<IntWrapper> livingInt(IntWrapper::create(42)); |
4382 | 4382 |
4383 { | 4383 { |
4384 Map map2; | 4384 Map map2; |
4385 Map* map3 = new Map(); | 4385 Map* map3 = new Map(); |
4386 map2.add(OffHeapInt::create(1001), PairWithWeakHandling(IntWrapper::crea
te(0), IntWrapper::create(1))); | 4386 map2.add(OffHeapInt::create(1001), PairWithWeakHandling(IntWrapper::crea
te(0), IntWrapper::create(1))); |
4387 map3->add(OffHeapInt::create(1002), PairWithWeakHandling(IntWrapper::cre
ate(2), IntWrapper::create(3))); | 4387 map3->add(OffHeapInt::create(1002), PairWithWeakHandling(IntWrapper::cre
ate(2), IntWrapper::create(3))); |
4388 map1->add(OffHeapInt::create(1003), PairWithWeakHandling(IntWrapper::cre
ate(4), IntWrapper::create(5))); | 4388 map1->add(OffHeapInt::create(1003), PairWithWeakHandling(IntWrapper::cre
ate(4), IntWrapper::create(5))); |
4389 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); | 4389 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); |
4390 | 4390 |
4391 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGCForTesting); | 4391 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); |
4392 // The first map2 is pointed to from a persistent, so it's referenced, b
ut | 4392 // The first map2 is pointed to from a persistent, so it's referenced, b
ut |
4393 // the weak processing may have taken place. | 4393 // the weak processing may have taken place. |
4394 if (map1->size()) { | 4394 if (map1->size()) { |
4395 Iterator i1 = map1->begin(); | 4395 Iterator i1 = map1->begin(); |
4396 EXPECT_EQ(4, i1->value.first->value()); | 4396 EXPECT_EQ(4, i1->value.first->value()); |
4397 EXPECT_EQ(5, i1->value.second->value()); | 4397 EXPECT_EQ(5, i1->value.second->value()); |
4398 EXPECT_EQ(1003, i1->key->value()); | 4398 EXPECT_EQ(1003, i1->key->value()); |
4399 } | 4399 } |
4400 // The second map2 is on-stack, so its backing store must be referenced
from | 4400 // The second map2 is on-stack, so its backing store must be referenced
from |
4401 // the stack. That makes the weak references strong. | 4401 // the stack. That makes the weak references strong. |
4402 Iterator i2 = map2.begin(); | 4402 Iterator i2 = map2.begin(); |
4403 EXPECT_EQ(0, i2->value.first->value()); | 4403 EXPECT_EQ(0, i2->value.first->value()); |
4404 EXPECT_EQ(1, i2->value.second->value()); | 4404 EXPECT_EQ(1, i2->value.second->value()); |
4405 EXPECT_EQ(1001, i2->key->value()); | 4405 EXPECT_EQ(1001, i2->key->value()); |
4406 // The third map2 is pointed to from the stack, so it's referenced, but
the | 4406 // The third map2 is pointed to from the stack, so it's referenced, but
the |
4407 // weak processing may have taken place. | 4407 // weak processing may have taken place. |
4408 if (map3->size()) { | 4408 if (map3->size()) { |
4409 Iterator i3 = map3->begin(); | 4409 Iterator i3 = map3->begin(); |
4410 EXPECT_EQ(2, i3->value.first->value()); | 4410 EXPECT_EQ(2, i3->value.first->value()); |
4411 EXPECT_EQ(3, i3->value.second->value()); | 4411 EXPECT_EQ(3, i3->value.second->value()); |
4412 EXPECT_EQ(1002, i3->key->value()); | 4412 EXPECT_EQ(1002, i3->key->value()); |
4413 } | 4413 } |
4414 } | 4414 } |
4415 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4415 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4416 | 4416 |
4417 EXPECT_EQ(0u, map1->size()); | 4417 EXPECT_EQ(0u, map1->size()); |
4418 EXPECT_EQ(3, OffHeapInt::s_destructorCalls); | 4418 EXPECT_EQ(3, OffHeapInt::s_destructorCalls); |
4419 | 4419 |
4420 OffHeapInt::s_destructorCalls = 0; | 4420 OffHeapInt::s_destructorCalls = 0; |
4421 | 4421 |
4422 map1->add(OffHeapInt::create(2000), PairWithWeakHandling(IntWrapper::create(
103), livingInt)); | 4422 map1->add(OffHeapInt::create(2000), PairWithWeakHandling(IntWrapper::create(
103), livingInt)); |
4423 map1->add(OffHeapInt::create(2001), PairWithWeakHandling(livingInt, IntWrapp
er::create(103))); // This one gets zapped at GC time because nothing holds the
103 alive. | 4423 map1->add(OffHeapInt::create(2001), PairWithWeakHandling(livingInt, IntWrapp
er::create(103))); // This one gets zapped at GC time because nothing holds the
103 alive. |
4424 map1->add(OffHeapInt::create(2002), PairWithWeakHandling(IntWrapper::create(
103), IntWrapper::create(103))); // This one gets zapped too. | 4424 map1->add(OffHeapInt::create(2002), PairWithWeakHandling(IntWrapper::create(
103), IntWrapper::create(103))); // This one gets zapped too. |
4425 RefPtr<OffHeapInt> dupeInt(OffHeapInt::create(2003)); | 4425 RefPtr<OffHeapInt> dupeInt(OffHeapInt::create(2003)); |
4426 map1->add(dupeInt, PairWithWeakHandling(livingInt, livingInt)); | 4426 map1->add(dupeInt, PairWithWeakHandling(livingInt, livingInt)); |
4427 map1->add(dupeInt, PairWithWeakHandling(livingInt, livingInt)); // This one
is identical to the previous and doesn't add anything. | 4427 map1->add(dupeInt, PairWithWeakHandling(livingInt, livingInt)); // This one
is identical to the previous and doesn't add anything. |
4428 dupeInt.clear(); | 4428 dupeInt.clear(); |
4429 | 4429 |
4430 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); | 4430 EXPECT_EQ(0, OffHeapInt::s_destructorCalls); |
4431 EXPECT_EQ(4u, map1->size()); | 4431 EXPECT_EQ(4u, map1->size()); |
4432 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4432 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4433 EXPECT_EQ(2, OffHeapInt::s_destructorCalls); | 4433 EXPECT_EQ(2, OffHeapInt::s_destructorCalls); |
4434 EXPECT_EQ(2u, map1->size()); | 4434 EXPECT_EQ(2u, map1->size()); |
4435 Iterator i1 = map1->begin(); | 4435 Iterator i1 = map1->begin(); |
4436 EXPECT_TRUE(i1->value.first->value() == 103 || i1->value.first == livingInt)
; | 4436 EXPECT_TRUE(i1->value.first->value() == 103 || i1->value.first == livingInt)
; |
4437 EXPECT_EQ(livingInt, i1->value.second); | 4437 EXPECT_EQ(livingInt, i1->value.second); |
4438 ++i1; | 4438 ++i1; |
4439 EXPECT_TRUE(i1->value.first->value() == 103 || i1->value.first == livingInt)
; | 4439 EXPECT_TRUE(i1->value.first->value() == 103 || i1->value.first == livingInt)
; |
4440 EXPECT_EQ(livingInt, i1->value.second); | 4440 EXPECT_EQ(livingInt, i1->value.second); |
4441 } | 4441 } |
4442 | 4442 |
4443 static void addElementsToWeakMap(HeapHashMap<int, WeakMember<IntWrapper>>* map) | 4443 static void addElementsToWeakMap(HeapHashMap<int, WeakMember<IntWrapper>>* map) |
4444 { | 4444 { |
4445 // Key cannot be zero in hashmap. | 4445 // Key cannot be zero in hashmap. |
4446 for (int i = 1; i < 11; i++) | 4446 for (int i = 1; i < 11; i++) |
4447 map->add(i, IntWrapper::create(i)); | 4447 map->add(i, IntWrapper::create(i)); |
4448 } | 4448 } |
4449 | 4449 |
4450 // crbug.com/402426 | 4450 // crbug.com/402426 |
4451 // If it doesn't assert a concurrent modification to the map, then it's passing. | 4451 // If it doesn't assert a concurrent modification to the map, then it's passing. |
4452 TEST(HeapTest, RegressNullIsStrongified) | 4452 TEST(HeapTest, RegressNullIsStrongified) |
4453 { | 4453 { |
4454 Persistent<HeapHashMap<int, WeakMember<IntWrapper>>> map = new HeapHashMap<i
nt, WeakMember<IntWrapper>>(); | 4454 Persistent<HeapHashMap<int, WeakMember<IntWrapper>>> map = new HeapHashMap<i
nt, WeakMember<IntWrapper>>(); |
4455 addElementsToWeakMap(map); | 4455 addElementsToWeakMap(map); |
4456 HeapHashMap<int, WeakMember<IntWrapper>>::AddResult result = map->add(800, n
ullptr); | 4456 HeapHashMap<int, WeakMember<IntWrapper>>::AddResult result = map->add(800, n
ullptr); |
4457 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWithSw
eep, Heap::ForcedGCForTesting); | 4457 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWithSw
eep, Heap::ForcedGC); |
4458 result.storedValue->value = IntWrapper::create(42); | 4458 result.storedValue->value = IntWrapper::create(42); |
4459 } | 4459 } |
4460 | 4460 |
4461 TEST(HeapTest, Bind) | 4461 TEST(HeapTest, Bind) |
4462 { | 4462 { |
4463 OwnPtr<Closure> closure = bind(static_cast<void (Bar::*)(Visitor*)>(&Bar::tr
ace), Bar::create(), static_cast<Visitor*>(0)); | 4463 OwnPtr<Closure> closure = bind(static_cast<void (Bar::*)(Visitor*)>(&Bar::tr
ace), Bar::create(), static_cast<Visitor*>(0)); |
4464 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4464 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4465 // The closure should have a persistent handle to the Bar. | 4465 // The closure should have a persistent handle to the Bar. |
4466 EXPECT_EQ(1u, Bar::s_live); | 4466 EXPECT_EQ(1u, Bar::s_live); |
4467 | 4467 |
4468 OwnPtr<Closure> closure2 = bind(static_cast<void (Bar::*)(Visitor*)>(&Bar::t
race), RawPtr<Bar>(Bar::create()), static_cast<Visitor*>(0)); | 4468 OwnPtr<Closure> closure2 = bind(static_cast<void (Bar::*)(Visitor*)>(&Bar::t
race), RawPtr<Bar>(Bar::create()), static_cast<Visitor*>(0)); |
4469 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4469 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4470 // The closure should have a persistent handle to the Bar. | 4470 // The closure should have a persistent handle to the Bar. |
4471 EXPECT_EQ(2u, Bar::s_live); | 4471 EXPECT_EQ(2u, Bar::s_live); |
4472 // RawPtr<OffHeapInt> should not make Persistent. | 4472 // RawPtr<OffHeapInt> should not make Persistent. |
4473 OwnPtr<Closure> closure3 = bind(&OffHeapInt::voidFunction, RawPtr<OffHeapInt
>(OffHeapInt::create(1).get())); | 4473 OwnPtr<Closure> closure3 = bind(&OffHeapInt::voidFunction, RawPtr<OffHeapInt
>(OffHeapInt::create(1).get())); |
4474 | 4474 |
4475 UseMixin::s_traceCount = 0; | 4475 UseMixin::s_traceCount = 0; |
4476 Mixin* mixin = UseMixin::create(); | 4476 Mixin* mixin = UseMixin::create(); |
4477 OwnPtr<Closure> mixinClosure = bind(static_cast<void (Mixin::*)(Visitor*)>(&
Mixin::trace), mixin, static_cast<Visitor*>(0)); | 4477 OwnPtr<Closure> mixinClosure = bind(static_cast<void (Mixin::*)(Visitor*)>(&
Mixin::trace), mixin, static_cast<Visitor*>(0)); |
4478 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4478 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4479 // The closure should have a persistent handle to the mixin. | 4479 // The closure should have a persistent handle to the mixin. |
4480 EXPECT_EQ(1, UseMixin::s_traceCount); | 4480 EXPECT_EQ(1, UseMixin::s_traceCount); |
4481 } | 4481 } |
4482 | 4482 |
4483 typedef HeapHashSet<WeakMember<IntWrapper>> WeakSet; | 4483 typedef HeapHashSet<WeakMember<IntWrapper>> WeakSet; |
4484 | 4484 |
4485 // These special traits will remove a set from a map when the set is empty. | 4485 // These special traits will remove a set from a map when the set is empty. |
4486 struct EmptyClearingHashSetTraits : HashTraits<WeakSet> { | 4486 struct EmptyClearingHashSetTraits : HashTraits<WeakSet> { |
4487 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; | 4487 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; |
4488 template<typename VisitorDispatcher> | 4488 template<typename VisitorDispatcher> |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4533 set.add(IntWrapper::create(103)); // Weak set can't hold this long. | 4533 set.add(IntWrapper::create(103)); // Weak set can't hold this long. |
4534 set.add(livingInt); // This prevents the set from being emptied. | 4534 set.add(livingInt); // This prevents the set from being emptied. |
4535 EXPECT_EQ(2u, set.size()); | 4535 EXPECT_EQ(2u, set.size()); |
4536 } | 4536 } |
4537 | 4537 |
4538 // The set we add here is empty, so the entry will be removed from the map | 4538 // The set we add here is empty, so the entry will be removed from the map |
4539 // at the next GC. | 4539 // at the next GC. |
4540 map->add(OffHeapInt::create(2), WeakSet()); | 4540 map->add(OffHeapInt::create(2), WeakSet()); |
4541 EXPECT_EQ(2u, map->size()); | 4541 EXPECT_EQ(2u, map->size()); |
4542 | 4542 |
4543 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4543 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4544 EXPECT_EQ(1u, map->size()); // The one with key 2 was removed. | 4544 EXPECT_EQ(1u, map->size()); // The one with key 2 was removed. |
4545 EXPECT_EQ(1, OffHeapInt::s_destructorCalls); | 4545 EXPECT_EQ(1, OffHeapInt::s_destructorCalls); |
4546 { | 4546 { |
4547 WeakSet& set = map->begin()->value; | 4547 WeakSet& set = map->begin()->value; |
4548 EXPECT_EQ(1u, set.size()); | 4548 EXPECT_EQ(1u, set.size()); |
4549 } | 4549 } |
4550 | 4550 |
4551 livingInt.clear(); // The weak set can no longer keep the '42' alive now. | 4551 livingInt.clear(); // The weak set can no longer keep the '42' alive now. |
4552 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4552 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4553 EXPECT_EQ(0u, map->size()); | 4553 EXPECT_EQ(0u, map->size()); |
4554 } | 4554 } |
4555 | 4555 |
4556 TEST(HeapTest, EphemeronsInEphemerons) | 4556 TEST(HeapTest, EphemeronsInEphemerons) |
4557 { | 4557 { |
4558 typedef HeapHashMap<WeakMember<IntWrapper>, Member<IntWrapper>> InnerMap; | 4558 typedef HeapHashMap<WeakMember<IntWrapper>, Member<IntWrapper>> InnerMap; |
4559 typedef HeapHashMap<WeakMember<IntWrapper>, InnerMap> OuterMap; | 4559 typedef HeapHashMap<WeakMember<IntWrapper>, InnerMap> OuterMap; |
4560 | 4560 |
4561 for (int keepOuterAlive = 0; keepOuterAlive <= 1; keepOuterAlive++) { | 4561 for (int keepOuterAlive = 0; keepOuterAlive <= 1; keepOuterAlive++) { |
4562 for (int keepInnerAlive = 0; keepInnerAlive <=1; keepInnerAlive++) { | 4562 for (int keepInnerAlive = 0; keepInnerAlive <=1; keepInnerAlive++) { |
4563 Persistent<OuterMap> outer = new OuterMap(); | 4563 Persistent<OuterMap> outer = new OuterMap(); |
4564 Persistent<IntWrapper> one = IntWrapper::create(1); | 4564 Persistent<IntWrapper> one = IntWrapper::create(1); |
4565 Persistent<IntWrapper> two = IntWrapper::create(2); | 4565 Persistent<IntWrapper> two = IntWrapper::create(2); |
4566 outer->add(one, InnerMap()); | 4566 outer->add(one, InnerMap()); |
4567 outer->begin()->value.add(two, IntWrapper::create(3)); | 4567 outer->begin()->value.add(two, IntWrapper::create(3)); |
4568 EXPECT_EQ(1u, outer->get(one).size()); | 4568 EXPECT_EQ(1u, outer->get(one).size()); |
4569 if (!keepOuterAlive) | 4569 if (!keepOuterAlive) |
4570 one.clear(); | 4570 one.clear(); |
4571 if (!keepInnerAlive) | 4571 if (!keepInnerAlive) |
4572 two.clear(); | 4572 two.clear(); |
4573 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGCForTesting); | 4573 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); |
4574 if (keepOuterAlive) { | 4574 if (keepOuterAlive) { |
4575 const InnerMap& inner = outer->get(one); | 4575 const InnerMap& inner = outer->get(one); |
4576 if (keepInnerAlive) { | 4576 if (keepInnerAlive) { |
4577 EXPECT_EQ(1u, inner.size()); | 4577 EXPECT_EQ(1u, inner.size()); |
4578 IntWrapper* three = inner.get(two); | 4578 IntWrapper* three = inner.get(two); |
4579 EXPECT_EQ(3, three->value()); | 4579 EXPECT_EQ(3, three->value()); |
4580 } else { | 4580 } else { |
4581 EXPECT_EQ(0u, inner.size()); | 4581 EXPECT_EQ(0u, inner.size()); |
4582 } | 4582 } |
4583 } else { | 4583 } else { |
4584 EXPECT_EQ(0u, outer->size()); | 4584 EXPECT_EQ(0u, outer->size()); |
4585 } | 4585 } |
4586 outer->clear(); | 4586 outer->clear(); |
4587 Persistent<IntWrapper> deep = IntWrapper::create(42); | 4587 Persistent<IntWrapper> deep = IntWrapper::create(42); |
4588 Persistent<IntWrapper> home = IntWrapper::create(103); | 4588 Persistent<IntWrapper> home = IntWrapper::create(103); |
4589 Persistent<IntWrapper> composite = IntWrapper::create(91); | 4589 Persistent<IntWrapper> composite = IntWrapper::create(91); |
4590 Persistent<HeapVector<Member<IntWrapper>>> keepAlive = new HeapVecto
r<Member<IntWrapper>>(); | 4590 Persistent<HeapVector<Member<IntWrapper>>> keepAlive = new HeapVecto
r<Member<IntWrapper>>(); |
4591 for (int i = 0; i < 10000; i++) { | 4591 for (int i = 0; i < 10000; i++) { |
4592 IntWrapper* value = IntWrapper::create(i); | 4592 IntWrapper* value = IntWrapper::create(i); |
4593 keepAlive->append(value); | 4593 keepAlive->append(value); |
4594 OuterMap::AddResult newEntry = outer->add(value, InnerMap()); | 4594 OuterMap::AddResult newEntry = outer->add(value, InnerMap()); |
4595 newEntry.storedValue->value.add(deep, home); | 4595 newEntry.storedValue->value.add(deep, home); |
4596 newEntry.storedValue->value.add(composite, home); | 4596 newEntry.storedValue->value.add(composite, home); |
4597 } | 4597 } |
4598 composite.clear(); | 4598 composite.clear(); |
4599 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGCForTesting); | 4599 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); |
4600 EXPECT_EQ(10000u, outer->size()); | 4600 EXPECT_EQ(10000u, outer->size()); |
4601 for (int i = 0; i < 10000; i++) { | 4601 for (int i = 0; i < 10000; i++) { |
4602 IntWrapper* value = keepAlive->at(i); | 4602 IntWrapper* value = keepAlive->at(i); |
4603 EXPECT_EQ(1u, outer->get(value).size()); // Other one was delete
d by weak handling. | 4603 EXPECT_EQ(1u, outer->get(value).size()); // Other one was delete
d by weak handling. |
4604 if (i & 1) | 4604 if (i & 1) |
4605 keepAlive->at(i) = nullptr; | 4605 keepAlive->at(i) = nullptr; |
4606 } | 4606 } |
4607 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGCForTesting); | 4607 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); |
4608 EXPECT_EQ(5000u, outer->size()); | 4608 EXPECT_EQ(5000u, outer->size()); |
4609 } | 4609 } |
4610 } | 4610 } |
4611 } | 4611 } |
4612 | 4612 |
4613 class EphemeronWrapper : public GarbageCollected<EphemeronWrapper> { | 4613 class EphemeronWrapper : public GarbageCollected<EphemeronWrapper> { |
4614 public: | 4614 public: |
4615 DEFINE_INLINE_TRACE() | 4615 DEFINE_INLINE_TRACE() |
4616 { | 4616 { |
4617 visitor->trace(m_map); | 4617 visitor->trace(m_map); |
(...skipping 15 matching lines...) Expand all Loading... |
4633 for (int i = 0; i < 100; i++) { | 4633 for (int i = 0; i < 100; i++) { |
4634 EphemeronWrapper* oldHead = chain; | 4634 EphemeronWrapper* oldHead = chain; |
4635 chain = new EphemeronWrapper(); | 4635 chain = new EphemeronWrapper(); |
4636 if (i == 50) | 4636 if (i == 50) |
4637 chain->map().add(key2, oldHead); | 4637 chain->map().add(key2, oldHead); |
4638 else | 4638 else |
4639 chain->map().add(key, oldHead); | 4639 chain->map().add(key, oldHead); |
4640 chain->map().add(IntWrapper::create(103), new EphemeronWrapper()); | 4640 chain->map().add(IntWrapper::create(103), new EphemeronWrapper()); |
4641 } | 4641 } |
4642 | 4642 |
4643 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4643 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4644 | 4644 |
4645 EphemeronWrapper* wrapper = chain; | 4645 EphemeronWrapper* wrapper = chain; |
4646 for (int i = 0; i< 100; i++) { | 4646 for (int i = 0; i< 100; i++) { |
4647 EXPECT_EQ(1u, wrapper->map().size()); | 4647 EXPECT_EQ(1u, wrapper->map().size()); |
4648 if (i == 49) | 4648 if (i == 49) |
4649 wrapper = wrapper->map().get(key2); | 4649 wrapper = wrapper->map().get(key2); |
4650 else | 4650 else |
4651 wrapper = wrapper->map().get(key); | 4651 wrapper = wrapper->map().get(key); |
4652 } | 4652 } |
4653 EXPECT_EQ(nullptr, wrapper); | 4653 EXPECT_EQ(nullptr, wrapper); |
4654 | 4654 |
4655 key2.clear(); | 4655 key2.clear(); |
4656 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4656 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4657 | 4657 |
4658 wrapper = chain; | 4658 wrapper = chain; |
4659 for (int i = 0; i < 50; i++) { | 4659 for (int i = 0; i < 50; i++) { |
4660 EXPECT_EQ(i == 49 ? 0u : 1u, wrapper->map().size()); | 4660 EXPECT_EQ(i == 49 ? 0u : 1u, wrapper->map().size()); |
4661 wrapper = wrapper->map().get(key); | 4661 wrapper = wrapper->map().get(key); |
4662 } | 4662 } |
4663 EXPECT_EQ(nullptr, wrapper); | 4663 EXPECT_EQ(nullptr, wrapper); |
4664 | 4664 |
4665 key.clear(); | 4665 key.clear(); |
4666 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4666 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4667 EXPECT_EQ(0u, chain->map().size()); | 4667 EXPECT_EQ(0u, chain->map().size()); |
4668 } | 4668 } |
4669 | 4669 |
4670 TEST(HeapTest, Ephemeron) | 4670 TEST(HeapTest, Ephemeron) |
4671 { | 4671 { |
4672 typedef HeapHashMap<WeakMember<IntWrapper>, PairWithWeakHandling> WeakPairM
ap; | 4672 typedef HeapHashMap<WeakMember<IntWrapper>, PairWithWeakHandling> WeakPairM
ap; |
4673 typedef HeapHashMap<PairWithWeakHandling, WeakMember<IntWrapper>> PairWeakM
ap; | 4673 typedef HeapHashMap<PairWithWeakHandling, WeakMember<IntWrapper>> PairWeakM
ap; |
4674 typedef HeapHashSet<WeakMember<IntWrapper>> Set; | 4674 typedef HeapHashSet<WeakMember<IntWrapper>> Set; |
4675 | 4675 |
4676 Persistent<WeakPairMap> weakPairMap = new WeakPairMap(); | 4676 Persistent<WeakPairMap> weakPairMap = new WeakPairMap(); |
(...skipping 28 matching lines...) Expand all Loading... |
4705 pairWeakMap2->add(PairWithWeakHandling(pw1, pw2), pw2); | 4705 pairWeakMap2->add(PairWithWeakHandling(pw1, pw2), pw2); |
4706 pairWeakMap2->add(PairWithWeakHandling(pw2, pw1), pw2); | 4706 pairWeakMap2->add(PairWithWeakHandling(pw2, pw1), pw2); |
4707 pairWeakMap2->add(PairWithWeakHandling(pw2, pw2), pw2); | 4707 pairWeakMap2->add(PairWithWeakHandling(pw2, pw2), pw2); |
4708 | 4708 |
4709 | 4709 |
4710 set->add(wp1); | 4710 set->add(wp1); |
4711 set->add(wp2); | 4711 set->add(wp2); |
4712 set->add(pw1); | 4712 set->add(pw1); |
4713 set->add(pw2); | 4713 set->add(pw2); |
4714 | 4714 |
4715 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4715 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4716 | 4716 |
4717 EXPECT_EQ(2u, weakPairMap->size()); | 4717 EXPECT_EQ(2u, weakPairMap->size()); |
4718 EXPECT_EQ(2u, weakPairMap2->size()); | 4718 EXPECT_EQ(2u, weakPairMap2->size()); |
4719 EXPECT_EQ(1u, weakPairMap3->size()); | 4719 EXPECT_EQ(1u, weakPairMap3->size()); |
4720 EXPECT_EQ(2u, weakPairMap4->size()); | 4720 EXPECT_EQ(2u, weakPairMap4->size()); |
4721 | 4721 |
4722 EXPECT_EQ(3u, pairWeakMap->size()); | 4722 EXPECT_EQ(3u, pairWeakMap->size()); |
4723 EXPECT_EQ(4u, pairWeakMap2->size()); | 4723 EXPECT_EQ(4u, pairWeakMap2->size()); |
4724 | 4724 |
4725 EXPECT_EQ(4u, set->size()); | 4725 EXPECT_EQ(4u, set->size()); |
4726 | 4726 |
4727 wp2.clear(); // Kills all entries in the weakPairMaps except the first. | 4727 wp2.clear(); // Kills all entries in the weakPairMaps except the first. |
4728 pw2.clear(); // Kills all entries in the pairWeakMaps except the first. | 4728 pw2.clear(); // Kills all entries in the pairWeakMaps except the first. |
4729 | 4729 |
4730 for (int i = 0; i < 2; i++) { | 4730 for (int i = 0; i < 2; i++) { |
4731 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 4731 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
4732 | 4732 |
4733 EXPECT_EQ(1u, weakPairMap->size()); | 4733 EXPECT_EQ(1u, weakPairMap->size()); |
4734 EXPECT_EQ(0u, weakPairMap2->size()); | 4734 EXPECT_EQ(0u, weakPairMap2->size()); |
4735 EXPECT_EQ(0u, weakPairMap3->size()); | 4735 EXPECT_EQ(0u, weakPairMap3->size()); |
4736 EXPECT_EQ(0u, weakPairMap4->size()); | 4736 EXPECT_EQ(0u, weakPairMap4->size()); |
4737 | 4737 |
4738 EXPECT_EQ(1u, pairWeakMap->size()); | 4738 EXPECT_EQ(1u, pairWeakMap->size()); |
4739 EXPECT_EQ(0u, pairWeakMap2->size()); | 4739 EXPECT_EQ(0u, pairWeakMap2->size()); |
4740 | 4740 |
4741 EXPECT_EQ(2u, set->size()); // wp1 and pw1. | 4741 EXPECT_EQ(2u, set->size()); // wp1 and pw1. |
4742 } | 4742 } |
4743 | 4743 |
4744 wp1.clear(); | 4744 wp1.clear(); |
4745 pw1.clear(); | 4745 pw1.clear(); |
4746 | 4746 |
4747 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4747 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4748 | 4748 |
4749 EXPECT_EQ(0u, weakPairMap->size()); | 4749 EXPECT_EQ(0u, weakPairMap->size()); |
4750 EXPECT_EQ(0u, pairWeakMap->size()); | 4750 EXPECT_EQ(0u, pairWeakMap->size()); |
4751 EXPECT_EQ(0u, set->size()); | 4751 EXPECT_EQ(0u, set->size()); |
4752 } | 4752 } |
4753 | 4753 |
4754 class Link1 : public GarbageCollected<Link1> { | 4754 class Link1 : public GarbageCollected<Link1> { |
4755 public: | 4755 public: |
4756 Link1(IntWrapper* link) : m_link(link) { } | 4756 Link1(IntWrapper* link) : m_link(link) { } |
4757 | 4757 |
(...skipping 10 matching lines...) Expand all Loading... |
4768 | 4768 |
4769 TEST(HeapTest, IndirectStrongToWeak) | 4769 TEST(HeapTest, IndirectStrongToWeak) |
4770 { | 4770 { |
4771 typedef HeapHashMap<WeakMember<IntWrapper>, Member<Link1>> Map; | 4771 typedef HeapHashMap<WeakMember<IntWrapper>, Member<Link1>> Map; |
4772 Persistent<Map> map = new Map(); | 4772 Persistent<Map> map = new Map(); |
4773 Persistent<IntWrapper> deadObject = IntWrapper::create(100); // Named for "D
rowning by Numbers" (1988). | 4773 Persistent<IntWrapper> deadObject = IntWrapper::create(100); // Named for "D
rowning by Numbers" (1988). |
4774 Persistent<IntWrapper> lifeObject = IntWrapper::create(42); | 4774 Persistent<IntWrapper> lifeObject = IntWrapper::create(42); |
4775 map->add(deadObject, new Link1(deadObject)); | 4775 map->add(deadObject, new Link1(deadObject)); |
4776 map->add(lifeObject, new Link1(lifeObject)); | 4776 map->add(lifeObject, new Link1(lifeObject)); |
4777 EXPECT_EQ(2u, map->size()); | 4777 EXPECT_EQ(2u, map->size()); |
4778 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4778 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4779 EXPECT_EQ(2u, map->size()); | 4779 EXPECT_EQ(2u, map->size()); |
4780 EXPECT_EQ(deadObject, map->get(deadObject)->link()); | 4780 EXPECT_EQ(deadObject, map->get(deadObject)->link()); |
4781 EXPECT_EQ(lifeObject, map->get(lifeObject)->link()); | 4781 EXPECT_EQ(lifeObject, map->get(lifeObject)->link()); |
4782 deadObject.clear(); // Now it can live up to its name. | 4782 deadObject.clear(); // Now it can live up to its name. |
4783 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4783 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4784 EXPECT_EQ(1u, map->size()); | 4784 EXPECT_EQ(1u, map->size()); |
4785 EXPECT_EQ(lifeObject, map->get(lifeObject)->link()); | 4785 EXPECT_EQ(lifeObject, map->get(lifeObject)->link()); |
4786 lifeObject.clear(); // Despite its name. | 4786 lifeObject.clear(); // Despite its name. |
4787 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 4787 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
4788 EXPECT_EQ(0u, map->size()); | 4788 EXPECT_EQ(0u, map->size()); |
4789 } | 4789 } |
4790 | 4790 |
4791 static Mutex& mainThreadMutex() | 4791 static Mutex& mainThreadMutex() |
4792 { | 4792 { |
4793 AtomicallyInitializedStaticReference(Mutex, mainMutex, new Mutex); | 4793 AtomicallyInitializedStaticReference(Mutex, mainMutex, new Mutex); |
4794 return mainMutex; | 4794 return mainMutex; |
4795 } | 4795 } |
4796 | 4796 |
4797 static ThreadCondition& mainThreadCondition() | 4797 static ThreadCondition& mainThreadCondition() |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4847 // Wait for the worker thread to have done its initialization, | 4847 // Wait for the worker thread to have done its initialization, |
4848 // IE. the worker allocates an object and then throw aways any | 4848 // IE. the worker allocates an object and then throw aways any |
4849 // pointers to it. | 4849 // pointers to it. |
4850 parkMainThread(); | 4850 parkMainThread(); |
4851 | 4851 |
4852 // Now do a GC. This will not find the worker threads object since it | 4852 // Now do a GC. This will not find the worker threads object since it |
4853 // is not referred from any of the threads. Even a conservative | 4853 // is not referred from any of the threads. Even a conservative |
4854 // GC will not find it. | 4854 // GC will not find it. |
4855 // Also at this point the worker is waiting for the main thread | 4855 // Also at this point the worker is waiting for the main thread |
4856 // to be parked and will not do any sweep of its heap. | 4856 // to be parked and will not do any sweep of its heap. |
4857 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 4857 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
4858 | 4858 |
4859 // Since the worker thread is not sweeping the worker object should | 4859 // Since the worker thread is not sweeping the worker object should |
4860 // not have been finalized. | 4860 // not have been finalized. |
4861 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 4861 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
4862 | 4862 |
4863 // Put the worker thread's object address on the stack and do a | 4863 // Put the worker thread's object address on the stack and do a |
4864 // conservative GC. This should find the worker object, but since | 4864 // conservative GC. This should find the worker object, but since |
4865 // it was dead in the previous GC it should not be traced in this | 4865 // it was dead in the previous GC it should not be traced in this |
4866 // GC. | 4866 // GC. |
4867 uintptr_t stackPtrValue = s_workerObjectPointer; | 4867 uintptr_t stackPtrValue = s_workerObjectPointer; |
4868 s_workerObjectPointer = 0; | 4868 s_workerObjectPointer = 0; |
4869 ASSERT_UNUSED(stackPtrValue, stackPtrValue); | 4869 ASSERT_UNUSED(stackPtrValue, stackPtrValue); |
4870 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGCForTesting); | 4870 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); |
4871 | 4871 |
4872 // Since the worker thread is not sweeping the worker object should | 4872 // Since the worker thread is not sweeping the worker object should |
4873 // not have been finalized. | 4873 // not have been finalized. |
4874 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 4874 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
4875 | 4875 |
4876 // Wake up the worker thread so it can continue with its sweeping. | 4876 // Wake up the worker thread so it can continue with its sweeping. |
4877 // This should finalized the worker object which we test below. | 4877 // This should finalized the worker object which we test below. |
4878 // The worker thread will go back to sleep once sweeping to ensure | 4878 // The worker thread will go back to sleep once sweeping to ensure |
4879 // we don't have thread local GCs until after validating the destructor | 4879 // we don't have thread local GCs until after validating the destructor |
4880 // was called. | 4880 // was called. |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4950 // Wait for the worker thread initialization. The worker | 4950 // Wait for the worker thread initialization. The worker |
4951 // allocates a weak collection where both collection and | 4951 // allocates a weak collection where both collection and |
4952 // contents are kept alive via persistent pointers. | 4952 // contents are kept alive via persistent pointers. |
4953 parkMainThread(); | 4953 parkMainThread(); |
4954 | 4954 |
4955 // Perform two garbage collections where the worker thread does | 4955 // Perform two garbage collections where the worker thread does |
4956 // not wake up in between. This will cause us to remove marks | 4956 // not wake up in between. This will cause us to remove marks |
4957 // and mark unmarked objects dead. The collection on the worker | 4957 // and mark unmarked objects dead. The collection on the worker |
4958 // heap is found through the persistent and the backing should | 4958 // heap is found through the persistent and the backing should |
4959 // be marked. | 4959 // be marked. |
4960 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 4960 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
4961 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGCForTesting); | 4961 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC
WithSweep, Heap::ForcedGC); |
4962 | 4962 |
4963 // Wake up the worker thread so it can continue. It will sweep | 4963 // Wake up the worker thread so it can continue. It will sweep |
4964 // and perform another GC where the backing store of its | 4964 // and perform another GC where the backing store of its |
4965 // collection should be strongified. | 4965 // collection should be strongified. |
4966 wakeWorkerThread(); | 4966 wakeWorkerThread(); |
4967 | 4967 |
4968 // Wait for the worker thread to sweep its heaps before checking. | 4968 // Wait for the worker thread to sweep its heaps before checking. |
4969 { | 4969 { |
4970 SafePointScope scope(ThreadState::NoHeapPointersOnStack); | 4970 SafePointScope scope(ThreadState::NoHeapPointersOnStack); |
4971 parkMainThread(); | 4971 parkMainThread(); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5014 { | 5014 { |
5015 MutexLocker locker(workerThreadMutex()); | 5015 MutexLocker locker(workerThreadMutex()); |
5016 | 5016 |
5017 ThreadState::attach(); | 5017 ThreadState::attach(); |
5018 | 5018 |
5019 { | 5019 { |
5020 Persistent<HeapHashSet<WeakMember<IntWrapper>>> collection = allocat
eCollection(); | 5020 Persistent<HeapHashSet<WeakMember<IntWrapper>>> collection = allocat
eCollection(); |
5021 { | 5021 { |
5022 // Prevent weak processing with an iterator and GC. | 5022 // Prevent weak processing with an iterator and GC. |
5023 HeapHashSet<WeakMember<IntWrapper>>::iterator it = collection->b
egin(); | 5023 HeapHashSet<WeakMember<IntWrapper>>::iterator it = collection->b
egin(); |
5024 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadSta
te::GCWithSweep, Heap::ForcedGCForTesting); | 5024 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadSta
te::GCWithSweep, Heap::ForcedGC); |
5025 | 5025 |
5026 // The backing should be strongified because of the iterator. | 5026 // The backing should be strongified because of the iterator. |
5027 EXPECT_EQ(6u, collection->size()); | 5027 EXPECT_EQ(6u, collection->size()); |
5028 EXPECT_EQ(32, (*it)->value()); | 5028 EXPECT_EQ(32, (*it)->value()); |
5029 } | 5029 } |
5030 | 5030 |
5031 // Disregarding the iterator but keeping the collection alive | 5031 // Disregarding the iterator but keeping the collection alive |
5032 // with a persistent should lead to weak processing. | 5032 // with a persistent should lead to weak processing. |
5033 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGCForTesting); | 5033 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); |
5034 EXPECT_EQ(0u, collection->size()); | 5034 EXPECT_EQ(0u, collection->size()); |
5035 } | 5035 } |
5036 | 5036 |
5037 wakeMainThread(); | 5037 wakeMainThread(); |
5038 ThreadState::detach(); | 5038 ThreadState::detach(); |
5039 } | 5039 } |
5040 | 5040 |
5041 static volatile uintptr_t s_workerObjectPointer; | 5041 static volatile uintptr_t s_workerObjectPointer; |
5042 }; | 5042 }; |
5043 | 5043 |
5044 TEST(HeapTest, ThreadedStrongification) | 5044 TEST(HeapTest, ThreadedStrongification) |
5045 { | 5045 { |
5046 ThreadedStrongificationTester::test(); | 5046 ThreadedStrongificationTester::test(); |
5047 } | 5047 } |
5048 | 5048 |
5049 static bool allocateAndReturnBool() | 5049 static bool allocateAndReturnBool() |
5050 { | 5050 { |
5051 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWithSw
eep, Heap::ForcedGCForTesting); | 5051 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWithSw
eep, Heap::ForcedGC); |
5052 return true; | 5052 return true; |
5053 } | 5053 } |
5054 | 5054 |
5055 class MixinWithGarbageCollectionInConstructor : public GarbageCollectedMixin { | 5055 class MixinWithGarbageCollectionInConstructor : public GarbageCollectedMixin { |
5056 public: | 5056 public: |
5057 MixinWithGarbageCollectionInConstructor() : m_dummy(allocateAndReturnBool()) | 5057 MixinWithGarbageCollectionInConstructor() : m_dummy(allocateAndReturnBool()) |
5058 { | 5058 { |
5059 } | 5059 } |
5060 private: | 5060 private: |
5061 bool m_dummy; | 5061 bool m_dummy; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5145 // Park the main thread until the worker thread has initialized. | 5145 // Park the main thread until the worker thread has initialized. |
5146 parkMainThread(); | 5146 parkMainThread(); |
5147 | 5147 |
5148 { | 5148 { |
5149 SafePointAwareMutexLocker recursiveLocker(recursiveMutex()); | 5149 SafePointAwareMutexLocker recursiveLocker(recursiveMutex()); |
5150 | 5150 |
5151 // Let the worker try to acquire the above mutex. It won't get it | 5151 // Let the worker try to acquire the above mutex. It won't get it |
5152 // until the main thread has done its GC. | 5152 // until the main thread has done its GC. |
5153 wakeWorkerThread(); | 5153 wakeWorkerThread(); |
5154 | 5154 |
5155 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGCForTesting); | 5155 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState
::GCWithSweep, Heap::ForcedGC); |
5156 | 5156 |
5157 // The worker thread should not have swept yet since it is waiting | 5157 // The worker thread should not have swept yet since it is waiting |
5158 // to get the global mutex. | 5158 // to get the global mutex. |
5159 EXPECT_EQ(0, DestructorLockingObject::s_destructorCalls); | 5159 EXPECT_EQ(0, DestructorLockingObject::s_destructorCalls); |
5160 } | 5160 } |
5161 // At this point the main thread releases the global lock and the worker | 5161 // At this point the main thread releases the global lock and the worker |
5162 // can acquire it and do its sweep of its heaps. Just wait for the worke
r | 5162 // can acquire it and do its sweep of its heaps. Just wait for the worke
r |
5163 // to complete its sweep and check the result. | 5163 // to complete its sweep and check the result. |
5164 parkMainThread(); | 5164 parkMainThread(); |
5165 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); | 5165 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5282 m_value = x.m_value; | 5282 m_value = x.m_value; |
5283 return *this; | 5283 return *this; |
5284 } | 5284 } |
5285 | 5285 |
5286 enum DeletedMarker { | 5286 enum DeletedMarker { |
5287 DeletedValue | 5287 DeletedValue |
5288 }; | 5288 }; |
5289 | 5289 |
5290 AllocatesOnAssignment(const AllocatesOnAssignment& other) | 5290 AllocatesOnAssignment(const AllocatesOnAssignment& other) |
5291 { | 5291 { |
5292 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGCForTesting); | 5292 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi
thSweep, Heap::ForcedGC); |
5293 m_value = new IntWrapper(other.m_value->value()); | 5293 m_value = new IntWrapper(other.m_value->value()); |
5294 } | 5294 } |
5295 | 5295 |
5296 AllocatesOnAssignment(DeletedMarker) | 5296 AllocatesOnAssignment(DeletedMarker) |
5297 : m_value(reinterpret_cast<IntWrapper*>(-1)) { } | 5297 : m_value(reinterpret_cast<IntWrapper*>(-1)) { } |
5298 | 5298 |
5299 inline bool isDeleted() const { return m_value == reinterpret_cast<IntWrappe
r*>(-1); } | 5299 inline bool isDeleted() const { return m_value == reinterpret_cast<IntWrappe
r*>(-1); } |
5300 | 5300 |
5301 DEFINE_INLINE_VIRTUAL_TRACE() | 5301 DEFINE_INLINE_VIRTUAL_TRACE() |
5302 { | 5302 { |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5422 DEFINE_INLINE_TRACE() { } | 5422 DEFINE_INLINE_TRACE() { } |
5423 | 5423 |
5424 static Persistent<IntNode>* s_node; | 5424 static Persistent<IntNode>* s_node; |
5425 }; | 5425 }; |
5426 | 5426 |
5427 Persistent<IntNode>* NonNodeAllocatingNodeInDestructor::s_node = 0; | 5427 Persistent<IntNode>* NonNodeAllocatingNodeInDestructor::s_node = 0; |
5428 | 5428 |
5429 TEST(HeapTest, NonNodeAllocatingNodeInDestructor) | 5429 TEST(HeapTest, NonNodeAllocatingNodeInDestructor) |
5430 { | 5430 { |
5431 new NonNodeAllocatingNodeInDestructor(); | 5431 new NonNodeAllocatingNodeInDestructor(); |
5432 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 5432 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
5433 EXPECT_EQ(10, (*NonNodeAllocatingNodeInDestructor::s_node)->value()); | 5433 EXPECT_EQ(10, (*NonNodeAllocatingNodeInDestructor::s_node)->value()); |
5434 delete NonNodeAllocatingNodeInDestructor::s_node; | 5434 delete NonNodeAllocatingNodeInDestructor::s_node; |
5435 NonNodeAllocatingNodeInDestructor::s_node = 0; | 5435 NonNodeAllocatingNodeInDestructor::s_node = 0; |
5436 } | 5436 } |
5437 | 5437 |
5438 class TraceTypeEagerly1 : public GarbageCollected<TraceTypeEagerly1> { }; | 5438 class TraceTypeEagerly1 : public GarbageCollected<TraceTypeEagerly1> { }; |
5439 class TraceTypeEagerly2 : public TraceTypeEagerly1 { }; | 5439 class TraceTypeEagerly2 : public TraceTypeEagerly1 { }; |
5440 | 5440 |
5441 class TraceTypeNonEagerly1 { }; | 5441 class TraceTypeNonEagerly1 { }; |
5442 WILL_NOT_BE_EAGERLY_TRACED_CLASS(TraceTypeNonEagerly1); | 5442 WILL_NOT_BE_EAGERLY_TRACED_CLASS(TraceTypeNonEagerly1); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5490 int DeepEagerly::sTraceLazy = 0; | 5490 int DeepEagerly::sTraceLazy = 0; |
5491 | 5491 |
5492 TEST(HeapTest, TraceDeepEagerly) | 5492 TEST(HeapTest, TraceDeepEagerly) |
5493 { | 5493 { |
5494 #if !ENABLE(ASSERT) | 5494 #if !ENABLE(ASSERT) |
5495 DeepEagerly* obj = nullptr; | 5495 DeepEagerly* obj = nullptr; |
5496 for (int i = 0; i < 10000000; i++) | 5496 for (int i = 0; i < 10000000; i++) |
5497 obj = new DeepEagerly(obj); | 5497 obj = new DeepEagerly(obj); |
5498 | 5498 |
5499 Persistent<DeepEagerly> persistent(obj); | 5499 Persistent<DeepEagerly> persistent(obj); |
5500 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGCForTesting); | 5500 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith
Sweep, Heap::ForcedGC); |
5501 | 5501 |
5502 // Verify that the DeepEagerly chain isn't completely unravelled | 5502 // Verify that the DeepEagerly chain isn't completely unravelled |
5503 // by performing eager trace() calls, but the explicit mark | 5503 // by performing eager trace() calls, but the explicit mark |
5504 // stack is switched once some nesting limit is exceeded. | 5504 // stack is switched once some nesting limit is exceeded. |
5505 EXPECT_GT(DeepEagerly::sTraceLazy, 2); | 5505 EXPECT_GT(DeepEagerly::sTraceLazy, 2); |
5506 #endif | 5506 #endif |
5507 } | 5507 } |
5508 | 5508 |
5509 TEST(HeapTest, DequeExpand) | 5509 TEST(HeapTest, DequeExpand) |
5510 { | 5510 { |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5692 { | 5692 { |
5693 Persistent<ClassWithMember> object = ClassWithMember::create(); | 5693 Persistent<ClassWithMember> object = ClassWithMember::create(); |
5694 EXPECT_EQ(0, object->traceCount()); | 5694 EXPECT_EQ(0, object->traceCount()); |
5695 TestMixinAllocatingObject* mixin = TestMixinAllocatingObject::create(object.
get()); | 5695 TestMixinAllocatingObject* mixin = TestMixinAllocatingObject::create(object.
get()); |
5696 EXPECT_TRUE(mixin); | 5696 EXPECT_TRUE(mixin); |
5697 EXPECT_GT(object->traceCount(), 0); | 5697 EXPECT_GT(object->traceCount(), 0); |
5698 EXPECT_GT(mixin->traceCount(), 0); | 5698 EXPECT_GT(mixin->traceCount(), 0); |
5699 } | 5699 } |
5700 | 5700 |
5701 } // namespace blink | 5701 } // namespace blink |
OLD | NEW |