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 |