Index: searchtree.h
===================================================================
--- searchtree.h (revision 5679)
+++ searchtree.h (working copy)
@@ -5,7 +5,8 @@
#ifndef SEARCHTREE_H
#define SEARCHTREE_H
-#include <wx/string.h>
+#include <wx/string.h>
+#include "blockallocated.h"
#include <vector>
#include <map>
@@ -74,7 +75,7 @@
SearchTreePoint (nSearchTreeNode nn, size_t dd) { n = nn; depth = dd; }
};
-class SearchTreeNode
+class SearchTreeNode:public BlockAllocated<SearchTreeNode, 10000>
{
friend class BasicSearchTree;
friend class BasicSearchTreeIterator;
class Token : public BlockAllocated<Token, 10000>
Token* ParserThread::DoAddToken(TokenKind kind, const wxString& name, int line, int implLineStart, int implLineEnd, const wxString& args, bool isOperator, bool isImpl)
{
if(TestDestroy())
return 0;
if (name.IsEmpty())
return 0; // oops!
// if (m_Options.useBuffer && !m_Options.isTemp && TokenExists(name, m_pLastParent, kind))
// return 0;
s_MutexProtection.Enter();
Token* newToken = 0;
wxString newname(name);
m_Str.Trim();
//if (name == _T("AlsoDoSomething"))
// asm("int $3;");
if (kind == tkDestructor)
{
// special class destructors case
newname.Prepend(ParserConsts::tilde);
m_Str.Clear();
}
Token* localParent = 0;
// preserve m_EncounteredTypeNamespaces; needed further down this function
std::queue<wxString> q = m_EncounteredTypeNamespaces;
if ((kind == tkDestructor || kind == tkConstructor) && !q.empty())
{
// look in m_EncounteredTypeNamespaces
localParent = FindTokenFromQueue(q, 0, true, m_pLastParent);
if (localParent)
newToken = TokenExists(newname, localParent);
}
// check for implementation member function
if (!newToken && !m_EncounteredNamespaces.empty())
{
localParent = FindTokenFromQueue(m_EncounteredNamespaces, 0, true, m_pLastParent);
if (localParent)
newToken = TokenExists(newname, localParent);
}
// none of the above; check for token under parent (but not if we 're parsing a temp buffer)
if (!newToken && !m_Options.isTemp)
newToken = TokenExists(name, m_pLastParent, kind);
if (newToken && newToken->m_TokenKind == kind && newToken->m_Args == args)
{
m_pTokens->m_modified = true;
}
else
{
Token* finalParent = localParent ? localParent : m_pLastParent;
newToken = new Token(newname,m_File,line);
newToken->m_ParentIndex = finalParent ? finalParent->GetSelf() : -1;
newToken->m_TokenKind = kind;
newToken->m_Scope = m_LastScope;
newToken->m_Args = args;
int newidx = m_pTokens->insert(newToken);
if (finalParent)
finalParent->AddChild(newidx);
}
if (!(kind & (tkConstructor | tkDestructor)))
{
wxString readType = m_Str;
wxString actualType = GetActualTokenType();
if (actualType.Find(_T(' ')) == wxNOT_FOUND)
{
// token type must contain all namespaces
actualType.Prepend(GetQueueAsNamespaceString(m_EncounteredTypeNamespaces));
}
newToken->m_Type = readType;
newToken->m_ActualType = actualType;
}
newToken->m_IsLocal = m_IsLocal;
newToken->m_IsTemp = m_Options.isTemp;
newToken->m_IsOperator = isOperator;
if (!isImpl)
{
newToken->m_File = m_File;
newToken->m_Line = line;
// Manager::Get()->GetLogManager()->DebugLog(F(_T("Added/updated token '%s' (%d), type '%s', actual '%s'. Parent is %s (%d)"), name.c_str(), newToken->GetSelf(), newToken->m_Type.c_str(), newToken->m_ActualType.c_str(), newToken->GetParentName().c_str(), newToken->m_ParentIndex));
}
else
{
newToken->m_ImplFile = m_File;
newToken->m_ImplLine = line;
newToken->m_ImplLineStart = implLineStart;
newToken->m_ImplLineEnd = implLineEnd;
m_pTokens->m_FilesMap[newToken->m_ImplFile].insert(newToken->GetSelf());
}
while (!m_EncounteredNamespaces.empty())
m_EncounteredNamespaces.pop();
while (!m_EncounteredTypeNamespaces.empty())
m_EncounteredTypeNamespaces.pop();
s_MutexProtection.Leave();
// wxMilliSleep(0);
return newToken;
}
Parsing stage done (22382 total parsed files, 914536 tokens in 2 minute(s), 21.896 seconds).
Parsing stage done (22382 total parsed files, 914536 tokens in 2 minute(s), 22.432 seconds).
int TokensTree::AddToken(Token* newToken,int forceidx)
{
...
size_t idx2 = m_Tree.AddItem(name,tmp_tokens,false);// this will add a now item to "TokenSearchTree"
...
}
Ok, I find some code that can confirm it is quite "SAFE", When adding a Token, it use a s_MutexProtection. In the parsing thread.That's an example of what happens if you fix things that you've not understood, and it's one of the reasons I'm not touching anything related to CC again :)
#include <cstdio>
static int xxx;
void foo();
void p1();
#include "foo.h"
void foo() { xxx = 5; }
void p1() { printf("%d\n", xxx); }
#include "foo.h"
void p2() { printf("%d\n", xxx); }
int main()
{
xxx = 1;
foo();
p1();
p2();
return 0;
}
Now, in your head, replace "int" with "wxCriticalSection" and "foo.h" with "token.h". Surprise.@thomas
On top of that the (misnomed) mutex has at least 4 global definitions in different compilation units, which somewhat defeats its purpose as a lock
I guess the reason of using this kind of mux is that they only want to lock the operation in it's own compilation units :D Not operation between different units.To be honest, I don't think this was intentional at all, it just incidentially happens to work without crashing :)
Parsing stage done (1211 total parsed files, 60710 tokens in 0 minute(s), 25.172 seconds).
Parsing stage done (1211 total parsed files, 60710 tokens in 0 minute(s), 25.250 seconds).
class SearchTreeNode:public BlockAllocated<SearchTreeNode, 10000>
{
......
protected:
unsigned int m_depth;
nSearchTreeNode m_parent;
nSearchTreeLabel m_label;
unsigned int m_labelstart, m_labellen;
SearchTreeLinkMap m_Children;
SearchTreeItemsMap m_Items;
};
And here is the definition:
/** SearchTreeLinkMap is the list of the edges towards other nodes. The character is the
key, and the node is the value */
typedef map<wxChar,nSearchTreeNode,less<wxChar> > SearchTreeLinkMap;
/** SearchTreeItemsMap contains all the items belonging to an edge */
typedef map<size_t,size_t,less<size_t> > SearchTreeItemsMap;
These codes were horrible :shock:.I guess the reason of using this kind of mux is that they only want to lock the operation in it's own compilation units :D Not operation between different units.To be honest, I don't think this was intentional at all, it just incidentially happens to work without crashing :)
#include <ext/pool_allocator.h>
......
typedef map<wxChar,nSearchTreeNode,less<wxChar>,__gnu_cxx::__pool_alloc<std::pair<const wxChar,nSearchTreeNode> > > SearchTreeLinkMap;
typedef map<size_t,size_t,less<size_t>, __gnu_cxx::__pool_alloc<std::pair<const size_t,size_t> > > SearchTreeItemsMap;
ollydbg: Do you know the first rule of optimizing code? It is: profile the code, so you know the exact place where the slowness comes from!
Though profiling C::B with gprof is impossible or quite hard for a normal human being (extraterrestrials are welcome to do so :) ).
You could manually profile it with wxStopWatch or some other form for doing it manually.
I don't get the last line. You are talking about parsing the whatis gdb command?Yes, exactly.