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 20 matching lines...) Expand all Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |