Change the ClangASTMap implementation to use a thread-safe wrapper over llvm::DenseMap. This helps avoid a certain class of spins per <rdar://problem/18160764>

llvm-svn: 217888
This commit is contained in:
Enrico Granata 2014-09-16 17:28:40 +00:00
parent 6cd75b36ed
commit 2267ad442a
3 changed files with 79 additions and 6 deletions

View File

@ -0,0 +1,65 @@
//===-- ThreadSafeDenseMap.h ------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef liblldb_ThreadSafeDenseMap_h_
#define liblldb_ThreadSafeDenseMap_h_
// C Includes
// C++ Includes
// Other libraries and framework includes
#include "llvm/ADT/DenseMap.h"
// Project includes
#include "lldb/Host/Mutex.h"
namespace lldb_private {
template <typename _KeyType, typename _ValueType>
class ThreadSafeDenseMap
{
public:
typedef llvm::DenseMap<_KeyType,_ValueType> LLVMMapType;
ThreadSafeDenseMap(unsigned map_initial_capacity = 0,
Mutex::Type mutex_type = Mutex::eMutexTypeNormal) :
m_map(map_initial_capacity),
m_mutex(mutex_type)
{
}
void
Insert (_KeyType k, _ValueType v)
{
Mutex::Locker locker(m_mutex);
m_map.insert(std::make_pair(k,v));
}
void
Erase (_KeyType k)
{
Mutex::Locker locker(m_mutex);
m_map.erase(k);
}
_ValueType
Lookup (_KeyType k)
{
Mutex::Locker locker(m_mutex);
return m_map.lookup(k);
}
protected:
LLVMMapType m_map;
Mutex m_mutex;
};
} // namespace lldb_private
#endif // liblldb_ThreadSafeSTLMap_h_

View File

@ -2046,6 +2046,7 @@
94EA1D5B15E6C9B400D4171A /* PythonDataObjects.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PythonDataObjects.cpp; path = source/Interpreter/PythonDataObjects.cpp; sourceTree = "<group>"; };
94EA27CD17DE91750070F505 /* LibCxxUnorderedMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxUnorderedMap.cpp; path = source/DataFormatters/LibCxxUnorderedMap.cpp; sourceTree = "<group>"; };
94EBAC8313D9EE26009BA64E /* PythonPointer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PythonPointer.h; path = include/lldb/Utility/PythonPointer.h; sourceTree = "<group>"; };
94ED54A119C8A822007BE2EA /* ThreadSafeDenseMap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ThreadSafeDenseMap.h; path = include/lldb/Core/ThreadSafeDenseMap.h; sourceTree = "<group>"; };
94EE33F218643C6900CD703B /* FormattersContainer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FormattersContainer.h; path = include/lldb/DataFormatters/FormattersContainer.h; sourceTree = "<group>"; };
94F6C4D119C264C70049D089 /* ProcessStructReader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ProcessStructReader.h; path = include/lldb/Utility/ProcessStructReader.h; sourceTree = "<group>"; };
94FA3DDD1405D4E500833217 /* ValueObjectConstResultChild.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ValueObjectConstResultChild.h; path = include/lldb/Core/ValueObjectConstResultChild.h; sourceTree = "<group>"; };
@ -3306,6 +3307,7 @@
263FEDA5112CC1DA00E4C208 /* ThreadSafeSTLMap.h */,
26BC7D7E10F1B77400F91463 /* Timer.h */,
26BC7E9610F1B85900F91463 /* Timer.cpp */,
94ED54A119C8A822007BE2EA /* ThreadSafeDenseMap.h */,
268A813F115B19D000F645B0 /* UniqueCStringMap.h */,
26BC7D8010F1B77400F91463 /* UserID.h */,
26BC7E9810F1B85900F91463 /* UserID.cpp */,

View File

@ -11,6 +11,7 @@
// C Includes
// C++ Includes
#include <mutex>
#include <string>
// Other libraries and framework includes
@ -62,6 +63,7 @@
#include "lldb/Core/Flags.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/ThreadSafeDenseMap.h"
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Expression/ASTDumper.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
@ -79,13 +81,17 @@ using namespace lldb_private;
using namespace llvm;
using namespace clang;
typedef llvm::DenseMap<clang::ASTContext *, ClangASTContext*> ClangASTMap;
typedef lldb_private::ThreadSafeDenseMap<clang::ASTContext *, ClangASTContext*> ClangASTMap;
static ClangASTMap &
GetASTMap()
{
static ClangASTMap g_map;
return g_map;
static ClangASTMap *g_map_ptr = nullptr;
static std::once_flag g_once_flag;
std::call_once(g_once_flag, []() {
g_map_ptr = new ClangASTMap(); // leaked on purpose to avoid spins
});
return *g_map_ptr;
}
@ -303,7 +309,7 @@ ClangASTContext::~ClangASTContext()
{
if (m_ast_ap.get())
{
GetASTMap().erase(m_ast_ap.get());
GetASTMap().Erase(m_ast_ap.get());
}
m_builtins_ap.reset();
@ -409,7 +415,7 @@ ClangASTContext::getASTContext()
m_ast_ap->getDiagnostics().setClient(getDiagnosticConsumer(), false);
GetASTMap().insert(std::make_pair(m_ast_ap.get(), this));
GetASTMap().Insert(m_ast_ap.get(), this);
}
return m_ast_ap.get();
}
@ -417,7 +423,7 @@ ClangASTContext::getASTContext()
ClangASTContext*
ClangASTContext::GetASTContext (clang::ASTContext* ast)
{
ClangASTContext *clang_ast = GetASTMap().lookup(ast);
ClangASTContext *clang_ast = GetASTMap().Lookup(ast);
return clang_ast;
}