More work for the dynamic type size feature
authorEnrico Granata <egranata@apple.com>
Wed, 28 Jan 2015 00:45:42 +0000 (00:45 +0000)
committerEnrico Granata <egranata@apple.com>
Wed, 28 Jan 2015 00:45:42 +0000 (00:45 +0000)
Namely, this commit provides an actual implementation of how to retrieve the byte size in a sane way for an ObjC class, by scanning ivar offsets and byte sizes, figuring out the farthest-from-base ivar, and adding its byte size to that

Still NFC

llvm-svn: 227277

lldb/include/lldb/Target/ObjCLanguageRuntime.h
lldb/source/Target/ObjCLanguageRuntime.cpp

index a3fee91..42a3914 100644 (file)
@@ -20,6 +20,7 @@
 // Project includes
 #include "lldb/lldb-private.h"
 #include "lldb/Core/PluginInterface.h"
+#include "lldb/Core/ThreadSafeDenseMap.h"
 #include "lldb/Symbol/ClangASTType.h"
 #include "lldb/Symbol/DeclVendor.h"
 #include "lldb/Symbol/Type.h"
@@ -514,6 +515,10 @@ public:
         m_negative_complete_class_cache.clear();
     }
     
+    virtual bool
+    GetTypeBitSize (const ClangASTType& clang_type,
+                    uint64_t &size);
+    
 protected:
     //------------------------------------------------------------------
     // Classes that inherit from ObjCLanguageRuntime can see and modify these
@@ -610,11 +615,13 @@ private:
     typedef std::multimap<uint32_t, ObjCISA> HashToISAMap;
     typedef ISAToDescriptorMap::iterator ISAToDescriptorIterator;
     typedef HashToISAMap::iterator HashToISAIterator;
+    typedef ThreadSafeDenseMap<void*, uint64_t> TypeSizeCache;
 
     MsgImplMap m_impl_cache;
     LazyBool m_has_new_literals_and_indexing;
     ISAToDescriptorMap m_isa_to_descriptor;
     HashToISAMap m_hash_to_isa_map;
+    TypeSizeCache m_type_size_cache;
 
 protected:
     uint32_t m_isa_to_descriptor_stop_id;
index b182407..3d7a902 100644 (file)
@@ -34,9 +34,14 @@ ObjCLanguageRuntime::~ObjCLanguageRuntime()
 
 ObjCLanguageRuntime::ObjCLanguageRuntime (Process *process) :
     LanguageRuntime (process),
+    m_impl_cache(),
     m_has_new_literals_and_indexing (eLazyBoolCalculate),
     m_isa_to_descriptor(),
-    m_isa_to_descriptor_stop_id (UINT32_MAX)
+    m_hash_to_isa_map(),
+    m_type_size_cache(),
+    m_isa_to_descriptor_stop_id (UINT32_MAX),
+    m_complete_class_cache(),
+    m_negative_complete_class_cache()
 {
 
 }
@@ -626,3 +631,42 @@ ObjCLanguageRuntime::GetEncodingToType ()
 {
     return nullptr;
 }
+
+bool
+ObjCLanguageRuntime::GetTypeBitSize (const ClangASTType& clang_type,
+                                     uint64_t &size)
+{
+    void *opaque_ptr = clang_type.GetQualType().getAsOpaquePtr();
+    size = m_type_size_cache.Lookup(opaque_ptr);
+    // an ObjC object will at least have an ISA, so 0 is definitely not OK
+    if (size > 0)
+        return true;
+    
+    ClassDescriptorSP class_descriptor_sp = GetClassDescriptorFromClassName(clang_type.GetTypeName());
+    if (!class_descriptor_sp)
+        return false;
+    
+    int32_t max_offset = INT32_MIN;
+    uint64_t sizeof_max = 0;
+    bool found = false;
+    
+    for (size_t idx = 0;
+         idx < class_descriptor_sp->GetNumIVars();
+         idx++)
+    {
+        const auto& ivar = class_descriptor_sp->GetIVarAtIndex(idx);
+        int32_t cur_offset = ivar.m_offset;
+        if (cur_offset > max_offset)
+        {
+            max_offset = cur_offset;
+            sizeof_max = ivar.m_size;
+            found = true;
+        }
+    }
+    
+    size = 8 * (max_offset + sizeof_max);
+    if (found)
+        m_type_size_cache.Insert(opaque_ptr, size);
+    
+    return found;
+}