Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: Source/platform/heap/HeapTest.cpp

Issue 223373002: Create HeapLinkedHashSet and LinkedHashSet, ordered heap-friendly hash sets. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix gtest-related compile error on gcc by removing internal typedefs in iterators Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/platform/heap/Heap.h ('k') | Source/platform/heap/Visitor.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 19 matching lines...) Expand all
30 30
31 #include "config.h" 31 #include "config.h"
32 32
33 #include "platform/heap/Handle.h" 33 #include "platform/heap/Handle.h"
34 #include "platform/heap/Heap.h" 34 #include "platform/heap/Heap.h"
35 #include "platform/heap/HeapLinkedStack.h" 35 #include "platform/heap/HeapLinkedStack.h"
36 #include "platform/heap/HeapTerminatedArrayBuilder.h" 36 #include "platform/heap/HeapTerminatedArrayBuilder.h"
37 #include "platform/heap/ThreadState.h" 37 #include "platform/heap/ThreadState.h"
38 #include "platform/heap/Visitor.h" 38 #include "platform/heap/Visitor.h"
39 #include "wtf/HashTraits.h" 39 #include "wtf/HashTraits.h"
40 #include "wtf/LinkedHashSet.h"
40 41
41 #include <gtest/gtest.h> 42 #include <gtest/gtest.h>
42 43
43 namespace WebCore { 44 namespace WebCore {
44 45
45 class ThreadMarker { 46 class ThreadMarker {
46 public: 47 public:
47 ThreadMarker() : m_creatingThread(reinterpret_cast<ThreadState*>(0)), m_num( 0) { } 48 ThreadMarker() : m_creatingThread(reinterpret_cast<ThreadState*>(0)), m_num( 0) { }
48 ThreadMarker(unsigned i) : m_creatingThread(ThreadState::current()), m_num(i ) { } 49 ThreadMarker(unsigned i) : m_creatingThread(ThreadState::current()), m_num(i ) { }
49 ThreadMarker(WTF::HashTableDeletedValueType deleted) : m_creatingThread(rein terpret_cast<ThreadState*>(-1)), m_num(0) { } 50 ThreadMarker(WTF::HashTableDeletedValueType deleted) : m_creatingThread(rein terpret_cast<ThreadState*>(-1)), m_num(0) { }
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 unsigned hash() { return IntHash<int>::hash(m_x); } 303 unsigned hash() { return IntHash<int>::hash(m_x); }
303 304
304 protected: 305 protected:
305 IntWrapper(int x) : m_x(x) { } 306 IntWrapper(int x) : m_x(x) { }
306 307
307 private: 308 private:
308 IntWrapper(); 309 IntWrapper();
309 int m_x; 310 int m_x;
310 }; 311 };
311 312
313 class OffHeapInt : public RefCounted<OffHeapInt> {
314 public:
315 static RefPtr<OffHeapInt> create(int x)
316 {
317 return adoptRef(new OffHeapInt(x));
318 }
319
320 virtual ~OffHeapInt()
321 {
322 ++s_destructorCalls;
323 }
324
325 static int s_destructorCalls;
326
327 int value() const { return m_x; }
328
329 bool operator==(const OffHeapInt& other) const { return other.value() == val ue(); }
330
331 unsigned hash() { return IntHash<int>::hash(m_x); }
332
333 protected:
334 OffHeapInt(int x) : m_x(x) { }
335
336 private:
337 OffHeapInt();
338 int m_x;
339 };
340
312 USED_FROM_MULTIPLE_THREADS(IntWrapper); 341 USED_FROM_MULTIPLE_THREADS(IntWrapper);
313 342
314 int IntWrapper::s_destructorCalls = 0; 343 int IntWrapper::s_destructorCalls = 0;
344 int OffHeapInt::s_destructorCalls = 0;
315 345
316 class ThreadedTesterBase { 346 class ThreadedTesterBase {
317 protected: 347 protected:
318 static void test(ThreadedTesterBase* tester) 348 static void test(ThreadedTesterBase* tester)
319 { 349 {
320 for (int i = 0; i < numberOfThreads; i++) 350 for (int i = 0; i < numberOfThreads; i++)
321 createThread(&threadFunc, tester, "testing thread"); 351 createThread(&threadFunc, tester, "testing thread");
322 while (tester->m_threadsToFinish) { 352 while (tester->m_threadsToFinish) {
323 ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack ); 353 ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack );
324 yield(); 354 yield();
(...skipping 1567 matching lines...) Expand 10 before | Expand all | Expand 10 after
1892 struct ShouldBeTraced { 1922 struct ShouldBeTraced {
1893 explicit ShouldBeTraced(IntWrapper* wrapper) : m_wrapper(wrapper) { } 1923 explicit ShouldBeTraced(IntWrapper* wrapper) : m_wrapper(wrapper) { }
1894 void trace(Visitor* visitor) { visitor->trace(m_wrapper); } 1924 void trace(Visitor* visitor) { visitor->trace(m_wrapper); }
1895 Member<IntWrapper> m_wrapper; 1925 Member<IntWrapper> m_wrapper;
1896 }; 1926 };
1897 1927
1898 class OffHeapContainer : public GarbageCollectedFinalized<OffHeapContainer> { 1928 class OffHeapContainer : public GarbageCollectedFinalized<OffHeapContainer> {
1899 public: 1929 public:
1900 static OffHeapContainer* create() { return new OffHeapContainer(); } 1930 static OffHeapContainer* create() { return new OffHeapContainer(); }
1901 1931
1932 static const int iterations = 300;
1933 static const int deadWrappers = 2700;
1934
1902 OffHeapContainer() 1935 OffHeapContainer()
1903 { 1936 {
1904 m_deque1.append(ShouldBeTraced(IntWrapper::create(1))); 1937 for (int i = 0; i < iterations; i++) {
1905 m_vector1.append(ShouldBeTraced(IntWrapper::create(2))); 1938 m_deque1.append(ShouldBeTraced(IntWrapper::create(i)));
1906 m_deque2.append(IntWrapper::create(3)); 1939 m_vector1.append(ShouldBeTraced(IntWrapper::create(i)));
1907 m_vector2.append(IntWrapper::create(4)); 1940 m_deque2.append(IntWrapper::create(i));
1908 m_hashSet.add(IntWrapper::create(5)); 1941 m_vector2.append(IntWrapper::create(i));
1909 m_hashMap.add(this, IntWrapper::create(6)); 1942 m_hashSet.add(IntWrapper::create(i));
1910 m_listHashSet.add(IntWrapper::create(7)); 1943 m_hashMap.add(i + 103, IntWrapper::create(i));
1911 m_ownedVector.append(adoptPtr(new ShouldBeTraced(IntWrapper::create(8))) ); 1944 m_listHashSet.add(IntWrapper::create(i));
1945 m_linkedHashSet.add(IntWrapper::create(i));
1946 m_ownedVector.append(adoptPtr(new ShouldBeTraced(IntWrapper::create( i))));
1947 }
1948
1949 Deque<ShouldBeTraced>::iterator d1Iterator(m_deque1.begin());
1950 Vector<ShouldBeTraced>::iterator v1Iterator(m_vector1.begin());
1951 Deque<Member<IntWrapper> >::iterator d2Iterator(m_deque2.begin());
1952 Vector<Member<IntWrapper> >::iterator v2Iterator(m_vector2.begin());
1953 HashSet<Member<IntWrapper> >::iterator setIterator(m_hashSet.begin());
1954 HashMap<int, Member<IntWrapper> >::iterator mapIterator(m_hashMap.begin( ));
1955 ListHashSet<Member<IntWrapper> >::iterator listSetIterator(m_listHashSet .begin());
1956 LinkedHashSet<Member<IntWrapper> >::iterator linkedSetIterator(m_linkedH ashSet.begin());
1957 Vector<OwnPtr<ShouldBeTraced> >::iterator ownedVectorIterator(m_ownedVec tor.begin());
1958
1959 for (int i = 0; i < iterations; i++) {
1960 EXPECT_EQ(i, m_vector1[i].m_wrapper->value());
1961 EXPECT_EQ(i, m_vector2[i]->value());
1962 EXPECT_EQ(i, d1Iterator->m_wrapper->value());
1963 EXPECT_EQ(i, v1Iterator->m_wrapper->value());
1964 EXPECT_EQ(i, d2Iterator->get()->value());
1965 EXPECT_EQ(i, v2Iterator->get()->value());
1966 EXPECT_EQ(i, linkedSetIterator->get()->value());
1967 EXPECT_EQ(i, ownedVectorIterator->get()->m_wrapper->value());
1968 int value = setIterator->get()->value();
1969 EXPECT_LE(0, value);
1970 EXPECT_GT(iterations, value);
1971 value = listSetIterator->get()->value();
1972 EXPECT_LE(0, value);
1973 EXPECT_GT(iterations, value);
1974 value = mapIterator->value.get()->value();
1975 EXPECT_LE(0, value);
1976 EXPECT_GT(iterations, value);
1977 ++d1Iterator;
1978 ++v1Iterator;
1979 ++d2Iterator;
1980 ++v2Iterator;
1981 ++setIterator;
1982 ++mapIterator;
1983 ++listSetIterator;
1984 ++linkedSetIterator;
1985 ++ownedVectorIterator;
1986 }
1987 EXPECT_EQ(d1Iterator, m_deque1.end());
1988 EXPECT_EQ(v1Iterator, m_vector1.end());
1989 EXPECT_EQ(d2Iterator, m_deque2.end());
1990 EXPECT_EQ(v2Iterator, m_vector2.end());
1991 EXPECT_EQ(setIterator, m_hashSet.end());
1992 EXPECT_EQ(mapIterator, m_hashMap.end());
1993 EXPECT_EQ(listSetIterator, m_listHashSet.end());
1994 EXPECT_EQ(linkedSetIterator, m_linkedHashSet.end());
1995 EXPECT_EQ(ownedVectorIterator, m_ownedVector.end());
1912 } 1996 }
1913 1997
1914 void trace(Visitor* visitor) 1998 void trace(Visitor* visitor)
1915 { 1999 {
1916 visitor->trace(m_deque1); 2000 visitor->trace(m_deque1);
1917 visitor->trace(m_vector1); 2001 visitor->trace(m_vector1);
1918 visitor->trace(m_deque2); 2002 visitor->trace(m_deque2);
1919 visitor->trace(m_vector2); 2003 visitor->trace(m_vector2);
1920 visitor->trace(m_hashSet); 2004 visitor->trace(m_hashSet);
1921 visitor->trace(m_hashMap); 2005 visitor->trace(m_hashMap);
1922 visitor->trace(m_listHashSet); 2006 visitor->trace(m_listHashSet);
2007 visitor->trace(m_linkedHashSet);
1923 visitor->trace(m_ownedVector); 2008 visitor->trace(m_ownedVector);
1924 } 2009 }
1925 2010
1926 Deque<ShouldBeTraced> m_deque1; 2011 Deque<ShouldBeTraced> m_deque1;
1927 Vector<ShouldBeTraced> m_vector1; 2012 Vector<ShouldBeTraced> m_vector1;
1928 Deque<Member<IntWrapper> > m_deque2; 2013 Deque<Member<IntWrapper> > m_deque2;
1929 Vector<Member<IntWrapper> > m_vector2; 2014 Vector<Member<IntWrapper> > m_vector2;
1930 HashSet<Member<IntWrapper> > m_hashSet; 2015 HashSet<Member<IntWrapper> > m_hashSet;
1931 HashMap<void*, Member<IntWrapper> > m_hashMap; 2016 HashMap<int, Member<IntWrapper> > m_hashMap;
1932 ListHashSet<Member<IntWrapper> > m_listHashSet; 2017 ListHashSet<Member<IntWrapper> > m_listHashSet;
2018 LinkedHashSet<Member<IntWrapper> > m_linkedHashSet;
1933 Vector<OwnPtr<ShouldBeTraced> > m_ownedVector; 2019 Vector<OwnPtr<ShouldBeTraced> > m_ownedVector;
1934 }; 2020 };
1935 2021
2022 const int OffHeapContainer::iterations;
2023 const int OffHeapContainer::deadWrappers;
1936 2024
1937 // These class definitions test compile-time asserts with transition 2025 // These class definitions test compile-time asserts with transition
1938 // types. They are therefore unused in test code and just need to 2026 // types. They are therefore unused in test code and just need to
1939 // compile. This is intentional; do not delete the A and B classes below. 2027 // compile. This is intentional; do not delete the A and B classes below.
1940 class A : public WillBeGarbageCollectedMixin { 2028 class A : public WillBeGarbageCollectedMixin {
1941 }; 2029 };
1942 2030
1943 class B : public NoBaseWillBeGarbageCollected<B>, public A { 2031 class B : public NoBaseWillBeGarbageCollected<B>, public A {
1944 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(B); 2032 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(B);
1945 public: 2033 public:
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
2379 keepNumbersAlive[0] = nullptr; 2467 keepNumbersAlive[0] = nullptr;
2380 2468
2381 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack); 2469 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2382 2470
2383 EXPECT_EQ(0u, weakStrong->size()); 2471 EXPECT_EQ(0u, weakStrong->size());
2384 EXPECT_EQ(0u, strongWeak->size()); 2472 EXPECT_EQ(0u, strongWeak->size());
2385 EXPECT_EQ(0u, weakWeak->size()); 2473 EXPECT_EQ(0u, weakWeak->size());
2386 EXPECT_EQ(2u, weakSet->size()); 2474 EXPECT_EQ(2u, weakSet->size());
2387 } 2475 }
2388 2476
2477 template<typename Set>
2478 void linkedSetHelper(bool strong)
2479 {
2480 HeapStats initialHeapStats;
2481 clearOutOldGarbage(&initialHeapStats);
2482 IntWrapper::s_destructorCalls = 0;
2483
2484 PersistentHeapVector<Member<IntWrapper> > keepNumbersAlive;
2485
2486 Persistent<Set> set1 = new Set();
2487 Persistent<Set> set2 = new Set();
2488
2489 const Set& constSet = *set1.get();
2490
2491 keepNumbersAlive.append(IntWrapper::create(2));
2492 keepNumbersAlive.append(IntWrapper::create(103));
2493 keepNumbersAlive.append(IntWrapper::create(10));
2494
2495 set1->add(IntWrapper::create(0));
2496 set1->add(keepNumbersAlive[0]);
2497 set1->add(keepNumbersAlive[1]);
2498 set1->add(keepNumbersAlive[2]);
2499
2500 set2->clear();
2501 set2->add(IntWrapper::create(42));
2502 set2->clear();
2503
2504 EXPECT_EQ(4u, set1->size());
2505 typename Set::iterator it(set1->begin());
2506 typename Set::reverse_iterator reverse(set1->rbegin());
2507 typename Set::const_iterator cit(constSet.begin());
2508 typename Set::const_reverse_iterator creverse(constSet.rbegin());
2509
2510 EXPECT_EQ(0, (*it)->value());
2511 EXPECT_EQ(0, (*cit)->value());
2512 ++it;
2513 ++cit;
2514 EXPECT_EQ(2, (*it)->value());
2515 EXPECT_EQ(2, (*cit)->value());
2516 --it;
2517 --cit;
2518 EXPECT_EQ(0, (*it)->value());
2519 EXPECT_EQ(0, (*cit)->value());
2520 ++it;
2521 ++cit;
2522 ++it;
2523 ++cit;
2524 EXPECT_EQ(103, (*it)->value());
2525 EXPECT_EQ(103, (*cit)->value());
2526 ++it;
2527 ++cit;
2528 EXPECT_EQ(10, (*it)->value());
2529 EXPECT_EQ(10, (*cit)->value());
2530 ++it;
2531 ++cit;
2532
2533 EXPECT_EQ(10, (*reverse)->value());
2534 EXPECT_EQ(10, (*creverse)->value());
2535 ++reverse;
2536 ++creverse;
2537 EXPECT_EQ(103, (*reverse)->value());
2538 EXPECT_EQ(103, (*creverse)->value());
2539 --reverse;
2540 --creverse;
2541 EXPECT_EQ(10, (*reverse)->value());
2542 EXPECT_EQ(10, (*creverse)->value());
2543 ++reverse;
2544 ++creverse;
2545 ++reverse;
2546 ++creverse;
2547 EXPECT_EQ(2, (*reverse)->value());
2548 EXPECT_EQ(2, (*creverse)->value());
2549 ++reverse;
2550 ++creverse;
2551 EXPECT_EQ(0, (*reverse)->value());
2552 EXPECT_EQ(0, (*creverse)->value());
2553 ++reverse;
2554 ++creverse;
2555
2556 EXPECT_EQ(set1->end(), it);
2557 EXPECT_EQ(constSet.end(), cit);
2558 EXPECT_EQ(set1->rend(), reverse);
2559 EXPECT_EQ(constSet.rend(), creverse);
2560
2561 typename Set::iterator iX(set2->begin());
2562 EXPECT_EQ(set2->end(), iX);
2563
2564 if (strong)
2565 set1->remove(keepNumbersAlive[0]);
2566
2567 keepNumbersAlive[0] = nullptr;
2568
2569 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2570
2571 EXPECT_EQ(2u + (strong ? 1u : 0u), set1->size());
2572
2573 EXPECT_EQ(2 + (strong ? 0 : 1), IntWrapper::s_destructorCalls);
2574
2575 typename Set::iterator i2(set1->begin());
2576 if (strong) {
2577 EXPECT_EQ(0, (*i2)->value());
2578 ++i2;
2579 EXPECT_NE(set1->end(), i2);
2580 }
2581 EXPECT_EQ(103, (*i2)->value());
2582 ++i2;
2583 EXPECT_NE(set1->end(), i2);
2584 EXPECT_EQ(10, (*i2)->value());
2585 ++i2;
2586 EXPECT_EQ(set1->end(), i2);
2587 }
2588
2589 TEST(HeapTest, HeapWeakLinkedHashSet)
2590 {
2591 linkedSetHelper<HeapLinkedHashSet<Member<IntWrapper> > >(true);
2592 linkedSetHelper<HeapLinkedHashSet<WeakMember<IntWrapper> > >(false);
2593 }
2594
2389 class ThingWithDestructor { 2595 class ThingWithDestructor {
2390 public: 2596 public:
2391 ThingWithDestructor() 2597 ThingWithDestructor()
2392 : m_x(emptyValue) 2598 : m_x(emptyValue)
2393 { 2599 {
2394 s_liveThingsWithDestructor++; 2600 s_liveThingsWithDestructor++;
2395 } 2601 }
2396 2602
2397 ThingWithDestructor(int x) 2603 ThingWithDestructor(int x)
2398 : m_x(x) 2604 : m_x(x)
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after
3005 TEST(HeapTest, VisitOffHeapCollections) 3211 TEST(HeapTest, VisitOffHeapCollections)
3006 { 3212 {
3007 HeapStats initialHeapStats; 3213 HeapStats initialHeapStats;
3008 clearOutOldGarbage(&initialHeapStats); 3214 clearOutOldGarbage(&initialHeapStats);
3009 IntWrapper::s_destructorCalls = 0; 3215 IntWrapper::s_destructorCalls = 0;
3010 Persistent<OffHeapContainer> container = OffHeapContainer::create(); 3216 Persistent<OffHeapContainer> container = OffHeapContainer::create();
3011 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack); 3217 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3012 EXPECT_EQ(0, IntWrapper::s_destructorCalls); 3218 EXPECT_EQ(0, IntWrapper::s_destructorCalls);
3013 container = nullptr; 3219 container = nullptr;
3014 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack); 3220 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
3015 EXPECT_EQ(8, IntWrapper::s_destructorCalls); 3221 EXPECT_EQ(OffHeapContainer::deadWrappers, IntWrapper::s_destructorCalls);
3016 } 3222 }
3017 3223
3018 TEST(HeapTest, PersistentHeapCollectionTypes) 3224 TEST(HeapTest, PersistentHeapCollectionTypes)
3019 { 3225 {
3020 HeapStats initialHeapSize; 3226 HeapStats initialHeapSize;
3021 IntWrapper::s_destructorCalls = 0; 3227 IntWrapper::s_destructorCalls = 0;
3022 3228
3023 typedef HeapVector<Member<IntWrapper> > Vec; 3229 typedef HeapVector<Member<IntWrapper> > Vec;
3024 typedef PersistentHeapVector<Member<IntWrapper> > PVec; 3230 typedef PersistentHeapVector<Member<IntWrapper> > PVec;
3025 typedef PersistentHeapHashSet<Member<IntWrapper> > PSet; 3231 typedef PersistentHeapHashSet<Member<IntWrapper> > PSet;
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
3416 { 3622 {
3417 HeapHashMap<SimpleClassWithDestructor*, OwnPtr<SimpleClassWithDestructor> > map; 3623 HeapHashMap<SimpleClassWithDestructor*, OwnPtr<SimpleClassWithDestructor> > map;
3418 SimpleClassWithDestructor* hasDestructor = new SimpleClassWithDestructor(); 3624 SimpleClassWithDestructor* hasDestructor = new SimpleClassWithDestructor();
3419 map.add(hasDestructor, adoptPtr(hasDestructor)); 3625 map.add(hasDestructor, adoptPtr(hasDestructor));
3420 SimpleClassWithDestructor::s_wasDestructed = false; 3626 SimpleClassWithDestructor::s_wasDestructed = false;
3421 map.clear(); 3627 map.clear();
3422 ASSERT(SimpleClassWithDestructor::s_wasDestructed); 3628 ASSERT(SimpleClassWithDestructor::s_wasDestructed);
3423 } 3629 }
3424 3630
3425 } // WebCore namespace 3631 } // WebCore namespace
OLDNEW
« no previous file with comments | « Source/platform/heap/Heap.h ('k') | Source/platform/heap/Visitor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698