[lldb-dev] std::shared_ptr, RTTI, and LLDB

Eli Friedman eli.friedman at gmail.com
Fri Jun 11 20:46:13 PDT 2010


On Fri, Jun 11, 2010 at 5:44 PM, Howard Hinnant <hhinnant at apple.com> wrote:
> On Jun 11, 2010, at 12:20 PM, Chris Lattner wrote:
>
>>
>> On Jun 10, 2010, at 6:06 PM, Greg Clayton wrote:
>>>
>>> Howard, that would be great if you could trim this down for us.
>>
>> Yep, thanks for doing this Howard!
>>
>>> I don't believe we need anyting fancy (no RTTI, no weak_ptr (what I am aware of), no enable_shard_from_this). If you can send me a header that we can include into our Utility folder, I will check it in ASAP and see if we switch over to using it.
>>
>> It would be great to drop this into include/llvm/ADT.  For example, we already have include/llvm/ADT/OwningPtr.h which is a close relation.
>
> Here is a much trimmed down refcounted ptr.  The trimming reduces both dependencies and features.

Okay; I can't test this properly, but the implementation appears to be
sufficient, although there appear to be a couple minor bugs (diff
attached).

In terms of completely turning off RTTI, there are a few more changes
required to eliminate the use of dynamic_cast; besides that, though,
it appears quite feasible (hacky diff attached).

-Eli
-------------- next part --------------
Index: source/Utility/SharingPtr.cpp
===================================================================
--- source/Utility/SharingPtr.cpp	(revision 0)
+++ source/Utility/SharingPtr.cpp	(revision 0)
@@ -0,0 +1,53 @@
+//===---------------------SharingPtr.cpp ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/SharingPtr.h"
+
+namespace llvm {
+
+namespace imp
+{
+
+template <class T>
+inline T
+increment(T& t)
+{
+    return __sync_add_and_fetch(&t, 1);
+}
+
+template <class T>
+inline T
+decrement(T& t)
+{
+    return __sync_add_and_fetch(&t, -1);
+}
+
+shared_count::~shared_count()
+{
+}
+
+void
+shared_count::add_shared()
+{
+    increment(shared_owners_);
+}
+
+void
+shared_count::release_shared()
+{
+    if (decrement(shared_owners_) == -1)
+    {
+        on_zero_shared();
+        delete this;
+    }
+}
+
+} // imp
+
+} // namespace llvm
Index: source/Target/Thread.cpp
===================================================================
--- source/Target/Thread.cpp	(revision 105806)
+++ source/Target/Thread.cpp	(working copy)
@@ -420,7 +420,7 @@
             // special to step over a breakpoint.
             
             ThreadPlan *cur_plan = GetCurrentPlan();
