Home | History | Annotate | Download | only in wtf
      1 /*
      2  *  Copyright (C) 2008 Apple Inc. All rights reserved.
      3  *
      4  *  This library is free software; you can redistribute it and/or
      5  *  modify it under the terms of the GNU Library General Public
      6  *  License as published by the Free Software Foundation; either
      7  *  version 2 of the License, or (at your option) any later version.
      8  *
      9  *  This library is distributed in the hope that it will be useful,
     10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12  *  Library General Public License for more details.
     13  *
     14  *  You should have received a copy of the GNU Library General Public License
     15  *  along with this library; see the file COPYING.LIB.  If not, write to
     16  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     17  *  Boston, MA 02110-1301, USA.
     18  *
     19  */
     20 
     21 #include "config.h"
     22 #include "RefCountedLeakCounter.h"
     23 
     24 #ifndef NDEBUG
     25 #include "wtf/Assertions.h"
     26 #include "wtf/Atomics.h"
     27 #include "wtf/HashCountedSet.h"
     28 #endif
     29 
     30 namespace WTF {
     31 
     32 #ifdef NDEBUG
     33 
     34 void RefCountedLeakCounter::suppressMessages(const char*) { }
     35 void RefCountedLeakCounter::cancelMessageSuppression(const char*) { }
     36 
     37 RefCountedLeakCounter::RefCountedLeakCounter(const char*) { }
     38 RefCountedLeakCounter::~RefCountedLeakCounter() { }
     39 
     40 void RefCountedLeakCounter::increment() { }
     41 void RefCountedLeakCounter::decrement() { }
     42 
     43 #else
     44 
     45 #define LOG_CHANNEL_PREFIX Log
     46 static WTFLogChannel LogRefCountedLeaks = { WTFLogChannelOn };
     47 
     48 typedef HashCountedSet<const char*, PtrHash<const char*> > ReasonSet;
     49 static ReasonSet* leakMessageSuppressionReasons;
     50 
     51 void RefCountedLeakCounter::suppressMessages(const char* reason)
     52 {
     53     if (!leakMessageSuppressionReasons)
     54         leakMessageSuppressionReasons = new ReasonSet;
     55     leakMessageSuppressionReasons->add(reason);
     56 }
     57 
     58 void RefCountedLeakCounter::cancelMessageSuppression(const char* reason)
     59 {
     60     ASSERT(leakMessageSuppressionReasons);
     61     ASSERT(leakMessageSuppressionReasons->contains(reason));
     62     leakMessageSuppressionReasons->remove(reason);
     63 }
     64 
     65 RefCountedLeakCounter::RefCountedLeakCounter(const char* description)
     66     : m_description(description)
     67 {
     68 }
     69 
     70 RefCountedLeakCounter::~RefCountedLeakCounter()
     71 {
     72     static bool loggedSuppressionReason;
     73     if (m_count) {
     74         if (!leakMessageSuppressionReasons || leakMessageSuppressionReasons->isEmpty())
     75             WTF_LOG(RefCountedLeaks, "LEAK: %u %s", m_count, m_description);
     76         else if (!loggedSuppressionReason) {
     77             // This logs only one reason. Later we could change it so we log all the reasons.
     78             WTF_LOG(RefCountedLeaks, "No leak checking done: %s", leakMessageSuppressionReasons->begin()->key);
     79             loggedSuppressionReason = true;
     80         }
     81     }
     82 }
     83 
     84 void RefCountedLeakCounter::increment()
     85 {
     86     atomicIncrement(&m_count);
     87 }
     88 
     89 void RefCountedLeakCounter::decrement()
     90 {
     91     atomicDecrement(&m_count);
     92 }
     93 
     94 #endif
     95 
     96 } // namespace WTF
     97