| 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 30 matching lines...) Expand all Loading... |
| 41 #include "public/platform/WebTaskRunner.h" | 41 #include "public/platform/WebTaskRunner.h" |
| 42 #include "public/platform/WebTraceLocation.h" | 42 #include "public/platform/WebTraceLocation.h" |
| 43 #include "testing/gtest/include/gtest/gtest.h" | 43 #include "testing/gtest/include/gtest/gtest.h" |
| 44 #include "wtf/HashTraits.h" | 44 #include "wtf/HashTraits.h" |
| 45 #include "wtf/LinkedHashSet.h" | 45 #include "wtf/LinkedHashSet.h" |
| 46 | 46 |
| 47 namespace blink { | 47 namespace blink { |
| 48 | 48 |
| 49 static void preciselyCollectGarbage() | 49 static void preciselyCollectGarbage() |
| 50 { | 50 { |
| 51 Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, B
linkGC::ForcedGC); | 51 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSw
eep, BlinkGC::ForcedGC); |
| 52 } | 52 } |
| 53 | 53 |
| 54 static void conservativelyCollectGarbage() | 54 static void conservativelyCollectGarbage() |
| 55 { | 55 { |
| 56 Heap::collectGarbage(BlinkGC::HeapPointersOnStack, BlinkGC::GCWithSweep, Bli
nkGC::ForcedGC); | 56 ThreadHeap::collectGarbage(BlinkGC::HeapPointersOnStack, BlinkGC::GCWithSwee
p, BlinkGC::ForcedGC); |
| 57 } | 57 } |
| 58 | 58 |
| 59 class IntWrapper : public GarbageCollectedFinalized<IntWrapper> { | 59 class IntWrapper : public GarbageCollectedFinalized<IntWrapper> { |
| 60 public: | 60 public: |
| 61 static IntWrapper* create(int x) | 61 static IntWrapper* create(int x) |
| 62 { | 62 { |
| 63 return new IntWrapper(x); | 63 return new IntWrapper(x); |
| 64 } | 64 } |
| 65 | 65 |
| 66 virtual ~IntWrapper() | 66 virtual ~IntWrapper() |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 bool isHashTableDeletedValue() const { return first == reinterpret_cast<IntW
rapper*>(-1); } | 150 bool isHashTableDeletedValue() const { return first == reinterpret_cast<IntW
rapper*>(-1); } |
| 151 | 151 |
| 152 // Since we don't allocate independent objects of this type, we don't need | 152 // Since we don't allocate independent objects of this type, we don't need |
| 153 // a regular trace method. Instead, we use a traceInCollection method. If | 153 // a regular trace method. Instead, we use a traceInCollection method. If |
| 154 // the entry should be deleted from the collection we return true and don't | 154 // the entry should be deleted from the collection we return true and don't |
| 155 // trace the strong pointer. | 155 // trace the strong pointer. |
| 156 template<typename VisitorDispatcher> | 156 template<typename VisitorDispatcher> |
| 157 bool traceInCollection(VisitorDispatcher visitor, WTF::ShouldWeakPointersBeM
arkedStrongly strongify) | 157 bool traceInCollection(VisitorDispatcher visitor, WTF::ShouldWeakPointersBeM
arkedStrongly strongify) |
| 158 { | 158 { |
| 159 visitor->traceInCollection(second, strongify); | 159 visitor->traceInCollection(second, strongify); |
| 160 if (!Heap::isHeapObjectAlive(second)) | 160 if (!ThreadHeap::isHeapObjectAlive(second)) |
| 161 return true; | 161 return true; |
| 162 // FIXME: traceInCollection is also called from WeakProcessing to check
if the entry is dead. | 162 // FIXME: traceInCollection is also called from WeakProcessing to check
if the entry is dead. |
| 163 // The below if avoids calling trace in that case by only calling trace
when |first| is not yet marked. | 163 // The below if avoids calling trace in that case by only calling trace
when |first| is not yet marked. |
| 164 if (!Heap::isHeapObjectAlive(first)) | 164 if (!ThreadHeap::isHeapObjectAlive(first)) |
| 165 visitor->trace(first); | 165 visitor->trace(first); |
| 166 return false; | 166 return false; |
| 167 } | 167 } |
| 168 }; | 168 }; |
| 169 | 169 |
| 170 template<typename T> struct WeakHandlingHashTraits : WTF::SimpleClassHashTraits<
T> { | 170 template<typename T> struct WeakHandlingHashTraits : WTF::SimpleClassHashTraits<
T> { |
| 171 // We want to treat the object as a weak object in the sense that it can | 171 // We want to treat the object as a weak object in the sense that it can |
| 172 // disappear from hash sets and hash maps. | 172 // disappear from hash sets and hash maps. |
| 173 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; | 173 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; |
| 174 // Normally whether or not an object needs tracing is inferred | 174 // Normally whether or not an object needs tracing is inferred |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 | 238 |
| 239 class TestGCScope { | 239 class TestGCScope { |
| 240 public: | 240 public: |
| 241 explicit TestGCScope(BlinkGC::StackState state) | 241 explicit TestGCScope(BlinkGC::StackState state) |
| 242 : m_state(ThreadState::current()) | 242 : m_state(ThreadState::current()) |
| 243 , m_safePointScope(state) | 243 , m_safePointScope(state) |
| 244 , m_parkedAllThreads(false) | 244 , m_parkedAllThreads(false) |
| 245 { | 245 { |
| 246 ASSERT(m_state->checkThread()); | 246 ASSERT(m_state->checkThread()); |
| 247 if (LIKELY(ThreadState::stopThreads())) { | 247 if (LIKELY(ThreadState::stopThreads())) { |
| 248 Heap::preGC(); | 248 ThreadHeap::preGC(); |
| 249 m_parkedAllThreads = true; | 249 m_parkedAllThreads = true; |
| 250 } | 250 } |
| 251 } | 251 } |
| 252 | 252 |
| 253 bool allThreadsParked() { return m_parkedAllThreads; } | 253 bool allThreadsParked() { return m_parkedAllThreads; } |
| 254 | 254 |
| 255 ~TestGCScope() | 255 ~TestGCScope() |
| 256 { | 256 { |
| 257 // Only cleanup if we parked all threads in which case the GC happened | 257 // Only cleanup if we parked all threads in which case the GC happened |
| 258 // and we need to resume the other threads. | 258 // and we need to resume the other threads. |
| 259 if (LIKELY(m_parkedAllThreads)) { | 259 if (LIKELY(m_parkedAllThreads)) { |
| 260 Heap::postGC(BlinkGC::GCWithSweep); | 260 ThreadHeap::postGC(BlinkGC::GCWithSweep); |
| 261 ThreadState::resumeThreads(); | 261 ThreadState::resumeThreads(); |
| 262 } | 262 } |
| 263 } | 263 } |
| 264 | 264 |
| 265 private: | 265 private: |
| 266 ThreadState* m_state; | 266 ThreadState* m_state; |
| 267 SafePointScope m_safePointScope; | 267 SafePointScope m_safePointScope; |
| 268 bool m_parkedAllThreads; // False if we fail to park all threads | 268 bool m_parkedAllThreads; // False if we fail to park all threads |
| 269 }; | 269 }; |
| 270 | 270 |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 private: | 408 private: |
| 409 static const int s_arraySize = 1000; | 409 static const int s_arraySize = 1000; |
| 410 int8_t m_array[s_arraySize]; | 410 int8_t m_array[s_arraySize]; |
| 411 }; | 411 }; |
| 412 | 412 |
| 413 // Do several GCs to make sure that later GCs don't free up old memory from | 413 // Do several GCs to make sure that later GCs don't free up old memory from |
| 414 // previously run tests in this process. | 414 // previously run tests in this process. |
| 415 static void clearOutOldGarbage() | 415 static void clearOutOldGarbage() |
| 416 { | 416 { |
| 417 while (true) { | 417 while (true) { |
| 418 size_t used = Heap::objectPayloadSizeForTesting(); | 418 size_t used = ThreadHeap::objectPayloadSizeForTesting(); |
| 419 preciselyCollectGarbage(); | 419 preciselyCollectGarbage(); |
| 420 if (Heap::objectPayloadSizeForTesting() >= used) | 420 if (ThreadHeap::objectPayloadSizeForTesting() >= used) |
| 421 break; | 421 break; |
| 422 } | 422 } |
| 423 } | 423 } |
| 424 | 424 |
| 425 class OffHeapInt : public RefCounted<OffHeapInt> { | 425 class OffHeapInt : public RefCounted<OffHeapInt> { |
| 426 public: | 426 public: |
| 427 static RefPtr<OffHeapInt> create(int x) | 427 static RefPtr<OffHeapInt> create(int x) |
| 428 { | 428 { |
| 429 return adoptRef(new OffHeapInt(x)); | 429 return adoptRef(new OffHeapInt(x)); |
| 430 } | 430 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 537 | 537 |
| 538 if (gcCount < gcPerThread) { | 538 if (gcCount < gcPerThread) { |
| 539 preciselyCollectGarbage(); | 539 preciselyCollectGarbage(); |
| 540 gcCount++; | 540 gcCount++; |
| 541 atomicIncrement(&m_gcCount); | 541 atomicIncrement(&m_gcCount); |
| 542 } | 542 } |
| 543 | 543 |
| 544 // Taking snapshot shouldn't have any bad side effect. | 544 // Taking snapshot shouldn't have any bad side effect. |
| 545 // TODO(haraken): This snapshot GC causes crashes, so disable | 545 // TODO(haraken): This snapshot GC causes crashes, so disable |
| 546 // it at the moment. Fix the crash and enable it. | 546 // it at the moment. Fix the crash and enable it. |
| 547 // Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC:
:TakeSnapshot, BlinkGC::ForcedGC); | 547 // ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, Bl
inkGC::TakeSnapshot, BlinkGC::ForcedGC); |
| 548 preciselyCollectGarbage(); | 548 preciselyCollectGarbage(); |
| 549 EXPECT_EQ(wrapper->value(), 0x0bbac0de); | 549 EXPECT_EQ(wrapper->value(), 0x0bbac0de); |
| 550 EXPECT_EQ((*globalPersistent)->value(), 0x0ed0cabb); | 550 EXPECT_EQ((*globalPersistent)->value(), 0x0ed0cabb); |
| 551 } | 551 } |
| 552 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | 552 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); |
| 553 testing::yieldCurrentThread(); | 553 testing::yieldCurrentThread(); |
| 554 } | 554 } |
| 555 | 555 |
| 556 // Intentionally leak the cross-thread persistent so as to verify | 556 // Intentionally leak the cross-thread persistent so as to verify |
| 557 // that later GCs correctly handle cross-thread persistents that | 557 // that later GCs correctly handle cross-thread persistents that |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 | 592 |
| 593 if (gcCount < gcPerThread) { | 593 if (gcCount < gcPerThread) { |
| 594 preciselyCollectGarbage(); | 594 preciselyCollectGarbage(); |
| 595 gcCount++; | 595 gcCount++; |
| 596 atomicIncrement(&m_gcCount); | 596 atomicIncrement(&m_gcCount); |
| 597 } | 597 } |
| 598 | 598 |
| 599 // Taking snapshot shouldn't have any bad side effect. | 599 // Taking snapshot shouldn't have any bad side effect. |
| 600 // TODO(haraken): This snapshot GC causes crashes, so disable | 600 // TODO(haraken): This snapshot GC causes crashes, so disable |
| 601 // it at the moment. Fix the crash and enable it. | 601 // it at the moment. Fix the crash and enable it. |
| 602 // Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC:
:TakeSnapshot, BlinkGC::ForcedGC); | 602 // ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, Bl
inkGC::TakeSnapshot, BlinkGC::ForcedGC); |
| 603 preciselyCollectGarbage(); | 603 preciselyCollectGarbage(); |
| 604 EXPECT_TRUE(weakMap->isEmpty()); | 604 EXPECT_TRUE(weakMap->isEmpty()); |
| 605 EXPECT_TRUE(weakMap2.isEmpty()); | 605 EXPECT_TRUE(weakMap2.isEmpty()); |
| 606 } | 606 } |
| 607 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); | 607 SafePointScope scope(BlinkGC::NoHeapPointersOnStack); |
| 608 testing::yieldCurrentThread(); | 608 testing::yieldCurrentThread(); |
| 609 } | 609 } |
| 610 ThreadState::detach(); | 610 ThreadState::detach(); |
| 611 atomicDecrement(&m_threadsToFinish); | 611 atomicDecrement(&m_threadsToFinish); |
| 612 } | 612 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 | 713 |
| 714 class ClassWithMember : public GarbageCollected<ClassWithMember> { | 714 class ClassWithMember : public GarbageCollected<ClassWithMember> { |
| 715 public: | 715 public: |
| 716 static ClassWithMember* create() | 716 static ClassWithMember* create() |
| 717 { | 717 { |
| 718 return new ClassWithMember(); | 718 return new ClassWithMember(); |
| 719 } | 719 } |
| 720 | 720 |
| 721 DEFINE_INLINE_TRACE() | 721 DEFINE_INLINE_TRACE() |
| 722 { | 722 { |
| 723 EXPECT_TRUE(Heap::isHeapObjectAlive(this)); | 723 EXPECT_TRUE(ThreadHeap::isHeapObjectAlive(this)); |
| 724 if (!traceCount()) | 724 if (!traceCount()) |
| 725 EXPECT_FALSE(Heap::isHeapObjectAlive(m_traceCounter)); | 725 EXPECT_FALSE(ThreadHeap::isHeapObjectAlive(m_traceCounter)); |
| 726 else | 726 else |
| 727 EXPECT_TRUE(Heap::isHeapObjectAlive(m_traceCounter)); | 727 EXPECT_TRUE(ThreadHeap::isHeapObjectAlive(m_traceCounter)); |
| 728 | 728 |
| 729 visitor->trace(m_traceCounter); | 729 visitor->trace(m_traceCounter); |
| 730 } | 730 } |
| 731 | 731 |
| 732 int traceCount() { return m_traceCounter->traceCount(); } | 732 int traceCount() { return m_traceCounter->traceCount(); } |
| 733 | 733 |
| 734 private: | 734 private: |
| 735 ClassWithMember() | 735 ClassWithMember() |
| 736 : m_traceCounter(TraceCounter::create()) | 736 : m_traceCounter(TraceCounter::create()) |
| 737 { } | 737 { } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 // Override operator new to allocate IntNode subtype objects onto | 769 // Override operator new to allocate IntNode subtype objects onto |
| 770 // the dedicated heap for blink::Node. | 770 // the dedicated heap for blink::Node. |
| 771 // | 771 // |
| 772 // TODO(haraken): untangling the heap unit tests from Blink would | 772 // TODO(haraken): untangling the heap unit tests from Blink would |
| 773 // simplify and avoid running into this problem - http://crbug.com/425381 | 773 // simplify and avoid running into this problem - http://crbug.com/425381 |
| 774 GC_PLUGIN_IGNORE("crbug.com/443854") | 774 GC_PLUGIN_IGNORE("crbug.com/443854") |
| 775 void* operator new(size_t size) | 775 void* operator new(size_t size) |
| 776 { | 776 { |
| 777 ThreadState* state = ThreadState::current(); | 777 ThreadState* state = ThreadState::current(); |
| 778 const char* typeName = WTF_HEAP_PROFILER_TYPE_NAME(IntNode); | 778 const char* typeName = WTF_HEAP_PROFILER_TYPE_NAME(IntNode); |
| 779 return Heap::allocateOnArenaIndex(state, size, BlinkGC::NodeArenaIndex,
GCInfoTrait<IntNode>::index(), typeName); | 779 return ThreadHeap::allocateOnArenaIndex(state, size, BlinkGC::NodeArenaI
ndex, GCInfoTrait<IntNode>::index(), typeName); |
| 780 } | 780 } |
| 781 | 781 |
| 782 static IntNode* create(int i) | 782 static IntNode* create(int i) |
| 783 { | 783 { |
| 784 return new IntNode(i); | 784 return new IntNode(i); |
| 785 } | 785 } |
| 786 | 786 |
| 787 DEFINE_INLINE_TRACE() { } | 787 DEFINE_INLINE_TRACE() { } |
| 788 | 788 |
| 789 int value() { return m_value; } | 789 int value() { return m_value; } |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1093 } | 1093 } |
| 1094 | 1094 |
| 1095 DEFINE_INLINE_VIRTUAL_TRACE() | 1095 DEFINE_INLINE_VIRTUAL_TRACE() |
| 1096 { | 1096 { |
| 1097 visitor->trace(m_strongBar); | 1097 visitor->trace(m_strongBar); |
| 1098 visitor->template registerWeakMembers<Weak, &Weak::zapWeakMembers>(this)
; | 1098 visitor->template registerWeakMembers<Weak, &Weak::zapWeakMembers>(this)
; |
| 1099 } | 1099 } |
| 1100 | 1100 |
| 1101 void zapWeakMembers(Visitor* visitor) | 1101 void zapWeakMembers(Visitor* visitor) |
| 1102 { | 1102 { |
| 1103 if (!Heap::isHeapObjectAlive(m_weakBar)) | 1103 if (!ThreadHeap::isHeapObjectAlive(m_weakBar)) |
| 1104 m_weakBar = 0; | 1104 m_weakBar = 0; |
| 1105 } | 1105 } |
| 1106 | 1106 |
| 1107 bool strongIsThere() { return !!m_strongBar; } | 1107 bool strongIsThere() { return !!m_strongBar; } |
| 1108 bool weakIsThere() { return !!m_weakBar; } | 1108 bool weakIsThere() { return !!m_weakBar; } |
| 1109 | 1109 |
| 1110 private: | 1110 private: |
| 1111 Weak(Bar* strongBar, Bar* weakBar) | 1111 Weak(Bar* strongBar, Bar* weakBar) |
| 1112 : Bar() | 1112 : Bar() |
| 1113 , m_strongBar(strongBar) | 1113 , m_strongBar(strongBar) |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1288 static FinalizationObserver* create(T* data) { return new FinalizationObserv
er(data); } | 1288 static FinalizationObserver* create(T* data) { return new FinalizationObserv
er(data); } |
| 1289 bool didCallWillFinalize() const { return m_didCallWillFinalize; } | 1289 bool didCallWillFinalize() const { return m_didCallWillFinalize; } |
| 1290 | 1290 |
| 1291 DEFINE_INLINE_TRACE() | 1291 DEFINE_INLINE_TRACE() |
| 1292 { | 1292 { |
| 1293 visitor->template registerWeakMembers<FinalizationObserver<T>, &Finaliza
tionObserver<T>::zapWeakMembers>(this); | 1293 visitor->template registerWeakMembers<FinalizationObserver<T>, &Finaliza
tionObserver<T>::zapWeakMembers>(this); |
| 1294 } | 1294 } |
| 1295 | 1295 |
| 1296 void zapWeakMembers(Visitor* visitor) | 1296 void zapWeakMembers(Visitor* visitor) |
| 1297 { | 1297 { |
| 1298 if (m_data && !Heap::isHeapObjectAlive(m_data)) { | 1298 if (m_data && !ThreadHeap::isHeapObjectAlive(m_data)) { |
| 1299 m_data->willFinalize(); | 1299 m_data->willFinalize(); |
| 1300 m_data = nullptr; | 1300 m_data = nullptr; |
| 1301 m_didCallWillFinalize = true; | 1301 m_didCallWillFinalize = true; |
| 1302 } | 1302 } |
| 1303 } | 1303 } |
| 1304 | 1304 |
| 1305 private: | 1305 private: |
| 1306 FinalizationObserver(T* data) | 1306 FinalizationObserver(T* data) |
| 1307 : m_data(data) | 1307 : m_data(data) |
| 1308 , m_didCallWillFinalize(false) | 1308 , m_didCallWillFinalize(false) |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1610 static const size_t s_length = 1024; | 1610 static const size_t s_length = 1024; |
| 1611 char m_data[s_length]; | 1611 char m_data[s_length]; |
| 1612 }; | 1612 }; |
| 1613 | 1613 |
| 1614 int OneKiloByteObject::s_destructorCalls = 0; | 1614 int OneKiloByteObject::s_destructorCalls = 0; |
| 1615 | 1615 |
| 1616 class DynamicallySizedObject : public GarbageCollected<DynamicallySizedObject> { | 1616 class DynamicallySizedObject : public GarbageCollected<DynamicallySizedObject> { |
| 1617 public: | 1617 public: |
| 1618 static DynamicallySizedObject* create(size_t size) | 1618 static DynamicallySizedObject* create(size_t size) |
| 1619 { | 1619 { |
| 1620 void* slot = Heap::allocate<DynamicallySizedObject>(size); | 1620 void* slot = ThreadHeap::allocate<DynamicallySizedObject>(size); |
| 1621 return new (slot) DynamicallySizedObject(); | 1621 return new (slot) DynamicallySizedObject(); |
| 1622 } | 1622 } |
| 1623 | 1623 |
| 1624 void* operator new(std::size_t, void* location) | 1624 void* operator new(std::size_t, void* location) |
| 1625 { | 1625 { |
| 1626 return location; | 1626 return location; |
| 1627 } | 1627 } |
| 1628 | 1628 |
| 1629 uint8_t get(int i) | 1629 uint8_t get(int i) |
| 1630 { | 1630 { |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1756 } | 1756 } |
| 1757 | 1757 |
| 1758 TEST(HeapTest, ThreadPersistent) | 1758 TEST(HeapTest, ThreadPersistent) |
| 1759 { | 1759 { |
| 1760 ThreadPersistentHeapTester::test(); | 1760 ThreadPersistentHeapTester::test(); |
| 1761 } | 1761 } |
| 1762 | 1762 |
| 1763 TEST(HeapTest, BasicFunctionality) | 1763 TEST(HeapTest, BasicFunctionality) |
| 1764 { | 1764 { |
| 1765 clearOutOldGarbage(); | 1765 clearOutOldGarbage(); |
| 1766 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); | 1766 size_t initialObjectPayloadSize = ThreadHeap::objectPayloadSizeForTesting(); |
| 1767 { | 1767 { |
| 1768 size_t slack = 0; | 1768 size_t slack = 0; |
| 1769 | 1769 |
| 1770 // When the test starts there may already have been leaked some memory | 1770 // When the test starts there may already have been leaked some memory |
| 1771 // on the heap, so we establish a base line. | 1771 // on the heap, so we establish a base line. |
| 1772 size_t baseLevel = initialObjectPayloadSize; | 1772 size_t baseLevel = initialObjectPayloadSize; |
| 1773 bool testPagesAllocated = !baseLevel; | 1773 bool testPagesAllocated = !baseLevel; |
| 1774 if (testPagesAllocated) | 1774 if (testPagesAllocated) |
| 1775 EXPECT_EQ(Heap::heapStats().allocatedSpace(), 0ul); | 1775 EXPECT_EQ(ThreadHeap::heapStats().allocatedSpace(), 0ul); |
| 1776 | 1776 |
| 1777 // This allocates objects on the general heap which should add a page of
memory. | 1777 // This allocates objects on the general heap which should add a page of
memory. |
| 1778 DynamicallySizedObject* alloc32 = DynamicallySizedObject::create(32); | 1778 DynamicallySizedObject* alloc32 = DynamicallySizedObject::create(32); |
| 1779 slack += 4; | 1779 slack += 4; |
| 1780 memset(alloc32, 40, 32); | 1780 memset(alloc32, 40, 32); |
| 1781 DynamicallySizedObject* alloc64 = DynamicallySizedObject::create(64); | 1781 DynamicallySizedObject* alloc64 = DynamicallySizedObject::create(64); |
| 1782 slack += 4; | 1782 slack += 4; |
| 1783 memset(alloc64, 27, 64); | 1783 memset(alloc64, 27, 64); |
| 1784 | 1784 |
| 1785 size_t total = 96; | 1785 size_t total = 96; |
| 1786 | 1786 |
| 1787 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), s
lack); | 1787 CheckWithSlack(baseLevel + total, ThreadHeap::objectPayloadSizeForTestin
g(), slack); |
| 1788 if (testPagesAllocated) | 1788 if (testPagesAllocated) |
| 1789 EXPECT_EQ(Heap::heapStats().allocatedSpace(), blinkPageSize * 2); | 1789 EXPECT_EQ(ThreadHeap::heapStats().allocatedSpace(), blinkPageSize *
2); |
| 1790 | 1790 |
| 1791 EXPECT_EQ(alloc32->get(0), 40); | 1791 EXPECT_EQ(alloc32->get(0), 40); |
| 1792 EXPECT_EQ(alloc32->get(31), 40); | 1792 EXPECT_EQ(alloc32->get(31), 40); |
| 1793 EXPECT_EQ(alloc64->get(0), 27); | 1793 EXPECT_EQ(alloc64->get(0), 27); |
| 1794 EXPECT_EQ(alloc64->get(63), 27); | 1794 EXPECT_EQ(alloc64->get(63), 27); |
| 1795 | 1795 |
| 1796 conservativelyCollectGarbage(); | 1796 conservativelyCollectGarbage(); |
| 1797 | 1797 |
| 1798 EXPECT_EQ(alloc32->get(0), 40); | 1798 EXPECT_EQ(alloc32->get(0), 40); |
| 1799 EXPECT_EQ(alloc32->get(31), 40); | 1799 EXPECT_EQ(alloc32->get(31), 40); |
| 1800 EXPECT_EQ(alloc64->get(0), 27); | 1800 EXPECT_EQ(alloc64->get(0), 27); |
| 1801 EXPECT_EQ(alloc64->get(63), 27); | 1801 EXPECT_EQ(alloc64->get(63), 27); |
| 1802 } | 1802 } |
| 1803 | 1803 |
| 1804 clearOutOldGarbage(); | 1804 clearOutOldGarbage(); |
| 1805 size_t total = 0; | 1805 size_t total = 0; |
| 1806 size_t slack = 0; | 1806 size_t slack = 0; |
| 1807 size_t baseLevel = Heap::objectPayloadSizeForTesting(); | 1807 size_t baseLevel = ThreadHeap::objectPayloadSizeForTesting(); |
| 1808 bool testPagesAllocated = !baseLevel; | 1808 bool testPagesAllocated = !baseLevel; |
| 1809 if (testPagesAllocated) | 1809 if (testPagesAllocated) |
| 1810 EXPECT_EQ(Heap::heapStats().allocatedSpace(), 0ul); | 1810 EXPECT_EQ(ThreadHeap::heapStats().allocatedSpace(), 0ul); |
| 1811 | 1811 |
| 1812 size_t big = 1008; | 1812 size_t big = 1008; |
| 1813 Persistent<DynamicallySizedObject> bigArea = DynamicallySizedObject::create(
big); | 1813 Persistent<DynamicallySizedObject> bigArea = DynamicallySizedObject::create(
big); |
| 1814 total += big; | 1814 total += big; |
| 1815 slack += 4; | 1815 slack += 4; |
| 1816 | 1816 |
| 1817 size_t persistentCount = 0; | 1817 size_t persistentCount = 0; |
| 1818 const size_t numPersistents = 100000; | 1818 const size_t numPersistents = 100000; |
| 1819 Persistent<DynamicallySizedObject>* persistents[numPersistents]; | 1819 Persistent<DynamicallySizedObject>* persistents[numPersistents]; |
| 1820 | 1820 |
| 1821 for (int i = 0; i < 1000; i++) { | 1821 for (int i = 0; i < 1000; i++) { |
| 1822 size_t size = 128 + i * 8; | 1822 size_t size = 128 + i * 8; |
| 1823 total += size; | 1823 total += size; |
| 1824 persistents[persistentCount++] = new Persistent<DynamicallySizedObject>(
DynamicallySizedObject::create(size)); | 1824 persistents[persistentCount++] = new Persistent<DynamicallySizedObject>(
DynamicallySizedObject::create(size)); |
| 1825 slack += 4; | 1825 slack += 4; |
| 1826 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), s
lack); | 1826 CheckWithSlack(baseLevel + total, ThreadHeap::objectPayloadSizeForTestin
g(), slack); |
| 1827 if (testPagesAllocated) | 1827 if (testPagesAllocated) |
| 1828 EXPECT_EQ(0ul, Heap::heapStats().allocatedSpace() & (blinkPageSize -
1)); | 1828 EXPECT_EQ(0ul, ThreadHeap::heapStats().allocatedSpace() & (blinkPage
Size - 1)); |
| 1829 } | 1829 } |
| 1830 | 1830 |
| 1831 { | 1831 { |
| 1832 DynamicallySizedObject* alloc32b(DynamicallySizedObject::create(32)); | 1832 DynamicallySizedObject* alloc32b(DynamicallySizedObject::create(32)); |
| 1833 slack += 4; | 1833 slack += 4; |
| 1834 memset(alloc32b, 40, 32); | 1834 memset(alloc32b, 40, 32); |
| 1835 DynamicallySizedObject* alloc64b(DynamicallySizedObject::create(64)); | 1835 DynamicallySizedObject* alloc64b(DynamicallySizedObject::create(64)); |
| 1836 slack += 4; | 1836 slack += 4; |
| 1837 memset(alloc64b, 27, 64); | 1837 memset(alloc64b, 27, 64); |
| 1838 EXPECT_TRUE(alloc32b != alloc64b); | 1838 EXPECT_TRUE(alloc32b != alloc64b); |
| 1839 | 1839 |
| 1840 total += 96; | 1840 total += 96; |
| 1841 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), s
lack); | 1841 CheckWithSlack(baseLevel + total, ThreadHeap::objectPayloadSizeForTestin
g(), slack); |
| 1842 if (testPagesAllocated) | 1842 if (testPagesAllocated) |
| 1843 EXPECT_EQ(0ul, Heap::heapStats().allocatedSpace() & (blinkPageSize -
1)); | 1843 EXPECT_EQ(0ul, ThreadHeap::heapStats().allocatedSpace() & (blinkPage
Size - 1)); |
| 1844 } | 1844 } |
| 1845 | 1845 |
| 1846 clearOutOldGarbage(); | 1846 clearOutOldGarbage(); |
| 1847 total -= 96; | 1847 total -= 96; |
| 1848 slack -= 8; | 1848 slack -= 8; |
| 1849 if (testPagesAllocated) | 1849 if (testPagesAllocated) |
| 1850 EXPECT_EQ(0ul, Heap::heapStats().allocatedSpace() & (blinkPageSize - 1))
; | 1850 EXPECT_EQ(0ul, ThreadHeap::heapStats().allocatedSpace() & (blinkPageSize
- 1)); |
| 1851 | 1851 |
| 1852 // Clear the persistent, so that the big area will be garbage collected. | 1852 // Clear the persistent, so that the big area will be garbage collected. |
| 1853 bigArea.release(); | 1853 bigArea.release(); |
| 1854 clearOutOldGarbage(); | 1854 clearOutOldGarbage(); |
| 1855 | 1855 |
| 1856 total -= big; | 1856 total -= big; |
| 1857 slack -= 4; | 1857 slack -= 4; |
| 1858 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), slack
); | 1858 CheckWithSlack(baseLevel + total, ThreadHeap::objectPayloadSizeForTesting(),
slack); |
| 1859 if (testPagesAllocated) | 1859 if (testPagesAllocated) |
| 1860 EXPECT_EQ(0ul, Heap::heapStats().allocatedSpace() & (blinkPageSize - 1))
; | 1860 EXPECT_EQ(0ul, ThreadHeap::heapStats().allocatedSpace() & (blinkPageSize
- 1)); |
| 1861 | 1861 |
| 1862 CheckWithSlack(baseLevel + total, Heap::objectPayloadSizeForTesting(), slack
); | 1862 CheckWithSlack(baseLevel + total, ThreadHeap::objectPayloadSizeForTesting(),
slack); |
| 1863 if (testPagesAllocated) | 1863 if (testPagesAllocated) |
| 1864 EXPECT_EQ(0ul, Heap::heapStats().allocatedSpace() & (blinkPageSize - 1))
; | 1864 EXPECT_EQ(0ul, ThreadHeap::heapStats().allocatedSpace() & (blinkPageSize
- 1)); |
| 1865 | 1865 |
| 1866 for (size_t i = 0; i < persistentCount; i++) { | 1866 for (size_t i = 0; i < persistentCount; i++) { |
| 1867 delete persistents[i]; | 1867 delete persistents[i]; |
| 1868 persistents[i] = 0; | 1868 persistents[i] = 0; |
| 1869 } | 1869 } |
| 1870 | 1870 |
| 1871 uint8_t* address = reinterpret_cast<uint8_t*>(Heap::allocate<DynamicallySize
dObject>(100)); | 1871 uint8_t* address = reinterpret_cast<uint8_t*>(ThreadHeap::allocate<Dynamical
lySizedObject>(100)); |
| 1872 for (int i = 0; i < 100; i++) | 1872 for (int i = 0; i < 100; i++) |
| 1873 address[i] = i; | 1873 address[i] = i; |
| 1874 address = reinterpret_cast<uint8_t*>(Heap::reallocate<DynamicallySizedObject
>(address, 100000)); | 1874 address = reinterpret_cast<uint8_t*>(ThreadHeap::reallocate<DynamicallySized
Object>(address, 100000)); |
| 1875 for (int i = 0; i < 100; i++) | 1875 for (int i = 0; i < 100; i++) |
| 1876 EXPECT_EQ(address[i], i); | 1876 EXPECT_EQ(address[i], i); |
| 1877 address = reinterpret_cast<uint8_t*>(Heap::reallocate<DynamicallySizedObject
>(address, 50)); | 1877 address = reinterpret_cast<uint8_t*>(ThreadHeap::reallocate<DynamicallySized
Object>(address, 50)); |
| 1878 for (int i = 0; i < 50; i++) | 1878 for (int i = 0; i < 50; i++) |
| 1879 EXPECT_EQ(address[i], i); | 1879 EXPECT_EQ(address[i], i); |
| 1880 // This should be equivalent to free(address). | 1880 // This should be equivalent to free(address). |
| 1881 EXPECT_EQ(reinterpret_cast<uintptr_t>(Heap::reallocate<DynamicallySizedObjec
t>(address, 0)), 0ul); | 1881 EXPECT_EQ(reinterpret_cast<uintptr_t>(ThreadHeap::reallocate<DynamicallySize
dObject>(address, 0)), 0ul); |
| 1882 // This should be equivalent to malloc(0). | 1882 // This should be equivalent to malloc(0). |
| 1883 EXPECT_EQ(reinterpret_cast<uintptr_t>(Heap::reallocate<DynamicallySizedObjec
t>(0, 0)), 0ul); | 1883 EXPECT_EQ(reinterpret_cast<uintptr_t>(ThreadHeap::reallocate<DynamicallySize
dObject>(0, 0)), 0ul); |
| 1884 } | 1884 } |
| 1885 | 1885 |
| 1886 TEST(HeapTest, SimpleAllocation) | 1886 TEST(HeapTest, SimpleAllocation) |
| 1887 { | 1887 { |
| 1888 clearOutOldGarbage(); | 1888 clearOutOldGarbage(); |
| 1889 EXPECT_EQ(0ul, Heap::objectPayloadSizeForTesting()); | 1889 EXPECT_EQ(0ul, ThreadHeap::objectPayloadSizeForTesting()); |
| 1890 | 1890 |
| 1891 // Allocate an object in the heap. | 1891 // Allocate an object in the heap. |
| 1892 HeapAllocatedArray* array = new HeapAllocatedArray(); | 1892 HeapAllocatedArray* array = new HeapAllocatedArray(); |
| 1893 EXPECT_TRUE(Heap::objectPayloadSizeForTesting() >= sizeof(HeapAllocatedArray
)); | 1893 EXPECT_TRUE(ThreadHeap::objectPayloadSizeForTesting() >= sizeof(HeapAllocate
dArray)); |
| 1894 | 1894 |
| 1895 // Sanity check of the contents in the heap. | 1895 // Sanity check of the contents in the heap. |
| 1896 EXPECT_EQ(0, array->at(0)); | 1896 EXPECT_EQ(0, array->at(0)); |
| 1897 EXPECT_EQ(42, array->at(42)); | 1897 EXPECT_EQ(42, array->at(42)); |
| 1898 EXPECT_EQ(0, array->at(128)); | 1898 EXPECT_EQ(0, array->at(128)); |
| 1899 EXPECT_EQ(999 % 128, array->at(999)); | 1899 EXPECT_EQ(999 % 128, array->at(999)); |
| 1900 } | 1900 } |
| 1901 | 1901 |
| 1902 TEST(HeapTest, SimplePersistent) | 1902 TEST(HeapTest, SimplePersistent) |
| 1903 { | 1903 { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1960 #endif | 1960 #endif |
| 1961 | 1961 |
| 1962 TEST(HeapTest, LazySweepingPages) | 1962 TEST(HeapTest, LazySweepingPages) |
| 1963 { | 1963 { |
| 1964 clearOutOldGarbage(); | 1964 clearOutOldGarbage(); |
| 1965 | 1965 |
| 1966 SimpleFinalizedObject::s_destructorCalls = 0; | 1966 SimpleFinalizedObject::s_destructorCalls = 0; |
| 1967 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 1967 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |
| 1968 for (int i = 0; i < 1000; i++) | 1968 for (int i = 0; i < 1000; i++) |
| 1969 SimpleFinalizedObject::create(); | 1969 SimpleFinalizedObject::create(); |
| 1970 Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithoutSweep
, BlinkGC::ForcedGC); | 1970 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithou
tSweep, BlinkGC::ForcedGC); |
| 1971 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 1971 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |
| 1972 for (int i = 0; i < 10000; i++) | 1972 for (int i = 0; i < 10000; i++) |
| 1973 SimpleFinalizedObject::create(); | 1973 SimpleFinalizedObject::create(); |
| 1974 EXPECT_EQ(1000, SimpleFinalizedObject::s_destructorCalls); | 1974 EXPECT_EQ(1000, SimpleFinalizedObject::s_destructorCalls); |
| 1975 preciselyCollectGarbage(); | 1975 preciselyCollectGarbage(); |
| 1976 EXPECT_EQ(11000, SimpleFinalizedObject::s_destructorCalls); | 1976 EXPECT_EQ(11000, SimpleFinalizedObject::s_destructorCalls); |
| 1977 } | 1977 } |
| 1978 | 1978 |
| 1979 TEST(HeapTest, LazySweepingLargeObjectPages) | 1979 TEST(HeapTest, LazySweepingLargeObjectPages) |
| 1980 { | 1980 { |
| 1981 clearOutOldGarbage(); | 1981 clearOutOldGarbage(); |
| 1982 | 1982 |
| 1983 // Create free lists that can be reused for IntWrappers created in | 1983 // Create free lists that can be reused for IntWrappers created in |
| 1984 // LargeHeapObject::create(). | 1984 // LargeHeapObject::create(). |
| 1985 Persistent<IntWrapper> p1 = new IntWrapper(1); | 1985 Persistent<IntWrapper> p1 = new IntWrapper(1); |
| 1986 for (int i = 0; i < 100; i++) { | 1986 for (int i = 0; i < 100; i++) { |
| 1987 new IntWrapper(i); | 1987 new IntWrapper(i); |
| 1988 } | 1988 } |
| 1989 Persistent<IntWrapper> p2 = new IntWrapper(2); | 1989 Persistent<IntWrapper> p2 = new IntWrapper(2); |
| 1990 preciselyCollectGarbage(); | 1990 preciselyCollectGarbage(); |
| 1991 preciselyCollectGarbage(); | 1991 preciselyCollectGarbage(); |
| 1992 | 1992 |
| 1993 LargeHeapObject::s_destructorCalls = 0; | 1993 LargeHeapObject::s_destructorCalls = 0; |
| 1994 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); | 1994 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); |
| 1995 for (int i = 0; i < 10; i++) | 1995 for (int i = 0; i < 10; i++) |
| 1996 LargeHeapObject::create(); | 1996 LargeHeapObject::create(); |
| 1997 Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithoutSweep
, BlinkGC::ForcedGC); | 1997 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithou
tSweep, BlinkGC::ForcedGC); |
| 1998 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); | 1998 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); |
| 1999 for (int i = 0; i < 10; i++) { | 1999 for (int i = 0; i < 10; i++) { |
| 2000 LargeHeapObject::create(); | 2000 LargeHeapObject::create(); |
| 2001 EXPECT_EQ(i + 1, LargeHeapObject::s_destructorCalls); | 2001 EXPECT_EQ(i + 1, LargeHeapObject::s_destructorCalls); |
| 2002 } | 2002 } |
| 2003 LargeHeapObject::create(); | 2003 LargeHeapObject::create(); |
| 2004 LargeHeapObject::create(); | 2004 LargeHeapObject::create(); |
| 2005 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); | 2005 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); |
| 2006 Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithoutSweep
, BlinkGC::ForcedGC); | 2006 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithou
tSweep, BlinkGC::ForcedGC); |
| 2007 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); | 2007 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); |
| 2008 preciselyCollectGarbage(); | 2008 preciselyCollectGarbage(); |
| 2009 EXPECT_EQ(22, LargeHeapObject::s_destructorCalls); | 2009 EXPECT_EQ(22, LargeHeapObject::s_destructorCalls); |
| 2010 } | 2010 } |
| 2011 | 2011 |
| 2012 class SimpleFinalizedEagerObjectBase : public GarbageCollectedFinalized<SimpleFi
nalizedEagerObjectBase> { | 2012 class SimpleFinalizedEagerObjectBase : public GarbageCollectedFinalized<SimpleFi
nalizedEagerObjectBase> { |
| 2013 public: | 2013 public: |
| 2014 virtual ~SimpleFinalizedEagerObjectBase() { } | 2014 virtual ~SimpleFinalizedEagerObjectBase() { } |
| 2015 DEFINE_INLINE_TRACE() { } | 2015 DEFINE_INLINE_TRACE() { } |
| 2016 | 2016 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2071 SimpleFinalizedEagerObject::s_destructorCalls = 0; | 2071 SimpleFinalizedEagerObject::s_destructorCalls = 0; |
| 2072 SimpleFinalizedObjectInstanceOfTemplate::s_destructorCalls = 0; | 2072 SimpleFinalizedObjectInstanceOfTemplate::s_destructorCalls = 0; |
| 2073 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 2073 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |
| 2074 EXPECT_EQ(0, SimpleFinalizedEagerObject::s_destructorCalls); | 2074 EXPECT_EQ(0, SimpleFinalizedEagerObject::s_destructorCalls); |
| 2075 for (int i = 0; i < 1000; i++) | 2075 for (int i = 0; i < 1000; i++) |
| 2076 SimpleFinalizedObject::create(); | 2076 SimpleFinalizedObject::create(); |
| 2077 for (int i = 0; i < 100; i++) | 2077 for (int i = 0; i < 100; i++) |
| 2078 SimpleFinalizedEagerObject::create(); | 2078 SimpleFinalizedEagerObject::create(); |
| 2079 for (int i = 0; i < 100; i++) | 2079 for (int i = 0; i < 100; i++) |
| 2080 SimpleFinalizedObjectInstanceOfTemplate::create(); | 2080 SimpleFinalizedObjectInstanceOfTemplate::create(); |
| 2081 Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithoutSweep
, BlinkGC::ForcedGC); | 2081 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithou
tSweep, BlinkGC::ForcedGC); |
| 2082 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); | 2082 EXPECT_EQ(0, SimpleFinalizedObject::s_destructorCalls); |
| 2083 EXPECT_EQ(100, SimpleFinalizedEagerObject::s_destructorCalls); | 2083 EXPECT_EQ(100, SimpleFinalizedEagerObject::s_destructorCalls); |
| 2084 EXPECT_EQ(100, SimpleFinalizedObjectInstanceOfTemplate::s_destructorCalls); | 2084 EXPECT_EQ(100, SimpleFinalizedObjectInstanceOfTemplate::s_destructorCalls); |
| 2085 } | 2085 } |
| 2086 | 2086 |
| 2087 TEST(HeapTest, Finalization) | 2087 TEST(HeapTest, Finalization) |
| 2088 { | 2088 { |
| 2089 { | 2089 { |
| 2090 HeapTestSubClass* t1 = HeapTestSubClass::create(); | 2090 HeapTestSubClass* t1 = HeapTestSubClass::create(); |
| 2091 HeapTestSubClass* t2 = HeapTestSubClass::create(); | 2091 HeapTestSubClass* t2 = HeapTestSubClass::create(); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2214 EXPECT_EQ(Bars::width + 1, Bar::s_live); | 2214 EXPECT_EQ(Bars::width + 1, Bar::s_live); |
| 2215 preciselyCollectGarbage(); | 2215 preciselyCollectGarbage(); |
| 2216 EXPECT_EQ(0u, Bar::s_live); | 2216 EXPECT_EQ(0u, Bar::s_live); |
| 2217 } | 2217 } |
| 2218 | 2218 |
| 2219 TEST(HeapTest, HashMapOfMembers) | 2219 TEST(HeapTest, HashMapOfMembers) |
| 2220 { | 2220 { |
| 2221 IntWrapper::s_destructorCalls = 0; | 2221 IntWrapper::s_destructorCalls = 0; |
| 2222 | 2222 |
| 2223 clearOutOldGarbage(); | 2223 clearOutOldGarbage(); |
| 2224 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); | 2224 size_t initialObjectPayloadSize = ThreadHeap::objectPayloadSizeForTesting(); |
| 2225 { | 2225 { |
| 2226 typedef HeapHashMap< | 2226 typedef HeapHashMap< |
| 2227 Member<IntWrapper>, | 2227 Member<IntWrapper>, |
| 2228 Member<IntWrapper>, | 2228 Member<IntWrapper>, |
| 2229 DefaultHash<Member<IntWrapper>>::Hash, | 2229 DefaultHash<Member<IntWrapper>>::Hash, |
| 2230 HashTraits<Member<IntWrapper>>, | 2230 HashTraits<Member<IntWrapper>>, |
| 2231 HashTraits<Member<IntWrapper>>> HeapObjectIdentityMap; | 2231 HashTraits<Member<IntWrapper>>> HeapObjectIdentityMap; |
| 2232 | 2232 |
| 2233 Persistent<HeapObjectIdentityMap> map = new HeapObjectIdentityMap(); | 2233 Persistent<HeapObjectIdentityMap> map = new HeapObjectIdentityMap(); |
| 2234 | 2234 |
| 2235 map->clear(); | 2235 map->clear(); |
| 2236 size_t afterSetWasCreated = Heap::objectPayloadSizeForTesting(); | 2236 size_t afterSetWasCreated = ThreadHeap::objectPayloadSizeForTesting(); |
| 2237 EXPECT_TRUE(afterSetWasCreated > initialObjectPayloadSize); | 2237 EXPECT_TRUE(afterSetWasCreated > initialObjectPayloadSize); |
| 2238 | 2238 |
| 2239 preciselyCollectGarbage(); | 2239 preciselyCollectGarbage(); |
| 2240 size_t afterGC = Heap::objectPayloadSizeForTesting(); | 2240 size_t afterGC = ThreadHeap::objectPayloadSizeForTesting(); |
| 2241 EXPECT_EQ(afterGC, afterSetWasCreated); | 2241 EXPECT_EQ(afterGC, afterSetWasCreated); |
| 2242 | 2242 |
| 2243 // If the additions below cause garbage collections, these | 2243 // If the additions below cause garbage collections, these |
| 2244 // pointers should be found by conservative stack scanning. | 2244 // pointers should be found by conservative stack scanning. |
| 2245 IntWrapper* one(IntWrapper::create(1)); | 2245 IntWrapper* one(IntWrapper::create(1)); |
| 2246 IntWrapper* anotherOne(IntWrapper::create(1)); | 2246 IntWrapper* anotherOne(IntWrapper::create(1)); |
| 2247 | 2247 |
| 2248 map->add(one, one); | 2248 map->add(one, one); |
| 2249 | 2249 |
| 2250 size_t afterOneAdd = Heap::objectPayloadSizeForTesting(); | 2250 size_t afterOneAdd = ThreadHeap::objectPayloadSizeForTesting(); |
| 2251 EXPECT_TRUE(afterOneAdd > afterGC); | 2251 EXPECT_TRUE(afterOneAdd > afterGC); |
| 2252 | 2252 |
| 2253 HeapObjectIdentityMap::iterator it(map->begin()); | 2253 HeapObjectIdentityMap::iterator it(map->begin()); |
| 2254 HeapObjectIdentityMap::iterator it2(map->begin()); | 2254 HeapObjectIdentityMap::iterator it2(map->begin()); |
| 2255 ++it; | 2255 ++it; |
| 2256 ++it2; | 2256 ++it2; |
| 2257 | 2257 |
| 2258 map->add(anotherOne, one); | 2258 map->add(anotherOne, one); |
| 2259 | 2259 |
| 2260 // The addition above can cause an allocation of a new | 2260 // The addition above can cause an allocation of a new |
| 2261 // backing store. We therefore garbage collect before | 2261 // backing store. We therefore garbage collect before |
| 2262 // taking the heap stats in order to get rid of the old | 2262 // taking the heap stats in order to get rid of the old |
| 2263 // backing store. We make sure to not use conservative | 2263 // backing store. We make sure to not use conservative |
| 2264 // stack scanning as that could find a pointer to the | 2264 // stack scanning as that could find a pointer to the |
| 2265 // old backing. | 2265 // old backing. |
| 2266 preciselyCollectGarbage(); | 2266 preciselyCollectGarbage(); |
| 2267 size_t afterAddAndGC = Heap::objectPayloadSizeForTesting(); | 2267 size_t afterAddAndGC = ThreadHeap::objectPayloadSizeForTesting(); |
| 2268 EXPECT_TRUE(afterAddAndGC >= afterOneAdd); | 2268 EXPECT_TRUE(afterAddAndGC >= afterOneAdd); |
| 2269 | 2269 |
| 2270 EXPECT_EQ(map->size(), 2u); // Two different wrappings of '1' are distin
ct. | 2270 EXPECT_EQ(map->size(), 2u); // Two different wrappings of '1' are distin
ct. |
| 2271 | 2271 |
| 2272 preciselyCollectGarbage(); | 2272 preciselyCollectGarbage(); |
| 2273 EXPECT_TRUE(map->contains(one)); | 2273 EXPECT_TRUE(map->contains(one)); |
| 2274 EXPECT_TRUE(map->contains(anotherOne)); | 2274 EXPECT_TRUE(map->contains(anotherOne)); |
| 2275 | 2275 |
| 2276 IntWrapper* gotten(map->get(one)); | 2276 IntWrapper* gotten(map->get(one)); |
| 2277 EXPECT_EQ(gotten->value(), one->value()); | 2277 EXPECT_EQ(gotten->value(), one->value()); |
| 2278 EXPECT_EQ(gotten, one); | 2278 EXPECT_EQ(gotten, one); |
| 2279 | 2279 |
| 2280 size_t afterGC2 = Heap::objectPayloadSizeForTesting(); | 2280 size_t afterGC2 = ThreadHeap::objectPayloadSizeForTesting(); |
| 2281 EXPECT_EQ(afterGC2, afterAddAndGC); | 2281 EXPECT_EQ(afterGC2, afterAddAndGC); |
| 2282 | 2282 |
| 2283 IntWrapper* dozen = 0; | 2283 IntWrapper* dozen = 0; |
| 2284 | 2284 |
| 2285 for (int i = 1; i < 1000; i++) { // 999 iterations. | 2285 for (int i = 1; i < 1000; i++) { // 999 iterations. |
| 2286 IntWrapper* iWrapper(IntWrapper::create(i)); | 2286 IntWrapper* iWrapper(IntWrapper::create(i)); |
| 2287 IntWrapper* iSquared(IntWrapper::create(i * i)); | 2287 IntWrapper* iSquared(IntWrapper::create(i * i)); |
| 2288 map->add(iWrapper, iSquared); | 2288 map->add(iWrapper, iSquared); |
| 2289 if (i == 12) | 2289 if (i == 12) |
| 2290 dozen = iWrapper; | 2290 dozen = iWrapper; |
| 2291 } | 2291 } |
| 2292 size_t afterAdding1000 = Heap::objectPayloadSizeForTesting(); | 2292 size_t afterAdding1000 = ThreadHeap::objectPayloadSizeForTesting(); |
| 2293 EXPECT_TRUE(afterAdding1000 > afterGC2); | 2293 EXPECT_TRUE(afterAdding1000 > afterGC2); |
| 2294 | 2294 |
| 2295 IntWrapper* gross(map->get(dozen)); | 2295 IntWrapper* gross(map->get(dozen)); |
| 2296 EXPECT_EQ(gross->value(), 144); | 2296 EXPECT_EQ(gross->value(), 144); |
| 2297 | 2297 |
| 2298 // This should clear out any junk backings created by all the adds. | 2298 // This should clear out any junk backings created by all the adds. |
| 2299 preciselyCollectGarbage(); | 2299 preciselyCollectGarbage(); |
| 2300 size_t afterGC3 = Heap::objectPayloadSizeForTesting(); | 2300 size_t afterGC3 = ThreadHeap::objectPayloadSizeForTesting(); |
| 2301 EXPECT_TRUE(afterGC3 <= afterAdding1000); | 2301 EXPECT_TRUE(afterGC3 <= afterAdding1000); |
| 2302 } | 2302 } |
| 2303 | 2303 |
| 2304 preciselyCollectGarbage(); | 2304 preciselyCollectGarbage(); |
| 2305 // The objects 'one', anotherOne, and the 999 other pairs. | 2305 // The objects 'one', anotherOne, and the 999 other pairs. |
| 2306 EXPECT_EQ(IntWrapper::s_destructorCalls, 2000); | 2306 EXPECT_EQ(IntWrapper::s_destructorCalls, 2000); |
| 2307 size_t afterGC4 = Heap::objectPayloadSizeForTesting(); | 2307 size_t afterGC4 = ThreadHeap::objectPayloadSizeForTesting(); |
| 2308 EXPECT_EQ(afterGC4, initialObjectPayloadSize); | 2308 EXPECT_EQ(afterGC4, initialObjectPayloadSize); |
| 2309 } | 2309 } |
| 2310 | 2310 |
| 2311 TEST(HeapTest, NestedAllocation) | 2311 TEST(HeapTest, NestedAllocation) |
| 2312 { | 2312 { |
| 2313 clearOutOldGarbage(); | 2313 clearOutOldGarbage(); |
| 2314 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); | 2314 size_t initialObjectPayloadSize = ThreadHeap::objectPayloadSizeForTesting(); |
| 2315 { | 2315 { |
| 2316 Persistent<ConstructorAllocation> constructorAllocation = ConstructorAll
ocation::create(); | 2316 Persistent<ConstructorAllocation> constructorAllocation = ConstructorAll
ocation::create(); |
| 2317 } | 2317 } |
| 2318 clearOutOldGarbage(); | 2318 clearOutOldGarbage(); |
| 2319 size_t afterFree = Heap::objectPayloadSizeForTesting(); | 2319 size_t afterFree = ThreadHeap::objectPayloadSizeForTesting(); |
| 2320 EXPECT_TRUE(initialObjectPayloadSize == afterFree); | 2320 EXPECT_TRUE(initialObjectPayloadSize == afterFree); |
| 2321 } | 2321 } |
| 2322 | 2322 |
| 2323 TEST(HeapTest, LargeHeapObjects) | 2323 TEST(HeapTest, LargeHeapObjects) |
| 2324 { | 2324 { |
| 2325 clearOutOldGarbage(); | 2325 clearOutOldGarbage(); |
| 2326 size_t initialObjectPayloadSize = Heap::objectPayloadSizeForTesting(); | 2326 size_t initialObjectPayloadSize = ThreadHeap::objectPayloadSizeForTesting(); |
| 2327 size_t initialAllocatedSpace = Heap::heapStats().allocatedSpace(); | 2327 size_t initialAllocatedSpace = ThreadHeap::heapStats().allocatedSpace(); |
| 2328 IntWrapper::s_destructorCalls = 0; | 2328 IntWrapper::s_destructorCalls = 0; |
| 2329 LargeHeapObject::s_destructorCalls = 0; | 2329 LargeHeapObject::s_destructorCalls = 0; |
| 2330 { | 2330 { |
| 2331 int slack = 8; // LargeHeapObject points to an IntWrapper that is also a
llocated. | 2331 int slack = 8; // LargeHeapObject points to an IntWrapper that is also a
llocated. |
| 2332 Persistent<LargeHeapObject> object = LargeHeapObject::create(); | 2332 Persistent<LargeHeapObject> object = LargeHeapObject::create(); |
| 2333 ASSERT(ThreadState::current()->findPageFromAddress(object)); | 2333 ASSERT(ThreadState::current()->findPageFromAddress(object)); |
| 2334 ASSERT(ThreadState::current()->findPageFromAddress(reinterpret_cast<char
*>(object.get()) + sizeof(LargeHeapObject) - 1)); | 2334 ASSERT(ThreadState::current()->findPageFromAddress(reinterpret_cast<char
*>(object.get()) + sizeof(LargeHeapObject) - 1)); |
| 2335 clearOutOldGarbage(); | 2335 clearOutOldGarbage(); |
| 2336 size_t afterAllocation = Heap::heapStats().allocatedSpace(); | 2336 size_t afterAllocation = ThreadHeap::heapStats().allocatedSpace(); |
| 2337 { | 2337 { |
| 2338 object->set(0, 'a'); | 2338 object->set(0, 'a'); |
| 2339 EXPECT_EQ('a', object->get(0)); | 2339 EXPECT_EQ('a', object->get(0)); |
| 2340 object->set(object->length() - 1, 'b'); | 2340 object->set(object->length() - 1, 'b'); |
| 2341 EXPECT_EQ('b', object->get(object->length() - 1)); | 2341 EXPECT_EQ('b', object->get(object->length() - 1)); |
| 2342 size_t expectedLargeHeapObjectPayloadSize = Heap::allocationSizeFrom
Size(sizeof(LargeHeapObject)); | 2342 size_t expectedLargeHeapObjectPayloadSize = ThreadHeap::allocationSi
zeFromSize(sizeof(LargeHeapObject)); |
| 2343 size_t expectedObjectPayloadSize = expectedLargeHeapObjectPayloadSiz
e + sizeof(IntWrapper); | 2343 size_t expectedObjectPayloadSize = expectedLargeHeapObjectPayloadSiz
e + sizeof(IntWrapper); |
| 2344 size_t actualObjectPayloadSize = Heap::objectPayloadSizeForTesting()
- initialObjectPayloadSize; | 2344 size_t actualObjectPayloadSize = ThreadHeap::objectPayloadSizeForTes
ting() - initialObjectPayloadSize; |
| 2345 CheckWithSlack(expectedObjectPayloadSize, actualObjectPayloadSize, s
lack); | 2345 CheckWithSlack(expectedObjectPayloadSize, actualObjectPayloadSize, s
lack); |
| 2346 // There is probably space for the IntWrapper in a heap page without | 2346 // There is probably space for the IntWrapper in a heap page without |
| 2347 // allocating extra pages. However, the IntWrapper allocation might
cause | 2347 // allocating extra pages. However, the IntWrapper allocation might
cause |
| 2348 // the addition of a heap page. | 2348 // the addition of a heap page. |
| 2349 size_t largeObjectAllocationSize = sizeof(LargeObjectPage) + expecte
dLargeHeapObjectPayloadSize; | 2349 size_t largeObjectAllocationSize = sizeof(LargeObjectPage) + expecte
dLargeHeapObjectPayloadSize; |
| 2350 size_t allocatedSpaceLowerBound = initialAllocatedSpace + largeObjec
tAllocationSize; | 2350 size_t allocatedSpaceLowerBound = initialAllocatedSpace + largeObjec
tAllocationSize; |
| 2351 size_t allocatedSpaceUpperBound = allocatedSpaceLowerBound + slack +
blinkPageSize; | 2351 size_t allocatedSpaceUpperBound = allocatedSpaceLowerBound + slack +
blinkPageSize; |
| 2352 EXPECT_LE(allocatedSpaceLowerBound, afterAllocation); | 2352 EXPECT_LE(allocatedSpaceLowerBound, afterAllocation); |
| 2353 EXPECT_LE(afterAllocation, allocatedSpaceUpperBound); | 2353 EXPECT_LE(afterAllocation, allocatedSpaceUpperBound); |
| 2354 EXPECT_EQ(0, IntWrapper::s_destructorCalls); | 2354 EXPECT_EQ(0, IntWrapper::s_destructorCalls); |
| 2355 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); | 2355 EXPECT_EQ(0, LargeHeapObject::s_destructorCalls); |
| 2356 for (int i = 0; i < 10; i++) | 2356 for (int i = 0; i < 10; i++) |
| 2357 object = LargeHeapObject::create(); | 2357 object = LargeHeapObject::create(); |
| 2358 } | 2358 } |
| 2359 clearOutOldGarbage(); | 2359 clearOutOldGarbage(); |
| 2360 EXPECT_TRUE(Heap::heapStats().allocatedSpace() == afterAllocation); | 2360 EXPECT_TRUE(ThreadHeap::heapStats().allocatedSpace() == afterAllocation)
; |
| 2361 EXPECT_EQ(10, IntWrapper::s_destructorCalls); | 2361 EXPECT_EQ(10, IntWrapper::s_destructorCalls); |
| 2362 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); | 2362 EXPECT_EQ(10, LargeHeapObject::s_destructorCalls); |
| 2363 } | 2363 } |
| 2364 clearOutOldGarbage(); | 2364 clearOutOldGarbage(); |
| 2365 EXPECT_TRUE(initialObjectPayloadSize == Heap::objectPayloadSizeForTesting())
; | 2365 EXPECT_TRUE(initialObjectPayloadSize == ThreadHeap::objectPayloadSizeForTest
ing()); |
| 2366 EXPECT_TRUE(initialAllocatedSpace == Heap::heapStats().allocatedSpace()); | 2366 EXPECT_TRUE(initialAllocatedSpace == ThreadHeap::heapStats().allocatedSpace(
)); |
| 2367 EXPECT_EQ(11, IntWrapper::s_destructorCalls); | 2367 EXPECT_EQ(11, IntWrapper::s_destructorCalls); |
| 2368 EXPECT_EQ(11, LargeHeapObject::s_destructorCalls); | 2368 EXPECT_EQ(11, LargeHeapObject::s_destructorCalls); |
| 2369 preciselyCollectGarbage(); | 2369 preciselyCollectGarbage(); |
| 2370 } | 2370 } |
| 2371 | 2371 |
| 2372 typedef std::pair<Member<IntWrapper>, int> PairWrappedUnwrapped; | 2372 typedef std::pair<Member<IntWrapper>, int> PairWrappedUnwrapped; |
| 2373 typedef std::pair<int, Member<IntWrapper>> PairUnwrappedWrapped; | 2373 typedef std::pair<int, Member<IntWrapper>> PairUnwrappedWrapped; |
| 2374 typedef std::pair<WeakMember<IntWrapper>, Member<IntWrapper>> PairWeakStrong; | 2374 typedef std::pair<WeakMember<IntWrapper>, Member<IntWrapper>> PairWeakStrong; |
| 2375 typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper>> PairStrongWeak; | 2375 typedef std::pair<Member<IntWrapper>, WeakMember<IntWrapper>> PairStrongWeak; |
| 2376 typedef std::pair<WeakMember<IntWrapper>, int> PairWeakUnwrapped; | 2376 typedef std::pair<WeakMember<IntWrapper>, int> PairWeakUnwrapped; |
| (...skipping 1395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3772 // causes the object start bitmap to be computed which requires the heap | 3772 // causes the object start bitmap to be computed which requires the heap |
| 3773 // to be in a consistent state (e.g. the free allocation area must be put | 3773 // to be in a consistent state (e.g. the free allocation area must be put |
| 3774 // into a free list header). However when we call makeConsistentForGC it | 3774 // into a free list header). However when we call makeConsistentForGC it |
| 3775 // also clears out the freelists so we have to rebuild those before trying | 3775 // also clears out the freelists so we have to rebuild those before trying |
| 3776 // to allocate anything again. We do this by forcing a GC after doing the | 3776 // to allocate anything again. We do this by forcing a GC after doing the |
| 3777 // checkAndMarkPointer tests. | 3777 // checkAndMarkPointer tests. |
| 3778 { | 3778 { |
| 3779 TestGCScope scope(BlinkGC::HeapPointersOnStack); | 3779 TestGCScope scope(BlinkGC::HeapPointersOnStack); |
| 3780 CountingVisitor visitor(ThreadState::current()); | 3780 CountingVisitor visitor(ThreadState::current()); |
| 3781 EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not
park all threads. | 3781 EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not
park all threads. |
| 3782 Heap::flushHeapDoesNotContainCache(); | 3782 ThreadHeap::flushHeapDoesNotContainCache(); |
| 3783 for (size_t i = 0; i < objectAddresses.size(); i++) { | 3783 for (size_t i = 0; i < objectAddresses.size(); i++) { |
| 3784 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, objectAddresses[i]))
; | 3784 EXPECT_TRUE(ThreadHeap::checkAndMarkPointer(&visitor, objectAddresse
s[i])); |
| 3785 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, endAddresses[i])); | 3785 EXPECT_TRUE(ThreadHeap::checkAndMarkPointer(&visitor, endAddresses[i
])); |
| 3786 } | 3786 } |
| 3787 EXPECT_EQ(objectAddresses.size() * 2, visitor.count()); | 3787 EXPECT_EQ(objectAddresses.size() * 2, visitor.count()); |
| 3788 visitor.reset(); | 3788 visitor.reset(); |
| 3789 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectAddress)); | 3789 EXPECT_TRUE(ThreadHeap::checkAndMarkPointer(&visitor, largeObjectAddress
)); |
| 3790 EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, largeObjectEndAddress)); | 3790 EXPECT_TRUE(ThreadHeap::checkAndMarkPointer(&visitor, largeObjectEndAddr
ess)); |
| 3791 EXPECT_EQ(2ul, visitor.count()); | 3791 EXPECT_EQ(2ul, visitor.count()); |
| 3792 visitor.reset(); | 3792 visitor.reset(); |
| 3793 } | 3793 } |
| 3794 // This forces a GC without stack scanning which results in the objects | 3794 // This forces a GC without stack scanning which results in the objects |
| 3795 // being collected. This will also rebuild the above mentioned freelists, | 3795 // being collected. This will also rebuild the above mentioned freelists, |
| 3796 // however we don't rely on that below since we don't have any allocations. | 3796 // however we don't rely on that below since we don't have any allocations. |
| 3797 clearOutOldGarbage(); | 3797 clearOutOldGarbage(); |
| 3798 { | 3798 { |
| 3799 TestGCScope scope(BlinkGC::HeapPointersOnStack); | 3799 TestGCScope scope(BlinkGC::HeapPointersOnStack); |
| 3800 CountingVisitor visitor(ThreadState::current()); | 3800 CountingVisitor visitor(ThreadState::current()); |
| 3801 EXPECT_TRUE(scope.allThreadsParked()); | 3801 EXPECT_TRUE(scope.allThreadsParked()); |
| 3802 Heap::flushHeapDoesNotContainCache(); | 3802 ThreadHeap::flushHeapDoesNotContainCache(); |
| 3803 for (size_t i = 0; i < objectAddresses.size(); i++) { | 3803 for (size_t i = 0; i < objectAddresses.size(); i++) { |
| 3804 // We would like to assert that checkAndMarkPointer returned false | 3804 // We would like to assert that checkAndMarkPointer returned false |
| 3805 // here because the pointers no longer point into a valid object | 3805 // here because the pointers no longer point into a valid object |
| 3806 // (it's been freed by the GCs. But checkAndMarkPointer will return | 3806 // (it's been freed by the GCs. But checkAndMarkPointer will return |
| 3807 // true for any pointer that points into a heap page, regardless of | 3807 // true for any pointer that points into a heap page, regardless of |
| 3808 // whether it points at a valid object (this ensures the | 3808 // whether it points at a valid object (this ensures the |
| 3809 // correctness of the page-based on-heap address caches), so we | 3809 // correctness of the page-based on-heap address caches), so we |
| 3810 // can't make that assert. | 3810 // can't make that assert. |
| 3811 Heap::checkAndMarkPointer(&visitor, objectAddresses[i]); | 3811 ThreadHeap::checkAndMarkPointer(&visitor, objectAddresses[i]); |
| 3812 Heap::checkAndMarkPointer(&visitor, endAddresses[i]); | 3812 ThreadHeap::checkAndMarkPointer(&visitor, endAddresses[i]); |
| 3813 } | 3813 } |
| 3814 EXPECT_EQ(0ul, visitor.count()); | 3814 EXPECT_EQ(0ul, visitor.count()); |
| 3815 Heap::checkAndMarkPointer(&visitor, largeObjectAddress); | 3815 ThreadHeap::checkAndMarkPointer(&visitor, largeObjectAddress); |
| 3816 Heap::checkAndMarkPointer(&visitor, largeObjectEndAddress); | 3816 ThreadHeap::checkAndMarkPointer(&visitor, largeObjectEndAddress); |
| 3817 EXPECT_EQ(0ul, visitor.count()); | 3817 EXPECT_EQ(0ul, visitor.count()); |
| 3818 } | 3818 } |
| 3819 // This round of GC is important to make sure that the object start | 3819 // This round of GC is important to make sure that the object start |
| 3820 // bitmap are cleared out and that the free lists are rebuild. | 3820 // bitmap are cleared out and that the free lists are rebuild. |
| 3821 clearOutOldGarbage(); | 3821 clearOutOldGarbage(); |
| 3822 } | 3822 } |
| 3823 | 3823 |
| 3824 TEST(HeapTest, PersistentHeapCollectionTypes) | 3824 TEST(HeapTest, PersistentHeapCollectionTypes) |
| 3825 { | 3825 { |
| 3826 IntWrapper::s_destructorCalls = 0; | 3826 IntWrapper::s_destructorCalls = 0; |
| (...skipping 1178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5005 | 5005 |
| 5006 // These special traits will remove a set from a map when the set is empty. | 5006 // These special traits will remove a set from a map when the set is empty. |
| 5007 struct EmptyClearingHashSetTraits : HashTraits<WeakSet> { | 5007 struct EmptyClearingHashSetTraits : HashTraits<WeakSet> { |
| 5008 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; | 5008 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; |
| 5009 template<typename VisitorDispatcher> | 5009 template<typename VisitorDispatcher> |
| 5010 static bool traceInCollection(VisitorDispatcher visitor, WeakSet& set, WTF::
ShouldWeakPointersBeMarkedStrongly strongify) | 5010 static bool traceInCollection(VisitorDispatcher visitor, WeakSet& set, WTF::
ShouldWeakPointersBeMarkedStrongly strongify) |
| 5011 { | 5011 { |
| 5012 bool liveEntriesFound = false; | 5012 bool liveEntriesFound = false; |
| 5013 WeakSet::iterator end = set.end(); | 5013 WeakSet::iterator end = set.end(); |
| 5014 for (WeakSet::iterator it = set.begin(); it != end; ++it) { | 5014 for (WeakSet::iterator it = set.begin(); it != end; ++it) { |
| 5015 if (Heap::isHeapObjectAlive(*it)) { | 5015 if (ThreadHeap::isHeapObjectAlive(*it)) { |
| 5016 liveEntriesFound = true; | 5016 liveEntriesFound = true; |
| 5017 break; | 5017 break; |
| 5018 } | 5018 } |
| 5019 } | 5019 } |
| 5020 // If there are live entries in the set then the set cannot be removed | 5020 // If there are live entries in the set then the set cannot be removed |
| 5021 // from the map it is contained in, and we need to mark it (and its | 5021 // from the map it is contained in, and we need to mark it (and its |
| 5022 // backing) live. We just trace normally, which will invoke the normal | 5022 // backing) live. We just trace normally, which will invoke the normal |
| 5023 // weak handling for any entries that are not live. | 5023 // weak handling for any entries that are not live. |
| 5024 if (liveEntriesFound) | 5024 if (liveEntriesFound) |
| 5025 set.trace(visitor); | 5025 set.trace(visitor); |
| (...skipping 907 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5933 { | 5933 { |
| 5934 } | 5934 } |
| 5935 }; | 5935 }; |
| 5936 | 5936 |
| 5937 // Regression test for crbug.com/404511. Tests conservative marking of | 5937 // Regression test for crbug.com/404511. Tests conservative marking of |
| 5938 // an object with an uninitialized vtable. | 5938 // an object with an uninitialized vtable. |
| 5939 TEST(HeapTest, AllocationInSuperConstructorArgument) | 5939 TEST(HeapTest, AllocationInSuperConstructorArgument) |
| 5940 { | 5940 { |
| 5941 AllocInSuperConstructorArgument* object = new AllocInSuperConstructorArgumen
t(); | 5941 AllocInSuperConstructorArgument* object = new AllocInSuperConstructorArgumen
t(); |
| 5942 EXPECT_TRUE(object); | 5942 EXPECT_TRUE(object); |
| 5943 Heap::collectAllGarbage(); | 5943 ThreadHeap::collectAllGarbage(); |
| 5944 } | 5944 } |
| 5945 | 5945 |
| 5946 class NonNodeAllocatingNodeInDestructor : public GarbageCollectedFinalized<NonNo
deAllocatingNodeInDestructor> { | 5946 class NonNodeAllocatingNodeInDestructor : public GarbageCollectedFinalized<NonNo
deAllocatingNodeInDestructor> { |
| 5947 public: | 5947 public: |
| 5948 ~NonNodeAllocatingNodeInDestructor() | 5948 ~NonNodeAllocatingNodeInDestructor() |
| 5949 { | 5949 { |
| 5950 s_node = new Persistent<IntNode>(IntNode::create(10)); | 5950 s_node = new Persistent<IntNode>(IntNode::create(10)); |
| 5951 } | 5951 } |
| 5952 | 5952 |
| 5953 DEFINE_INLINE_TRACE() { } | 5953 DEFINE_INLINE_TRACE() { } |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6385 void workerThreadMainForCrossThreadWeakPersistentTest(DestructorLockingObject**
object) | 6385 void workerThreadMainForCrossThreadWeakPersistentTest(DestructorLockingObject**
object) |
| 6386 { | 6386 { |
| 6387 // Step 2: Create an object and store the pointer. | 6387 // Step 2: Create an object and store the pointer. |
| 6388 MutexLocker locker(workerThreadMutex()); | 6388 MutexLocker locker(workerThreadMutex()); |
| 6389 ThreadState::attach(); | 6389 ThreadState::attach(); |
| 6390 *object = DestructorLockingObject::create(); | 6390 *object = DestructorLockingObject::create(); |
| 6391 wakeMainThread(); | 6391 wakeMainThread(); |
| 6392 parkWorkerThread(); | 6392 parkWorkerThread(); |
| 6393 | 6393 |
| 6394 // Step 4: Run a GC. | 6394 // Step 4: Run a GC. |
| 6395 Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, B
linkGC::ForcedGC); | 6395 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSw
eep, BlinkGC::ForcedGC); |
| 6396 wakeMainThread(); | 6396 wakeMainThread(); |
| 6397 parkWorkerThread(); | 6397 parkWorkerThread(); |
| 6398 | 6398 |
| 6399 // Step 6: Finish. | 6399 // Step 6: Finish. |
| 6400 ThreadState::detach(); | 6400 ThreadState::detach(); |
| 6401 wakeMainThread(); | 6401 wakeMainThread(); |
| 6402 } | 6402 } |
| 6403 | 6403 |
| 6404 } // anonymous namespace | 6404 } // anonymous namespace |
| 6405 | 6405 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6490 persistentHeapVectorIntWrapper.append(&intWrapper); | 6490 persistentHeapVectorIntWrapper.append(&intWrapper); |
| 6491 heapVectorIntWrapper.append(&intWrapper); | 6491 heapVectorIntWrapper.append(&intWrapper); |
| 6492 EXPECT_EQ(1u, persistentHeapVectorIntWrapper.size()); | 6492 EXPECT_EQ(1u, persistentHeapVectorIntWrapper.size()); |
| 6493 EXPECT_EQ(1u, heapVectorIntWrapper.size()); | 6493 EXPECT_EQ(1u, heapVectorIntWrapper.size()); |
| 6494 | 6494 |
| 6495 EXPECT_EQ(persistentHeapVectorIntWrapper[0], heapVectorIntWrapper[0]); | 6495 EXPECT_EQ(persistentHeapVectorIntWrapper[0], heapVectorIntWrapper[0]); |
| 6496 EXPECT_EQ(33, heapVectorIntWrapper[0]->value()); | 6496 EXPECT_EQ(33, heapVectorIntWrapper[0]->value()); |
| 6497 } | 6497 } |
| 6498 | 6498 |
| 6499 } // namespace blink | 6499 } // namespace blink |
| OLD | NEW |