[Lldb-commits] [lldb] r166693 - in /lldb/trunk: include/lldb/Target/ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/ source/Plugins/ObjectFile/PECOFF/ source/Plugins/OperatingSystem/Darwin-Kernel/ source/Target/

Greg Clayton gclayton at apple.com
Thu Oct 25 09:54:22 PDT 2012


Author: gclayton
Date: Thu Oct 25 11:54:22 2012
New Revision: 166693

URL: http://llvm.org/viewvc/llvm-project?rev=166693&view=rev
Log:
Changed the V1 and V2 runtimes to be able to detect when the ISA hash table has changed, and auto update as needed.


Modified:
    lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
    lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
    lldb/trunk/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp
    lldb/trunk/source/Target/ObjCLanguageRuntime.cpp

Modified: lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h?rev=166693&r1=166692&r2=166693&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h (original)
+++ lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h Thu Oct 25 11:54:22 2012
@@ -251,16 +251,17 @@
         return m_isa_to_descriptor_cache.count(isa) > 0;
     }
 
-    virtual bool
-    UpdateISAToDescriptorMap_Impl() = 0;
-    
+    virtual void
+    UpdateISAToDescriptorMapIfNeeded() = 0;
+
     void
     UpdateISAToDescriptorMap()
     {
-        if (m_isa_to_descriptor_cache_is_up_to_date)
-            return;
-        
-        m_isa_to_descriptor_cache_is_up_to_date = UpdateISAToDescriptorMap_Impl();
+        if (m_process && m_process->GetStopID() != m_isa_to_descriptor_cache_stop_id)
+        {
+            UpdateISAToDescriptorMapIfNeeded ();
+            assert (m_process->GetStopID() == m_isa_to_descriptor_cache_stop_id); // REMOVE THIS PRIOR TO CHECKIN
+        }
     }
     
     virtual ObjCISA
@@ -450,9 +451,8 @@
 protected:
     typedef std::map<ObjCISA, ClassDescriptorSP> ISAToDescriptorMap;
     typedef ISAToDescriptorMap::iterator ISAToDescriptorIterator;
-    ISAToDescriptorMap                  m_isa_to_descriptor_cache;
-    bool                                m_isa_to_descriptor_cache_is_up_to_date;
-    
+    ISAToDescriptorMap m_isa_to_descriptor_cache;
+    uint32_t m_isa_to_descriptor_cache_stop_id;
     typedef std::map<ConstString, lldb::TypeWP> CompleteClassMap;
     CompleteClassMap m_complete_class_cache;
 

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp?rev=166693&r1=166692&r2=166693&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp Thu Oct 25 11:54:22 2012
@@ -40,8 +40,16 @@
 static const char *pluginDesc = "Apple Objective C Language Runtime - Version 1";
 static const char *pluginShort = "language.apple.objc.v1";
 
+
+AppleObjCRuntimeV1::AppleObjCRuntimeV1(Process *process) :
+    AppleObjCRuntime (process),
+    m_hash_signature (),
+    m_isa_hash_table_ptr (LLDB_INVALID_ADDRESS)
+{
+}
+
 bool
-AppleObjCRuntimeV1::GetDynamicTypeAndAddress (ValueObject &in_value, 
+AppleObjCRuntimeV1::GetDynamicTypeAndAddress (ValueObject &in_value,
                                              lldb::DynamicValueType use_dynamic, 
                                              TypeAndOrName &class_type_or_name, 
                                              Address &address)
@@ -70,6 +78,7 @@
         return NULL;
 }
 
+
 void
 AppleObjCRuntimeV1::Initialize()
 {
@@ -188,11 +197,8 @@
 
 AppleObjCRuntimeV1::ClassDescriptorV1::ClassDescriptorV1 (ValueObject &isa_pointer)
 {
-    ObjCISA ptr_value = isa_pointer.GetValueAsUnsigned(0);
-
-    lldb::ProcessSP process_sp = isa_pointer.GetProcessSP();
-
-    Initialize (ptr_value,process_sp);
+    Initialize (isa_pointer.GetValueAsUnsigned(0),
+                isa_pointer.GetProcessSP());
 }
 
 AppleObjCRuntimeV1::ClassDescriptorV1::ClassDescriptorV1 (ObjCISA isa, lldb::ProcessSP process_sp)
@@ -288,62 +294,99 @@
     return ObjCLanguageRuntime::ClassDescriptorSP(new AppleObjCRuntimeV1::ClassDescriptorV1(m_parent_isa,process_sp));
 }
 
