[Lldb-commits] [lldb] r116049 - in /lldb/trunk: include/lldb/Symbol/Symtab.h include/lldb/lldb-enumerations.h source/Commands/CommandObjectImage.cpp source/Commands/CommandObjectThread.cpp source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp source/Symbol/Symtab.cpp

Greg Clayton gclayton at apple.com
Thu Oct 7 21:20:14 PDT 2010


Author: gclayton
Date: Thu Oct  7 23:20:14 2010
New Revision: 116049

URL: http://llvm.org/viewvc/llvm-project?rev=116049&view=rev
Log:
Added mutex protection to the Symtab class.

Added a new SortOrder enumeration and hooked it up to the "image dump symtab"
command so we can dump symbol tables in the original order, sorted by address, 
or sorted by name.


Modified:
    lldb/trunk/include/lldb/Symbol/Symtab.h
    lldb/trunk/include/lldb/lldb-enumerations.h
    lldb/trunk/source/Commands/CommandObjectImage.cpp
    lldb/trunk/source/Commands/CommandObjectThread.cpp
    lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
    lldb/trunk/source/Symbol/Symtab.cpp

Modified: lldb/trunk/include/lldb/Symbol/Symtab.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Symtab.h?rev=116049&r1=116048&r2=116049&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/Symtab.h (original)
+++ lldb/trunk/include/lldb/Symbol/Symtab.h Thu Oct  7 23:20:14 2010
@@ -15,6 +15,7 @@
 
 #include "lldb/lldb-private.h"
 #include "lldb/Core/UniqueCStringMap.h"
+#include "lldb/Host/Mutex.h"
 #include "lldb/Symbol/Symbol.h"
 
 namespace lldb_private {
@@ -41,9 +42,13 @@
             Symbol *    Resize (uint32_t count);
             uint32_t    AddSymbol(const Symbol& symbol);
             size_t      GetNumSymbols() const;
-            void        Dump(Stream *s, Target *target) const;
+            void        Dump(Stream *s, Target *target, lldb::SortOrder sort_type);
             void        Dump(Stream *s, Target *target, std::vector<uint32_t>& indexes) const;
             uint32_t    GetIndexForSymbol (const Symbol *symbol) const;
+            Mutex &     GetMutex ()
+                        {
+                            return m_mutex;
+                        }
             Symbol *    FindSymbolByID (lldb::user_id_t uid) const;
             Symbol *    SymbolAtIndex (uint32_t idx);
     const   Symbol *    SymbolAtIndex (uint32_t idx) const;
@@ -84,7 +89,9 @@
     collection          m_symbols;
     std::vector<uint32_t> m_addr_indexes;
     UniqueCStringMap<uint32_t> m_name_to_index;
-
+    mutable Mutex       m_mutex; // Provide thread safety for this symbol table
+    bool                m_addr_indexes_computed:1,
+                        m_name_indexes_computed:1;
 private:
 
     bool

Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=116049&r1=116048&r2=116049&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Thu Oct  7 23:20:14 2010
@@ -558,6 +558,7 @@
     eArgTypeSettingVariableName,
     eArgTypeShlibName,
     eArgTypeSourceFile,
+    eArgTypeSortOrder,
     eArgTypeStartAddress,
     eArgTypeSymbol,
     eArgTypeThreadID,
@@ -573,19 +574,25 @@
 
 typedef enum ArgumentRepetitionType
 {
-    eArgRepeatPlain,     // Exactly one occurrence
-    eArgRepeatOptional,  // At most one occurrence, but it's optional
-    eArgRepeatPlus,      // One or more occurrences
-    eArgRepeatStar,      // Zero or more occurrences
-    eArgRepeatRange,      // Repetition of same argument, from 1 to n
-    eArgRepeatPairPlain, // A pair of arguments that must always go together ([arg-type arg-value]), occurs exactly once
-    eArgRepeatPairOptional, // A pair that occurs at most once (optional)
-    eArgRepeatPairPlus,  // One or more occurrences of a pair
-    eArgRepeatPairStar,  // Zero or more occurrences of a pair
-    eArgRepeatPairRange,  // A pair that repeats from 1 to n
-    eArgRepeatPairRangeOptional,  // A pair that repeats from 1 to n, but is optional
+    eArgRepeatPlain,            // Exactly one occurrence
+    eArgRepeatOptional,         // At most one occurrence, but it's optional
+    eArgRepeatPlus,             // One or more occurrences
+    eArgRepeatStar,             // Zero or more occurrences
+    eArgRepeatRange,            // Repetition of same argument, from 1 to n
+    eArgRepeatPairPlain,        // A pair of arguments that must always go together ([arg-type arg-value]), occurs exactly once
+    eArgRepeatPairOptional,     // A pair that occurs at most once (optional)
+    eArgRepeatPairPlus,         // One or more occurrences of a pair
+    eArgRepeatPairStar,         // Zero or more occurrences of a pair
+    eArgRepeatPairRange,        // A pair that repeats from 1 to n
+    eArgRepeatPairRangeOptional // A pair that repeats from 1 to n, but is optional
 } ArgumentRepetitionType;
 
+typedef enum SortOrder
+{
+    eSortOrderNone,
+    eSortOrderByAddress,
+    eSortOrderByName,
+} SortOrder;
 
 } // namespace lldb
 

