mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1036789 - Convert the third quarter of MFBT to Gecko style. r=Ms2ger.
--HG-- extra : rebase_source : 668cd394806203ddfa34bd4f226335ff26c846b5
This commit is contained in:
parent
cc394c3799
commit
8ea1b7923f
@ -940,7 +940,7 @@ public:
|
|||||||
} else {
|
} else {
|
||||||
SHA1Sum sha1;
|
SHA1Sum sha1;
|
||||||
sha1.update(owner->mData, owner->mLength);
|
sha1.update(owner->mData, owner->mLength);
|
||||||
uint8_t digest[SHA1Sum::HashSize]; // SHA1 digests are 20 bytes long.
|
uint8_t digest[SHA1Sum::kHashSize]; // SHA1 digests are 20 bytes long.
|
||||||
sha1.finish(digest);
|
sha1.finish(digest);
|
||||||
|
|
||||||
nsAutoCString digestString;
|
nsAutoCString digestString;
|
||||||
|
@ -243,9 +243,9 @@ private:
|
|||||||
SHA1Sum sha1;
|
SHA1Sum sha1;
|
||||||
nsCString combined(wsKey + guid);
|
nsCString combined(wsKey + guid);
|
||||||
sha1.update(combined.get(), combined.Length());
|
sha1.update(combined.get(), combined.Length());
|
||||||
uint8_t digest[SHA1Sum::HashSize]; // SHA1 digests are 20 bytes long.
|
uint8_t digest[SHA1Sum::kHashSize]; // SHA1 digests are 20 bytes long.
|
||||||
sha1.finish(digest);
|
sha1.finish(digest);
|
||||||
nsCString newString(reinterpret_cast<char*>(digest), SHA1Sum::HashSize);
|
nsCString newString(reinterpret_cast<char*>(digest), SHA1Sum::kHashSize);
|
||||||
Base64Encode(newString, res);
|
Base64Encode(newString, res);
|
||||||
|
|
||||||
nsCString response("HTTP/1.1 101 Switching Protocols\r\n");
|
nsCString response("HTTP/1.1 101 Switching Protocols\r\n");
|
||||||
|
@ -1016,7 +1016,7 @@ class HashTable : private AllocPolicy
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
friend class mozilla::ReentrancyGuard;
|
friend class mozilla::ReentrancyGuard;
|
||||||
mutable mozilla::DebugOnly<bool> entered;
|
mutable mozilla::DebugOnly<bool> mEntered;
|
||||||
mozilla::DebugOnly<uint64_t> mutationCount;
|
mozilla::DebugOnly<uint64_t> mutationCount;
|
||||||
|
|
||||||
// The default initial capacity is 32 (enough to hold 16 elements), but it
|
// The default initial capacity is 32 (enough to hold 16 elements), but it
|
||||||
@ -1076,7 +1076,7 @@ class HashTable : private AllocPolicy
|
|||||||
gen(0),
|
gen(0),
|
||||||
removedCount(0),
|
removedCount(0),
|
||||||
table(nullptr),
|
table(nullptr),
|
||||||
entered(false),
|
mEntered(false),
|
||||||
mutationCount(0)
|
mutationCount(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -1452,7 +1452,7 @@ class HashTable : private AllocPolicy
|
|||||||
|
|
||||||
void finish()
|
void finish()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!entered);
|
MOZ_ASSERT(!mEntered);
|
||||||
|
|
||||||
if (!table)
|
if (!table)
|
||||||
return;
|
return;
|
||||||
|
@ -422,14 +422,14 @@ class StoreBuffer
|
|||||||
|
|
||||||
bool aboutToOverflow_;
|
bool aboutToOverflow_;
|
||||||
bool enabled_;
|
bool enabled_;
|
||||||
mozilla::DebugOnly<bool> entered; /* For ReentrancyGuard. */
|
mozilla::DebugOnly<bool> mEntered; /* For ReentrancyGuard. */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit StoreBuffer(JSRuntime *rt, const Nursery &nursery)
|
explicit StoreBuffer(JSRuntime *rt, const Nursery &nursery)
|
||||||
: bufferVal(), bufferCell(), bufferSlot(), bufferWholeCell(),
|
: bufferVal(), bufferCell(), bufferSlot(), bufferWholeCell(),
|
||||||
bufferRelocVal(), bufferRelocCell(), bufferGeneric(),
|
bufferRelocVal(), bufferRelocCell(), bufferGeneric(),
|
||||||
runtime_(rt), nursery_(nursery), aboutToOverflow_(false), enabled_(false),
|
runtime_(rt), nursery_(nursery), aboutToOverflow_(false), enabled_(false),
|
||||||
entered(false)
|
mEntered(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,8 +64,8 @@ template<size_t Align>
|
|||||||
struct AlignedElem;
|
struct AlignedElem;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have to specialize this template because GCC doesn't like __attribute__((aligned(foo))) where
|
* We have to specialize this template because GCC doesn't like
|
||||||
* foo is a template parameter.
|
* __attribute__((aligned(foo))) where foo is a template parameter.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -144,7 +144,8 @@ template<typename T>
|
|||||||
inline bool
|
inline bool
|
||||||
IsInRange(T* aPtr, uintptr_t aBegin, uintptr_t aEnd)
|
IsInRange(T* aPtr, uintptr_t aBegin, uintptr_t aEnd)
|
||||||
{
|
{
|
||||||
return IsInRange(aPtr, reinterpret_cast<T*>(aBegin), reinterpret_cast<T*>(aEnd));
|
return IsInRange(aPtr,
|
||||||
|
reinterpret_cast<T*>(aBegin), reinterpret_cast<T*>(aEnd));
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
@ -149,7 +149,8 @@ MOZ_ReportAssertionFailure(const char* aStr, const char* aFilename, int aLine)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static MOZ_ALWAYS_INLINE void
|
static MOZ_ALWAYS_INLINE void
|
||||||
MOZ_ReportCrash(const char* aStr, const char* aFilename, int aLine) MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS
|
MOZ_ReportCrash(const char* aStr, const char* aFilename, int aLine)
|
||||||
|
MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS
|
||||||
{
|
{
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
__android_log_print(ANDROID_LOG_FATAL, "MOZ_CRASH",
|
__android_log_print(ANDROID_LOG_FATAL, "MOZ_CRASH",
|
||||||
@ -254,7 +255,7 @@ __declspec(noreturn) __inline void MOZ_NoReturn() {}
|
|||||||
do { \
|
do { \
|
||||||
MOZ_ReportCrash("" __VA_ARGS__, __FILE__, __LINE__); \
|
MOZ_ReportCrash("" __VA_ARGS__, __FILE__, __LINE__); \
|
||||||
MOZ_REALLY_CRASH(); \
|
MOZ_REALLY_CRASH(); \
|
||||||
} while(0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -384,7 +385,7 @@ void ValidateAssertConditionType()
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
# define MOZ_ASSERT(...) MOZ_RELEASE_ASSERT(__VA_ARGS__)
|
# define MOZ_ASSERT(...) MOZ_RELEASE_ASSERT(__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
# define MOZ_ASSERT(...) do { } while(0)
|
# define MOZ_ASSERT(...) do { } while (0)
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -285,7 +285,8 @@ private:
|
|||||||
* atomic<T*> is not the same as adding X to a T*. Hence the need
|
* atomic<T*> is not the same as adding X to a T*. Hence the need
|
||||||
* for this function to provide the correct addend.
|
* for this function to provide the correct addend.
|
||||||
*/
|
*/
|
||||||
static ptrdiff_t fixupAddend(ptrdiff_t aVal) {
|
static ptrdiff_t fixupAddend(ptrdiff_t aVal)
|
||||||
|
{
|
||||||
#if defined(__clang__) || defined(_MSC_VER)
|
#if defined(__clang__) || defined(_MSC_VER)
|
||||||
return aVal;
|
return aVal;
|
||||||
#elif defined(__GNUC__) && MOZ_GCC_VERSION_AT_LEAST(4, 6, 0) && \
|
#elif defined(__GNUC__) && MOZ_GCC_VERSION_AT_LEAST(4, 6, 0) && \
|
||||||
|
@ -155,9 +155,10 @@
|
|||||||
* template<typename T>
|
* template<typename T>
|
||||||
* class Ptr
|
* class Ptr
|
||||||
* {
|
* {
|
||||||
* T* ptr;
|
* T* mPtr;
|
||||||
* MOZ_EXPLICIT_CONVERSION operator bool() const {
|
* MOZ_EXPLICIT_CONVERSION operator bool() const
|
||||||
* return ptr != nullptr;
|
* {
|
||||||
|
* return mPtr != nullptr;
|
||||||
* }
|
* }
|
||||||
* };
|
* };
|
||||||
*
|
*
|
||||||
@ -206,7 +207,8 @@
|
|||||||
* function does not return. (The function definition does not need to be
|
* function does not return. (The function definition does not need to be
|
||||||
* annotated.)
|
* annotated.)
|
||||||
*
|
*
|
||||||
* MOZ_ReportCrash(const char* s, const char* file, int ln) MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS
|
* MOZ_ReportCrash(const char* s, const char* file, int ln)
|
||||||
|
* MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS
|
||||||
*
|
*
|
||||||
* Some static analyzers, like scan-build from clang, can use this information
|
* Some static analyzers, like scan-build from clang, can use this information
|
||||||
* to eliminate false positives. From the upstream documentation of scan-build:
|
* to eliminate false positives. From the upstream documentation of scan-build:
|
||||||
@ -447,13 +449,13 @@
|
|||||||
*
|
*
|
||||||
* typedef int MOZ_TYPE_ATTRIBUTE MagicInt;
|
* typedef int MOZ_TYPE_ATTRIBUTE MagicInt;
|
||||||
* int MOZ_TYPE_ATTRIBUTE someVariable;
|
* int MOZ_TYPE_ATTRIBUTE someVariable;
|
||||||
* int * MOZ_TYPE_ATTRIBUTE magicPtrInt;
|
* int* MOZ_TYPE_ATTRIBUTE magicPtrInt;
|
||||||
* int MOZ_TYPE_ATTRIBUTE * ptrToMagicInt;
|
* int MOZ_TYPE_ATTRIBUTE* ptrToMagicInt;
|
||||||
*
|
*
|
||||||
* Attributes that apply to statements precede the statement:
|
* Attributes that apply to statements precede the statement:
|
||||||
*
|
*
|
||||||
* MOZ_IF_ATTRIBUTE if (x == 0)
|
* MOZ_IF_ATTRIBUTE if (x == 0)
|
||||||
* MOZ_DO_ATTRIBUTE do { } while(0);
|
* MOZ_DO_ATTRIBUTE do { } while (0);
|
||||||
*
|
*
|
||||||
* Attributes that apply to labels precede the label:
|
* Attributes that apply to labels precede the label:
|
||||||
*
|
*
|
||||||
|
@ -26,8 +26,9 @@ namespace mozilla {
|
|||||||
* Vector<int> sortedInts = ...
|
* Vector<int> sortedInts = ...
|
||||||
*
|
*
|
||||||
* size_t match;
|
* size_t match;
|
||||||
* if (BinarySearch(sortedInts, 0, sortedInts.length(), 13, &match))
|
* if (BinarySearch(sortedInts, 0, sortedInts.length(), 13, &match)) {
|
||||||
* printf("found 13 at %lu\n", match);
|
* printf("found 13 at %lu\n", match);
|
||||||
|
* }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <typename Container, typename T>
|
template <typename Container, typename T>
|
||||||
|
@ -107,9 +107,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some Windows API calls accept BYTE* but require that data actually be WCHAR*.
|
* Some Windows API calls accept BYTE* but require that data actually be
|
||||||
* Supporting this requires explicit operators to support the requisite explicit
|
* WCHAR*. Supporting this requires explicit operators to support the
|
||||||
* casts.
|
* requisite explicit casts.
|
||||||
*/
|
*/
|
||||||
explicit operator const char*() const
|
explicit operator const char*() const
|
||||||
{
|
{
|
||||||
@ -121,7 +121,8 @@ public:
|
|||||||
}
|
}
|
||||||
explicit operator unsigned char*() const
|
explicit operator unsigned char*() const
|
||||||
{
|
{
|
||||||
return const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(mPtr));
|
return
|
||||||
|
const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(mPtr));
|
||||||
}
|
}
|
||||||
explicit operator void*() const
|
explicit operator void*() const
|
||||||
{
|
{
|
||||||
@ -133,7 +134,7 @@ public:
|
|||||||
{
|
{
|
||||||
return mPtr[aIndex];
|
return mPtr[aIndex];
|
||||||
}
|
}
|
||||||
bool operator==(const char16ptr_t &aOther) const
|
bool operator==(const char16ptr_t& aOther) const
|
||||||
{
|
{
|
||||||
return mPtr == aOther.mPtr;
|
return mPtr == aOther.mPtr;
|
||||||
}
|
}
|
||||||
@ -141,7 +142,7 @@ public:
|
|||||||
{
|
{
|
||||||
return mPtr == nullptr;
|
return mPtr == nullptr;
|
||||||
}
|
}
|
||||||
bool operator!=(const char16ptr_t &aOther) const
|
bool operator!=(const char16ptr_t& aOther) const
|
||||||
{
|
{
|
||||||
return mPtr != aOther.mPtr;
|
return mPtr != aOther.mPtr;
|
||||||
}
|
}
|
||||||
@ -153,7 +154,7 @@ public:
|
|||||||
{
|
{
|
||||||
return char16ptr_t(mPtr + aValue);
|
return char16ptr_t(mPtr + aValue);
|
||||||
}
|
}
|
||||||
ptrdiff_t operator-(const char16ptr_t &aOther) const
|
ptrdiff_t operator-(const char16ptr_t& aOther) const
|
||||||
{
|
{
|
||||||
return mPtr - aOther.mPtr;
|
return mPtr - aOther.mPtr;
|
||||||
}
|
}
|
||||||
|
@ -447,7 +447,7 @@ struct NegateImpl<T, true>
|
|||||||
* (aX+aY)/aZ, that doesn't crash if aZ==0, and that reports on error (divide by
|
* (aX+aY)/aZ, that doesn't crash if aZ==0, and that reports on error (divide by
|
||||||
* zero or integer overflow). You could code it as follows:
|
* zero or integer overflow). You could code it as follows:
|
||||||
@code
|
@code
|
||||||
bool computeXPlusYOverZ(int aX, int aY, int aZ, int *aResult)
|
bool computeXPlusYOverZ(int aX, int aY, int aZ, int* aResult)
|
||||||
{
|
{
|
||||||
CheckedInt<int> checkedResult = (CheckedInt<int>(aX) + aY) / aZ;
|
CheckedInt<int> checkedResult = (CheckedInt<int>(aX) + aY) / aZ;
|
||||||
if (checkedResult.isValid()) {
|
if (checkedResult.isValid()) {
|
||||||
|
@ -48,7 +48,7 @@ LZ4::decompress(const char* aSource, char* aDest, size_t aOutputSize)
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
LZ4::decompress(const char* aSource, size_t aInputSize, char* aDest,
|
LZ4::decompress(const char* aSource, size_t aInputSize, char* aDest,
|
||||||
size_t aMaxOutputSize, size_t *aOutputSize)
|
size_t aMaxOutputSize, size_t* aOutputSize)
|
||||||
{
|
{
|
||||||
CheckedInt<int> maxOutputSizeChecked = aMaxOutputSize;
|
CheckedInt<int> maxOutputSizeChecked = aMaxOutputSize;
|
||||||
MOZ_ASSERT(maxOutputSizeChecked.isValid());
|
MOZ_ASSERT(maxOutputSizeChecked.isValid());
|
||||||
|
@ -94,7 +94,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
static MFBT_API bool
|
static MFBT_API bool
|
||||||
decompress(const char* aSource, size_t aInputSize, char* aDest,
|
decompress(const char* aSource, size_t aInputSize, char* aDest,
|
||||||
size_t aMaxOutputSize, size_t *aOutputSize);
|
size_t aMaxOutputSize, size_t* aOutputSize);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Provides the maximum size that LZ4 may output in a "worst case"
|
* Provides the maximum size that LZ4 may output in a "worst case"
|
||||||
|
@ -474,7 +474,8 @@ protected:
|
|||||||
* Likewise, but converts values in place.
|
* Likewise, but converts values in place.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void swapToBigEndianInPlace(T* aPtr, size_t aCount) {
|
static void swapToBigEndianInPlace(T* aPtr, size_t aCount)
|
||||||
|
{
|
||||||
maybeSwapInPlace<ThisEndian, Big>(aPtr, aCount);
|
maybeSwapInPlace<ThisEndian, Big>(aPtr, aCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
/* Implements the C99 <inttypes.h> interface, minus the SCN* format macros. */
|
/* Implements the C99 <inttypes.h> interface, minus the SCN* format macros. */
|
||||||
|
|
||||||
|
@ -82,7 +82,8 @@ struct UnsignedStdintTypeForSize
|
|||||||
template<typename IntegerType>
|
template<typename IntegerType>
|
||||||
struct PositionOfSignBit
|
struct PositionOfSignBit
|
||||||
{
|
{
|
||||||
static_assert(IsIntegral<IntegerType>::value, "PositionOfSignBit is only for integral types");
|
static_assert(IsIntegral<IntegerType>::value,
|
||||||
|
"PositionOfSignBit is only for integral types");
|
||||||
// 8 here should be CHAR_BIT from limits.h, but the world has moved on.
|
// 8 here should be CHAR_BIT from limits.h, but the world has moved on.
|
||||||
static const size_t value = 8 * sizeof(IntegerType) - 1;
|
static const size_t value = 8 * sizeof(IntegerType) - 1;
|
||||||
};
|
};
|
||||||
@ -96,7 +97,8 @@ template<typename IntegerType>
|
|||||||
struct MinValue
|
struct MinValue
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static_assert(IsIntegral<IntegerType>::value, "MinValue is only for integral types");
|
static_assert(IsIntegral<IntegerType>::value,
|
||||||
|
"MinValue is only for integral types");
|
||||||
|
|
||||||
typedef typename MakeUnsigned<IntegerType>::Type UnsignedIntegerType;
|
typedef typename MakeUnsigned<IntegerType>::Type UnsignedIntegerType;
|
||||||
static const size_t PosOfSignBit = PositionOfSignBit<IntegerType>::value;
|
static const size_t PosOfSignBit = PositionOfSignBit<IntegerType>::value;
|
||||||
@ -122,7 +124,8 @@ public:
|
|||||||
template<typename IntegerType>
|
template<typename IntegerType>
|
||||||
struct MaxValue
|
struct MaxValue
|
||||||
{
|
{
|
||||||
static_assert(IsIntegral<IntegerType>::value, "MaxValue is only for integral types");
|
static_assert(IsIntegral<IntegerType>::value,
|
||||||
|
"MaxValue is only for integral types");
|
||||||
|
|
||||||
// Tricksy, but covered by the CheckedInt unit test.
|
// Tricksy, but covered by the CheckedInt unit test.
|
||||||
// Relies on the type of MinValue<IntegerType>::value
|
// Relies on the type of MinValue<IntegerType>::value
|
||||||
|
@ -463,7 +463,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
friend class LinkedListElement<T>;
|
friend class LinkedListElement<T>;
|
||||||
|
|
||||||
void assertContains(const T* aValue) const {
|
void assertContains(const T* aValue) const
|
||||||
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
for (const T* elem = getFirst(); elem; elem = elem->getNext()) {
|
for (const T* elem = getFirst(); elem; elem = elem->getNext()) {
|
||||||
if (elem == aValue) {
|
if (elem == aValue) {
|
||||||
|
@ -102,7 +102,8 @@ template<> struct AbsReturnTypeFixed<int64_t> { typedef uint64_t Type; };
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct AbsReturnType : AbsReturnTypeFixed<T> {};
|
struct AbsReturnType : AbsReturnTypeFixed<T> {};
|
||||||
|
|
||||||
template<> struct AbsReturnType<char> : EnableIf<char(-1) < char(0), unsigned char> {};
|
template<> struct AbsReturnType<char> :
|
||||||
|
EnableIf<char(-1) < char(0), unsigned char> {};
|
||||||
template<> struct AbsReturnType<signed char> { typedef unsigned char Type; };
|
template<> struct AbsReturnType<signed char> { typedef unsigned char Type; };
|
||||||
template<> struct AbsReturnType<short> { typedef unsigned short Type; };
|
template<> struct AbsReturnType<short> { typedef unsigned short Type; };
|
||||||
template<> struct AbsReturnType<int> { typedef unsigned int Type; };
|
template<> struct AbsReturnType<int> { typedef unsigned int Type; };
|
||||||
@ -145,7 +146,8 @@ Abs<long double>(const long double aLongDouble)
|
|||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
#if defined(_WIN32) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
|
#if defined(_WIN32) && (_MSC_VER >= 1300) && \
|
||||||
|
(defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
|
||||||
# define MOZ_BITSCAN_WINDOWS
|
# define MOZ_BITSCAN_WINDOWS
|
||||||
|
|
||||||
# include <intrin.h>
|
# include <intrin.h>
|
||||||
|
@ -12,8 +12,7 @@
|
|||||||
#include "mozilla/Move.h"
|
#include "mozilla/Move.h"
|
||||||
#include "mozilla/TemplateLib.h"
|
#include "mozilla/TemplateLib.h"
|
||||||
|
|
||||||
// For placement new
|
#include <new> // For placement new
|
||||||
#include <new>
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
@ -35,13 +34,15 @@ class MaybeOneOf
|
|||||||
template <class T, class Ignored = void> struct Type2State {};
|
template <class T, class Ignored = void> struct Type2State {};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
T& as() {
|
T& as()
|
||||||
|
{
|
||||||
MOZ_ASSERT(state == Type2State<T>::result);
|
MOZ_ASSERT(state == Type2State<T>::result);
|
||||||
return *(T*)storage.addr();
|
return *(T*)storage.addr();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
const T& as() const {
|
const T& as() const
|
||||||
|
{
|
||||||
MOZ_ASSERT(state == Type2State<T>::result);
|
MOZ_ASSERT(state == Type2State<T>::result);
|
||||||
return *(T*)storage.addr();
|
return *(T*)storage.addr();
|
||||||
}
|
}
|
||||||
@ -124,14 +125,16 @@ private:
|
|||||||
|
|
||||||
template <class T1, class T2>
|
template <class T1, class T2>
|
||||||
template <class Ignored>
|
template <class Ignored>
|
||||||
struct MaybeOneOf<T1, T2>::Type2State<T1, Ignored> {
|
struct MaybeOneOf<T1, T2>::Type2State<T1, Ignored>
|
||||||
|
{
|
||||||
typedef MaybeOneOf<T1, T2> Enclosing;
|
typedef MaybeOneOf<T1, T2> Enclosing;
|
||||||
static const typename Enclosing::State result = Enclosing::SomeT1;
|
static const typename Enclosing::State result = Enclosing::SomeT1;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T1, class T2>
|
template <class T1, class T2>
|
||||||
template <class Ignored>
|
template <class Ignored>
|
||||||
struct MaybeOneOf<T1, T2>::Type2State<T2, Ignored> {
|
struct MaybeOneOf<T1, T2>::Type2State<T2, Ignored>
|
||||||
|
{
|
||||||
typedef MaybeOneOf<T1, T2> Enclosing;
|
typedef MaybeOneOf<T1, T2> Enclosing;
|
||||||
static const typename Enclosing::State result = Enclosing::SomeT2;
|
static const typename Enclosing::State result = Enclosing::SomeT2;
|
||||||
};
|
};
|
||||||
|
@ -63,9 +63,9 @@ void MOZ_EXPORT __asan_unpoison_memory_region(void const volatile *addr, size_t
|
|||||||
VALGRIND_MAKE_MEM_DEFINED((addr), (size))
|
VALGRIND_MAKE_MEM_DEFINED((addr), (size))
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define MOZ_MAKE_MEM_NOACCESS(addr, size) do {} while(0)
|
#define MOZ_MAKE_MEM_NOACCESS(addr, size) do {} while (0)
|
||||||
#define MOZ_MAKE_MEM_UNDEFINED(addr, size) do {} while(0)
|
#define MOZ_MAKE_MEM_UNDEFINED(addr, size) do {} while (0)
|
||||||
#define MOZ_MAKE_MEM_DEFINED(addr, size) do {} while(0)
|
#define MOZ_MAKE_MEM_DEFINED(addr, size) do {} while (0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -144,8 +144,8 @@ namespace mozilla {
|
|||||||
* - First, when a function template takes an argument that is an rvalue
|
* - First, when a function template takes an argument that is an rvalue
|
||||||
* reference to a template argument (like 'XArg&& x' and 'YArg&& y' above),
|
* reference to a template argument (like 'XArg&& x' and 'YArg&& y' above),
|
||||||
* then when the argument is applied to an lvalue, the template argument
|
* then when the argument is applied to an lvalue, the template argument
|
||||||
* resolves to 'T &'; and when it is applied to an rvalue, the template
|
* resolves to 'T&'; and when it is applied to an rvalue, the template
|
||||||
* argument resolves to 'T &&'. Thus, in a call to C::C like:
|
* argument resolves to 'T&&'. Thus, in a call to C::C like:
|
||||||
*
|
*
|
||||||
* X foo(int);
|
* X foo(int);
|
||||||
* Y yy;
|
* Y yy;
|
||||||
|
106
mfbt/Pair.h
106
mfbt/Pair.h
@ -38,84 +38,87 @@ struct PairHelper;
|
|||||||
template<typename A, typename B>
|
template<typename A, typename B>
|
||||||
struct PairHelper<A, B, AsMember, AsMember>
|
struct PairHelper<A, B, AsMember, AsMember>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
template<typename AArg, typename BArg>
|
template<typename AArg, typename BArg>
|
||||||
PairHelper(AArg&& a, BArg&& b)
|
PairHelper(AArg&& aA, BArg&& aB)
|
||||||
: firstA(Forward<AArg>(a)),
|
: mFirstA(Forward<AArg>(aA)),
|
||||||
secondB(Forward<BArg>(b))
|
mSecondB(Forward<BArg>(aB))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
A& first() { return firstA; }
|
A& first() { return mFirstA; }
|
||||||
const A& first() const { return firstA; }
|
const A& first() const { return mFirstA; }
|
||||||
B& second() { return secondB; }
|
B& second() { return mSecondB; }
|
||||||
const B& second() const { return secondB; }
|
const B& second() const { return mSecondB; }
|
||||||
|
|
||||||
void swap(PairHelper& other) {
|
void swap(PairHelper& aOther)
|
||||||
Swap(firstA, other.firstA);
|
{
|
||||||
Swap(secondB, other.secondB);
|
Swap(mFirstA, aOther.mFirstA);
|
||||||
|
Swap(mSecondB, aOther.mSecondB);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
A firstA;
|
A mFirstA;
|
||||||
B secondB;
|
B mSecondB;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename A, typename B>
|
template<typename A, typename B>
|
||||||
struct PairHelper<A, B, AsMember, AsBase> : private B
|
struct PairHelper<A, B, AsMember, AsBase> : private B
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
template<typename AArg, typename BArg>
|
template<typename AArg, typename BArg>
|
||||||
PairHelper(AArg&& a, BArg&& b)
|
PairHelper(AArg&& aA, BArg&& aB)
|
||||||
: B(Forward<BArg>(b)),
|
: B(Forward<BArg>(aB)),
|
||||||
firstA(Forward<AArg>(a))
|
mFirstA(Forward<AArg>(aA))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
A& first() { return firstA; }
|
A& first() { return mFirstA; }
|
||||||
const A& first() const { return firstA; }
|
const A& first() const { return mFirstA; }
|
||||||
B& second() { return *this; }
|
B& second() { return *this; }
|
||||||
const B& second() const { return *this; }
|
const B& second() const { return *this; }
|
||||||
|
|
||||||
void swap(PairHelper& other) {
|
void swap(PairHelper& aOther)
|
||||||
Swap(firstA, other.firstA);
|
{
|
||||||
Swap(static_cast<B&>(*this), static_cast<B&>(other));
|
Swap(mFirstA, aOther.mFirstA);
|
||||||
|
Swap(static_cast<B&>(*this), static_cast<B&>(aOther));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
A firstA;
|
A mFirstA;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename A, typename B>
|
template<typename A, typename B>
|
||||||
struct PairHelper<A, B, AsBase, AsMember> : private A
|
struct PairHelper<A, B, AsBase, AsMember> : private A
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
template<typename AArg, typename BArg>
|
template<typename AArg, typename BArg>
|
||||||
PairHelper(AArg&& a, BArg&& b)
|
PairHelper(AArg&& aA, BArg&& aB)
|
||||||
: A(Forward<AArg>(a)),
|
: A(Forward<AArg>(aA)),
|
||||||
secondB(Forward<BArg>(b))
|
mSecondB(Forward<BArg>(aB))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
A& first() { return *this; }
|
A& first() { return *this; }
|
||||||
const A& first() const { return *this; }
|
const A& first() const { return *this; }
|
||||||
B& second() { return secondB; }
|
B& second() { return mSecondB; }
|
||||||
const B& second() const { return secondB; }
|
const B& second() const { return mSecondB; }
|
||||||
|
|
||||||
void swap(PairHelper& other) {
|
void swap(PairHelper& aOther)
|
||||||
Swap(static_cast<A&>(*this), static_cast<A&>(other));
|
{
|
||||||
Swap(secondB, other.secondB);
|
Swap(static_cast<A&>(*this), static_cast<A&>(aOther));
|
||||||
|
Swap(mSecondB, aOther.mSecondB);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
B secondB;
|
B mSecondB;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename A, typename B>
|
template<typename A, typename B>
|
||||||
struct PairHelper<A, B, AsBase, AsBase> : private A, private B
|
struct PairHelper<A, B, AsBase, AsBase> : private A, private B
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
template<typename AArg, typename BArg>
|
template<typename AArg, typename BArg>
|
||||||
PairHelper(AArg&& a, BArg&& b)
|
PairHelper(AArg&& aA, BArg&& aB)
|
||||||
: A(Forward<AArg>(a)),
|
: A(Forward<AArg>(aA)),
|
||||||
B(Forward<BArg>(b))
|
B(Forward<BArg>(aB))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
A& first() { return static_cast<A&>(*this); }
|
A& first() { return static_cast<A&>(*this); }
|
||||||
@ -123,9 +126,10 @@ struct PairHelper<A, B, AsBase, AsBase> : private A, private B
|
|||||||
B& second() { return static_cast<B&>(*this); }
|
B& second() { return static_cast<B&>(*this); }
|
||||||
const B& second() const { return static_cast<B&>(*this); }
|
const B& second() const { return static_cast<B&>(*this); }
|
||||||
|
|
||||||
void swap(PairHelper& other) {
|
void swap(PairHelper& aOther)
|
||||||
Swap(static_cast<A&>(*this), static_cast<A&>(other));
|
{
|
||||||
Swap(static_cast<B&>(*this), static_cast<B&>(other));
|
Swap(static_cast<A&>(*this), static_cast<A&>(aOther));
|
||||||
|
Swap(static_cast<B&>(*this), static_cast<B&>(aOther));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -150,10 +154,10 @@ struct Pair
|
|||||||
{
|
{
|
||||||
typedef typename detail::PairHelper<A, B> Base;
|
typedef typename detail::PairHelper<A, B> Base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename AArg, typename BArg>
|
template<typename AArg, typename BArg>
|
||||||
Pair(AArg&& a, BArg&& b)
|
Pair(AArg&& aA, BArg&& aB)
|
||||||
: Base(Forward<AArg>(a), Forward<BArg>(b))
|
: Base(Forward<AArg>(aA), Forward<BArg>(aB))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/** The A instance. */
|
/** The A instance. */
|
||||||
@ -162,19 +166,17 @@ struct Pair
|
|||||||
using Base::second;
|
using Base::second;
|
||||||
|
|
||||||
/** Swap this pair with another pair. */
|
/** Swap this pair with another pair. */
|
||||||
void swap(Pair& other) {
|
void swap(Pair& aOther) { Base::swap(aOther); }
|
||||||
Base::swap(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Pair(const Pair&) MOZ_DELETE;
|
Pair(const Pair&) MOZ_DELETE;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename A, class B>
|
template<typename A, class B>
|
||||||
void
|
void
|
||||||
Swap(Pair<A, B>& x, Pair<A, B>& y)
|
Swap(Pair<A, B>& aX, Pair<A, B>& aY)
|
||||||
{
|
{
|
||||||
x.swap(y);
|
aX.swap(aY);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
@ -41,14 +41,14 @@ uintptr_t gMozillaPoisonSize;
|
|||||||
// file.
|
// file.
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static void *
|
static void*
|
||||||
ReserveRegion(uintptr_t aRegion, uintptr_t aSize)
|
ReserveRegion(uintptr_t aRegion, uintptr_t aSize)
|
||||||
{
|
{
|
||||||
return VirtualAlloc((void *)aRegion, aSize, MEM_RESERVE, PAGE_NOACCESS);
|
return VirtualAlloc((void*)aRegion, aSize, MEM_RESERVE, PAGE_NOACCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ReleaseRegion(void *aRegion, uintptr_t aSize)
|
ReleaseRegion(void* aRegion, uintptr_t aSize)
|
||||||
{
|
{
|
||||||
VirtualFree(aRegion, aSize, MEM_RELEASE);
|
VirtualFree(aRegion, aSize, MEM_RELEASE);
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ GetDesiredRegionSize()
|
|||||||
#define RESERVE_FAILED 0
|
#define RESERVE_FAILED 0
|
||||||
|
|
||||||
#elif defined(__OS2__)
|
#elif defined(__OS2__)
|
||||||
static void *
|
static void*
|
||||||
ReserveRegion(uintptr_t aRegion, uintptr_t aSize)
|
ReserveRegion(uintptr_t aRegion, uintptr_t aSize)
|
||||||
{
|
{
|
||||||
// OS/2 doesn't support allocation at an arbitrary address,
|
// OS/2 doesn't support allocation at an arbitrary address,
|
||||||
@ -86,7 +86,7 @@ ReserveRegion(uintptr_t aRegion, uintptr_t aSize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ReleaseRegion(void *aRegion, uintptr_t aSize)
|
ReleaseRegion(void* aRegion, uintptr_t aSize)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -112,7 +112,7 @@ GetDesiredRegionSize()
|
|||||||
|
|
||||||
#include "mozilla/TaggedAnonymousMemory.h"
|
#include "mozilla/TaggedAnonymousMemory.h"
|
||||||
|
|
||||||
static void *
|
static void*
|
||||||
ReserveRegion(uintptr_t aRegion, uintptr_t aSize)
|
ReserveRegion(uintptr_t aRegion, uintptr_t aSize)
|
||||||
{
|
{
|
||||||
return MozTaggedAnonymousMmap(reinterpret_cast<void*>(aRegion), aSize,
|
return MozTaggedAnonymousMmap(reinterpret_cast<void*>(aRegion), aSize,
|
||||||
@ -121,7 +121,7 @@ ReserveRegion(uintptr_t aRegion, uintptr_t aSize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ReleaseRegion(void *aRegion, uintptr_t aSize)
|
ReleaseRegion(void* aRegion, uintptr_t aSize)
|
||||||
{
|
{
|
||||||
munmap(aRegion, aSize);
|
munmap(aRegion, aSize);
|
||||||
}
|
}
|
||||||
@ -147,7 +147,7 @@ GetDesiredRegionSize()
|
|||||||
#endif // system dependencies
|
#endif // system dependencies
|
||||||
|
|
||||||
static_assert(sizeof(uintptr_t) == 4 || sizeof(uintptr_t) == 8, "");
|
static_assert(sizeof(uintptr_t) == 4 || sizeof(uintptr_t) == 8, "");
|
||||||
static_assert(sizeof(uintptr_t) == sizeof(void *), "");
|
static_assert(sizeof(uintptr_t) == sizeof(void*), "");
|
||||||
|
|
||||||
static uintptr_t
|
static uintptr_t
|
||||||
ReservePoisonArea(uintptr_t rgnsize)
|
ReservePoisonArea(uintptr_t rgnsize)
|
||||||
@ -163,8 +163,8 @@ ReservePoisonArea(uintptr_t rgnsize)
|
|||||||
|
|
||||||
// First see if we can allocate the preferred poison address from the OS.
|
// First see if we can allocate the preferred poison address from the OS.
|
||||||
uintptr_t candidate = (0xF0DEAFFF & ~(rgnsize-1));
|
uintptr_t candidate = (0xF0DEAFFF & ~(rgnsize-1));
|
||||||
void *result = ReserveRegion(candidate, rgnsize);
|
void* result = ReserveRegion(candidate, rgnsize);
|
||||||
if (result == (void *)candidate) {
|
if (result == (void*)candidate) {
|
||||||
// success - inaccessible page allocated
|
// success - inaccessible page allocated
|
||||||
return candidate;
|
return candidate;
|
||||||
}
|
}
|
||||||
|
12
mfbt/Range.h
12
mfbt/Range.h
@ -24,20 +24,18 @@ class Range
|
|||||||
typedef void (Range::* ConvertibleToBool)();
|
typedef void (Range::* ConvertibleToBool)();
|
||||||
void nonNull() {}
|
void nonNull() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Range() : mStart(nullptr, 0), mEnd(nullptr, 0) {}
|
Range() : mStart(nullptr, 0), mEnd(nullptr, 0) {}
|
||||||
Range(T* p, size_t len)
|
Range(T* aPtr, size_t aLength)
|
||||||
: mStart(p, p, p + len),
|
: mStart(aPtr, aPtr, aPtr + aLength),
|
||||||
mEnd(p + len, p, p + len)
|
mEnd(aPtr + aLength, aPtr, aPtr + aLength)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
RangedPtr<T> start() const { return mStart; }
|
RangedPtr<T> start() const { return mStart; }
|
||||||
RangedPtr<T> end() const { return mEnd; }
|
RangedPtr<T> end() const { return mEnd; }
|
||||||
size_t length() const { return mEnd - mStart; }
|
size_t length() const { return mEnd - mStart; }
|
||||||
|
|
||||||
T& operator[](size_t offset) const {
|
T& operator[](size_t aOffset) const { return mStart[aOffset]; }
|
||||||
return mStart[offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
operator ConvertibleToBool() const { return mStart ? &Range::nonNull : 0; }
|
operator ConvertibleToBool() const { return mStart ? &Range::nonNull : 0; }
|
||||||
};
|
};
|
||||||
|
198
mfbt/RangedPtr.h
198
mfbt/RangedPtr.h
@ -43,81 +43,83 @@ namespace mozilla {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
class RangedPtr
|
class RangedPtr
|
||||||
{
|
{
|
||||||
T* ptr;
|
T* mPtr;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
T* const rangeStart;
|
T* const mRangeStart;
|
||||||
T* const rangeEnd;
|
T* const mRangeEnd;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef void (RangedPtr::* ConvertibleToBool)();
|
typedef void (RangedPtr::* ConvertibleToBool)();
|
||||||
void nonNull() {}
|
void nonNull() {}
|
||||||
|
|
||||||
void checkSanity() {
|
void checkSanity()
|
||||||
MOZ_ASSERT(rangeStart <= ptr);
|
{
|
||||||
MOZ_ASSERT(ptr <= rangeEnd);
|
MOZ_ASSERT(mRangeStart <= mPtr);
|
||||||
|
MOZ_ASSERT(mPtr <= mRangeEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Creates a new pointer for |p|, restricted to this pointer's range. */
|
/* Creates a new pointer for |aPtr|, restricted to this pointer's range. */
|
||||||
RangedPtr<T> create(T *p) const {
|
RangedPtr<T> create(T* aPtr) const
|
||||||
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
return RangedPtr<T>(p, rangeStart, rangeEnd);
|
return RangedPtr<T>(aPtr, mRangeStart, mRangeEnd);
|
||||||
#else
|
#else
|
||||||
return RangedPtr<T>(p, nullptr, size_t(0));
|
return RangedPtr<T>(aPtr, nullptr, size_t(0));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t asUintptr() const { return uintptr_t(ptr); }
|
uintptr_t asUintptr() const { return reinterpret_cast<uintptr_t>(mPtr); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RangedPtr(T* p, T* start, T* end)
|
RangedPtr(T* aPtr, T* aStart, T* aEnd)
|
||||||
: ptr(p)
|
: mPtr(aPtr)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
, rangeStart(start), rangeEnd(end)
|
, mRangeStart(aStart), mRangeEnd(aEnd)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(rangeStart <= rangeEnd);
|
MOZ_ASSERT(mRangeStart <= mRangeEnd);
|
||||||
checkSanity();
|
checkSanity();
|
||||||
}
|
}
|
||||||
RangedPtr(T* p, T* start, size_t length)
|
RangedPtr(T* aPtr, T* aStart, size_t aLength)
|
||||||
: ptr(p)
|
: mPtr(aPtr)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
, rangeStart(start), rangeEnd(start + length)
|
, mRangeStart(aStart), mRangeEnd(aStart + aLength)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(length <= size_t(-1) / sizeof(T));
|
MOZ_ASSERT(aLength <= size_t(-1) / sizeof(T));
|
||||||
MOZ_ASSERT(uintptr_t(rangeStart) + length * sizeof(T) >= uintptr_t(rangeStart));
|
MOZ_ASSERT(reinterpret_cast<uintptr_t>(mRangeStart) + aLength * sizeof(T) >=
|
||||||
|
reinterpret_cast<uintptr_t>(mRangeStart));
|
||||||
checkSanity();
|
checkSanity();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Equivalent to RangedPtr(p, p, length). */
|
/* Equivalent to RangedPtr(aPtr, aPtr, aLength). */
|
||||||
RangedPtr(T* p, size_t length)
|
RangedPtr(T* aPtr, size_t aLength)
|
||||||
: ptr(p)
|
: mPtr(aPtr)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
, rangeStart(p), rangeEnd(p + length)
|
, mRangeStart(aPtr), mRangeEnd(aPtr + aLength)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(length <= size_t(-1) / sizeof(T));
|
MOZ_ASSERT(aLength <= size_t(-1) / sizeof(T));
|
||||||
MOZ_ASSERT(uintptr_t(rangeStart) + length * sizeof(T) >= uintptr_t(rangeStart));
|
MOZ_ASSERT(reinterpret_cast<uintptr_t>(mRangeStart) + aLength * sizeof(T) >=
|
||||||
|
reinterpret_cast<uintptr_t>(mRangeStart));
|
||||||
checkSanity();
|
checkSanity();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Equivalent to RangedPtr(arr, arr, N). */
|
/* Equivalent to RangedPtr(aArr, aArr, N). */
|
||||||
template<size_t N>
|
template<size_t N>
|
||||||
RangedPtr(T (&arr)[N])
|
RangedPtr(T (&aArr)[N])
|
||||||
: ptr(arr)
|
: mPtr(aArr)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
, rangeStart(arr), rangeEnd(arr + N)
|
, mRangeStart(aArr), mRangeEnd(aArr + N)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
checkSanity();
|
checkSanity();
|
||||||
}
|
}
|
||||||
|
|
||||||
T* get() const {
|
T* get() const { return mPtr; }
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator ConvertibleToBool() const { return ptr ? &RangedPtr::nonNull : 0; }
|
operator ConvertibleToBool() const { return mPtr ? &RangedPtr::nonNull : 0; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* You can only assign one RangedPtr into another if the two pointers have
|
* You can only assign one RangedPtr into another if the two pointers have
|
||||||
@ -129,24 +131,27 @@ class RangedPtr
|
|||||||
* p1 = RangedPtr<char>(arr1 + 1, arr1, arr1 + 2); // works
|
* p1 = RangedPtr<char>(arr1 + 1, arr1, arr1 + 2); // works
|
||||||
* p1 = RangedPtr<char>(arr2, 3); // asserts
|
* p1 = RangedPtr<char>(arr2, 3); // asserts
|
||||||
*/
|
*/
|
||||||
RangedPtr<T>& operator=(const RangedPtr<T>& other) {
|
RangedPtr<T>& operator=(const RangedPtr<T>& aOther)
|
||||||
MOZ_ASSERT(rangeStart == other.rangeStart);
|
{
|
||||||
MOZ_ASSERT(rangeEnd == other.rangeEnd);
|
MOZ_ASSERT(mRangeStart == aOther.mRangeStart);
|
||||||
ptr = other.ptr;
|
MOZ_ASSERT(mRangeEnd == aOther.mRangeEnd);
|
||||||
|
mPtr = aOther.mPtr;
|
||||||
checkSanity();
|
checkSanity();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
RangedPtr<T> operator+(size_t inc) {
|
RangedPtr<T> operator+(size_t aInc)
|
||||||
MOZ_ASSERT(inc <= size_t(-1) / sizeof(T));
|
{
|
||||||
MOZ_ASSERT(asUintptr() + inc * sizeof(T) >= asUintptr());
|
MOZ_ASSERT(aInc <= size_t(-1) / sizeof(T));
|
||||||
return create(ptr + inc);
|
MOZ_ASSERT(asUintptr() + aInc * sizeof(T) >= asUintptr());
|
||||||
|
return create(mPtr + aInc);
|
||||||
}
|
}
|
||||||
|
|
||||||
RangedPtr<T> operator-(size_t dec) {
|
RangedPtr<T> operator-(size_t aDec)
|
||||||
MOZ_ASSERT(dec <= size_t(-1) / sizeof(T));
|
{
|
||||||
MOZ_ASSERT(asUintptr() - dec * sizeof(T) <= asUintptr());
|
MOZ_ASSERT(aDec <= size_t(-1) / sizeof(T));
|
||||||
return create(ptr - dec);
|
MOZ_ASSERT(asUintptr() - aDec * sizeof(T) <= asUintptr());
|
||||||
|
return create(mPtr - aDec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -154,103 +159,122 @@ class RangedPtr
|
|||||||
* within the range specified at creation.
|
* within the range specified at creation.
|
||||||
*/
|
*/
|
||||||
template <typename U>
|
template <typename U>
|
||||||
RangedPtr<T>& operator=(U* p) {
|
RangedPtr<T>& operator=(U* aPtr)
|
||||||
*this = create(p);
|
{
|
||||||
|
*this = create(aPtr);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
RangedPtr<T>& operator=(const RangedPtr<U>& p) {
|
RangedPtr<T>& operator=(const RangedPtr<U>& aPtr)
|
||||||
MOZ_ASSERT(rangeStart <= p.ptr);
|
{
|
||||||
MOZ_ASSERT(p.ptr <= rangeEnd);
|
MOZ_ASSERT(mRangeStart <= aPtr.mPtr);
|
||||||
ptr = p.ptr;
|
MOZ_ASSERT(aPtr.mPtr <= mRangeEnd);
|
||||||
|
mPtr = aPtr.mPtr;
|
||||||
checkSanity();
|
checkSanity();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
RangedPtr<T>& operator++() {
|
RangedPtr<T>& operator++()
|
||||||
|
{
|
||||||
return (*this += 1);
|
return (*this += 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
RangedPtr<T> operator++(int) {
|
RangedPtr<T> operator++(int)
|
||||||
|
{
|
||||||
RangedPtr<T> rcp = *this;
|
RangedPtr<T> rcp = *this;
|
||||||
++*this;
|
++*this;
|
||||||
return rcp;
|
return rcp;
|
||||||
}
|
}
|
||||||
|
|
||||||
RangedPtr<T>& operator--() {
|
RangedPtr<T>& operator--()
|
||||||
|
{
|
||||||
return (*this -= 1);
|
return (*this -= 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
RangedPtr<T> operator--(int) {
|
RangedPtr<T> operator--(int)
|
||||||
|
{
|
||||||
RangedPtr<T> rcp = *this;
|
RangedPtr<T> rcp = *this;
|
||||||
--*this;
|
--*this;
|
||||||
return rcp;
|
return rcp;
|
||||||
}
|
}
|
||||||
|
|
||||||
RangedPtr<T>& operator+=(size_t inc) {
|
RangedPtr<T>& operator+=(size_t aInc)
|
||||||
*this = *this + inc;
|
{
|
||||||
|
*this = *this + aInc;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
RangedPtr<T>& operator-=(size_t dec) {
|
RangedPtr<T>& operator-=(size_t aDec)
|
||||||
*this = *this - dec;
|
{
|
||||||
|
*this = *this - aDec;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
T& operator[](int index) const {
|
T& operator[](int aIndex) const
|
||||||
MOZ_ASSERT(size_t(index > 0 ? index : -index) <= size_t(-1) / sizeof(T));
|
{
|
||||||
return *create(ptr + index);
|
MOZ_ASSERT(size_t(aIndex > 0 ? aIndex : -aIndex) <= size_t(-1) / sizeof(T));
|
||||||
|
return *create(mPtr + aIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
T& operator*() const {
|
T& operator*() const
|
||||||
MOZ_ASSERT(ptr >= rangeStart);
|
{
|
||||||
MOZ_ASSERT(ptr < rangeEnd);
|
MOZ_ASSERT(mPtr >= mRangeStart);
|
||||||
return *ptr;
|
MOZ_ASSERT(mPtr < mRangeEnd);
|
||||||
|
return *mPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
bool operator==(const RangedPtr<U>& other) const {
|
bool operator==(const RangedPtr<U>& aOther) const
|
||||||
return ptr == other.ptr;
|
{
|
||||||
|
return mPtr == aOther.mPtr;
|
||||||
}
|
}
|
||||||
template <typename U>
|
template <typename U>
|
||||||
bool operator!=(const RangedPtr<U>& other) const {
|
bool operator!=(const RangedPtr<U>& aOther) const
|
||||||
return !(*this == other);
|
{
|
||||||
|
return !(*this == aOther);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
bool operator==(const U* u) const {
|
bool operator==(const U* u) const
|
||||||
return ptr == u;
|
{
|
||||||
|
return mPtr == u;
|
||||||
}
|
}
|
||||||
template<typename U>
|
template<typename U>
|
||||||
bool operator!=(const U* u) const {
|
bool operator!=(const U* u) const
|
||||||
|
{
|
||||||
return !(*this == u);
|
return !(*this == u);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
bool operator<(const RangedPtr<U>& other) const {
|
bool operator<(const RangedPtr<U>& aOther) const
|
||||||
return ptr < other.ptr;
|
{
|
||||||
|
return mPtr < aOther.mPtr;
|
||||||
}
|
}
|
||||||
template <typename U>
|
template <typename U>
|
||||||
bool operator<=(const RangedPtr<U>& other) const {
|
bool operator<=(const RangedPtr<U>& aOther) const
|
||||||
return ptr <= other.ptr;
|
{
|
||||||
|
return mPtr <= aOther.mPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
bool operator>(const RangedPtr<U>& other) const {
|
bool operator>(const RangedPtr<U>& aOther) const
|
||||||
return ptr > other.ptr;
|
{
|
||||||
|
return mPtr > aOther.mPtr;
|
||||||
}
|
}
|
||||||
template <typename U>
|
template <typename U>
|
||||||
bool operator>=(const RangedPtr<U>& other) const {
|
bool operator>=(const RangedPtr<U>& aOther) const
|
||||||
return ptr >= other.ptr;
|
{
|
||||||
|
return mPtr >= aOther.mPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t operator-(const RangedPtr<T>& other) const {
|
size_t operator-(const RangedPtr<T>& aOther) const
|
||||||
MOZ_ASSERT(ptr >= other.ptr);
|
{
|
||||||
return PointerRangeSize(other.ptr, ptr);
|
MOZ_ASSERT(mPtr >= aOther.mPtr);
|
||||||
|
return PointerRangeSize(aOther.mPtr, mPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RangedPtr() MOZ_DELETE;
|
RangedPtr() MOZ_DELETE;
|
||||||
T* operator&() MOZ_DELETE;
|
T* operator&() MOZ_DELETE;
|
||||||
};
|
};
|
||||||
|
@ -20,15 +20,15 @@ class ReentrancyGuard
|
|||||||
{
|
{
|
||||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
bool& entered;
|
bool& mEntered;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<class T>
|
template<class T>
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
ReentrancyGuard(T& obj
|
ReentrancyGuard(T& aObj
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||||
: entered(obj.entered)
|
: mEntered(aObj.mEntered)
|
||||||
#else
|
#else
|
||||||
ReentrancyGuard(T&
|
ReentrancyGuard(T&
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||||
@ -36,18 +36,18 @@ class ReentrancyGuard
|
|||||||
{
|
{
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
MOZ_ASSERT(!entered);
|
MOZ_ASSERT(!mEntered);
|
||||||
entered = true;
|
mEntered = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
~ReentrancyGuard()
|
~ReentrancyGuard()
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
entered = false;
|
mEntered = false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ReentrancyGuard(const ReentrancyGuard&) MOZ_DELETE;
|
ReentrancyGuard(const ReentrancyGuard&) MOZ_DELETE;
|
||||||
void operator=(const ReentrancyGuard&) MOZ_DELETE;
|
void operator=(const ReentrancyGuard&) MOZ_DELETE;
|
||||||
};
|
};
|
||||||
|
258
mfbt/RefPtr.h
258
mfbt/RefPtr.h
@ -12,13 +12,15 @@
|
|||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/Atomics.h"
|
#include "mozilla/Atomics.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/NullPtr.h"
|
||||||
#include "mozilla/RefCountType.h"
|
#include "mozilla/RefCountType.h"
|
||||||
#include "mozilla/TypeTraits.h"
|
#include "mozilla/TypeTraits.h"
|
||||||
#if defined(MOZILLA_INTERNAL_API)
|
#if defined(MOZILLA_INTERNAL_API)
|
||||||
#include "nsXPCOM.h"
|
#include "nsXPCOM.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MOZILLA_INTERNAL_API) && (defined(DEBUG) || defined(FORCE_BUILD_REFCNT_LOGGING))
|
#if defined(MOZILLA_INTERNAL_API) && \
|
||||||
|
(defined(DEBUG) || defined(FORCE_BUILD_REFCNT_LOGGING))
|
||||||
#define MOZ_REFCOUNTED_LEAK_CHECKING
|
#define MOZ_REFCOUNTED_LEAK_CHECKING
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -65,12 +67,13 @@ const MozRefCountType DEAD = 0xffffdead;
|
|||||||
#ifdef MOZ_REFCOUNTED_LEAK_CHECKING
|
#ifdef MOZ_REFCOUNTED_LEAK_CHECKING
|
||||||
class RefCountLogger
|
class RefCountLogger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void logAddRef(const void* aPointer, MozRefCountType aRefCount,
|
static void logAddRef(const void* aPointer, MozRefCountType aRefCount,
|
||||||
const char* aTypeName, uint32_t aInstanceSize)
|
const char* aTypeName, uint32_t aInstanceSize)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aRefCount != DEAD);
|
MOZ_ASSERT(aRefCount != DEAD);
|
||||||
NS_LogAddRef(const_cast<void*>(aPointer), aRefCount, aTypeName, aInstanceSize);
|
NS_LogAddRef(const_cast<void*>(aPointer), aRefCount, aTypeName,
|
||||||
|
aInstanceSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void logRelease(const void* aPointer, MozRefCountType aRefCount,
|
static void logRelease(const void* aPointer, MozRefCountType aRefCount,
|
||||||
@ -94,37 +97,37 @@ class RefCounted
|
|||||||
{
|
{
|
||||||
friend class RefPtr<T>;
|
friend class RefPtr<T>;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RefCounted() : refCnt(0) { }
|
RefCounted() : mRefCnt(0) {}
|
||||||
~RefCounted() {
|
~RefCounted() { MOZ_ASSERT(mRefCnt == detail::DEAD); }
|
||||||
MOZ_ASSERT(refCnt == detail::DEAD);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Compatibility with nsRefPtr.
|
// Compatibility with nsRefPtr.
|
||||||
void AddRef() const {
|
void AddRef() const
|
||||||
|
{
|
||||||
// Note: this method must be thread safe for AtomicRefCounted.
|
// Note: this method must be thread safe for AtomicRefCounted.
|
||||||
MOZ_ASSERT(int32_t(refCnt) >= 0);
|
MOZ_ASSERT(int32_t(mRefCnt) >= 0);
|
||||||
#ifndef MOZ_REFCOUNTED_LEAK_CHECKING
|
#ifndef MOZ_REFCOUNTED_LEAK_CHECKING
|
||||||
++refCnt;
|
++mRefCnt;
|
||||||
#else
|
#else
|
||||||
const char* type = static_cast<const T*>(this)->typeName();
|
const char* type = static_cast<const T*>(this)->typeName();
|
||||||
uint32_t size = static_cast<const T*>(this)->typeSize();
|
uint32_t size = static_cast<const T*>(this)->typeSize();
|
||||||
const void* ptr = static_cast<const T*>(this);
|
const void* ptr = static_cast<const T*>(this);
|
||||||
MozRefCountType cnt = ++refCnt;
|
MozRefCountType cnt = ++mRefCnt;
|
||||||
detail::RefCountLogger::logAddRef(ptr, cnt, type, size);
|
detail::RefCountLogger::logAddRef(ptr, cnt, type, size);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Release() const {
|
void Release() const
|
||||||
|
{
|
||||||
// Note: this method must be thread safe for AtomicRefCounted.
|
// Note: this method must be thread safe for AtomicRefCounted.
|
||||||
MOZ_ASSERT(int32_t(refCnt) > 0);
|
MOZ_ASSERT(int32_t(mRefCnt) > 0);
|
||||||
#ifndef MOZ_REFCOUNTED_LEAK_CHECKING
|
#ifndef MOZ_REFCOUNTED_LEAK_CHECKING
|
||||||
MozRefCountType cnt = --refCnt;
|
MozRefCountType cnt = --mRefCnt;
|
||||||
#else
|
#else
|
||||||
const char* type = static_cast<const T*>(this)->typeName();
|
const char* type = static_cast<const T*>(this)->typeName();
|
||||||
const void* ptr = static_cast<const T*>(this);
|
const void* ptr = static_cast<const T*>(this);
|
||||||
MozRefCountType cnt = --refCnt;
|
MozRefCountType cnt = --mRefCnt;
|
||||||
// Note: it's not safe to touch |this| after decrementing the refcount,
|
// Note: it's not safe to touch |this| after decrementing the refcount,
|
||||||
// except for below.
|
// except for below.
|
||||||
detail::RefCountLogger::logRelease(ptr, cnt, type);
|
detail::RefCountLogger::logRelease(ptr, cnt, type);
|
||||||
@ -135,7 +138,7 @@ class RefCounted
|
|||||||
// everything else in the system is accessing this object through
|
// everything else in the system is accessing this object through
|
||||||
// RefPtrs, it's safe to access |this| here.
|
// RefPtrs, it's safe to access |this| here.
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
refCnt = detail::DEAD;
|
mRefCnt = detail::DEAD;
|
||||||
#endif
|
#endif
|
||||||
delete static_cast<const T*>(this);
|
delete static_cast<const T*>(this);
|
||||||
}
|
}
|
||||||
@ -144,14 +147,17 @@ class RefCounted
|
|||||||
// Compatibility with wtf::RefPtr.
|
// Compatibility with wtf::RefPtr.
|
||||||
void ref() { AddRef(); }
|
void ref() { AddRef(); }
|
||||||
void deref() { Release(); }
|
void deref() { Release(); }
|
||||||
MozRefCountType refCount() const { return refCnt; }
|
MozRefCountType refCount() const { return mRefCnt; }
|
||||||
bool hasOneRef() const {
|
bool hasOneRef() const
|
||||||
MOZ_ASSERT(refCnt > 0);
|
{
|
||||||
return refCnt == 1;
|
MOZ_ASSERT(mRefCnt > 0);
|
||||||
|
return mRefCnt == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable typename Conditional<Atomicity == AtomicRefCount, Atomic<MozRefCountType>, MozRefCountType>::Type refCnt;
|
mutable typename Conditional<Atomicity == AtomicRefCount,
|
||||||
|
Atomic<MozRefCountType>,
|
||||||
|
MozRefCountType>::Type mRefCnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef MOZ_REFCOUNTED_LEAK_CHECKING
|
#ifdef MOZ_REFCOUNTED_LEAK_CHECKING
|
||||||
@ -169,13 +175,14 @@ class RefCounted
|
|||||||
const char* typeName() const { return #T; } \
|
const char* typeName() const { return #T; } \
|
||||||
size_t typeSize() const { return sizeof(*this); }
|
size_t typeSize() const { return sizeof(*this); }
|
||||||
|
|
||||||
}
|
} // namespace detail
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class RefCounted : public detail::RefCounted<T, detail::NonAtomicRefCount>
|
class RefCounted : public detail::RefCounted<T, detail::NonAtomicRefCount>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
~RefCounted() {
|
~RefCounted()
|
||||||
|
{
|
||||||
static_assert(IsBaseOf<RefCounted, T>::value,
|
static_assert(IsBaseOf<RefCounted, T>::value,
|
||||||
"T must derive from RefCounted<T>");
|
"T must derive from RefCounted<T>");
|
||||||
}
|
}
|
||||||
@ -191,16 +198,18 @@ namespace external {
|
|||||||
* instead.
|
* instead.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class AtomicRefCounted : public mozilla::detail::RefCounted<T, mozilla::detail::AtomicRefCount>
|
class AtomicRefCounted :
|
||||||
|
public mozilla::detail::RefCounted<T, mozilla::detail::AtomicRefCount>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
~AtomicRefCounted() {
|
~AtomicRefCounted()
|
||||||
|
{
|
||||||
static_assert(IsBaseOf<AtomicRefCounted, T>::value,
|
static_assert(IsBaseOf<AtomicRefCounted, T>::value,
|
||||||
"T must derive from AtomicRefCounted<T>");
|
"T must derive from AtomicRefCounted<T>");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace external
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RefPtr points to a refcounted thing that has AddRef and Release
|
* RefPtr points to a refcounted thing that has AddRef and Release
|
||||||
@ -221,66 +230,76 @@ class RefPtr
|
|||||||
|
|
||||||
struct DontRef {};
|
struct DontRef {};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RefPtr() : ptr(0) { }
|
RefPtr() : mPtr(0) {}
|
||||||
RefPtr(const RefPtr& o) : ptr(ref(o.ptr)) {}
|
RefPtr(const RefPtr& aOther) : mPtr(ref(aOther.mPtr)) {}
|
||||||
MOZ_IMPLICIT RefPtr(const TemporaryRef<T>& o) : ptr(o.drop()) {}
|
MOZ_IMPLICIT RefPtr(const TemporaryRef<T>& aOther) : mPtr(aOther.drop()) {}
|
||||||
MOZ_IMPLICIT RefPtr(T* t) : ptr(ref(t)) {}
|
MOZ_IMPLICIT RefPtr(T* aVal) : mPtr(ref(aVal)) {}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
RefPtr(const RefPtr<U>& o) : ptr(ref(o.get())) {}
|
RefPtr(const RefPtr<U>& aOther) : mPtr(ref(aOther.get())) {}
|
||||||
|
|
||||||
~RefPtr() { unref(ptr); }
|
~RefPtr() { unref(mPtr); }
|
||||||
|
|
||||||
RefPtr& operator=(const RefPtr& o) {
|
RefPtr& operator=(const RefPtr& aOther)
|
||||||
assign(ref(o.ptr));
|
{
|
||||||
|
assign(ref(aOther.mPtr));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
RefPtr& operator=(const TemporaryRef<T>& o) {
|
RefPtr& operator=(const TemporaryRef<T>& aOther)
|
||||||
assign(o.drop());
|
{
|
||||||
|
assign(aOther.drop());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
RefPtr& operator=(T* t) {
|
RefPtr& operator=(T* aVal)
|
||||||
assign(ref(t));
|
{
|
||||||
|
assign(ref(aVal));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
RefPtr& operator=(const RefPtr<U>& o) {
|
RefPtr& operator=(const RefPtr<U>& aOther)
|
||||||
assign(ref(o.get()));
|
{
|
||||||
|
assign(ref(aOther.get()));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
TemporaryRef<T> forget() {
|
TemporaryRef<T> forget()
|
||||||
T* tmp = ptr;
|
{
|
||||||
ptr = 0;
|
T* tmp = mPtr;
|
||||||
|
mPtr = nullptr;
|
||||||
return TemporaryRef<T>(tmp, DontRef());
|
return TemporaryRef<T>(tmp, DontRef());
|
||||||
}
|
}
|
||||||
|
|
||||||
T* get() const { return ptr; }
|
T* get() const { return mPtr; }
|
||||||
operator T*() const { return ptr; }
|
operator T*() const { return mPtr; }
|
||||||
T* operator->() const { return ptr; }
|
T* operator->() const { return mPtr; }
|
||||||
T& operator*() const { return *ptr; }
|
T& operator*() const { return *mPtr; }
|
||||||
template<typename U>
|
template<typename U>
|
||||||
operator TemporaryRef<U>() { return TemporaryRef<U>(ptr); }
|
operator TemporaryRef<U>() { return TemporaryRef<U>(mPtr); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void assign(T* t) {
|
void assign(T* aVal)
|
||||||
unref(ptr);
|
{
|
||||||
ptr = t;
|
unref(mPtr);
|
||||||
|
mPtr = aVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
T* ptr;
|
T* mPtr;
|
||||||
|
|
||||||
static MOZ_ALWAYS_INLINE T* ref(T* t) {
|
static MOZ_ALWAYS_INLINE T* ref(T* aVal)
|
||||||
if (t)
|
{
|
||||||
t->AddRef();
|
if (aVal) {
|
||||||
return t;
|
aVal->AddRef();
|
||||||
|
}
|
||||||
|
return aVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOZ_ALWAYS_INLINE void unref(T* t) {
|
static MOZ_ALWAYS_INLINE void unref(T* aVal)
|
||||||
if (t)
|
{
|
||||||
t->Release();
|
if (aVal) {
|
||||||
|
aVal->Release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -298,25 +317,26 @@ class TemporaryRef
|
|||||||
|
|
||||||
typedef typename RefPtr<T>::DontRef DontRef;
|
typedef typename RefPtr<T>::DontRef DontRef;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MOZ_IMPLICIT TemporaryRef(T* t) : ptr(RefPtr<T>::ref(t)) {}
|
MOZ_IMPLICIT TemporaryRef(T* aVal) : mPtr(RefPtr<T>::ref(aVal)) {}
|
||||||
TemporaryRef(const TemporaryRef& o) : ptr(o.drop()) {}
|
TemporaryRef(const TemporaryRef& aOther) : mPtr(aOther.drop()) {}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
TemporaryRef(const TemporaryRef<U>& o) : ptr(o.drop()) {}
|
TemporaryRef(const TemporaryRef<U>& aOther) : mPtr(aOther.drop()) {}
|
||||||
|
|
||||||
~TemporaryRef() { RefPtr<T>::unref(ptr); }
|
~TemporaryRef() { RefPtr<T>::unref(mPtr); }
|
||||||
|
|
||||||
T* drop() const {
|
T* drop() const
|
||||||
T* tmp = ptr;
|
{
|
||||||
ptr = 0;
|
T* tmp = mPtr;
|
||||||
|
mPtr = nullptr;
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TemporaryRef(T* t, const DontRef&) : ptr(t) {}
|
TemporaryRef(T* aVal, const DontRef&) : mPtr(aVal) {}
|
||||||
|
|
||||||
mutable T* ptr;
|
mutable T* mPtr;
|
||||||
|
|
||||||
TemporaryRef() MOZ_DELETE;
|
TemporaryRef() MOZ_DELETE;
|
||||||
void operator=(const TemporaryRef&) MOZ_DELETE;
|
void operator=(const TemporaryRef&) MOZ_DELETE;
|
||||||
@ -341,19 +361,20 @@ class OutParamRef
|
|||||||
{
|
{
|
||||||
friend OutParamRef byRef<T>(RefPtr<T>&);
|
friend OutParamRef byRef<T>(RefPtr<T>&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~OutParamRef() {
|
~OutParamRef()
|
||||||
RefPtr<T>::unref(refPtr.ptr);
|
{
|
||||||
refPtr.ptr = tmp;
|
RefPtr<T>::unref(mRefPtr.mPtr);
|
||||||
|
mRefPtr.mPtr = mTmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator T**() { return &tmp; }
|
operator T**() { return &mTmp; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit OutParamRef(RefPtr<T>& p) : refPtr(p), tmp(p.get()) {}
|
explicit OutParamRef(RefPtr<T>& p) : mRefPtr(p), mTmp(p.get()) {}
|
||||||
|
|
||||||
RefPtr<T>& refPtr;
|
RefPtr<T>& mRefPtr;
|
||||||
T* tmp;
|
T* mTmp;
|
||||||
|
|
||||||
OutParamRef() MOZ_DELETE;
|
OutParamRef() MOZ_DELETE;
|
||||||
OutParamRef& operator=(const OutParamRef&) MOZ_DELETE;
|
OutParamRef& operator=(const OutParamRef&) MOZ_DELETE;
|
||||||
@ -364,9 +385,9 @@ class OutParamRef
|
|||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
OutParamRef<T>
|
OutParamRef<T>
|
||||||
byRef(RefPtr<T>& ptr)
|
byRef(RefPtr<T>& aPtr)
|
||||||
{
|
{
|
||||||
return OutParamRef<T>(ptr);
|
return OutParamRef<T>(aPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
@ -382,19 +403,20 @@ using namespace mozilla;
|
|||||||
struct Foo : public RefCounted<Foo>
|
struct Foo : public RefCounted<Foo>
|
||||||
{
|
{
|
||||||
MOZ_DECLARE_REFCOUNTED_TYPENAME(Foo)
|
MOZ_DECLARE_REFCOUNTED_TYPENAME(Foo)
|
||||||
Foo() : dead(false) { }
|
Foo() : mDead(false) {}
|
||||||
~Foo() {
|
~Foo()
|
||||||
MOZ_ASSERT(!dead);
|
{
|
||||||
dead = true;
|
MOZ_ASSERT(!mDead);
|
||||||
numDestroyed++;
|
mDead = true;
|
||||||
|
sNumDestroyed++;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dead;
|
bool mDead;
|
||||||
static int numDestroyed;
|
static int sNumDestroyed;
|
||||||
};
|
};
|
||||||
int Foo::numDestroyed;
|
int Foo::sNumDestroyed;
|
||||||
|
|
||||||
struct Bar : public Foo { };
|
struct Bar : public Foo {};
|
||||||
|
|
||||||
TemporaryRef<Foo>
|
TemporaryRef<Foo>
|
||||||
NewFoo()
|
NewFoo()
|
||||||
@ -445,25 +467,25 @@ main(int argc, char** argv)
|
|||||||
// This should blow up
|
// This should blow up
|
||||||
// Foo* f = new Foo(); delete f;
|
// Foo* f = new Foo(); delete f;
|
||||||
|
|
||||||
MOZ_ASSERT(0 == Foo::numDestroyed);
|
MOZ_ASSERT(0 == Foo::sNumDestroyed);
|
||||||
{
|
{
|
||||||
RefPtr<Foo> f = new Foo();
|
RefPtr<Foo> f = new Foo();
|
||||||
MOZ_ASSERT(f->refCount() == 1);
|
MOZ_ASSERT(f->refCount() == 1);
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(1 == Foo::numDestroyed);
|
MOZ_ASSERT(1 == Foo::sNumDestroyed);
|
||||||
|
|
||||||
{
|
{
|
||||||
RefPtr<Foo> f1 = NewFoo();
|
RefPtr<Foo> f1 = NewFoo();
|
||||||
RefPtr<Foo> f2(NewFoo());
|
RefPtr<Foo> f2(NewFoo());
|
||||||
MOZ_ASSERT(1 == Foo::numDestroyed);
|
MOZ_ASSERT(1 == Foo::sNumDestroyed);
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(3 == Foo::numDestroyed);
|
MOZ_ASSERT(3 == Foo::sNumDestroyed);
|
||||||
|
|
||||||
{
|
{
|
||||||
RefPtr<Foo> b = NewBar();
|
RefPtr<Foo> b = NewBar();
|
||||||
MOZ_ASSERT(3 == Foo::numDestroyed);
|
MOZ_ASSERT(3 == Foo::sNumDestroyed);
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(4 == Foo::numDestroyed);
|
MOZ_ASSERT(4 == Foo::sNumDestroyed);
|
||||||
|
|
||||||
{
|
{
|
||||||
RefPtr<Foo> f1;
|
RefPtr<Foo> f1;
|
||||||
@ -471,56 +493,56 @@ main(int argc, char** argv)
|
|||||||
f1 = new Foo();
|
f1 = new Foo();
|
||||||
RefPtr<Foo> f2(f1);
|
RefPtr<Foo> f2(f1);
|
||||||
RefPtr<Foo> f3 = f2;
|
RefPtr<Foo> f3 = f2;
|
||||||
MOZ_ASSERT(4 == Foo::numDestroyed);
|
MOZ_ASSERT(4 == Foo::sNumDestroyed);
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(4 == Foo::numDestroyed);
|
MOZ_ASSERT(4 == Foo::sNumDestroyed);
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(5 == Foo::numDestroyed);
|
MOZ_ASSERT(5 == Foo::sNumDestroyed);
|
||||||
|
|
||||||
{
|
{
|
||||||
RefPtr<Foo> f = new Foo();
|
RefPtr<Foo> f = new Foo();
|
||||||
f.forget();
|
f.forget();
|
||||||
MOZ_ASSERT(6 == Foo::numDestroyed);
|
MOZ_ASSERT(6 == Foo::sNumDestroyed);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
RefPtr<Foo> f = new Foo();
|
RefPtr<Foo> f = new Foo();
|
||||||
GetNewFoo(byRef(f));
|
GetNewFoo(byRef(f));
|
||||||
MOZ_ASSERT(7 == Foo::numDestroyed);
|
MOZ_ASSERT(7 == Foo::sNumDestroyed);
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(8 == Foo::numDestroyed);
|
MOZ_ASSERT(8 == Foo::sNumDestroyed);
|
||||||
|
|
||||||
{
|
{
|
||||||
RefPtr<Foo> f = new Foo();
|
RefPtr<Foo> f = new Foo();
|
||||||
GetPassedFoo(byRef(f));
|
GetPassedFoo(byRef(f));
|
||||||
MOZ_ASSERT(8 == Foo::numDestroyed);
|
MOZ_ASSERT(8 == Foo::sNumDestroyed);
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(9 == Foo::numDestroyed);
|
MOZ_ASSERT(9 == Foo::sNumDestroyed);
|
||||||
|
|
||||||
{
|
{
|
||||||
RefPtr<Foo> f = new Foo();
|
RefPtr<Foo> f = new Foo();
|
||||||
GetNewFoo(&f);
|
GetNewFoo(&f);
|
||||||
MOZ_ASSERT(10 == Foo::numDestroyed);
|
MOZ_ASSERT(10 == Foo::sNumDestroyed);
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(11 == Foo::numDestroyed);
|
MOZ_ASSERT(11 == Foo::sNumDestroyed);
|
||||||
|
|
||||||
{
|
{
|
||||||
RefPtr<Foo> f = new Foo();
|
RefPtr<Foo> f = new Foo();
|
||||||
GetPassedFoo(&f);
|
GetPassedFoo(&f);
|
||||||
MOZ_ASSERT(11 == Foo::numDestroyed);
|
MOZ_ASSERT(11 == Foo::sNumDestroyed);
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(12 == Foo::numDestroyed);
|
MOZ_ASSERT(12 == Foo::sNumDestroyed);
|
||||||
|
|
||||||
{
|
{
|
||||||
RefPtr<Foo> f1 = new Bar();
|
RefPtr<Foo> f1 = new Bar();
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(13 == Foo::numDestroyed);
|
MOZ_ASSERT(13 == Foo::sNumDestroyed);
|
||||||
|
|
||||||
{
|
{
|
||||||
RefPtr<Foo> f = GetNullFoo();
|
RefPtr<Foo> f = GetNullFoo();
|
||||||
MOZ_ASSERT(13 == Foo::numDestroyed);
|
MOZ_ASSERT(13 == Foo::sNumDestroyed);
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(13 == Foo::numDestroyed);
|
MOZ_ASSERT(13 == Foo::sNumDestroyed);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/* -*- Mode: C++; tab-w idth: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
@ -28,13 +29,13 @@ namespace mozilla {
|
|||||||
template<typename T, typename S>
|
template<typename T, typename S>
|
||||||
class RollingMean
|
class RollingMean
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
size_t mInsertIndex;
|
size_t mInsertIndex;
|
||||||
size_t mMaxValues;
|
size_t mMaxValues;
|
||||||
Vector<T> mValues;
|
Vector<T> mValues;
|
||||||
S mTotal;
|
S mTotal;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static_assert(!IsFloatingPoint<T>::value,
|
static_assert(!IsFloatingPoint<T>::value,
|
||||||
"floating-point types are unsupported due to rounding "
|
"floating-point types are unsupported due to rounding "
|
||||||
"errors");
|
"errors");
|
||||||
@ -47,7 +48,8 @@ class RollingMean
|
|||||||
MOZ_ASSERT(aMaxValues > 0);
|
MOZ_ASSERT(aMaxValues > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
RollingMean& operator=(RollingMean&& aOther) {
|
RollingMean& operator=(RollingMean&& aOther)
|
||||||
|
{
|
||||||
MOZ_ASSERT(this != &aOther, "self-assignment is forbidden");
|
MOZ_ASSERT(this != &aOther, "self-assignment is forbidden");
|
||||||
this->~RollingMean();
|
this->~RollingMean();
|
||||||
new(this) RollingMean(aOther.mMaxValues);
|
new(this) RollingMean(aOther.mMaxValues);
|
||||||
@ -60,15 +62,17 @@ class RollingMean
|
|||||||
/**
|
/**
|
||||||
* Insert a value into the rolling mean.
|
* Insert a value into the rolling mean.
|
||||||
*/
|
*/
|
||||||
bool insert(T aValue) {
|
bool insert(T aValue)
|
||||||
|
{
|
||||||
MOZ_ASSERT(mValues.length() <= mMaxValues);
|
MOZ_ASSERT(mValues.length() <= mMaxValues);
|
||||||
|
|
||||||
if (mValues.length() == mMaxValues) {
|
if (mValues.length() == mMaxValues) {
|
||||||
mTotal = mTotal - mValues[mInsertIndex] + aValue;
|
mTotal = mTotal - mValues[mInsertIndex] + aValue;
|
||||||
mValues[mInsertIndex] = aValue;
|
mValues[mInsertIndex] = aValue;
|
||||||
} else {
|
} else {
|
||||||
if (!mValues.append(aValue))
|
if (!mValues.append(aValue)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
mTotal = mTotal + aValue;
|
mTotal = mTotal + aValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,25 +83,29 @@ class RollingMean
|
|||||||
/**
|
/**
|
||||||
* Calculate the rolling mean.
|
* Calculate the rolling mean.
|
||||||
*/
|
*/
|
||||||
T mean() {
|
T mean()
|
||||||
|
{
|
||||||
MOZ_ASSERT(!empty());
|
MOZ_ASSERT(!empty());
|
||||||
return T(mTotal / mValues.length());
|
return T(mTotal / mValues.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty() {
|
bool empty()
|
||||||
|
{
|
||||||
return mValues.empty();
|
return mValues.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove all values from the rolling mean.
|
* Remove all values from the rolling mean.
|
||||||
*/
|
*/
|
||||||
void clear() {
|
void clear()
|
||||||
|
{
|
||||||
mValues.clear();
|
mValues.clear();
|
||||||
mInsertIndex = 0;
|
mInsertIndex = 0;
|
||||||
mTotal = T(0);
|
mTotal = T(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t maxValues() {
|
size_t maxValues()
|
||||||
|
{
|
||||||
return mMaxValues;
|
return mMaxValues;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
@ -12,14 +14,14 @@ using mozilla::NativeEndian;
|
|||||||
using mozilla::SHA1Sum;
|
using mozilla::SHA1Sum;
|
||||||
|
|
||||||
static inline uint32_t
|
static inline uint32_t
|
||||||
SHA_ROTL(uint32_t t, uint32_t n)
|
SHA_ROTL(uint32_t aT, uint32_t aN)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(n < 32);
|
MOZ_ASSERT(aN < 32);
|
||||||
return (t << n) | (t >> (32 - n));
|
return (aT << aN) | (aT >> (32 - aN));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
shaCompress(volatile unsigned* X, const uint32_t* datain);
|
shaCompress(volatile unsigned* aX, const uint32_t* aBuf);
|
||||||
|
|
||||||
#define SHA_F1(X, Y, Z) ((((Y) ^ (Z)) & (X)) ^ (Z))
|
#define SHA_F1(X, Y, Z) ((((Y) ^ (Z)) & (X)) ^ (Z))
|
||||||
#define SHA_F2(X, Y, Z) ((X) ^ (Y) ^ (Z))
|
#define SHA_F2(X, Y, Z) ((X) ^ (Y) ^ (Z))
|
||||||
@ -29,14 +31,14 @@ shaCompress(volatile unsigned* X, const uint32_t* datain);
|
|||||||
#define SHA_MIX(n, a, b, c) XW(n) = SHA_ROTL(XW(a) ^ XW(b) ^ XW(c) ^XW(n), 1)
|
#define SHA_MIX(n, a, b, c) XW(n) = SHA_ROTL(XW(a) ^ XW(b) ^ XW(c) ^XW(n), 1)
|
||||||
|
|
||||||
SHA1Sum::SHA1Sum()
|
SHA1Sum::SHA1Sum()
|
||||||
: size(0), mDone(false)
|
: mSize(0), mDone(false)
|
||||||
{
|
{
|
||||||
// Initialize H with constants from FIPS180-1.
|
// Initialize H with constants from FIPS180-1.
|
||||||
H[0] = 0x67452301L;
|
mH[0] = 0x67452301L;
|
||||||
H[1] = 0xefcdab89L;
|
mH[1] = 0xefcdab89L;
|
||||||
H[2] = 0x98badcfeL;
|
mH[2] = 0x98badcfeL;
|
||||||
H[3] = 0x10325476L;
|
mH[3] = 0x10325476L;
|
||||||
H[4] = 0xc3d2e1f0L;
|
mH[4] = 0xc3d2e1f0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -79,42 +81,46 @@ SHA1Sum::SHA1Sum()
|
|||||||
* SHA: Add data to context.
|
* SHA: Add data to context.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
SHA1Sum::update(const void* dataIn, uint32_t len)
|
SHA1Sum::update(const void* aData, uint32_t aLen)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!mDone, "SHA1Sum can only be used to compute a single hash.");
|
MOZ_ASSERT(!mDone, "SHA1Sum can only be used to compute a single hash.");
|
||||||
|
|
||||||
const uint8_t* data = static_cast<const uint8_t*>(dataIn);
|
const uint8_t* data = static_cast<const uint8_t*>(aData);
|
||||||
|
|
||||||
if (len == 0)
|
if (aLen == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Accumulate the byte count. */
|
/* Accumulate the byte count. */
|
||||||
unsigned int lenB = static_cast<unsigned int>(size) & 63U;
|
unsigned int lenB = static_cast<unsigned int>(mSize) & 63U;
|
||||||
|
|
||||||
size += len;
|
mSize += aLen;
|
||||||
|
|
||||||
/* Read the data into W and process blocks as they get full. */
|
/* Read the data into W and process blocks as they get full. */
|
||||||
unsigned int togo;
|
unsigned int togo;
|
||||||
if (lenB > 0) {
|
if (lenB > 0) {
|
||||||
togo = 64U - lenB;
|
togo = 64U - lenB;
|
||||||
if (len < togo)
|
if (aLen < togo) {
|
||||||
togo = len;
|
togo = aLen;
|
||||||
memcpy(u.b + lenB, data, togo);
|
}
|
||||||
len -= togo;
|
memcpy(mU.mB + lenB, data, togo);
|
||||||
|
aLen -= togo;
|
||||||
data += togo;
|
data += togo;
|
||||||
lenB = (lenB + togo) & 63U;
|
lenB = (lenB + togo) & 63U;
|
||||||
if (!lenB)
|
if (!lenB) {
|
||||||
shaCompress(&H[H2X], u.w);
|
shaCompress(&mH[H2X], mU.mW);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (len >= 64U) {
|
while (aLen >= 64U) {
|
||||||
len -= 64U;
|
aLen -= 64U;
|
||||||
shaCompress(&H[H2X], reinterpret_cast<const uint32_t*>(data));
|
shaCompress(&mH[H2X], reinterpret_cast<const uint32_t*>(data));
|
||||||
data += 64U;
|
data += 64U;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len > 0)
|
if (aLen > 0) {
|
||||||
memcpy(u.b, data, len);
|
memcpy(mU.mB, data, aLen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -122,12 +128,12 @@ SHA1Sum::update(const void* dataIn, uint32_t len)
|
|||||||
* SHA: Generate hash value
|
* SHA: Generate hash value
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
SHA1Sum::finish(SHA1Sum::Hash& hashOut)
|
SHA1Sum::finish(SHA1Sum::Hash& aHashOut)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!mDone, "SHA1Sum can only be used to compute a single hash.");
|
MOZ_ASSERT(!mDone, "SHA1Sum can only be used to compute a single hash.");
|
||||||
|
|
||||||
uint64_t size2 = size;
|
uint64_t size = mSize;
|
||||||
uint32_t lenB = uint32_t(size2) & 63;
|
uint32_t lenB = uint32_t(size) & 63;
|
||||||
|
|
||||||
static const uint8_t bulk_pad[64] =
|
static const uint8_t bulk_pad[64] =
|
||||||
{ 0x80,0,0,0,0,0,0,0,0,0,
|
{ 0x80,0,0,0,0,0,0,0,0,0,
|
||||||
@ -136,21 +142,21 @@ SHA1Sum::finish(SHA1Sum::Hash& hashOut)
|
|||||||
|
|
||||||
/* Pad with a binary 1 (e.g. 0x80), then zeroes, then length in bits. */
|
/* Pad with a binary 1 (e.g. 0x80), then zeroes, then length in bits. */
|
||||||
update(bulk_pad, (((55 + 64) - lenB) & 63) + 1);
|
update(bulk_pad, (((55 + 64) - lenB) & 63) + 1);
|
||||||
MOZ_ASSERT((uint32_t(size) & 63) == 56);
|
MOZ_ASSERT((uint32_t(mSize) & 63) == 56);
|
||||||
|
|
||||||
/* Convert size from bytes to bits. */
|
/* Convert size from bytes to bits. */
|
||||||
size2 <<= 3;
|
size <<= 3;
|
||||||
u.w[14] = NativeEndian::swapToBigEndian(uint32_t(size2 >> 32));
|
mU.mW[14] = NativeEndian::swapToBigEndian(uint32_t(size >> 32));
|
||||||
u.w[15] = NativeEndian::swapToBigEndian(uint32_t(size2));
|
mU.mW[15] = NativeEndian::swapToBigEndian(uint32_t(size));
|
||||||
shaCompress(&H[H2X], u.w);
|
shaCompress(&mH[H2X], mU.mW);
|
||||||
|
|
||||||
/* Output hash. */
|
/* Output hash. */
|
||||||
u.w[0] = NativeEndian::swapToBigEndian(H[0]);
|
mU.mW[0] = NativeEndian::swapToBigEndian(mH[0]);
|
||||||
u.w[1] = NativeEndian::swapToBigEndian(H[1]);
|
mU.mW[1] = NativeEndian::swapToBigEndian(mH[1]);
|
||||||
u.w[2] = NativeEndian::swapToBigEndian(H[2]);
|
mU.mW[2] = NativeEndian::swapToBigEndian(mH[2]);
|
||||||
u.w[3] = NativeEndian::swapToBigEndian(H[3]);
|
mU.mW[3] = NativeEndian::swapToBigEndian(mH[3]);
|
||||||
u.w[4] = NativeEndian::swapToBigEndian(H[4]);
|
mU.mW[4] = NativeEndian::swapToBigEndian(mH[4]);
|
||||||
memcpy(hashOut, u.w, 20);
|
memcpy(aHashOut, mU.mW, 20);
|
||||||
mDone = true;
|
mDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,12 +208,12 @@ SHA1Sum::finish(SHA1Sum::Hash& hashOut)
|
|||||||
* code on AMD64.
|
* code on AMD64.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
shaCompress(volatile unsigned *X, const uint32_t *inbuf)
|
shaCompress(volatile unsigned* aX, const uint32_t* aBuf)
|
||||||
{
|
{
|
||||||
unsigned A, B, C, D, E;
|
unsigned A, B, C, D, E;
|
||||||
|
|
||||||
#define XH(n) X[n - H2X]
|
#define XH(n) aX[n - H2X]
|
||||||
#define XW(n) X[n - W2X]
|
#define XW(n) aX[n - W2X]
|
||||||
|
|
||||||
#define K0 0x5a827999L
|
#define K0 0x5a827999L
|
||||||
#define K1 0x6ed9eba1L
|
#define K1 0x6ed9eba1L
|
||||||
@ -223,7 +229,7 @@ shaCompress(volatile unsigned *X, const uint32_t *inbuf)
|
|||||||
#define SHA_RND4(a, b, c, d, e, n) \
|
#define SHA_RND4(a, b, c, d, e, n) \
|
||||||
a = SHA_ROTL(b ,5) + SHA_F4(c, d, e) + a + XW(n) + K3; c = SHA_ROTL(c, 30)
|
a = SHA_ROTL(b ,5) + SHA_F4(c, d, e) + a + XW(n) + K3; c = SHA_ROTL(c, 30)
|
||||||
|
|
||||||
#define LOAD(n) XW(n) = NativeEndian::swapToBigEndian(inbuf[n])
|
#define LOAD(n) XW(n) = NativeEndian::swapToBigEndian(aBuf[n])
|
||||||
|
|
||||||
A = XH(0);
|
A = XH(0);
|
||||||
B = XH(1);
|
B = XH(1);
|
||||||
|
23
mfbt/SHA1.h
23
mfbt/SHA1.h
@ -36,25 +36,26 @@ namespace mozilla {
|
|||||||
*/
|
*/
|
||||||
class SHA1Sum
|
class SHA1Sum
|
||||||
{
|
{
|
||||||
union {
|
union
|
||||||
uint32_t w[16]; /* input buffer */
|
{
|
||||||
uint8_t b[64];
|
uint32_t mW[16]; /* input buffer */
|
||||||
} u;
|
uint8_t mB[64];
|
||||||
uint64_t size; /* count of hashed bytes. */
|
} mU;
|
||||||
unsigned H[22]; /* 5 state variables, 16 tmp values, 1 extra */
|
uint64_t mSize; /* count of hashed bytes. */
|
||||||
|
unsigned mH[22]; /* 5 state variables, 16 tmp values, 1 extra */
|
||||||
bool mDone;
|
bool mDone;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MFBT_API SHA1Sum();
|
MFBT_API SHA1Sum();
|
||||||
|
|
||||||
static const size_t HashSize = 20;
|
static const size_t kHashSize = 20;
|
||||||
typedef uint8_t Hash[HashSize];
|
typedef uint8_t Hash[kHashSize];
|
||||||
|
|
||||||
/* Add len bytes of dataIn to the data sequence being hashed. */
|
/* Add len bytes of dataIn to the data sequence being hashed. */
|
||||||
MFBT_API void update(const void* dataIn, uint32_t len);
|
MFBT_API void update(const void* aData, uint32_t aLength);
|
||||||
|
|
||||||
/* Compute the final hash of all data into hashOut. */
|
/* Compute the final hash of all data into hashOut. */
|
||||||
MFBT_API void finish(SHA1Sum::Hash& hashOut);
|
MFBT_API void finish(SHA1Sum::Hash& aHashOut);
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace mozilla */
|
} /* namespace mozilla */
|
||||||
|
113
mfbt/Scoped.h
113
mfbt/Scoped.h
@ -64,7 +64,8 @@ namespace mozilla {
|
|||||||
* Scoped is a helper to create RAII wrappers
|
* Scoped is a helper to create RAII wrappers
|
||||||
* Type argument |Traits| is expected to have the following structure:
|
* Type argument |Traits| is expected to have the following structure:
|
||||||
*
|
*
|
||||||
* struct Traits {
|
* struct Traits
|
||||||
|
* {
|
||||||
* // Define the type of the value stored in the wrapper
|
* // Define the type of the value stored in the wrapper
|
||||||
* typedef value_type type;
|
* typedef value_type type;
|
||||||
* // Returns the value corresponding to the uninitialized or freed state
|
* // Returns the value corresponding to the uninitialized or freed state
|
||||||
@ -77,41 +78,39 @@ namespace mozilla {
|
|||||||
template<typename Traits>
|
template<typename Traits>
|
||||||
class Scoped
|
class Scoped
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename Traits::type Resource;
|
typedef typename Traits::type Resource;
|
||||||
|
|
||||||
explicit Scoped(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
|
explicit Scoped(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
|
||||||
: value(Traits::empty())
|
: mValue(Traits::empty())
|
||||||
{
|
{
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit Scoped(const Resource& v
|
explicit Scoped(const Resource& aValue
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||||
: value(v)
|
: mValue(aValue)
|
||||||
{
|
{
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move constructor. */
|
/* Move constructor. */
|
||||||
explicit Scoped(Scoped&& v
|
explicit Scoped(Scoped&& aOther
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||||
: value(Move(v.value))
|
: mValue(Move(aOther.mValue))
|
||||||
{
|
{
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||||
v.value = Traits::empty();
|
aOther.mValue = Traits::empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
~Scoped() {
|
~Scoped() { Traits::release(mValue); }
|
||||||
Traits::release(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constant getter
|
// Constant getter
|
||||||
operator const Resource&() const { return value; }
|
operator const Resource&() const { return mValue; }
|
||||||
const Resource& operator->() const { return value; }
|
const Resource& operator->() const { return mValue; }
|
||||||
const Resource& get() const { return value; }
|
const Resource& get() const { return mValue; }
|
||||||
// Non-constant getter.
|
// Non-constant getter.
|
||||||
Resource& rwget() { return value; }
|
Resource& rwget() { return mValue; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Forget the resource.
|
* Forget the resource.
|
||||||
@ -122,9 +121,10 @@ class Scoped
|
|||||||
*
|
*
|
||||||
* @return The original resource.
|
* @return The original resource.
|
||||||
*/
|
*/
|
||||||
Resource forget() {
|
Resource forget()
|
||||||
Resource tmp = value;
|
{
|
||||||
value = Traits::empty();
|
Resource tmp = mValue;
|
||||||
|
mValue = Traits::empty();
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,14 +133,13 @@ class Scoped
|
|||||||
*
|
*
|
||||||
* If this |Scoped| is currently empty, this method has no effect.
|
* If this |Scoped| is currently empty, this method has no effect.
|
||||||
*/
|
*/
|
||||||
void dispose() {
|
void dispose()
|
||||||
Traits::release(value);
|
{
|
||||||
value = Traits::empty();
|
Traits::release(mValue);
|
||||||
|
mValue = Traits::empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const Resource& other) const {
|
bool operator==(const Resource& aOther) const { return mValue == aOther; }
|
||||||
return value == other;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Replace the resource with another resource.
|
* Replace the resource with another resource.
|
||||||
@ -150,29 +149,30 @@ class Scoped
|
|||||||
*
|
*
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
Scoped& operator=(const Resource& other) {
|
Scoped& operator=(const Resource& aOther) { return reset(aOther); }
|
||||||
return reset(other);
|
|
||||||
}
|
Scoped& reset(const Resource& aOther)
|
||||||
Scoped& reset(const Resource& other) {
|
{
|
||||||
Traits::release(value);
|
Traits::release(mValue);
|
||||||
value = other;
|
mValue = aOther;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move assignment operator. */
|
/* Move assignment operator. */
|
||||||
Scoped& operator=(Scoped&& rhs) {
|
Scoped& operator=(Scoped&& aRhs)
|
||||||
MOZ_ASSERT(&rhs != this, "self-move-assignment not allowed");
|
{
|
||||||
|
MOZ_ASSERT(&aRhs != this, "self-move-assignment not allowed");
|
||||||
this->~Scoped();
|
this->~Scoped();
|
||||||
new(this) Scoped(Move(rhs));
|
new(this) Scoped(Move(aRhs));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit Scoped(const Scoped& value) MOZ_DELETE;
|
explicit Scoped(const Scoped& aValue) MOZ_DELETE;
|
||||||
Scoped& operator=(const Scoped& value) MOZ_DELETE;
|
Scoped& operator=(const Scoped& aValue) MOZ_DELETE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Resource value;
|
Resource mValue;
|
||||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -190,28 +190,30 @@ struct name : public mozilla::Scoped<Traits<Type> > \
|
|||||||
{ \
|
{ \
|
||||||
typedef mozilla::Scoped<Traits<Type> > Super; \
|
typedef mozilla::Scoped<Traits<Type> > Super; \
|
||||||
typedef typename Super::Resource Resource; \
|
typedef typename Super::Resource Resource; \
|
||||||
name& operator=(Resource rhs) { \
|
name& operator=(Resource aRhs) \
|
||||||
Super::operator=(rhs); \
|
{ \
|
||||||
|
Super::operator=(aRhs); \
|
||||||
return *this; \
|
return *this; \
|
||||||
} \
|
} \
|
||||||
name& operator=(name&& rhs) { \
|
name& operator=(name&& aRhs) \
|
||||||
Super::operator=(Move(rhs)); \
|
{ \
|
||||||
|
Super::operator=(Move(aRhs)); \
|
||||||
return *this; \
|
return *this; \
|
||||||
} \
|
} \
|
||||||
explicit name(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) \
|
explicit name(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) \
|
||||||
: Super(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT) \
|
: Super(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT) \
|
||||||
{} \
|
{} \
|
||||||
explicit name(Resource rhs \
|
explicit name(Resource aRhs \
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \
|
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \
|
||||||
: Super(rhs \
|
: Super(aRhs \
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \
|
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \
|
||||||
{} \
|
{} \
|
||||||
explicit name(name&& rhs \
|
explicit name(name&& aRhs \
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \
|
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \
|
||||||
: Super(Move(rhs) \
|
: Super(Move(aRhs) \
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \
|
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \
|
||||||
{} \
|
{} \
|
||||||
private: \
|
private: \
|
||||||
explicit name(name&) MOZ_DELETE; \
|
explicit name(name&) MOZ_DELETE; \
|
||||||
name& operator=(name&) MOZ_DELETE; \
|
name& operator=(name&) MOZ_DELETE; \
|
||||||
};
|
};
|
||||||
@ -228,7 +230,7 @@ struct ScopedFreePtrTraits
|
|||||||
{
|
{
|
||||||
typedef T* type;
|
typedef T* type;
|
||||||
static T* empty() { return nullptr; }
|
static T* empty() { return nullptr; }
|
||||||
static void release(T* ptr) { free(ptr); }
|
static void release(T* aPtr) { free(aPtr); }
|
||||||
};
|
};
|
||||||
SCOPED_TEMPLATE(ScopedFreePtr, ScopedFreePtrTraits)
|
SCOPED_TEMPLATE(ScopedFreePtr, ScopedFreePtrTraits)
|
||||||
|
|
||||||
@ -241,7 +243,7 @@ SCOPED_TEMPLATE(ScopedFreePtr, ScopedFreePtrTraits)
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct ScopedDeletePtrTraits : public ScopedFreePtrTraits<T>
|
struct ScopedDeletePtrTraits : public ScopedFreePtrTraits<T>
|
||||||
{
|
{
|
||||||
static void release(T* ptr) { delete ptr; }
|
static void release(T* aPtr) { delete aPtr; }
|
||||||
};
|
};
|
||||||
SCOPED_TEMPLATE(ScopedDeletePtr, ScopedDeletePtrTraits)
|
SCOPED_TEMPLATE(ScopedDeletePtr, ScopedDeletePtrTraits)
|
||||||
|
|
||||||
@ -254,7 +256,7 @@ SCOPED_TEMPLATE(ScopedDeletePtr, ScopedDeletePtrTraits)
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct ScopedDeleteArrayTraits : public ScopedFreePtrTraits<T>
|
struct ScopedDeleteArrayTraits : public ScopedFreePtrTraits<T>
|
||||||
{
|
{
|
||||||
static void release(T* ptr) { delete [] ptr; }
|
static void release(T* aPtr) { delete [] aPtr; }
|
||||||
};
|
};
|
||||||
SCOPED_TEMPLATE(ScopedDeleteArray, ScopedDeleteArrayTraits)
|
SCOPED_TEMPLATE(ScopedDeleteArray, ScopedDeleteArrayTraits)
|
||||||
|
|
||||||
@ -281,20 +283,21 @@ SCOPED_TEMPLATE(ScopedDeleteArray, ScopedDeleteArrayTraits)
|
|||||||
* } // file is closed with PR_Close here
|
* } // file is closed with PR_Close here
|
||||||
*/
|
*/
|
||||||
#define MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(name, Type, Deleter) \
|
#define MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(name, Type, Deleter) \
|
||||||
template <> inline void TypeSpecificDelete(Type * value) { Deleter(value); } \
|
template <> inline void TypeSpecificDelete(Type* aValue) { Deleter(aValue); } \
|
||||||
typedef ::mozilla::TypeSpecificScopedPointer<Type> name;
|
typedef ::mozilla::TypeSpecificScopedPointer<Type> name;
|
||||||
|
|
||||||
template <typename T> void TypeSpecificDelete(T * value);
|
template <typename T> void TypeSpecificDelete(T* aValue);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct TypeSpecificScopedPointerTraits
|
struct TypeSpecificScopedPointerTraits
|
||||||
{
|
{
|
||||||
typedef T* type;
|
typedef T* type;
|
||||||
static type empty() { return nullptr; }
|
static type empty() { return nullptr; }
|
||||||
static void release(type value)
|
static void release(type aValue)
|
||||||
{
|
{
|
||||||
if (value)
|
if (aValue) {
|
||||||
TypeSpecificDelete(value);
|
TypeSpecificDelete(aValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -82,7 +82,8 @@ struct NBitMask
|
|||||||
// triggers divide-by-zero at compile time: a guaranteed compile error in
|
// triggers divide-by-zero at compile time: a guaranteed compile error in
|
||||||
// C++11, and usually one in C++98. Add this value to |value| to assure
|
// C++11, and usually one in C++98. Add this value to |value| to assure
|
||||||
// its computation.
|
// its computation.
|
||||||
static const size_t checkPrecondition = 0 / size_t(N < BitSize<size_t>::value);
|
static const size_t checkPrecondition =
|
||||||
|
0 / size_t(N < BitSize<size_t>::value);
|
||||||
static const size_t value = (size_t(1) << N) - 1 + checkPrecondition;
|
static const size_t value = (size_t(1) << N) - 1 + checkPrecondition;
|
||||||
};
|
};
|
||||||
template<>
|
template<>
|
||||||
|
@ -78,25 +78,24 @@ class ThreadLocal
|
|||||||
typedef pthread_key_t key_t;
|
typedef pthread_key_t key_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
union Helper {
|
union Helper
|
||||||
void* ptr;
|
{
|
||||||
T value;
|
void* mPtr;
|
||||||
|
T mValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MOZ_WARN_UNUSED_RESULT inline bool init();
|
MOZ_WARN_UNUSED_RESULT inline bool init();
|
||||||
|
|
||||||
inline T get() const;
|
inline T get() const;
|
||||||
|
|
||||||
inline void set(const T value);
|
inline void set(const T aValue);
|
||||||
|
|
||||||
bool initialized() const {
|
bool initialized() const { return mInited; }
|
||||||
return inited;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
key_t key;
|
key_t mKey;
|
||||||
bool inited;
|
bool mInited;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -108,12 +107,12 @@ ThreadLocal<T>::init()
|
|||||||
"a pointer");
|
"a pointer");
|
||||||
MOZ_ASSERT(!initialized());
|
MOZ_ASSERT(!initialized());
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
key = TlsAlloc();
|
mKey = TlsAlloc();
|
||||||
inited = key != 0xFFFFFFFFUL; // TLS_OUT_OF_INDEXES
|
mInited = mKey != 0xFFFFFFFFUL; // TLS_OUT_OF_INDEXES
|
||||||
#else
|
#else
|
||||||
inited = !pthread_key_create(&key, nullptr);
|
mInited = !pthread_key_create(&mKey, nullptr);
|
||||||
#endif
|
#endif
|
||||||
return inited;
|
return mInited;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -123,28 +122,28 @@ ThreadLocal<T>::get() const
|
|||||||
MOZ_ASSERT(initialized());
|
MOZ_ASSERT(initialized());
|
||||||
Helper h;
|
Helper h;
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
h.ptr = TlsGetValue(key);
|
h.mPtr = TlsGetValue(mKey);
|
||||||
#else
|
#else
|
||||||
h.ptr = pthread_getspecific(key);
|
h.mPtr = pthread_getspecific(mKey);
|
||||||
#endif
|
#endif
|
||||||
return h.value;
|
return h.mValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline void
|
inline void
|
||||||
ThreadLocal<T>::set(const T value)
|
ThreadLocal<T>::set(const T aValue)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(initialized());
|
MOZ_ASSERT(initialized());
|
||||||
Helper h;
|
Helper h;
|
||||||
h.value = value;
|
h.mValue = aValue;
|
||||||
bool succeeded;
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
succeeded = TlsSetValue(key, h.ptr);
|
bool succeeded = TlsSetValue(mKey, h.mPtr);
|
||||||
#else
|
#else
|
||||||
succeeded = !pthread_setspecific(key, h.ptr);
|
bool succeeded = !pthread_setspecific(mKey, h.mPtr);
|
||||||
#endif
|
#endif
|
||||||
if (!succeeded)
|
if (!succeeded) {
|
||||||
MOZ_CRASH();
|
MOZ_CRASH();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
@ -20,10 +20,10 @@ namespace mozilla {
|
|||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::string
|
std::string
|
||||||
ToString(const T& t)
|
ToString(const T& aValue)
|
||||||
{
|
{
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
stream << t;
|
stream << aValue;
|
||||||
return stream.str();
|
return stream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,7 +522,7 @@ struct BaseOfTester : IntegralConstant<bool, __is_base_of(Base, Derived)> {};
|
|||||||
template<class Base, class Derived>
|
template<class Base, class Derived>
|
||||||
struct BaseOfHelper
|
struct BaseOfHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
operator Base*() const;
|
operator Base*() const;
|
||||||
operator Derived*();
|
operator Derived*();
|
||||||
};
|
};
|
||||||
@ -530,12 +530,12 @@ struct BaseOfHelper
|
|||||||
template<class Base, class Derived>
|
template<class Base, class Derived>
|
||||||
struct BaseOfTester
|
struct BaseOfTester
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
template<class T>
|
template<class T>
|
||||||
static char test(Derived*, T);
|
static char test(Derived*, T);
|
||||||
static int test(Base*, int);
|
static int test(Base*, int);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const bool value =
|
static const bool value =
|
||||||
sizeof(test(BaseOfHelper<Base, Derived>(), int())) == sizeof(char);
|
sizeof(test(BaseOfHelper<Base, Derived>(), int())) == sizeof(char);
|
||||||
};
|
};
|
||||||
@ -543,12 +543,12 @@ struct BaseOfTester
|
|||||||
template<class Base, class Derived>
|
template<class Base, class Derived>
|
||||||
struct BaseOfTester<Base, const Derived>
|
struct BaseOfTester<Base, const Derived>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
template<class T>
|
template<class T>
|
||||||
static char test(Derived*, T);
|
static char test(Derived*, T);
|
||||||
static int test(Base*, int);
|
static int test(Base*, int);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const bool value =
|
static const bool value =
|
||||||
sizeof(test(BaseOfHelper<Base, Derived>(), int())) == sizeof(char);
|
sizeof(test(BaseOfHelper<Base, Derived>(), int())) == sizeof(char);
|
||||||
};
|
};
|
||||||
@ -588,7 +588,7 @@ namespace detail {
|
|||||||
template<typename From, typename To>
|
template<typename From, typename To>
|
||||||
struct ConvertibleTester
|
struct ConvertibleTester
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static From create();
|
static From create();
|
||||||
|
|
||||||
template<typename From1, typename To1>
|
template<typename From1, typename To1>
|
||||||
@ -597,7 +597,7 @@ struct ConvertibleTester
|
|||||||
template<typename From1, typename To1>
|
template<typename From1, typename To1>
|
||||||
static int test(...);
|
static int test(...);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const bool value =
|
static const bool value =
|
||||||
sizeof(test<From, To>(create())) == sizeof(char);
|
sizeof(test<From, To>(create())) == sizeof(char);
|
||||||
};
|
};
|
||||||
@ -839,7 +839,8 @@ struct MakeSigned<T, CVRemoved, false>
|
|||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct MakeSigned
|
struct MakeSigned
|
||||||
: EnableIf<IsIntegral<T>::value && !IsSame<bool, typename RemoveCV<T>::Type>::value,
|
: EnableIf<IsIntegral<T>::value &&
|
||||||
|
!IsSame<bool, typename RemoveCV<T>::Type>::value,
|
||||||
typename detail::MakeSigned<T>
|
typename detail::MakeSigned<T>
|
||||||
>::Type
|
>::Type
|
||||||
{};
|
{};
|
||||||
@ -907,7 +908,8 @@ struct MakeUnsigned<T, CVRemoved, false>
|
|||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct MakeUnsigned
|
struct MakeUnsigned
|
||||||
: EnableIf<IsIntegral<T>::value && !IsSame<bool, typename RemoveCV<T>::Type>::value,
|
: EnableIf<IsIntegral<T>::value &&
|
||||||
|
!IsSame<bool, typename RemoveCV<T>::Type>::value,
|
||||||
typename detail::MakeUnsigned<T>
|
typename detail::MakeUnsigned<T>
|
||||||
>::Type
|
>::Type
|
||||||
{};
|
{};
|
||||||
|
@ -69,13 +69,12 @@
|
|||||||
* in namespace scope to handle bits that can only be implemented with
|
* in namespace scope to handle bits that can only be implemented with
|
||||||
* namespace-scoped code. For example:
|
* namespace-scoped code. For example:
|
||||||
*
|
*
|
||||||
* class FooBar {
|
* class FooBar
|
||||||
*
|
* {
|
||||||
* MOZ_BEGIN_NESTED_ENUM_CLASS(Enum, int32_t)
|
* MOZ_BEGIN_NESTED_ENUM_CLASS(Enum, int32_t)
|
||||||
* A,
|
* A,
|
||||||
* B = 6
|
* B = 6
|
||||||
* MOZ_END_NESTED_ENUM_CLASS(Enum)
|
* MOZ_END_NESTED_ENUM_CLASS(Enum)
|
||||||
*
|
|
||||||
* };
|
* };
|
||||||
*
|
*
|
||||||
* MOZ_FINISH_NESTED_ENUM_CLASS(FooBar::Enum)
|
* MOZ_FINISH_NESTED_ENUM_CLASS(FooBar::Enum)
|
||||||
@ -253,14 +252,14 @@
|
|||||||
*
|
*
|
||||||
* S<E, E::Bar> s;
|
* S<E, E::Bar> s;
|
||||||
*
|
*
|
||||||
* In this example, the second template parameter to S is meant to be of type T,
|
* In this example, the second template parameter to S is meant to be of type
|
||||||
* but on non-C++11 compilers, type T is a class type, not an integer type, so
|
* T, but on non-C++11 compilers, type T is a class type, not an integer
|
||||||
* it is not accepted as the type of a constant template parameter. One would
|
* type, so it is not accepted as the type of a constant template parameter.
|
||||||
* then want to use MOZ_ENUM_CLASS_ENUM_TYPE(T), but that doesn't work either
|
* One would then want to use MOZ_ENUM_CLASS_ENUM_TYPE(T), but that doesn't
|
||||||
* as T depends on template parameters (more specifically here, T _is_ a template
|
* work either as T depends on template parameters (more specifically here, T
|
||||||
* parameter) so as MOZ_ENUM_CLASS_ENUM_TYPE(T) expands to T::Enum, we are missing
|
* _is_ a template parameter) so as MOZ_ENUM_CLASS_ENUM_TYPE(T) expands to
|
||||||
* the required "typename" keyword. So here, MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE
|
* T::Enum, we are missing the required "typename" keyword. So here,
|
||||||
* is needed.
|
* MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE is needed.
|
||||||
*/
|
*/
|
||||||
# define MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(Name) typename Name::Enum
|
# define MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(Name) typename Name::Enum
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
/* MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS allows using a typed enum as bit flags. */
|
/*
|
||||||
|
* MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS allows using a typed enum as bit flags.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef mozilla_TypedEnumBits_h
|
#ifndef mozilla_TypedEnumBits_h
|
||||||
#define mozilla_TypedEnumBits_h
|
#define mozilla_TypedEnumBits_h
|
||||||
@ -17,22 +19,22 @@ namespace mozilla {
|
|||||||
#define MOZ_CASTABLETYPEDENUMRESULT_BINOP(Op, OtherType, ReturnType) \
|
#define MOZ_CASTABLETYPEDENUMRESULT_BINOP(Op, OtherType, ReturnType) \
|
||||||
template<typename E> \
|
template<typename E> \
|
||||||
MOZ_CONSTEXPR ReturnType \
|
MOZ_CONSTEXPR ReturnType \
|
||||||
operator Op(const OtherType& e, const CastableTypedEnumResult<E>& r) \
|
operator Op(const OtherType& aE, const CastableTypedEnumResult<E>& aR) \
|
||||||
{ \
|
{ \
|
||||||
return ReturnType(e Op OtherType(r)); \
|
return ReturnType(aE Op OtherType(aR)); \
|
||||||
} \
|
} \
|
||||||
template<typename E> \
|
template<typename E> \
|
||||||
MOZ_CONSTEXPR ReturnType \
|
MOZ_CONSTEXPR ReturnType \
|
||||||
operator Op(const CastableTypedEnumResult<E>& r, const OtherType& e) \
|
operator Op(const CastableTypedEnumResult<E>& aR, const OtherType& aE) \
|
||||||
{ \
|
{ \
|
||||||
return ReturnType(OtherType(r) Op e); \
|
return ReturnType(OtherType(aR) Op aE); \
|
||||||
} \
|
} \
|
||||||
template<typename E> \
|
template<typename E> \
|
||||||
MOZ_CONSTEXPR ReturnType \
|
MOZ_CONSTEXPR ReturnType \
|
||||||
operator Op(const CastableTypedEnumResult<E>& r1, \
|
operator Op(const CastableTypedEnumResult<E>& aR1, \
|
||||||
const CastableTypedEnumResult<E>& r2) \
|
const CastableTypedEnumResult<E>& aR2) \
|
||||||
{ \
|
{ \
|
||||||
return ReturnType(OtherType(r1) Op OtherType(r2)); \
|
return ReturnType(OtherType(aR1) Op OtherType(aR2)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_CASTABLETYPEDENUMRESULT_BINOP(|, E, CastableTypedEnumResult<E>)
|
MOZ_CASTABLETYPEDENUMRESULT_BINOP(|, E, CastableTypedEnumResult<E>)
|
||||||
@ -45,18 +47,18 @@ MOZ_CASTABLETYPEDENUMRESULT_BINOP(&&, bool, bool)
|
|||||||
|
|
||||||
template <typename E>
|
template <typename E>
|
||||||
MOZ_CONSTEXPR CastableTypedEnumResult<E>
|
MOZ_CONSTEXPR CastableTypedEnumResult<E>
|
||||||
operator ~(const CastableTypedEnumResult<E>& r)
|
operator ~(const CastableTypedEnumResult<E>& aR)
|
||||||
{
|
{
|
||||||
return CastableTypedEnumResult<E>(~(E(r)));
|
return CastableTypedEnumResult<E>(~(E(aR)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(Op) \
|
#define MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(Op) \
|
||||||
template<typename E> \
|
template<typename E> \
|
||||||
E& \
|
E& \
|
||||||
operator Op(E& r1, \
|
operator Op(E& aR1, \
|
||||||
const CastableTypedEnumResult<E>& r2) \
|
const CastableTypedEnumResult<E>& aR2) \
|
||||||
{ \
|
{ \
|
||||||
return r1 Op E(r2); \
|
return aR1 Op E(aR2); \
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(&=)
|
MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(&=)
|
||||||
@ -72,15 +74,15 @@ MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(^=)
|
|||||||
#define MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(Op, ReturnType) \
|
#define MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(Op, ReturnType) \
|
||||||
template<typename E> \
|
template<typename E> \
|
||||||
MOZ_CONSTEXPR ReturnType \
|
MOZ_CONSTEXPR ReturnType \
|
||||||
operator Op(typename E::Enum e, const CastableTypedEnumResult<E>& r) \
|
operator Op(typename E::Enum aE, const CastableTypedEnumResult<E>& aR) \
|
||||||
{ \
|
{ \
|
||||||
return ReturnType(e Op E(r)); \
|
return ReturnType(aE Op E(aR)); \
|
||||||
} \
|
} \
|
||||||
template<typename E> \
|
template<typename E> \
|
||||||
MOZ_CONSTEXPR ReturnType \
|
MOZ_CONSTEXPR ReturnType \
|
||||||
operator Op(const CastableTypedEnumResult<E>& r, typename E::Enum e) \
|
operator Op(const CastableTypedEnumResult<E>& aR, typename E::Enum aE) \
|
||||||
{ \
|
{ \
|
||||||
return ReturnType(E(r) Op e); \
|
return ReturnType(E(aR) Op aE); \
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(|, CastableTypedEnumResult<E>)
|
MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(|, CastableTypedEnumResult<E>)
|
||||||
|
@ -74,21 +74,19 @@ namespace mozilla {
|
|||||||
template<typename E>
|
template<typename E>
|
||||||
class CastableTypedEnumResult
|
class CastableTypedEnumResult
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
const E mValue;
|
const E mValue;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MOZ_CONSTEXPR CastableTypedEnumResult(E value)
|
explicit MOZ_CONSTEXPR CastableTypedEnumResult(E aValue)
|
||||||
: mValue(value)
|
: mValue(aValue)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
MOZ_CONSTEXPR operator E() const { return mValue; }
|
MOZ_CONSTEXPR operator E() const { return mValue; }
|
||||||
|
|
||||||
template<typename DestinationType>
|
template<typename DestinationType>
|
||||||
MOZ_EXPLICIT_CONVERSION MOZ_CONSTEXPR
|
MOZ_EXPLICIT_CONVERSION MOZ_CONSTEXPR
|
||||||
operator DestinationType() const {
|
operator DestinationType() const { return DestinationType(mValue); }
|
||||||
return DestinationType(mValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_CONSTEXPR bool operator !() const { return !bool(mValue); }
|
MOZ_CONSTEXPR bool operator !() const { return !bool(mValue); }
|
||||||
|
|
||||||
|
755
mfbt/Vector.h
755
mfbt/Vector.h
File diff suppressed because it is too large
Load Diff
102
mfbt/WeakPtr.h
102
mfbt/WeakPtr.h
@ -26,12 +26,13 @@
|
|||||||
*
|
*
|
||||||
* Example of usage:
|
* Example of usage:
|
||||||
*
|
*
|
||||||
* // To have a class C support weak pointers, inherit from SupportsWeakPtr<C>.
|
* // To have a class C support weak pointers, inherit from
|
||||||
|
* // SupportsWeakPtr<C>.
|
||||||
* class C : public SupportsWeakPtr<C>
|
* class C : public SupportsWeakPtr<C>
|
||||||
* {
|
* {
|
||||||
* public:
|
* public:
|
||||||
* MOZ_DECLARE_REFCOUNTED_TYPENAME(C)
|
* MOZ_DECLARE_REFCOUNTED_TYPENAME(C)
|
||||||
* int num;
|
* int mNum;
|
||||||
* void act();
|
* void act();
|
||||||
* };
|
* };
|
||||||
*
|
*
|
||||||
@ -46,7 +47,7 @@
|
|||||||
*
|
*
|
||||||
* // Test a weak pointer for validity before using it.
|
* // Test a weak pointer for validity before using it.
|
||||||
* if (weak) {
|
* if (weak) {
|
||||||
* weak->num = 17;
|
* weak->mNum = 17;
|
||||||
* weak->act();
|
* weak->act();
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
@ -81,46 +82,48 @@ template <typename T, class WeakReference> class SupportsWeakPtrBase;
|
|||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
// This can live beyond the lifetime of the class derived from SupportsWeakPtrBase.
|
// This can live beyond the lifetime of the class derived from
|
||||||
|
// SupportsWeakPtrBase.
|
||||||
template<class T>
|
template<class T>
|
||||||
class WeakReference : public ::mozilla::RefCounted<WeakReference<T> >
|
class WeakReference : public ::mozilla::RefCounted<WeakReference<T> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit WeakReference(T* p) : ptr(p) {}
|
explicit WeakReference(T* p) : mPtr(p) {}
|
||||||
T* get() const {
|
|
||||||
return ptr;
|
T* get() const { return mPtr; }
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MOZ_REFCOUNTED_LEAK_CHECKING
|
#ifdef MOZ_REFCOUNTED_LEAK_CHECKING
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#endif
|
#endif
|
||||||
const char* typeName() const {
|
const char* typeName() const
|
||||||
|
{
|
||||||
static char nameBuffer[1024];
|
static char nameBuffer[1024];
|
||||||
const char* innerType = ptr->typeName();
|
const char* innerType = mPtr->typeName();
|
||||||
// We could do fancier length checks at runtime, but innerType is
|
// We could do fancier length checks at runtime, but innerType is
|
||||||
// controlled by us so we can ensure that this never causes a buffer
|
// controlled by us so we can ensure that this never causes a buffer
|
||||||
// overflow by this assertion.
|
// overflow by this assertion.
|
||||||
MOZ_ASSERT(strlen(innerType) + sizeof("WeakReference<>") < ArrayLength(nameBuffer),
|
MOZ_ASSERT(strlen(innerType) + sizeof("WeakReference<>") <
|
||||||
|
ArrayLength(nameBuffer),
|
||||||
"Exceedingly large type name");
|
"Exceedingly large type name");
|
||||||
snprintf(nameBuffer, ArrayLength(nameBuffer), "WeakReference<%s>", innerType);
|
snprintf(nameBuffer, ArrayLength(nameBuffer), "WeakReference<%s>",
|
||||||
|
innerType);
|
||||||
// This is usually not OK, but here we are returning a pointer to a static
|
// This is usually not OK, but here we are returning a pointer to a static
|
||||||
// buffer which will immediately be used by the caller.
|
// buffer which will immediately be used by the caller.
|
||||||
return nameBuffer;
|
return nameBuffer;
|
||||||
}
|
}
|
||||||
size_t typeSize() const {
|
|
||||||
return sizeof(*this);
|
size_t typeSize() const { return sizeof(*this); }
|
||||||
}
|
|
||||||
#undef snprintf
|
#undef snprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class WeakPtrBase<T, WeakReference<T> >;
|
friend class WeakPtrBase<T, WeakReference<T> >;
|
||||||
friend class SupportsWeakPtrBase<T, WeakReference<T> >;
|
friend class SupportsWeakPtrBase<T, WeakReference<T> >;
|
||||||
void detach() {
|
|
||||||
ptr = nullptr;
|
void detach() { mPtr = nullptr; }
|
||||||
}
|
|
||||||
T* ptr;
|
T* mPtr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
@ -128,22 +131,26 @@ class WeakReference : public ::mozilla::RefCounted<WeakReference<T> >
|
|||||||
template <typename T, class WeakReference>
|
template <typename T, class WeakReference>
|
||||||
class SupportsWeakPtrBase
|
class SupportsWeakPtrBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WeakPtrBase<T, WeakReference> asWeakPtr() {
|
WeakPtrBase<T, WeakReference> asWeakPtr()
|
||||||
if (!weakRef)
|
{
|
||||||
|
if (!weakRef) {
|
||||||
weakRef = new WeakReference(static_cast<T*>(this));
|
weakRef = new WeakReference(static_cast<T*>(this));
|
||||||
|
}
|
||||||
return WeakPtrBase<T, WeakReference>(weakRef);
|
return WeakPtrBase<T, WeakReference>(weakRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~SupportsWeakPtrBase() {
|
~SupportsWeakPtrBase()
|
||||||
|
{
|
||||||
static_assert(IsBaseOf<SupportsWeakPtrBase<T, WeakReference>, T>::value,
|
static_assert(IsBaseOf<SupportsWeakPtrBase<T, WeakReference>, T>::value,
|
||||||
"T must derive from SupportsWeakPtrBase<T, WeakReference>");
|
"T must derive from SupportsWeakPtrBase<T, WeakReference>");
|
||||||
if (weakRef)
|
if (weakRef) {
|
||||||
weakRef->detach();
|
weakRef->detach();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class WeakPtrBase<T, WeakReference>;
|
friend class WeakPtrBase<T, WeakReference>;
|
||||||
|
|
||||||
RefPtr<WeakReference> weakRef;
|
RefPtr<WeakReference> weakRef;
|
||||||
@ -157,41 +164,36 @@ class SupportsWeakPtr : public SupportsWeakPtrBase<T, detail::WeakReference<T> >
|
|||||||
template <typename T, class WeakReference>
|
template <typename T, class WeakReference>
|
||||||
class WeakPtrBase
|
class WeakPtrBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WeakPtrBase(const WeakPtrBase<T, WeakReference>& o) : ref(o.ref) {}
|
WeakPtrBase(const WeakPtrBase<T, WeakReference>& aOther)
|
||||||
// Ensure that ref is dereferenceable in the uninitialized state
|
: mRef(aOther.mRef)
|
||||||
WeakPtrBase() : ref(new WeakReference(nullptr)) {}
|
{}
|
||||||
|
|
||||||
operator T*() const {
|
// Ensure that mRef is dereferenceable in the uninitialized state.
|
||||||
return ref->get();
|
WeakPtrBase() : mRef(new WeakReference(nullptr)) {}
|
||||||
}
|
|
||||||
T& operator*() const {
|
|
||||||
return *ref->get();
|
|
||||||
}
|
|
||||||
|
|
||||||
T* operator->() const {
|
operator T*() const { return mRef->get(); }
|
||||||
return ref->get();
|
T& operator*() const { return *mRef->get(); }
|
||||||
}
|
|
||||||
|
|
||||||
T* get() const {
|
T* operator->() const { return mRef->get(); }
|
||||||
return ref->get();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
T* get() const { return mRef->get(); }
|
||||||
|
|
||||||
|
private:
|
||||||
friend class SupportsWeakPtrBase<T, WeakReference>;
|
friend class SupportsWeakPtrBase<T, WeakReference>;
|
||||||
|
|
||||||
explicit WeakPtrBase(const RefPtr<WeakReference> &o) : ref(o) {}
|
explicit WeakPtrBase(const RefPtr<WeakReference> &aOther) : mRef(aOther) {}
|
||||||
|
|
||||||
RefPtr<WeakReference> ref;
|
RefPtr<WeakReference> mRef;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class WeakPtr : public WeakPtrBase<T, detail::WeakReference<T> >
|
class WeakPtr : public WeakPtrBase<T, detail::WeakReference<T> >
|
||||||
{
|
{
|
||||||
typedef WeakPtrBase<T, detail::WeakReference<T> > Base;
|
typedef WeakPtrBase<T, detail::WeakReference<T> > Base;
|
||||||
public:
|
public:
|
||||||
WeakPtr(const WeakPtr<T>& o) : Base(o) {}
|
WeakPtr(const WeakPtr<T>& aOther) : Base(aOther) {}
|
||||||
MOZ_IMPLICIT WeakPtr(const Base& o) : Base(o) {}
|
MOZ_IMPLICIT WeakPtr(const Base& aOther) : Base(aOther) {}
|
||||||
WeakPtr() {}
|
WeakPtr() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
@ -9,11 +11,11 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
namespace mozilla
|
namespace mozilla {
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
IsWindowsVersionOrLater(uint32_t aVersion)
|
||||||
{
|
{
|
||||||
inline bool
|
|
||||||
IsWindowsVersionOrLater(uint32_t aVersion)
|
|
||||||
{
|
|
||||||
static uint32_t minVersion = 0;
|
static uint32_t minVersion = 0;
|
||||||
static uint32_t maxVersion = UINT32_MAX;
|
static uint32_t maxVersion = UINT32_MAX;
|
||||||
|
|
||||||
@ -49,11 +51,11 @@ namespace mozilla
|
|||||||
|
|
||||||
maxVersion = aVersion;
|
maxVersion = aVersion;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
IsWindowsBuildOrLater(uint32_t aBuild)
|
IsWindowsBuildOrLater(uint32_t aBuild)
|
||||||
{
|
{
|
||||||
static uint32_t minBuild = 0;
|
static uint32_t minBuild = 0;
|
||||||
static uint32_t maxBuild = UINT32_MAX;
|
static uint32_t maxBuild = UINT32_MAX;
|
||||||
|
|
||||||
@ -80,46 +82,63 @@ namespace mozilla
|
|||||||
|
|
||||||
maxBuild = aBuild;
|
maxBuild = aBuild;
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ALWAYS_INLINE bool
|
|
||||||
IsXPSP3OrLater()
|
|
||||||
{ return IsWindowsVersionOrLater(0x05010300ul); }
|
|
||||||
|
|
||||||
MOZ_ALWAYS_INLINE bool
|
|
||||||
IsWin2003OrLater()
|
|
||||||
{ return IsWindowsVersionOrLater(0x05020000ul); }
|
|
||||||
|
|
||||||
MOZ_ALWAYS_INLINE bool
|
|
||||||
IsWin2003SP2OrLater()
|
|
||||||
{ return IsWindowsVersionOrLater(0x05020200ul); }
|
|
||||||
|
|
||||||
MOZ_ALWAYS_INLINE bool
|
|
||||||
IsVistaOrLater()
|
|
||||||
{ return IsWindowsVersionOrLater(0x06000000ul); }
|
|
||||||
|
|
||||||
MOZ_ALWAYS_INLINE bool
|
|
||||||
IsVistaSP1OrLater()
|
|
||||||
{ return IsWindowsVersionOrLater(0x06000100ul); }
|
|
||||||
|
|
||||||
MOZ_ALWAYS_INLINE bool
|
|
||||||
IsWin7OrLater()
|
|
||||||
{ return IsWindowsVersionOrLater(0x06010000ul); }
|
|
||||||
|
|
||||||
MOZ_ALWAYS_INLINE bool
|
|
||||||
IsWin7SP1OrLater()
|
|
||||||
{ return IsWindowsVersionOrLater(0x06010100ul); }
|
|
||||||
|
|
||||||
MOZ_ALWAYS_INLINE bool
|
|
||||||
IsWin8OrLater()
|
|
||||||
{ return IsWindowsVersionOrLater(0x06020000ul); }
|
|
||||||
|
|
||||||
MOZ_ALWAYS_INLINE bool
|
|
||||||
IsNotWin7PreRTM()
|
|
||||||
{
|
|
||||||
return IsWin7SP1OrLater() || !IsWin7OrLater() ||
|
|
||||||
IsWindowsBuildOrLater(7600);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MOZ_ALWAYS_INLINE bool
|
||||||
|
IsXPSP3OrLater()
|
||||||
|
{
|
||||||
|
return IsWindowsVersionOrLater(0x05010300ul);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ALWAYS_INLINE bool
|
||||||
|
IsWin2003OrLater()
|
||||||
|
{
|
||||||
|
return IsWindowsVersionOrLater(0x05020000ul);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ALWAYS_INLINE bool
|
||||||
|
IsWin2003SP2OrLater()
|
||||||
|
{
|
||||||
|
return IsWindowsVersionOrLater(0x05020200ul);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ALWAYS_INLINE bool
|
||||||
|
IsVistaOrLater()
|
||||||
|
{
|
||||||
|
return IsWindowsVersionOrLater(0x06000000ul);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ALWAYS_INLINE bool
|
||||||
|
IsVistaSP1OrLater()
|
||||||
|
{
|
||||||
|
return IsWindowsVersionOrLater(0x06000100ul);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ALWAYS_INLINE bool
|
||||||
|
IsWin7OrLater()
|
||||||
|
{
|
||||||
|
return IsWindowsVersionOrLater(0x06010000ul);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ALWAYS_INLINE bool
|
||||||
|
IsWin7SP1OrLater()
|
||||||
|
{
|
||||||
|
return IsWindowsVersionOrLater(0x06010100ul);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ALWAYS_INLINE bool
|
||||||
|
IsWin8OrLater()
|
||||||
|
{
|
||||||
|
return IsWindowsVersionOrLater(0x06020000ul);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ALWAYS_INLINE bool
|
||||||
|
IsNotWin7PreRTM()
|
||||||
|
{
|
||||||
|
return IsWin7SP1OrLater() || !IsWin7OrLater() ||
|
||||||
|
IsWindowsBuildOrLater(7600);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif /* mozilla_WindowsVersion_h */
|
#endif /* mozilla_WindowsVersion_h */
|
||||||
|
@ -197,8 +197,9 @@ main()
|
|||||||
"expected-data size should be the same as the actual hash "
|
"expected-data size should be the same as the actual hash "
|
||||||
"size");
|
"size");
|
||||||
|
|
||||||
for (size_t i = 0; i < SHA1Sum::HashSize; i++)
|
for (size_t i = 0; i < SHA1Sum::kHashSize; i++) {
|
||||||
MOZ_RELEASE_ASSERT(hash[i] == expected[i]);
|
MOZ_RELEASE_ASSERT(hash[i] == expected[i]);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -64,11 +64,11 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_org_mozilla_gecko_background_native
|
|||||||
|
|
||||||
env->ReleaseByteArrayElements(jstr, str, JNI_ABORT);
|
env->ReleaseByteArrayElements(jstr, str, JNI_ABORT);
|
||||||
|
|
||||||
jbyteArray out = env->NewByteArray(SHA1Sum::HashSize);
|
jbyteArray out = env->NewByteArray(SHA1Sum::kHashSize);
|
||||||
if (out == NULL) {
|
if (out == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
env->SetByteArrayRegion(out, 0, SHA1Sum::HashSize, (jbyte *) hashResult);
|
env->SetByteArrayRegion(out, 0, SHA1Sum::kHashSize, (jbyte *) hashResult);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ template <> inline void RefCounted<LibHandle, AtomicRefCount>::Release() const;
|
|||||||
|
|
||||||
template <> inline RefCounted<LibHandle, AtomicRefCount>::~RefCounted()
|
template <> inline RefCounted<LibHandle, AtomicRefCount>::~RefCounted()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(refCnt == 0x7fffdead);
|
MOZ_ASSERT(mRefCnt == 0x7fffdead);
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace detail */
|
} /* namespace detail */
|
||||||
@ -219,27 +219,27 @@ private:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Specialized RefCounted<LibHandle>::Release. Under normal operation, when
|
* Specialized RefCounted<LibHandle>::Release. Under normal operation, when
|
||||||
* refCnt reaches 0, the LibHandle is deleted. Its refCnt is however increased
|
* mRefCnt reaches 0, the LibHandle is deleted. Its mRefCnt is however
|
||||||
* to 1 on normal builds, and 0x7fffdead on debug builds so that the LibHandle
|
* increased to 1 on normal builds, and 0x7fffdead on debug builds so that the
|
||||||
* can still be referenced while the destructor is executing. The refCnt is
|
* LibHandle can still be referenced while the destructor is executing. The
|
||||||
* allowed to grow > 0x7fffdead, but not to decrease under that value, which
|
* mRefCnt is allowed to grow > 0x7fffdead, but not to decrease under that
|
||||||
* would mean too many Releases from within the destructor.
|
* value, which would mean too many Releases from within the destructor.
|
||||||
*/
|
*/
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template <> inline void RefCounted<LibHandle, AtomicRefCount>::Release() const {
|
template <> inline void RefCounted<LibHandle, AtomicRefCount>::Release() const {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (refCnt > 0x7fff0000)
|
if (mRefCnt > 0x7fff0000)
|
||||||
MOZ_ASSERT(refCnt > 0x7fffdead);
|
MOZ_ASSERT(mRefCnt > 0x7fffdead);
|
||||||
#endif
|
#endif
|
||||||
MOZ_ASSERT(refCnt > 0);
|
MOZ_ASSERT(mRefCnt > 0);
|
||||||
if (refCnt > 0) {
|
if (mRefCnt > 0) {
|
||||||
if (0 == --refCnt) {
|
if (0 == --mRefCnt) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
refCnt = 0x7fffdead;
|
mRefCnt = 0x7fffdead;
|
||||||
#else
|
#else
|
||||||
refCnt = 1;
|
mRefCnt = 1;
|
||||||
#endif
|
#endif
|
||||||
delete static_cast<const LibHandle*>(this);
|
delete static_cast<const LibHandle*>(this);
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ public:
|
|||||||
HandleHashKey(KeyTypePointer aKey)
|
HandleHashKey(KeyTypePointer aKey)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(HandleHashKey);
|
MOZ_COUNT_CTOR(HandleHashKey);
|
||||||
mHash = (SHA1Sum::Hash*)new uint8_t[SHA1Sum::HashSize];
|
mHash = (SHA1Sum::Hash*)new uint8_t[SHA1Sum::kHashSize];
|
||||||
memcpy(mHash, aKey, sizeof(SHA1Sum::Hash));
|
memcpy(mHash, aKey, sizeof(SHA1Sum::Hash));
|
||||||
}
|
}
|
||||||
HandleHashKey(const HandleHashKey& aOther)
|
HandleHashKey(const HandleHashKey& aOther)
|
||||||
|
Loading…
Reference in New Issue
Block a user