Bug 1036789 - Convert the third quarter of MFBT to Gecko style. r=Ms2ger.

--HG--
extra : rebase_source : 668cd394806203ddfa34bd4f226335ff26c846b5
This commit is contained in:
Nicholas Nethercote 2014-07-10 19:10:17 -07:00
parent cc394c3799
commit 8ea1b7923f
48 changed files with 1931 additions and 1769 deletions

View File

@ -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;

View File

@ -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");

View File

@ -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;

View File

@ -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)
{
}

View File

@ -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<>

View File

@ -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 {

View File

@ -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 */
/*

View File

@ -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) && \

View File

@ -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:
*

View File

@ -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>

View File

@ -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;
}

View File

@ -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()) {

View File

@ -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());

View File

@ -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"

View File

@ -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);
}

View File

@ -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/. */

View File

@ -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/. */

View File

@ -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. */

View File

@ -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

View File

@ -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) {

View File

@ -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>

View File

@ -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;
};

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}
@ -185,7 +191,7 @@ SHA1Sum::finish(SHA1Sum::Hash& hashOut)
* W array in the stack by creating a W array of 80 members, each of
* whose elements is assigned only once. It also separated the computations
* of the W array values and the computations of the values for the 5
* state variables into two separate passes, W's, then A-E's so that the
* state variables into two separate passes, W's, then A-E's so that the
* second pass could be done all in registers (except for accessing the W
* array) on machines with fewer registers. The method is suboptimal
* for machines with enough registers to do it all in one pass, and it
@ -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);

View File

@ -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 */

View File

@ -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)

View File

@ -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; };

View File

@ -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

View File

@ -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();
}

View File

@ -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 */

View File

@ -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

View File

@ -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>)

View File

@ -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
};

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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)