-            ThreadPlanStepOverBreakpoint *step_over_bp = dynamic_cast<ThreadPlanStepOverBreakpoint *> (cur_plan);
+            ThreadPlanStepOverBreakpoint *step_over_bp;// = dynamic_cast<ThreadPlanStepOverBreakpoint *> (cur_plan);
             if (step_over_bp == NULL)
             {
 
Index: source/API/SBThread.cpp
===================================================================
--- source/API/SBThread.cpp	(revision 105806)
+++ source/API/SBThread.cpp	(working copy)
@@ -362,7 +362,7 @@
                                                                                   stop_other_threads);
             if (new_plan)
             {
-                ThreadPlanStepInRange *real_plan = dynamic_cast<ThreadPlanStepInRange *> (new_plan);
+                ThreadPlanStepInRange *real_plan;// = dynamic_cast<ThreadPlanStepInRange *> (new_plan);
                 if (real_plan)
                 {
                     bool avoid_no_debug = true;
Index: include/lldb/Utility/SharingPtr.h
===================================================================
--- include/lldb/Utility/SharingPtr.h	(revision 0)
+++ include/lldb/Utility/SharingPtr.h	(revision 0)
@@ -0,0 +1,254 @@
+//===---------------------SharingPtr.h --------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SHARING_PTR
+#define LLVM_ADT_SHARING_PTR
+
+#include <algorithm>
+#include <memory>
+
+namespace llvm {
+
+namespace imp {
+
+class shared_count
+{
+    shared_count(const shared_count&);
+    shared_count& operator=(const shared_count&);
+
+protected:
+    long shared_owners_;
+    virtual ~shared_count();
+private:
+    virtual void on_zero_shared() = 0;
+
+public:
+    explicit shared_count(long refs = 0)
+        : shared_owners_(refs) {}
+
+    void add_shared();
+    void release_shared();
+    long use_count() const {return shared_owners_ + 1;}
+};
+
+template <class T>
+class shared_ptr_pointer
+    : public shared_count
+{
+    T data_;
+public:
+    shared_ptr_pointer(T p)
+        :  data_(p) {}
+
+private:
+    virtual void on_zero_shared();
+};
+
+template <class T>
+void
+shared_ptr_pointer<T>::on_zero_shared()
+{
+    delete data_;
+}
+
+}  // namespace
+
+template<class T>
+class SharingPtr
+{
+public: 
+    typedef T element_type; 
+private:
+    element_type*      ptr_;
+    imp::shared_count* cntrl_;
+
+    struct nat {int for_bool_;};
+public:
+    SharingPtr();
+    template<class Y> explicit SharingPtr(Y* p);
+    template<class Y> SharingPtr(const SharingPtr<Y>& r, element_type *p); 
+    SharingPtr(const SharingPtr& r);
+    template<class Y>
+        SharingPtr(const SharingPtr<Y>& r);
+
+    ~SharingPtr();
+
+    SharingPtr& operator=(const SharingPtr& r); 
+    template<class Y> SharingPtr& operator=(const SharingPtr<Y>& r); 
+
+    void swap(SharingPtr& r);
+    void reset();
+    template<class Y> void reset(Y* p);
+
+    element_type* get() const {return ptr_;}
+    element_type& operator*() const {return *ptr_;}
+    element_type* operator->() const {return ptr_;}
+    long use_count() const {return cntrl_ ? cntrl_->use_count() : 0;}
+    bool unique() const {return use_count() == 1;}
+    bool empty() const {return cntrl_ == 0;}
+    operator nat*() const {return (nat*)get();}
+
+private:
+
+    template <class U> friend class SharingPtr;
+};
+
+template<class T>
+inline
+SharingPtr<T>::SharingPtr()
+    : ptr_(0),
+      cntrl_(0)
+{
+}
+
+template<class T>
+template<class Y>
+SharingPtr<T>::SharingPtr(Y* p)
+    : ptr_(p)
+{
+    std::auto_ptr<Y> hold(p);
+    typedef imp::shared_ptr_pointer<Y*> _CntrlBlk;
+    cntrl_ = new _CntrlBlk(p);
+    hold.release();
+}
+
+template<class T>
+template<class Y>
+inline
+SharingPtr<T>::SharingPtr(const SharingPtr<Y>& r, element_type *p)
+    : ptr_(p),
+      cntrl_(r.cntrl_)
+{
+    if (cntrl_)
+        cntrl_->add_shared();
+}
+
+template<class T>
+inline
+SharingPtr<T>::SharingPtr(const SharingPtr& r)
+    : ptr_(r.ptr_),
+      cntrl_(r.cntrl_)
+{
+    if (cntrl_)
+        cntrl_->add_shared();
+}
+
+template<class T>
+template<class Y>
+inline
+SharingPtr<T>::SharingPtr(const SharingPtr<Y>& r)
+    : ptr_(r.ptr_),
+      cntrl_(r.cntrl_)
+{
+    if (cntrl_)
+        cntrl_->add_shared();
+}
+
+template<class T>
+SharingPtr<T>::~SharingPtr()
+{
+    if (cntrl_)
+        cntrl_->release_shared();
+}
+
+template<class T>
+inline
+SharingPtr<T>&
+SharingPtr<T>::operator=(const SharingPtr& r)
+{
+    SharingPtr(r).swap(*this);
+    return *this;
+}
+
+template<class T>
+template<class Y>
+inline
+SharingPtr<T>&
+SharingPtr<T>::operator=(const SharingPtr<Y>& r)
+{
+    SharingPtr(r).swap(*this);
+    return *this;
+}
+
+template<class T>
+inline
+void
+SharingPtr<T>::swap(SharingPtr& r)
+{
+    std::swap(ptr_, r.ptr_);
+    std::swap(cntrl_, r.cntrl_);
+}
+
+template<class T>
+inline
+void
+SharingPtr<T>::reset()
+{
+    SharingPtr().swap(*this);
+}
+
+template<class T>
+template<class Y>
+inline
+void
+SharingPtr<T>::reset(Y* p)
+{
+    SharingPtr(p).swap(*this);
+}
+
+template<class T, class U>
+inline
+bool
+operator==(const SharingPtr<T>& __x, const SharingPtr<U>& __y)
+{
+    return __x.get() == __y.get();
+}
+
+template<class T, class U>
+inline
+bool
+operator!=(const SharingPtr<T>& __x, const SharingPtr<U>& __y)
+{
+    return !(__x == __y);
+}
+
+template<class T, class U>
+inline
+bool
+operator<(const SharingPtr<T>& __x, const SharingPtr<U>& __y)
+{
+    return __x.get() < __y.get();
+}
+
+template<class T>
+inline
+void
+swap(SharingPtr<T>& __x, SharingPtr<T>& __y)
+{
+    __x.swap(__y);
+}
+
+template<class T, class U>
+inline
+SharingPtr<T>
+static_pointer_cast(const SharingPtr<U>& r)
+{
+    return SharingPtr<T>(r, static_cast<T*>(r.get()));
+}
+
+template<class T, class U>
+SharingPtr<T>
+const_pointer_cast(const SharingPtr<U>& r)
+{
+    return SharingPtr<T>(r, const_cast<T*>(r.get()));
+}
+
+} // namespace llvm
+
+#endif  // LLVM_ADT_SHARING_PTR
Index: include/lldb/lldb-types.h
===================================================================
--- include/lldb/lldb-types.h	(revision 105863)
+++ include/lldb/lldb-types.h	(working copy)
@@ -26,19 +26,9 @@
 #include <stdbool.h>
 #include <unistd.h>
 
-#ifndef NO_RTTI
+#include "lldb/Utility/SharingPtr.h"
 
 //----------------------------------------------------------------------
-// And source files that may not have RTTI enabled during their
-// compilation will want to do a "#define NO_RTTI" before including the
-// lldb-include.h file.
-//----------------------------------------------------------------------
-
-#include <tr1/memory> // for std::tr1::shared_ptr
-
-#endif
-
-//----------------------------------------------------------------------
 // All host systems must define:
 //  liblldb::condition_t       The native condition type (or a substitute class) for conditions on the host system.
 //  liblldb::mutex_t           The native mutex type for mutex objects on the host system.
@@ -67,7 +57,6 @@
         typedef void *              thread_result_t;            // Host thread result type
         typedef void *              (*thread_func_t)(void *);   // Host thread function type
 
-#ifndef NO_RTTI
         // The template below can be used in a few useful ways:
         //
         //      // Make a single shared pointer a class Foo
@@ -79,9 +68,8 @@
         template<typename _Tp>
         struct SharedPtr
         {
-            typedef std::tr1::shared_ptr<_Tp> Type;
+            typedef llvm::SharingPtr<_Tp> Type;
         };
-#endif
 
 } // namespace lldb
 
-------------- next part --------------
--- /tmp/SharingPtr.h	2010-06-11 20:41:43.325827865 -0700
+++ include/lldb/Utility/SharingPtr.h	2010-06-11 18:29:22.475760680 -0700
@@ -11,6 +11,7 @@
 #define LLVM_ADT_SHARING_PTR
 
 #include <algorithm>
+#include <memory>
 
 namespace llvm {
 
@@ -91,7 +92,7 @@
     long use_count() const {return cntrl_ ? cntrl_->use_count() : 0;}
     bool unique() const {return use_count() == 1;}
     bool empty() const {return cntrl_ == 0;}
-    operator nat*() const {return get() != 0;}
+    operator nat*() const {return (nat*)get();}
 
 private:
 


More information about the lldb-dev mailing list