Modified: lldb/trunk/source/Commands/CommandObjectImage.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectImage.cpp?rev=116049&r1=116048&r2=116049&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectImage.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectImage.cpp Thu Oct  7 23:20:14 2010
@@ -156,7 +156,7 @@
 
 
 static void
-DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module)
+DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, lldb::SortOrder sort_order)
 {
     if (module)
     {
@@ -165,7 +165,7 @@
         {
             Symtab *symtab = objfile->GetSymtab();
             if (symtab)
-                symtab->Dump(&strm, interpreter.GetDebugger().GetExecutionContext().target);
+                symtab->Dump(&strm, interpreter.GetDebugger().GetExecutionContext().target, sort_order);
         }
     }
 }
@@ -634,8 +634,13 @@
                     result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
                     for (uint32_t image_idx = 0;  image_idx<num_modules; ++image_idx)
                     {
+                        if (num_dumped > 0)
+                        {
+                            result.GetOutputStream().EOL();
+                            result.GetOutputStream().EOL();
+                        }
                         num_dumped++;
-                        DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
+                        DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx), m_options.m_sort_order);
                     }
                 }
                 else
@@ -672,8 +677,13 @@
                             Module *image_module = matching_modules.GetModulePointerAtIndex(i);
                             if (image_module)
                             {
+                                if (num_dumped > 0)
+                                {
+                                    result.GetOutputStream().EOL();
+                                    result.GetOutputStream().EOL();
+                                }
                                 num_dumped++;
-                                DumpModuleSymtab (m_interpreter, result.GetOutputStream(), image_module);
+                                DumpModuleSymtab (m_interpreter, result.GetOutputStream(), image_module, m_options.m_sort_order);
                             }
                         }
                     }
@@ -692,9 +702,100 @@
         }
         return result.Succeeded();
     }
