[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