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

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

Powered by Google App Engine
This is Rietveld 408576698