+    
+    virtual Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+    
+    class CommandOptions : public Options
+    {
+    public:
+
+        CommandOptions () :
+            Options(),
+            m_sort_order (eSortOrderNone)
+        {
+        }
+
+        virtual
+        ~CommandOptions ()
+        {
+        }
+
+        virtual Error
+        SetOptionValue (int option_idx, const char *option_arg)
+        {
+            Error error;
+            char short_option = (char) m_getopt_table[option_idx].val;
+
+            switch (short_option)
+            {
+            case 's':
+                {
+                    bool found_one = false;
+                    m_sort_order = (lldb::SortOrder) Args::StringToOptionEnum (option_arg, 
+                                                                               g_option_table[option_idx].enum_values, 
+                                                                               eSortOrderNone,
+                                                                               &found_one);
+                    if (!found_one)
+                        error.SetErrorStringWithFormat("Invalid enumeration value '%s' for option '%c'.\n", 
+                                                       option_arg, 
+                                                       short_option);
+                }
+                break;
 
+            default:
+                error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
+                break;
+
+            }
+            return error;
+        }
+
+        void
+        ResetOptionValues ()
+        {
+            Options::ResetOptionValues();
+            m_sort_order = eSortOrderNone;
+        }
+
+        const lldb::OptionDefinition*
+        GetDefinitions ()
+        {
+            return g_option_table;
+        }
+
+        // Options table: Required for subclasses of Options.
+        static lldb::OptionDefinition g_option_table[];
+
+        SortOrder m_sort_order;
+    };
+
+protected:
+
+    CommandOptions m_options;
+};
+
+lldb::OptionEnumValueElement
+g_sort_option_enumeration[4] =
+{
+    { eSortOrderNone,       "none",     "No sorting, use the original symbol table order."},
+    { eSortOrderByAddress,  "address",  "Sort output by symbol address."},
+    { eSortOrderByName,     "name",     "Sort output by symbol name."},
+    { 0,                    NULL,       NULL }
 };
 
+
+lldb::OptionDefinition
+CommandObjectImageDumpSymtab::CommandOptions::g_option_table[] =
+{
+{ LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."},
+{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
+};
+
+
 //----------------------------------------------------------------------
 // Image section dumping command
 //----------------------------------------------------------------------
@@ -1380,8 +1481,7 @@
     {
     }
 
-    virtual
-    Options *
+    virtual Options *
     GetOptions ()
     {
         return &m_options;

Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=116049&r1=116048&r2=116049&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectThread.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectThread.cpp Thu Oct  7 23:20:14 2010
@@ -506,7 +506,7 @@
 
             switch (short_option)
             {
-                case 'a':
+            case 'a':
                 {
                     bool success;
                     m_avoid_no_debug =  Args::StringToBoolean (option_arg, true, &success);
@@ -514,7 +514,8 @@
                         error.SetErrorStringWithFormat("Invalid boolean value for option '%c'.\n", short_option);
                 }
                 break;
-                case 'm':
+            
+            case 'm':
                 {
                     bool found_one = false;
                     OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values; 
@@ -523,15 +524,17 @@
                         error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option);
                 }
                 break;
-                case 'r':
+            
+            case 'r':
                 {
                     m_avoid_regexp.clear();
                     m_avoid_regexp.assign(option_arg);
                 }
                 break;
-                default:
-                    error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
-                    break;
+
+            default:
+                error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
+                break;
 
             }
             return error;

Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=116049&r1=116048&r2=116049&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Thu Oct  7 23:20:14 2010
@@ -647,6 +647,8 @@
     Symtab *symbol_table = new Symtab(this);
     m_symtab_ap.reset(symbol_table);
 
+    Mutex::Locker locker (symbol_table->GetMutex ());
+    
     if (!(ParseSectionHeaders() && GetSectionHeaderStringTable()))
         return symbol_table;
 
@@ -658,7 +660,7 @@
         {
             const ELFSectionHeader &symtab_section = *I;
             user_id_t section_id = SectionIndex(I);
-            ParseSymbolTable(symbol_table, symtab_section, section_id);
+            ParseSymbolTable (symbol_table, symtab_section, section_id);
         }
     }
 
@@ -685,7 +687,7 @@
         section_list->Dump(s, NULL, true);
     Symtab *symtab = GetSymtab();
     if (symtab)
-        symtab->Dump(s, NULL);
+        symtab->Dump(s, NULL, lldb::eSortOrderNone);
     s->EOL();
     DumpDependentModules(s);
     s->EOL();

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=116049&r1=116048&r2=116049&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Thu Oct  7 23:20:14 2010
@@ -206,6 +206,7 @@
     if (m_symtab_ap.get() == NULL)
     {
         m_symtab_ap.reset(new Symtab(this));
+        Mutex::Locker locker (m_symtab_ap->GetMutex());
         ParseSymtab (true);
     }
     return m_symtab_ap.get();
@@ -1348,7 +1349,7 @@
         m_sections_ap->Dump(s, NULL, true);
 
     if (m_symtab_ap.get())
-        m_symtab_ap->Dump(s, NULL);
+        m_symtab_ap->Dump(s, NULL, eSortOrderNone);
 }
 
 

