[Lldb-commits] [lldb] r165567 - in /lldb/trunk: include/lldb/Target/ObjCLanguageRuntime.h source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
Sean Callanan
scallanan at apple.com
Tue Oct 9 16:45:42 PDT 2012
Author: spyffe
Date: Tue Oct 9 18:45:42 2012
New Revision: 165567
URL: http://llvm.org/viewvc/llvm-project?rev=165567&view=rev
Log:
Thinned the AppleObjCRuntimeV2's class descriptors.
The following are now derived lazily:
- The name of the class (cached);
- the instance size of the class (not cached);
The following have been removed entirely:
- Whether the class is realized. This is an
implementation detail.
- The contents of the objc_class object. That
object can be read as needed.
- Whether the class is valid. The fact that
we vended a class to begin with means it's
valid. We will only give up looking parts
of it up if they are not in the format we
expect.
Modified:
lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
Modified: lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h?rev=165567&r1=165566&r2=165567&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h (original)
+++ lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h Tue Oct 9 18:45:42 2012
@@ -98,13 +98,6 @@
virtual uint64_t
GetInstanceSize () = 0;
- virtual bool
- IsRealized ()
- {
- // anything other than some instances of v2 classes are always realized
- return true;
- }
-
// use to implement version-specific additional constraints on pointers
virtual bool
CheckPointer (lldb::addr_t value,
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=165567&r1=165566&r2=165567&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Tue Oct 9 18:45:42 2012
@@ -981,63 +981,32 @@
// or populates them. A ClassDescriptorV2 should only ever exist in a cache.
ClassDescriptorV2 (AppleObjCRuntimeV2 &runtime, ObjCLanguageRuntime::ObjCISA isa) :
m_runtime (runtime),
- m_valid (false),
- m_objc_class_ptr (0),
- m_objc_class (),
- m_name (),
- m_instance_size (0),
- m_realized (eLazyBoolCalculate),
- m_process_wp ()
+ m_objc_class_ptr (isa),
+ m_name ()
{
- Initialize (isa, m_runtime.GetProcessSP());
}
public:
virtual ConstString
GetClassName ()
{
- if (m_valid && !m_name)
+ if (!m_name)
{
- const lldb::addr_t class_ro_t_ptr = get_class_ro_t_ptr ();
-
- ProcessSP process_sp = m_process_wp.lock();
-
+ lldb::ProcessSP process_sp = m_runtime.GetProcessSP();
+
if (process_sp)
{
- const size_t ptr_size = process_sp->GetAddressByteSize();
+ std::auto_ptr<objc_class_t> objc_class;
+ std::auto_ptr<class_ro_t> class_ro;
+ std::auto_ptr<class_rw_t> class_rw;
- Error error;
- lldb::addr_t name_ptr = process_sp->ReadPointerFromMemory (class_ro_t_ptr
- + 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 (!Read_objc_class(process_sp, objc_class))
+ return m_name;
+ if (!Read_class_row(process_sp, *objc_class, class_ro, class_rw))
+ return m_name;
- if (error.Success())
- {
- char class_name_cstr[1024];
-
- size_t count = process_sp->ReadCStringFromMemory(name_ptr, class_name_cstr, sizeof(class_name_cstr), error);
-
- if (error.Fail())
- {
- m_valid = false;
- }
- else
- {
- if (count)
- m_name.SetCString(class_name_cstr);
- else
- m_valid = false;
- }
- }
- else
- m_valid = false;
+ m_name = ConstString(class_ro->m_name.c_str());
}
- else
- m_valid = false;
}
return m_name;
}
@@ -1045,16 +1014,23 @@
virtual ObjCLanguageRuntime::ClassDescriptorSP
GetSuperclass ()
{
- if (!m_valid)
+ lldb::ProcessSP process_sp = m_runtime.GetProcessSP();
+
+ if (!process_sp)
return ObjCLanguageRuntime::ClassDescriptorSP();
- return m_runtime.ObjCLanguageRuntime::GetClassDescriptor(m_objc_class.m_superclass);
+ std::auto_ptr<objc_class_t> objc_class;
+
+ if (!Read_objc_class(process_sp, objc_class))
+ return ObjCLanguageRuntime::ClassDescriptorSP();
+
+ return m_runtime.ObjCLanguageRuntime::GetClassDescriptor(objc_class->m_superclass);
}
virtual bool
IsValid ()
{
- return m_valid;
+ return true; // any Objective-C v2 runtime class descriptor we vend is valid
}
virtual bool
@@ -1066,39 +1042,28 @@
virtual uint64_t
GetInstanceSize ()
{
- if (!m_valid)
- return 0;
+ lldb::ProcessSP process_sp = m_runtime.GetProcessSP();
- if (m_instance_size == 0)
+ if (process_sp)
{
- const lldb::addr_t class_ro_t_ptr = get_class_ro_t_ptr ();
+ 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))
+ return 0;
+ if (!Read_class_row(process_sp, *objc_class, class_ro, class_rw))
+ return 0;
- ProcessSP process_sp = m_process_wp.lock();
-
- if (process_sp)
- {
- Error error;
- m_instance_size = process_sp->ReadUnsignedIntegerFromMemory(class_ro_t_ptr
- + sizeof(uint32_t) // uint32_t flags
- + sizeof(uint32_t), // uint32_t instanceStart
- sizeof(uint32_t),
- 0,
- error);
- if (error.Fail())
- m_valid = false;
- }
- else
- m_valid = false;
+ return class_ro->m_instanceSize;
}
- return m_instance_size;
+
+ return 0;
}
virtual ObjCLanguageRuntime::ObjCISA
GetISA ()
- {
- if (!m_valid)
- return 0;
-
+ {
return m_objc_class_ptr;
}
@@ -1107,45 +1072,28 @@
std::function <void (const char *, const char *)> const &instance_method_func,
std::function <void (const char *, const char *)> const &class_method_func)
{
- if (!m_valid)
- return false;
-
- std::auto_ptr <class_ro_t> ro;
- std::auto_ptr <class_rw_t> rw;
-
- ProcessSP process_sp = m_process_wp.lock();
-
- if (!process_sp)
- return false;
+ lldb::ProcessSP process_sp = m_runtime.GetProcessSP();
+
+ 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 (IsRealized())
- {
- rw.reset(new class_rw_t);
- if (!rw->Read(process_sp, m_objc_class.m_data_ptr))
- return false;
-
- ro.reset(new class_ro_t);
- if (!ro->Read(process_sp, rw->m_ro_ptr))
- return false;
- }
- else
- {
- ro.reset(new class_ro_t);
- if (!ro->Read(process_sp, m_objc_class.m_data_ptr))
- return false;
- }
+ if (!Read_objc_class(process_sp, objc_class))
+ return 0;
+ if (!Read_class_row(process_sp, *objc_class, class_ro, class_rw))
+ return 0;
static ConstString NSObject_name("NSObject");
if (m_name != NSObject_name && superclass_func)
- superclass_func(m_objc_class.m_superclass);
+ superclass_func(objc_class->m_superclass);
if (instance_method_func)
{
std::auto_ptr <method_list_t> base_method_list;
base_method_list.reset(new method_list_t);
- if (!base_method_list->Read(process_sp, ro->m_baseMethods_ptr))
+ if (!base_method_list->Read(process_sp, class_ro->m_baseMethods_ptr))
return false;
if (base_method_list->m_entsize != method_t::GetSize(process_sp))
@@ -1164,7 +1112,7 @@
if (class_method_func)
{
- ObjCLanguageRuntime::ClassDescriptorSP metaclass = m_runtime.ObjCLanguageRuntime::GetClassDescriptor(m_objc_class.m_isa);
+ ObjCLanguageRuntime::ClassDescriptorSP metaclass = m_runtime.ObjCLanguageRuntime::GetClassDescriptor(objc_class->m_isa);
// We don't care about the metaclass's superclass, or its class methods. Its instance methods are
// our class methods.
@@ -1178,133 +1126,10 @@
return true;
}
- virtual bool
- IsRealized ()
- {
- if (!m_valid)
- return false;
-
- if (m_realized == eLazyBoolCalculate)
- {
- if (class_row_t_flags() & RW_REALIZED)
- m_realized = eLazyBoolYes;
- else
- m_realized = eLazyBoolNo;
- }
- return m_realized == eLazyBoolYes;
- }
-
virtual
~ClassDescriptorV2 ()
{
}
-
-protected:
- virtual bool
- CheckPointer (lldb::addr_t value, uint32_t ptr_size) const
- {
- if (ptr_size != 8)
- return true;
- return ((value & 0xFFFF800000000000) == 0);
- }
-
- uint32_t
- class_row_t_flags ()
- {
- if (m_valid && m_objc_class.m_data_ptr)
- {
- ProcessSP process_sp (m_process_wp.lock());
- if (process_sp)
- {
- Error error;
- uint32_t class_row_t_flags = process_sp->ReadUnsignedIntegerFromMemory(m_objc_class.m_data_ptr, sizeof(uint32_t), 0, error);
- if (error.Success())
- return class_row_t_flags;
- else
- m_valid = false;
- }
- }
- return 0;
- }
-
- lldb::addr_t
- get_class_ro_t_ptr ()
- {
- if (m_valid && m_objc_class.m_data_ptr)
- {
- if (IsRealized())
- {
- ProcessSP process_sp (m_process_wp.lock());
- if (process_sp)
- {
- lldb::addr_t class_rw_t_ptr = m_objc_class.m_data_ptr;
-
- Error error;
- const lldb::addr_t class_ro_t_ptr = process_sp->ReadPointerFromMemory (class_rw_t_ptr
- + sizeof(uint32_t) // uint32_t flags
- + sizeof(uint32_t), // uint32_t version
- error);
-
- if (error.Success() && IsPointerValid(class_ro_t_ptr, process_sp->GetAddressByteSize()))
- return class_ro_t_ptr;
- else
- m_valid = false;
- }
- else
- m_valid = false;
- }
- else
- {
- return m_objc_class.m_data_ptr;
- }
- }
- return 0;
- }
-
- void
- Initialize (ObjCLanguageRuntime::ObjCISA objc_class_ptr, lldb::ProcessSP process_sp)
- {
- if (!objc_class_ptr || !process_sp)
- {
- m_valid = false;
- return;
- }
- m_valid = true;
-
-
- m_objc_class_ptr = objc_class_ptr;
-
- size_t ptr_size = process_sp->GetAddressByteSize();
- Error error;
-
- const bool allow_NULLs = false;
- const bool allow_tagged = false;
- const bool check_version_specific = true;
-
- if (!IsPointerValid(m_objc_class_ptr, ptr_size, allow_NULLs, allow_tagged, check_version_specific))
- {
- m_valid = false;
- return;
- }
-
- if (!m_objc_class.Read(process_sp, m_objc_class_ptr))
- {
- m_valid = false;
- return;
- }
-
- // 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_ptr, ptr_size, allow_NULLs, allow_tagged, check_version_specific))
- {
- m_valid = false;
- return;
- }
-
- m_process_wp = process_sp;
- }
private:
static const uint32_t RW_REALIZED = (1 << 31);
@@ -1389,6 +1214,8 @@
lldb::addr_t m_weakIvarLayout_ptr;
lldb::addr_t m_baseProperties_ptr;
+ std::string m_name;
+
bool Read(ProcessSP &process_sp, lldb::addr_t addr)
{
size_t ptr_size = process_sp->GetAddressByteSize();
@@ -1433,6 +1260,17 @@
m_weakIvarLayout_ptr = extractor.GetAddress_unchecked(&cursor);
m_baseProperties_ptr = extractor.GetAddress_unchecked(&cursor);
+ DataBufferHeap name_buf(1024, '\0');
+
+ process_sp->ReadCStringFromMemory(m_name_ptr, (char*)name_buf.GetBytes(), name_buf.GetByteSize(), error);
+
+ if (error.Fail())
+ {
+ return false;
+ }
+
+ m_name.assign((char*)name_buf.GetBytes());
+
return true;
}
};
@@ -1575,17 +1413,65 @@
return true;
}
};
+
+ bool Read_objc_class (lldb::ProcessSP process_sp, 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);
+
+ if (!ret)
+ objc_class.reset();
+
+ 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)
+ {
+ 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);
+ if (!error.Success())
+ return false;
+
+ if (class_row_t_flags & RW_REALIZED)
+ {
+ class_rw.reset(new class_rw_t);
+
+ if (!class_rw->Read(process_sp, objc_class.m_data_ptr))
+ {
+ class_rw.reset();
+ return false;
+ }
+
+ class_ro.reset(new class_ro_t);
+
+ if (!class_ro->Read(process_sp, class_rw->m_ro_ptr))
+ {
+ class_rw.reset();
+ class_ro.reset();
+ return false;
+ }
+ }
+ else
+ {
+ class_ro.reset(new class_ro_t);
+
+ if (!class_ro->Read(process_sp, objc_class.m_data_ptr))
+ {
+ class_ro.reset();
+ return false;
+ }
+ }
+
+ return true;
+ }
- AppleObjCRuntimeV2 &m_runtime; // The runtime, so we can read our metaclass.
- bool m_valid; // Gates whether we trust anything here at all.
- lldb::addr_t m_objc_class_ptr; // The address of the objc_class_t.
- objc_class_t m_objc_class;
-
- // cached information from the class_r[ow]_t
- ConstString m_name;
- uint32_t m_instance_size;
- LazyBool m_realized;
- lldb::ProcessWP m_process_wp;
+ AppleObjCRuntimeV2 &m_runtime; // The runtime, so we can read information lazily.
+ lldb::addr_t m_objc_class_ptr; // The address of the objc_class_t. (I.e., objects of this class type have this as their ISA)
+ ConstString m_name; // May be NULL
};
class ClassDescriptorV2Tagged : public ObjCLanguageRuntime::ClassDescriptor
More information about the lldb-commits
mailing list