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

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: Review feedback and many more tests 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
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 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 unsigned hash() { return IntHash<int>::hash(m_x); } 293 unsigned hash() { return IntHash<int>::hash(m_x); }
293 294
294 protected: 295 protected:
295 IntWrapper(int x) : m_x(x) { } 296 IntWrapper(int x) : m_x(x) { }
296 297
297 private: 298 private:
298 IntWrapper(); 299 IntWrapper();
299 int m_x; 300 int m_x;
300 }; 301 };
301 302
303 class OffHeapInt : public RefCounted<OffHeapInt> {
304 public:
305 static RefPtr<OffHeapInt> create(int x)
306 {
307 return adoptRef(new OffHeapInt(x));
308 }
309
310 virtual ~OffHeapInt()
311 {
312 ++s_destructorCalls;
313 }
314
315 static int s_destructorCalls;
316
317 int value() const { return m_x; }
318
319 bool operator==(const OffHeapInt& other) const { return other.value() == val ue(); }
320
321 unsigned hash() { return IntHash<int>::hash(m_x); }
322
323 protected:
324 OffHeapInt(int x) : m_x(x) { }
325
326 private:
327 OffHeapInt();
328 int m_x;
329 };
330
302 USED_FROM_MULTIPLE_THREADS(IntWrapper); 331 USED_FROM_MULTIPLE_THREADS(IntWrapper);
303 332
304 int IntWrapper::s_destructorCalls = 0; 333 int IntWrapper::s_destructorCalls = 0;
334 int OffHeapInt::s_destructorCalls = 0;
305 335
306 class ThreadedTesterBase { 336 class ThreadedTesterBase {
307 protected: 337 protected:
308 static void test(ThreadedTesterBase* tester) 338 static void test(ThreadedTesterBase* tester)
309 { 339 {
310 for (int i = 0; i < numberOfThreads; i++) 340 for (int i = 0; i < numberOfThreads; i++)
311 createThread(&threadFunc, tester, "testing thread"); 341 createThread(&threadFunc, tester, "testing thread");
312 while (tester->m_threadsToFinish) { 342 while (tester->m_threadsToFinish) {
313 ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack ); 343 ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack );
314 yield(); 344 yield();
(...skipping 1559 matching lines...) Expand 10 before | Expand all | Expand 10 after
1874 struct ShouldBeTraced { 1904 struct ShouldBeTraced {
1875 explicit ShouldBeTraced(IntWrapper* wrapper) : m_wrapper(wrapper) { } 1905 explicit ShouldBeTraced(IntWrapper* wrapper) : m_wrapper(wrapper) { }
1876 void trace(Visitor* visitor) { visitor->trace(m_wrapper); } 1906 void trace(Visitor* visitor) { visitor->trace(m_wrapper); }
1877 Member<IntWrapper> m_wrapper; 1907 Member<IntWrapper> m_wrapper;
1878 }; 1908 };
1879 1909
1880 class OffHeapContainer : public GarbageCollectedFinalized<OffHeapContainer> { 1910 class OffHeapContainer : public GarbageCollectedFinalized<OffHeapContainer> {
1881 public: 1911 public:
1882 static OffHeapContainer* create() { return new OffHeapContainer(); } 1912 static OffHeapContainer* create() { return new OffHeapContainer(); }
1883 1913
1914 static const int iterations = 300;
1915 static const int deadWrappers = 2400;
1916
1884 OffHeapContainer() 1917 OffHeapContainer()
1885 { 1918 {
1886 m_deque1.append(ShouldBeTraced(IntWrapper::create(1))); 1919 for (int i = 0; i < iterations; i++) {
1887 m_vector1.append(ShouldBeTraced(IntWrapper::create(2))); 1920 m_deque1.append(ShouldBeTraced(IntWrapper::create(i)));
1888 m_deque2.append(IntWrapper::create(3)); 1921 m_vector1.append(ShouldBeTraced(IntWrapper::create(i)));
1889 m_vector2.append(IntWrapper::create(4)); 1922 m_deque2.append(IntWrapper::create(i));
1890 m_hashSet.add(IntWrapper::create(5)); 1923 m_vector2.append(IntWrapper::create(i));
1891 m_hashMap.add(this, IntWrapper::create(6)); 1924 m_hashSet.add(IntWrapper::create(i));
1892 m_listHashSet.add(IntWrapper::create(7)); 1925 m_hashMap.add(i + 103, IntWrapper::create(i));
1926 m_listHashSet.add(IntWrapper::create(i));
1927 m_linkedHashSet.add(IntWrapper::create(i));
1928 }
1929
1930 Deque<ShouldBeTraced>::iterator d1Iterator(m_deque1.begin());
1931 Vector<ShouldBeTraced>::iterator v1Iterator(m_vector1.begin());
1932 Deque<Member<IntWrapper> >::iterator d2Iterator(m_deque2.begin());
1933 Vector<Member<IntWrapper> >::iterator v2Iterator(m_vector2.begin());
1934 HashSet<Member<IntWrapper> >::iterator setIterator(m_hashSet.begin());
1935 HashMap<int, Member<IntWrapper> >::iterator mapIterator(m_hashMap.begin( ));
1936 ListHashSet<Member<IntWrapper> >::iterator listSetIterator(m_listHashSet .begin());
1937 LinkedHashSet<Member<IntWrapper> >::iterator linkedSetIterator(m_linkedH ashSet.begin());
1938
1939 for (int i = 0; i < iterations; i++) {
1940 EXPECT_EQ(i, m_vector1[i].m_wrapper->value());
1941 EXPECT_EQ(i, m_vector2[i]->value());
1942 EXPECT_EQ(i, d1Iterator->m_wrapper->value());
1943 EXPECT_EQ(i, v1Iterator->m_wrapper->value());
1944 EXPECT_EQ(i, d2Iterator->get()->value());
1945 EXPECT_EQ(i, v2Iterator->get()->value());
1946 EXPECT_EQ(i, linkedSetIterator->get()->value());
1947 int value = setIterator->get()->value();
1948 EXPECT_LE(0, value);
1949 EXPECT_GT(iterations, value);
1950 value = listSetIterator->get()->value();
1951 EXPECT_LE(0, value);
1952 EXPECT_GT(iterations, value);
1953 value = mapIterator->value.get()->value();
1954 EXPECT_LE(0, value);
1955 EXPECT_GT(iterations, value);
1956 ++d1Iterator;
1957 ++v1Iterator;
1958 ++d2Iterator;
1959 ++v2Iterator;
1960 ++setIterator;
1961 ++mapIterator;
1962 ++listSetIterator;
1963 ++linkedSetIterator;
1964 }
1965 EXPECT_EQ(d1Iterator, m_deque1.end());
1966 EXPECT_EQ(v1Iterator, m_vector1.end());
1967 EXPECT_EQ(d2Iterator, m_deque2.end());
1968 EXPECT_EQ(v2Iterator, m_vector2.end());
1969 EXPECT_EQ(setIterator, m_hashSet.end());
1970 EXPECT_EQ(mapIterator, m_hashMap.end());
1971 EXPECT_EQ(listSetIterator, m_listHashSet.end());
1972 EXPECT_EQ(linkedSetIterator, m_linkedHashSet.end());
1893 } 1973 }
1894 1974
1895 void trace(Visitor* visitor) 1975 void trace(Visitor* visitor)
1896 { 1976 {
1897 visitor->trace(m_deque1); 1977 visitor->trace(m_deque1);
1898 visitor->trace(m_vector1); 1978 visitor->trace(m_vector1);
1899 visitor->trace(m_deque2); 1979 visitor->trace(m_deque2);
1900 visitor->trace(m_vector2); 1980 visitor->trace(m_vector2);
1901 visitor->trace(m_hashSet); 1981 visitor->trace(m_hashSet);
1902 visitor->trace(m_hashMap); 1982 visitor->trace(m_hashMap);
1903 visitor->trace(m_listHashSet); 1983 visitor->trace(m_listHashSet);
1984 visitor->trace(m_linkedHashSet);
1904 } 1985 }
1905 1986
1906 Deque<ShouldBeTraced> m_deque1; 1987 Deque<ShouldBeTraced> m_deque1;
1907 Vector<ShouldBeTraced> m_vector1; 1988 Vector<ShouldBeTraced> m_vector1;
1908 Deque<Member<IntWrapper> > m_deque2; 1989 Deque<Member<IntWrapper> > m_deque2;
1909 Vector<Member<IntWrapper> > m_vector2; 1990 Vector<Member<IntWrapper> > m_vector2;
1910 HashSet<Member<IntWrapper> > m_hashSet; 1991 HashSet<Member<IntWrapper> > m_hashSet;
1911 HashMap<void*, Member<IntWrapper> > m_hashMap; 1992 HashMap<int, Member<IntWrapper> > m_hashMap;
1912 ListHashSet<Member<IntWrapper> > m_listHashSet; 1993 ListHashSet<Member<IntWrapper> > m_listHashSet;
1994 LinkedHashSet<Member<IntWrapper> > m_linkedHashSet;
1913 }; 1995 };
1914 1996
1997 const int OffHeapContainer::iterations;
1998 const int OffHeapContainer::deadWrappers;
1915 1999
1916 // These class definitions test compile-time asserts with transition 2000 // These class definitions test compile-time asserts with transition
1917 // types. They are therefore unused in test code and just need to 2001 // types. They are therefore unused in test code and just need to
1918 // compile. This is intentional; do not delete the A and B classes below. 2002 // compile. This is intentional; do not delete the A and B classes below.
1919 class A : public WillBeGarbageCollectedMixin { 2003 class A : public WillBeGarbageCollectedMixin {
1920 }; 2004 };
1921 2005
1922 class B : public NoBaseWillBeGarbageCollected<B>, public A { 2006 class B : public NoBaseWillBeGarbageCollected<B>, public A {
1923 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(B); 2007 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(B);
1924 public: 2008 public:
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
2268 keepNumbersAlive[0] = nullptr; 2352 keepNumbersAlive[0] = nullptr;
2269 2353
2270 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack); 2354 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2271 2355
2272 EXPECT_EQ(0u, weakStrong->size()); 2356 EXPECT_EQ(0u, weakStrong->size());
2273 EXPECT_EQ(0u, strongWeak->size()); 2357 EXPECT_EQ(0u, strongWeak->size());
2274 EXPECT_EQ(0u, weakWeak->size()); 2358 EXPECT_EQ(0u, weakWeak->size());
2275 EXPECT_EQ(2u, weakSet->size()); 2359 EXPECT_EQ(2u, weakSet->size());
2276 } 2360 }
2277 2361
2362 template<typename Set>
2363 void linkedSetHelper(bool strong)
2364 {
2365 HeapStats initialHeapStats;
2366 clearOutOldGarbage(&initialHeapStats);
2367 IntWrapper::s_destructorCalls = 0;
2368
2369 PersistentHeapVector<Member<IntWrapper> > keepNumbersAlive;
2370
2371 Persistent<Set> set1 = new Set();
2372 Persistent<Set> set2 = new Set();
2373
2374 const Set& constSet = *set1.get();
2375
2376 keepNumbersAlive.append(IntWrapper::create(2));
2377 keepNumbersAlive.append(IntWrapper::create(103));
2378 keepNumbersAlive.append(IntWrapper::create(10));
2379
2380 set1->add(IntWrapper::create(0));
2381 set1->add(keepNumbersAlive[0]);
2382 set1->add(keepNumbersAlive[1]);
2383 set1->add(keepNumbersAlive[2]);
2384
2385 set2->clear();
2386 set2->add(IntWrapper::create(42));
2387 set2->clear();
2388
2389 EXPECT_EQ(4u, set1->size());
2390 typename Set::iterator it(set1->begin());
2391 typename Set::reverse_iterator reverse(set1->rbegin());
2392 typename Set::const_iterator cit(constSet.begin());
2393 typename Set::const_reverse_iterator creverse(constSet.rbegin());
2394
2395 EXPECT_EQ(0, (*it)->value());
2396 EXPECT_EQ(0, (*cit)->value());
2397 ++it;
2398 ++cit;
2399 EXPECT_EQ(2, (*it)->value());
2400 EXPECT_EQ(2, (*cit)->value());
2401 --it;
2402 --cit;
2403 EXPECT_EQ(0, (*it)->value());
2404 EXPECT_EQ(0, (*cit)->value());
2405 ++it;
2406 ++cit;
2407 ++it;
2408 ++cit;
2409 EXPECT_EQ(103, (*it)->value());
2410 EXPECT_EQ(103, (*cit)->value());
2411 ++it;
2412 ++cit;
2413 EXPECT_EQ(10, (*it)->value());
2414 EXPECT_EQ(10, (*cit)->value());
2415 ++it;
2416 ++cit;
2417
2418 EXPECT_EQ(10, (*reverse)->value());
2419 EXPECT_EQ(10, (*creverse)->value());
2420 ++reverse;
2421 ++creverse;
2422 EXPECT_EQ(103, (*reverse)->value());
2423 EXPECT_EQ(103, (*creverse)->value());
2424 --reverse;
2425 --creverse;
2426 EXPECT_EQ(10, (*reverse)->value());
2427 EXPECT_EQ(10, (*creverse)->value());
2428 ++reverse;
2429 ++creverse;
2430 ++reverse;
2431 ++creverse;
2432 EXPECT_EQ(2, (*reverse)->value());
2433 EXPECT_EQ(2, (*creverse)->value());
2434 ++reverse;
2435 ++creverse;
2436 EXPECT_EQ(0, (*reverse)->value());
2437 EXPECT_EQ(0, (*creverse)->value());
2438 ++reverse;
2439 ++creverse;
2440
2441 EXPECT_EQ(set1->end(), it);
2442 EXPECT_EQ(constSet.end(), cit);
2443 EXPECT_EQ(set1->rend(), reverse);
2444 EXPECT_EQ(constSet.rend(), creverse);
2445
2446 typename Set::iterator iX(set2->begin());
2447 EXPECT_EQ(set2->end(), iX);
2448
2449 if (strong)
2450 set1->remove(keepNumbersAlive[0]);
2451
2452 keepNumbersAlive[0] = nullptr;
2453
2454 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2455
2456 EXPECT_EQ(2u + (strong ? 1u : 0u), set1->size());
2457
2458 EXPECT_EQ(2 + (strong ? 0 : 1), IntWrapper::s_destructorCalls);
2459
2460 typename Set::iterator i2(set1->begin());
2461 if (strong) {
2462 EXPECT_EQ(0, (*i2)->value());
2463 ++i2;
2464 EXPECT_NE(set1->end(), i2);
2465 }
2466 EXPECT_EQ(103, (*i2)->value());
2467 ++i2;
2468 EXPECT_NE(set1->end(), i2);
2469 EXPECT_EQ(10, (*i2)->value());
2470 ++i2;
2471 EXPECT_EQ(set1->end(), i2);
2472 }
2473
2474 TEST(HeapTest, HeapWeakLinkedHashSet)
2475 {
2476 linkedSetHelper<HeapLinkedHashSet<Member<IntWrapper> > >(true);
2477 linkedSetHelper<HeapLinkedHashSet<WeakMember<IntWrapper> > >(false);
2478 }
2479
2278 class ThingWithDestructor { 2480 class ThingWithDestructor {
2279 public: 2481 public:
2280 ThingWithDestructor() 2482 ThingWithDestructor()
2281 : m_x(emptyValue) 2483 : m_x(emptyValue)
2282 { 2484 {
2283 s_liveThingsWithDestructor++; 2485 s_liveThingsWithDestructor++;
2284 } 2486 }
2285 2487
2286 ThingWithDestructor(int x) 2488 ThingWithDestructor(int x)
2287 : m_x(x) 2489 : m_x(x)
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after
2894 TEST(HeapTest, VisitOffHeapCollections) 3096 TEST(HeapTest, VisitOffHeapCollections)
2895 { 3097 {
2896 HeapStats initialHeapStats; 3098 HeapStats initialHeapStats;
2897 clearOutOldGarbage(&initialHeapStats); 3099 clearOutOldGarbage(&initialHeapStats);
2898 IntWrapper::s_destructorCalls = 0; 3100 IntWrapper::s_destructorCalls = 0;
2899 Persistent<OffHeapContainer> container = OffHeapContainer::create(); 3101 Persistent<OffHeapContainer> container = OffHeapContainer::create();
2900 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack); 3102 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2901 EXPECT_EQ(0, IntWrapper::s_destructorCalls); 3103 EXPECT_EQ(0, IntWrapper::s_destructorCalls);
2902 container = nullptr; 3104 container = nullptr;
2903 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack); 3105 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
2904 EXPECT_EQ(7, IntWrapper::s_destructorCalls); 3106 EXPECT_EQ(OffHeapContainer::deadWrappers, IntWrapper::s_destructorCalls);
2905 } 3107 }
2906 3108
2907 TEST(HeapTest, PersistentHeapCollectionTypes) 3109 TEST(HeapTest, PersistentHeapCollectionTypes)
2908 { 3110 {
2909 HeapStats initialHeapSize; 3111 HeapStats initialHeapSize;
2910 IntWrapper::s_destructorCalls = 0; 3112 IntWrapper::s_destructorCalls = 0;
2911 3113
2912 typedef HeapVector<Member<IntWrapper> > Vec; 3114 typedef HeapVector<Member<IntWrapper> > Vec;
2913 typedef PersistentHeapVector<Member<IntWrapper> > PVec; 3115 typedef PersistentHeapVector<Member<IntWrapper> > PVec;
2914 typedef PersistentHeapHashSet<Member<IntWrapper> > PSet; 3116 typedef PersistentHeapHashSet<Member<IntWrapper> > PSet;
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
3225 { 3427 {
3226 HeapHashMap<SimpleClassWithDestructor*, OwnPtr<SimpleClassWithDestructor> > map; 3428 HeapHashMap<SimpleClassWithDestructor*, OwnPtr<SimpleClassWithDestructor> > map;
3227 SimpleClassWithDestructor* hasDestructor = new SimpleClassWithDestructor(); 3429 SimpleClassWithDestructor* hasDestructor = new SimpleClassWithDestructor();
3228 map.add(hasDestructor, adoptPtr(hasDestructor)); 3430 map.add(hasDestructor, adoptPtr(hasDestructor));
3229 SimpleClassWithDestructor::s_wasDestructed = false; 3431 SimpleClassWithDestructor::s_wasDestructed = false;
3230 map.clear(); 3432 map.clear();
3231 ASSERT(SimpleClassWithDestructor::s_wasDestructed); 3433 ASSERT(SimpleClassWithDestructor::s_wasDestructed);
3232 } 3434 }
3233 3435
3234 } // WebCore namespace 3436 } // WebCore namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698