Modified: lldb/trunk/source/Symbol/Symtab.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Symtab.cpp?rev=116049&r1=116048&r2=116049&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Symtab.cpp (original)
+++ lldb/trunk/source/Symbol/Symtab.cpp Thu Oct  7 23:20:14 2010
@@ -21,10 +21,13 @@
 
 
 Symtab::Symtab(ObjectFile *objfile) :
-    m_objfile(objfile),
-    m_symbols(),
-    m_addr_indexes(),
-    m_name_to_index()
+    m_objfile (objfile),
+    m_symbols (),
+    m_addr_indexes (),
+    m_name_to_index (),
+    m_mutex (Mutex::eMutexTypeRecursive),
+    m_addr_indexes_computed (false),
+    m_name_indexes_computed (false)
 {
 }
 
@@ -35,12 +38,16 @@
 void
 Symtab::Reserve(uint32_t count)
 {
+    // Clients should grab the mutex from this symbol table and lock it manually
+    // when calling this function to avoid performance issues.
     m_symbols.reserve (count);
 }
 
 Symbol *
 Symtab::Resize(uint32_t count)
 {
+    // Clients should grab the mutex from this symbol table and lock it manually
+    // when calling this function to avoid performance issues.
     m_symbols.resize (count);
     return &m_symbols[0];
 }
@@ -48,23 +55,29 @@
 uint32_t
 Symtab::AddSymbol(const Symbol& symbol)
 {
+    // Clients should grab the mutex from this symbol table and lock it manually
+    // when calling this function to avoid performance issues.
     uint32_t symbol_idx = m_symbols.size();
     m_name_to_index.Clear();
     m_addr_indexes.clear();
     m_symbols.push_back(symbol);
+    m_addr_indexes_computed = false;
+    m_name_indexes_computed = false;
     return symbol_idx;
 }
 
 size_t
 Symtab::GetNumSymbols() const
 {
+    Mutex::Locker locker (m_mutex);
     return m_symbols.size();
 }
 
 void
