1de69a4ca2fd66cc600116a10bef1f3ab1610d62cChris Lattner//===-- LeakDetector.cpp - Implement LeakDetector interface ---------------===//
2fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman//
3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//                     The LLVM Compiler Infrastructure
4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman//
8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//===----------------------------------------------------------------------===//
9de69a4ca2fd66cc600116a10bef1f3ab1610d62cChris Lattner//
10de69a4ca2fd66cc600116a10bef1f3ab1610d62cChris Lattner// This file implements the LeakDetector class.
11de69a4ca2fd66cc600116a10bef1f3ab1610d62cChris Lattner//
12de69a4ca2fd66cc600116a10bef1f3ab1610d62cChris Lattner//===----------------------------------------------------------------------===//
13de69a4ca2fd66cc600116a10bef1f3ab1610d62cChris Lattner
1436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/LeakDetector.h"
15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "LLVMContextImpl.h"
169d7f0b76aac3bf0524e9285101e34c15e1e2c599Owen Anderson#include "llvm/ADT/SmallPtrSet.h"
170b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Value.h"
18e81561909d128c6e2d8033cb5465a49b2596b26aBill Wendling#include "llvm/Support/Compiler.h"
1992f2c871105a1ae5e00655a2f731b6bab3983621Owen Anderson#include "llvm/Support/ManagedStatic.h"
201f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Mutex.h"
211f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Threading.h"
222cdd21c2e4d855500dfb53f77aa74da53ccf9de6Chris Lattnerusing namespace llvm;
23d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
24c34ebf65af0139eaf5cb0969fabcd32c0b6e1710Owen Andersonstatic ManagedStatic<sys::SmartMutex<true> > ObjectsLock;
25c34ebf65af0139eaf5cb0969fabcd32c0b6e1710Owen Andersonstatic ManagedStatic<LeakDetectorImpl<void> > Objects;
26ce36d55cf8d3239942e0e9c426c835f0c33a11e6Chris Lattner
27c34ebf65af0139eaf5cb0969fabcd32c0b6e1710Owen Andersonstatic void clearGarbage(LLVMContext &Context) {
28c34ebf65af0139eaf5cb0969fabcd32c0b6e1710Owen Anderson  Objects->clear();
29c34ebf65af0139eaf5cb0969fabcd32c0b6e1710Owen Anderson  Context.pImpl->LLVMObjects.clear();
30de69a4ca2fd66cc600116a10bef1f3ab1610d62cChris Lattner}
31b663d76f866d03756dd563d246d9bdaabca4ca33Alkis Evlogimenos
32b663d76f866d03756dd563d246d9bdaabca4ca33Alkis Evlogimenosvoid LeakDetector::addGarbageObjectImpl(void *Object) {
33c34ebf65af0139eaf5cb0969fabcd32c0b6e1710Owen Anderson  sys::SmartScopedLock<true> Lock(*ObjectsLock);
3492f2c871105a1ae5e00655a2f731b6bab3983621Owen Anderson  Objects->addGarbage(Object);
35b663d76f866d03756dd563d246d9bdaabca4ca33Alkis Evlogimenos}
36b663d76f866d03756dd563d246d9bdaabca4ca33Alkis Evlogimenos
37b663d76f866d03756dd563d246d9bdaabca4ca33Alkis Evlogimenosvoid LeakDetector::addGarbageObjectImpl(const Value *Object) {
38c34ebf65af0139eaf5cb0969fabcd32c0b6e1710Owen Anderson  LLVMContextImpl *pImpl = Object->getContext().pImpl;
39c34ebf65af0139eaf5cb0969fabcd32c0b6e1710Owen Anderson  pImpl->LLVMObjects.addGarbage(Object);
40b663d76f866d03756dd563d246d9bdaabca4ca33Alkis Evlogimenos}
41b663d76f866d03756dd563d246d9bdaabca4ca33Alkis Evlogimenos
42b663d76f866d03756dd563d246d9bdaabca4ca33Alkis Evlogimenosvoid LeakDetector::removeGarbageObjectImpl(void *Object) {
43c34ebf65af0139eaf5cb0969fabcd32c0b6e1710Owen Anderson  sys::SmartScopedLock<true> Lock(*ObjectsLock);
4492f2c871105a1ae5e00655a2f731b6bab3983621Owen Anderson  Objects->removeGarbage(Object);
45b663d76f866d03756dd563d246d9bdaabca4ca33Alkis Evlogimenos}
46b663d76f866d03756dd563d246d9bdaabca4ca33Alkis Evlogimenos
47b663d76f866d03756dd563d246d9bdaabca4ca33Alkis Evlogimenosvoid LeakDetector::removeGarbageObjectImpl(const Value *Object) {
48c34ebf65af0139eaf5cb0969fabcd32c0b6e1710Owen Anderson  LLVMContextImpl *pImpl = Object->getContext().pImpl;
49c34ebf65af0139eaf5cb0969fabcd32c0b6e1710Owen Anderson  pImpl->LLVMObjects.removeGarbage(Object);
50b663d76f866d03756dd563d246d9bdaabca4ca33Alkis Evlogimenos}
51b663d76f866d03756dd563d246d9bdaabca4ca33Alkis Evlogimenos
52c34ebf65af0139eaf5cb0969fabcd32c0b6e1710Owen Andersonvoid LeakDetector::checkForGarbageImpl(LLVMContext &Context,
53c34ebf65af0139eaf5cb0969fabcd32c0b6e1710Owen Anderson                                       const std::string &Message) {
54c34ebf65af0139eaf5cb0969fabcd32c0b6e1710Owen Anderson  LLVMContextImpl *pImpl = Context.pImpl;
55c34ebf65af0139eaf5cb0969fabcd32c0b6e1710Owen Anderson  sys::SmartScopedLock<true> Lock(*ObjectsLock);
56c34ebf65af0139eaf5cb0969fabcd32c0b6e1710Owen Anderson
5792f2c871105a1ae5e00655a2f731b6bab3983621Owen Anderson  Objects->setName("GENERIC");
58c34ebf65af0139eaf5cb0969fabcd32c0b6e1710Owen Anderson  pImpl->LLVMObjects.setName("LLVM");
5992f2c871105a1ae5e00655a2f731b6bab3983621Owen Anderson
60b663d76f866d03756dd563d246d9bdaabca4ca33Alkis Evlogimenos  // use non-short-circuit version so that both checks are performed
6192f2c871105a1ae5e00655a2f731b6bab3983621Owen Anderson  if (Objects->hasGarbage(Message) |
62c34ebf65af0139eaf5cb0969fabcd32c0b6e1710Owen Anderson      pImpl->LLVMObjects.hasGarbage(Message))
63cfa6ec92e61a1ab040c2b79db5de3a39df732ff6Benjamin Kramer    errs() << "\nThis is probably because you removed an object, but didn't "
64cfa6ec92e61a1ab040c2b79db5de3a39df732ff6Benjamin Kramer           << "delete it.  Please check your code for memory leaks.\n";
659945826d50e46212234a6297fda88e2de50f48a6Chris Lattner
669945826d50e46212234a6297fda88e2de50f48a6Chris Lattner  // Clear out results so we don't get duplicate warnings on
679945826d50e46212234a6297fda88e2de50f48a6Chris Lattner  // next call...
68c34ebf65af0139eaf5cb0969fabcd32c0b6e1710Owen Anderson  clearGarbage(Context);
69b663d76f866d03756dd563d246d9bdaabca4ca33Alkis Evlogimenos}
70