-bool
-AppleObjCRuntimeV1::UpdateISAToDescriptorMap_Impl()
+lldb::addr_t
+AppleObjCRuntimeV1::GetISAHashTablePointer ()
 {
-    lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-    
-    Process *process_ptr = GetProcess();
-    
-    if (!process_ptr)
-        return false;
-    
-    ProcessSP process_sp = process_ptr->shared_from_this();
-    
-    ModuleSP objc_module_sp(GetObjCModule());
-    
-    if (!objc_module_sp)
-        return false;
-    
-    uint32_t isa_count = 0;
-    
-    static ConstString g_objc_debug_class_hash("_objc_debug_class_hash");
+    if (m_isa_hash_table_ptr == LLDB_INVALID_ADDRESS)
+    {
+        ModuleSP objc_module_sp(GetObjCModule());
+        
+        if (!objc_module_sp)
+            return LLDB_INVALID_ADDRESS;
+        
+        static ConstString g_objc_debug_class_hash("_objc_debug_class_hash");
+        
+        const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(g_objc_debug_class_hash, lldb::eSymbolTypeData);
+        if (symbol)
+        {
+            Process *process = GetProcess();
+            if (process)
+            {
+
+                lldb::addr_t objc_debug_class_hash_addr = symbol->GetAddress().GetLoadAddress(&process->GetTarget());
+            
+                if (objc_debug_class_hash_addr != LLDB_INVALID_ADDRESS)
+                {
+                    Error error;
+                    lldb::addr_t objc_debug_class_hash_ptr = process->ReadPointerFromMemory(objc_debug_class_hash_addr, error);
+                    if (objc_debug_class_hash_ptr != 0 &&
+                        objc_debug_class_hash_ptr != LLDB_INVALID_ADDRESS)
+                    {
+                        m_isa_hash_table_ptr = objc_debug_class_hash_ptr;
+                    }
+                }
+            }
+        }
+    }
+    return m_isa_hash_table_ptr;
+}
+
+void
+AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded()
+{
+    // TODO: implement HashTableSignature...
+    Process *process = GetProcess();
     
-    const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(g_objc_debug_class_hash, lldb::eSymbolTypeData);
-    if (symbol)
+    if (process)
     {
-        lldb::addr_t objc_debug_class_hash_addr = symbol->GetAddress().GetLoadAddress(&process_sp->GetTarget());
+        // Update the process stop ID that indicates the last time we updated the
+        // map, wether it was successful or not.
+        m_isa_to_descriptor_cache_stop_id = process->GetStopID();
+        
+
+        lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+        
+        ProcessSP process_sp = process->shared_from_this();
         
-        if (objc_debug_class_hash_addr != LLDB_INVALID_ADDRESS)
+        ModuleSP objc_module_sp(GetObjCModule());
+        
+        if (!objc_module_sp)
+            return;
+        
+        uint32_t isa_count = 0;
+        
+        lldb::addr_t hash_table_ptr = GetISAHashTablePointer ();
+        if (hash_table_ptr != LLDB_INVALID_ADDRESS)
         {
+            // Read the NXHashTable struct:
+            //
+            // typedef struct {
+            //     const NXHashTablePrototype *prototype;
+            //     unsigned   count;
+            //     unsigned   nbBuckets;
+            //     void       *buckets;
+            //     const void *info;
+            // } NXHashTable;
+
             Error error;
-            lldb::addr_t objc_debug_class_hash_ptr = process_sp->ReadPointerFromMemory(objc_debug_class_hash_addr, error);
-            if (error.Success() && objc_debug_class_hash_ptr != 0 && objc_debug_class_hash_ptr != LLDB_INVALID_ADDRESS)
+            DataBufferHeap buffer(1024, 0);
+            if (process->ReadMemory(hash_table_ptr, buffer.GetBytes(), 20, error) == 20)
             {
-                // Read the NXHashTable struct:
-                //
-                // typedef struct {
-                //     const NXHashTablePrototype *prototype;
-                //     unsigned   count;
-                //     unsigned   nbBuckets;
-                //     void       *buckets;
-                //     const void *info;
-                // } NXHashTable;
-
-                DataBufferHeap buffer(1024, 0);
-                if (process_sp->ReadMemory(objc_debug_class_hash_ptr, buffer.GetBytes(), 20, error) == 20)
+                const uint32_t addr_size = m_process->GetAddressByteSize();
+                const ByteOrder byte_order = m_process->GetByteOrder();
+                DataExtractor data (buffer.GetBytes(), buffer.GetByteSize(), byte_order, addr_size);
+                uint32_t offset = addr_size; // Skip prototype
+                const uint32_t count = data.GetU32(&offset);
+                const uint32_t num_buckets = data.GetU32(&offset);
+                const addr_t buckets_ptr = data.GetPointer(&offset);
+                if (m_hash_signature.NeedsUpdate (count, num_buckets, buckets_ptr))
                 {
-                    const uint32_t addr_size = m_process->GetAddressByteSize();
-                    const ByteOrder byte_order = m_process->GetByteOrder();
-                    DataExtractor data (buffer.GetBytes(), buffer.GetByteSize(), byte_order, addr_size);
-                    uint32_t offset = addr_size + 4; // Skip prototype
-                    const uint32_t num_buckets = data.GetU32(&offset);
-                    const addr_t buckets_ptr = data.GetPointer(&offset);
-                
+                    m_hash_signature.UpdateSignature (count, num_buckets, buckets_ptr);
+
                     const uint32_t data_size = num_buckets * 2 * sizeof(uint32_t);
                     buffer.SetByteSize(data_size);
                     
-                    if (process_sp->ReadMemory(buckets_ptr, buffer.GetBytes(), data_size, error) == data_size)
+                    if (process->ReadMemory(buckets_ptr, buffer.GetBytes(), data_size, error) == data_size)
                     {
                         data.SetData(buffer.GetBytes(), buffer.GetByteSize(), byte_order);
                         offset = 0;
@@ -403,9 +446,11 @@
                     }
                 }
             }
-        }
+        }        
+    }
+    else
+    {
+        m_isa_to_descriptor_cache_stop_id = UINT32_MAX;
     }
-
-    return isa_count > 0;
 }
 

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h?rev=166693&r1=166692&r2=166693&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h Thu Oct 25 11:54:22 2012
@@ -123,17 +123,58 @@
         return eAppleObjC_V1;
     }
     
-    virtual bool
-    UpdateISAToDescriptorMap_Impl();
+    virtual void
+    UpdateISAToDescriptorMapIfNeeded();
 
 protected:
     virtual lldb::BreakpointResolverSP
     CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp);
-            
+    
+    
+    class HashTableSignature
+    {
+    public:
+        HashTableSignature () :
+            m_count (0),
+            m_num_buckets (0),
+            m_buckets_ptr (LLDB_INVALID_ADDRESS)
+        {
+        }
+        
+        bool
+        NeedsUpdate (uint32_t count,
+                     uint32_t num_buckets,
+                     lldb::addr_t buckets_ptr)
+        {
+            return m_count       != count       ||
+                   m_num_buckets != num_buckets ||
+                   m_buckets_ptr != buckets_ptr ;
+        }
+        
+        void
+        UpdateSignature (uint32_t count,
+                         uint32_t num_buckets,
+                         lldb::addr_t buckets_ptr)
+        {
+            m_count = count;
+            m_num_buckets = num_buckets;
+            m_buckets_ptr = buckets_ptr;
+        }
+
+    protected:
+        uint32_t m_count;
+        uint32_t m_num_buckets;
+        lldb::addr_t m_buckets_ptr;
+    };
+    
+
+    lldb::addr_t
+    GetISAHashTablePointer ();
+    
+    HashTableSignature m_hash_signature;
+    lldb::addr_t m_isa_hash_table_ptr;
 private:
-    AppleObjCRuntimeV1(Process *process) : 
-        lldb_private::AppleObjCRuntime (process)
-     { } // Call CreateInstance instead.
+    AppleObjCRuntimeV1(Process *process);
 };
     
 } // namespace lldb_private

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp?rev=166693&r1=166692&r2=166693&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Thu Oct 25 11:54:22 2012
@@ -106,9 +106,14 @@
 AppleObjCRuntimeV2::AppleObjCRuntimeV2 (Process *process, 
                                         const ModuleSP &objc_module_sp) : 
     AppleObjCRuntime (process),
