diff --git a/mfbt/Alignment.h b/mfbt/Alignment.h index 29599d0ef18..e0843cad03e 100644 --- a/mfbt/Alignment.h +++ b/mfbt/Alignment.h @@ -21,14 +21,14 @@ namespace mozilla { template class AlignmentFinder { - struct Aligner - { - char c; - T t; - }; + struct Aligner + { + char mChar; + T mT; + }; - public: - static const size_t alignment = sizeof(Aligner) - sizeof(T); +public: + static const size_t alignment = sizeof(Aligner) - sizeof(T); }; #define MOZ_ALIGNOF(T) mozilla::AlignmentFinder::alignment @@ -71,31 +71,31 @@ struct AlignedElem; template<> struct AlignedElem<1> { - MOZ_ALIGNED_DECL(uint8_t elem, 1); + MOZ_ALIGNED_DECL(uint8_t elem, 1); }; template<> struct AlignedElem<2> { - MOZ_ALIGNED_DECL(uint8_t elem, 2); + MOZ_ALIGNED_DECL(uint8_t elem, 2); }; template<> struct AlignedElem<4> { - MOZ_ALIGNED_DECL(uint8_t elem, 4); + MOZ_ALIGNED_DECL(uint8_t elem, 4); }; template<> struct AlignedElem<8> { - MOZ_ALIGNED_DECL(uint8_t elem, 8); + MOZ_ALIGNED_DECL(uint8_t elem, 8); }; template<> struct AlignedElem<16> { - MOZ_ALIGNED_DECL(uint8_t elem, 16); + MOZ_ALIGNED_DECL(uint8_t elem, 16); }; /* @@ -111,25 +111,27 @@ struct AlignedElem<16> template struct AlignedStorage { - union U { - char bytes[Nbytes]; - uint64_t _; - } u; + union U + { + char mBytes[Nbytes]; + uint64_t mDummy; + } u; - const void* addr() const { return u.bytes; } - void* addr() { return u.bytes; } + const void* addr() const { return u.mBytes; } + void* addr() { return u.mBytes; } }; template struct AlignedStorage2 { - union U { - char bytes[sizeof(T)]; - uint64_t _; - } u; + union U + { + char mBytes[sizeof(T)]; + uint64_t mDummy; + } u; - const T* addr() const { return reinterpret_cast(u.bytes); } - T* addr() { return static_cast(static_cast(u.bytes)); } + const T* addr() const { return reinterpret_cast(u.mBytes); } + T* addr() { return static_cast(static_cast(u.mBytes)); } }; } /* namespace mozilla */ diff --git a/mfbt/AllocPolicy.h b/mfbt/AllocPolicy.h index 20087e93bbc..357c632a02b 100644 --- a/mfbt/AllocPolicy.h +++ b/mfbt/AllocPolicy.h @@ -49,14 +49,31 @@ namespace mozilla { */ class MallocAllocPolicy { - public: - void* malloc_(size_t bytes) { return malloc(bytes); } - void* calloc_(size_t bytes) { return calloc(bytes, 1); } - void* realloc_(void* p, size_t oldBytes, size_t bytes) { return realloc(p, bytes); } - void free_(void* p) { free(p); } - void reportAllocOverflow() const {} -}; +public: + void* malloc_(size_t aBytes) + { + return malloc(aBytes); + } + void* calloc_(size_t aBytes) + { + return calloc(aBytes, 1); + } + + void* realloc_(void* aPtr, size_t aOldBytes, size_t aBytes) + { + return realloc(aPtr, aBytes); + } + + void free_(void* aPtr) + { + free(aPtr); + } + + void reportAllocOverflow() const + { + } +}; } // namespace mozilla diff --git a/mfbt/Array.h b/mfbt/Array.h index 71e45dffd1f..b2ab578d4b8 100644 --- a/mfbt/Array.h +++ b/mfbt/Array.h @@ -19,31 +19,35 @@ namespace mozilla { template class Array { - T arr[Length]; + T mArr[Length]; - public: - T& operator[](size_t i) { - MOZ_ASSERT(i < Length); - return arr[i]; - } +public: + T& operator[](size_t aIndex) + { + MOZ_ASSERT(aIndex < Length); + return mArr[aIndex]; + } - const T& operator[](size_t i) const { - MOZ_ASSERT(i < Length); - return arr[i]; - } + const T& operator[](size_t aIndex) const + { + MOZ_ASSERT(aIndex < Length); + return mArr[aIndex]; + } }; template class Array { - public: - T& operator[](size_t i) { - MOZ_CRASH("indexing into zero-length array"); - } +public: + T& operator[](size_t aIndex) + { + MOZ_CRASH("indexing into zero-length array"); + } - const T& operator[](size_t i) const { - MOZ_CRASH("indexing into zero-length array"); - } + const T& operator[](size_t aIndex) const + { + MOZ_CRASH("indexing into zero-length array"); + } }; } /* namespace mozilla */ diff --git a/mfbt/ArrayUtils.h b/mfbt/ArrayUtils.h index 3d5a5d4ec05..fcf06f92f33 100644 --- a/mfbt/ArrayUtils.h +++ b/mfbt/ArrayUtils.h @@ -23,17 +23,17 @@ namespace mozilla { /* - * Safely subtract two pointers when it is known that end >= begin. This avoids - * the common compiler bug that if (size_t(end) - size_t(begin)) has the MSB - * set, the unsigned subtraction followed by right shift will produce -1, or - * size_t(-1), instead of the real difference. + * Safely subtract two pointers when it is known that aEnd >= aBegin. This + * avoids the common compiler bug that if (size_t(aEnd) - size_t(aBegin)) has + * the MSB set, the unsigned subtraction followed by right shift will produce + * -1, or size_t(-1), instead of the real difference. */ template MOZ_ALWAYS_INLINE size_t -PointerRangeSize(T* begin, T* end) +PointerRangeSize(T* aBegin, T* aEnd) { - MOZ_ASSERT(end >= begin); - return (size_t(end) - size_t(begin)) / sizeof(T); + MOZ_ASSERT(aEnd >= aBegin); + return (size_t(aEnd) - size_t(aBegin)) / sizeof(T); } /* @@ -44,14 +44,14 @@ PointerRangeSize(T* begin, T* end) */ template MOZ_CONSTEXPR size_t -ArrayLength(T (&arr)[N]) +ArrayLength(T (&aArr)[N]) { return N; } template MOZ_CONSTEXPR size_t -ArrayLength(const Array& arr) +ArrayLength(const Array& aArr) { return N; } @@ -63,23 +63,23 @@ ArrayLength(const Array& arr) */ template MOZ_CONSTEXPR T* -ArrayEnd(T (&arr)[N]) +ArrayEnd(T (&aArr)[N]) { - return arr + ArrayLength(arr); + return aArr + ArrayLength(aArr); } template MOZ_CONSTEXPR T* -ArrayEnd(Array& arr) +ArrayEnd(Array& aArr) { - return &arr[0] + ArrayLength(arr); + return &aArr[0] + ArrayLength(aArr); } template MOZ_CONSTEXPR const T* -ArrayEnd(const Array& arr) +ArrayEnd(const Array& aArr) { - return &arr[0] + ArrayLength(arr); + return &aArr[0] + ArrayLength(aArr); } namespace detail { diff --git a/mfbt/Assertions.h b/mfbt/Assertions.h index 15623aa3da6..857e034fc2f 100644 --- a/mfbt/Assertions.h +++ b/mfbt/Assertions.h @@ -32,13 +32,13 @@ * number of undesired macros and symbols. */ # ifdef __cplusplus - extern "C" { +extern "C" { # endif - __declspec(dllimport) int __stdcall - TerminateProcess(void* hProcess, unsigned int uExitCode); - __declspec(dllimport) void* __stdcall GetCurrentProcess(void); +__declspec(dllimport) int __stdcall +TerminateProcess(void* hProcess, unsigned int uExitCode); +__declspec(dllimport) void* __stdcall GetCurrentProcess(void); # ifdef __cplusplus - } +} # endif #else # include @@ -124,21 +124,23 @@ extern "C" { #endif /* - * Prints |s| as an assertion failure (using file and ln as the location of the - * assertion) to the standard debug-output channel. + * Prints |aStr| as an assertion failure (using aFilename and aLine as the + * location of the assertion) to the standard debug-output channel. * * Usually you should use MOZ_ASSERT or MOZ_CRASH instead of this method. This * method is primarily for internal use in this header, and only secondarily * for use in implementing release-build assertions. */ static MOZ_ALWAYS_INLINE void -MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS +MOZ_ReportAssertionFailure(const char* aStr, const char* aFilename, int aLine) + MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS { #ifdef ANDROID __android_log_print(ANDROID_LOG_FATAL, "MOZ_Assert", - "Assertion failure: %s, at %s:%d\n", s, file, ln); + "Assertion failure: %s, at %s:%d\n", + aStr, aFilename, aLine); #else - fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln); + fprintf(stderr, "Assertion failure: %s, at %s:%d\n", aStr, aFilename, aLine); #ifdef MOZ_DUMP_ASSERTION_STACK nsTraceRefcnt::WalkTheStack(stderr); #endif @@ -147,13 +149,13 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) MOZ_PRETEND_ } static MOZ_ALWAYS_INLINE void -MOZ_ReportCrash(const char* s, const char* file, int ln) 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", - "Hit MOZ_CRASH(%s) at %s:%d\n", s, file, ln); + __android_log_print(ANDROID_LOG_FATAL, "MOZ_CRASH", + "Hit MOZ_CRASH(%s) at %s:%d\n", aStr, aFilename, aLine); #else - fprintf(stderr, "Hit MOZ_CRASH(%s) at %s:%d\n", s, file, ln); + fprintf(stderr, "Hit MOZ_CRASH(%s) at %s:%d\n", aStr, aFilename, aLine); #ifdef MOZ_DUMP_ASSERTION_STACK nsTraceRefcnt::WalkTheStack(stderr); #endif @@ -319,13 +321,13 @@ namespace detail { template struct IsFunction { - static const bool value = false; + static const bool value = false; }; template struct IsFunction { - static const bool value = true; + static const bool value = true; }; template @@ -333,47 +335,51 @@ void ValidateAssertConditionType() { typedef typename RemoveReference::Type ValueT; static_assert(!IsArray::value, - "Expected boolean assertion condition, got an array or a string!"); + "Expected boolean assertion condition, got an array or a " + "string!"); static_assert(!IsFunction::value, - "Expected boolean assertion condition, got a function! Did you intend to call that function?"); + "Expected boolean assertion condition, got a function! Did " + "you intend to call that function?"); static_assert(!IsFloatingPoint::value, - "It's often a bad idea to assert that a floating-point number is nonzero, " - "because such assertions tend to intermittently fail. Shouldn't your code gracefully handle " - "this case instead of asserting? Anyway, if you really want to " - "do that, write an explicit boolean condition, like !!x or x!=0."); + "It's often a bad idea to assert that a floating-point number " + "is nonzero, because such assertions tend to intermittently " + "fail. Shouldn't your code gracefully handle this case instead " + "of asserting? Anyway, if you really want to do that, write an " + "explicit boolean condition, like !!x or x!=0."); } } // namespace detail } // namespace mozilla -# define MOZ_VALIDATE_ASSERT_CONDITION_TYPE(x) mozilla::detail::ValidateAssertConditionType() +# define MOZ_VALIDATE_ASSERT_CONDITION_TYPE(x) \ + mozilla::detail::ValidateAssertConditionType() #else # define MOZ_VALIDATE_ASSERT_CONDITION_TYPE(x) #endif /* First the single-argument form. */ #define MOZ_ASSERT_HELPER1(expr) \ - do { \ - MOZ_VALIDATE_ASSERT_CONDITION_TYPE(expr); \ - if (MOZ_UNLIKELY(!(expr))) { \ - MOZ_ReportAssertionFailure(#expr, __FILE__, __LINE__); \ - MOZ_REALLY_CRASH(); \ - } \ - } while (0) + do { \ + MOZ_VALIDATE_ASSERT_CONDITION_TYPE(expr); \ + if (MOZ_UNLIKELY(!(expr))) { \ + MOZ_ReportAssertionFailure(#expr, __FILE__, __LINE__); \ + MOZ_REALLY_CRASH(); \ + } \ + } while (0) /* Now the two-argument form. */ #define MOZ_ASSERT_HELPER2(expr, explain) \ - do { \ - MOZ_VALIDATE_ASSERT_CONDITION_TYPE(expr); \ - if (MOZ_UNLIKELY(!(expr))) { \ - MOZ_ReportAssertionFailure(#expr " (" explain ")", __FILE__, __LINE__); \ - MOZ_REALLY_CRASH(); \ - } \ - } while (0) + do { \ + MOZ_VALIDATE_ASSERT_CONDITION_TYPE(expr); \ + if (MOZ_UNLIKELY(!(expr))) { \ + MOZ_ReportAssertionFailure(#expr " (" explain ")", __FILE__, __LINE__); \ + MOZ_REALLY_CRASH(); \ + } \ + } while (0) #define MOZ_RELEASE_ASSERT_GLUE(a, b) a b #define MOZ_RELEASE_ASSERT(...) \ - MOZ_RELEASE_ASSERT_GLUE( \ - MOZ_PASTE_PREFIX_AND_ARG_COUNT(MOZ_ASSERT_HELPER, __VA_ARGS__), \ - (__VA_ARGS__)) + MOZ_RELEASE_ASSERT_GLUE( \ + MOZ_PASTE_PREFIX_AND_ARG_COUNT(MOZ_ASSERT_HELPER, __VA_ARGS__), \ + (__VA_ARGS__)) #ifdef DEBUG # define MOZ_ASSERT(...) MOZ_RELEASE_ASSERT(__VA_ARGS__) @@ -411,10 +417,11 @@ void ValidateAssertConditionType() #endif /* - * MOZ_ASSUME_UNREACHABLE_MARKER() expands to an expression which states that it is - * undefined behavior for execution to reach this point. No guarantees are made - * about what will happen if this is reached at runtime. Most code should use - * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE because it has extra asserts. + * MOZ_ASSUME_UNREACHABLE_MARKER() expands to an expression which states that + * it is undefined behavior for execution to reach this point. No guarantees + * are made about what will happen if this is reached at runtime. Most code + * should use MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE because it has extra + * asserts. */ #if defined(__clang__) # define MOZ_ASSUME_UNREACHABLE_MARKER() __builtin_unreachable() diff --git a/mfbt/Atomics.h b/mfbt/Atomics.h index eb138a06b6c..224de27b06b 100644 --- a/mfbt/Atomics.h +++ b/mfbt/Atomics.h @@ -114,6 +114,7 @@ enum MemoryOrdering { * ordering if you can't easily test non-x86 architectures! */ Relaxed, + /* * When an atomic value is updated with ReleaseAcquire ordering, and * that new value is observed with ReleaseAcquire ordering, prior @@ -135,6 +136,7 @@ enum MemoryOrdering { * a good, hard look at actual lock or mutex primitives first. */ ReleaseAcquire, + /* * When an atomic value is updated with SequentiallyConsistent * ordering, all writes observable when the update is observed, just @@ -184,126 +186,153 @@ template struct AtomicOrderConstraints; template<> struct AtomicOrderConstraints { - static const std::memory_order AtomicRMWOrder = std::memory_order_relaxed; - static const std::memory_order LoadOrder = std::memory_order_relaxed; - static const std::memory_order StoreOrder = std::memory_order_relaxed; - static const std::memory_order CompareExchangeFailureOrder = - std::memory_order_relaxed; + static const std::memory_order AtomicRMWOrder = std::memory_order_relaxed; + static const std::memory_order LoadOrder = std::memory_order_relaxed; + static const std::memory_order StoreOrder = std::memory_order_relaxed; + static const std::memory_order CompareExchangeFailureOrder = + std::memory_order_relaxed; }; template<> struct AtomicOrderConstraints { - static const std::memory_order AtomicRMWOrder = std::memory_order_acq_rel; - static const std::memory_order LoadOrder = std::memory_order_acquire; - static const std::memory_order StoreOrder = std::memory_order_release; - static const std::memory_order CompareExchangeFailureOrder = - std::memory_order_acquire; + static const std::memory_order AtomicRMWOrder = std::memory_order_acq_rel; + static const std::memory_order LoadOrder = std::memory_order_acquire; + static const std::memory_order StoreOrder = std::memory_order_release; + static const std::memory_order CompareExchangeFailureOrder = + std::memory_order_acquire; }; template<> struct AtomicOrderConstraints { - static const std::memory_order AtomicRMWOrder = std::memory_order_seq_cst; - static const std::memory_order LoadOrder = std::memory_order_seq_cst; - static const std::memory_order StoreOrder = std::memory_order_seq_cst; - static const std::memory_order CompareExchangeFailureOrder = - std::memory_order_seq_cst; + static const std::memory_order AtomicRMWOrder = std::memory_order_seq_cst; + static const std::memory_order LoadOrder = std::memory_order_seq_cst; + static const std::memory_order StoreOrder = std::memory_order_seq_cst; + static const std::memory_order CompareExchangeFailureOrder = + std::memory_order_seq_cst; }; template struct IntrinsicBase { - typedef std::atomic ValueType; - typedef AtomicOrderConstraints OrderedOp; + typedef std::atomic ValueType; + typedef AtomicOrderConstraints OrderedOp; }; template struct IntrinsicMemoryOps : public IntrinsicBase { - typedef IntrinsicBase Base; - static T load(const typename Base::ValueType& ptr) { - return ptr.load(Base::OrderedOp::LoadOrder); - } - static void store(typename Base::ValueType& ptr, T val) { - ptr.store(val, Base::OrderedOp::StoreOrder); - } - static T exchange(typename Base::ValueType& ptr, T val) { - return ptr.exchange(val, Base::OrderedOp::AtomicRMWOrder); - } - static bool compareExchange(typename Base::ValueType& ptr, T oldVal, T newVal) { - return ptr.compare_exchange_strong(oldVal, newVal, - Base::OrderedOp::AtomicRMWOrder, - Base::OrderedOp::CompareExchangeFailureOrder); - } + typedef IntrinsicBase Base; + + static T load(const typename Base::ValueType& aPtr) + { + return aPtr.load(Base::OrderedOp::LoadOrder); + } + + static void store(typename Base::ValueType& aPtr, T aVal) + { + aPtr.store(aVal, Base::OrderedOp::StoreOrder); + } + + static T exchange(typename Base::ValueType& aPtr, T aVal) + { + return aPtr.exchange(aVal, Base::OrderedOp::AtomicRMWOrder); + } + + static bool compareExchange(typename Base::ValueType& aPtr, + T aOldVal, T aNewVal) + { + return aPtr.compare_exchange_strong(aOldVal, aNewVal, + Base::OrderedOp::AtomicRMWOrder, + Base::OrderedOp::CompareExchangeFailureOrder); + } }; template struct IntrinsicAddSub : public IntrinsicBase { - typedef IntrinsicBase Base; - static T add(typename Base::ValueType& ptr, T val) { - return ptr.fetch_add(val, Base::OrderedOp::AtomicRMWOrder); - } - static T sub(typename Base::ValueType& ptr, T val) { - return ptr.fetch_sub(val, Base::OrderedOp::AtomicRMWOrder); - } + typedef IntrinsicBase Base; + + static T add(typename Base::ValueType& aPtr, T aVal) + { + return aPtr.fetch_add(aVal, Base::OrderedOp::AtomicRMWOrder); + } + + static T sub(typename Base::ValueType& aPtr, T aVal) + { + return aPtr.fetch_sub(aVal, Base::OrderedOp::AtomicRMWOrder); + } }; template struct IntrinsicAddSub : public IntrinsicBase { - typedef IntrinsicBase Base; - static T* add(typename Base::ValueType& ptr, ptrdiff_t val) { - return ptr.fetch_add(fixupAddend(val), Base::OrderedOp::AtomicRMWOrder); - } - static T* sub(typename Base::ValueType& ptr, ptrdiff_t val) { - return ptr.fetch_sub(fixupAddend(val), Base::OrderedOp::AtomicRMWOrder); - } - private: - /* - * GCC 4.6's header has a bug where adding X to an - * atomic 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 val) { + typedef IntrinsicBase Base; + + static T* add(typename Base::ValueType& aPtr, ptrdiff_t aVal) + { + return aPtr.fetch_add(fixupAddend(aVal), Base::OrderedOp::AtomicRMWOrder); + } + + static T* sub(typename Base::ValueType& aPtr, ptrdiff_t aVal) + { + return aPtr.fetch_sub(fixupAddend(aVal), Base::OrderedOp::AtomicRMWOrder); + } +private: + /* + * GCC 4.6's header has a bug where adding X to an + * atomic 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) { #if defined(__clang__) || defined(_MSC_VER) - return val; + return aVal; #elif defined(__GNUC__) && MOZ_GCC_VERSION_AT_LEAST(4, 6, 0) && \ - !MOZ_GCC_VERSION_AT_LEAST(4, 7, 0) - return val * sizeof(T); + !MOZ_GCC_VERSION_AT_LEAST(4, 7, 0) + return aVal * sizeof(T); #else - return val; + return aVal; #endif - } + } }; template struct IntrinsicIncDec : public IntrinsicAddSub { - typedef IntrinsicBase Base; - static T inc(typename Base::ValueType& ptr) { - return IntrinsicAddSub::add(ptr, 1); - } - static T dec(typename Base::ValueType& ptr) { - return IntrinsicAddSub::sub(ptr, 1); - } + typedef IntrinsicBase Base; + + static T inc(typename Base::ValueType& aPtr) + { + return IntrinsicAddSub::add(aPtr, 1); + } + + static T dec(typename Base::ValueType& aPtr) + { + return IntrinsicAddSub::sub(aPtr, 1); + } }; template struct AtomicIntrinsics : public IntrinsicMemoryOps, public IntrinsicIncDec { - typedef IntrinsicBase Base; - static T or_(typename Base::ValueType& ptr, T val) { - return ptr.fetch_or(val, Base::OrderedOp::AtomicRMWOrder); - } - static T xor_(typename Base::ValueType& ptr, T val) { - return ptr.fetch_xor(val, Base::OrderedOp::AtomicRMWOrder); - } - static T and_(typename Base::ValueType& ptr, T val) { - return ptr.fetch_and(val, Base::OrderedOp::AtomicRMWOrder); - } + typedef IntrinsicBase Base; + + static T or_(typename Base::ValueType& aPtr, T aVal) + { + return aPtr.fetch_or(aVal, Base::OrderedOp::AtomicRMWOrder); + } + + static T xor_(typename Base::ValueType& aPtr, T aVal) + { + return aPtr.fetch_xor(aVal, Base::OrderedOp::AtomicRMWOrder); + } + + static T and_(typename Base::ValueType& aPtr, T aVal) + { + return aPtr.fetch_and(aVal, Base::OrderedOp::AtomicRMWOrder); + } }; template @@ -352,111 +381,119 @@ template struct Barrier; template<> struct Barrier { - static void beforeLoad() {} - static void afterLoad() {} - static void beforeStore() {} - static void afterStore() {} + static void beforeLoad() {} + static void afterLoad() {} + static void beforeStore() {} + static void afterStore() {} }; template<> struct Barrier { - static void beforeLoad() {} - static void afterLoad() { __sync_synchronize(); } - static void beforeStore() { __sync_synchronize(); } - static void afterStore() {} + static void beforeLoad() {} + static void afterLoad() { __sync_synchronize(); } + static void beforeStore() { __sync_synchronize(); } + static void afterStore() {} }; template<> struct Barrier { - static void beforeLoad() { __sync_synchronize(); } - static void afterLoad() { __sync_synchronize(); } - static void beforeStore() { __sync_synchronize(); } - static void afterStore() { __sync_synchronize(); } + static void beforeLoad() { __sync_synchronize(); } + static void afterLoad() { __sync_synchronize(); } + static void beforeStore() { __sync_synchronize(); } + static void afterStore() { __sync_synchronize(); } }; template struct IntrinsicMemoryOps { - static T load(const T& ptr) { - Barrier::beforeLoad(); - T val = ptr; - Barrier::afterLoad(); - return val; - } - static void store(T& ptr, T val) { - Barrier::beforeStore(); - ptr = val; - Barrier::afterStore(); - } - static T exchange(T& ptr, T val) { - // __sync_lock_test_and_set is only an acquire barrier; loads and stores - // can't be moved up from after to before it, but they can be moved down - // from before to after it. We may want a stricter ordering, so we need - // an explicit barrier. + static T load(const T& aPtr) + { + Barrier::beforeLoad(); + T val = aPtr; + Barrier::afterLoad(); + return val; + } - Barrier::beforeStore(); - return __sync_lock_test_and_set(&ptr, val); - } - static bool compareExchange(T& ptr, T oldVal, T newVal) { - return __sync_bool_compare_and_swap(&ptr, oldVal, newVal); - } + static void store(T& aPtr, T aVal) + { + Barrier::beforeStore(); + aPtr = aVal; + Barrier::afterStore(); + } + + static T exchange(T& aPtr, T aVal) + { + // __sync_lock_test_and_set is only an acquire barrier; loads and stores + // can't be moved up from after to before it, but they can be moved down + // from before to after it. We may want a stricter ordering, so we need + // an explicit barrier. + Barrier::beforeStore(); + return __sync_lock_test_and_set(&aPtr, aVal); + } + + static bool compareExchange(T& aPtr, T aOldVal, T aNewVal) + { + return __sync_bool_compare_and_swap(&aPtr, aOldVal, aNewVal); + } }; template struct IntrinsicAddSub { - typedef T ValueType; - static T add(T& ptr, T val) { - return __sync_fetch_and_add(&ptr, val); - } - static T sub(T& ptr, T val) { - return __sync_fetch_and_sub(&ptr, val); - } + typedef T ValueType; + + static T add(T& aPtr, T aVal) + { + return __sync_fetch_and_add(&aPtr, aVal); + } + + static T sub(T& aPtr, T aVal) + { + return __sync_fetch_and_sub(&aPtr, aVal); + } }; template struct IntrinsicAddSub { - typedef T* ValueType; - /* - * The reinterpret_casts are needed so that - * __sync_fetch_and_{add,sub} will properly type-check. - * - * Also, these functions do not provide standard semantics for - * pointer types, so we need to adjust the addend. - */ - static ValueType add(ValueType& ptr, ptrdiff_t val) { - ValueType amount = reinterpret_cast(val * sizeof(T)); - return __sync_fetch_and_add(&ptr, amount); - } - static ValueType sub(ValueType& ptr, ptrdiff_t val) { - ValueType amount = reinterpret_cast(val * sizeof(T)); - return __sync_fetch_and_sub(&ptr, amount); - } + typedef T* ValueType; + + /* + * The reinterpret_casts are needed so that + * __sync_fetch_and_{add,sub} will properly type-check. + * + * Also, these functions do not provide standard semantics for + * pointer types, so we need to adjust the addend. + */ + static ValueType add(ValueType& aPtr, ptrdiff_t aVal) + { + ValueType amount = reinterpret_cast(aVal * sizeof(T)); + return __sync_fetch_and_add(&aPtr, amount); + } + + static ValueType sub(ValueType& aPtr, ptrdiff_t aVal) + { + ValueType amount = reinterpret_cast(aVal * sizeof(T)); + return __sync_fetch_and_sub(&aPtr, amount); + } }; template struct IntrinsicIncDec : public IntrinsicAddSub { - static T inc(T& ptr) { return IntrinsicAddSub::add(ptr, 1); } - static T dec(T& ptr) { return IntrinsicAddSub::sub(ptr, 1); } + static T inc(T& aPtr) { return IntrinsicAddSub::add(aPtr, 1); } + static T dec(T& aPtr) { return IntrinsicAddSub::sub(aPtr, 1); } }; template struct AtomicIntrinsics : public IntrinsicMemoryOps, public IntrinsicIncDec { - static T or_(T& ptr, T val) { - return __sync_fetch_and_or(&ptr, val); - } - static T xor_(T& ptr, T val) { - return __sync_fetch_and_xor(&ptr, val); - } - static T and_(T& ptr, T val) { - return __sync_fetch_and_and(&ptr, val); - } + static T or_( T& aPtr, T aVal) { return __sync_fetch_and_or(&aPtr, aVal); } + static T xor_(T& aPtr, T aVal) { return __sync_fetch_and_xor(&aPtr, aVal); } + static T and_(T& aPtr, T aVal) { return __sync_fetch_and_and(&aPtr, aVal); } }; template @@ -483,12 +520,12 @@ struct AtomicIntrinsics : public IntrinsicMemoryOps, */ extern "C" { -long __cdecl _InterlockedExchangeAdd(long volatile* dst, long value); -long __cdecl _InterlockedOr(long volatile* dst, long value); -long __cdecl _InterlockedXor(long volatile* dst, long value); -long __cdecl _InterlockedAnd(long volatile* dst, long value); -long __cdecl _InterlockedExchange(long volatile *dst, long value); -long __cdecl _InterlockedCompareExchange(long volatile *dst, long newVal, long oldVal); +long __cdecl _InterlockedExchangeAdd(long volatile* aDst, long aVal); +long __cdecl _InterlockedOr(long volatile* aDst, long aVal); +long __cdecl _InterlockedXor(long volatile* aDst, long aVal); +long __cdecl _InterlockedAnd(long volatile* aDst, long aVal); +long __cdecl _InterlockedExchange(long volatile *aDst, long aVal); +long __cdecl _InterlockedCompareExchange(long volatile *aDst, long aNewVal, long aOldVal); } # pragma intrinsic(_InterlockedExchangeAdd) @@ -514,34 +551,34 @@ namespace detail { * The PrimitiveIntrinsics template should define |Type|, the datatype of size * DataSize upon which we operate, and the following eight functions. * - * static Type add(Type* ptr, Type val); - * static Type sub(Type* ptr, Type val); - * static Type or_(Type* ptr, Type val); - * static Type xor_(Type* ptr, Type val); - * static Type and_(Type* ptr, Type val); + * static Type add(Type* aPtr, Type aVal); + * static Type sub(Type* aPtr, Type aVal); + * static Type or_(Type* aPtr, Type aVal); + * static Type xor_(Type* aPtr, Type aVal); + * static Type and_(Type* aPtr, Type aVal); * * These functions perform the obvious operation on the value contained in - * |*ptr| combined with |val| and return the value previously stored in - * |*ptr|. + * |*aPtr| combined with |aVal| and return the value previously stored in + * |*aPtr|. * - * static void store(Type* ptr, Type val); + * static void store(Type* aPtr, Type aVal); * - * This function atomically stores |val| into |*ptr| and must provide a full + * This function atomically stores |aVal| into |*aPtr| and must provide a full * memory fence after the store to prevent compiler and hardware instruction * reordering. It should also act as a compiler barrier to prevent reads and * writes from moving to after the store. * - * static Type exchange(Type* ptr, Type val); + * static Type exchange(Type* aPtr, Type aVal); * - * This function atomically stores |val| into |*ptr| and returns the previous - * contents of *ptr; + * This function atomically stores |aVal| into |*aPtr| and returns the + * previous contents of |*aPtr|; * - * static bool compareExchange(Type* ptr, Type oldVal, Type newVal); + * static bool compareExchange(Type* aPtr, Type aOldVal, Type aNewVal); * * This function atomically performs the following operation: * - * if (*ptr == oldVal) { - * *ptr = newVal; + * if (*aPtr == aOldVal) { + * *aPtr = aNewVal; * return true; * } else { * return false; @@ -553,54 +590,69 @@ template struct PrimitiveIntrinsics; template<> struct PrimitiveIntrinsics<4> { - typedef long Type; + typedef long Type; - static Type add(Type* ptr, Type val) { - return _InterlockedExchangeAdd(ptr, val); - } - static Type sub(Type* ptr, Type val) { - /* - * _InterlockedExchangeSubtract isn't available before Windows 7, - * and we must support Windows XP. - */ - return _InterlockedExchangeAdd(ptr, -val); - } - static Type or_(Type* ptr, Type val) { - return _InterlockedOr(ptr, val); - } - static Type xor_(Type* ptr, Type val) { - return _InterlockedXor(ptr, val); - } - static Type and_(Type* ptr, Type val) { - return _InterlockedAnd(ptr, val); - } - static void store(Type* ptr, Type val) { - _InterlockedExchange(ptr, val); - } - static Type exchange(Type* ptr, Type val) { - return _InterlockedExchange(ptr, val); - } - static bool compareExchange(Type* ptr, Type oldVal, Type newVal) { - return _InterlockedCompareExchange(ptr, newVal, oldVal) == oldVal; - } + static Type add(Type* aPtr, Type aVal) + { + return _InterlockedExchangeAdd(aPtr, aVal); + } + + static Type sub(Type* aPtr, Type aVal) + { + /* + * _InterlockedExchangeSubtract isn't available before Windows 7, + * and we must support Windows XP. + */ + return _InterlockedExchangeAdd(aPtr, -aVal); + } + + static Type or_(Type* aPtr, Type aVal) + { + return _InterlockedOr(aPtr, aVal); + } + + static Type xor_(Type* aPtr, Type aVal) + { + return _InterlockedXor(aPtr, aVal); + } + + static Type and_(Type* aPtr, Type aVal) + { + return _InterlockedAnd(aPtr, aVal); + } + + static void store(Type* aPtr, Type aVal) + { + _InterlockedExchange(aPtr, aVal); + } + + static Type exchange(Type* aPtr, Type aVal) + { + return _InterlockedExchange(aPtr, aVal); + } + + static bool compareExchange(Type* aPtr, Type aOldVal, Type aNewVal) + { + return _InterlockedCompareExchange(aPtr, aNewVal, aOldVal) == aOldVal; + } }; # if defined(_M_X64) extern "C" { -long long __cdecl _InterlockedExchangeAdd64(long long volatile* dst, - long long value); -long long __cdecl _InterlockedOr64(long long volatile* dst, - long long value); -long long __cdecl _InterlockedXor64(long long volatile* dst, - long long value); -long long __cdecl _InterlockedAnd64(long long volatile* dst, - long long value); -long long __cdecl _InterlockedExchange64(long long volatile* dst, - long long value); -long long __cdecl _InterlockedCompareExchange64(long long volatile* dst, - long long newVal, - long long oldVal); +long long __cdecl _InterlockedExchangeAdd64(long long volatile* aDst, + long long aVal); +long long __cdecl _InterlockedOr64(long long volatile* aDst, + long long aVal); +long long __cdecl _InterlockedXor64(long long volatile* aDst, + long long aVal); +long long __cdecl _InterlockedAnd64(long long volatile* aDst, + long long aVal); +long long __cdecl _InterlockedExchange64(long long volatile* aDst, + long long aVal); +long long __cdecl _InterlockedCompareExchange64(long long volatile* aDst, + long long aNewVal, + long long aOldVal); } # pragma intrinsic(_InterlockedExchangeAdd64) @@ -613,35 +665,50 @@ long long __cdecl _InterlockedCompareExchange64(long long volatile* dst, template <> struct PrimitiveIntrinsics<8> { - typedef __int64 Type; + typedef __int64 Type; - static Type add(Type* ptr, Type val) { - return _InterlockedExchangeAdd64(ptr, val); - } - static Type sub(Type* ptr, Type val) { - /* - * There is no _InterlockedExchangeSubtract64. - */ - return _InterlockedExchangeAdd64(ptr, -val); - } - static Type or_(Type* ptr, Type val) { - return _InterlockedOr64(ptr, val); - } - static Type xor_(Type* ptr, Type val) { - return _InterlockedXor64(ptr, val); - } - static Type and_(Type* ptr, Type val) { - return _InterlockedAnd64(ptr, val); - } - static void store(Type* ptr, Type val) { - _InterlockedExchange64(ptr, val); - } - static Type exchange(Type* ptr, Type val) { - return _InterlockedExchange64(ptr, val); - } - static bool compareExchange(Type* ptr, Type oldVal, Type newVal) { - return _InterlockedCompareExchange64(ptr, newVal, oldVal) == oldVal; - } + static Type add(Type* aPtr, Type aVal) + { + return _InterlockedExchangeAdd64(aPtr, aVal); + } + + static Type sub(Type* aPtr, Type aVal) + { + /* + * There is no _InterlockedExchangeSubtract64. + */ + return _InterlockedExchangeAdd64(aPtr, -aVal); + } + + static Type or_(Type* aPtr, Type aVal) + { + return _InterlockedOr64(aPtr, aVal); + } + + static Type xor_(Type* aPtr, Type aVal) + { + return _InterlockedXor64(aPtr, aVal); + } + + static Type and_(Type* aPtr, Type aVal) + { + return _InterlockedAnd64(aPtr, aVal); + } + + static void store(Type* aPtr, Type aVal) + { + _InterlockedExchange64(aPtr, aVal); + } + + static Type exchange(Type* aPtr, Type aVal) + { + return _InterlockedExchange64(aPtr, aVal); + } + + static bool compareExchange(Type* aPtr, Type aOldVal, Type aNewVal) + { + return _InterlockedCompareExchange64(aPtr, aNewVal, aOldVal) == aOldVal; + } }; # endif @@ -661,168 +728,193 @@ template struct Barrier; template<> struct Barrier { - static void beforeLoad() {} - static void afterLoad() {} - static void beforeStore() {} + static void beforeLoad() {} + static void afterLoad() {} + static void beforeStore() {} }; template<> struct Barrier { - static void beforeLoad() {} - static void afterLoad() { _ReadWriteBarrier(); } - static void beforeStore() { _ReadWriteBarrier(); } + static void beforeLoad() {} + static void afterLoad() { _ReadWriteBarrier(); } + static void beforeStore() { _ReadWriteBarrier(); } }; template<> struct Barrier { - static void beforeLoad() { _ReadWriteBarrier(); } - static void afterLoad() { _ReadWriteBarrier(); } - static void beforeStore() { _ReadWriteBarrier(); } + static void beforeLoad() { _ReadWriteBarrier(); } + static void afterLoad() { _ReadWriteBarrier(); } + static void beforeStore() { _ReadWriteBarrier(); } }; template struct CastHelper { - static PrimType toPrimType(T val) { return static_cast(val); } - static T fromPrimType(PrimType val) { return static_cast(val); } + static PrimType toPrimType(T aVal) { return static_cast(aVal); } + static T fromPrimType(PrimType aVal) { return static_cast(aVal); } }; template struct CastHelper { - static PrimType toPrimType(T* val) { return reinterpret_cast(val); } - static T* fromPrimType(PrimType val) { return reinterpret_cast(val); } + static PrimType toPrimType(T* aVal) { return reinterpret_cast(aVal); } + static T* fromPrimType(PrimType aVal) { return reinterpret_cast(aVal); } }; template struct IntrinsicBase { - typedef T ValueType; - typedef PrimitiveIntrinsics Primitives; - typedef typename Primitives::Type PrimType; - static_assert(sizeof(PrimType) == sizeof(T), - "Selection of PrimitiveIntrinsics was wrong"); - typedef CastHelper Cast; + typedef T ValueType; + typedef PrimitiveIntrinsics Primitives; + typedef typename Primitives::Type PrimType; + static_assert(sizeof(PrimType) == sizeof(T), + "Selection of PrimitiveIntrinsics was wrong"); + typedef CastHelper Cast; }; template struct IntrinsicMemoryOps : public IntrinsicBase { - typedef typename IntrinsicBase::ValueType ValueType; - typedef typename IntrinsicBase::Primitives Primitives; - typedef typename IntrinsicBase::PrimType PrimType; - typedef typename IntrinsicBase::Cast Cast; - static ValueType load(const ValueType& ptr) { - Barrier::beforeLoad(); - ValueType val = ptr; - Barrier::afterLoad(); - return val; - } - static void store(ValueType& ptr, ValueType val) { - // For SequentiallyConsistent, Primitives::store() will generate the - // proper memory fence. Everything else just needs a barrier before - // the store. - if (Order == SequentiallyConsistent) { - Primitives::store(reinterpret_cast(&ptr), - Cast::toPrimType(val)); - } else { - Barrier::beforeStore(); - ptr = val; - } - } - static ValueType exchange(ValueType& ptr, ValueType val) { - PrimType oldval = - Primitives::exchange(reinterpret_cast(&ptr), - Cast::toPrimType(val)); - return Cast::fromPrimType(oldval); - } - static bool compareExchange(ValueType& ptr, ValueType oldVal, ValueType newVal) { - return Primitives::compareExchange(reinterpret_cast(&ptr), - Cast::toPrimType(oldVal), - Cast::toPrimType(newVal)); + typedef typename IntrinsicBase::ValueType ValueType; + typedef typename IntrinsicBase::Primitives Primitives; + typedef typename IntrinsicBase::PrimType PrimType; + typedef typename IntrinsicBase::Cast Cast; + + static ValueType load(const ValueType& aPtr) + { + Barrier::beforeLoad(); + ValueType val = aPtr; + Barrier::afterLoad(); + return val; + } + + static void store(ValueType& aPtr, ValueType aVal) + { + // For SequentiallyConsistent, Primitives::store() will generate the + // proper memory fence. Everything else just needs a barrier before + // the store. + if (Order == SequentiallyConsistent) { + Primitives::store(reinterpret_cast(&aPtr), + Cast::toPrimType(aVal)); + } else { + Barrier::beforeStore(); + aPtr = aVal; } + } + + static ValueType exchange(ValueType& aPtr, ValueType aVal) + { + PrimType oldval = + Primitives::exchange(reinterpret_cast(&aPtr), + Cast::toPrimType(aVal)); + return Cast::fromPrimType(oldval); + } + + static bool compareExchange(ValueType& aPtr, ValueType aOldVal, + ValueType aNewVal) + { + return Primitives::compareExchange(reinterpret_cast(&aPtr), + Cast::toPrimType(aOldVal), + Cast::toPrimType(aNewVal)); + } }; template struct IntrinsicApplyHelper : public IntrinsicBase { - typedef typename IntrinsicBase::ValueType ValueType; - typedef typename IntrinsicBase::PrimType PrimType; - typedef typename IntrinsicBase::Cast Cast; - typedef PrimType (*BinaryOp)(PrimType*, PrimType); - typedef PrimType (*UnaryOp)(PrimType*); + typedef typename IntrinsicBase::ValueType ValueType; + typedef typename IntrinsicBase::PrimType PrimType; + typedef typename IntrinsicBase::Cast Cast; + typedef PrimType (*BinaryOp)(PrimType*, PrimType); + typedef PrimType (*UnaryOp)(PrimType*); - static ValueType applyBinaryFunction(BinaryOp op, ValueType& ptr, - ValueType val) { - PrimType* primTypePtr = reinterpret_cast(&ptr); - PrimType primTypeVal = Cast::toPrimType(val); - return Cast::fromPrimType(op(primTypePtr, primTypeVal)); - } + static ValueType applyBinaryFunction(BinaryOp aOp, ValueType& aPtr, + ValueType aVal) + { + PrimType* primTypePtr = reinterpret_cast(&aPtr); + PrimType primTypeVal = Cast::toPrimType(aVal); + return Cast::fromPrimType(aOp(primTypePtr, primTypeVal)); + } - static ValueType applyUnaryFunction(UnaryOp op, ValueType& ptr) { - PrimType* primTypePtr = reinterpret_cast(&ptr); - return Cast::fromPrimType(op(primTypePtr)); - } + static ValueType applyUnaryFunction(UnaryOp aOp, ValueType& aPtr) + { + PrimType* primTypePtr = reinterpret_cast(&aPtr); + return Cast::fromPrimType(aOp(primTypePtr)); + } }; template struct IntrinsicAddSub : public IntrinsicApplyHelper { - typedef typename IntrinsicApplyHelper::ValueType ValueType; - typedef typename IntrinsicBase::Primitives Primitives; - static ValueType add(ValueType& ptr, ValueType val) { - return applyBinaryFunction(&Primitives::add, ptr, val); - } - static ValueType sub(ValueType& ptr, ValueType val) { - return applyBinaryFunction(&Primitives::sub, ptr, val); - } + typedef typename IntrinsicApplyHelper::ValueType ValueType; + typedef typename IntrinsicBase::Primitives Primitives; + + static ValueType add(ValueType& aPtr, ValueType aVal) + { + return applyBinaryFunction(&Primitives::add, aPtr, aVal); + } + + static ValueType sub(ValueType& aPtr, ValueType aVal) + { + return applyBinaryFunction(&Primitives::sub, aPtr, aVal); + } }; template struct IntrinsicAddSub : public IntrinsicApplyHelper { - typedef typename IntrinsicApplyHelper::ValueType ValueType; - static ValueType add(ValueType& ptr, ptrdiff_t amount) { - return applyBinaryFunction(&Primitives::add, ptr, - (ValueType)(amount * sizeof(ValueType))); - } - static ValueType sub(ValueType& ptr, ptrdiff_t amount) { - return applyBinaryFunction(&Primitives::sub, ptr, - (ValueType)(amount * sizeof(ValueType))); - } + typedef typename IntrinsicApplyHelper::ValueType ValueType; + + static ValueType add(ValueType& aPtr, ptrdiff_t aAmount) + { + return applyBinaryFunction(&Primitives::add, aPtr, + (ValueType)(aAmount * sizeof(ValueType))); + } + + static ValueType sub(ValueType& aPtr, ptrdiff_t aAmount) + { + return applyBinaryFunction(&Primitives::sub, aPtr, + (ValueType)(aAmount * sizeof(ValueType))); + } }; template struct IntrinsicIncDec : public IntrinsicAddSub { - typedef typename IntrinsicAddSub::ValueType ValueType; - static ValueType inc(ValueType& ptr) { return add(ptr, 1); } - static ValueType dec(ValueType& ptr) { return sub(ptr, 1); } + typedef typename IntrinsicAddSub::ValueType ValueType; + static ValueType inc(ValueType& aPtr) { return add(aPtr, 1); } + static ValueType dec(ValueType& aPtr) { return sub(aPtr, 1); } }; template struct AtomicIntrinsics : public IntrinsicMemoryOps, public IntrinsicIncDec { - typedef typename IntrinsicIncDec::ValueType ValueType; - static ValueType or_(ValueType& ptr, T val) { - return applyBinaryFunction(&Primitives::or_, ptr, val); - } - static ValueType xor_(ValueType& ptr, T val) { - return applyBinaryFunction(&Primitives::xor_, ptr, val); - } - static ValueType and_(ValueType& ptr, T val) { - return applyBinaryFunction(&Primitives::and_, ptr, val); - } + typedef typename IntrinsicIncDec::ValueType ValueType; + + static ValueType or_(ValueType& aPtr, T aVal) + { + return applyBinaryFunction(&Primitives::or_, aPtr, aVal); + } + + static ValueType xor_(ValueType& aPtr, T aVal) + { + return applyBinaryFunction(&Primitives::xor_, aPtr, aVal); + } + + static ValueType and_(ValueType& aPtr, T aVal) + { + return applyBinaryFunction(&Primitives::and_, aPtr, aVal); + } }; template struct AtomicIntrinsics : public IntrinsicMemoryOps, public IntrinsicIncDec { - typedef typename IntrinsicMemoryOps::ValueType ValueType; + typedef typename IntrinsicMemoryOps::ValueType ValueType; }; } // namespace detail @@ -839,77 +931,80 @@ namespace detail { template class AtomicBase { - // We only support 32-bit types on 32-bit Windows, which constrains our - // implementation elsewhere. But we support pointer-sized types everywhere. - static_assert(sizeof(T) == 4 || (sizeof(uintptr_t) == 8 && sizeof(T) == 8), - "mozilla/Atomics.h only supports 32-bit and pointer-sized types"); + // We only support 32-bit types on 32-bit Windows, which constrains our + // implementation elsewhere. But we support pointer-sized types everywhere. + static_assert(sizeof(T) == 4 || (sizeof(uintptr_t) == 8 && sizeof(T) == 8), + "mozilla/Atomics.h only supports 32-bit and pointer-sized types"); - protected: - typedef typename detail::AtomicIntrinsics Intrinsics; - typename Intrinsics::ValueType mValue; +protected: + typedef typename detail::AtomicIntrinsics Intrinsics; + typename Intrinsics::ValueType mValue; - public: - MOZ_CONSTEXPR AtomicBase() : mValue() {} - MOZ_CONSTEXPR AtomicBase(T aInit) : mValue(aInit) {} +public: + MOZ_CONSTEXPR AtomicBase() : mValue() {} + MOZ_CONSTEXPR AtomicBase(T aInit) : mValue(aInit) {} - // Note: we can't provide operator T() here because Atomic inherits - // from AtomcBase with T=uint32_t and not T=bool. If we implemented - // operator T() here, it would cause errors when comparing Atomic with - // a regular bool. + // Note: we can't provide operator T() here because Atomic inherits + // from AtomcBase with T=uint32_t and not T=bool. If we implemented + // operator T() here, it would cause errors when comparing Atomic with + // a regular bool. - T operator=(T aValue) { - Intrinsics::store(mValue, aValue); - return aValue; - } + T operator=(T aVal) + { + Intrinsics::store(mValue, aVal); + return aVal; + } - /** - * Performs an atomic swap operation. aValue is stored and the previous - * value of this variable is returned. - */ - T exchange(T aValue) { - return Intrinsics::exchange(mValue, aValue); - } + /** + * Performs an atomic swap operation. aVal is stored and the previous + * value of this variable is returned. + */ + T exchange(T aVal) + { + return Intrinsics::exchange(mValue, aVal); + } - /** - * Performs an atomic compare-and-swap operation and returns true if it - * succeeded. This is equivalent to atomically doing - * - * if (mValue == aOldValue) { - * mValue = aNewValue; - * return true; - * } else { - * return false; - * } - */ - bool compareExchange(T aOldValue, T aNewValue) { - return Intrinsics::compareExchange(mValue, aOldValue, aNewValue); - } + /** + * Performs an atomic compare-and-swap operation and returns true if it + * succeeded. This is equivalent to atomically doing + * + * if (mValue == aOldValue) { + * mValue = aNewValue; + * return true; + * } else { + * return false; + * } + */ + bool compareExchange(T aOldValue, T aNewValue) + { + return Intrinsics::compareExchange(mValue, aOldValue, aNewValue); + } - private: - template - AtomicBase(const AtomicBase& aCopy) MOZ_DELETE; +private: + template + AtomicBase(const AtomicBase& aCopy) MOZ_DELETE; }; template class AtomicBaseIncDec : public AtomicBase { - typedef typename detail::AtomicBase Base; + typedef typename detail::AtomicBase Base; - public: - MOZ_CONSTEXPR AtomicBaseIncDec() : Base() {} - MOZ_CONSTEXPR AtomicBaseIncDec(T aInit) : Base(aInit) {} +public: + MOZ_CONSTEXPR AtomicBaseIncDec() : Base() {} + MOZ_CONSTEXPR AtomicBaseIncDec(T aInit) : Base(aInit) {} - using Base::operator=; + using Base::operator=; - operator T() const { return Base::Intrinsics::load(Base::mValue); } - T operator++(int) { return Base::Intrinsics::inc(Base::mValue); } - T operator--(int) { return Base::Intrinsics::dec(Base::mValue); } - T operator++() { return Base::Intrinsics::inc(Base::mValue) + 1; } - T operator--() { return Base::Intrinsics::dec(Base::mValue) - 1; } + operator T() const { return Base::Intrinsics::load(Base::mValue); } + T operator++(int) { return Base::Intrinsics::inc(Base::mValue); } + T operator--(int) { return Base::Intrinsics::dec(Base::mValue); } + T operator++() { return Base::Intrinsics::inc(Base::mValue) + 1; } + T operator--() { return Base::Intrinsics::dec(Base::mValue) - 1; } - private: - template - AtomicBaseIncDec(const AtomicBaseIncDec& aCopy) MOZ_DELETE; +private: + template + AtomicBaseIncDec(const AtomicBaseIncDec& aCopy) MOZ_DELETE; }; } // namespace detail @@ -945,25 +1040,45 @@ class Atomic; * swap method is provided. */ template -class Atomic::value && !IsSame::value>::Type> +class Atomic::value && + !IsSame::value>::Type> : public detail::AtomicBaseIncDec { - typedef typename detail::AtomicBaseIncDec Base; + typedef typename detail::AtomicBaseIncDec Base; - public: - MOZ_CONSTEXPR Atomic() : Base() {} - MOZ_CONSTEXPR Atomic(T aInit) : Base(aInit) {} +public: + MOZ_CONSTEXPR Atomic() : Base() {} + MOZ_CONSTEXPR Atomic(T aInit) : Base(aInit) {} - using Base::operator=; + using Base::operator=; - T operator+=(T delta) { return Base::Intrinsics::add(Base::mValue, delta) + delta; } - T operator-=(T delta) { return Base::Intrinsics::sub(Base::mValue, delta) - delta; } - T operator|=(T val) { return Base::Intrinsics::or_(Base::mValue, val) | val; } - T operator^=(T val) { return Base::Intrinsics::xor_(Base::mValue, val) ^ val; } - T operator&=(T val) { return Base::Intrinsics::and_(Base::mValue, val) & val; } + T operator+=(T aDelta) + { + return Base::Intrinsics::add(Base::mValue, aDelta) + aDelta; + } - private: - Atomic(Atomic& aOther) MOZ_DELETE; + T operator-=(T aDelta) + { + return Base::Intrinsics::sub(Base::mValue, aDelta) - aDelta; + } + + T operator|=(T aVal) + { + return Base::Intrinsics::or_(Base::mValue, aVal) | aVal; + } + + T operator^=(T aVal) + { + return Base::Intrinsics::xor_(Base::mValue, aVal) ^ aVal; + } + + T operator&=(T aVal) + { + return Base::Intrinsics::and_(Base::mValue, aVal) & aVal; + } + +private: + Atomic(Atomic& aOther) MOZ_DELETE; }; /** @@ -977,23 +1092,26 @@ class Atomic::value && !IsSame class Atomic : public detail::AtomicBaseIncDec { - typedef typename detail::AtomicBaseIncDec Base; + typedef typename detail::AtomicBaseIncDec Base; - public: - MOZ_CONSTEXPR Atomic() : Base() {} - MOZ_CONSTEXPR Atomic(T* aInit) : Base(aInit) {} +public: + MOZ_CONSTEXPR Atomic() : Base() {} + MOZ_CONSTEXPR Atomic(T* aInit) : Base(aInit) {} - using Base::operator=; + using Base::operator=; - T* operator+=(ptrdiff_t delta) { - return Base::Intrinsics::add(Base::mValue, delta) + delta; - } - T* operator-=(ptrdiff_t delta) { - return Base::Intrinsics::sub(Base::mValue, delta) - delta; - } + T* operator+=(ptrdiff_t aDelta) + { + return Base::Intrinsics::add(Base::mValue, aDelta) + aDelta; + } - private: - Atomic(Atomic& aOther) MOZ_DELETE; + T* operator-=(ptrdiff_t aDelta) + { + return Base::Intrinsics::sub(Base::mValue, aDelta) - aDelta; + } + +private: + Atomic(Atomic& aOther) MOZ_DELETE; }; /** @@ -1005,18 +1123,18 @@ template class Atomic::value>::Type> : public detail::AtomicBase { - typedef typename detail::AtomicBase Base; + typedef typename detail::AtomicBase Base; - public: - MOZ_CONSTEXPR Atomic() : Base() {} - MOZ_CONSTEXPR Atomic(T aInit) : Base(aInit) {} +public: + MOZ_CONSTEXPR Atomic() : Base() {} + MOZ_CONSTEXPR Atomic(T aInit) : Base(aInit) {} - operator T() const { return Base::Intrinsics::load(Base::mValue); } + operator T() const { return Base::Intrinsics::load(Base::mValue); } - using Base::operator=; + using Base::operator=; - private: - Atomic(Atomic& aOther) MOZ_DELETE; +private: + Atomic(Atomic& aOther) MOZ_DELETE; }; /** @@ -1039,22 +1157,35 @@ template class Atomic : protected detail::AtomicBase { - typedef typename detail::AtomicBase Base; + typedef typename detail::AtomicBase Base; - public: - MOZ_CONSTEXPR Atomic() : Base() {} - MOZ_CONSTEXPR Atomic(bool aInit) : Base(aInit) {} +public: + MOZ_CONSTEXPR Atomic() : Base() {} + MOZ_CONSTEXPR Atomic(bool aInit) : Base(aInit) {} - // We provide boolean wrappers for the underlying AtomicBase methods. - operator bool() const { return Base::Intrinsics::load(Base::mValue); } - bool operator=(bool aValue) { return Base::operator=(aValue); } - bool exchange(bool aValue) { return Base::exchange(aValue); } - bool compareExchange(bool aOldValue, bool aNewValue) { - return Base::compareExchange(aOldValue, aNewValue); - } + // We provide boolean wrappers for the underlying AtomicBase methods. + operator bool() const + { + return Base::Intrinsics::load(Base::mValue); + } - private: - Atomic(Atomic& aOther) MOZ_DELETE; + bool operator=(bool aVal) + { + return Base::operator=(aVal); + } + + bool exchange(bool aVal) + { + return Base::exchange(aVal); + } + + bool compareExchange(bool aOldValue, bool aNewValue) + { + return Base::compareExchange(aOldValue, aNewValue); + } + +private: + Atomic(Atomic& aOther) MOZ_DELETE; }; } // namespace mozilla diff --git a/mfbt/Attributes.h b/mfbt/Attributes.h index ba335800cf4..79b3a1bc62e 100644 --- a/mfbt/Attributes.h +++ b/mfbt/Attributes.h @@ -150,10 +150,10 @@ * template * class Ptr * { - * T* ptr; - * MOZ_EXPLICIT_CONVERSION operator bool() const { - * return ptr != nullptr; - * } + * T* ptr; + * MOZ_EXPLICIT_CONVERSION operator bool() const { + * return ptr != nullptr; + * } * }; * */ @@ -267,9 +267,9 @@ * * struct NonCopyable * { - * private: - * NonCopyable(const NonCopyable& other) MOZ_DELETE; - * void operator=(const NonCopyable& other) MOZ_DELETE; + * private: + * NonCopyable(const NonCopyable& other) MOZ_DELETE; + * void operator=(const NonCopyable& other) MOZ_DELETE; * }; * * If MOZ_DELETE can't be implemented for the current compiler, use of the @@ -295,23 +295,23 @@ * * class Base * { - * public: - * virtual void f() = 0; + * public: + * virtual void f() = 0; * }; * class Derived1 : public Base * { - * public: - * virtual void f() MOZ_OVERRIDE; + * public: + * virtual void f() MOZ_OVERRIDE; * }; * class Derived2 : public Base * { - * public: - * virtual void f() MOZ_OVERRIDE = 0; + * public: + * virtual void f() MOZ_OVERRIDE = 0; * }; * class Derived3 : public Base * { - * public: - * virtual void f() MOZ_OVERRIDE { } + * public: + * virtual void f() MOZ_OVERRIDE { } * }; * * In compilers supporting C++11 override controls, MOZ_OVERRIDE *requires* that @@ -339,16 +339,16 @@ * * class Base MOZ_FINAL * { - * public: - * Base(); - * ~Base(); - * virtual void f() { } + * public: + * Base(); + * ~Base(); + * virtual void f() { } * }; * // This will be an error in some compilers: * class Derived : public Base * { - * public: - * ~Derived() { } + * public: + * ~Derived() { } * }; * * One particularly common reason to specify MOZ_FINAL upon a class is to tell @@ -375,14 +375,14 @@ * * class Base * { - * public: - * virtual void f() MOZ_FINAL; + * public: + * virtual void f() MOZ_FINAL; * }; * class Derived * { - * public: - * // This will be an error in some compilers: - * virtual void f(); + * public: + * // This will be an error in some compilers: + * virtual void f(); * }; * * In compilers implementing final controls, it is an error for a derived class diff --git a/mfbt/BinarySearch.h b/mfbt/BinarySearch.h index 4013cd4f27e..5c195204e15 100644 --- a/mfbt/BinarySearch.h +++ b/mfbt/BinarySearch.h @@ -14,12 +14,12 @@ namespace mozilla { /* - * The algorithm searches the given container 'c' over the sorted index range - * [begin, end) for an index 'i' where 'c[i] == target'. If such an index 'i' is - * found, BinarySearch returns 'true' and the index is returned via the outparam - * 'matchOrInsertionPoint'. If no index is found, BinarySearch returns 'false' - * and the outparam returns the first index in [begin, end] where 'target' can - * be inserted to maintain sorted order. + * The algorithm searches the given container |aContainer| over the sorted + * index range [aBegin, aEnd) for an index |i| where |aContainer[i] == aTarget|. + * If such an index |i| is found, BinarySearch returns |true| and the index is + * returned via the outparam |aMatchOrInsertionPoint|. If no index is found, + * BinarySearch returns |false| and the outparam returns the first index in + * [aBegin, aEnd] where |aTarget| can be inserted to maintain sorted order. * * Example: * @@ -32,32 +32,34 @@ namespace mozilla { template bool -BinarySearch(const Container &c, size_t begin, size_t end, T target, size_t *matchOrInsertionPoint) +BinarySearch(const Container& aContainer, size_t aBegin, size_t aEnd, + T aTarget, size_t* aMatchOrInsertionPoint) { - MOZ_ASSERT(begin <= end); + MOZ_ASSERT(aBegin <= aEnd); - size_t low = begin; - size_t high = end; + size_t low = aBegin; + size_t high = aEnd; while (low != high) { size_t middle = low + (high - low) / 2; - const T &middleValue = c[middle]; + const T& middleValue = aContainer[middle]; - MOZ_ASSERT(c[low] <= c[middle]); - MOZ_ASSERT(c[middle] <= c[high - 1]); - MOZ_ASSERT(c[low] <= c[high - 1]); + MOZ_ASSERT(aContainer[low] <= aContainer[middle]); + MOZ_ASSERT(aContainer[middle] <= aContainer[high - 1]); + MOZ_ASSERT(aContainer[low] <= aContainer[high - 1]); - if (target == middleValue) { - *matchOrInsertionPoint = middle; + if (aTarget == middleValue) { + *aMatchOrInsertionPoint = middle; return true; } - if (target < middleValue) + if (aTarget < middleValue) { high = middle; - else + } else { low = middle + 1; + } } - *matchOrInsertionPoint = low; + *aMatchOrInsertionPoint = low; return false; } diff --git a/mfbt/BloomFilter.h b/mfbt/BloomFilter.h index 8129c489d4c..fe79d8caf53 100644 --- a/mfbt/BloomFilter.h +++ b/mfbt/BloomFilter.h @@ -55,177 +55,199 @@ namespace mozilla { template class BloomFilter { - /* - * A counting Bloom filter with 8-bit counters. For now we assume - * that having two hash functions is enough, but we may revisit that - * decision later. - * - * The filter uses an array with 2**KeySize entries. - * - * Assuming a well-distributed hash function, a Bloom filter with - * array size M containing N elements and - * using k hash function has expected false positive rate exactly - * - * $ (1 - (1 - 1/M)^{kN})^k $ - * - * because each array slot has a - * - * $ (1 - 1/M)^{kN} $ - * - * chance of being 0, and the expected false positive rate is the - * probability that all of the k hash functions will hit a nonzero - * slot. - * - * For reasonable assumptions (M large, kN large, which should both - * hold if we're worried about false positives) about M and kN this - * becomes approximately - * - * $$ (1 - \exp(-kN/M))^k $$ - * - * For our special case of k == 2, that's $(1 - \exp(-2N/M))^2$, - * or in other words - * - * $$ N/M = -0.5 * \ln(1 - \sqrt(r)) $$ - * - * where r is the false positive rate. This can be used to compute - * the desired KeySize for a given load N and false positive rate r. - * - * If N/M is assumed small, then the false positive rate can - * further be approximated as 4*N^2/M^2. So increasing KeySize by - * 1, which doubles M, reduces the false positive rate by about a - * factor of 4, and a false positive rate of 1% corresponds to - * about M/N == 20. - * - * What this means in practice is that for a few hundred keys using a - * KeySize of 12 gives false positive rates on the order of 0.25-4%. - * - * Similarly, using a KeySize of 10 would lead to a 4% false - * positive rate for N == 100 and to quite bad false positive - * rates for larger N. - */ - public: - BloomFilter() { - static_assert(KeySize <= keyShift, "KeySize too big"); + /* + * A counting Bloom filter with 8-bit counters. For now we assume + * that having two hash functions is enough, but we may revisit that + * decision later. + * + * The filter uses an array with 2**KeySize entries. + * + * Assuming a well-distributed hash function, a Bloom filter with + * array size M containing N elements and + * using k hash function has expected false positive rate exactly + * + * $ (1 - (1 - 1/M)^{kN})^k $ + * + * because each array slot has a + * + * $ (1 - 1/M)^{kN} $ + * + * chance of being 0, and the expected false positive rate is the + * probability that all of the k hash functions will hit a nonzero + * slot. + * + * For reasonable assumptions (M large, kN large, which should both + * hold if we're worried about false positives) about M and kN this + * becomes approximately + * + * $$ (1 - \exp(-kN/M))^k $$ + * + * For our special case of k == 2, that's $(1 - \exp(-2N/M))^2$, + * or in other words + * + * $$ N/M = -0.5 * \ln(1 - \sqrt(r)) $$ + * + * where r is the false positive rate. This can be used to compute + * the desired KeySize for a given load N and false positive rate r. + * + * If N/M is assumed small, then the false positive rate can + * further be approximated as 4*N^2/M^2. So increasing KeySize by + * 1, which doubles M, reduces the false positive rate by about a + * factor of 4, and a false positive rate of 1% corresponds to + * about M/N == 20. + * + * What this means in practice is that for a few hundred keys using a + * KeySize of 12 gives false positive rates on the order of 0.25-4%. + * + * Similarly, using a KeySize of 10 would lead to a 4% false + * positive rate for N == 100 and to quite bad false positive + * rates for larger N. + */ +public: + BloomFilter() + { + static_assert(KeySize <= kKeyShift, "KeySize too big"); - // Should we have a custom operator new using calloc instead and - // require that we're allocated via the operator? - clear(); - } + // Should we have a custom operator new using calloc instead and + // require that we're allocated via the operator? + clear(); + } - /* - * Clear the filter. This should be done before reusing it, because - * just removing all items doesn't clear counters that hit the upper - * bound. - */ - void clear(); + /* + * Clear the filter. This should be done before reusing it, because + * just removing all items doesn't clear counters that hit the upper + * bound. + */ + void clear(); - /* - * Add an item to the filter. - */ - void add(const T* t); + /* + * Add an item to the filter. + */ + void add(const T* aValue); - /* - * Remove an item from the filter. - */ - void remove(const T* t); + /* + * Remove an item from the filter. + */ + void remove(const T* aValue); - /* - * Check whether the filter might contain an item. This can - * sometimes return true even if the item is not in the filter, - * but will never return false for items that are actually in the - * filter. - */ - bool mightContain(const T* t) const; + /* + * Check whether the filter might contain an item. This can + * sometimes return true even if the item is not in the filter, + * but will never return false for items that are actually in the + * filter. + */ + bool mightContain(const T* aValue) const; - /* - * Methods for add/remove/contain when we already have a hash computed - */ - void add(uint32_t hash); - void remove(uint32_t hash); - bool mightContain(uint32_t hash) const; + /* + * Methods for add/remove/contain when we already have a hash computed + */ + void add(uint32_t aHash); + void remove(uint32_t aHash); + bool mightContain(uint32_t aHash) const; - private: - static const size_t arraySize = (1 << KeySize); - static const uint32_t keyMask = (1 << KeySize) - 1; - static const uint32_t keyShift = 16; +private: + static const size_t kArraySize = (1 << KeySize); + static const uint32_t kKeyMask = (1 << KeySize) - 1; + static const uint32_t kKeyShift = 16; - static uint32_t hash1(uint32_t hash) { return hash & keyMask; } - static uint32_t hash2(uint32_t hash) { return (hash >> keyShift) & keyMask; } + static uint32_t hash1(uint32_t aHash) + { + return aHash & kKeyMask; + } + static uint32_t hash2(uint32_t aHash) + { + return (aHash >> kKeyShift) & kKeyMask; + } - uint8_t& firstSlot(uint32_t hash) { return counters[hash1(hash)]; } - uint8_t& secondSlot(uint32_t hash) { return counters[hash2(hash)]; } - const uint8_t& firstSlot(uint32_t hash) const { return counters[hash1(hash)]; } - const uint8_t& secondSlot(uint32_t hash) const { return counters[hash2(hash)]; } + uint8_t& firstSlot(uint32_t aHash) + { + return mCounters[hash1(aHash)]; + } + uint8_t& secondSlot(uint32_t aHash) + { + return mCounters[hash2(aHash)]; + } - static bool full(const uint8_t& slot) { return slot == UINT8_MAX; } + const uint8_t& firstSlot(uint32_t aHash) const + { + return mCounters[hash1(aHash)]; + } + const uint8_t& secondSlot(uint32_t aHash) const + { + return mCounters[hash2(aHash)]; + } - uint8_t counters[arraySize]; + static bool full(const uint8_t& aSlot) { return aSlot == UINT8_MAX; } + + uint8_t mCounters[kArraySize]; }; template inline void BloomFilter::clear() { - memset(counters, 0, arraySize); + memset(mCounters, 0, kArraySize); } template inline void -BloomFilter::add(uint32_t hash) +BloomFilter::add(uint32_t aHash) { - uint8_t& slot1 = firstSlot(hash); - if (MOZ_LIKELY(!full(slot1))) + uint8_t& slot1 = firstSlot(aHash); + if (MOZ_LIKELY(!full(slot1))) { ++slot1; - - uint8_t& slot2 = secondSlot(hash); + } + uint8_t& slot2 = secondSlot(aHash); { if (MOZ_LIKELY(!full(slot2))) ++slot2; + } } template MOZ_ALWAYS_INLINE void -BloomFilter::add(const T* t) +BloomFilter::add(const T* aValue) { - uint32_t hash = t->hash(); + uint32_t hash = aValue->hash(); return add(hash); } template inline void -BloomFilter::remove(uint32_t hash) +BloomFilter::remove(uint32_t aHash) { // If the slots are full, we don't know whether we bumped them to be // there when we added or not, so just leave them full. - uint8_t& slot1 = firstSlot(hash); - if (MOZ_LIKELY(!full(slot1))) + uint8_t& slot1 = firstSlot(aHash); + if (MOZ_LIKELY(!full(slot1))) { --slot1; - - uint8_t& slot2 = secondSlot(hash); - if (MOZ_LIKELY(!full(slot2))) + } + uint8_t& slot2 = secondSlot(aHash); + if (MOZ_LIKELY(!full(slot2))) { --slot2; + } } template MOZ_ALWAYS_INLINE void -BloomFilter::remove(const T* t) +BloomFilter::remove(const T* aValue) { - uint32_t hash = t->hash(); + uint32_t hash = aValue->hash(); remove(hash); } template MOZ_ALWAYS_INLINE bool -BloomFilter::mightContain(uint32_t hash) const +BloomFilter::mightContain(uint32_t aHash) const { // Check that all the slots for this hash contain something - return firstSlot(hash) && secondSlot(hash); + return firstSlot(aHash) && secondSlot(aHash); } template MOZ_ALWAYS_INLINE bool -BloomFilter::mightContain(const T* t) const +BloomFilter::mightContain(const T* aValue) const { - uint32_t hash = t->hash(); + uint32_t hash = aValue->hash(); return mightContain(hash); } diff --git a/mfbt/Casting.h b/mfbt/Casting.h index 76df0ef27ef..dc449af6b69 100644 --- a/mfbt/Casting.h +++ b/mfbt/Casting.h @@ -17,7 +17,8 @@ namespace mozilla { /** - * Return a value of type |To|, containing the underlying bit pattern of |from|. + * Return a value of type |To|, containing the underlying bit pattern of + * |aFrom|. * * |To| and |From| must be types of the same size; be careful of cross-platform * size differences, or this might fail to compile on some but not all @@ -25,16 +26,17 @@ namespace mozilla { */ template inline To -BitwiseCast(const From from) +BitwiseCast(const From aFrom) { static_assert(sizeof(From) == sizeof(To), "To and From must have the same size"); - union { - From from; - To to; + union + { + From mFrom; + To mTo; } u; - u.from = from; - return u.to; + u.mFrom = aFrom; + return u.mTo; } namespace detail { @@ -58,34 +60,39 @@ enum UUComparison { FromIsBigger, FromIsNotBigger }; // Unsigned-to-unsigned range check template sizeof(To)) ? FromIsBigger : FromIsNotBigger> + UUComparison = (sizeof(From) > sizeof(To)) + ? FromIsBigger + : FromIsNotBigger> struct UnsignedUnsignedCheck; template struct UnsignedUnsignedCheck { - public: - static bool checkBounds(const From from) { - return from <= From(To(-1)); - } +public: + static bool checkBounds(const From aFrom) + { + return aFrom <= From(To(-1)); + } }; template struct UnsignedUnsignedCheck { - public: - static bool checkBounds(const From from) { - return true; - } +public: + static bool checkBounds(const From aFrom) + { + return true; + } }; template struct BoundsCheckImpl { - public: - static bool checkBounds(const From from) { - return UnsignedUnsignedCheck::checkBounds(from); - } +public: + static bool checkBounds(const From aFrom) + { + return UnsignedUnsignedCheck::checkBounds(aFrom); + } }; // Signed-to-unsigned range check @@ -93,14 +100,17 @@ struct BoundsCheckImpl template struct BoundsCheckImpl { - public: - static bool checkBounds(const From from) { - if (from < 0) - return false; - if (sizeof(To) >= sizeof(From)) - return true; - return from <= From(To(-1)); +public: + static bool checkBounds(const From aFrom) + { + if (aFrom < 0) { + return false; } + if (sizeof(To) >= sizeof(From)) { + return true; + } + return aFrom <= From(To(-1)); + } }; // Unsigned-to-signed range check @@ -108,35 +118,40 @@ struct BoundsCheckImpl enum USComparison { FromIsSmaller, FromIsNotSmaller }; template + USComparison = (sizeof(From) < sizeof(To)) + ? FromIsSmaller + : FromIsNotSmaller> struct UnsignedSignedCheck; template struct UnsignedSignedCheck { - public: - static bool checkBounds(const From from) { - return true; - } +public: + static bool checkBounds(const From aFrom) + { + return true; + } }; template struct UnsignedSignedCheck { - public: - static bool checkBounds(const From from) { - const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); - return from <= From(MaxValue); - } +public: + static bool checkBounds(const From aFrom) + { + const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); + return aFrom <= From(MaxValue); + } }; template struct BoundsCheckImpl { - public: - static bool checkBounds(const From from) { - return UnsignedSignedCheck::checkBounds(from); - } +public: + static bool checkBounds(const From aFrom) + { + return UnsignedSignedCheck::checkBounds(aFrom); + } }; // Signed-to-signed range check @@ -144,42 +159,46 @@ struct BoundsCheckImpl template struct BoundsCheckImpl { - public: - static bool checkBounds(const From from) { - if (sizeof(From) <= sizeof(To)) - return true; - const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); - const To MinValue = -MaxValue - To(1); - return From(MinValue) <= from && - From(from) <= From(MaxValue); +public: + static bool checkBounds(const From aFrom) + { + if (sizeof(From) <= sizeof(To)) { + return true; } + const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1); + const To MinValue = -MaxValue - To(1); + return From(MinValue) <= aFrom && + From(aFrom) <= From(MaxValue); + } }; template::value && IsIntegral::value> + bool TypesAreIntegral = IsIntegral::value && + IsIntegral::value> class BoundsChecker; template class BoundsChecker { - public: - static bool checkBounds(const From from) { return true; } +public: + static bool checkBounds(const From aFrom) { return true; } }; template class BoundsChecker { - public: - static bool checkBounds(const From from) { - return BoundsCheckImpl::checkBounds(from); - } +public: + static bool checkBounds(const From aFrom) + { + return BoundsCheckImpl::checkBounds(aFrom); + } }; template inline bool -IsInBounds(const From from) +IsInBounds(const From aFrom) { - return BoundsChecker::checkBounds(from); + return BoundsChecker::checkBounds(aFrom); } } // namespace detail @@ -191,10 +210,10 @@ IsInBounds(const From from) */ template inline To -SafeCast(const From from) +SafeCast(const From aFrom) { - MOZ_ASSERT((detail::IsInBounds(from))); - return static_cast(from); + MOZ_ASSERT((detail::IsInBounds(aFrom))); + return static_cast(aFrom); } } // namespace mozilla diff --git a/mfbt/ChaosMode.h b/mfbt/ChaosMode.h index e4e9d741926..ff59f2c6ec5 100644 --- a/mfbt/ChaosMode.h +++ b/mfbt/ChaosMode.h @@ -19,21 +19,21 @@ namespace mozilla { */ class ChaosMode { - public: - static bool isActive() - { - // Flip this to true to activate chaos mode - return false; - } +public: + static bool isActive() + { + // Flip this to true to activate chaos mode + return false; + } - /** - * Returns a somewhat (but not uniformly) random uint32_t < aBound. - * Not to be used for anything except ChaosMode, since it's not very random. - */ - static uint32_t randomUint32LessThan(uint32_t aBound) - { - return uint32_t(rand()) % aBound; - } + /** + * Returns a somewhat (but not uniformly) random uint32_t < aBound. + * Not to be used for anything except ChaosMode, since it's not very random. + */ + static uint32_t randomUint32LessThan(uint32_t aBound) + { + return uint32_t(rand()) % aBound; + } }; } /* namespace mozilla */ diff --git a/mfbt/Char16.h b/mfbt/Char16.h index 7bcd00840b5..af416690a0f 100644 --- a/mfbt/Char16.h +++ b/mfbt/Char16.h @@ -32,8 +32,8 @@ */ # define MOZ_UTF16_HELPER(s) L##s # define _CHAR16T - typedef wchar_t char16_t; - typedef unsigned int char32_t; +typedef wchar_t char16_t; +typedef unsigned int char32_t; #else /* C++11 has a builtin char16_t type. */ # define MOZ_UTF16_HELPER(s) u##s @@ -61,86 +61,108 @@ */ class char16ptr_t { - private: - const char16_t* ptr; - static_assert(sizeof(char16_t) == sizeof(wchar_t), "char16_t and wchar_t sizes differ"); +private: + const char16_t* mPtr; + static_assert(sizeof(char16_t) == sizeof(wchar_t), + "char16_t and wchar_t sizes differ"); - public: - char16ptr_t(const char16_t* p) : ptr(p) {} - char16ptr_t(const wchar_t* p) : ptr(reinterpret_cast(p)) {} +public: + char16ptr_t(const char16_t* aPtr) : mPtr(aPtr) {} + char16ptr_t(const wchar_t* aPtr) : + mPtr(reinterpret_cast(aPtr)) + {} - /* Without this, nullptr assignment would be ambiguous. */ - constexpr char16ptr_t(decltype(nullptr)) : ptr(nullptr) {} + /* Without this, nullptr assignment would be ambiguous. */ + constexpr char16ptr_t(decltype(nullptr)) : mPtr(nullptr) {} - operator const char16_t*() const { - return ptr; - } - operator const wchar_t*() const { - return reinterpret_cast(ptr); - } - operator const void*() const { - return ptr; - } - operator bool() const { - return ptr != nullptr; - } - operator std::wstring() const { - return std::wstring(static_cast(*this)); - } + operator const char16_t*() const + { + return mPtr; + } + operator const wchar_t*() const + { + return reinterpret_cast(mPtr); + } + operator const void*() const + { + return mPtr; + } + operator bool() const + { + return mPtr != nullptr; + } + operator std::wstring() const + { + return std::wstring(static_cast(*this)); + } - /* Explicit cast operators to allow things like (char16_t*)str. */ - explicit operator char16_t*() const { - return const_cast(ptr); - } - explicit operator wchar_t*() const { - return const_cast(static_cast(*this)); - } + /* Explicit cast operators to allow things like (char16_t*)str. */ + explicit operator char16_t*() const + { + return const_cast(mPtr); + } + explicit operator wchar_t*() const + { + return const_cast(static_cast(*this)); + } - /** - * 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 { - return reinterpret_cast(ptr); - } - explicit operator const unsigned char*() const { - return reinterpret_cast(ptr); - } - explicit operator unsigned char*() const { - return const_cast(reinterpret_cast(ptr)); - } - explicit operator void*() const { - return const_cast(ptr); - } + /** + * 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 + { + return reinterpret_cast(mPtr); + } + explicit operator const unsigned char*() const + { + return reinterpret_cast(mPtr); + } + explicit operator unsigned char*() const + { + return const_cast(reinterpret_cast(mPtr)); + } + explicit operator void*() const + { + return const_cast(mPtr); + } - /* Some operators used on pointers. */ - char16_t operator[](size_t i) const { - return ptr[i]; - } - bool operator==(const char16ptr_t &x) const { - return ptr == x.ptr; - } - bool operator==(decltype(nullptr)) const { - return ptr == nullptr; - } - bool operator!=(const char16ptr_t &x) const { - return ptr != x.ptr; - } - bool operator!=(decltype(nullptr)) const { - return ptr != nullptr; - } - char16ptr_t operator+(size_t add) const { - return char16ptr_t(ptr + add); - } - ptrdiff_t operator-(const char16ptr_t &other) const { - return ptr - other.ptr; - } + /* Some operators used on pointers. */ + char16_t operator[](size_t aIndex) const + { + return mPtr[aIndex]; + } + bool operator==(const char16ptr_t &aOther) const + { + return mPtr == aOther.mPtr; + } + bool operator==(decltype(nullptr)) const + { + return mPtr == nullptr; + } + bool operator!=(const char16ptr_t &aOther) const + { + return mPtr != aOther.mPtr; + } + bool operator!=(decltype(nullptr)) const + { + return mPtr != nullptr; + } + char16ptr_t operator+(size_t aValue) const + { + return char16ptr_t(mPtr + aValue); + } + ptrdiff_t operator-(const char16ptr_t &aOther) const + { + return mPtr - aOther.mPtr; + } }; inline decltype((char*)0-(char*)0) -operator-(const char16_t* x, const char16ptr_t y) { - return x - static_cast(y); +operator-(const char16_t* aX, const char16ptr_t aY) +{ + return aX - static_cast(aY); } #else diff --git a/mfbt/CheckedInt.h b/mfbt/CheckedInt.h index 548ba01eb83..e37c548eff4 100644 --- a/mfbt/CheckedInt.h +++ b/mfbt/CheckedInt.h @@ -35,13 +35,13 @@ struct UnsupportedType {}; template struct IsSupportedPass2 { - static const bool value = false; + static const bool value = false; }; template struct IsSupported { - static const bool value = IsSupportedPass2::value; + static const bool value = IsSupportedPass2::value; }; template<> @@ -130,36 +130,37 @@ struct IsSupportedPass2 template struct TwiceBiggerType { - typedef typename detail::StdintTypeForSizeAndSignedness< - sizeof(IntegerType) * 2, - IsSigned::value - >::Type Type; + typedef typename detail::StdintTypeForSizeAndSignedness< + sizeof(IntegerType) * 2, + IsSigned::value + >::Type Type; }; template struct TwiceBiggerType { - typedef UnsupportedType Type; + typedef UnsupportedType Type; }; template inline bool -HasSignBit(T x) +HasSignBit(T aX) { // In C++, right bit shifts on negative values is undefined by the standard. // Notice that signed-to-unsigned conversions are always well-defined in the // standard, as the value congruent modulo 2**n as expected. By contrast, // unsigned-to-signed is only well-defined if the value is representable. - return bool(typename MakeUnsigned::Type(x) >> PositionOfSignBit::value); + return bool(typename MakeUnsigned::Type(aX) >> + PositionOfSignBit::value); } // Bitwise ops may return a larger type, so it's good to use this inline // helper guaranteeing that the result is really of type T. template inline T -BinaryComplement(T x) +BinaryComplement(T aX) { - return ~x; + return ~aX; } template struct DoesRangeContainRange { - static const bool value = sizeof(T) >= sizeof(U); + static const bool value = sizeof(T) >= sizeof(U); }; template struct DoesRangeContainRange { - static const bool value = sizeof(T) > sizeof(U); + static const bool value = sizeof(T) > sizeof(U); }; template struct DoesRangeContainRange { - static const bool value = false; + static const bool value = false; }; template struct IsInRangeImpl { - static bool run(U) - { - return true; - } + static bool run(U) + { + return true; + } }; template struct IsInRangeImpl { - static bool run(U x) - { - return x <= MaxValue::value && x >= MinValue::value; - } + static bool run(U aX) + { + return aX <= MaxValue::value && aX >= MinValue::value; + } }; template struct IsInRangeImpl { - static bool run(U x) - { - return x <= MaxValue::value; - } + static bool run(U aX) + { + return aX <= MaxValue::value; + } }; template struct IsInRangeImpl { - static bool run(U x) - { - return sizeof(T) > sizeof(U) || x <= U(MaxValue::value); - } + static bool run(U aX) + { + return sizeof(T) > sizeof(U) || aX <= U(MaxValue::value); + } }; template struct IsInRangeImpl { - static bool run(U x) - { - return sizeof(T) >= sizeof(U) - ? x >= 0 - : x >= 0 && x <= U(MaxValue::value); - } + static bool run(U aX) + { + return sizeof(T) >= sizeof(U) + ? aX >= 0 + : aX >= 0 && aX <= U(MaxValue::value); + } }; template inline bool -IsInRange(U x) +IsInRange(U aX) { - return IsInRangeImpl::run(x); + return IsInRangeImpl::run(aX); } template inline bool -IsAddValid(T x, T y) +IsAddValid(T aX, T aY) { - // Addition is valid if the sign of x+y is equal to either that of x or that - // of y. Since the value of x+y is undefined if we have a signed type, we - // compute it using the unsigned type of the same size. - // Beware! These bitwise operations can return a larger integer type, - // if T was a small type like int8_t, so we explicitly cast to T. + // Addition is valid if the sign of aX+aY is equal to either that of aX or + // that of aY. Since the value of aX+aY is undefined if we have a signed + // type, we compute it using the unsigned type of the same size. Beware! + // These bitwise operations can return a larger integer type, if T was a + // small type like int8_t, so we explicitly cast to T. - typename MakeUnsigned::Type ux = x; - typename MakeUnsigned::Type uy = y; + typename MakeUnsigned::Type ux = aX; + typename MakeUnsigned::Type uy = aY; typename MakeUnsigned::Type result = ux + uy; return IsSigned::value - ? HasSignBit(BinaryComplement(T((result ^ x) & (result ^ y)))) - : BinaryComplement(x) >= y; + ? HasSignBit(BinaryComplement(T((result ^ aX) & (result ^ aY)))) + : BinaryComplement(aX) >= aY; } template inline bool -IsSubValid(T x, T y) +IsSubValid(T aX, T aY) { - // Subtraction is valid if either x and y have same sign, or x-y and x have - // same sign. Since the value of x-y is undefined if we have a signed type, - // we compute it using the unsigned type of the same size. - typename MakeUnsigned::Type ux = x; - typename MakeUnsigned::Type uy = y; + // Subtraction is valid if either aX and aY have same sign, or aX-aY and aX + // have same sign. Since the value of aX-aY is undefined if we have a signed + // type, we compute it using the unsigned type of the same size. + typename MakeUnsigned::Type ux = aX; + typename MakeUnsigned::Type uy = aY; typename MakeUnsigned::Type result = ux - uy; return IsSigned::value - ? HasSignBit(BinaryComplement(T((result ^ x) & (x ^ y)))) - : x >= y; + ? HasSignBit(BinaryComplement(T((result ^ aX) & (aX ^ aY)))) + : aX >= aY; } template struct IsMulValidImpl { - static bool run(T x, T y) - { - typedef typename TwiceBiggerType::Type TwiceBiggerType; - TwiceBiggerType product = TwiceBiggerType(x) * TwiceBiggerType(y); - return IsInRange(product); - } + static bool run(T aX, T aY) + { + typedef typename TwiceBiggerType::Type TwiceBiggerType; + TwiceBiggerType product = TwiceBiggerType(aX) * TwiceBiggerType(aY); + return IsInRange(product); + } }; template struct IsMulValidImpl { - static bool run(T x, T y) - { - const T max = MaxValue::value; - const T min = MinValue::value; + static bool run(T aX, T aY) + { + const T max = MaxValue::value; + const T min = MinValue::value; - if (x == 0 || y == 0) - return true; - - if (x > 0) { - return y > 0 - ? x <= max / y - : y >= min / x; - } - - // If we reach this point, we know that x < 0. - return y > 0 - ? x >= min / y - : y >= max / x; + if (aX == 0 || aY == 0) { + return true; } + if (aX > 0) { + return aY > 0 + ? aX <= max / aY + : aY >= min / aX; + } + + // If we reach this point, we know that aX < 0. + return aY > 0 + ? aX >= min / aY + : aY >= max / aX; + } }; template struct IsMulValidImpl { - static bool run(T x, T y) - { - return y == 0 || x <= MaxValue::value / y; - } + static bool run(T aX, T aY) + { + return aY == 0 || aX <= MaxValue::value / aY; + } }; template inline bool -IsMulValid(T x, T y) +IsMulValid(T aX, T aY) { - return IsMulValidImpl::run(x, y); + return IsMulValidImpl::run(aX, aY); } template inline bool -IsDivValid(T x, T y) +IsDivValid(T aX, T aY) { - // Keep in mind that in the signed case, min/-1 is invalid because abs(min)>max. - return y != 0 && - !(IsSigned::value && x == MinValue::value && y == T(-1)); + // Keep in mind that in the signed case, min/-1 is invalid because + // abs(min)>max. + return aY != 0 && + !(IsSigned::value && aX == MinValue::value && aY == T(-1)); } template::value> @@ -354,36 +356,40 @@ struct IsModValidImpl; template inline bool -IsModValid(T x, T y) +IsModValid(T aX, T aY) { - return IsModValidImpl::run(x, y); + return IsModValidImpl::run(aX, aY); } /* * Mod is pretty simple. * For now, let's just use the ANSI C definition: - * If x or y are negative, the results are implementation defined. + * If aX or aY are negative, the results are implementation defined. * Consider these invalid. - * Undefined for y=0. - * The result will never exceed either x or y. + * Undefined for aY=0. + * The result will never exceed either aX or aY. * - * Checking that x>=0 is a warning when T is unsigned. + * Checking that aX>=0 is a warning when T is unsigned. */ template -struct IsModValidImpl { - static inline bool run(T x, T y) { - return y >= 1; +struct IsModValidImpl +{ + static inline bool run(T aX, T aY) + { + return aY >= 1; } }; template -struct IsModValidImpl { - static inline bool run(T x, T y) { - if (x < 0) +struct IsModValidImpl +{ + static inline bool run(T aX, T aY) + { + if (aX < 0) { return false; - - return y >= 1; + } + return aY >= 1; } }; @@ -393,25 +399,26 @@ struct NegateImpl; template struct NegateImpl { - static CheckedInt negate(const CheckedInt& val) - { - // Handle negation separately for signed/unsigned, for simpler code and to - // avoid an MSVC warning negating an unsigned value. - return CheckedInt(0, val.isValid() && val.mValue == 0); - } + static CheckedInt negate(const CheckedInt& aVal) + { + // Handle negation separately for signed/unsigned, for simpler code and to + // avoid an MSVC warning negating an unsigned value. + return CheckedInt(0, aVal.isValid() && aVal.mValue == 0); + } }; template struct NegateImpl { - static CheckedInt negate(const CheckedInt& val) - { - // Watch out for the min-value, which (with twos-complement) can't be - // negated as -min-value is then (max-value + 1). - if (!val.isValid() || val.mValue == MinValue::value) - return CheckedInt(val.mValue, false); - return CheckedInt(-val.mValue, true); + static CheckedInt negate(const CheckedInt& aVal) + { + // Watch out for the min-value, which (with twos-complement) can't be + // negated as -min-value is then (max-value + 1). + if (!aVal.isValid() || aVal.mValue == MinValue::value) { + return CheckedInt(aVal.mValue, false); } + return CheckedInt(-aVal.mValue, true); + } }; } // namespace detail @@ -437,18 +444,18 @@ struct NegateImpl * (e.g. in case of a division by zero). * * For example, suppose that you want to implement a function that computes - * (x+y)/z, that doesn't crash if z==0, and that reports on error (divide by + * (aX+aY)/aZ, that doesn't crash if aZ==0, and that reports on error (divide by * zero or integer overflow). You could code it as follows: @code - bool computeXPlusYOverZ(int x, int y, int z, int *result) + bool computeXPlusYOverZ(int aX, int aY, int aZ, int *aResult) { - CheckedInt checkedResult = (CheckedInt(x) + y) / z; - if (checkedResult.isValid()) { - *result = checkedResult.value(); - return true; - } else { - return false; - } + CheckedInt checkedResult = (CheckedInt(aX) + aY) / aZ; + if (checkedResult.isValid()) { + *aResult = checkedResult.value(); + return true; + } else { + return false; + } } @endcode * @@ -491,193 +498,188 @@ struct NegateImpl template class CheckedInt { - protected: - T mValue; - bool mIsValid; +protected: + T mValue; + bool mIsValid; - template - CheckedInt(U aValue, bool aIsValid) : mValue(aValue), mIsValid(aIsValid) - { - static_assert(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); - } + template + CheckedInt(U aValue, bool aIsValid) : mValue(aValue), mIsValid(aIsValid) + { + static_assert(detail::IsSupported::value && + detail::IsSupported::value, + "This type is not supported by CheckedInt"); + } - friend struct detail::NegateImpl; + friend struct detail::NegateImpl; - public: - /** - * Constructs a checked integer with given @a value. The checked integer is - * initialized as valid or invalid depending on whether the @a value - * is in range. - * - * This constructor is not explicit. Instead, the type of its argument is a - * separate template parameter, ensuring that no conversion is performed - * before this constructor is actually called. As explained in the above - * documentation for class CheckedInt, this constructor checks that its - * argument is valid. - */ - template - CheckedInt(U aValue) - : mValue(T(aValue)), - mIsValid(detail::IsInRange(aValue)) - { - static_assert(detail::IsSupported::value && - detail::IsSupported::value, - "This type is not supported by CheckedInt"); - } +public: + /** + * Constructs a checked integer with given @a value. The checked integer is + * initialized as valid or invalid depending on whether the @a value + * is in range. + * + * This constructor is not explicit. Instead, the type of its argument is a + * separate template parameter, ensuring that no conversion is performed + * before this constructor is actually called. As explained in the above + * documentation for class CheckedInt, this constructor checks that its + * argument is valid. + */ + template + CheckedInt(U aValue) + : mValue(T(aValue)), + mIsValid(detail::IsInRange(aValue)) + { + static_assert(detail::IsSupported::value && + detail::IsSupported::value, + "This type is not supported by CheckedInt"); + } - template - friend class CheckedInt; + template + friend class CheckedInt; - template - CheckedInt toChecked() const - { - CheckedInt ret(mValue); - ret.mIsValid = ret.mIsValid && mIsValid; - return ret; - } + template + CheckedInt toChecked() const + { + CheckedInt ret(mValue); + ret.mIsValid = ret.mIsValid && mIsValid; + return ret; + } - /** Constructs a valid checked integer with initial value 0 */ - CheckedInt() : mValue(0), mIsValid(true) - { - static_assert(detail::IsSupported::value, - "This type is not supported by CheckedInt"); - } + /** Constructs a valid checked integer with initial value 0 */ + CheckedInt() : mValue(0), mIsValid(true) + { + static_assert(detail::IsSupported::value, + "This type is not supported by CheckedInt"); + } - /** @returns the actual value */ - T value() const - { - MOZ_ASSERT(mIsValid, "Invalid checked integer (division by zero or integer overflow)"); - return mValue; - } + /** @returns the actual value */ + T value() const + { + MOZ_ASSERT(mIsValid, "Invalid checked integer (division by zero or integer overflow)"); + return mValue; + } - /** - * @returns true if the checked integer is valid, i.e. is not the result - * of an invalid operation or of an operation involving an invalid checked - * integer - */ - bool isValid() const - { - return mIsValid; - } + /** + * @returns true if the checked integer is valid, i.e. is not the result + * of an invalid operation or of an operation involving an invalid checked + * integer + */ + bool isValid() const + { + return mIsValid; + } - template - friend CheckedInt operator +(const CheckedInt& lhs, - const CheckedInt& rhs); - template - CheckedInt& operator +=(U rhs); + template + friend CheckedInt operator +(const CheckedInt& aLhs, + const CheckedInt& aRhs); + template + CheckedInt& operator +=(U aRhs); - template - friend CheckedInt operator -(const CheckedInt& lhs, - const CheckedInt& rhs); - template - CheckedInt& operator -=(U rhs); + template + friend CheckedInt operator -(const CheckedInt& aLhs, + const CheckedInt& aRhs); + template + CheckedInt& operator -=(U aRhs); - template - friend CheckedInt operator *(const CheckedInt& lhs, - const CheckedInt& rhs); - template - CheckedInt& operator *=(U rhs); + template + friend CheckedInt operator *(const CheckedInt& aLhs, + const CheckedInt& aRhs); + template + CheckedInt& operator *=(U aRhs); - template - friend CheckedInt operator /(const CheckedInt& lhs, - const CheckedInt& rhs); - template - CheckedInt& operator /=(U rhs); + template + friend CheckedInt operator /(const CheckedInt& aLhs, + const CheckedInt& aRhs); + template + CheckedInt& operator /=(U aRhs); - template - friend CheckedInt operator %(const CheckedInt& lhs, - const CheckedInt& rhs); - template - CheckedInt& operator %=(U rhs); + template + friend CheckedInt operator %(const CheckedInt& aLhs, + const CheckedInt& aRhs); + template + CheckedInt& operator %=(U aRhs); - CheckedInt operator -() const - { - return detail::NegateImpl::negate(*this); - } + CheckedInt operator -() const + { + return detail::NegateImpl::negate(*this); + } - /** - * @returns true if the left and right hand sides are valid - * and have the same value. - * - * Note that these semantics are the reason why we don't offer - * a operator!=. Indeed, we'd want to have a!=b be equivalent to !(a==b) - * but that would mean that whenever a or b is invalid, a!=b - * is always true, which would be very confusing. - * - * For similar reasons, operators <, >, <=, >= would be very tricky to - * specify, so we just avoid offering them. - * - * Notice that these == semantics are made more reasonable by these facts: - * 1. a==b implies equality at the raw data level - * (the converse is false, as a==b is never true among invalids) - * 2. This is similar to the behavior of IEEE floats, where a==b - * means that a and b have the same value *and* neither is NaN. - */ - bool operator ==(const CheckedInt& other) const - { - return mIsValid && other.mIsValid && mValue == other.mValue; - } + /** + * @returns true if the left and right hand sides are valid + * and have the same value. + * + * Note that these semantics are the reason why we don't offer + * a operator!=. Indeed, we'd want to have a!=b be equivalent to !(a==b) + * but that would mean that whenever a or b is invalid, a!=b + * is always true, which would be very confusing. + * + * For similar reasons, operators <, >, <=, >= would be very tricky to + * specify, so we just avoid offering them. + * + * Notice that these == semantics are made more reasonable by these facts: + * 1. a==b implies equality at the raw data level + * (the converse is false, as a==b is never true among invalids) + * 2. This is similar to the behavior of IEEE floats, where a==b + * means that a and b have the same value *and* neither is NaN. + */ + bool operator ==(const CheckedInt& aOther) const + { + return mIsValid && aOther.mIsValid && mValue == aOther.mValue; + } - /** prefix ++ */ - CheckedInt& operator++() - { - *this += 1; - return *this; - } + /** prefix ++ */ + CheckedInt& operator++() + { + *this += 1; + return *this; + } - /** postfix ++ */ - CheckedInt operator++(int) - { - CheckedInt tmp = *this; - *this += 1; - return tmp; - } + /** postfix ++ */ + CheckedInt operator++(int) + { + CheckedInt tmp = *this; + *this += 1; + return tmp; + } - /** prefix -- */ - CheckedInt& operator--() - { - *this -= 1; - return *this; - } + /** prefix -- */ + CheckedInt& operator--() + { + *this -= 1; + return *this; + } - /** postfix -- */ - CheckedInt operator--(int) - { - CheckedInt tmp = *this; - *this -= 1; - return tmp; - } + /** postfix -- */ + CheckedInt operator--(int) + { + CheckedInt tmp = *this; + *this -= 1; + return tmp; + } - private: - /** - * The !=, <, <=, >, >= operators are disabled: - * see the comment on operator==. - */ - template - bool operator !=(U other) const MOZ_DELETE; - template - bool operator <(U other) const MOZ_DELETE; - template - bool operator <=(U other) const MOZ_DELETE; - template - bool operator >(U other) const MOZ_DELETE; - template - bool operator >=(U other) const MOZ_DELETE; +private: + /** + * The !=, <, <=, >, >= operators are disabled: + * see the comment on operator==. + */ + template bool operator !=(U aOther) const MOZ_DELETE; + template bool operator < (U aOther) const MOZ_DELETE; + template bool operator <=(U aOther) const MOZ_DELETE; + template bool operator > (U aOther) const MOZ_DELETE; + template bool operator >=(U aOther) const MOZ_DELETE; }; -#define MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(NAME, OP) \ -template \ -inline CheckedInt operator OP(const CheckedInt &lhs, \ - const CheckedInt &rhs) \ -{ \ - if (!detail::Is##NAME##Valid(lhs.mValue, rhs.mValue)) \ - return CheckedInt(0, false); \ - \ - return CheckedInt(lhs.mValue OP rhs.mValue, \ - lhs.mIsValid && rhs.mIsValid); \ -} +#define MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(NAME, OP) \ + template \ + inline CheckedInt \ + operator OP(const CheckedInt &aLhs, const CheckedInt &aRhs) \ + { \ + if (!detail::Is##NAME##Valid(aLhs.mValue, aRhs.mValue)) { \ + return CheckedInt(0, false); \ + } \ + return CheckedInt(aLhs.mValue OP aRhs.mValue, \ + aLhs.mIsValid && aRhs.mIsValid); \ + } MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Add, +) MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Sub, -) @@ -698,47 +700,47 @@ namespace detail { template struct CastToCheckedIntImpl { - typedef CheckedInt ReturnType; - static CheckedInt run(U u) { return u; } + typedef CheckedInt ReturnType; + static CheckedInt run(U aU) { return aU; } }; template struct CastToCheckedIntImpl > { - typedef const CheckedInt& ReturnType; - static const CheckedInt& run(const CheckedInt& u) { return u; } + typedef const CheckedInt& ReturnType; + static const CheckedInt& run(const CheckedInt& aU) { return aU; } }; } // namespace detail template inline typename detail::CastToCheckedIntImpl::ReturnType -castToCheckedInt(U u) +castToCheckedInt(U aU) { static_assert(detail::IsSupported::value && detail::IsSupported::value, "This type is not supported by CheckedInt"); - return detail::CastToCheckedIntImpl::run(u); + return detail::CastToCheckedIntImpl::run(aU); } -#define MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(OP, COMPOUND_OP) \ -template \ -template \ -CheckedInt& CheckedInt::operator COMPOUND_OP(U rhs) \ -{ \ - *this = *this OP castToCheckedInt(rhs); \ - return *this; \ -} \ -template \ -inline CheckedInt operator OP(const CheckedInt &lhs, U rhs) \ -{ \ - return lhs OP castToCheckedInt(rhs); \ -} \ -template \ -inline CheckedInt operator OP(U lhs, const CheckedInt &rhs) \ -{ \ - return castToCheckedInt(lhs) OP rhs; \ -} +#define MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(OP, COMPOUND_OP) \ + template \ + template \ + CheckedInt& CheckedInt::operator COMPOUND_OP(U aRhs) \ + { \ + *this = *this OP castToCheckedInt(aRhs); \ + return *this; \ + } \ + template \ + inline CheckedInt operator OP(const CheckedInt &aLhs, U aRhs) \ + { \ + return aLhs OP castToCheckedInt(aRhs); \ + } \ + template \ + inline CheckedInt operator OP(U aLhs, const CheckedInt &aRhs) \ + { \ + return castToCheckedInt(aLhs) OP aRhs; \ + } MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(+, +=) MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(*, *=) @@ -750,16 +752,16 @@ MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(%, %=) template inline bool -operator ==(const CheckedInt &lhs, U rhs) +operator ==(const CheckedInt &aLhs, U aRhs) { - return lhs == castToCheckedInt(rhs); + return aLhs == castToCheckedInt(aRhs); } template inline bool -operator ==(U lhs, const CheckedInt &rhs) +operator ==(U aLhs, const CheckedInt &aRhs) { - return castToCheckedInt(lhs) == rhs; + return castToCheckedInt(aLhs) == aRhs; } // Convenience typedefs. diff --git a/mfbt/Compression.cpp b/mfbt/Compression.cpp index a47eeea7a08..b22052978b7 100644 --- a/mfbt/Compression.cpp +++ b/mfbt/Compression.cpp @@ -1,9 +1,12 @@ +/* -*- 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/. */ #include "mozilla/Compression.h" #include "mozilla/CheckedInt.h" + using namespace mozilla::Compression; namespace { @@ -15,50 +18,51 @@ namespace { /* Our wrappers */ size_t -LZ4::compress(const char* source, size_t inputSize, char* dest) +LZ4::compress(const char* aSource, size_t aInputSize, char* aDest) { - CheckedInt inputSizeChecked = inputSize; - MOZ_ASSERT(inputSizeChecked.isValid()); - return LZ4_compress(source, dest, inputSizeChecked.value()); + CheckedInt inputSizeChecked = aInputSize; + MOZ_ASSERT(inputSizeChecked.isValid()); + return LZ4_compress(aSource, aDest, inputSizeChecked.value()); } size_t -LZ4::compressLimitedOutput(const char* source, size_t inputSize, char* dest, size_t maxOutputSize) +LZ4::compressLimitedOutput(const char* aSource, size_t aInputSize, char* aDest, + size_t aMaxOutputSize) { - CheckedInt inputSizeChecked = inputSize; - MOZ_ASSERT(inputSizeChecked.isValid()); - CheckedInt maxOutputSizeChecked = maxOutputSize; - MOZ_ASSERT(maxOutputSizeChecked.isValid()); - return LZ4_compress_limitedOutput(source, dest, inputSizeChecked.value(), - maxOutputSizeChecked.value()); + CheckedInt inputSizeChecked = aInputSize; + MOZ_ASSERT(inputSizeChecked.isValid()); + CheckedInt maxOutputSizeChecked = aMaxOutputSize; + MOZ_ASSERT(maxOutputSizeChecked.isValid()); + return LZ4_compress_limitedOutput(aSource, aDest, inputSizeChecked.value(), + maxOutputSizeChecked.value()); } bool -LZ4::decompress(const char* source, char* dest, size_t outputSize) +LZ4::decompress(const char* aSource, char* aDest, size_t aOutputSize) { - CheckedInt outputSizeChecked = outputSize; - MOZ_ASSERT(outputSizeChecked.isValid()); - int ret = LZ4_decompress_fast(source, dest, outputSizeChecked.value()); - return ret >= 0; + CheckedInt outputSizeChecked = aOutputSize; + MOZ_ASSERT(outputSizeChecked.isValid()); + int ret = LZ4_decompress_fast(aSource, aDest, outputSizeChecked.value()); + return ret >= 0; } bool -LZ4::decompress(const char* source, size_t inputSize, char* dest, size_t maxOutputSize, - size_t *outputSize) +LZ4::decompress(const char* aSource, size_t aInputSize, char* aDest, + size_t aMaxOutputSize, size_t *aOutputSize) { - CheckedInt maxOutputSizeChecked = maxOutputSize; - MOZ_ASSERT(maxOutputSizeChecked.isValid()); - CheckedInt inputSizeChecked = inputSize; - MOZ_ASSERT(inputSizeChecked.isValid()); + CheckedInt maxOutputSizeChecked = aMaxOutputSize; + MOZ_ASSERT(maxOutputSizeChecked.isValid()); + CheckedInt inputSizeChecked = aInputSize; + MOZ_ASSERT(inputSizeChecked.isValid()); - int ret = LZ4_decompress_safe(source, dest, inputSizeChecked.value(), - maxOutputSizeChecked.value()); - if (ret >= 0) { - *outputSize = ret; - return true; - } else { - *outputSize = 0; - return false; - } + int ret = LZ4_decompress_safe(aSource, aDest, inputSizeChecked.value(), + maxOutputSizeChecked.value()); + if (ret >= 0) { + *aOutputSize = ret; + return true; + } + + *aOutputSize = 0; + return false; } diff --git a/mfbt/Compression.h b/mfbt/Compression.h index 592f6f457d8..8f9336752ba 100644 --- a/mfbt/Compression.h +++ b/mfbt/Compression.h @@ -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/. */ @@ -22,41 +23,41 @@ namespace Compression { * * Compared to zlib it compresses at about 10x the speed, decompresses at about * 4x the speed and produces output of about 1.5x the size. - * */ class LZ4 { - public: - /** - * Compresses 'inputSize' bytes from 'source' into 'dest'. - * Destination buffer must be already allocated, - * and must be sized to handle worst cases situations (input data not compressible) - * Worst case size evaluation is provided by function maxCompressedSize() + * Compresses |aInputSize| bytes from |aSource| into |aDest|. Destination + * buffer must be already allocated, and must be sized to handle worst cases + * situations (input data not compressible). Worst case size evaluation is + * provided by function maxCompressedSize() * - * @param inputSize is the input size. Max supported value is ~1.9GB - * @param return the number of bytes written in buffer dest + * @param aInputSize is the input size. Max supported value is ~1.9GB + * @return the number of bytes written in buffer |aDest| */ - static MFBT_API size_t compress(const char* source, size_t inputSize, char* dest); + static MFBT_API size_t + compress(const char* aSource, size_t aInputSize, char* aDest); /** - * Compress 'inputSize' bytes from 'source' into an output buffer - * 'dest' of maximum size 'maxOutputSize'. If it cannot achieve it, + * Compress |aInputSize| bytes from |aSource| into an output buffer + * |aDest| of maximum size |aMaxOutputSize|. If it cannot achieve it, * compression will stop, and result of the function will be zero, - * 'dest' will still be written to, but since the number of input + * |aDest| will still be written to, but since the number of input * bytes consumed is not returned the result is not usable. * * This function never writes outside of provided output buffer. * - * @param inputSize is the input size. Max supported value is ~1.9GB - * @param maxOutputSize is the size of the destination buffer (which must be already allocated) - * @return the number of bytes written in buffer 'dest' - or 0 if the compression fails - */ - static MFBT_API size_t compressLimitedOutput(const char* source, size_t inputSize, char* dest, - size_t maxOutputSize); + * @param aInputSize is the input size. Max supported value is ~1.9GB + * @param aMaxOutputSize is the size of the destination buffer (which must + * be already allocated) + * @return the number of bytes written in buffer |aDest| or 0 if the + * compression fails + */ + static MFBT_API size_t + compressLimitedOutput(const char* aSource, size_t aInputSize, char* aDest, + size_t aMaxOutputSize); /** * If the source stream is malformed, the function will stop decoding @@ -66,48 +67,50 @@ public: * This function never writes outside of provided buffers, and never * modifies input buffer. * - * note : destination buffer must be already allocated. - * its size must be a minimum of 'outputSize' bytes. - * @param outputSize is the output size, therefore the original size + * Note: destination buffer must be already allocated, and its size must be a + * minimum of |aOutputSize| bytes. + * + * @param aOutputSize is the output size, therefore the original size * @return the number of bytes read in the source buffer - */ - static MFBT_API bool decompress(const char* source, char* dest, size_t outputSize); + */ + static MFBT_API bool + decompress(const char* aSource, char* aDest, size_t aOutputSize); /** * If the source stream is malformed, the function will stop decoding * and return false. * - * This function never writes beyond dest + maxOutputSize, and is + * This function never writes beyond aDest + aMaxOutputSize, and is * therefore protected against malicious data packets. * - * note : Destination buffer must be already allocated. - * This version is slightly slower than the decompress - * without the maxOutputSize + * Note: Destination buffer must be already allocated. This version is + * slightly slower than the decompress without the aMaxOutputSize. * - * @param inputSize is the length of the input compressed data - * @param maxOutputSize is the size of the destination buffer (which must be already allocated) - * @param outputSize the actual number of bytes decoded in the destination buffer (necessarily <= maxOutputSize) - - */ - static MFBT_API bool decompress(const char* source, size_t inputSize, char* dest, - size_t maxOutputSize, size_t *outputSize); + * @param aInputSize is the length of the input compressed data + * @param aMaxOutputSize is the size of the destination buffer (which must be + * already allocated) + * @param aOutputSize the actual number of bytes decoded in the destination + * buffer (necessarily <= aMaxOutputSize) + */ + static MFBT_API bool + decompress(const char* aSource, size_t aInputSize, char* aDest, + size_t aMaxOutputSize, size_t *aOutputSize); /* - Provides the maximum size that LZ4 may output in a "worst case" - scenario (input data not compressible) primarily useful for memory - allocation of output buffer. - note : this function is limited by "int" range (2^31-1) - - @param inputSize is the input size. Max supported value is ~1.9GB - @return maximum output size in a "worst case" scenario - */ - static inline size_t maxCompressedSize(size_t inputSize) + * Provides the maximum size that LZ4 may output in a "worst case" + * scenario (input data not compressible) primarily useful for memory + * allocation of output buffer. + * note : this function is limited by "int" range (2^31-1) + * + * @param aInputSize is the input size. Max supported value is ~1.9GB + * @return maximum output size in a "worst case" scenario + */ + static inline size_t maxCompressedSize(size_t aInputSize) { - size_t max = ((inputSize) + ((inputSize)/255) + 16); - MOZ_ASSERT(max > inputSize); - return max; + size_t max = (aInputSize + (aInputSize / 255) + 16); + MOZ_ASSERT(max > aInputSize); + return max; } - }; } /* namespace Compression */ diff --git a/mfbt/DebugOnly.h b/mfbt/DebugOnly.h index abbbc20ba12..fc1e029a7bb 100644 --- a/mfbt/DebugOnly.h +++ b/mfbt/DebugOnly.h @@ -34,47 +34,44 @@ namespace mozilla { template class DebugOnly { - public: +public: #ifdef DEBUG - T value; + T value; - DebugOnly() { } - DebugOnly(const T& other) : value(other) { } - DebugOnly(const DebugOnly& other) : value(other.value) { } - DebugOnly& operator=(const T& rhs) { - value = rhs; - return *this; - } - void operator++(int) { - value++; - } - void operator--(int) { - value--; - } + DebugOnly() { } + DebugOnly(const T& aOther) : value(aOther) { } + DebugOnly(const DebugOnly& aOther) : value(aOther.value) { } + DebugOnly& operator=(const T& aRhs) { + value = aRhs; + return *this; + } - T* operator&() { return &value; } + void operator++(int) { value++; } + void operator--(int) { value--; } - operator T&() { return value; } - operator const T&() const { return value; } + T* operator&() { return &value; } - T& operator->() { return value; } - const T& operator->() const { return value; } + operator T&() { return value; } + operator const T&() const { return value; } + + T& operator->() { return value; } + const T& operator->() const { return value; } #else - DebugOnly() { } - DebugOnly(const T&) { } - DebugOnly(const DebugOnly&) { } - DebugOnly& operator=(const T&) { return *this; } - void operator++(int) { } - void operator--(int) { } + DebugOnly() { } + DebugOnly(const T&) { } + DebugOnly(const DebugOnly&) { } + DebugOnly& operator=(const T&) { return *this; } + void operator++(int) { } + void operator--(int) { } #endif - /* - * DebugOnly must always have a destructor or else it will - * generate "unused variable" warnings, exactly what it's intended - * to avoid! - */ - ~DebugOnly() {} + /* + * DebugOnly must always have a destructor or else it will + * generate "unused variable" warnings, exactly what it's intended + * to avoid! + */ + ~DebugOnly() {} }; }