diff options
| author | Sean Callanan <scallanan@apple.com> | 2012-09-19 03:23:13 +0000 | 
|---|---|---|
| committer | Sean Callanan <scallanan@apple.com> | 2012-09-19 03:23:13 +0000 | 
| commit | 43dd07ec3ea881af3fcd81a40c84be579caae0ef (patch) | |
| tree | 127d28beb7f6b35a4931ae73b475b431aa9977fa | |
| parent | e6706e40bb6927d0d1aecf33aef411ccfe888081 (diff) | |
| download | bcm5719-llvm-43dd07ec3ea881af3fcd81a40c84be579caae0ef.tar.gz bcm5719-llvm-43dd07ec3ea881af3fcd81a40c84be579caae0ef.zip | |
Updated AppleObjCV2Runtime to load the class
data structures more rapidly.  Also added fields
for the other data structures in a class.
I also fixed a problem where I accidentally used
hasExternalLexicalStorage() instead of
hasExternalVisibleStorage() to mark an
incomplete object.
llvm-svn: 164197
| -rw-r--r-- | lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp | 227 | ||||
| -rw-r--r-- | lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp | 6 | 
2 files changed, 164 insertions, 69 deletions
| diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index 326a34cdc8e..78ccc1425ad 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -991,6 +991,9 @@ public:      virtual ConstString      GetClassName ()      { +        if (!m_valid) +            return ConstString(); +                  return m_name;      } @@ -999,10 +1002,11 @@ public:      {          if (!m_valid)              return ObjCLanguageRuntime::ClassDescriptorSP(); +                  ProcessSP process_sp = m_process_wp.lock();          if (!process_sp)              return ObjCLanguageRuntime::ClassDescriptorSP(); -        return AppleObjCRuntime::ClassDescriptorSP(new ClassDescriptorV2(m_parent_isa,process_sp)); +        return AppleObjCRuntime::ClassDescriptorSP(new ClassDescriptorV2(m_objc_class.m_superclass,process_sp));      }      virtual bool @@ -1020,30 +1024,43 @@ public:      virtual uint64_t      GetInstanceSize ()      { +        if (!m_valid) +            return 0; +                  return m_instance_size;      }      virtual ObjCLanguageRuntime::ObjCISA      GetISA ()      { -        return m_isa; +        if (!m_valid) +            return 0; +         +        return m_objc_class_la;      }      virtual bool      CompleteInterface (clang::ObjCInterfaceDecl *interface_decl)      { +        if (!m_valid) +            return false; +                  return false;      }      virtual bool      IsRealized ()      { +        if (!m_valid) +            return false; +                  return m_realized;      }      virtual      ~ClassDescriptorV2 () -    {} +    { +    }  protected:      virtual bool @@ -1056,107 +1073,136 @@ protected:      }      void -    Initialize (ObjCLanguageRuntime::ObjCISA isa, lldb::ProcessSP process_sp) +    Initialize (ObjCLanguageRuntime::ObjCISA pointer_to_isa, lldb::ProcessSP process_sp)      { -        if (!isa || !process_sp) +        m_valid = true; + +        if (!pointer_to_isa || !process_sp)          {              m_valid = false;              return;          } -        m_valid = true; -         +        size_t ptr_size = process_sp->GetAddressByteSize();          Error error; -        m_isa = process_sp->ReadPointerFromMemory(isa, error); -         +        m_objc_class_la = process_sp->ReadPointerFromMemory(pointer_to_isa, error); +          if (error.Fail())          {              m_valid = false;              return;          } -        uint32_t ptr_size = process_sp->GetAddressByteSize(); -         -        if (!IsPointerValid(m_isa,ptr_size,false,false,true)) -        { -            m_valid = false; -            return; -        } -         -        lldb::addr_t data_ptr = process_sp->ReadPointerFromMemory(m_isa + 4 * ptr_size, error); -         -        if (error.Fail()) +        const bool allow_NULLs = false; +        const bool allow_tagged = false; +        const bool check_version_specific = true; + +        if (!IsPointerValid(m_objc_class_la, ptr_size, allow_NULLs, allow_tagged, check_version_specific))          {              m_valid = false;              return;          } +                 +        size_t objc_class_size = ptr_size   // uintptr_t isa; +                               + ptr_size   // Class superclass; +                               + ptr_size   // void *cache; +                               + ptr_size   // IMP *vtable; +                               + ptr_size;  // uintptr_t data_NEVER_USE; -        if (!IsPointerValid(data_ptr,ptr_size,false,false,true))          { -            m_valid = false; -            return; +            DataBufferHeap objc_class_buf (objc_class_size, '\0'); +             +            process_sp->ReadMemory(m_objc_class_la, objc_class_buf.GetBytes(), objc_class_size, error); +            if (error.Fail()) +            { +                m_valid = false; +                return; +            } +             +            DataExtractor objc_class_extractor(objc_class_buf.GetBytes(), objc_class_size, process_sp->GetByteOrder(), process_sp->GetAddressByteSize()); +             +            uint32_t cursor = 0; +             +            m_objc_class.m_isa          = objc_class_extractor.GetAddress_unchecked(&cursor);   // uintptr_t isa; +            m_objc_class.m_superclass   = objc_class_extractor.GetAddress_unchecked(&cursor);   // Class superclass; +            m_objc_class.m_cache_la     = objc_class_extractor.GetAddress_unchecked(&cursor);   // void *cache; +            m_objc_class.m_vtable_la    = objc_class_extractor.GetAddress_unchecked(&cursor);   // IMP *vtable; +            lldb::addr_t data_NEVER_USE = objc_class_extractor.GetAddress_unchecked(&cursor);   // uintptr_t data_NEVER_USE; +             +            m_objc_class.m_flags = (uint8_t)(data_NEVER_USE & (lldb::addr_t)3); +            m_objc_class.m_data_la = data_NEVER_USE & ~(lldb::addr_t)3;          } -         -        m_parent_isa = process_sp->ReadPointerFromMemory(isa + ptr_size,error); -         -        if (error.Fail()) +                     +        // Now we just want to grab the instance size and the name. +        // Since we find out whether the class is realized on the way, we'll remember that too. +     +        // The flags for class_r[ow]_t always are the first uint32_t.  So just read that. +        if (!IsPointerValid(m_objc_class.m_data_la, ptr_size, allow_NULLs, allow_tagged, check_version_specific))          {              m_valid = false;              return;          } -        // sanity checks -        lldb::addr_t cache_ptr = process_sp->ReadPointerFromMemory(m_isa + 2*ptr_size, error); +        uint32_t class_row_t_flags = process_sp->ReadUnsignedIntegerFromMemory(m_objc_class.m_data_la, sizeof(uint32_t), 0, error);          if (error.Fail())          {              m_valid = false;              return;          } -        if (!IsPointerValid(cache_ptr,ptr_size,true,false,true)) -        { -            m_valid = false; -            return; -        } -        lldb::addr_t rot_pointer; +        m_realized = class_row_t_flags & RW_REALIZED; -        // now construct the data object +        lldb::addr_t class_ro_t_la = NULL; -        uint32_t flags; -        process_sp->ReadMemory(data_ptr, &flags, 4, error); -        if (error.Fail()) +        if (m_realized)          { -            m_valid = false; -            return; -        } - -        if (flags & RW_REALIZED) -        { -            m_realized = true; -            rot_pointer = process_sp->ReadPointerFromMemory(data_ptr + 8, error); +            lldb::addr_t class_rw_t_la = m_objc_class.m_data_la; +             +            class_ro_t_la = process_sp->ReadPointerFromMemory(class_rw_t_la +                                                              + sizeof(uint32_t)    // uint32_t flags +                                                              + sizeof(uint32_t),   // uint32_t version +                                                              error); +             +            if (error.Fail()) +            { +                m_valid = false; +                return; +            }          }          else          { -            m_realized = false; -            rot_pointer = data_ptr; +            class_ro_t_la = m_objc_class.m_data_la;          } -        if (error.Fail()) +        if (!IsPointerValid(class_ro_t_la, ptr_size))          {              m_valid = false;              return;          } -        if (!IsPointerValid(rot_pointer,ptr_size)) +        // Now that we have a handle on class_ro_t_la, read the desired data out +         +        m_instance_size = process_sp->ReadUnsignedIntegerFromMemory(class_ro_t_la +                                                                    + sizeof(uint32_t)                        // uint32_t flags +                                                                    + sizeof(uint32_t),                       // uint32_t instanceStart +                                                                    sizeof(uint32_t), +                                                                    0, +                                                                    error); +         +        if (error.Fail())          {              m_valid = false;              return;          } -        // now read from the rot -         -        lldb::addr_t name_ptr = process_sp->ReadPointerFromMemory(rot_pointer + (ptr_size == 8 ? 24 : 16) ,error); +        lldb::addr_t name_ptr = process_sp->ReadPointerFromMemory(class_ro_t_la +                                                                  + sizeof(uint32_t)                        // uint32_t flags +                                                                  + sizeof(uint32_t)                        // uint32_t instanceStart +                                                                  + sizeof(uint32_t)                        // uint32_t instanceSize +                                                                  + (ptr_size == 8 ? sizeof(uint32_t) : 0)  // uint32_t reserved (__LP64__ only) +                                                                  + ptr_size,                               // const uint8_t *ivarLayout +                                                                  error);          if (error.Fail())          { @@ -1164,9 +1210,10 @@ protected:              return;          } -        lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0)); +        const size_t buffer_size = 1024; -        size_t count = process_sp->ReadCStringFromMemory(name_ptr, (char*)buffer_sp->GetBytes(), 1024, error); +        DataBufferHeap buffer(buffer_size, 0); +        size_t count = process_sp->ReadCStringFromMemory(name_ptr, (char*)buffer.GetBytes(), buffer_size, error);          if (error.Fail())          { @@ -1175,24 +1222,72 @@ protected:          }          if (count) -            m_name = ConstString((char*)buffer_sp->GetBytes()); +            m_name = ConstString((char*)buffer.GetBytes());          else              m_name = ConstString(); -         -        m_instance_size = process_sp->ReadUnsignedIntegerFromMemory(rot_pointer + 8, ptr_size, 0, error); -         +                          m_process_wp = lldb::ProcessWP(process_sp);      }  private:      static const uint32_t RW_REALIZED = (1 << 31); -    ConstString m_name; -    ObjCLanguageRuntime::ObjCISA m_isa; -    ObjCLanguageRuntime::ObjCISA m_parent_isa; -    bool m_valid; +     +    bool                                m_valid;            // Gates whether we trust anything here at all. +    lldb::addr_t                        m_objc_class_la;    // The address of the objc_class_t. +     +    struct objc_class_t { +        ObjCLanguageRuntime::ObjCISA    m_isa;              // The class's metaclass. +        ObjCLanguageRuntime::ObjCISA    m_superclass; +        lldb::addr_t                    m_cache_la; +        lldb::addr_t                    m_vtable_la; +        lldb::addr_t                    m_data_la; +        uint8_t                         m_flags; +    }; +     +    objc_class_t                        m_objc_class; +     +    // cached information from the class_r[ow]_t +    ConstString                         m_name; +    uint32_t                            m_instance_size; +    bool                                m_realized; +     +    struct class_ro_t { +        uint32_t                        m_flags; +        uint32_t                        m_instanceStart; +        uint32_t                        m_instanceSize; +        uint32_t                        m_reserved; +         +        lldb::addr_t                    m_ivarLayout_la; +        lldb::addr_t                    m_name_la; +        lldb::addr_t                    m_baseMethods_la; +        lldb::addr_t                    m_baseProtocols_la; +        lldb::addr_t                    m_ivars_la; +         +        lldb::addr_t                    m_weakIvarLayout_la; +        lldb::addr_t                    m_baseProperties_la; +    }; +     +    std::auto_ptr<class_ro_t>           m_class_ro; +     +    struct class_rw_t { +        uint32_t                        m_flags; +        uint32_t                        m_version; +         +        lldb::addr_t                    m_ro_la; +        union { +            lldb::addr_t                m_method_list_la; +            lldb::addr_t                m_method_lists_la; +        }; +        lldb::addr_t                    m_properties_la; +        lldb::addr_t                    m_protocols_la; +         +        ObjCLanguageRuntime::ObjCISA    m_firstSubclass; +        ObjCLanguageRuntime::ObjCISA    m_nextSiblingClass; +    }; +     +    std::auto_ptr<class_rw_t>           m_class_rw; +          lldb::ProcessWP m_process_wp; -    uint64_t m_instance_size; -    bool m_realized;  };  class ClassDescriptorV2Tagged : public ObjCLanguageRuntime::ClassDescriptor diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp index ced2026d4d3..ac293946bf3 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp @@ -71,10 +71,10 @@ public:                      break;                  if (descriptor->CompleteInterface(non_const_interface_decl)) -                    non_const_interface_decl->setHasExternalLexicalStorage(false); +                    non_const_interface_decl->setHasExternalVisibleStorage(false);              } -            if (non_const_interface_decl->hasExternalLexicalStorage()) // hasExternalLexicalStorage() is cleared during completion +            if (non_const_interface_decl->hasExternalVisibleStorage())                  break;              return non_const_interface_decl->lookup(name); @@ -253,7 +253,7 @@ AppleObjCTypeVendor::FindTypes (const ConstString &name,          // It's not.  If it exists, we have to put it into our ASTContext. -        // TODO Actually do this.  But we have to search the class list first.  Until then we'll just give up. +        // TODO Remove this break once testing is complete.          break;          ObjCLanguageRuntime::ObjCISA isa = m_runtime.GetISA(name); | 