-    m_get_class_name_args(LLDB_INVALID_ADDRESS),
-    m_get_class_name_args_mutex(Mutex::eMutexTypeNormal),
-    m_process_wp (process->shared_from_this())
+    m_get_class_name_function (),
+    m_get_class_name_code (),
+    m_get_class_name_args (LLDB_INVALID_ADDRESS),
+    m_get_class_name_args_mutex (Mutex::eMutexTypeNormal),
+    m_type_vendor_ap (),
+    m_isa_hash_table_ptr (LLDB_INVALID_ADDRESS),
+    m_hash_signature (),
+    m_has_object_getClass (false)
 {
     static const ConstString g_gdb_object_getClass("gdb_object_getClass");
     m_has_object_getClass = (objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_object_getClass, eSymbolTypeCode) != NULL);
@@ -470,32 +475,65 @@
 class RemoteNXMapTable
 {
 public:
-    RemoteNXMapTable (lldb::ProcessSP process_sp,
-                      lldb::addr_t load_addr) :
-        m_process_sp(process_sp),
-        m_end_iterator(*this, -1),
-        m_load_addr(load_addr),
-        m_map_pair_size(m_process_sp->GetAddressByteSize() * 2),
-        m_NXMAPNOTAKEY(m_process_sp->GetAddressByteSize() == 8 ? UINT64_MAX : UINT32_MAX)
+    
+    RemoteNXMapTable () :
+        m_count (0),
+        m_num_buckets_minus_one (0),
+        m_buckets_ptr (LLDB_INVALID_ADDRESS),
+        m_process (NULL),
+        m_end_iterator (*this, -1),
+        m_load_addr (LLDB_INVALID_ADDRESS),
+        m_map_pair_size (0),
+        m_invalid_key (0)
     {
-        lldb::addr_t cursor = load_addr;
-     
+    }
+    
+    bool
+    ParseHeader (Process* process, lldb::addr_t load_addr)
+    {
+        m_process = process;
+        m_load_addr = load_addr;
+        m_map_pair_size = m_process->GetAddressByteSize() * 2;
+        m_invalid_key = m_process->GetAddressByteSize() == 8 ? UINT64_MAX : UINT32_MAX;
         Error err;
         
-        // const struct +NXMapTablePrototype *prototype;
-        m_prototype_ptr = m_process_sp->ReadPointerFromMemory(cursor, err);
-        cursor += m_process_sp->GetAddressByteSize();
+        // This currently holds true for all platforms we support, but we might
+        // need to change this to use get the actualy byte size of "unsigned"
+        // from the target AST...
+        const uint32_t unsigned_byte_size = sizeof(uint32_t);
+        // Skip the prototype as we don't need it (const struct +NXMapTablePrototype *prototype)
+        
+        bool success = true;
+        if (load_addr == LLDB_INVALID_ADDRESS)
+            success = false;
+        else
+        {
+            lldb::addr_t cursor = load_addr + m_process->GetAddressByteSize();
+                    
+            // unsigned count;
+            m_count = m_process->ReadUnsignedIntegerFromMemory(cursor, unsigned_byte_size, 0, err);
+            if (m_count)
+            {
+                cursor += unsigned_byte_size;
+            
+                // unsigned nbBucketsMinusOne;
+                m_num_buckets_minus_one = m_process->ReadUnsignedIntegerFromMemory(cursor, unsigned_byte_size, 0, err);
+                cursor += unsigned_byte_size;
+            
+                // void *buckets;
+                m_buckets_ptr = m_process->ReadPointerFromMemory(cursor, err);
                 
-        // unsigned count;
-        m_count = m_process_sp->ReadUnsignedIntegerFromMemory(cursor, sizeof(unsigned), 0, err);
-        cursor += sizeof(unsigned);
-        
-        // unsigned nbBucketsMinusOne;
-        m_nbBucketsMinusOne = m_process_sp->ReadUnsignedIntegerFromMemory(cursor, sizeof(unsigned), 0, err);
-        cursor += sizeof(unsigned);
+                success = m_count > 0 && m_buckets_ptr != LLDB_INVALID_ADDRESS;
+            }
+        }
         
-        // void *buckets;
-        m_buckets_ptr = m_process_sp->ReadPointerFromMemory(cursor, err);
+        if (!success)
+        {
+            m_count = 0;
+            m_num_buckets_minus_one = 0;
+            m_buckets_ptr = LLDB_INVALID_ADDRESS;
+        }
+        return success;
     }
     
     // const_iterator mimics NXMapState and its code comes from NXInitMapState and NXNextMapState.
@@ -552,22 +590,22 @@
                 return element();
             }
          
-            lldb::addr_t    pairs_ptr        = m_parent.m_buckets_ptr;
-            size_t          map_pair_size   = m_parent.m_map_pair_size;
-            lldb::addr_t    pair_ptr         = pairs_ptr + (m_index * map_pair_size);
+            lldb::addr_t pairs_ptr = m_parent.m_buckets_ptr;
+            size_t map_pair_size = m_parent.m_map_pair_size;
+            lldb::addr_t pair_ptr = pairs_ptr + (m_index * map_pair_size);
             
-            Error           err;
+            Error err;
             
-            lldb::addr_t    key     = m_parent.m_process_sp->ReadPointerFromMemory(pair_ptr, err);
+            lldb::addr_t key = m_parent.m_process->ReadPointerFromMemory(pair_ptr, err);
             if (!err.Success())
                 return element();
-            lldb::addr_t    value   = m_parent.m_process_sp->ReadPointerFromMemory(pair_ptr + m_parent.m_process_sp->GetAddressByteSize(), err);
+            lldb::addr_t value = m_parent.m_process->ReadPointerFromMemory(pair_ptr + m_parent.m_process->GetAddressByteSize(), err);
             if (!err.Success())
                 return element();
             
             std::string key_string;
             
-            m_parent.m_process_sp->ReadCStringFromMemory(key, key_string, err);
+            m_parent.m_process->ReadCStringFromMemory(key, key_string, err);
             if (!err.Success())
                 return element();
             
@@ -579,15 +617,15 @@
             if (m_index == -1)
                 return;
             
-            lldb::addr_t    pairs_ptr        = m_parent.m_buckets_ptr;
-            size_t          map_pair_size   = m_parent.m_map_pair_size;
-            lldb::addr_t    NXMAPNOTAKEY    = m_parent.m_NXMAPNOTAKEY;
-            Error           err;
+            const lldb::addr_t pairs_ptr = m_parent.m_buckets_ptr;
+            const size_t map_pair_size = m_parent.m_map_pair_size;
+            const lldb::addr_t invalid_key = m_parent.m_invalid_key;
+            Error err;
 
             while (m_index--)
             {
                 lldb::addr_t pair_ptr = pairs_ptr + (m_index * map_pair_size);
-                lldb::addr_t key = m_parent.m_process_sp->ReadPointerFromMemory(pair_ptr, err);
+                lldb::addr_t key = m_parent.m_process->ReadPointerFromMemory(pair_ptr, err);
                 
                 if (!err.Success())
                 {
@@ -595,7 +633,7 @@
                     return;
                 }
                 
-                if (key != NXMAPNOTAKEY)
+                if (key != invalid_key)
                     return;
             }
         }
