blob: 835e5e61cdf9380133abc6cba8ff54afa49e5a7a [file] [log] [blame]
Chris Lattnerde69a4c2002-09-08 18:51:16 +00001//===-- LeakDetector.cpp - Implement LeakDetector interface ---------------===//
Misha Brukmanfd939082005-04-21 23:48:37 +00002//
John Criswellb576c942003-10-20 19:43:21 +00003// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Misha Brukmanfd939082005-04-21 23:48:37 +00007//
John Criswellb576c942003-10-20 19:43:21 +00008//===----------------------------------------------------------------------===//
Chris Lattnerde69a4c2002-09-08 18:51:16 +00009//
10// This file implements the LeakDetector class.
11//
12//===----------------------------------------------------------------------===//
13
Bill Wendling8f487662006-11-28 02:09:03 +000014#include "llvm/Support/LeakDetector.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000015#include "LLVMContextImpl.h"
Owen Anderson9d7f0b72008-08-14 20:40:10 +000016#include "llvm/ADT/SmallPtrSet.h"
Chandler Carruth0b8c9a82013-01-02 11:36:10 +000017#include "llvm/IR/Value.h"
Bill Wendlinge8156192006-12-07 01:30:32 +000018#include "llvm/Support/Compiler.h"
Owen Anderson92f2c872009-06-17 21:56:05 +000019#include "llvm/Support/ManagedStatic.h"
Michael J. Spencer1f6efa32010-11-29 18:16:10 +000020#include "llvm/Support/Mutex.h"
21#include "llvm/Support/Threading.h"
Chris Lattner2cdd21c2003-12-14 21:35:53 +000022using namespace llvm;
Brian Gaeked0fde302003-11-11 22:41:34 +000023
Owen Andersonc34ebf62009-08-19 17:07:46 +000024static ManagedStatic<sys::SmartMutex<true> > ObjectsLock;
25static ManagedStatic<LeakDetectorImpl<void> > Objects;
Chris Lattnerce36d552004-07-15 01:29:12 +000026
Owen Andersonc34ebf62009-08-19 17:07:46 +000027static void clearGarbage(LLVMContext &Context) {
28 Objects->clear();
29 Context.pImpl->LLVMObjects.clear();
Chris Lattnerde69a4c2002-09-08 18:51:16 +000030}
31
Alkis Evlogimenosb663d762004-02-14 23:33:39 +000032void LeakDetector::addGarbageObjectImpl(void *Object) {
Owen Andersonc34ebf62009-08-19 17:07:46 +000033 sys::SmartScopedLock<true> Lock(*ObjectsLock);
Owen Anderson92f2c872009-06-17 21:56:05 +000034 Objects->addGarbage(Object);
Chris Lattnerde69a4c2002-09-08 18:51:16 +000035}
36
37void LeakDetector::addGarbageObjectImpl(const Value *Object) {
Owen Andersonc34ebf62009-08-19 17:07:46 +000038 LLVMContextImpl *pImpl = Object->getContext().pImpl;
Owen Andersonc34ebf62009-08-19 17:07:46 +000039 pImpl->LLVMObjects.addGarbage(Object);
Alkis Evlogimenosb663d762004-02-14 23:33:39 +000040}
41
42void LeakDetector::removeGarbageObjectImpl(void *Object) {
Owen Andersonc34ebf62009-08-19 17:07:46 +000043 sys::SmartScopedLock<true> Lock(*ObjectsLock);
Owen Anderson92f2c872009-06-17 21:56:05 +000044 Objects->removeGarbage(Object);
Chris Lattnerde69a4c2002-09-08 18:51:16 +000045}
46
47void LeakDetector::removeGarbageObjectImpl(const Value *Object) {
Owen Andersonc34ebf62009-08-19 17:07:46 +000048 LLVMContextImpl *pImpl = Object->getContext().pImpl;
Owen Andersonc34ebf62009-08-19 17:07:46 +000049 pImpl->LLVMObjects.removeGarbage(Object);
Chris Lattnerde69a4c2002-09-08 18:51:16 +000050}
51
Owen Andersonc34ebf62009-08-19 17:07:46 +000052void LeakDetector::checkForGarbageImpl(LLVMContext &Context,
53 const std::string &Message) {
54 LLVMContextImpl *pImpl = Context.pImpl;
55 sys::SmartScopedLock<true> Lock(*ObjectsLock);
Owen Andersonc34ebf62009-08-19 17:07:46 +000056
Owen Anderson92f2c872009-06-17 21:56:05 +000057 Objects->setName("GENERIC");
Owen Andersonc34ebf62009-08-19 17:07:46 +000058 pImpl->LLVMObjects.setName("LLVM");
Owen Anderson92f2c872009-06-17 21:56:05 +000059
Alkis Evlogimenosb663d762004-02-14 23:33:39 +000060 // use non-short-circuit version so that both checks are performed
Owen Anderson92f2c872009-06-17 21:56:05 +000061 if (Objects->hasGarbage(Message) |
Owen Andersonc34ebf62009-08-19 17:07:46 +000062 pImpl->LLVMObjects.hasGarbage(Message))
Benjamin Kramercfa6ec92009-08-23 11:37:21 +000063 errs() << "\nThis is probably because you removed an object, but didn't "
64 << "delete it. Please check your code for memory leaks.\n";
Chris Lattner99458262004-11-19 17:09:48 +000065
66 // Clear out results so we don't get duplicate warnings on
67 // next call...
Owen Andersonc34ebf62009-08-19 17:07:46 +000068 clearGarbage(Context);
Chris Lattnerde69a4c2002-09-08 18:51:16 +000069}