blob: ffb081a998201e696db07fe1ef726faa8e757d6b [file] [log] [blame]
Chris Lattnerde69a4c2002-09-08 18:51:16 +00001//===-- LeakDetector.cpp - Implement LeakDetector interface ---------------===//
John Criswellb576c942003-10-20 19:43:21 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Chris Lattnerde69a4c2002-09-08 18:51:16 +00009//
10// This file implements the LeakDetector class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Support/LeakDetector.h"
15#include "llvm/Value.h"
16#include <set>
Chris Lattnerde69a4c2002-09-08 18:51:16 +000017
Brian Gaeked0fde302003-11-11 22:41:34 +000018namespace llvm {
19
Chris Lattnerde69a4c2002-09-08 18:51:16 +000020// Lazily allocate set so that release build doesn't have to do anything.
21static std::set<const void*> *Objects = 0;
22static std::set<const Value*> *LLVMObjects = 0;
23
Chris Lattner3f6962e2002-09-19 19:22:11 +000024// Because the most common usage pattern, by far, is to add a garbage object,
25// then remove it immediately, we optimize this case. When an object is added,
26// it is not added to the set immediately, it is added to the CachedValue Value.
27// If it is immediately removed, no set search need be performed.
28//
29static const Value *CachedValue;
30
Chris Lattnerde69a4c2002-09-08 18:51:16 +000031void LeakDetector::addGarbageObjectImpl(void *Object) {
32 if (Objects == 0)
33 Objects = new std::set<const void*>();
34 assert(Objects->count(Object) == 0 && "Object already in set!");
35 Objects->insert(Object);
36}
37
38void LeakDetector::removeGarbageObjectImpl(void *Object) {
39 if (Objects)
40 Objects->erase(Object);
41}
42
43void LeakDetector::addGarbageObjectImpl(const Value *Object) {
Chris Lattner3f6962e2002-09-19 19:22:11 +000044 if (CachedValue) {
45 if (LLVMObjects == 0)
46 LLVMObjects = new std::set<const Value*>();
47 assert(LLVMObjects->count(CachedValue) == 0 && "Object already in set!");
48 LLVMObjects->insert(CachedValue);
49 }
50 CachedValue = Object;
Chris Lattnerde69a4c2002-09-08 18:51:16 +000051}
52
53void LeakDetector::removeGarbageObjectImpl(const Value *Object) {
Chris Lattner3f6962e2002-09-19 19:22:11 +000054 if (Object == CachedValue)
55 CachedValue = 0; // Cache hit!
56 else if (LLVMObjects)
Chris Lattnerde69a4c2002-09-08 18:51:16 +000057 LLVMObjects->erase(Object);
58}
59
60void LeakDetector::checkForGarbageImpl(const std::string &Message) {
Chris Lattner3f6962e2002-09-19 19:22:11 +000061 if (CachedValue) // Flush the cache to the set...
62 addGarbageObjectImpl((Value*)0);
63
64 assert(CachedValue == 0 && "No value should be cached anymore!");
65
Chris Lattnerde69a4c2002-09-08 18:51:16 +000066 if ((Objects && !Objects->empty()) || (LLVMObjects && !LLVMObjects->empty())){
67 std::cerr << "Leaked objects found: " << Message << "\n";
68
69 if (Objects && !Objects->empty()) {
70 std::cerr << " Non-Value objects leaked:";
71 for (std::set<const void*>::iterator I = Objects->begin(),
72 E = Objects->end(); I != E; ++I)
73 std::cerr << " " << *I;
74 }
75
76 if (LLVMObjects && !LLVMObjects->empty()) {
77 std::cerr << " LLVM Value subclasses leaked:";
78 for (std::set<const Value*>::iterator I = LLVMObjects->begin(),
79 E = LLVMObjects->end(); I != E; ++I)
80 std::cerr << **I << "\n";
81 }
82
83 std::cerr << "This is probably because you removed an LLVM value "
84 << "(Instruction, BasicBlock, \netc), but didn't delete it. "
85 << "Please check your code for memory leaks.\n";
86
87 // Clear out results so we don't get duplicate warnings on next call...
88 delete Objects; delete LLVMObjects;
89 Objects = 0; LLVMObjects = 0;
90 }
91}
Brian Gaeked0fde302003-11-11 22:41:34 +000092
93} // End llvm namespace