/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
#ifndef RefCounted_h
#define RefCounted_h
-#include <wtf/Assertions.h>
-#include <wtf/Noncopyable.h>
+#include "Assertions.h"
+#include "FastAllocBase.h"
+#include "Noncopyable.h"
namespace WTF {
// This base class holds the non-template methods and attributes.
// The RefCounted class inherits from it reducing the template bloat
// generated by the compiler (technique called template hoisting).
-class RefCountedBase : Noncopyable {
+class RefCountedBase {
public:
void ref()
{
ASSERT(!m_deletionHasBegun);
+ ASSERT(!m_adoptionIsRequired);
++m_refCount;
}
return m_refCount;
}
+ void relaxAdoptionRequirement()
+ {
+#ifndef NDEBUG
+ ASSERT(!m_deletionHasBegun);
+ ASSERT(m_adoptionIsRequired);
+ m_adoptionIsRequired = false;
+#endif
+ }
+
+ // Helper for generating JIT code. Please do not use for non-JIT purposes.
+ const int* addressOfCount() const
+ {
+ return &m_refCount;
+ }
+
protected:
- RefCountedBase(int initialRefCount)
- : m_refCount(initialRefCount)
+ RefCountedBase()
+ : m_refCount(1)
#ifndef NDEBUG
, m_deletionHasBegun(false)
+ , m_adoptionIsRequired(true)
#endif
{
}
- ~RefCountedBase() {}
+ ~RefCountedBase()
+ {
+ ASSERT(m_deletionHasBegun);
+ ASSERT(!m_adoptionIsRequired);
+ }
// Returns whether the pointer should be freed or not.
bool derefBase()
{
ASSERT(!m_deletionHasBegun);
+ ASSERT(!m_adoptionIsRequired);
+
ASSERT(m_refCount > 0);
if (m_refCount == 1) {
#ifndef NDEBUG
return false;
}
-protected:
+#ifndef NDEBUG
+ bool deletionHasBegun() const
+ {
+ return m_deletionHasBegun;
+ }
+#endif
+
+private:
+ template<typename T> friend class CrossThreadRefCounted;
+
+#ifndef NDEBUG
+ friend void adopted(RefCountedBase*);
+#endif
+
int m_refCount;
#ifndef NDEBUG
bool m_deletionHasBegun;
+ bool m_adoptionIsRequired;
#endif
};
+#ifndef NDEBUG
+
+inline void adopted(RefCountedBase* object)
+{
+ if (!object)
+ return;
+ ASSERT(!object->m_deletionHasBegun);
+ object->m_adoptionIsRequired = false;
+}
-template<class T> class RefCounted : public RefCountedBase {
+#endif
+
+template<typename T> class RefCounted : public RefCountedBase {
+ WTF_MAKE_NONCOPYABLE(RefCounted); WTF_MAKE_FAST_ALLOCATED;
public:
- RefCounted(int initialRefCount = 1)
- : RefCountedBase(initialRefCount)
+ void deref()
{
+ if (derefBase())
+ delete static_cast<T*>(this);
}
+protected:
+ RefCounted() { }
+ ~RefCounted()
+ {
+ }
+};
+
+template<typename T> class RefCountedCustomAllocated : public RefCountedBase {
+ WTF_MAKE_NONCOPYABLE(RefCountedCustomAllocated);
+
+public:
void deref()
{
if (derefBase())
}
protected:
- ~RefCounted() {}
+ ~RefCountedCustomAllocated()
+ {
+ }
};
} // namespace WTF
using WTF::RefCounted;
+using WTF::RefCountedCustomAllocated;
#endif // RefCounted_h