@@ -605,7 +643,7 @@
     
     const_iterator begin ()
     {
-        return const_iterator(*this, m_nbBucketsMinusOne + 1);
+        return const_iterator(*this, m_num_buckets_minus_one + 1);
     }
     
     const_iterator end ()
@@ -613,26 +651,80 @@
         return m_end_iterator;
     }
     
+    uint32_t
+    GetCount () const
+    {
+        return m_count;
+    }
+    
+    uint32_t
+    GetBucketCount () const
+    {
+        return m_num_buckets_minus_one;
+    }
+    
+    lldb::addr_t
+    GetBucketDataPointer () const
+    {
+        return m_buckets_ptr;
+    }
+
 private:
     // contents of _NXMapTable struct
-    lldb::addr_t                        m_prototype_ptr;
-    uint32_t                            m_count;
-    uint32_t                            m_nbBucketsMinusOne;
-    lldb::addr_t                        m_buckets_ptr;
-    
-    lldb::ProcessSP                     m_process_sp;
-    const_iterator                      m_end_iterator;
-    lldb::addr_t                        m_load_addr;
-    size_t                              m_map_pair_size;
-    lldb::addr_t                        m_NXMAPNOTAKEY;
+    uint32_t m_count;
+    uint32_t m_num_buckets_minus_one;
+    lldb::addr_t m_buckets_ptr;
+    lldb_private::Process *m_process;
+    const_iterator m_end_iterator;
+    lldb::addr_t m_load_addr;
+    size_t m_map_pair_size;
+    lldb::addr_t m_invalid_key;
 };
 
