| 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 |