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 {
|
||||
SHA1Sum sha1;
|
||||
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);
|
||||
|
||||
nsAutoCString digestString;
|
||||
|
@ -243,9 +243,9 @@ private:
|
||||
SHA1Sum sha1;
|
||||
nsCString combined(wsKey + guid);
|
||||
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);
|
||||
nsCString newString(reinterpret_cast<char*>(digest), SHA1Sum::HashSize);
|
||||
nsCString newString(reinterpret_cast<char*>(digest), SHA1Sum::kHashSize);
|
||||
Base64Encode(newString, res);
|
||||
|
||||
nsCString response("HTTP/1.1 101 Switching Protocols\r\n");
|
||||
|
@ -1016,7 +1016,7 @@ class HashTable : private AllocPolicy
|
||||
#endif
|
||||
|
||||
friend class mozilla::ReentrancyGuard;
|
||||
mutable mozilla::DebugOnly<bool> entered;
|
||||
mutable mozilla::DebugOnly<bool> mEntered;
|
||||
mozilla::DebugOnly<uint64_t> mutationCount;
|
||||
|
||||
// The default initial capacity is 32 (enough to hold 16 elements), but it
|
||||
@ -1076,7 +1076,7 @@ class HashTable : private AllocPolicy
|
||||
gen(0),
|
||||
removedCount(0),
|
||||
table(nullptr),
|
||||
entered(false),
|
||||
mEntered(false),
|
||||
mutationCount(0)
|
||||
{}
|
||||
|
||||
@ -1452,7 +1452,7 @@ class HashTable : private AllocPolicy
|
||||
|
||||
void finish()
|
||||
{
|
||||
MOZ_ASSERT(!entered);
|
||||
MOZ_ASSERT(!mEntered);
|
||||
|
||||
if (!table)
|
||||
return;
|
||||
|
@ -422,14 +422,14 @@ class StoreBuffer
|
||||
|
||||
bool aboutToOverflow_;
|
||||
bool enabled_;
|
||||
mozilla::DebugOnly<bool> entered; /* For ReentrancyGuard. */
|
||||
mozilla::DebugOnly<bool> mEntered; /* For ReentrancyGuard. */
|
||||
|
||||
public:
|
||||
explicit StoreBuffer(JSRuntime *rt, const Nursery &nursery)
|
||||
: bufferVal(), bufferCell(), bufferSlot(), bufferWholeCell(),
|
||||
bufferRelocVal(), bufferRelocCell(), bufferGeneric(),
|
||||
runtime_(rt), nursery_(nursery), aboutToOverflow_(false), enabled_(false),
|
||||
entered(false)
|
||||
mEntered(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -64,8 +64,8 @@ template<size_t Align>
|
||||
struct AlignedElem;
|
||||
|
||||
/*
|
||||
* We have to specialize this template because GCC doesn't like __attribute__((aligned(foo))) where
|
||||
* foo is a template parameter.
|
||||
* We have to specialize this template because GCC doesn't like
|
||||
* __attribute__((aligned(foo))) where foo is a template parameter.
|
||||
*/
|
||||
|
||||
template<>
|
||||
|
@ -144,7 +144,8 @@ template<typename T>
|
||||
inline bool
|
||||
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 {
|
||||
|
@ -149,7 +149,8 @@ MOZ_ReportAssertionFailure(const char* aStr, const char* aFilename, int aLine)
|
||||
}
|
||||
|
||||
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
|
||||
__android_log_print(ANDROID_LOG_FATAL, "MOZ_CRASH",
|
||||
@ -254,7 +255,7 @@ __declspec(noreturn) __inline void MOZ_NoReturn() {}
|
||||
do { \
|
||||
MOZ_ReportCrash("" __VA_ARGS__, __FILE__, __LINE__); \
|
||||
MOZ_REALLY_CRASH(); \
|
||||
} while(0)
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -384,7 +385,7 @@ void ValidateAssertConditionType()
|
||||
#ifdef DEBUG
|
||||
# define MOZ_ASSERT(...) MOZ_RELEASE_ASSERT(__VA_ARGS__)
|
||||
#else
|
||||
# define MOZ_ASSERT(...) do { } while(0)
|
||||
# define MOZ_ASSERT(...) do { } while (0)
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
|
@ -285,7 +285,8 @@ private:
|
||||
* atomic<T*> is not the same as adding X to a T*. Hence the need
|
||||
* 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)
|
||||
return aVal;
|
||||
#elif defined(__GNUC__) && MOZ_GCC_VERSION_AT_LEAST(4, 6, 0) && \
|
||||
|
@ -155,9 +155,10 @@
|
||||
* template<typename T>
|
||||
* class Ptr
|
||||
* {
|
||||
* T* ptr;
|
||||
* MOZ_EXPLICIT_CONVERSION operator bool() const {
|
||||
* return ptr != nullptr;
|
||||
* T* mPtr;
|
||||
* MOZ_EXPLICIT_CONVERSION operator bool() const
|
||||
* {
|
||||
* return mPtr != nullptr;
|
||||
* }
|
||||
* };
|
||||
*
|
||||
@ -206,7 +207,8 @@
|
||||
* function does not return. (The function definition does not need to be
|
||||
* 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
|
||||
* to eliminate false positives. From the upstream documentation of scan-build:
|
||||
@ -447,13 +449,13 @@
|
||||
*
|
||||
* typedef int MOZ_TYPE_ATTRIBUTE MagicInt;
|
||||
* int MOZ_TYPE_ATTRIBUTE someVariable;
|
||||
* int * MOZ_TYPE_ATTRIBUTE magicPtrInt;
|
||||
* int MOZ_TYPE_ATTRIBUTE * ptrToMagicInt;
|
||||
* int* MOZ_TYPE_ATTRIBUTE magicPtrInt;
|
||||
* int MOZ_TYPE_ATTRIBUTE* ptrToMagicInt;
|
||||
*
|
||||
* Attributes that apply to statements precede the statement:
|
||||
*
|
||||
* 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:
|
||||
*
|
||||
|
@ -26,8 +26,9 @@ namespace mozilla {
|
||||
* Vector<int> sortedInts = ...
|
||||
*
|
||||
* 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);
|
||||
* }
|
||||
*/
|
||||
|
||||
template <typename Container, typename T>
|
||||
|
@ -107,9 +107,9 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Some Windows API calls accept BYTE* but require that data actually be WCHAR*.
|
||||
* Supporting this requires explicit operators to support the requisite explicit
|
||||
* casts.
|
||||
* Some Windows API calls accept BYTE* but require that data actually be
|
||||
* WCHAR*. Supporting this requires explicit operators to support the
|
||||
* requisite explicit casts.
|
||||
*/
|
||||
explicit operator const char*() const
|
||||
{
|
||||
@ -121,7 +121,8 @@ public:
|
||||
}
|
||||
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
|
||||
{
|
||||
@ -133,7 +134,7 @@ public:
|
||||
{
|
||||
return mPtr[aIndex];
|
||||
}
|
||||
bool operator==(const char16ptr_t &aOther) const
|
||||
bool operator==(const char16ptr_t& aOther) const
|
||||
{
|
||||
return mPtr == aOther.mPtr;
|
||||
}
|
||||
@ -141,7 +142,7 @@ public:
|
||||
{
|
||||
return mPtr == nullptr;
|
||||
}
|
||||
bool operator!=(const char16ptr_t &aOther) const
|
||||
bool operator!=(const char16ptr_t& aOther) const
|
||||
{
|
||||
return mPtr != aOther.mPtr;
|
||||
}
|
||||
@ -153,7 +154,7 @@ public:
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -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
|
||||
* zero or integer overflow). You could code it as follows:
|
||||
@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;
|
||||
if (checkedResult.isValid()) {
|
||||
|
@ -48,7 +48,7 @@ LZ4::decompress(const char* aSource, char* aDest, size_t aOutputSize)
|
||||
|
||||
bool
|
||||
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;
|
||||
MOZ_ASSERT(maxOutputSizeChecked.isValid());
|
||||
|
@ -94,7 +94,7 @@ public:
|
||||
*/
|
||||
static MFBT_API bool
|
||||
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"
|
||||
|
@ -474,7 +474,8 @@ protected:
|
||||
* Likewise, but converts values in place.
|
||||
*/
|
||||
template<typename T>
|
||||
static void swapToBigEndianInPlace(T* aPtr, size_t aCount) {
|
||||
static void swapToBigEndianInPlace(T* aPtr, size_t 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
|
||||
* 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/. */
|
||||
|
@ -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
|
||||
* 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/. */
|
||||
|
@ -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
|
||||
* 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/. */
|
||||
* 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/. */
|
||||
|
||||
/* Implements the C99 <inttypes.h> interface, minus the SCN* format macros. */
|
||||
|
||||
|
@ -82,7 +82,8 @@ struct UnsignedStdintTypeForSize
|
||||
template<typename IntegerType>
|
||||
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.
|
||||
static const size_t value = 8 * sizeof(IntegerType) - 1;
|
||||
};
|
||||
@ -96,7 +97,8 @@ template<typename IntegerType>
|
||||
struct MinValue
|
||||
{
|
||||
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;
|
||||
static const size_t PosOfSignBit = PositionOfSignBit<IntegerType>::value;
|
||||
@ -122,7 +124,8 @@ public:
|
||||
template<typename IntegerType>
|
||||
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.
|
||||
// Relies on the type of MinValue<IntegerType>::value
|
||||
|
@ -463,7 +463,8 @@ public:
|
||||
private:
|
||||
friend class LinkedListElement<T>;
|
||||
|
||||
void assertContains(const T* aValue) const {
|
||||
void assertContains(const T* aValue) const
|
||||
{
|
||||
#ifdef DEBUG
|
||||
for (const T* elem = getFirst(); elem; elem = elem->getNext()) {
|
||||
if (elem == aValue) {
|
||||
|
@ -102,7 +102,8 @@ template<> struct AbsReturnTypeFixed<int64_t> { typedef uint64_t Type; };
|
||||
template<typename 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<short> { typedef unsigned short Type; };
|
||||
template<> struct AbsReturnType<int> { typedef unsigned int Type; };
|
||||
@ -145,7 +146,8 @@ Abs<long double>(const long double aLongDouble)
|
||||
|
||||
} // 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
|
||||
|
||||
# include <intrin.h>
|
||||
|
@ -12,8 +12,7 @@
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/TemplateLib.h"
|
||||
|
||||
// For placement new
|
||||
#include <new>
|
||||
#include <new> // For placement new
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -35,13 +34,15 @@ class MaybeOneOf
|
||||
template <class T, class Ignored = void> struct Type2State {};
|
||||
|
||||
template <class T>
|
||||
T& as() {
|
||||
T& as()
|
||||
{
|
||||
MOZ_ASSERT(state == Type2State<T>::result);
|
||||
return *(T*)storage.addr();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T& as() const {
|
||||
const T& as() const
|
||||
{
|
||||
MOZ_ASSERT(state == Type2State<T>::result);
|
||||
return *(T*)storage.addr();
|
||||
}
|
||||
@ -124,14 +125,16 @@ private:
|
||||
|
||||
template <class T1, class T2>
|
||||
template <class Ignored>
|
||||
struct MaybeOneOf<T1, T2>::Type2State<T1, Ignored> {
|
||||
struct MaybeOneOf<T1, T2>::Type2State<T1, Ignored>
|
||||
{
|
||||
typedef MaybeOneOf<T1, T2> Enclosing;
|
||||
static const typename Enclosing::State result = Enclosing::SomeT1;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
template <class Ignored>
|
||||
struct MaybeOneOf<T1, T2>::Type2State<T2, Ignored> {
|
||||
struct MaybeOneOf<T1, T2>::Type2State<T2, Ignored>
|
||||
{
|
||||
typedef MaybeOneOf<T1, T2> Enclosing;
|
||||
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))
|
||||
#else
|
||||
|
||||
#define MOZ_MAKE_MEM_NOACCESS(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_NOACCESS(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)
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -144,8 +144,8 @@ namespace mozilla {
|
||||
* - First, when a function template takes an argument that is an rvalue
|
||||
* reference to a template argument (like 'XArg&& x' and 'YArg&& y' above),
|
||||
* 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
|
||||
* argument resolves to 'T &&'. Thus, in a call to C::C like:
|
||||
* 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:
|
||||
*
|
||||
* X foo(int);
|
||||
* Y yy;
|
||||
|
164
mfbt/Pair.h
164
mfbt/Pair.h
@ -38,95 +38,99 @@ struct PairHelper;
|
||||
template<typename A, typename B>
|
||||
struct PairHelper<A, B, AsMember, AsMember>
|
||||
{
|
||||
protected:
|
||||
template<typename AArg, typename BArg>
|
||||
PairHelper(AArg&& a, BArg&& b)
|
||||
: firstA(Forward<AArg>(a)),
|
||||
secondB(Forward<BArg>(b))
|
||||
{}
|
||||
protected:
|
||||
template<typename AArg, typename BArg>
|
||||
PairHelper(AArg&& aA, BArg&& aB)
|
||||
: mFirstA(Forward<AArg>(aA)),
|
||||
mSecondB(Forward<BArg>(aB))
|
||||
{}
|
||||
|
||||
A& first() { return firstA; }
|
||||
const A& first() const { return firstA; }
|
||||
B& second() { return secondB; }
|
||||
const B& second() const { return secondB; }
|
||||
A& first() { return mFirstA; }
|
||||
const A& first() const { return mFirstA; }
|
||||
B& second() { return mSecondB; }
|
||||
const B& second() const { return mSecondB; }
|
||||
|
||||
void swap(PairHelper& other) {
|
||||
Swap(firstA, other.firstA);
|
||||
Swap(secondB, other.secondB);
|
||||
}
|
||||
void swap(PairHelper& aOther)
|
||||
{
|
||||
Swap(mFirstA, aOther.mFirstA);
|
||||
Swap(mSecondB, aOther.mSecondB);
|
||||
}
|
||||
|
||||
private:
|
||||
A firstA;
|
||||
B secondB;
|
||||
private:
|
||||
A mFirstA;
|
||||
B mSecondB;
|
||||
};
|
||||
|
||||
template<typename A, typename B>
|
||||
struct PairHelper<A, B, AsMember, AsBase> : private B
|
||||
{
|
||||
protected:
|
||||
template<typename AArg, typename BArg>
|
||||
PairHelper(AArg&& a, BArg&& b)
|
||||
: B(Forward<BArg>(b)),
|
||||
firstA(Forward<AArg>(a))
|
||||
{}
|
||||
protected:
|
||||
template<typename AArg, typename BArg>
|
||||
PairHelper(AArg&& aA, BArg&& aB)
|
||||
: B(Forward<BArg>(aB)),
|
||||
mFirstA(Forward<AArg>(aA))
|
||||
{}
|
||||
|
||||
A& first() { return firstA; }
|
||||
const A& first() const { return firstA; }
|
||||
B& second() { return *this; }
|
||||
const B& second() const { return *this; }
|
||||
A& first() { return mFirstA; }
|
||||
const A& first() const { return mFirstA; }
|
||||
B& second() { return *this; }
|
||||
const B& second() const { return *this; }
|
||||
|
||||
void swap(PairHelper& other) {
|
||||
Swap(firstA, other.firstA);
|
||||
Swap(static_cast<B&>(*this), static_cast<B&>(other));
|
||||
}
|
||||
void swap(PairHelper& aOther)
|
||||
{
|
||||
Swap(mFirstA, aOther.mFirstA);
|
||||
Swap(static_cast<B&>(*this), static_cast<B&>(aOther));
|
||||
}
|
||||
|
||||
private:
|
||||
A firstA;
|
||||
private:
|
||||
A mFirstA;
|
||||
};
|
||||
|
||||
template<typename A, typename B>
|
||||
struct PairHelper<A, B, AsBase, AsMember> : private A
|
||||
{
|
||||
protected:
|
||||
template<typename AArg, typename BArg>
|
||||
PairHelper(AArg&& a, BArg&& b)
|
||||
: A(Forward<AArg>(a)),
|
||||
secondB(Forward<BArg>(b))
|
||||
{}
|
||||
protected:
|
||||
template<typename AArg, typename BArg>
|
||||
PairHelper(AArg&& aA, BArg&& aB)
|
||||
: A(Forward<AArg>(aA)),
|
||||
mSecondB(Forward<BArg>(aB))
|
||||
{}
|
||||
|
||||
A& first() { return *this; }
|
||||
const A& first() const { return *this; }
|
||||
B& second() { return secondB; }
|
||||
const B& second() const { return secondB; }
|
||||
A& first() { return *this; }
|
||||
const A& first() const { return *this; }
|
||||
B& second() { return mSecondB; }
|
||||
const B& second() const { return mSecondB; }
|
||||
|
||||
void swap(PairHelper& other) {
|
||||
Swap(static_cast<A&>(*this), static_cast<A&>(other));
|
||||
Swap(secondB, other.secondB);
|
||||
}
|
||||
void swap(PairHelper& aOther)
|
||||
{
|
||||
Swap(static_cast<A&>(*this), static_cast<A&>(aOther));
|
||||
Swap(mSecondB, aOther.mSecondB);
|
||||
}
|
||||
|
||||
private:
|
||||
B secondB;
|
||||
private:
|
||||
B mSecondB;
|
||||
};
|
||||
|
||||
template<typename A, typename B>
|
||||
struct PairHelper<A, B, AsBase, AsBase> : private A, private B
|
||||
{
|
||||
protected:
|
||||
template<typename AArg, typename BArg>
|
||||
PairHelper(AArg&& a, BArg&& b)
|
||||
: A(Forward<AArg>(a)),
|
||||
B(Forward<BArg>(b))
|
||||
{}
|
||||
protected:
|
||||
template<typename AArg, typename BArg>
|
||||
PairHelper(AArg&& aA, BArg&& aB)
|
||||
: A(Forward<AArg>(aA)),
|
||||
B(Forward<BArg>(aB))
|
||||
{}
|
||||
|
||||
A& first() { return static_cast<A&>(*this); }
|
||||
const A& first() const { return static_cast<A&>(*this); }
|
||||
B& second() { return static_cast<B&>(*this); }
|
||||
const B& second() const { return static_cast<B&>(*this); }
|
||||
A& first() { return static_cast<A&>(*this); }
|
||||
const A& first() const { return static_cast<A&>(*this); }
|
||||
B& second() { return static_cast<B&>(*this); }
|
||||
const B& second() const { return static_cast<B&>(*this); }
|
||||
|
||||
void swap(PairHelper& other) {
|
||||
Swap(static_cast<A&>(*this), static_cast<A&>(other));
|
||||
Swap(static_cast<B&>(*this), static_cast<B&>(other));
|
||||
}
|
||||
void swap(PairHelper& aOther)
|
||||
{
|
||||
Swap(static_cast<A&>(*this), static_cast<A&>(aOther));
|
||||
Swap(static_cast<B&>(*this), static_cast<B&>(aOther));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
@ -148,33 +152,31 @@ template<typename A, typename B>
|
||||
struct Pair
|
||||
: private detail::PairHelper<A, B>
|
||||
{
|
||||
typedef typename detail::PairHelper<A, B> Base;
|
||||
typedef typename detail::PairHelper<A, B> Base;
|
||||
|
||||
public:
|
||||
template<typename AArg, typename BArg>
|
||||
Pair(AArg&& a, BArg&& b)
|
||||
: Base(Forward<AArg>(a), Forward<BArg>(b))
|
||||
{}
|
||||
public:
|
||||
template<typename AArg, typename BArg>
|
||||
Pair(AArg&& aA, BArg&& aB)
|
||||
: Base(Forward<AArg>(aA), Forward<BArg>(aB))
|
||||
{}
|
||||
|
||||
/** The A instance. */
|
||||
using Base::first;
|
||||
/** The B instance. */
|
||||
using Base::second;
|
||||
/** The A instance. */
|
||||
using Base::first;
|
||||
/** The B instance. */
|
||||
using Base::second;
|
||||
|
||||
/** Swap this pair with another pair. */
|
||||
void swap(Pair& other) {
|
||||
Base::swap(other);
|
||||
}
|
||||
/** Swap this pair with another pair. */
|
||||
void swap(Pair& aOther) { Base::swap(aOther); }
|
||||
|
||||
private:
|
||||
Pair(const Pair&) MOZ_DELETE;
|
||||
private:
|
||||
Pair(const Pair&) MOZ_DELETE;
|
||||
};
|
||||
|
||||
template<typename A, class B>
|
||||
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
|
||||
|
@ -41,14 +41,14 @@ uintptr_t gMozillaPoisonSize;
|
||||
// file.
|
||||
|
||||
#ifdef _WIN32
|
||||
static void *
|
||||
static void*
|
||||
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
|
||||
ReleaseRegion(void *aRegion, uintptr_t aSize)
|
||||
ReleaseRegion(void* aRegion, uintptr_t aSize)
|
||||
{
|
||||
VirtualFree(aRegion, aSize, MEM_RELEASE);
|
||||
}
|
||||
@ -77,7 +77,7 @@ GetDesiredRegionSize()
|
||||
#define RESERVE_FAILED 0
|
||||
|
||||
#elif defined(__OS2__)
|
||||
static void *
|
||||
static void*
|
||||
ReserveRegion(uintptr_t aRegion, uintptr_t aSize)
|
||||
{
|
||||
// OS/2 doesn't support allocation at an arbitrary address,
|
||||
@ -86,7 +86,7 @@ ReserveRegion(uintptr_t aRegion, uintptr_t aSize)
|
||||
}
|
||||
|
||||
static void
|
||||
ReleaseRegion(void *aRegion, uintptr_t aSize)
|
||||
ReleaseRegion(void* aRegion, uintptr_t aSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -112,7 +112,7 @@ GetDesiredRegionSize()
|
||||
|
||||
#include "mozilla/TaggedAnonymousMemory.h"
|
||||
|
||||
static void *
|
||||
static void*
|
||||
ReserveRegion(uintptr_t aRegion, uintptr_t aSize)
|
||||
{
|
||||
return MozTaggedAnonymousMmap(reinterpret_cast<void*>(aRegion), aSize,
|
||||
@ -121,7 +121,7 @@ ReserveRegion(uintptr_t aRegion, uintptr_t aSize)
|
||||
}
|
||||
|
||||
static void
|
||||
ReleaseRegion(void *aRegion, uintptr_t aSize)
|
||||
ReleaseRegion(void* aRegion, uintptr_t aSize)
|
||||
{
|
||||
munmap(aRegion, aSize);
|
||||
}
|
||||
@ -147,7 +147,7 @@ GetDesiredRegionSize()
|
||||
#endif // system dependencies
|
||||
|
||||
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
|
||||
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.
|
||||
uintptr_t candidate = (0xF0DEAFFF & ~(rgnsize-1));
|
||||
void *result = ReserveRegion(candidate, rgnsize);
|
||||
if (result == (void *)candidate) {
|
||||
void* result = ReserveRegion(candidate, rgnsize);
|
||||
if (result == (void*)candidate) {
|
||||
// success - inaccessible page allocated
|
||||
return candidate;
|
||||
}
|
||||
|
32
mfbt/Range.h
32
mfbt/Range.h
@ -18,28 +18,26 @@ namespace mozilla {
|
||||
template <typename T>
|
||||
class Range
|
||||
{
|
||||
const RangedPtr<T> mStart;
|
||||
const RangedPtr<T> mEnd;
|
||||
const RangedPtr<T> mStart;
|
||||
const RangedPtr<T> mEnd;
|
||||
|
||||
typedef void (Range::* ConvertibleToBool)();
|
||||
void nonNull() {}
|
||||
typedef void (Range::* ConvertibleToBool)();
|
||||
void nonNull() {}
|
||||
|
||||
public:
|
||||
Range() : mStart(nullptr, 0), mEnd(nullptr, 0) {}
|
||||
Range(T* p, size_t len)
|
||||
: mStart(p, p, p + len),
|
||||
mEnd(p + len, p, p + len)
|
||||
{}
|
||||
public:
|
||||
Range() : mStart(nullptr, 0), mEnd(nullptr, 0) {}
|
||||
Range(T* aPtr, size_t aLength)
|
||||
: mStart(aPtr, aPtr, aPtr + aLength),
|
||||
mEnd(aPtr + aLength, aPtr, aPtr + aLength)
|
||||
{}
|
||||
|
||||
RangedPtr<T> start() const { return mStart; }
|
||||
RangedPtr<T> end() const { return mEnd; }
|
||||
size_t length() const { return mEnd - mStart; }
|
||||
RangedPtr<T> start() const { return mStart; }
|
||||
RangedPtr<T> end() const { return mEnd; }
|
||||
size_t length() const { return mEnd - mStart; }
|
||||
|
||||
T& operator[](size_t offset) const {
|
||||
return mStart[offset];
|
||||
}
|
||||
T& operator[](size_t aOffset) const { return mStart[aOffset]; }
|
||||
|
||||
operator ConvertibleToBool() const { return mStart ? &Range::nonNull : 0; }
|
||||
operator ConvertibleToBool() const { return mStart ? &Range::nonNull : 0; }
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
360
mfbt/RangedPtr.h
360
mfbt/RangedPtr.h
@ -43,216 +43,240 @@ namespace mozilla {
|
||||
template<typename T>
|
||||
class RangedPtr
|
||||
{
|
||||
T* ptr;
|
||||
T* mPtr;
|
||||
|
||||
#ifdef DEBUG
|
||||
T* const rangeStart;
|
||||
T* const rangeEnd;
|
||||
T* const mRangeStart;
|
||||
T* const mRangeEnd;
|
||||
#endif
|
||||
|
||||
typedef void (RangedPtr::* ConvertibleToBool)();
|
||||
void nonNull() {}
|
||||
typedef void (RangedPtr::* ConvertibleToBool)();
|
||||
void nonNull() {}
|
||||
|
||||
void checkSanity() {
|
||||
MOZ_ASSERT(rangeStart <= ptr);
|
||||
MOZ_ASSERT(ptr <= rangeEnd);
|
||||
}
|
||||
void checkSanity()
|
||||
{
|
||||
MOZ_ASSERT(mRangeStart <= mPtr);
|
||||
MOZ_ASSERT(mPtr <= mRangeEnd);
|
||||
}
|
||||
|
||||
/* Creates a new pointer for |p|, restricted to this pointer's range. */
|
||||
RangedPtr<T> create(T *p) const {
|
||||
/* Creates a new pointer for |aPtr|, restricted to this pointer's range. */
|
||||
RangedPtr<T> create(T* aPtr) const
|
||||
{
|
||||
#ifdef DEBUG
|
||||
return RangedPtr<T>(p, rangeStart, rangeEnd);
|
||||
return RangedPtr<T>(aPtr, mRangeStart, mRangeEnd);
|
||||
#else
|
||||
return RangedPtr<T>(p, nullptr, size_t(0));
|
||||
return RangedPtr<T>(aPtr, nullptr, size_t(0));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t asUintptr() const { return uintptr_t(ptr); }
|
||||
uintptr_t asUintptr() const { return reinterpret_cast<uintptr_t>(mPtr); }
|
||||
|
||||
public:
|
||||
RangedPtr(T* p, T* start, T* end)
|
||||
: ptr(p)
|
||||
public:
|
||||
RangedPtr(T* aPtr, T* aStart, T* aEnd)
|
||||
: mPtr(aPtr)
|
||||
#ifdef DEBUG
|
||||
, rangeStart(start), rangeEnd(end)
|
||||
, mRangeStart(aStart), mRangeEnd(aEnd)
|
||||
#endif
|
||||
{
|
||||
MOZ_ASSERT(rangeStart <= rangeEnd);
|
||||
checkSanity();
|
||||
}
|
||||
RangedPtr(T* p, T* start, size_t length)
|
||||
: ptr(p)
|
||||
{
|
||||
MOZ_ASSERT(mRangeStart <= mRangeEnd);
|
||||
checkSanity();
|
||||
}
|
||||
RangedPtr(T* aPtr, T* aStart, size_t aLength)
|
||||
: mPtr(aPtr)
|
||||
#ifdef DEBUG
|
||||
, rangeStart(start), rangeEnd(start + length)
|
||||
, mRangeStart(aStart), mRangeEnd(aStart + aLength)
|
||||
#endif
|
||||
{
|
||||
MOZ_ASSERT(length <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(uintptr_t(rangeStart) + length * sizeof(T) >= uintptr_t(rangeStart));
|
||||
checkSanity();
|
||||
}
|
||||
{
|
||||
MOZ_ASSERT(aLength <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(reinterpret_cast<uintptr_t>(mRangeStart) + aLength * sizeof(T) >=
|
||||
reinterpret_cast<uintptr_t>(mRangeStart));
|
||||
checkSanity();
|
||||
}
|
||||
|
||||
/* Equivalent to RangedPtr(p, p, length). */
|
||||
RangedPtr(T* p, size_t length)
|
||||
: ptr(p)
|
||||
/* Equivalent to RangedPtr(aPtr, aPtr, aLength). */
|
||||
RangedPtr(T* aPtr, size_t aLength)
|
||||
: mPtr(aPtr)
|
||||
#ifdef DEBUG
|
||||
, rangeStart(p), rangeEnd(p + length)
|
||||
, mRangeStart(aPtr), mRangeEnd(aPtr + aLength)
|
||||
#endif
|
||||
{
|
||||
MOZ_ASSERT(length <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(uintptr_t(rangeStart) + length * sizeof(T) >= uintptr_t(rangeStart));
|
||||
checkSanity();
|
||||
}
|
||||
{
|
||||
MOZ_ASSERT(aLength <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(reinterpret_cast<uintptr_t>(mRangeStart) + aLength * sizeof(T) >=
|
||||
reinterpret_cast<uintptr_t>(mRangeStart));
|
||||
checkSanity();
|
||||
}
|
||||
|
||||
/* Equivalent to RangedPtr(arr, arr, N). */
|
||||
template<size_t N>
|
||||
RangedPtr(T (&arr)[N])
|
||||
: ptr(arr)
|
||||
/* Equivalent to RangedPtr(aArr, aArr, N). */
|
||||
template<size_t N>
|
||||
RangedPtr(T (&aArr)[N])
|
||||
: mPtr(aArr)
|
||||
#ifdef DEBUG
|
||||
, rangeStart(arr), rangeEnd(arr + N)
|
||||
, mRangeStart(aArr), mRangeEnd(aArr + N)
|
||||
#endif
|
||||
{
|
||||
checkSanity();
|
||||
}
|
||||
{
|
||||
checkSanity();
|
||||
}
|
||||
|
||||
T* get() const {
|
||||
return ptr;
|
||||
}
|
||||
T* get() const { return mPtr; }
|
||||
|
||||
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
|
||||
* the same valid range:
|
||||
*
|
||||
* char arr1[] = "hi";
|
||||
* char arr2[] = "bye";
|
||||
* RangedPtr<char> p1(arr1, 2);
|
||||
* p1 = RangedPtr<char>(arr1 + 1, arr1, arr1 + 2); // works
|
||||
* p1 = RangedPtr<char>(arr2, 3); // asserts
|
||||
*/
|
||||
RangedPtr<T>& operator=(const RangedPtr<T>& other) {
|
||||
MOZ_ASSERT(rangeStart == other.rangeStart);
|
||||
MOZ_ASSERT(rangeEnd == other.rangeEnd);
|
||||
ptr = other.ptr;
|
||||
checkSanity();
|
||||
return *this;
|
||||
}
|
||||
/*
|
||||
* You can only assign one RangedPtr into another if the two pointers have
|
||||
* the same valid range:
|
||||
*
|
||||
* char arr1[] = "hi";
|
||||
* char arr2[] = "bye";
|
||||
* RangedPtr<char> p1(arr1, 2);
|
||||
* p1 = RangedPtr<char>(arr1 + 1, arr1, arr1 + 2); // works
|
||||
* p1 = RangedPtr<char>(arr2, 3); // asserts
|
||||
*/
|
||||
RangedPtr<T>& operator=(const RangedPtr<T>& aOther)
|
||||
{
|
||||
MOZ_ASSERT(mRangeStart == aOther.mRangeStart);
|
||||
MOZ_ASSERT(mRangeEnd == aOther.mRangeEnd);
|
||||
mPtr = aOther.mPtr;
|
||||
checkSanity();
|
||||
return *this;
|
||||
}
|
||||
|
||||
RangedPtr<T> operator+(size_t inc) {
|
||||
MOZ_ASSERT(inc <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(asUintptr() + inc * sizeof(T) >= asUintptr());
|
||||
return create(ptr + inc);
|
||||
}
|
||||
RangedPtr<T> operator+(size_t aInc)
|
||||
{
|
||||
MOZ_ASSERT(aInc <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(asUintptr() + aInc * sizeof(T) >= asUintptr());
|
||||
return create(mPtr + aInc);
|
||||
}
|
||||
|
||||
RangedPtr<T> operator-(size_t dec) {
|
||||
MOZ_ASSERT(dec <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(asUintptr() - dec * sizeof(T) <= asUintptr());
|
||||
return create(ptr - dec);
|
||||
}
|
||||
RangedPtr<T> operator-(size_t aDec)
|
||||
{
|
||||
MOZ_ASSERT(aDec <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(asUintptr() - aDec * sizeof(T) <= asUintptr());
|
||||
return create(mPtr - aDec);
|
||||
}
|
||||
|
||||
/*
|
||||
* You can assign a raw pointer into a RangedPtr if the raw pointer is
|
||||
* within the range specified at creation.
|
||||
*/
|
||||
template <typename U>
|
||||
RangedPtr<T>& operator=(U* p) {
|
||||
*this = create(p);
|
||||
return *this;
|
||||
}
|
||||
/*
|
||||
* You can assign a raw pointer into a RangedPtr if the raw pointer is
|
||||
* within the range specified at creation.
|
||||
*/
|
||||
template <typename U>
|
||||
RangedPtr<T>& operator=(U* aPtr)
|
||||
{
|
||||
*this = create(aPtr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
RangedPtr<T>& operator=(const RangedPtr<U>& p) {
|
||||
MOZ_ASSERT(rangeStart <= p.ptr);
|
||||
MOZ_ASSERT(p.ptr <= rangeEnd);
|
||||
ptr = p.ptr;
|
||||
checkSanity();
|
||||
return *this;
|
||||
}
|
||||
template <typename U>
|
||||
RangedPtr<T>& operator=(const RangedPtr<U>& aPtr)
|
||||
{
|
||||
MOZ_ASSERT(mRangeStart <= aPtr.mPtr);
|
||||
MOZ_ASSERT(aPtr.mPtr <= mRangeEnd);
|
||||
mPtr = aPtr.mPtr;
|
||||
checkSanity();
|
||||
return *this;
|
||||
}
|
||||
|
||||
RangedPtr<T>& operator++() {
|
||||
return (*this += 1);
|
||||
}
|
||||
RangedPtr<T>& operator++()
|
||||
{
|
||||
return (*this += 1);
|
||||
}
|
||||
|
||||
RangedPtr<T> operator++(int) {
|
||||
RangedPtr<T> rcp = *this;
|
||||
++*this;
|
||||
return rcp;
|
||||
}
|
||||
RangedPtr<T> operator++(int)
|
||||
{
|
||||
RangedPtr<T> rcp = *this;
|
||||
++*this;
|
||||
return rcp;
|
||||
}
|
||||
|
||||
RangedPtr<T>& operator--() {
|
||||
return (*this -= 1);
|
||||
}
|
||||
RangedPtr<T>& operator--()
|
||||
{
|
||||
return (*this -= 1);
|
||||
}
|
||||
|
||||
RangedPtr<T> operator--(int) {
|
||||
RangedPtr<T> rcp = *this;
|
||||
--*this;
|
||||
return rcp;
|
||||
}
|
||||
RangedPtr<T> operator--(int)
|
||||
{
|
||||
RangedPtr<T> rcp = *this;
|
||||
--*this;
|
||||
return rcp;
|
||||
}
|
||||
|
||||
RangedPtr<T>& operator+=(size_t inc) {
|
||||
*this = *this + inc;
|
||||
return *this;
|
||||
}
|
||||
RangedPtr<T>& operator+=(size_t aInc)
|
||||
{
|
||||
*this = *this + aInc;
|
||||
return *this;
|
||||
}
|
||||
|
||||
RangedPtr<T>& operator-=(size_t dec) {
|
||||
*this = *this - dec;
|
||||
return *this;
|
||||
}
|
||||
RangedPtr<T>& operator-=(size_t aDec)
|
||||
{
|
||||
*this = *this - aDec;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T& operator[](int index) const {
|
||||
MOZ_ASSERT(size_t(index > 0 ? index : -index) <= size_t(-1) / sizeof(T));
|
||||
return *create(ptr + index);
|
||||
}
|
||||
T& operator[](int aIndex) const
|
||||
{
|
||||
MOZ_ASSERT(size_t(aIndex > 0 ? aIndex : -aIndex) <= size_t(-1) / sizeof(T));
|
||||
return *create(mPtr + aIndex);
|
||||
}
|
||||
|
||||
T& operator*() const {
|
||||
MOZ_ASSERT(ptr >= rangeStart);
|
||||
MOZ_ASSERT(ptr < rangeEnd);
|
||||
return *ptr;
|
||||
}
|
||||
T& operator*() const
|
||||
{
|
||||
MOZ_ASSERT(mPtr >= mRangeStart);
|
||||
MOZ_ASSERT(mPtr < mRangeEnd);
|
||||
return *mPtr;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
bool operator==(const RangedPtr<U>& other) const {
|
||||
return ptr == other.ptr;
|
||||
}
|
||||
template <typename U>
|
||||
bool operator!=(const RangedPtr<U>& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
template <typename U>
|
||||
bool operator==(const RangedPtr<U>& aOther) const
|
||||
{
|
||||
return mPtr == aOther.mPtr;
|
||||
}
|
||||
template <typename U>
|
||||
bool operator!=(const RangedPtr<U>& aOther) const
|
||||
{
|
||||
return !(*this == aOther);
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
bool operator==(const U* u) const {
|
||||
return ptr == u;
|
||||
}
|
||||
template<typename U>
|
||||
bool operator!=(const U* u) const {
|
||||
return !(*this == u);
|
||||
}
|
||||
template<typename U>
|
||||
bool operator==(const U* u) const
|
||||
{
|
||||
return mPtr == u;
|
||||
}
|
||||
template<typename U>
|
||||
bool operator!=(const U* u) const
|
||||
{
|
||||
return !(*this == u);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
bool operator<(const RangedPtr<U>& other) const {
|
||||
return ptr < other.ptr;
|
||||
}
|
||||
template <typename U>
|
||||
bool operator<=(const RangedPtr<U>& other) const {
|
||||
return ptr <= other.ptr;
|
||||
}
|
||||
template <typename U>
|
||||
bool operator<(const RangedPtr<U>& aOther) const
|
||||
{
|
||||
return mPtr < aOther.mPtr;
|
||||
}
|
||||
template <typename U>
|
||||
bool operator<=(const RangedPtr<U>& aOther) const
|
||||
{
|
||||
return mPtr <= aOther.mPtr;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
bool operator>(const RangedPtr<U>& other) const {
|
||||
return ptr > other.ptr;
|
||||
}
|
||||
template <typename U>
|
||||
bool operator>=(const RangedPtr<U>& other) const {
|
||||
return ptr >= other.ptr;
|
||||
}
|
||||
template <typename U>
|
||||
bool operator>(const RangedPtr<U>& aOther) const
|
||||
{
|
||||
return mPtr > aOther.mPtr;
|
||||
}
|
||||
template <typename U>
|
||||
bool operator>=(const RangedPtr<U>& aOther) const
|
||||
{
|
||||
return mPtr >= aOther.mPtr;
|
||||
}
|
||||
|
||||
size_t operator-(const RangedPtr<T>& other) const {
|
||||
MOZ_ASSERT(ptr >= other.ptr);
|
||||
return PointerRangeSize(other.ptr, ptr);
|
||||
}
|
||||
size_t operator-(const RangedPtr<T>& aOther) const
|
||||
{
|
||||
MOZ_ASSERT(mPtr >= aOther.mPtr);
|
||||
return PointerRangeSize(aOther.mPtr, mPtr);
|
||||
}
|
||||
|
||||
private:
|
||||
RangedPtr() MOZ_DELETE;
|
||||
T* operator&() MOZ_DELETE;
|
||||
private:
|
||||
RangedPtr() MOZ_DELETE;
|
||||
T* operator&() MOZ_DELETE;
|
||||
};
|
||||
|
||||
} /* namespace mozilla */
|
||||
|
@ -18,38 +18,38 @@ namespace mozilla {
|
||||
/* Useful for implementing containers that assert non-reentrancy */
|
||||
class ReentrancyGuard
|
||||
{
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
#ifdef DEBUG
|
||||
bool& entered;
|
||||
bool& mEntered;
|
||||
#endif
|
||||
|
||||
public:
|
||||
template<class T>
|
||||
public:
|
||||
template<class T>
|
||||
#ifdef DEBUG
|
||||
ReentrancyGuard(T& obj
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: entered(obj.entered)
|
||||
ReentrancyGuard(T& aObj
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: mEntered(aObj.mEntered)
|
||||
#else
|
||||
ReentrancyGuard(T&
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
ReentrancyGuard(T&
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
#endif
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(!entered);
|
||||
entered = true;
|
||||
MOZ_ASSERT(!mEntered);
|
||||
mEntered = true;
|
||||
#endif
|
||||
}
|
||||
~ReentrancyGuard()
|
||||
{
|
||||
}
|
||||
~ReentrancyGuard()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
entered = false;
|
||||
mEntered = false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ReentrancyGuard(const ReentrancyGuard&) MOZ_DELETE;
|
||||
void operator=(const ReentrancyGuard&) MOZ_DELETE;
|
||||
private:
|
||||
ReentrancyGuard(const ReentrancyGuard&) MOZ_DELETE;
|
||||
void operator=(const ReentrancyGuard&) MOZ_DELETE;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
414
mfbt/RefPtr.h
414
mfbt/RefPtr.h
@ -12,13 +12,15 @@
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/NullPtr.h"
|
||||
#include "mozilla/RefCountType.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
#if defined(MOZILLA_INTERNAL_API)
|
||||
#include "nsXPCOM.h"
|
||||
#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
|
||||
#endif
|
||||
|
||||
@ -65,20 +67,21 @@ const MozRefCountType DEAD = 0xffffdead;
|
||||
#ifdef MOZ_REFCOUNTED_LEAK_CHECKING
|
||||
class RefCountLogger
|
||||
{
|
||||
public:
|
||||
static void logAddRef(const void* aPointer, MozRefCountType aRefCount,
|
||||
const char* aTypeName, uint32_t aInstanceSize)
|
||||
{
|
||||
MOZ_ASSERT(aRefCount != DEAD);
|
||||
NS_LogAddRef(const_cast<void*>(aPointer), aRefCount, aTypeName, aInstanceSize);
|
||||
}
|
||||
public:
|
||||
static void logAddRef(const void* aPointer, MozRefCountType aRefCount,
|
||||
const char* aTypeName, uint32_t aInstanceSize)
|
||||
{
|
||||
MOZ_ASSERT(aRefCount != DEAD);
|
||||
NS_LogAddRef(const_cast<void*>(aPointer), aRefCount, aTypeName,
|
||||
aInstanceSize);
|
||||
}
|
||||
|
||||
static void logRelease(const void* aPointer, MozRefCountType aRefCount,
|
||||
const char* aTypeName)
|
||||
{
|
||||
MOZ_ASSERT(aRefCount != DEAD);
|
||||
NS_LogRelease(const_cast<void*>(aPointer), aRefCount, aTypeName);
|
||||
}
|
||||
static void logRelease(const void* aPointer, MozRefCountType aRefCount,
|
||||
const char* aTypeName)
|
||||
{
|
||||
MOZ_ASSERT(aRefCount != DEAD);
|
||||
NS_LogRelease(const_cast<void*>(aPointer), aRefCount, aTypeName);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -92,66 +95,69 @@ enum RefCountAtomicity
|
||||
template<typename T, RefCountAtomicity Atomicity>
|
||||
class RefCounted
|
||||
{
|
||||
friend class RefPtr<T>;
|
||||
friend class RefPtr<T>;
|
||||
|
||||
protected:
|
||||
RefCounted() : refCnt(0) { }
|
||||
~RefCounted() {
|
||||
MOZ_ASSERT(refCnt == detail::DEAD);
|
||||
}
|
||||
protected:
|
||||
RefCounted() : mRefCnt(0) {}
|
||||
~RefCounted() { MOZ_ASSERT(mRefCnt == detail::DEAD); }
|
||||
|
||||
public:
|
||||
// Compatibility with nsRefPtr.
|
||||
void AddRef() const {
|
||||
// Note: this method must be thread safe for AtomicRefCounted.
|
||||
MOZ_ASSERT(int32_t(refCnt) >= 0);
|
||||
public:
|
||||
// Compatibility with nsRefPtr.
|
||||
void AddRef() const
|
||||
{
|
||||
// Note: this method must be thread safe for AtomicRefCounted.
|
||||
MOZ_ASSERT(int32_t(mRefCnt) >= 0);
|
||||
#ifndef MOZ_REFCOUNTED_LEAK_CHECKING
|
||||
++refCnt;
|
||||
++mRefCnt;
|
||||
#else
|
||||
const char* type = static_cast<const T*>(this)->typeName();
|
||||
uint32_t size = static_cast<const T*>(this)->typeSize();
|
||||
const void* ptr = static_cast<const T*>(this);
|
||||
MozRefCountType cnt = ++refCnt;
|
||||
detail::RefCountLogger::logAddRef(ptr, cnt, type, size);
|
||||
const char* type = static_cast<const T*>(this)->typeName();
|
||||
uint32_t size = static_cast<const T*>(this)->typeSize();
|
||||
const void* ptr = static_cast<const T*>(this);
|
||||
MozRefCountType cnt = ++mRefCnt;
|
||||
detail::RefCountLogger::logAddRef(ptr, cnt, type, size);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void Release() const {
|
||||
// Note: this method must be thread safe for AtomicRefCounted.
|
||||
MOZ_ASSERT(int32_t(refCnt) > 0);
|
||||
void Release() const
|
||||
{
|
||||
// Note: this method must be thread safe for AtomicRefCounted.
|
||||
MOZ_ASSERT(int32_t(mRefCnt) > 0);
|
||||
#ifndef MOZ_REFCOUNTED_LEAK_CHECKING
|
||||
MozRefCountType cnt = --refCnt;
|
||||
MozRefCountType cnt = --mRefCnt;
|
||||
#else
|
||||
const char* type = static_cast<const T*>(this)->typeName();
|
||||
const void* ptr = static_cast<const T*>(this);
|
||||
MozRefCountType cnt = --refCnt;
|
||||
// Note: it's not safe to touch |this| after decrementing the refcount,
|
||||
// except for below.
|
||||
detail::RefCountLogger::logRelease(ptr, cnt, type);
|
||||
const char* type = static_cast<const T*>(this)->typeName();
|
||||
const void* ptr = static_cast<const T*>(this);
|
||||
MozRefCountType cnt = --mRefCnt;
|
||||
// Note: it's not safe to touch |this| after decrementing the refcount,
|
||||
// except for below.
|
||||
detail::RefCountLogger::logRelease(ptr, cnt, type);
|
||||
#endif
|
||||
if (0 == cnt) {
|
||||
// Because we have atomically decremented the refcount above, only
|
||||
// one thread can get a 0 count here, so as long as we can assume that
|
||||
// everything else in the system is accessing this object through
|
||||
// RefPtrs, it's safe to access |this| here.
|
||||
if (0 == cnt) {
|
||||
// Because we have atomically decremented the refcount above, only
|
||||
// one thread can get a 0 count here, so as long as we can assume that
|
||||
// everything else in the system is accessing this object through
|
||||
// RefPtrs, it's safe to access |this| here.
|
||||
#ifdef DEBUG
|
||||
refCnt = detail::DEAD;
|
||||
mRefCnt = detail::DEAD;
|
||||
#endif
|
||||
delete static_cast<const T*>(this);
|
||||
}
|
||||
delete static_cast<const T*>(this);
|
||||
}
|
||||
}
|
||||
|
||||
// Compatibility with wtf::RefPtr.
|
||||
void ref() { AddRef(); }
|
||||
void deref() { Release(); }
|
||||
MozRefCountType refCount() const { return refCnt; }
|
||||
bool hasOneRef() const {
|
||||
MOZ_ASSERT(refCnt > 0);
|
||||
return refCnt == 1;
|
||||
}
|
||||
// Compatibility with wtf::RefPtr.
|
||||
void ref() { AddRef(); }
|
||||
void deref() { Release(); }
|
||||
MozRefCountType refCount() const { return mRefCnt; }
|
||||
bool hasOneRef() const
|
||||
{
|
||||
MOZ_ASSERT(mRefCnt > 0);
|
||||
return mRefCnt == 1;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable typename Conditional<Atomicity == AtomicRefCount, Atomic<MozRefCountType>, MozRefCountType>::Type refCnt;
|
||||
private:
|
||||
mutable typename Conditional<Atomicity == AtomicRefCount,
|
||||
Atomic<MozRefCountType>,
|
||||
MozRefCountType>::Type mRefCnt;
|
||||
};
|
||||
|
||||
#ifdef MOZ_REFCOUNTED_LEAK_CHECKING
|
||||
@ -169,16 +175,17 @@ class RefCounted
|
||||
const char* typeName() const { return #T; } \
|
||||
size_t typeSize() const { return sizeof(*this); }
|
||||
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template<typename T>
|
||||
class RefCounted : public detail::RefCounted<T, detail::NonAtomicRefCount>
|
||||
{
|
||||
public:
|
||||
~RefCounted() {
|
||||
static_assert(IsBaseOf<RefCounted, T>::value,
|
||||
"T must derive from RefCounted<T>");
|
||||
}
|
||||
public:
|
||||
~RefCounted()
|
||||
{
|
||||
static_assert(IsBaseOf<RefCounted, T>::value,
|
||||
"T must derive from RefCounted<T>");
|
||||
}
|
||||
};
|
||||
|
||||
namespace external {
|
||||
@ -191,16 +198,18 @@ namespace external {
|
||||
* instead.
|
||||
*/
|
||||
template<typename T>
|
||||
class AtomicRefCounted : public mozilla::detail::RefCounted<T, mozilla::detail::AtomicRefCount>
|
||||
class AtomicRefCounted :
|
||||
public mozilla::detail::RefCounted<T, mozilla::detail::AtomicRefCount>
|
||||
{
|
||||
public:
|
||||
~AtomicRefCounted() {
|
||||
static_assert(IsBaseOf<AtomicRefCounted, T>::value,
|
||||
"T must derive from AtomicRefCounted<T>");
|
||||
}
|
||||
public:
|
||||
~AtomicRefCounted()
|
||||
{
|
||||
static_assert(IsBaseOf<AtomicRefCounted, T>::value,
|
||||
"T must derive from AtomicRefCounted<T>");
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace external
|
||||
|
||||
/**
|
||||
* RefPtr points to a refcounted thing that has AddRef and Release
|
||||
@ -215,73 +224,83 @@ class AtomicRefCounted : public mozilla::detail::RefCounted<T, mozilla::detail::
|
||||
template<typename T>
|
||||
class RefPtr
|
||||
{
|
||||
// To allow them to use unref()
|
||||
friend class TemporaryRef<T>;
|
||||
friend class OutParamRef<T>;
|
||||
// To allow them to use unref()
|
||||
friend class TemporaryRef<T>;
|
||||
friend class OutParamRef<T>;
|
||||
|
||||
struct DontRef {};
|
||||
struct DontRef {};
|
||||
|
||||
public:
|
||||
RefPtr() : ptr(0) { }
|
||||
RefPtr(const RefPtr& o) : ptr(ref(o.ptr)) {}
|
||||
MOZ_IMPLICIT RefPtr(const TemporaryRef<T>& o) : ptr(o.drop()) {}
|
||||
MOZ_IMPLICIT RefPtr(T* t) : ptr(ref(t)) {}
|
||||
public:
|
||||
RefPtr() : mPtr(0) {}
|
||||
RefPtr(const RefPtr& aOther) : mPtr(ref(aOther.mPtr)) {}
|
||||
MOZ_IMPLICIT RefPtr(const TemporaryRef<T>& aOther) : mPtr(aOther.drop()) {}
|
||||
MOZ_IMPLICIT RefPtr(T* aVal) : mPtr(ref(aVal)) {}
|
||||
|
||||
template<typename U>
|
||||
RefPtr(const RefPtr<U>& o) : ptr(ref(o.get())) {}
|
||||
template<typename U>
|
||||
RefPtr(const RefPtr<U>& aOther) : mPtr(ref(aOther.get())) {}
|
||||
|
||||
~RefPtr() { unref(ptr); }
|
||||
~RefPtr() { unref(mPtr); }
|
||||
|
||||
RefPtr& operator=(const RefPtr& o) {
|
||||
assign(ref(o.ptr));
|
||||
return *this;
|
||||
}
|
||||
RefPtr& operator=(const TemporaryRef<T>& o) {
|
||||
assign(o.drop());
|
||||
return *this;
|
||||
}
|
||||
RefPtr& operator=(T* t) {
|
||||
assign(ref(t));
|
||||
return *this;
|
||||
RefPtr& operator=(const RefPtr& aOther)
|
||||
{
|
||||
assign(ref(aOther.mPtr));
|
||||
return *this;
|
||||
}
|
||||
RefPtr& operator=(const TemporaryRef<T>& aOther)
|
||||
{
|
||||
assign(aOther.drop());
|
||||
return *this;
|
||||
}
|
||||
RefPtr& operator=(T* aVal)
|
||||
{
|
||||
assign(ref(aVal));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
RefPtr& operator=(const RefPtr<U>& aOther)
|
||||
{
|
||||
assign(ref(aOther.get()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
TemporaryRef<T> forget()
|
||||
{
|
||||
T* tmp = mPtr;
|
||||
mPtr = nullptr;
|
||||
return TemporaryRef<T>(tmp, DontRef());
|
||||
}
|
||||
|
||||
T* get() const { return mPtr; }
|
||||
operator T*() const { return mPtr; }
|
||||
T* operator->() const { return mPtr; }
|
||||
T& operator*() const { return *mPtr; }
|
||||
template<typename U>
|
||||
operator TemporaryRef<U>() { return TemporaryRef<U>(mPtr); }
|
||||
|
||||
private:
|
||||
void assign(T* aVal)
|
||||
{
|
||||
unref(mPtr);
|
||||
mPtr = aVal;
|
||||
}
|
||||
|
||||
T* mPtr;
|
||||
|
||||
static MOZ_ALWAYS_INLINE T* ref(T* aVal)
|
||||
{
|
||||
if (aVal) {
|
||||
aVal->AddRef();
|
||||
}
|
||||
return aVal;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
RefPtr& operator=(const RefPtr<U>& o) {
|
||||
assign(ref(o.get()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
TemporaryRef<T> forget() {
|
||||
T* tmp = ptr;
|
||||
ptr = 0;
|
||||
return TemporaryRef<T>(tmp, DontRef());
|
||||
}
|
||||
|
||||
T* get() const { return ptr; }
|
||||
operator T*() const { return ptr; }
|
||||
T* operator->() const { return ptr; }
|
||||
T& operator*() const { return *ptr; }
|
||||
template<typename U>
|
||||
operator TemporaryRef<U>() { return TemporaryRef<U>(ptr); }
|
||||
|
||||
private:
|
||||
void assign(T* t) {
|
||||
unref(ptr);
|
||||
ptr = t;
|
||||
}
|
||||
|
||||
T* ptr;
|
||||
|
||||
static MOZ_ALWAYS_INLINE T* ref(T* t) {
|
||||
if (t)
|
||||
t->AddRef();
|
||||
return t;
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE void unref(T* t) {
|
||||
if (t)
|
||||
t->Release();
|
||||
static MOZ_ALWAYS_INLINE void unref(T* aVal)
|
||||
{
|
||||
if (aVal) {
|
||||
aVal->Release();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -293,33 +312,34 @@ class RefPtr
|
||||
template<typename T>
|
||||
class TemporaryRef
|
||||
{
|
||||
// To allow it to construct TemporaryRef from a bare T*
|
||||
friend class RefPtr<T>;
|
||||
// To allow it to construct TemporaryRef from a bare T*
|
||||
friend class RefPtr<T>;
|
||||
|
||||
typedef typename RefPtr<T>::DontRef DontRef;
|
||||
typedef typename RefPtr<T>::DontRef DontRef;
|
||||
|
||||
public:
|
||||
MOZ_IMPLICIT TemporaryRef(T* t) : ptr(RefPtr<T>::ref(t)) {}
|
||||
TemporaryRef(const TemporaryRef& o) : ptr(o.drop()) {}
|
||||
public:
|
||||
MOZ_IMPLICIT TemporaryRef(T* aVal) : mPtr(RefPtr<T>::ref(aVal)) {}
|
||||
TemporaryRef(const TemporaryRef& aOther) : mPtr(aOther.drop()) {}
|
||||
|
||||
template<typename U>
|
||||
TemporaryRef(const TemporaryRef<U>& o) : ptr(o.drop()) {}
|
||||
template<typename U>
|
||||
TemporaryRef(const TemporaryRef<U>& aOther) : mPtr(aOther.drop()) {}
|
||||
|
||||
~TemporaryRef() { RefPtr<T>::unref(ptr); }
|
||||
~TemporaryRef() { RefPtr<T>::unref(mPtr); }
|
||||
|
||||
T* drop() const {
|
||||
T* tmp = ptr;
|
||||
ptr = 0;
|
||||
return tmp;
|
||||
}
|
||||
T* drop() const
|
||||
{
|
||||
T* tmp = mPtr;
|
||||
mPtr = nullptr;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
private:
|
||||
TemporaryRef(T* t, const DontRef&) : ptr(t) {}
|
||||
private:
|
||||
TemporaryRef(T* aVal, const DontRef&) : mPtr(aVal) {}
|
||||
|
||||
mutable T* ptr;
|
||||
mutable T* mPtr;
|
||||
|
||||
TemporaryRef() MOZ_DELETE;
|
||||
void operator=(const TemporaryRef&) MOZ_DELETE;
|
||||
TemporaryRef() MOZ_DELETE;
|
||||
void operator=(const TemporaryRef&) MOZ_DELETE;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -339,24 +359,25 @@ class TemporaryRef
|
||||
template<typename T>
|
||||
class OutParamRef
|
||||
{
|
||||
friend OutParamRef byRef<T>(RefPtr<T>&);
|
||||
friend OutParamRef byRef<T>(RefPtr<T>&);
|
||||
|
||||
public:
|
||||
~OutParamRef() {
|
||||
RefPtr<T>::unref(refPtr.ptr);
|
||||
refPtr.ptr = tmp;
|
||||
}
|
||||
public:
|
||||
~OutParamRef()
|
||||
{
|
||||
RefPtr<T>::unref(mRefPtr.mPtr);
|
||||
mRefPtr.mPtr = mTmp;
|
||||
}
|
||||
|
||||
operator T**() { return &tmp; }
|
||||
operator T**() { return &mTmp; }
|
||||
|
||||
private:
|
||||
explicit OutParamRef(RefPtr<T>& p) : refPtr(p), tmp(p.get()) {}
|
||||
private:
|
||||
explicit OutParamRef(RefPtr<T>& p) : mRefPtr(p), mTmp(p.get()) {}
|
||||
|
||||
RefPtr<T>& refPtr;
|
||||
T* tmp;
|
||||
RefPtr<T>& mRefPtr;
|
||||
T* mTmp;
|
||||
|
||||
OutParamRef() MOZ_DELETE;
|
||||
OutParamRef& operator=(const OutParamRef&) MOZ_DELETE;
|
||||
OutParamRef() MOZ_DELETE;
|
||||
OutParamRef& operator=(const OutParamRef&) MOZ_DELETE;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -364,9 +385,9 @@ class OutParamRef
|
||||
*/
|
||||
template<typename T>
|
||||
OutParamRef<T>
|
||||
byRef(RefPtr<T>& ptr)
|
||||
byRef(RefPtr<T>& aPtr)
|
||||
{
|
||||
return OutParamRef<T>(ptr);
|
||||
return OutParamRef<T>(aPtr);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
@ -382,19 +403,20 @@ using namespace mozilla;
|
||||
struct Foo : public RefCounted<Foo>
|
||||
{
|
||||
MOZ_DECLARE_REFCOUNTED_TYPENAME(Foo)
|
||||
Foo() : dead(false) { }
|
||||
~Foo() {
|
||||
MOZ_ASSERT(!dead);
|
||||
dead = true;
|
||||
numDestroyed++;
|
||||
Foo() : mDead(false) {}
|
||||
~Foo()
|
||||
{
|
||||
MOZ_ASSERT(!mDead);
|
||||
mDead = true;
|
||||
sNumDestroyed++;
|
||||
}
|
||||
|
||||
bool dead;
|
||||
static int numDestroyed;
|
||||
bool mDead;
|
||||
static int sNumDestroyed;
|
||||
};
|
||||
int Foo::numDestroyed;
|
||||
int Foo::sNumDestroyed;
|
||||
|
||||
struct Bar : public Foo { };
|
||||
struct Bar : public Foo {};
|
||||
|
||||
TemporaryRef<Foo>
|
||||
NewFoo()
|
||||
@ -445,25 +467,25 @@ main(int argc, char** argv)
|
||||
// This should blow up
|
||||
// Foo* f = new Foo(); delete f;
|
||||
|
||||
MOZ_ASSERT(0 == Foo::numDestroyed);
|
||||
MOZ_ASSERT(0 == Foo::sNumDestroyed);
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
MOZ_ASSERT(f->refCount() == 1);
|
||||
}
|
||||
MOZ_ASSERT(1 == Foo::numDestroyed);
|
||||
MOZ_ASSERT(1 == Foo::sNumDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> f1 = 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();
|
||||
MOZ_ASSERT(3 == Foo::numDestroyed);
|
||||
MOZ_ASSERT(3 == Foo::sNumDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(4 == Foo::numDestroyed);
|
||||
MOZ_ASSERT(4 == Foo::sNumDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> f1;
|
||||
@ -471,56 +493,56 @@ main(int argc, char** argv)
|
||||
f1 = new Foo();
|
||||
RefPtr<Foo> f2(f1);
|
||||
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();
|
||||
f.forget();
|
||||
MOZ_ASSERT(6 == Foo::numDestroyed);
|
||||
MOZ_ASSERT(6 == Foo::sNumDestroyed);
|
||||
}
|
||||
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
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();
|
||||
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();
|
||||
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();
|
||||
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();
|
||||
}
|
||||
MOZ_ASSERT(13 == Foo::numDestroyed);
|
||||
MOZ_ASSERT(13 == Foo::sNumDestroyed);
|
||||
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -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
|
||||
* 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/. */
|
||||
@ -28,78 +29,85 @@ namespace mozilla {
|
||||
template<typename T, typename S>
|
||||
class RollingMean
|
||||
{
|
||||
private:
|
||||
size_t mInsertIndex;
|
||||
size_t mMaxValues;
|
||||
Vector<T> mValues;
|
||||
S mTotal;
|
||||
private:
|
||||
size_t mInsertIndex;
|
||||
size_t mMaxValues;
|
||||
Vector<T> mValues;
|
||||
S mTotal;
|
||||
|
||||
public:
|
||||
static_assert(!IsFloatingPoint<T>::value,
|
||||
"floating-point types are unsupported due to rounding "
|
||||
"errors");
|
||||
public:
|
||||
static_assert(!IsFloatingPoint<T>::value,
|
||||
"floating-point types are unsupported due to rounding "
|
||||
"errors");
|
||||
|
||||
explicit RollingMean(size_t aMaxValues)
|
||||
: mInsertIndex(0),
|
||||
mMaxValues(aMaxValues),
|
||||
mTotal(0)
|
||||
{
|
||||
MOZ_ASSERT(aMaxValues > 0);
|
||||
}
|
||||
explicit RollingMean(size_t aMaxValues)
|
||||
: mInsertIndex(0),
|
||||
mMaxValues(aMaxValues),
|
||||
mTotal(0)
|
||||
{
|
||||
MOZ_ASSERT(aMaxValues > 0);
|
||||
}
|
||||
|
||||
RollingMean& operator=(RollingMean&& aOther) {
|
||||
MOZ_ASSERT(this != &aOther, "self-assignment is forbidden");
|
||||
this->~RollingMean();
|
||||
new(this) RollingMean(aOther.mMaxValues);
|
||||
mInsertIndex = aOther.mInsertIndex;
|
||||
mTotal = aOther.mTotal;
|
||||
mValues.swap(aOther.mValues);
|
||||
return *this;
|
||||
}
|
||||
RollingMean& operator=(RollingMean&& aOther)
|
||||
{
|
||||
MOZ_ASSERT(this != &aOther, "self-assignment is forbidden");
|
||||
this->~RollingMean();
|
||||
new(this) RollingMean(aOther.mMaxValues);
|
||||
mInsertIndex = aOther.mInsertIndex;
|
||||
mTotal = aOther.mTotal;
|
||||
mValues.swap(aOther.mValues);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a value into the rolling mean.
|
||||
*/
|
||||
bool insert(T aValue) {
|
||||
MOZ_ASSERT(mValues.length() <= mMaxValues);
|
||||
/**
|
||||
* Insert a value into the rolling mean.
|
||||
*/
|
||||
bool insert(T aValue)
|
||||
{
|
||||
MOZ_ASSERT(mValues.length() <= mMaxValues);
|
||||
|
||||
if (mValues.length() == mMaxValues) {
|
||||
mTotal = mTotal - mValues[mInsertIndex] + aValue;
|
||||
mValues[mInsertIndex] = aValue;
|
||||
} else {
|
||||
if (!mValues.append(aValue))
|
||||
return false;
|
||||
mTotal = mTotal + aValue;
|
||||
if (mValues.length() == mMaxValues) {
|
||||
mTotal = mTotal - mValues[mInsertIndex] + aValue;
|
||||
mValues[mInsertIndex] = aValue;
|
||||
} else {
|
||||
if (!mValues.append(aValue)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mInsertIndex = (mInsertIndex + 1) % mMaxValues;
|
||||
return true;
|
||||
mTotal = mTotal + aValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the rolling mean.
|
||||
*/
|
||||
T mean() {
|
||||
MOZ_ASSERT(!empty());
|
||||
return T(mTotal / mValues.length());
|
||||
}
|
||||
mInsertIndex = (mInsertIndex + 1) % mMaxValues;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool empty() {
|
||||
return mValues.empty();
|
||||
}
|
||||
/**
|
||||
* Calculate the rolling mean.
|
||||
*/
|
||||
T mean()
|
||||
{
|
||||
MOZ_ASSERT(!empty());
|
||||
return T(mTotal / mValues.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all values from the rolling mean.
|
||||
*/
|
||||
void clear() {
|
||||
mValues.clear();
|
||||
mInsertIndex = 0;
|
||||
mTotal = T(0);
|
||||
}
|
||||
bool empty()
|
||||
{
|
||||
return mValues.empty();
|
||||
}
|
||||
|
||||
size_t maxValues() {
|
||||
return mMaxValues;
|
||||
}
|
||||
/**
|
||||
* Remove all values from the rolling mean.
|
||||
*/
|
||||
void clear()
|
||||
{
|
||||
mValues.clear();
|
||||
mInsertIndex = 0;
|
||||
mTotal = T(0);
|
||||
}
|
||||
|
||||
size_t maxValues()
|
||||
{
|
||||
return mMaxValues;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -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
|
||||
* 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/. */
|
||||
@ -12,14 +14,14 @@ using mozilla::NativeEndian;
|
||||
using mozilla::SHA1Sum;
|
||||
|
||||
static inline uint32_t
|
||||
SHA_ROTL(uint32_t t, uint32_t n)
|
||||
SHA_ROTL(uint32_t aT, uint32_t aN)
|
||||
{
|
||||
MOZ_ASSERT(n < 32);
|
||||
return (t << n) | (t >> (32 - n));
|
||||
MOZ_ASSERT(aN < 32);
|
||||
return (aT << aN) | (aT >> (32 - aN));
|
||||
}
|
||||
|
||||
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_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)
|
||||
|
||||
SHA1Sum::SHA1Sum()
|
||||
: size(0), mDone(false)
|
||||
: mSize(0), mDone(false)
|
||||
{
|
||||
// Initialize H with constants from FIPS180-1.
|
||||
H[0] = 0x67452301L;
|
||||
H[1] = 0xefcdab89L;
|
||||
H[2] = 0x98badcfeL;
|
||||
H[3] = 0x10325476L;
|
||||
H[4] = 0xc3d2e1f0L;
|
||||
mH[0] = 0x67452301L;
|
||||
mH[1] = 0xefcdab89L;
|
||||
mH[2] = 0x98badcfeL;
|
||||
mH[3] = 0x10325476L;
|
||||
mH[4] = 0xc3d2e1f0L;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -79,42 +81,46 @@ SHA1Sum::SHA1Sum()
|
||||
* SHA: Add data to context.
|
||||
*/
|
||||
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.");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
unsigned int togo;
|
||||
if (lenB > 0) {
|
||||
togo = 64U - lenB;
|
||||
if (len < togo)
|
||||
togo = len;
|
||||
memcpy(u.b + lenB, data, togo);
|
||||
len -= togo;
|
||||
if (aLen < togo) {
|
||||
togo = aLen;
|
||||
}
|
||||
memcpy(mU.mB + lenB, data, togo);
|
||||
aLen -= togo;
|
||||
data += togo;
|
||||
lenB = (lenB + togo) & 63U;
|
||||
if (!lenB)
|
||||
shaCompress(&H[H2X], u.w);
|
||||
if (!lenB) {
|
||||
shaCompress(&mH[H2X], mU.mW);
|
||||
}
|
||||
}
|
||||
|
||||
while (len >= 64U) {
|
||||
len -= 64U;
|
||||
shaCompress(&H[H2X], reinterpret_cast<const uint32_t*>(data));
|
||||
while (aLen >= 64U) {
|
||||
aLen -= 64U;
|
||||
shaCompress(&mH[H2X], reinterpret_cast<const uint32_t*>(data));
|
||||
data += 64U;
|
||||
}
|
||||
|
||||
if (len > 0)
|
||||
memcpy(u.b, data, len);
|
||||
if (aLen > 0) {
|
||||
memcpy(mU.mB, data, aLen);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -122,12 +128,12 @@ SHA1Sum::update(const void* dataIn, uint32_t len)
|
||||
* SHA: Generate hash value
|
||||
*/
|
||||
void
|
||||
SHA1Sum::finish(SHA1Sum::Hash& hashOut)
|
||||
SHA1Sum::finish(SHA1Sum::Hash& aHashOut)
|
||||
{
|
||||
MOZ_ASSERT(!mDone, "SHA1Sum can only be used to compute a single hash.");
|
||||
|
||||
uint64_t size2 = size;
|
||||
uint32_t lenB = uint32_t(size2) & 63;
|
||||
uint64_t size = mSize;
|
||||
uint32_t lenB = uint32_t(size) & 63;
|
||||
|
||||
static const uint8_t bulk_pad[64] =
|
||||
{ 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. */
|
||||
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. */
|
||||
size2 <<= 3;
|
||||
u.w[14] = NativeEndian::swapToBigEndian(uint32_t(size2 >> 32));
|
||||
u.w[15] = NativeEndian::swapToBigEndian(uint32_t(size2));
|
||||
shaCompress(&H[H2X], u.w);
|
||||
size <<= 3;
|
||||
mU.mW[14] = NativeEndian::swapToBigEndian(uint32_t(size >> 32));
|
||||
mU.mW[15] = NativeEndian::swapToBigEndian(uint32_t(size));
|
||||
shaCompress(&mH[H2X], mU.mW);
|
||||
|
||||
/* Output hash. */
|
||||
u.w[0] = NativeEndian::swapToBigEndian(H[0]);
|
||||
u.w[1] = NativeEndian::swapToBigEndian(H[1]);
|
||||
u.w[2] = NativeEndian::swapToBigEndian(H[2]);
|
||||
u.w[3] = NativeEndian::swapToBigEndian(H[3]);
|
||||
u.w[4] = NativeEndian::swapToBigEndian(H[4]);
|
||||
memcpy(hashOut, u.w, 20);
|
||||
mU.mW[0] = NativeEndian::swapToBigEndian(mH[0]);
|
||||
mU.mW[1] = NativeEndian::swapToBigEndian(mH[1]);
|
||||
mU.mW[2] = NativeEndian::swapToBigEndian(mH[2]);
|
||||
mU.mW[3] = NativeEndian::swapToBigEndian(mH[3]);
|
||||
mU.mW[4] = NativeEndian::swapToBigEndian(mH[4]);
|
||||
memcpy(aHashOut, mU.mW, 20);
|
||||
mDone = true;
|
||||
}
|
||||
|
||||
@ -202,12 +208,12 @@ SHA1Sum::finish(SHA1Sum::Hash& hashOut)
|
||||
* code on AMD64.
|
||||
*/
|
||||
static void
|
||||
shaCompress(volatile unsigned *X, const uint32_t *inbuf)
|
||||
shaCompress(volatile unsigned* aX, const uint32_t* aBuf)
|
||||
{
|
||||
unsigned A, B, C, D, E;
|
||||
|
||||
#define XH(n) X[n - H2X]
|
||||
#define XW(n) X[n - W2X]
|
||||
#define XH(n) aX[n - H2X]
|
||||
#define XW(n) aX[n - W2X]
|
||||
|
||||
#define K0 0x5a827999L
|
||||
#define K1 0x6ed9eba1L
|
||||
@ -223,7 +229,7 @@ shaCompress(volatile unsigned *X, const uint32_t *inbuf)
|
||||
#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)
|
||||
|
||||
#define LOAD(n) XW(n) = NativeEndian::swapToBigEndian(inbuf[n])
|
||||
#define LOAD(n) XW(n) = NativeEndian::swapToBigEndian(aBuf[n])
|
||||
|
||||
A = XH(0);
|
||||
B = XH(1);
|
||||
|
31
mfbt/SHA1.h
31
mfbt/SHA1.h
@ -36,25 +36,26 @@ namespace mozilla {
|
||||
*/
|
||||
class SHA1Sum
|
||||
{
|
||||
union {
|
||||
uint32_t w[16]; /* input buffer */
|
||||
uint8_t b[64];
|
||||
} u;
|
||||
uint64_t size; /* count of hashed bytes. */
|
||||
unsigned H[22]; /* 5 state variables, 16 tmp values, 1 extra */
|
||||
bool mDone;
|
||||
union
|
||||
{
|
||||
uint32_t mW[16]; /* input buffer */
|
||||
uint8_t mB[64];
|
||||
} mU;
|
||||
uint64_t mSize; /* count of hashed bytes. */
|
||||
unsigned mH[22]; /* 5 state variables, 16 tmp values, 1 extra */
|
||||
bool mDone;
|
||||
|
||||
public:
|
||||
MFBT_API SHA1Sum();
|
||||
public:
|
||||
MFBT_API SHA1Sum();
|
||||
|
||||
static const size_t HashSize = 20;
|
||||
typedef uint8_t Hash[HashSize];
|
||||
static const size_t kHashSize = 20;
|
||||
typedef uint8_t Hash[kHashSize];
|
||||
|
||||
/* Add len bytes of dataIn to the data sequence being hashed. */
|
||||
MFBT_API void update(const void* dataIn, uint32_t len);
|
||||
/* Add len bytes of dataIn to the data sequence being hashed. */
|
||||
MFBT_API void update(const void* aData, uint32_t aLength);
|
||||
|
||||
/* Compute the final hash of all data into hashOut. */
|
||||
MFBT_API void finish(SHA1Sum::Hash& hashOut);
|
||||
/* Compute the final hash of all data into hashOut. */
|
||||
MFBT_API void finish(SHA1Sum::Hash& aHashOut);
|
||||
};
|
||||
|
||||
} /* namespace mozilla */
|
||||
|
261
mfbt/Scoped.h
261
mfbt/Scoped.h
@ -64,7 +64,8 @@ namespace mozilla {
|
||||
* Scoped is a helper to create RAII wrappers
|
||||
* Type argument |Traits| is expected to have the following structure:
|
||||
*
|
||||
* struct Traits {
|
||||
* struct Traits
|
||||
* {
|
||||
* // Define the type of the value stored in the wrapper
|
||||
* typedef value_type type;
|
||||
* // Returns the value corresponding to the uninitialized or freed state
|
||||
@ -77,103 +78,102 @@ namespace mozilla {
|
||||
template<typename Traits>
|
||||
class Scoped
|
||||
{
|
||||
public:
|
||||
typedef typename Traits::type Resource;
|
||||
public:
|
||||
typedef typename Traits::type Resource;
|
||||
|
||||
explicit Scoped(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
|
||||
: value(Traits::empty())
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
explicit Scoped(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
|
||||
: mValue(Traits::empty())
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
explicit Scoped(const Resource& v
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: value(v)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
explicit Scoped(const Resource& aValue
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: mValue(aValue)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
/* Move constructor. */
|
||||
explicit Scoped(Scoped&& v
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: value(Move(v.value))
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
v.value = Traits::empty();
|
||||
}
|
||||
/* Move constructor. */
|
||||
explicit Scoped(Scoped&& aOther
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: mValue(Move(aOther.mValue))
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
aOther.mValue = Traits::empty();
|
||||
}
|
||||
|
||||
~Scoped() {
|
||||
Traits::release(value);
|
||||
}
|
||||
~Scoped() { Traits::release(mValue); }
|
||||
|
||||
// Constant getter
|
||||
operator const Resource&() const { return value; }
|
||||
const Resource& operator->() const { return value; }
|
||||
const Resource& get() const { return value; }
|
||||
// Non-constant getter.
|
||||
Resource& rwget() { return value; }
|
||||
// Constant getter
|
||||
operator const Resource&() const { return mValue; }
|
||||
const Resource& operator->() const { return mValue; }
|
||||
const Resource& get() const { return mValue; }
|
||||
// Non-constant getter.
|
||||
Resource& rwget() { return mValue; }
|
||||
|
||||
/*
|
||||
* Forget the resource.
|
||||
*
|
||||
* Once |forget| has been called, the |Scoped| is neutralized, i.e. it will
|
||||
* have no effect at destruction (unless it is reset to another resource by
|
||||
* |operator=|).
|
||||
*
|
||||
* @return The original resource.
|
||||
*/
|
||||
Resource forget() {
|
||||
Resource tmp = value;
|
||||
value = Traits::empty();
|
||||
return tmp;
|
||||
}
|
||||
/*
|
||||
* Forget the resource.
|
||||
*
|
||||
* Once |forget| has been called, the |Scoped| is neutralized, i.e. it will
|
||||
* have no effect at destruction (unless it is reset to another resource by
|
||||
* |operator=|).
|
||||
*
|
||||
* @return The original resource.
|
||||
*/
|
||||
Resource forget()
|
||||
{
|
||||
Resource tmp = mValue;
|
||||
mValue = Traits::empty();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform immediate clean-up of this |Scoped|.
|
||||
*
|
||||
* If this |Scoped| is currently empty, this method has no effect.
|
||||
*/
|
||||
void dispose() {
|
||||
Traits::release(value);
|
||||
value = Traits::empty();
|
||||
}
|
||||
/*
|
||||
* Perform immediate clean-up of this |Scoped|.
|
||||
*
|
||||
* If this |Scoped| is currently empty, this method has no effect.
|
||||
*/
|
||||
void dispose()
|
||||
{
|
||||
Traits::release(mValue);
|
||||
mValue = Traits::empty();
|
||||
}
|
||||
|
||||
bool operator==(const Resource& other) const {
|
||||
return value == other;
|
||||
}
|
||||
bool operator==(const Resource& aOther) const { return mValue == aOther; }
|
||||
|
||||
/*
|
||||
* Replace the resource with another resource.
|
||||
*
|
||||
* Calling |operator=| has the side-effect of triggering clean-up. If you do
|
||||
* not want to trigger clean-up, you should first invoke |forget|.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
Scoped& operator=(const Resource& other) {
|
||||
return reset(other);
|
||||
}
|
||||
Scoped& reset(const Resource& other) {
|
||||
Traits::release(value);
|
||||
value = other;
|
||||
return *this;
|
||||
}
|
||||
/*
|
||||
* Replace the resource with another resource.
|
||||
*
|
||||
* Calling |operator=| has the side-effect of triggering clean-up. If you do
|
||||
* not want to trigger clean-up, you should first invoke |forget|.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
Scoped& operator=(const Resource& aOther) { return reset(aOther); }
|
||||
|
||||
/* Move assignment operator. */
|
||||
Scoped& operator=(Scoped&& rhs) {
|
||||
MOZ_ASSERT(&rhs != this, "self-move-assignment not allowed");
|
||||
this->~Scoped();
|
||||
new(this) Scoped(Move(rhs));
|
||||
return *this;
|
||||
}
|
||||
Scoped& reset(const Resource& aOther)
|
||||
{
|
||||
Traits::release(mValue);
|
||||
mValue = aOther;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
explicit Scoped(const Scoped& value) MOZ_DELETE;
|
||||
Scoped& operator=(const Scoped& value) MOZ_DELETE;
|
||||
/* Move assignment operator. */
|
||||
Scoped& operator=(Scoped&& aRhs)
|
||||
{
|
||||
MOZ_ASSERT(&aRhs != this, "self-move-assignment not allowed");
|
||||
this->~Scoped();
|
||||
new(this) Scoped(Move(aRhs));
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
Resource value;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
private:
|
||||
explicit Scoped(const Scoped& aValue) MOZ_DELETE;
|
||||
Scoped& operator=(const Scoped& aValue) MOZ_DELETE;
|
||||
|
||||
private:
|
||||
Resource mValue;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
/*
|
||||
@ -184,36 +184,38 @@ class Scoped
|
||||
* @param Traits A struct implementing clean-up. See the implementations
|
||||
* for more details.
|
||||
*/
|
||||
#define SCOPED_TEMPLATE(name, Traits) \
|
||||
template<typename Type> \
|
||||
struct name : public mozilla::Scoped<Traits<Type> > \
|
||||
{ \
|
||||
typedef mozilla::Scoped<Traits<Type> > Super; \
|
||||
typedef typename Super::Resource Resource; \
|
||||
name& operator=(Resource rhs) { \
|
||||
Super::operator=(rhs); \
|
||||
return *this; \
|
||||
} \
|
||||
name& operator=(name&& rhs) { \
|
||||
Super::operator=(Move(rhs)); \
|
||||
return *this; \
|
||||
} \
|
||||
explicit name(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) \
|
||||
: Super(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT) \
|
||||
{} \
|
||||
explicit name(Resource rhs \
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \
|
||||
: Super(rhs \
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \
|
||||
{} \
|
||||
explicit name(name&& rhs \
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \
|
||||
: Super(Move(rhs) \
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \
|
||||
{} \
|
||||
private: \
|
||||
explicit name(name&) MOZ_DELETE; \
|
||||
name& operator=(name&) MOZ_DELETE; \
|
||||
#define SCOPED_TEMPLATE(name, Traits) \
|
||||
template<typename Type> \
|
||||
struct name : public mozilla::Scoped<Traits<Type> > \
|
||||
{ \
|
||||
typedef mozilla::Scoped<Traits<Type> > Super; \
|
||||
typedef typename Super::Resource Resource; \
|
||||
name& operator=(Resource aRhs) \
|
||||
{ \
|
||||
Super::operator=(aRhs); \
|
||||
return *this; \
|
||||
} \
|
||||
name& operator=(name&& aRhs) \
|
||||
{ \
|
||||
Super::operator=(Move(aRhs)); \
|
||||
return *this; \
|
||||
} \
|
||||
explicit name(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) \
|
||||
: Super(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT) \
|
||||
{} \
|
||||
explicit name(Resource aRhs \
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \
|
||||
: Super(aRhs \
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \
|
||||
{} \
|
||||
explicit name(name&& aRhs \
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \
|
||||
: Super(Move(aRhs) \
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \
|
||||
{} \
|
||||
private: \
|
||||
explicit name(name&) MOZ_DELETE; \
|
||||
name& operator=(name&) MOZ_DELETE; \
|
||||
};
|
||||
|
||||
/*
|
||||
@ -226,9 +228,9 @@ struct name : public mozilla::Scoped<Traits<Type> > \
|
||||
template<typename T>
|
||||
struct ScopedFreePtrTraits
|
||||
{
|
||||
typedef T* type;
|
||||
static T* empty() { return nullptr; }
|
||||
static void release(T* ptr) { free(ptr); }
|
||||
typedef T* type;
|
||||
static T* empty() { return nullptr; }
|
||||
static void release(T* aPtr) { free(aPtr); }
|
||||
};
|
||||
SCOPED_TEMPLATE(ScopedFreePtr, ScopedFreePtrTraits)
|
||||
|
||||
@ -241,7 +243,7 @@ SCOPED_TEMPLATE(ScopedFreePtr, ScopedFreePtrTraits)
|
||||
template<typename T>
|
||||
struct ScopedDeletePtrTraits : public ScopedFreePtrTraits<T>
|
||||
{
|
||||
static void release(T* ptr) { delete ptr; }
|
||||
static void release(T* aPtr) { delete aPtr; }
|
||||
};
|
||||
SCOPED_TEMPLATE(ScopedDeletePtr, ScopedDeletePtrTraits)
|
||||
|
||||
@ -254,7 +256,7 @@ SCOPED_TEMPLATE(ScopedDeletePtr, ScopedDeletePtrTraits)
|
||||
template<typename T>
|
||||
struct ScopedDeleteArrayTraits : public ScopedFreePtrTraits<T>
|
||||
{
|
||||
static void release(T* ptr) { delete [] ptr; }
|
||||
static void release(T* aPtr) { delete [] aPtr; }
|
||||
};
|
||||
SCOPED_TEMPLATE(ScopedDeleteArray, ScopedDeleteArrayTraits)
|
||||
|
||||
@ -281,21 +283,22 @@ SCOPED_TEMPLATE(ScopedDeleteArray, ScopedDeleteArrayTraits)
|
||||
* } // file is closed with PR_Close here
|
||||
*/
|
||||
#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;
|
||||
|
||||
template <typename T> void TypeSpecificDelete(T * value);
|
||||
template <typename T> void TypeSpecificDelete(T* aValue);
|
||||
|
||||
template <typename T>
|
||||
struct TypeSpecificScopedPointerTraits
|
||||
{
|
||||
typedef T* type;
|
||||
static type empty() { return nullptr; }
|
||||
static void release(type value)
|
||||
{
|
||||
if (value)
|
||||
TypeSpecificDelete(value);
|
||||
typedef T* type;
|
||||
static type empty() { return nullptr; }
|
||||
static void release(type aValue)
|
||||
{
|
||||
if (aValue) {
|
||||
TypeSpecificDelete(aValue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SCOPED_TEMPLATE(TypeSpecificScopedPointer, TypeSpecificScopedPointerTraits)
|
||||
|
@ -28,19 +28,19 @@ namespace tl {
|
||||
template<size_t I, size_t J>
|
||||
struct Min
|
||||
{
|
||||
static const size_t value = I < J ? I : J;
|
||||
static const size_t value = I < J ? I : J;
|
||||
};
|
||||
template<size_t I, size_t J>
|
||||
struct Max
|
||||
{
|
||||
static const size_t value = I > J ? I : J;
|
||||
static const size_t value = I > J ? I : J;
|
||||
};
|
||||
|
||||
/** Compute floor(log2(i)). */
|
||||
template<size_t I>
|
||||
struct FloorLog2
|
||||
{
|
||||
static const size_t value = 1 + FloorLog2<I / 2>::value;
|
||||
static const size_t value = 1 + FloorLog2<I / 2>::value;
|
||||
};
|
||||
template<> struct FloorLog2<0> { /* Error */ };
|
||||
template<> struct FloorLog2<1> { static const size_t value = 0; };
|
||||
@ -49,26 +49,26 @@ template<> struct FloorLog2<1> { static const size_t value = 0; };
|
||||
template<size_t I>
|
||||
struct CeilingLog2
|
||||
{
|
||||
static const size_t value = FloorLog2<2 * I - 1>::value;
|
||||
static const size_t value = FloorLog2<2 * I - 1>::value;
|
||||
};
|
||||
|
||||
/** Round up to the nearest power of 2. */
|
||||
template<size_t I>
|
||||
struct RoundUpPow2
|
||||
{
|
||||
static const size_t value = size_t(1) << CeilingLog2<I>::value;
|
||||
static const size_t value = size_t(1) << CeilingLog2<I>::value;
|
||||
};
|
||||
template<>
|
||||
struct RoundUpPow2<0>
|
||||
{
|
||||
static const size_t value = 1;
|
||||
static const size_t value = 1;
|
||||
};
|
||||
|
||||
/** Compute the number of bits in the given unsigned type. */
|
||||
template<typename T>
|
||||
struct BitSize
|
||||
{
|
||||
static const size_t value = sizeof(T) * CHAR_BIT;
|
||||
static const size_t value = sizeof(T) * CHAR_BIT;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -78,17 +78,18 @@ struct BitSize
|
||||
template<size_t N>
|
||||
struct NBitMask
|
||||
{
|
||||
// Assert the precondition. On success this evaluates to 0. Otherwise it
|
||||
// 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
|
||||
// its computation.
|
||||
static const size_t checkPrecondition = 0 / size_t(N < BitSize<size_t>::value);
|
||||
static const size_t value = (size_t(1) << N) - 1 + checkPrecondition;
|
||||
// Assert the precondition. On success this evaluates to 0. Otherwise it
|
||||
// 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
|
||||
// its computation.
|
||||
static const size_t checkPrecondition =
|
||||
0 / size_t(N < BitSize<size_t>::value);
|
||||
static const size_t value = (size_t(1) << N) - 1 + checkPrecondition;
|
||||
};
|
||||
template<>
|
||||
struct NBitMask<BitSize<size_t>::value>
|
||||
{
|
||||
static const size_t value = size_t(-1);
|
||||
static const size_t value = size_t(-1);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -98,8 +99,8 @@ struct NBitMask<BitSize<size_t>::value>
|
||||
template<size_t N>
|
||||
struct MulOverflowMask
|
||||
{
|
||||
static const size_t value =
|
||||
~NBitMask<BitSize<size_t>::value - CeilingLog2<N>::value>::value;
|
||||
static const size_t value =
|
||||
~NBitMask<BitSize<size_t>::value - CeilingLog2<N>::value>::value;
|
||||
};
|
||||
template<> struct MulOverflowMask<0> { /* Error */ };
|
||||
template<> struct MulOverflowMask<1> { static const size_t value = 0; };
|
||||
|
@ -73,30 +73,29 @@ template<typename T>
|
||||
class ThreadLocal
|
||||
{
|
||||
#if defined(XP_WIN)
|
||||
typedef unsigned long key_t;
|
||||
typedef unsigned long key_t;
|
||||
#else
|
||||
typedef pthread_key_t key_t;
|
||||
typedef pthread_key_t key_t;
|
||||
#endif
|
||||
|
||||
union Helper {
|
||||
void* ptr;
|
||||
T value;
|
||||
};
|
||||
union Helper
|
||||
{
|
||||
void* mPtr;
|
||||
T mValue;
|
||||
};
|
||||
|
||||
public:
|
||||
MOZ_WARN_UNUSED_RESULT inline bool init();
|
||||
public:
|
||||
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 {
|
||||
return inited;
|
||||
}
|
||||
bool initialized() const { return mInited; }
|
||||
|
||||
private:
|
||||
key_t key;
|
||||
bool inited;
|
||||
private:
|
||||
key_t mKey;
|
||||
bool mInited;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@ -108,12 +107,12 @@ ThreadLocal<T>::init()
|
||||
"a pointer");
|
||||
MOZ_ASSERT(!initialized());
|
||||
#ifdef XP_WIN
|
||||
key = TlsAlloc();
|
||||
inited = key != 0xFFFFFFFFUL; // TLS_OUT_OF_INDEXES
|
||||
mKey = TlsAlloc();
|
||||
mInited = mKey != 0xFFFFFFFFUL; // TLS_OUT_OF_INDEXES
|
||||
#else
|
||||
inited = !pthread_key_create(&key, nullptr);
|
||||
mInited = !pthread_key_create(&mKey, nullptr);
|
||||
#endif
|
||||
return inited;
|
||||
return mInited;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -123,28 +122,28 @@ ThreadLocal<T>::get() const
|
||||
MOZ_ASSERT(initialized());
|
||||
Helper h;
|
||||
#ifdef XP_WIN
|
||||
h.ptr = TlsGetValue(key);
|
||||
h.mPtr = TlsGetValue(mKey);
|
||||
#else
|
||||
h.ptr = pthread_getspecific(key);
|
||||
h.mPtr = pthread_getspecific(mKey);
|
||||
#endif
|
||||
return h.value;
|
||||
return h.mValue;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void
|
||||
ThreadLocal<T>::set(const T value)
|
||||
ThreadLocal<T>::set(const T aValue)
|
||||
{
|
||||
MOZ_ASSERT(initialized());
|
||||
Helper h;
|
||||
h.value = value;
|
||||
bool succeeded;
|
||||
h.mValue = aValue;
|
||||
#ifdef XP_WIN
|
||||
succeeded = TlsSetValue(key, h.ptr);
|
||||
bool succeeded = TlsSetValue(mKey, h.mPtr);
|
||||
#else
|
||||
succeeded = !pthread_setspecific(key, h.ptr);
|
||||
bool succeeded = !pthread_setspecific(mKey, h.mPtr);
|
||||
#endif
|
||||
if (!succeeded)
|
||||
if (!succeeded) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -20,10 +20,10 @@ namespace mozilla {
|
||||
*/
|
||||
template<typename T>
|
||||
std::string
|
||||
ToString(const T& t)
|
||||
ToString(const T& aValue)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << t;
|
||||
stream << aValue;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
|
@ -34,9 +34,9 @@ template<typename> struct RemoveCV;
|
||||
template<typename T, T Value>
|
||||
struct IntegralConstant
|
||||
{
|
||||
static const T value = Value;
|
||||
typedef T ValueType;
|
||||
typedef IntegralConstant<T, Value> Type;
|
||||
static const T value = Value;
|
||||
typedef T ValueType;
|
||||
typedef IntegralConstant<T, Value> Type;
|
||||
};
|
||||
|
||||
/** Convenient aliases. */
|
||||
@ -522,35 +522,35 @@ struct BaseOfTester : IntegralConstant<bool, __is_base_of(Base, Derived)> {};
|
||||
template<class Base, class Derived>
|
||||
struct BaseOfHelper
|
||||
{
|
||||
public:
|
||||
operator Base*() const;
|
||||
operator Derived*();
|
||||
public:
|
||||
operator Base*() const;
|
||||
operator Derived*();
|
||||
};
|
||||
|
||||
template<class Base, class Derived>
|
||||
struct BaseOfTester
|
||||
{
|
||||
private:
|
||||
template<class T>
|
||||
static char test(Derived*, T);
|
||||
static int test(Base*, int);
|
||||
private:
|
||||
template<class T>
|
||||
static char test(Derived*, T);
|
||||
static int test(Base*, int);
|
||||
|
||||
public:
|
||||
static const bool value =
|
||||
sizeof(test(BaseOfHelper<Base, Derived>(), int())) == sizeof(char);
|
||||
public:
|
||||
static const bool value =
|
||||
sizeof(test(BaseOfHelper<Base, Derived>(), int())) == sizeof(char);
|
||||
};
|
||||
|
||||
template<class Base, class Derived>
|
||||
struct BaseOfTester<Base, const Derived>
|
||||
{
|
||||
private:
|
||||
template<class T>
|
||||
static char test(Derived*, T);
|
||||
static int test(Base*, int);
|
||||
private:
|
||||
template<class T>
|
||||
static char test(Derived*, T);
|
||||
static int test(Base*, int);
|
||||
|
||||
public:
|
||||
static const bool value =
|
||||
sizeof(test(BaseOfHelper<Base, Derived>(), int())) == sizeof(char);
|
||||
public:
|
||||
static const bool value =
|
||||
sizeof(test(BaseOfHelper<Base, Derived>(), int())) == sizeof(char);
|
||||
};
|
||||
|
||||
template<class Base, class Derived>
|
||||
@ -588,18 +588,18 @@ namespace detail {
|
||||
template<typename From, typename To>
|
||||
struct ConvertibleTester
|
||||
{
|
||||
private:
|
||||
static From create();
|
||||
private:
|
||||
static From create();
|
||||
|
||||
template<typename From1, typename To1>
|
||||
static char test(To to);
|
||||
template<typename From1, typename To1>
|
||||
static char test(To to);
|
||||
|
||||
template<typename From1, typename To1>
|
||||
static int test(...);
|
||||
template<typename From1, typename To1>
|
||||
static int test(...);
|
||||
|
||||
public:
|
||||
static const bool value =
|
||||
sizeof(test<From, To>(create())) == sizeof(char);
|
||||
public:
|
||||
static const bool value =
|
||||
sizeof(test<From, To>(create())) == sizeof(char);
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
@ -645,13 +645,13 @@ struct IsConvertible
|
||||
template<typename T>
|
||||
struct RemoveConst
|
||||
{
|
||||
typedef T Type;
|
||||
typedef T Type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct RemoveConst<const T>
|
||||
{
|
||||
typedef T Type;
|
||||
typedef T Type;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -665,13 +665,13 @@ struct RemoveConst<const T>
|
||||
template<typename T>
|
||||
struct RemoveVolatile
|
||||
{
|
||||
typedef T Type;
|
||||
typedef T Type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct RemoveVolatile<volatile T>
|
||||
{
|
||||
typedef T Type;
|
||||
typedef T Type;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -685,7 +685,7 @@ struct RemoveVolatile<volatile T>
|
||||
template<typename T>
|
||||
struct RemoveCV
|
||||
{
|
||||
typedef typename RemoveConst<typename RemoveVolatile<T>::Type>::Type Type;
|
||||
typedef typename RemoveConst<typename RemoveVolatile<T>::Type>::Type Type;
|
||||
};
|
||||
|
||||
/* 20.9.7.2 Reference modifications [meta.trans.ref] */
|
||||
@ -701,19 +701,19 @@ struct RemoveCV
|
||||
template<typename T>
|
||||
struct RemoveReference
|
||||
{
|
||||
typedef T Type;
|
||||
typedef T Type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct RemoveReference<T&>
|
||||
{
|
||||
typedef T Type;
|
||||
typedef T Type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct RemoveReference<T&&>
|
||||
{
|
||||
typedef T Type;
|
||||
typedef T Type;
|
||||
};
|
||||
|
||||
template<bool Condition, typename A, typename B>
|
||||
@ -729,13 +729,13 @@ struct AddLvalueReferenceHelper;
|
||||
template<typename T>
|
||||
struct AddLvalueReferenceHelper<T, TIsVoid>
|
||||
{
|
||||
typedef void Type;
|
||||
typedef void Type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct AddLvalueReferenceHelper<T, TIsNotVoid>
|
||||
{
|
||||
typedef T& Type;
|
||||
typedef T& Type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
@ -804,7 +804,7 @@ struct MakeSigned;
|
||||
template<typename T, typename CVRemoved>
|
||||
struct MakeSigned<T, CVRemoved, true>
|
||||
{
|
||||
typedef T Type;
|
||||
typedef T Type;
|
||||
};
|
||||
|
||||
template<typename T, typename CVRemoved>
|
||||
@ -839,7 +839,8 @@ struct MakeSigned<T, CVRemoved, false>
|
||||
*/
|
||||
template<typename T>
|
||||
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>
|
||||
>::Type
|
||||
{};
|
||||
@ -872,7 +873,7 @@ struct MakeUnsigned;
|
||||
template<typename T, typename CVRemoved>
|
||||
struct MakeUnsigned<T, CVRemoved, true>
|
||||
{
|
||||
typedef T Type;
|
||||
typedef T Type;
|
||||
};
|
||||
|
||||
template<typename T, typename CVRemoved>
|
||||
@ -907,7 +908,8 @@ struct MakeUnsigned<T, CVRemoved, false>
|
||||
*/
|
||||
template<typename T>
|
||||
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>
|
||||
>::Type
|
||||
{};
|
||||
@ -926,19 +928,19 @@ struct MakeUnsigned
|
||||
template<typename T>
|
||||
struct RemoveExtent
|
||||
{
|
||||
typedef T Type;
|
||||
typedef T Type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct RemoveExtent<T[]>
|
||||
{
|
||||
typedef T Type;
|
||||
typedef T Type;
|
||||
};
|
||||
|
||||
template<typename T, decltype(sizeof(1)) N>
|
||||
struct RemoveExtent<T[N]>
|
||||
{
|
||||
typedef T Type;
|
||||
typedef T Type;
|
||||
};
|
||||
|
||||
/* 20.9.7.5 Pointer modifications [meta.trans.ptr] */
|
||||
@ -970,7 +972,7 @@ struct EnableIf
|
||||
template<typename T>
|
||||
struct EnableIf<true, T>
|
||||
{
|
||||
typedef T Type;
|
||||
typedef T Type;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -982,13 +984,13 @@ struct EnableIf<true, T>
|
||||
template<bool Condition, typename A, typename B>
|
||||
struct Conditional
|
||||
{
|
||||
typedef A Type;
|
||||
typedef A Type;
|
||||
};
|
||||
|
||||
template<class A, class B>
|
||||
struct Conditional<false, A, B>
|
||||
{
|
||||
typedef B Type;
|
||||
typedef B Type;
|
||||
};
|
||||
|
||||
} /* namespace mozilla */
|
||||
|
@ -69,13 +69,12 @@
|
||||
* in namespace scope to handle bits that can only be implemented with
|
||||
* namespace-scoped code. For example:
|
||||
*
|
||||
* class FooBar {
|
||||
*
|
||||
* class FooBar
|
||||
* {
|
||||
* MOZ_BEGIN_NESTED_ENUM_CLASS(Enum, int32_t)
|
||||
* A,
|
||||
* B = 6
|
||||
* MOZ_END_NESTED_ENUM_CLASS(Enum)
|
||||
*
|
||||
* };
|
||||
*
|
||||
* MOZ_FINISH_NESTED_ENUM_CLASS(FooBar::Enum)
|
||||
@ -148,28 +147,28 @@
|
||||
# define MOZ_BEGIN_NESTED_ENUM_CLASS_HELPER1(Name) \
|
||||
class Name \
|
||||
{ \
|
||||
public: \
|
||||
enum Enum \
|
||||
{
|
||||
public: \
|
||||
enum Enum \
|
||||
{
|
||||
/* Two-argument form. */
|
||||
# define MOZ_BEGIN_NESTED_ENUM_CLASS_HELPER2(Name, type) \
|
||||
class Name \
|
||||
{ \
|
||||
public: \
|
||||
enum Enum MOZ_ENUM_TYPE(type) \
|
||||
{
|
||||
public: \
|
||||
enum Enum MOZ_ENUM_TYPE(type) \
|
||||
{
|
||||
# define MOZ_END_NESTED_ENUM_CLASS(Name) \
|
||||
}; \
|
||||
Name() {} \
|
||||
MOZ_CONSTEXPR Name(Enum aEnum) : mEnum(aEnum) {} \
|
||||
template<typename Other> \
|
||||
explicit MOZ_CONSTEXPR Name(Other num) : mEnum((Enum)num) {} \
|
||||
MOZ_CONSTEXPR operator Enum() const { return mEnum; } \
|
||||
explicit MOZ_CONSTEXPR Name(const mozilla::CastableTypedEnumResult<Name>& aOther) \
|
||||
: mEnum(aOther.get()) \
|
||||
{} \
|
||||
private: \
|
||||
Enum mEnum; \
|
||||
}; \
|
||||
Name() {} \
|
||||
MOZ_CONSTEXPR Name(Enum aEnum) : mEnum(aEnum) {} \
|
||||
template<typename Other> \
|
||||
explicit MOZ_CONSTEXPR Name(Other num) : mEnum((Enum)num) {} \
|
||||
MOZ_CONSTEXPR operator Enum() const { return mEnum; } \
|
||||
explicit MOZ_CONSTEXPR Name(const mozilla::CastableTypedEnumResult<Name>& aOther) \
|
||||
: mEnum(aOther.get()) \
|
||||
{} \
|
||||
private: \
|
||||
Enum mEnum; \
|
||||
};
|
||||
# define MOZ_FINISH_NESTED_ENUM_CLASS(Name) \
|
||||
inline int operator+(const int&, const Name::Enum&) MOZ_DELETE; \
|
||||
@ -253,14 +252,14 @@
|
||||
*
|
||||
* S<E, E::Bar> s;
|
||||
*
|
||||
* In this example, the second template parameter to S is meant to be of type T,
|
||||
* but on non-C++11 compilers, type T is a class type, not an integer type, so
|
||||
* it is not accepted as the type of a constant template parameter. One would
|
||||
* then want to use MOZ_ENUM_CLASS_ENUM_TYPE(T), but that doesn't work either
|
||||
* as T depends on template parameters (more specifically here, T _is_ a template
|
||||
* parameter) so as MOZ_ENUM_CLASS_ENUM_TYPE(T) expands to T::Enum, we are missing
|
||||
* the required "typename" keyword. So here, MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE
|
||||
* is needed.
|
||||
* In this example, the second template parameter to S is meant to be of type
|
||||
* T, but on non-C++11 compilers, type T is a class type, not an integer
|
||||
* type, so it is not accepted as the type of a constant template parameter.
|
||||
* One would then want to use MOZ_ENUM_CLASS_ENUM_TYPE(T), but that doesn't
|
||||
* work either as T depends on template parameters (more specifically here, T
|
||||
* _is_ a template parameter) so as MOZ_ENUM_CLASS_ENUM_TYPE(T) expands to
|
||||
* T::Enum, we are missing the required "typename" keyword. So here,
|
||||
* MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE is needed.
|
||||
*/
|
||||
# define MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(Name) typename Name::Enum
|
||||
#endif
|
||||
|
@ -4,7 +4,9 @@
|
||||
* 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/. */
|
||||
|
||||
/* 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
|
||||
#define mozilla_TypedEnumBits_h
|
||||
@ -17,22 +19,22 @@ namespace mozilla {
|
||||
#define MOZ_CASTABLETYPEDENUMRESULT_BINOP(Op, OtherType, ReturnType) \
|
||||
template<typename E> \
|
||||
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> \
|
||||
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> \
|
||||
MOZ_CONSTEXPR ReturnType \
|
||||
operator Op(const CastableTypedEnumResult<E>& r1, \
|
||||
const CastableTypedEnumResult<E>& r2) \
|
||||
operator Op(const CastableTypedEnumResult<E>& aR1, \
|
||||
const CastableTypedEnumResult<E>& aR2) \
|
||||
{ \
|
||||
return ReturnType(OtherType(r1) Op OtherType(r2)); \
|
||||
return ReturnType(OtherType(aR1) Op OtherType(aR2)); \
|
||||
}
|
||||
|
||||
MOZ_CASTABLETYPEDENUMRESULT_BINOP(|, E, CastableTypedEnumResult<E>)
|
||||
@ -45,18 +47,18 @@ MOZ_CASTABLETYPEDENUMRESULT_BINOP(&&, bool, bool)
|
||||
|
||||
template <typename 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) \
|
||||
template<typename E> \
|
||||
E& \
|
||||
operator Op(E& r1, \
|
||||
const CastableTypedEnumResult<E>& r2) \
|
||||
operator Op(E& aR1, \
|
||||
const CastableTypedEnumResult<E>& aR2) \
|
||||
{ \
|
||||
return r1 Op E(r2); \
|
||||
return aR1 Op E(aR2); \
|
||||
}
|
||||
|
||||
MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(&=)
|
||||
@ -72,15 +74,15 @@ MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(^=)
|
||||
#define MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(Op, ReturnType) \
|
||||
template<typename E> \
|
||||
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> \
|
||||
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>)
|
||||
|
@ -74,34 +74,32 @@ namespace mozilla {
|
||||
template<typename E>
|
||||
class CastableTypedEnumResult
|
||||
{
|
||||
private:
|
||||
const E mValue;
|
||||
private:
|
||||
const E mValue;
|
||||
|
||||
public:
|
||||
explicit MOZ_CONSTEXPR CastableTypedEnumResult(E value)
|
||||
: mValue(value)
|
||||
{}
|
||||
public:
|
||||
explicit MOZ_CONSTEXPR CastableTypedEnumResult(E aValue)
|
||||
: mValue(aValue)
|
||||
{}
|
||||
|
||||
MOZ_CONSTEXPR operator E() const { return mValue; }
|
||||
MOZ_CONSTEXPR operator E() const { return mValue; }
|
||||
|
||||
template<typename DestinationType>
|
||||
MOZ_EXPLICIT_CONVERSION MOZ_CONSTEXPR
|
||||
operator DestinationType() const {
|
||||
return DestinationType(mValue);
|
||||
}
|
||||
template<typename DestinationType>
|
||||
MOZ_EXPLICIT_CONVERSION MOZ_CONSTEXPR
|
||||
operator DestinationType() const { return DestinationType(mValue); }
|
||||
|
||||
MOZ_CONSTEXPR bool operator !() const { return !bool(mValue); }
|
||||
MOZ_CONSTEXPR bool operator !() const { return !bool(mValue); }
|
||||
|
||||
#ifndef MOZ_HAVE_CXX11_STRONG_ENUMS
|
||||
// This get() method is used to implement a constructor in the
|
||||
// non-c++11 fallback path for MOZ_BEGIN_ENUM_CLASS, taking a
|
||||
// CastableTypedEnumResult. If we try to implement it using the
|
||||
// above conversion operator E(), then at least clang 3.3
|
||||
// (when forced to take the non-c++11 fallback path) compiles
|
||||
// this constructor to an infinite recursion. So we introduce this
|
||||
// get() method, that does exactly the same as the conversion operator,
|
||||
// to work around this.
|
||||
MOZ_CONSTEXPR E get() const { return mValue; }
|
||||
// This get() method is used to implement a constructor in the
|
||||
// non-c++11 fallback path for MOZ_BEGIN_ENUM_CLASS, taking a
|
||||
// CastableTypedEnumResult. If we try to implement it using the
|
||||
// above conversion operator E(), then at least clang 3.3
|
||||
// (when forced to take the non-c++11 fallback path) compiles
|
||||
// this constructor to an infinite recursion. So we introduce this
|
||||
// get() method, that does exactly the same as the conversion operator,
|
||||
// to work around this.
|
||||
MOZ_CONSTEXPR E get() const { return mValue; }
|
||||
#endif
|
||||
};
|
||||
|
||||
|
1281
mfbt/Vector.h
1281
mfbt/Vector.h
File diff suppressed because it is too large
Load Diff
152
mfbt/WeakPtr.h
152
mfbt/WeakPtr.h
@ -26,16 +26,17 @@
|
||||
*
|
||||
* 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>
|
||||
* {
|
||||
* public:
|
||||
* MOZ_DECLARE_REFCOUNTED_TYPENAME(C)
|
||||
* int num;
|
||||
* void act();
|
||||
* public:
|
||||
* MOZ_DECLARE_REFCOUNTED_TYPENAME(C)
|
||||
* int mNum;
|
||||
* void act();
|
||||
* };
|
||||
*
|
||||
* C* ptr = new C();
|
||||
* C* ptr = new C();
|
||||
*
|
||||
* // Get weak pointers to ptr. The first time asWeakPtr is called
|
||||
* // a reference counted WeakReference object is created that
|
||||
@ -46,7 +47,7 @@
|
||||
*
|
||||
* // Test a weak pointer for validity before using it.
|
||||
* if (weak) {
|
||||
* weak->num = 17;
|
||||
* weak->mNum = 17;
|
||||
* weak->act();
|
||||
* }
|
||||
*
|
||||
@ -81,46 +82,48 @@ template <typename T, class WeakReference> class SupportsWeakPtrBase;
|
||||
|
||||
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>
|
||||
class WeakReference : public ::mozilla::RefCounted<WeakReference<T> >
|
||||
{
|
||||
public:
|
||||
explicit WeakReference(T* p) : ptr(p) {}
|
||||
T* get() const {
|
||||
return ptr;
|
||||
}
|
||||
public:
|
||||
explicit WeakReference(T* p) : mPtr(p) {}
|
||||
|
||||
T* get() const { return mPtr; }
|
||||
|
||||
#ifdef MOZ_REFCOUNTED_LEAK_CHECKING
|
||||
#ifdef XP_WIN
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
const char* typeName() const {
|
||||
static char nameBuffer[1024];
|
||||
const char* innerType = ptr->typeName();
|
||||
// We could do fancier length checks at runtime, but innerType is
|
||||
// controlled by us so we can ensure that this never causes a buffer
|
||||
// overflow by this assertion.
|
||||
MOZ_ASSERT(strlen(innerType) + sizeof("WeakReference<>") < ArrayLength(nameBuffer),
|
||||
"Exceedingly large type name");
|
||||
snprintf(nameBuffer, ArrayLength(nameBuffer), "WeakReference<%s>", innerType);
|
||||
// This is usually not OK, but here we are returning a pointer to a static
|
||||
// buffer which will immediately be used by the caller.
|
||||
return nameBuffer;
|
||||
}
|
||||
size_t typeSize() const {
|
||||
return sizeof(*this);
|
||||
}
|
||||
const char* typeName() const
|
||||
{
|
||||
static char nameBuffer[1024];
|
||||
const char* innerType = mPtr->typeName();
|
||||
// We could do fancier length checks at runtime, but innerType is
|
||||
// controlled by us so we can ensure that this never causes a buffer
|
||||
// overflow by this assertion.
|
||||
MOZ_ASSERT(strlen(innerType) + sizeof("WeakReference<>") <
|
||||
ArrayLength(nameBuffer),
|
||||
"Exceedingly large type name");
|
||||
snprintf(nameBuffer, ArrayLength(nameBuffer), "WeakReference<%s>",
|
||||
innerType);
|
||||
// This is usually not OK, but here we are returning a pointer to a static
|
||||
// buffer which will immediately be used by the caller.
|
||||
return nameBuffer;
|
||||
}
|
||||
|
||||
size_t typeSize() const { return sizeof(*this); }
|
||||
#undef snprintf
|
||||
#endif
|
||||
|
||||
private:
|
||||
friend class WeakPtrBase<T, WeakReference<T> >;
|
||||
friend class SupportsWeakPtrBase<T, WeakReference<T> >;
|
||||
void detach() {
|
||||
ptr = nullptr;
|
||||
}
|
||||
T* ptr;
|
||||
private:
|
||||
friend class WeakPtrBase<T, WeakReference<T> >;
|
||||
friend class SupportsWeakPtrBase<T, WeakReference<T> >;
|
||||
|
||||
void detach() { mPtr = nullptr; }
|
||||
|
||||
T* mPtr;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
@ -128,25 +131,29 @@ class WeakReference : public ::mozilla::RefCounted<WeakReference<T> >
|
||||
template <typename T, class WeakReference>
|
||||
class SupportsWeakPtrBase
|
||||
{
|
||||
public:
|
||||
WeakPtrBase<T, WeakReference> asWeakPtr() {
|
||||
if (!weakRef)
|
||||
weakRef = new WeakReference(static_cast<T*>(this));
|
||||
return WeakPtrBase<T, WeakReference>(weakRef);
|
||||
public:
|
||||
WeakPtrBase<T, WeakReference> asWeakPtr()
|
||||
{
|
||||
if (!weakRef) {
|
||||
weakRef = new WeakReference(static_cast<T*>(this));
|
||||
}
|
||||
return WeakPtrBase<T, WeakReference>(weakRef);
|
||||
}
|
||||
|
||||
protected:
|
||||
~SupportsWeakPtrBase() {
|
||||
static_assert(IsBaseOf<SupportsWeakPtrBase<T, WeakReference>, T>::value,
|
||||
"T must derive from SupportsWeakPtrBase<T, WeakReference>");
|
||||
if (weakRef)
|
||||
weakRef->detach();
|
||||
protected:
|
||||
~SupportsWeakPtrBase()
|
||||
{
|
||||
static_assert(IsBaseOf<SupportsWeakPtrBase<T, WeakReference>, T>::value,
|
||||
"T must derive from SupportsWeakPtrBase<T, WeakReference>");
|
||||
if (weakRef) {
|
||||
weakRef->detach();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
friend class WeakPtrBase<T, WeakReference>;
|
||||
private:
|
||||
friend class WeakPtrBase<T, WeakReference>;
|
||||
|
||||
RefPtr<WeakReference> weakRef;
|
||||
RefPtr<WeakReference> weakRef;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@ -157,42 +164,37 @@ class SupportsWeakPtr : public SupportsWeakPtrBase<T, detail::WeakReference<T> >
|
||||
template <typename T, class WeakReference>
|
||||
class WeakPtrBase
|
||||
{
|
||||
public:
|
||||
WeakPtrBase(const WeakPtrBase<T, WeakReference>& o) : ref(o.ref) {}
|
||||
// Ensure that ref is dereferenceable in the uninitialized state
|
||||
WeakPtrBase() : ref(new WeakReference(nullptr)) {}
|
||||
public:
|
||||
WeakPtrBase(const WeakPtrBase<T, WeakReference>& aOther)
|
||||
: mRef(aOther.mRef)
|
||||
{}
|
||||
|
||||
operator T*() const {
|
||||
return ref->get();
|
||||
}
|
||||
T& operator*() const {
|
||||
return *ref->get();
|
||||
}
|
||||
// Ensure that mRef is dereferenceable in the uninitialized state.
|
||||
WeakPtrBase() : mRef(new WeakReference(nullptr)) {}
|
||||
|
||||
T* operator->() const {
|
||||
return ref->get();
|
||||
}
|
||||
operator T*() const { return mRef->get(); }
|
||||
T& operator*() const { return *mRef->get(); }
|
||||
|
||||
T* get() const {
|
||||
return ref->get();
|
||||
}
|
||||
T* operator->() const { return mRef->get(); }
|
||||
|
||||
private:
|
||||
friend class SupportsWeakPtrBase<T, WeakReference>;
|
||||
T* get() const { return mRef->get(); }
|
||||
|
||||
explicit WeakPtrBase(const RefPtr<WeakReference> &o) : ref(o) {}
|
||||
private:
|
||||
friend class SupportsWeakPtrBase<T, WeakReference>;
|
||||
|
||||
RefPtr<WeakReference> ref;
|
||||
explicit WeakPtrBase(const RefPtr<WeakReference> &aOther) : mRef(aOther) {}
|
||||
|
||||
RefPtr<WeakReference> mRef;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class WeakPtr : public WeakPtrBase<T, detail::WeakReference<T> >
|
||||
{
|
||||
typedef WeakPtrBase<T, detail::WeakReference<T> > Base;
|
||||
public:
|
||||
WeakPtr(const WeakPtr<T>& o) : Base(o) {}
|
||||
MOZ_IMPLICIT WeakPtr(const Base& o) : Base(o) {}
|
||||
WeakPtr() {}
|
||||
typedef WeakPtrBase<T, detail::WeakReference<T> > Base;
|
||||
public:
|
||||
WeakPtr(const WeakPtr<T>& aOther) : Base(aOther) {}
|
||||
MOZ_IMPLICIT WeakPtr(const Base& aOther) : Base(aOther) {}
|
||||
WeakPtr() {}
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -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
|
||||
* 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/. */
|
||||
@ -9,117 +11,134 @@
|
||||
#include <stdint.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 maxVersion = UINT32_MAX;
|
||||
static uint32_t minVersion = 0;
|
||||
static uint32_t maxVersion = UINT32_MAX;
|
||||
|
||||
if (minVersion >= aVersion) {
|
||||
return true;
|
||||
}
|
||||
if (minVersion >= aVersion) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aVersion >= maxVersion) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OSVERSIONINFOEX info;
|
||||
ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
|
||||
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||
info.dwMajorVersion = aVersion >> 24;
|
||||
info.dwMinorVersion = (aVersion >> 16) & 0xFF;
|
||||
info.wServicePackMajor = (aVersion >> 8) & 0xFF;
|
||||
info.wServicePackMinor = aVersion & 0xFF;
|
||||
|
||||
DWORDLONG conditionMask = 0;
|
||||
VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||
VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||
VER_SET_CONDITION(conditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||
VER_SET_CONDITION(conditionMask, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
|
||||
|
||||
if (VerifyVersionInfo(&info,
|
||||
VER_MAJORVERSION | VER_MINORVERSION |
|
||||
VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
|
||||
conditionMask)) {
|
||||
minVersion = aVersion;
|
||||
return true;
|
||||
}
|
||||
|
||||
maxVersion = aVersion;
|
||||
if (aVersion >= maxVersion) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
IsWindowsBuildOrLater(uint32_t aBuild)
|
||||
{
|
||||
static uint32_t minBuild = 0;
|
||||
static uint32_t maxBuild = UINT32_MAX;
|
||||
OSVERSIONINFOEX info;
|
||||
ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
|
||||
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||
info.dwMajorVersion = aVersion >> 24;
|
||||
info.dwMinorVersion = (aVersion >> 16) & 0xFF;
|
||||
info.wServicePackMajor = (aVersion >> 8) & 0xFF;
|
||||
info.wServicePackMinor = aVersion & 0xFF;
|
||||
|
||||
if (minBuild >= aBuild) {
|
||||
return true;
|
||||
}
|
||||
DWORDLONG conditionMask = 0;
|
||||
VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||
VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||
VER_SET_CONDITION(conditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||
VER_SET_CONDITION(conditionMask, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
|
||||
|
||||
if (aBuild >= maxBuild) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OSVERSIONINFOEX info;
|
||||
ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
|
||||
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||
info.dwBuildNumber = aBuild;
|
||||
|
||||
DWORDLONG conditionMask = 0;
|
||||
VER_SET_CONDITION(conditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL);
|
||||
|
||||
if (VerifyVersionInfo(&info, VER_BUILDNUMBER, conditionMask)) {
|
||||
minBuild = aBuild;
|
||||
return true;
|
||||
}
|
||||
|
||||
maxBuild = aBuild;
|
||||
return false;
|
||||
if (VerifyVersionInfo(&info,
|
||||
VER_MAJORVERSION | VER_MINORVERSION |
|
||||
VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
|
||||
conditionMask)) {
|
||||
minVersion = aVersion;
|
||||
return true;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
maxVersion = aVersion;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
IsWindowsBuildOrLater(uint32_t aBuild)
|
||||
{
|
||||
static uint32_t minBuild = 0;
|
||||
static uint32_t maxBuild = UINT32_MAX;
|
||||
|
||||
if (minBuild >= aBuild) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aBuild >= maxBuild) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OSVERSIONINFOEX info;
|
||||
ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
|
||||
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||
info.dwBuildNumber = aBuild;
|
||||
|
||||
DWORDLONG conditionMask = 0;
|
||||
VER_SET_CONDITION(conditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL);
|
||||
|
||||
if (VerifyVersionInfo(&info, VER_BUILDNUMBER, conditionMask)) {
|
||||
minBuild = aBuild;
|
||||
return true;
|
||||
}
|
||||
|
||||
maxBuild = aBuild;
|
||||
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);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_WindowsVersion_h */
|
||||
|
@ -197,8 +197,9 @@ main()
|
||||
"expected-data size should be the same as the actual hash "
|
||||
"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]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -64,11 +64,11 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_org_mozilla_gecko_background_native
|
||||
|
||||
env->ReleaseByteArrayElements(jstr, str, JNI_ABORT);
|
||||
|
||||
jbyteArray out = env->NewByteArray(SHA1Sum::HashSize);
|
||||
jbyteArray out = env->NewByteArray(SHA1Sum::kHashSize);
|
||||
if (out == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
env->SetByteArrayRegion(out, 0, SHA1Sum::HashSize, (jbyte *) hashResult);
|
||||
env->SetByteArrayRegion(out, 0, SHA1Sum::kHashSize, (jbyte *) hashResult);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ template <> inline void RefCounted<LibHandle, AtomicRefCount>::Release() const;
|
||||
|
||||
template <> inline RefCounted<LibHandle, AtomicRefCount>::~RefCounted()
|
||||
{
|
||||
MOZ_ASSERT(refCnt == 0x7fffdead);
|
||||
MOZ_ASSERT(mRefCnt == 0x7fffdead);
|
||||
}
|
||||
|
||||
} /* namespace detail */
|
||||
@ -219,27 +219,27 @@ private:
|
||||
|
||||
/**
|
||||
* Specialized RefCounted<LibHandle>::Release. Under normal operation, when
|
||||
* refCnt reaches 0, the LibHandle is deleted. Its refCnt is however increased
|
||||
* to 1 on normal builds, and 0x7fffdead on debug builds so that the LibHandle
|
||||
* can still be referenced while the destructor is executing. The refCnt is
|
||||
* allowed to grow > 0x7fffdead, but not to decrease under that value, which
|
||||
* would mean too many Releases from within the destructor.
|
||||
* mRefCnt reaches 0, the LibHandle is deleted. Its mRefCnt is however
|
||||
* increased to 1 on normal builds, and 0x7fffdead on debug builds so that the
|
||||
* LibHandle can still be referenced while the destructor is executing. The
|
||||
* mRefCnt is allowed to grow > 0x7fffdead, but not to decrease under that
|
||||
* value, which would mean too many Releases from within the destructor.
|
||||
*/
|
||||
namespace mozilla {
|
||||
namespace detail {
|
||||
|
||||
template <> inline void RefCounted<LibHandle, AtomicRefCount>::Release() const {
|
||||
#ifdef DEBUG
|
||||
if (refCnt > 0x7fff0000)
|
||||
MOZ_ASSERT(refCnt > 0x7fffdead);
|
||||
if (mRefCnt > 0x7fff0000)
|
||||
MOZ_ASSERT(mRefCnt > 0x7fffdead);
|
||||
#endif
|
||||
MOZ_ASSERT(refCnt > 0);
|
||||
if (refCnt > 0) {
|
||||
if (0 == --refCnt) {
|
||||
MOZ_ASSERT(mRefCnt > 0);
|
||||
if (mRefCnt > 0) {
|
||||
if (0 == --mRefCnt) {
|
||||
#ifdef DEBUG
|
||||
refCnt = 0x7fffdead;
|
||||
mRefCnt = 0x7fffdead;
|
||||
#else
|
||||
refCnt = 1;
|
||||
mRefCnt = 1;
|
||||
#endif
|
||||
delete static_cast<const LibHandle*>(this);
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ public:
|
||||
HandleHashKey(KeyTypePointer aKey)
|
||||
{
|
||||
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));
|
||||
}
|
||||
HandleHashKey(const HandleHashKey& aOther)
|
||||
|
Loading…
Reference in New Issue
Block a user