+
+
+AppleObjCRuntimeV2::HashTableSignature::HashTableSignature() :
+    m_count (0),
+    m_num_buckets (0),
+    m_buckets_ptr (0)
+{
+}
+
+void
+AppleObjCRuntimeV2::HashTableSignature::UpdateSignature (const RemoteNXMapTable &hash_table)
+{
+    m_count = hash_table.GetCount();
+    m_num_buckets = hash_table.GetBucketCount();
+    m_buckets_ptr = hash_table.GetBucketDataPointer();
+}
+
+bool
+AppleObjCRuntimeV2::HashTableSignature::NeedsUpdate (Process *process, AppleObjCRuntimeV2 *runtime, RemoteNXMapTable &hash_table)
+{
+    if (!hash_table.ParseHeader(process, runtime->GetISAHashTablePointer ()))
+    {
+        return false; // Failed to parse the header, no need to update anything
+    }
+
+    // Check with out current signature and return true if the count,
+    // number of buckets or the hash table address changes.
+    if (m_count == hash_table.GetCount() &&
+        m_num_buckets == hash_table.GetBucketCount() &&
+        m_buckets_ptr == hash_table.GetBucketDataPointer())
+    {
+        // Hash table hasn't changed
+        return false;
+    }
+    // Hash table data has changed, we need to update
+    return true;
+}
+
 class RemoteObjCOpt
 {
 public:
-    RemoteObjCOpt (lldb::ProcessSP process_sp,
+    RemoteObjCOpt (Process* process,
                    lldb::addr_t load_addr) :
-        m_process_sp(process_sp),
+        m_process(process),
         m_end_iterator(*this, -1ll),
         m_load_addr(load_addr)
     {
@@ -641,7 +733,7 @@
         Error err;
         
         // uint32_t version;
-        m_version = m_process_sp->ReadUnsignedIntegerFromMemory(cursor, sizeof(uint32_t), 0, err);
+        m_version = m_process->ReadUnsignedIntegerFromMemory(cursor, sizeof(uint32_t), 0, err);
         cursor += sizeof(uint32_t);
         
         // int32_t selopt_offset;
@@ -653,7 +745,7 @@
         // int32_t clsopt_offset;
         {
             Scalar clsopt_offset;
-            m_process_sp->ReadScalarIntegerFromMemory(cursor, sizeof(int32_t), /*is_signed*/ true, clsopt_offset, err);
+            m_process->ReadScalarIntegerFromMemory(cursor, sizeof(int32_t), /*is_signed*/ true, clsopt_offset, err);
             m_clsopt_offset = clsopt_offset.SInt();
             cursor += sizeof(int32_t);
         }
@@ -666,7 +758,7 @@
         cursor = m_clsopt_ptr;
         
         // uint32_t capacity;
-        m_capacity = m_process_sp->ReadUnsignedIntegerFromMemory(cursor, sizeof(uint32_t), 0, err);
+        m_capacity = m_process->ReadUnsignedIntegerFromMemory(cursor, sizeof(uint32_t), 0, err);
         cursor += sizeof(uint32_t);
         
         // uint32_t occupied;
@@ -676,7 +768,7 @@
         cursor += sizeof(uint32_t);
         
         // uint32_t mask;
-        m_mask = m_process_sp->ReadUnsignedIntegerFromMemory(cursor, sizeof(uint32_t), 0, err);
+        m_mask = m_process->ReadUnsignedIntegerFromMemory(cursor, sizeof(uint32_t), 0, err);
         cursor += sizeof(uint32_t);
 
         // uint32_t zero;
@@ -706,7 +798,7 @@
         cursor += (m_classheader_size * m_capacity);
         
         // uint32_t duplicateCount;
-        m_duplicateCount = m_process_sp->ReadUnsignedIntegerFromMemory(cursor, sizeof(uint32_t), 0, err);
+        m_duplicateCount = m_process->ReadUnsignedIntegerFromMemory(cursor, sizeof(uint32_t), 0, err);
         cursor += sizeof(uint32_t);
         
         // objc_classheader_t duplicateOffsets[duplicateCount];
@@ -784,7 +876,7 @@
             }
             
             Scalar clsOffset;
-            m_parent.m_process_sp->ReadScalarIntegerFromMemory(classheader_ptr, sizeof(int32_t), /*is_signed*/ true, clsOffset, err);
+            m_parent.m_process->ReadScalarIntegerFromMemory(classheader_ptr, sizeof(int32_t), /*is_signed*/ true, clsOffset, err);
             if (!err.Success())
                 return 0;
             
@@ -831,23 +923,21 @@
     
 private:
     // contents of objc_opt struct
-    uint32_t                            m_version;
-    int32_t                             m_clsopt_offset;
-    
-    lldb::addr_t                        m_clsopt_ptr;
+    uint32_t m_version;
+    int32_t m_clsopt_offset;
+    lldb::addr_t m_clsopt_ptr;
     
     // contents of objc_clsopt struct
-    uint32_t                            m_capacity;
-    uint32_t                            m_mask;
-    uint32_t                            m_duplicateCount;
-    lldb::addr_t                        m_clsOffsets_ptr;
-    lldb::addr_t                        m_duplicateOffsets_ptr;
-    int32_t                             m_zero_offset;
-    
-    lldb::ProcessSP                     m_process_sp;
-    const_iterator                      m_end_iterator;
-    lldb::addr_t                        m_load_addr;
-    const size_t                        m_classheader_size = (sizeof(int32_t) * 2);
+    uint32_t m_capacity;
+    uint32_t m_mask;
+    uint32_t m_duplicateCount;
+    lldb::addr_t m_clsOffsets_ptr;
+    lldb::addr_t m_duplicateOffsets_ptr;
+    int32_t m_zero_offset;    
+    lldb_private::Process *m_process;
+    const_iterator m_end_iterator;
+    lldb::addr_t m_load_addr;
+    const size_t m_classheader_size = (sizeof(int32_t) * 2);
 };
 
 class ClassDescriptorV2 : public ObjCLanguageRuntime::ClassDescriptor
@@ -871,17 +961,17 @@
     {
         if (!m_name)
         {
-            lldb::ProcessSP process_sp = m_runtime.GetProcessSP();
+            lldb_private::Process *process = m_runtime.GetProcess();
 
-            if (process_sp)
+            if (process)
             {
                 std::auto_ptr<objc_class_t> objc_class;
                 std::auto_ptr<class_ro_t> class_ro;
                 std::auto_ptr<class_rw_t> class_rw;
                 
-                if (!Read_objc_class(process_sp, objc_class))
+                if (!Read_objc_class(process, objc_class))
                     return m_name;
-                if (!Read_class_row(process_sp, *objc_class, class_ro, class_rw))
+                if (!Read_class_row(process, *objc_class, class_ro, class_rw))
                     return m_name;
                 
                 m_name = ConstString(class_ro->m_name.c_str());
@@ -893,14 +983,14 @@
     virtual ObjCLanguageRuntime::ClassDescriptorSP
     GetSuperclass ()
     {
-        lldb::ProcessSP process_sp = m_runtime.GetProcessSP();
+        lldb_private::Process *process = m_runtime.GetProcess();
 
-        if (!process_sp)
+        if (!process)
             return ObjCLanguageRuntime::ClassDescriptorSP();
         
         std::auto_ptr<objc_class_t> objc_class;
 
-        if (!Read_objc_class(process_sp, objc_class))
+        if (!Read_objc_class(process, objc_class))
             return ObjCLanguageRuntime::ClassDescriptorSP();
 
         return m_runtime.ObjCLanguageRuntime::GetClassDescriptor(objc_class->m_superclass);
@@ -921,17 +1011,17 @@
     virtual uint64_t
     GetInstanceSize ()
     {
-        lldb::ProcessSP process_sp = m_runtime.GetProcessSP();
+        lldb_private::Process *process = m_runtime.GetProcess();
         
-        if (process_sp)
+        if (process)
         {
             std::auto_ptr<objc_class_t> objc_class;
             std::auto_ptr<class_ro_t> class_ro;
             std::auto_ptr<class_rw_t> class_rw;
             
-            if (!Read_objc_class(process_sp, objc_class))
+            if (!Read_objc_class(process, objc_class))
                 return 0;
-            if (!Read_class_row(process_sp, *objc_class, class_ro, class_rw))
+            if (!Read_class_row(process, *objc_class, class_ro, class_rw))
                 return 0;
             
             return class_ro->m_instanceSize;
@@ -951,15 +1041,15 @@
               std::function <void (const char *, const char *)> const &instance_method_func,
               std::function <void (const char *, const char *)> const &class_method_func)
     {
-        lldb::ProcessSP process_sp = m_runtime.GetProcessSP();
+        lldb_private::Process *process = m_runtime.GetProcess();
 
         std::auto_ptr<objc_class_t> objc_class;
         std::auto_ptr<class_ro_t> class_ro;
         std::auto_ptr<class_rw_t> class_rw;
         
-        if (!Read_objc_class(process_sp, objc_class))
+        if (!Read_objc_class(process, objc_class))
             return 0;
-        if (!Read_class_row(process_sp, *objc_class, class_ro, class_rw))
+        if (!Read_class_row(process, *objc_class, class_ro, class_rw))
             return 0;
     
         static ConstString NSObject_name("NSObject");
@@ -972,10 +1062,10 @@
             std::auto_ptr <method_list_t> base_method_list;
             
             base_method_list.reset(new method_list_t);
-            if (!base_method_list->Read(process_sp, class_ro->m_baseMethods_ptr))
+            if (!base_method_list->Read(process, class_ro->m_baseMethods_ptr))
                 return false;
             
-            if (base_method_list->m_entsize != method_t::GetSize(process_sp))
+            if (base_method_list->m_entsize != method_t::GetSize(process))
                 return false;
             
             std::auto_ptr <method_t> method;
@@ -983,7 +1073,7 @@
             
             for (uint32_t i = 0, e = base_method_list->m_count; i < e; ++i)
             {
-                method->Read(process_sp, base_method_list->m_first_ptr + (i * base_method_list->m_entsize));
+                method->Read(process, base_method_list->m_first_ptr + (i * base_method_list->m_entsize));
                 
                 instance_method_func(method->m_name.c_str(), method->m_types.c_str());
             }
@@ -1042,9 +1132,9 @@
             m_flags = 0;
         }
 
-        bool Read(ProcessSP &process_sp, lldb::addr_t addr)
+        bool Read(Process *process, lldb::addr_t addr)
         {
-            size_t ptr_size = process_sp->GetAddressByteSize();
+            size_t ptr_size = process->GetAddressByteSize();
             
             size_t objc_class_size = ptr_size   // uintptr_t isa;
             + ptr_size   // Class superclass;
@@ -1055,13 +1145,13 @@
             DataBufferHeap objc_class_buf (objc_class_size, '\0');
             Error error;
             
-            process_sp->ReadMemory(addr, objc_class_buf.GetBytes(), objc_class_size, error);
+            process->ReadMemory(addr, objc_class_buf.GetBytes(), objc_class_size, error);
             if (error.Fail())
             {
                 return false;
             }
             
-            DataExtractor extractor(objc_class_buf.GetBytes(), objc_class_size, process_sp->GetByteOrder(), process_sp->GetAddressByteSize());
+            DataExtractor extractor(objc_class_buf.GetBytes(), objc_class_size, process->GetByteOrder(), process->GetAddressByteSize());
             
             uint32_t cursor = 0;
             
@@ -1095,9 +1185,9 @@
         
         std::string                     m_name;
         
-        bool Read(ProcessSP &process_sp, lldb::addr_t addr)
+        bool Read(Process *process, lldb::addr_t addr)
         {
-            size_t ptr_size = process_sp->GetAddressByteSize();
+            size_t ptr_size = process->GetAddressByteSize();
             
             size_t size = sizeof(uint32_t)             // uint32_t flags;
             + sizeof(uint32_t)                         // uint32_t instanceStart;
@@ -1114,13 +1204,13 @@
             DataBufferHeap buffer (size, '\0');
             Error error;
             
-            process_sp->ReadMemory(addr, buffer.GetBytes(), size, error);
+            process->ReadMemory(addr, buffer.GetBytes(), size, error);
             if (error.Fail())
             {
                 return false;
             }
             
-            DataExtractor extractor(buffer.GetBytes(), size, process_sp->GetByteOrder(), process_sp->GetAddressByteSize());
+            DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
             
             uint32_t cursor = 0;
             
@@ -1141,7 +1231,7 @@
             
             DataBufferHeap name_buf(1024, '\0');
             
-            process_sp->ReadCStringFromMemory(m_name_ptr, (char*)name_buf.GetBytes(), name_buf.GetByteSize(), error);
+            process->ReadCStringFromMemory(m_name_ptr, (char*)name_buf.GetBytes(), name_buf.GetByteSize(), error);
             
             if (error.Fail())
             {
@@ -1169,9 +1259,9 @@
         ObjCLanguageRuntime::ObjCISA    m_firstSubclass;
         ObjCLanguageRuntime::ObjCISA    m_nextSiblingClass;
         
-        bool Read(ProcessSP &process_sp, lldb::addr_t addr)
+        bool Read(Process *process, lldb::addr_t addr)
         {
-            size_t ptr_size = process_sp->GetAddressByteSize();
+            size_t ptr_size = process->GetAddressByteSize();
             
             size_t size = sizeof(uint32_t)  // uint32_t flags;
             + sizeof(uint32_t)  // uint32_t version;
@@ -1185,13 +1275,13 @@
             DataBufferHeap buffer (size, '\0');
             Error error;
             
-            process_sp->ReadMemory(addr, buffer.GetBytes(), size, error);
+            process->ReadMemory(addr, buffer.GetBytes(), size, error);
             if (error.Fail())
             {
                 return false;
             }
             
-            DataExtractor extractor(buffer.GetBytes(), size, process_sp->GetByteOrder(), process_sp->GetAddressByteSize());
+            DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
             
             uint32_t cursor = 0;
             
@@ -1213,7 +1303,7 @@
         uint32_t        m_count;
         lldb::addr_t    m_first_ptr;
         
-        bool Read(ProcessSP &process_sp, lldb::addr_t addr)
+        bool Read(Process *process, lldb::addr_t addr)
         {
             size_t size = sizeof(uint32_t)  // uint32_t entsize_NEVER_USE;
             + sizeof(uint32_t); // uint32_t count;
@@ -1221,13 +1311,13 @@
             DataBufferHeap buffer (size, '\0');
             Error error;
             
-            process_sp->ReadMemory(addr, buffer.GetBytes(), size, error);
+            process->ReadMemory(addr, buffer.GetBytes(), size, error);
             if (error.Fail())
             {
                 return false;
             }
             
-            DataExtractor extractor(buffer.GetBytes(), size, process_sp->GetByteOrder(), process_sp->GetAddressByteSize());
+            DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
             
             uint32_t cursor = 0;
             
@@ -1248,29 +1338,29 @@
         std::string     m_name;
         std::string     m_types;
         
-        static size_t GetSize(ProcessSP &process_sp)
+        static size_t GetSize(Process *process)
         {
-            size_t ptr_size = process_sp->GetAddressByteSize();
+            size_t ptr_size = process->GetAddressByteSize();
             
             return ptr_size     // SEL name;
             + ptr_size   // const char *types;
             + ptr_size;  // IMP imp;
         }
         
-        bool Read(ProcessSP &process_sp, lldb::addr_t addr)
+        bool Read(Process *process, lldb::addr_t addr)
         {
-            size_t size = GetSize(process_sp);
+            size_t size = GetSize(process);
             
             DataBufferHeap buffer (size, '\0');
             Error error;
             
-            process_sp->ReadMemory(addr, buffer.GetBytes(), size, error);
+            process->ReadMemory(addr, buffer.GetBytes(), size, error);
             if (error.Fail())
             {
                 return false;
             }
             
-            DataExtractor extractor(buffer.GetBytes(), size, process_sp->GetByteOrder(), process_sp->GetAddressByteSize());
+            DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
             
             uint32_t cursor = 0;
             
@@ -1283,21 +1373,21 @@
             
             DataBufferHeap string_buf(buffer_size, 0);
             
-            count = process_sp->ReadCStringFromMemory(m_name_ptr, (char*)string_buf.GetBytes(), buffer_size, error);
+            count = process->ReadCStringFromMemory(m_name_ptr, (char*)string_buf.GetBytes(), buffer_size, error);
             m_name.assign((char*)string_buf.GetBytes(), count);
             
-            count = process_sp->ReadCStringFromMemory(m_types_ptr, (char*)string_buf.GetBytes(), buffer_size, error);
+            count = process->ReadCStringFromMemory(m_types_ptr, (char*)string_buf.GetBytes(), buffer_size, error);
             m_types.assign((char*)string_buf.GetBytes(), count);
             
             return true;
         }
     };
     
-    bool Read_objc_class (lldb::ProcessSP process_sp, std::auto_ptr<objc_class_t> &objc_class)
+    bool Read_objc_class (Process* process, std::auto_ptr<objc_class_t> &objc_class)
     {
         objc_class.reset(new objc_class_t);
         
-        bool ret = objc_class->Read (process_sp, m_objc_class_ptr);
+        bool ret = objc_class->Read (process, m_objc_class_ptr);
         
         if (!ret)
             objc_class.reset();
@@ -1305,13 +1395,13 @@
         return ret;
     }
     
-    bool Read_class_row (lldb::ProcessSP process_sp, const objc_class_t &objc_class, std::auto_ptr<class_ro_t> &class_ro, std::auto_ptr<class_rw_t> &class_rw)
+    bool Read_class_row (Process* process, const objc_class_t &objc_class, std::auto_ptr<class_ro_t> &class_ro, std::auto_ptr<class_rw_t> &class_rw)
     {
         class_ro.reset();
         class_rw.reset();
         
         Error error;
-        uint32_t class_row_t_flags = process_sp->ReadUnsignedIntegerFromMemory(objc_class.m_data_ptr, sizeof(uint32_t), 0, error);
+        uint32_t class_row_t_flags = process->ReadUnsignedIntegerFromMemory(objc_class.m_data_ptr, sizeof(uint32_t), 0, error);
         if (!error.Success())
             return false;
 
@@ -1319,7 +1409,7 @@
         {
             class_rw.reset(new class_rw_t);
             
-            if (!class_rw->Read(process_sp, objc_class.m_data_ptr))
+            if (!class_rw->Read(process, objc_class.m_data_ptr))
             {
                 class_rw.reset();
                 return false;
@@ -1327,7 +1417,7 @@
             
             class_ro.reset(new class_ro_t);
             
-            if (!class_ro->Read(process_sp, class_rw->m_ro_ptr))
+            if (!class_ro->Read(process, class_rw->m_ro_ptr))
             {
                 class_rw.reset();
                 class_ro.reset();
@@ -1338,7 +1428,7 @@
         {
             class_ro.reset(new class_ro_t);
             
-            if (!class_ro->Read(process_sp, objc_class.m_data_ptr))
+            if (!class_ro->Read(process, objc_class.m_data_ptr))
             {
                 class_ro.reset();
                 return false;
@@ -1360,7 +1450,7 @@
     {
         m_valid = false;
         uint64_t value = isa_pointer.GetValueAsUnsigned(0);
-        lldb::ProcessSP process_sp = isa_pointer.GetProcessSP();
+        ProcessSP process_sp = isa_pointer.GetProcessSP();
         if (process_sp)
             m_pointer_size = process_sp->GetAddressByteSize();
         else
@@ -1595,46 +1685,63 @@
     return objc_class_sp;
 }
 
-bool
-AppleObjCRuntimeV2::UpdateISAToDescriptorMap_Impl()
+lldb::addr_t
+AppleObjCRuntimeV2::GetISAHashTablePointer ()
 {
-    lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+    if (m_isa_hash_table_ptr == LLDB_INVALID_ADDRESS)
+    {
+        Process *process = GetProcess();
 
-    Process *process_ptr = GetProcess();
-    
-    if (!process_ptr)
-        return false;
-    
-    ProcessSP process_sp (process_ptr->shared_from_this());
-    
-    ModuleSP objc_module_sp(GetObjCModule());
-    
-    if (!objc_module_sp)
-        return false;
+        ModuleSP objc_module_sp(GetObjCModule());
 
-    uint32_t num_map_table_isas = 0;
-    uint32_t num_objc_opt_ro_isas = 0;
+        static ConstString g_gdb_objc_realized_classes("gdb_objc_realized_classes");
+        
+        const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_objc_realized_classes, lldb::eSymbolTypeData);
+        if (symbol)
+        {
+            lldb::addr_t gdb_objc_realized_classes_ptr = symbol->GetAddress().GetLoadAddress(&process->GetTarget());
+            
+            if (gdb_objc_realized_classes_ptr != LLDB_INVALID_ADDRESS)
+            {
+                Error error;
+                lldb::addr_t ptr = process->ReadPointerFromMemory(gdb_objc_realized_classes_ptr, error);
+                if (ptr != LLDB_INVALID_ADDRESS);
+                    m_isa_hash_table_ptr = ptr;
+            }
+        }
+    }
+    return m_isa_hash_table_ptr;
+}
 
-    static ConstString g_gdb_objc_realized_classes("gdb_objc_realized_classes");
+void
+AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded()
+{
+    // Else we need to check with our process to see when the map was updated.
+    Process *process = GetProcess();
 
-    const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_objc_realized_classes, lldb::eSymbolTypeData);
-    if (symbol)
+    if (process)
     {
-        lldb::addr_t gdb_objc_realized_classes_ptr = symbol->GetAddress().GetLoadAddress(&process_sp->GetTarget());
+        // Update the process stop ID that indicates the last time we updated the
+        // map, wether it was successful or not.
+        m_isa_to_descriptor_cache_stop_id = process->GetStopID();
         
-        if (gdb_objc_realized_classes_ptr != LLDB_INVALID_ADDRESS)
+        RemoteNXMapTable hash_table;
+        
+        if (m_hash_signature.NeedsUpdate(process, this, hash_table))
         {
-            // <rdar://problem/10763513>
+            // Update the hash table signature
+            m_hash_signature.UpdateSignature (hash_table);
+
+            lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
 
-            lldb::addr_t gdb_objc_realized_classes_nxmaptable_ptr;
+            uint32_t num_map_table_isas = 0;
+            uint32_t num_objc_opt_ro_isas = 0;
+
+            ModuleSP objc_module_sp(GetObjCModule());
             
-            Error err;
-            gdb_objc_realized_classes_nxmaptable_ptr = process_sp->ReadPointerFromMemory(gdb_objc_realized_classes_ptr, err);
-            if (err.Success())
+            if (objc_module_sp)
             {
-                RemoteNXMapTable gdb_objc_realized_classes(process_sp, gdb_objc_realized_classes_nxmaptable_ptr);
-            
-                for (RemoteNXMapTable::element elt : gdb_objc_realized_classes)
+                for (RemoteNXMapTable::element elt : hash_table)
                 {
                     ++num_map_table_isas;
                     
@@ -1648,52 +1755,54 @@
                     
                     m_isa_to_descriptor_cache[elt.second] = descriptor_sp;
                 }
-            }
-        }
-    }
-    
-    ObjectFile *objc_object = objc_module_sp->GetObjectFile();
-    
-    if (objc_object)
-    {
-        SectionList *section_list = objc_object->GetSectionList();
-    
-        if (section_list)
-        {
-            SectionSP text_segment_sp (section_list->FindSectionByName(ConstString("__TEXT")));
-            
-            if (text_segment_sp)
-            {
-                SectionSP objc_opt_section_sp (text_segment_sp->GetChildren().FindSectionByName(ConstString("__objc_opt_ro")));
                 
-                if (objc_opt_section_sp)
+                ObjectFile *objc_object = objc_module_sp->GetObjectFile();
+                
+                if (objc_object)
                 {
-                    lldb::addr_t objc_opt_ptr = objc_opt_section_sp->GetLoadBaseAddress(&process_sp->GetTarget());
-                    
-                    if (objc_opt_ptr != LLDB_INVALID_ADDRESS)
+                    SectionList *section_list = objc_object->GetSectionList();
+                
+                    if (section_list)
                     {
-                        RemoteObjCOpt objc_opt(process_sp, objc_opt_ptr);
+                        SectionSP text_segment_sp (section_list->FindSectionByName(ConstString("__TEXT")));
                         
-                        for (ObjCLanguageRuntime::ObjCISA objc_isa : objc_opt)
+                        if (text_segment_sp)
                         {
-                            ++num_objc_opt_ro_isas;
-                            if (m_isa_to_descriptor_cache.count(objc_isa))
-                                continue;
-                            
-                            ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(*this, objc_isa));
+                            SectionSP objc_opt_section_sp (text_segment_sp->GetChildren().FindSectionByName(ConstString("__objc_opt_ro")));
                             
-                            if (log && log->GetVerbose())
-                                log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%llx (%s) from static table to isa->descriptor cache", objc_isa, descriptor_sp->GetClassName().AsCString());
-                            
-                            m_isa_to_descriptor_cache[objc_isa] = descriptor_sp;
+                            if (objc_opt_section_sp)
+                            {
+                                lldb::addr_t objc_opt_ptr = objc_opt_section_sp->GetLoadBaseAddress(&process->GetTarget());
+                                
+                                if (objc_opt_ptr != LLDB_INVALID_ADDRESS)
+                                {
+                                    RemoteObjCOpt objc_opt(process, objc_opt_ptr);
+                                    
+                                    for (ObjCLanguageRuntime::ObjCISA objc_isa : objc_opt)
+                                    {
+                                        ++num_objc_opt_ro_isas;
+                                        if (m_isa_to_descriptor_cache.count(objc_isa))
+                                            continue;
+                                        
+                                        ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(*this, objc_isa));
+                                        
+                                        if (log && log->GetVerbose())
+                                            log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%llx (%s) from static table to isa->descriptor cache", objc_isa, descriptor_sp->GetClassName().AsCString());
+                                        
+                                        m_isa_to_descriptor_cache[objc_isa] = descriptor_sp;
+                                    }
+                                }
+                            }
                         }
                     }
                 }
             }
         }
     }
-    
-    return num_objc_opt_ro_isas > 0 && num_map_table_isas > 0;
+    else
+    {
+        m_isa_to_descriptor_cache_stop_id = UINT32_MAX;
+    }
 }
 
 

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h?rev=166693&r1=166692&r2=166693&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h Thu Oct 25 11:54:22 2012
@@ -21,6 +21,8 @@
 #include "lldb/Target/ObjCLanguageRuntime.h"
 #include "AppleObjCRuntime.h"
 
+class RemoteNXMapTable;
+
 namespace lldb_private {
 
 class AppleObjCRuntimeV2 :
@@ -72,9 +74,9 @@
 
     virtual size_t
     GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name);
-    
-    virtual bool
-    UpdateISAToDescriptorMap_Impl();
+
+    virtual void
+    UpdateISAToDescriptorMapIfNeeded();
     
     // none of these are valid ISAs - we use them to infer the type
     // of tagged pointers - if we have something meaningful to say
@@ -97,34 +99,49 @@
     virtual TypeVendor *
     GetTypeVendor();
     
-    lldb::ProcessSP
-    GetProcessSP ()
-    {
-        return m_process_wp.lock();
-    }
-    
 protected:
     virtual lldb::BreakpointResolverSP
     CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp);
 
 private:
     
+    class HashTableSignature
+    {
+    public:
+        HashTableSignature ();
+
+        bool
+        NeedsUpdate (Process *process,
+                     AppleObjCRuntimeV2 *runtime,
+                     RemoteNXMapTable &hash_table);
+        
+        void
+        UpdateSignature (const RemoteNXMapTable &hash_table);
+    protected:
+        uint32_t m_count;
+        uint32_t m_num_buckets;
+        lldb::addr_t m_buckets_ptr;
+    };
+
     AppleObjCRuntimeV2 (Process *process,
                         const lldb::ModuleSP &objc_module_sp);
     
     bool
     IsTaggedPointer(lldb::addr_t ptr);
     
+    lldb::addr_t
+    GetISAHashTablePointer ();
+
     bool RunFunctionToFindClassName (lldb::addr_t class_addr, Thread *thread, char *name_dst, size_t max_name_len);
     
-    bool                                m_has_object_getClass;
     std::auto_ptr<ClangFunction>        m_get_class_name_function;
     std::auto_ptr<ClangUtilityFunction> m_get_class_name_code;
     lldb::addr_t                        m_get_class_name_args;
     Mutex                               m_get_class_name_args_mutex;
-    
     std::auto_ptr<TypeVendor>           m_type_vendor_ap;
-    lldb::ProcessWP                     m_process_wp; // used by class descriptors to lazily fill their own data
+    lldb::addr_t                        m_isa_hash_table_ptr;
+    HashTableSignature                  m_hash_signature;
+    bool                                m_has_object_getClass;
     
     static const char *g_find_class_name_function_name;
     static const char *g_find_class_name_function_body;

Modified: lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp?rev=166693&r1=166692&r2=166693&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp Thu Oct 25 11:54:22 2012
@@ -220,8 +220,6 @@
                     ParseCOFFOptionalHeader(&offset);
                 ParseSectionHeaders (offset);
             }
-            StreamFile s(stdout, false);// REMOVE THIS LINE!!!
-            Dump(&s);// REMOVE THIS LINE!!!
             return true;
         }
     }

Modified: lldb/trunk/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp?rev=166693&r1=166692&r2=166693&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp (original)
+++ lldb/trunk/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp Thu Oct 25 11:54:22 2012
@@ -189,10 +189,6 @@
                     reg_info.kinds[eRegisterKindLLDB] = reg_num++;
                     m_register_info_ap->AddRegister (reg_info, reg_name, empty_name, gpr_name);
                 }
-                else
-                {
-                    printf ("not able to find register info for %s\n", reg_name.GetCString()); // REMOVE THIS printf before checkin!!!
-                }
             }
             
             m_register_info_ap->Finalize();

Modified: lldb/trunk/source/Target/ObjCLanguageRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ObjCLanguageRuntime.cpp?rev=166693&r1=166692&r2=166693&view=diff
==============================================================================
--- lldb/trunk/source/Target/ObjCLanguageRuntime.cpp (original)
+++ lldb/trunk/source/Target/ObjCLanguageRuntime.cpp Thu Oct 25 11:54:22 2012
@@ -32,7 +32,7 @@
     LanguageRuntime (process),
     m_has_new_literals_and_indexing (eLazyBoolCalculate),
     m_isa_to_descriptor_cache(),
-    m_isa_to_descriptor_cache_is_up_to_date (false)
+    m_isa_to_descriptor_cache_stop_id (UINT32_MAX)
 {
 
 }





More information about the lldb-commits mailing list