Bug 1465452 Part 2 - Allow nsISupports subclasses to record/replay their refcount changes, r=froydnj.

--HG--
extra : rebase_source : c67e1da8a34c6b6bf6e40087da85c599f2aaeaf9
This commit is contained in:
Brian Hackett 2018-07-21 14:29:15 +00:00
Родитель 38e406e8a5
Коммит b65c22bb28
1 изменённых файлов: 20 добавлений и 7 удалений

Просмотреть файл

@ -22,6 +22,7 @@
#include <atomic> #include <atomic>
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/Assertions.h" #include "mozilla/Assertions.h"
#include "mozilla/Atomics.h"
#include "mozilla/Compiler.h" #include "mozilla/Compiler.h"
#include "mozilla/Likely.h" #include "mozilla/Likely.h"
#include "mozilla/MacroArgs.h" #include "mozilla/MacroArgs.h"
@ -317,14 +318,15 @@ private:
}; };
namespace mozilla { namespace mozilla {
class ThreadSafeAutoRefCnt template <recordreplay::Behavior Recording>
class ThreadSafeAutoRefCntWithRecording
{ {
public: public:
ThreadSafeAutoRefCnt() : mValue(0) {} ThreadSafeAutoRefCntWithRecording() : mValue(0) {}
explicit ThreadSafeAutoRefCnt(nsrefcnt aValue) : mValue(aValue) {} explicit ThreadSafeAutoRefCntWithRecording(nsrefcnt aValue) : mValue(aValue) {}
ThreadSafeAutoRefCnt(const ThreadSafeAutoRefCnt&) = delete; ThreadSafeAutoRefCntWithRecording(const ThreadSafeAutoRefCntWithRecording&) = delete;
void operator=(const ThreadSafeAutoRefCnt&) = delete; void operator=(const ThreadSafeAutoRefCntWithRecording&) = delete;
// only support prefix increment/decrement // only support prefix increment/decrement
MOZ_ALWAYS_INLINE nsrefcnt operator++() MOZ_ALWAYS_INLINE nsrefcnt operator++()
@ -337,6 +339,7 @@ public:
// first increment on that thread. The necessary memory // first increment on that thread. The necessary memory
// synchronization is done by the mechanism that transfers the // synchronization is done by the mechanism that transfers the
// pointer between threads. // pointer between threads.
detail::AutoRecordAtomicAccess<Recording> record;
return mValue.fetch_add(1, std::memory_order_relaxed) + 1; return mValue.fetch_add(1, std::memory_order_relaxed) + 1;
} }
MOZ_ALWAYS_INLINE nsrefcnt operator--() MOZ_ALWAYS_INLINE nsrefcnt operator--()
@ -345,6 +348,7 @@ public:
// release semantics so that prior writes on this thread are visible // release semantics so that prior writes on this thread are visible
// to the thread that destroys the object when it reads mValue with // to the thread that destroys the object when it reads mValue with
// acquire semantics. // acquire semantics.
detail::AutoRecordAtomicAccess<Recording> record;
nsrefcnt result = mValue.fetch_sub(1, std::memory_order_release) - 1; nsrefcnt result = mValue.fetch_sub(1, std::memory_order_release) - 1;
if (result == 0) { if (result == 0) {
// We're going to destroy the object on this thread, so we need // We're going to destroy the object on this thread, so we need
@ -360,6 +364,7 @@ public:
{ {
// Use release semantics since we're not sure what the caller is // Use release semantics since we're not sure what the caller is
// doing. // doing.
detail::AutoRecordAtomicAccess<Recording> record;
mValue.store(aValue, std::memory_order_release); mValue.store(aValue, std::memory_order_release);
return aValue; return aValue;
} }
@ -368,6 +373,7 @@ public:
{ {
// Use acquire semantics since we're not sure what the caller is // Use acquire semantics since we're not sure what the caller is
// doing. // doing.
detail::AutoRecordAtomicAccess<Recording> record;
return mValue.load(std::memory_order_acquire); return mValue.load(std::memory_order_acquire);
} }
@ -377,6 +383,10 @@ private:
nsrefcnt operator--(int) = delete; nsrefcnt operator--(int) = delete;
std::atomic<nsrefcnt> mValue; std::atomic<nsrefcnt> mValue;
}; };
typedef ThreadSafeAutoRefCntWithRecording<recordreplay::Behavior::DontPreserve>
ThreadSafeAutoRefCnt;
} // namespace mozilla } // namespace mozilla
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -398,7 +408,7 @@ protected: \
NS_DECL_OWNINGTHREAD \ NS_DECL_OWNINGTHREAD \
public: public:
#define NS_DECL_THREADSAFE_ISUPPORTS \ #define NS_DECL_THREADSAFE_ISUPPORTS_WITH_RECORDING(_recording) \
public: \ public: \
NS_IMETHOD QueryInterface(REFNSIID aIID, \ NS_IMETHOD QueryInterface(REFNSIID aIID, \
void** aInstancePtr) override; \ void** aInstancePtr) override; \
@ -406,10 +416,13 @@ public: \
NS_IMETHOD_(MozExternalRefCountType) Release(void) override; \ NS_IMETHOD_(MozExternalRefCountType) Release(void) override; \
typedef mozilla::TrueType HasThreadSafeRefCnt; \ typedef mozilla::TrueType HasThreadSafeRefCnt; \
protected: \ protected: \
::mozilla::ThreadSafeAutoRefCnt mRefCnt; \ ::mozilla::ThreadSafeAutoRefCntWithRecording<_recording> mRefCnt; \
NS_DECL_OWNINGTHREAD \ NS_DECL_OWNINGTHREAD \
public: public:
#define NS_DECL_THREADSAFE_ISUPPORTS \
NS_DECL_THREADSAFE_ISUPPORTS_WITH_RECORDING(mozilla::recordreplay::Behavior::DontPreserve)
#define NS_DECL_CYCLE_COLLECTING_ISUPPORTS \ #define NS_DECL_CYCLE_COLLECTING_ISUPPORTS \
public: \ public: \
NS_IMETHOD QueryInterface(REFNSIID aIID, \ NS_IMETHOD QueryInterface(REFNSIID aIID, \