-Symtab::Dump(Stream *s, Target *target) const
+Symtab::Dump (Stream *s, Target *target, lldb::SortOrder sort_order)
 {
-    const_iterator pos;
+    Mutex::Locker locker (m_mutex);
+
 //    s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
     s->Indent();
     const FileSpec &file_spec = m_objfile->GetFileSpec();
@@ -73,7 +86,7 @@
         object_name = m_objfile->GetModule()->GetObjectName().GetCString();
 
     if (file_spec)
-        s->Printf("Symtab, file = %s/%s%s%s%s, num_symbols = %u:\n",
+        s->Printf("Symtab, file = %s/%s%s%s%s, num_symbols = %u",
         file_spec.GetDirectory().AsCString(),
         file_spec.GetFilename().AsCString(),
         object_name ? "(" : "",
@@ -81,28 +94,79 @@
         object_name ? ")" : "",
         m_symbols.size());
     else
-        s->Printf("Symtab, num_symbols = %u:\n", m_symbols.size());
-    s->IndentMore();
+        s->Printf("Symtab, num_symbols = %u", m_symbols.size());
 
     if (!m_symbols.empty())
     {
-        const_iterator begin = m_symbols.begin();
-        const_iterator end = m_symbols.end();
-        DumpSymbolHeader (s);
-        for (pos = m_symbols.begin(); pos != end; ++pos)
+        switch (sort_order)
         {
-            s->Indent();
-            pos->Dump(s, target, std::distance(begin, pos));
+        case eSortOrderNone:
+            {
+                s->PutCString (":\n");
+                DumpSymbolHeader (s);
+                const_iterator begin = m_symbols.begin();
+                const_iterator end = m_symbols.end();
+                for (const_iterator pos = m_symbols.begin(); pos != end; ++pos)
+                {
+                    s->Indent();
+                    pos->Dump(s, target, std::distance(begin, pos));
+                }
+            }
+            break;
+
+        case eSortOrderByName:
+            {
+                // Although we maintain a lookup by exact name map, the table
+                // isn't sorted by name. So we must make the ordered symbol list
+                // up ourselves.
+                s->PutCString (" (sorted by name):\n");
+                DumpSymbolHeader (s);
+                typedef std::multimap<const char*, const Symbol *, CStringCompareFunctionObject> CStringToSymbol;
+                CStringToSymbol name_map;
+                for (const_iterator pos = m_symbols.begin(), end = m_symbols.end(); pos != end; ++pos)
+                {
+                    const char *name = pos->GetMangled().GetName(Mangled::ePreferDemangled).AsCString();
+                    if (name && name[0])
+                        name_map.insert (std::make_pair(name, &(*pos)));
+                }
+                
+                for (CStringToSymbol::const_iterator pos = name_map.begin(), end = name_map.end(); pos != end; ++pos)
+                {
+                    s->Indent();
+                    pos->second->Dump (s, target, pos->second - &m_symbols[0]);
+                }
+            }
+            break;
+            
+        case eSortOrderByAddress:
+            s->PutCString (" (sorted by address):\n");
+            DumpSymbolHeader (s);
+            if (!m_addr_indexes_computed)
+                InitAddressIndexes();
+            const size_t num_symbols = GetNumSymbols();
+            std::vector<uint32_t>::const_iterator pos;
+            std::vector<uint32_t>::const_iterator end = m_addr_indexes.end();
+            for (pos = m_addr_indexes.begin(); pos != end; ++pos)
+            {
+                uint32_t idx = *pos;
+                if (idx < num_symbols)
+                {
+                    s->Indent();
+                    m_symbols[idx].Dump(s, target, idx);
+                }
+            }
+            break;
         }
     }
-    s->IndentLess ();
 }
 
 void
 Symtab::Dump(Stream *s, Target *target, std::vector<uint32_t>& indexes) const
 {
+    Mutex::Locker locker (m_mutex);
+
     const size_t num_symbols = GetNumSymbols();
-    s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
+    //s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
     s->Indent();
     s->Printf("Symtab %u symbol indexes (%u symbols total):\n", indexes.size(), m_symbols.size());
     s->IndentMore();
@@ -152,6 +216,8 @@
 Symbol *
 Symtab::FindSymbolByID (lldb::user_id_t symbol_uid) const
 {
+    Mutex::Locker locker (m_mutex);
+
     Symbol *symbol = (Symbol*)::bsearch (&symbol_uid, 
                                          &m_symbols[0], 
                                          m_symbols.size(), 
@@ -164,6 +230,8 @@
 Symbol *
 Symtab::SymbolAtIndex(uint32_t idx)
 {
+    // Clients should grab the mutex from this symbol table and lock it manually
+    // when calling this function to avoid performance issues.
     if (idx < m_symbols.size())
         return &m_symbols[idx];
     return NULL;
@@ -173,6 +241,8 @@
 const Symbol *
 Symtab::SymbolAtIndex(uint32_t idx) const
 {
+    // Clients should grab the mutex from this symbol table and lock it manually
+    // when calling this function to avoid performance issues.
     if (idx < m_symbols.size())
         return &m_symbols[idx];
     return NULL;
@@ -184,42 +254,70 @@
 void
 Symtab::InitNameIndexes()
 {
-    Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
-    // Create the name index vector to be able to quickly search by name
-    const size_t count = m_symbols.size();
-    assert(m_objfile != NULL);
-    assert(m_objfile->GetModule() != NULL);
-    m_name_to_index.Reserve (count);
-
-    UniqueCStringMap<uint32_t>::Entry entry;
-
-    for (entry.value = 0; entry.value < count; ++entry.value)
-    {
-        const Symbol *symbol = &m_symbols[entry.value];
-
-        // Don't let trampolines get into the lookup by name map
-        // If we ever need the trampoline symbols to be searchable by name
-        // we can remove this and then possibly add a new bool to any of the
-        // Symtab functions that lookup symbols by name to indicate if they
-        // want trampolines.
-        if (symbol->IsTrampoline())
-            continue;
-
-        const Mangled &mangled = symbol->GetMangled();
-        entry.cstring = mangled.GetMangledName().GetCString();
-        if (entry.cstring && entry.cstring[0])
-            m_name_to_index.Append (entry);
-
-        entry.cstring = mangled.GetDemangledName().GetCString();
-        if (entry.cstring && entry.cstring[0])
-            m_name_to_index.Append (entry);
+    // Protected function, no need to lock mutex...
+    if (!m_name_indexes_computed)
+    {
+        m_name_indexes_computed = true;
+        Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
+        // Create the name index vector to be able to quickly search by name
+        const size_t count = m_symbols.size();
+        assert(m_objfile != NULL);
+        assert(m_objfile->GetModule() != NULL);
+
+#if 1
+        m_name_to_index.Reserve (count);
+#else
+        // TODO: benchmark this to see if we save any memory. Otherwise we
+        // will always keep the memory reserved in the vector unless we pull
+        // some STL swap magic and then recopy...
+        uint32_t actual_count = 0;
+        for (const_iterator pos = m_symbols.begin(), end = m_symbols.end();
+             pos != end; 
+             ++pos)
+        {
+            const Mangled &mangled = pos->GetMangled();
+            if (mangled.GetMangledName())
+                ++actual_count;
+            
+            if (mangled.GetDemangledName())
+                ++actual_count;
+        }
+
+        m_name_to_index.Reserve (actual_count);
+#endif
+
+        UniqueCStringMap<uint32_t>::Entry entry;
+
+        for (entry.value = 0; entry.value < count; ++entry.value)
+        {
+            const Symbol *symbol = &m_symbols[entry.value];
+
+            // Don't let trampolines get into the lookup by name map
+            // If we ever need the trampoline symbols to be searchable by name
+            // we can remove this and then possibly add a new bool to any of the
+            // Symtab functions that lookup symbols by name to indicate if they
+            // want trampolines.
+            if (symbol->IsTrampoline())
+                continue;
+
+            const Mangled &mangled = symbol->GetMangled();
+            entry.cstring = mangled.GetMangledName().GetCString();
+            if (entry.cstring && entry.cstring[0])
+                m_name_to_index.Append (entry);
+
+            entry.cstring = mangled.GetDemangledName().GetCString();
+            if (entry.cstring && entry.cstring[0])
+                m_name_to_index.Append (entry);
+        }
+        m_name_to_index.Sort();
     }
-    m_name_to_index.Sort();
 }
 
 uint32_t
 Symtab::AppendSymbolIndexesWithType (SymbolType symbol_type, std::vector<uint32_t>& indexes, uint32_t start_idx, uint32_t end_index) const
 {
+    Mutex::Locker locker (m_mutex);
+
     uint32_t prev_size = indexes.size();
 
     const uint32_t count = std::min<uint32_t> (m_symbols.size(), end_index);
@@ -236,6 +334,8 @@
 uint32_t
 Symtab::AppendSymbolIndexesWithType (SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes, uint32_t start_idx, uint32_t end_index) const
 {
+    Mutex::Locker locker (m_mutex);
+
     uint32_t prev_size = indexes.size();
 
     const uint32_t count = std::min<uint32_t> (m_symbols.size(), end_index);
@@ -303,6 +403,8 @@
 void
 Symtab::SortSymbolIndexesByValue (std::vector<uint32_t>& indexes, bool remove_duplicates) const
 {
+    Mutex::Locker locker (m_mutex);
+
     Timer scoped_timer (__PRETTY_FUNCTION__,__PRETTY_FUNCTION__);
     // No need to sort if we have zero or one items...
     if (indexes.size() <= 1)
@@ -322,15 +424,18 @@
 uint32_t
 Symtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, std::vector<uint32_t>& indexes)
 {
+    Mutex::Locker locker (m_mutex);
+
     Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
     if (symbol_name)
     {
         const size_t old_size = indexes.size();
-        if (m_name_to_index.IsEmpty())
+        if (!m_name_indexes_computed)
             InitNameIndexes();
 
         const char *symbol_cstr = symbol_name.GetCString();
         const UniqueCStringMap<uint32_t>::Entry *entry_ptr;
+
         for (entry_ptr = m_name_to_index.FindFirstValueForName (symbol_cstr);
              entry_ptr!= NULL;
              entry_ptr = m_name_to_index.FindNextValueForName (symbol_cstr, entry_ptr))
@@ -345,11 +450,13 @@
 uint32_t
 Symtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes)
 {
+    Mutex::Locker locker (m_mutex);
+
     Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
     if (symbol_name)
     {
         const size_t old_size = indexes.size();
-        if (m_name_to_index.IsEmpty())
+        if (!m_name_indexes_computed)
             InitNameIndexes();
 
         const char *symbol_cstr = symbol_name.GetCString();
@@ -369,6 +476,8 @@
 uint32_t
 Symtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, SymbolType symbol_type, std::vector<uint32_t>& indexes)
 {
+    Mutex::Locker locker (m_mutex);
+
     if (AppendSymbolIndexesWithName(symbol_name, indexes) > 0)
     {
         std::vector<uint32_t>::iterator pos = indexes.begin();
@@ -386,6 +495,8 @@
 uint32_t
 Symtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes)
 {
+    Mutex::Locker locker (m_mutex);
+
     if (AppendSymbolIndexesWithName(symbol_name, symbol_debug_type, symbol_visibility, indexes) > 0)
     {
         std::vector<uint32_t>::iterator pos = indexes.begin();
@@ -404,6 +515,8 @@
 uint32_t
 Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression &regexp, SymbolType symbol_type, std::vector<uint32_t>& indexes)
 {
+    Mutex::Locker locker (m_mutex);
+
     uint32_t prev_size = indexes.size();
     uint32_t sym_end = m_symbols.size();
 
@@ -426,6 +539,8 @@
 uint32_t
 Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression &regexp, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes)
 {
+    Mutex::Locker locker (m_mutex);
+
     uint32_t prev_size = indexes.size();
     uint32_t sym_end = m_symbols.size();
 
@@ -451,6 +566,8 @@
 Symbol *
 Symtab::FindSymbolWithType (SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t& start_idx)
 {
+    Mutex::Locker locker (m_mutex);
+
     const size_t count = m_symbols.size();
     for (uint32_t idx = start_idx; idx < count; ++idx)
     {
@@ -469,10 +586,12 @@
 size_t
 Symtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, std::vector<uint32_t>& symbol_indexes)
 {
+    Mutex::Locker locker (m_mutex);
+
     Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
     // Initialize all of the lookup by name indexes before converting NAME
     // to a uniqued string NAME_STR below.
-    if (m_name_to_index.IsEmpty())
+    if (!m_name_indexes_computed)
         InitNameIndexes();
 
     if (name)
@@ -487,10 +606,12 @@
 size_t
 Symtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes)
 {
+    Mutex::Locker locker (m_mutex);
+
     Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
     // Initialize all of the lookup by name indexes before converting NAME
     // to a uniqued string NAME_STR below.
-    if (m_name_to_index.IsEmpty())
+    if (!m_name_indexes_computed)
         InitNameIndexes();
 
     if (name)
@@ -505,6 +626,8 @@
 size_t
 Symtab::FindAllSymbolsMatchingRexExAndType (const RegularExpression &regex, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes)
 {
+    Mutex::Locker locker (m_mutex);
+
     AppendSymbolIndexesMatchingRegExAndType(regex, symbol_type, symbol_debug_type, symbol_visibility, symbol_indexes);
     return symbol_indexes.size();
 }
@@ -512,8 +635,10 @@
 Symbol *
 Symtab::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility)
 {
+    Mutex::Locker locker (m_mutex);
+
     Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__);
-    if (m_name_to_index.IsEmpty())
+    if (!m_name_indexes_computed)
         InitNameIndexes();
 
     if (name)
@@ -614,19 +739,36 @@
 void
 Symtab::InitAddressIndexes()
 {
-    if (m_addr_indexes.empty())
+    // Protected function, no need to lock mutex...
+    if (!m_addr_indexes_computed && !m_symbols.empty())
     {
+        m_addr_indexes_computed = true;
+#if 0
+        // The old was to add only code, trampoline or data symbols...
         AppendSymbolIndexesWithType (eSymbolTypeCode, m_addr_indexes);
         AppendSymbolIndexesWithType (eSymbolTypeTrampoline, m_addr_indexes);
         AppendSymbolIndexesWithType (eSymbolTypeData, m_addr_indexes);
-        SortSymbolIndexesByValue(m_addr_indexes, true);
-        m_addr_indexes.push_back(UINT32_MAX);   // Terminator for bsearch since we might need to look at the next symbol
+#else
+        // The new way adds all symbols with valid addresses that are section
+        // offset.
+        const_iterator begin = m_symbols.begin();
+        const_iterator end = m_symbols.end();
+        for (const_iterator pos = m_symbols.begin(); pos != end; ++pos)
+        {
+            if (pos->GetAddressRangePtr())
+                m_addr_indexes.push_back (std::distance(begin, pos));
+        }
+#endif
+        SortSymbolIndexesByValue (m_addr_indexes, false);
+        m_addr_indexes.push_back (UINT32_MAX);   // Terminator for bsearch since we might need to look at the next symbol
     }
 }
 
 size_t
 Symtab::CalculateSymbolSize (Symbol *symbol)
 {
+    Mutex::Locker locker (m_mutex);
+
     if (m_symbols.empty())
         return 0;
 
@@ -647,7 +789,7 @@
     // it and the next address based symbol
     if (symbol->GetAddressRangePtr())
     {
-        if (m_addr_indexes.empty())
+        if (!m_addr_indexes_computed)
             InitAddressIndexes();
         const size_t num_addr_indexes = m_addr_indexes.size();
         SymbolSearchInfo info = FindIndexPtrForSymbolContainingAddress(this, symbol->GetAddressRangePtr()->GetBaseAddress().GetFileAddress(), &m_addr_indexes.front(), num_addr_indexes);
@@ -684,7 +826,9 @@
 Symbol *
 Symtab::FindSymbolWithFileAddress (addr_t file_addr)
 {
-    if (m_addr_indexes.empty())
+    Mutex::Locker locker (m_mutex);
+
+    if (!m_addr_indexes_computed)
         InitAddressIndexes();
 
     SymbolSearchInfo info = { this, file_addr, NULL, NULL, 0 };
@@ -699,6 +843,8 @@
 Symbol *
 Symtab::FindSymbolContainingFileAddress (addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes)
 {
+    Mutex::Locker locker (m_mutex);
+
     SymbolSearchInfo info = { this, file_addr, NULL, NULL, 0 };
 
     bsearch(&info, indexes, num_indexes, sizeof(uint32_t), (comparison_function)SymbolWithClosestFileAddress);
@@ -731,7 +877,9 @@
 Symbol *
 Symtab::FindSymbolContainingFileAddress (addr_t file_addr)
 {
-    if (m_addr_indexes.empty())
+    Mutex::Locker locker (m_mutex);
+
+    if (!m_addr_indexes_computed)
         InitAddressIndexes();
 
     return FindSymbolContainingFileAddress (file_addr, &m_addr_indexes[0], m_addr_indexes.size());





More information about the lldb-commits mailing list