mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Style patrol to make everything conform to mfbt/STYLE. No bug, r=sparky
This commit is contained in:
parent
6400135f0b
commit
03b6751e09
@ -1,7 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
@ -52,7 +52,8 @@ namespace mozilla {
|
||||
*/
|
||||
|
||||
template<unsigned KeySize, class T>
|
||||
class BloomFilter {
|
||||
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
|
||||
@ -101,7 +102,7 @@ class BloomFilter {
|
||||
* positive rate for N == 100 and to quite bad false positive
|
||||
* rates for larger N.
|
||||
*/
|
||||
public:
|
||||
public:
|
||||
BloomFilter() {
|
||||
MOZ_STATIC_ASSERT(KeySize <= keyShift, "KeySize too big");
|
||||
|
||||
@ -142,7 +143,7 @@ public:
|
||||
void remove(uint32_t hash);
|
||||
bool mightContain(uint32_t hash) const;
|
||||
|
||||
private:
|
||||
private:
|
||||
static const size_t arraySize = (1 << KeySize);
|
||||
static const uint32_t keyMask = (1 << KeySize) - 1;
|
||||
static const uint32_t keyShift = 16;
|
||||
@ -164,67 +165,67 @@ template<unsigned KeySize, class T>
|
||||
inline void
|
||||
BloomFilter<KeySize, T>::clear()
|
||||
{
|
||||
memset(counters, 0, arraySize);
|
||||
memset(counters, 0, arraySize);
|
||||
}
|
||||
|
||||
template<unsigned KeySize, class T>
|
||||
inline void
|
||||
BloomFilter<KeySize, T>::add(uint32_t hash)
|
||||
{
|
||||
uint8_t& slot1 = firstSlot(hash);
|
||||
if (MOZ_LIKELY(!full(slot1)))
|
||||
++slot1;
|
||||
uint8_t& slot1 = firstSlot(hash);
|
||||
if (MOZ_LIKELY(!full(slot1)))
|
||||
++slot1;
|
||||
|
||||
uint8_t& slot2 = secondSlot(hash);
|
||||
if (MOZ_LIKELY(!full(slot2)))
|
||||
++slot2;
|
||||
uint8_t& slot2 = secondSlot(hash);
|
||||
if (MOZ_LIKELY(!full(slot2)))
|
||||
++slot2;
|
||||
}
|
||||
|
||||
template<unsigned KeySize, class T>
|
||||
MOZ_ALWAYS_INLINE void
|
||||
BloomFilter<KeySize, T>::add(const T* t)
|
||||
{
|
||||
uint32_t hash = t->hash();
|
||||
return add(hash);
|
||||
uint32_t hash = t->hash();
|
||||
return add(hash);
|
||||
}
|
||||
|
||||
template<unsigned KeySize, class T>
|
||||
inline void
|
||||
BloomFilter<KeySize, T>::remove(uint32_t hash)
|
||||
{
|
||||
// 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)))
|
||||
--slot1;
|
||||
// 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)))
|
||||
--slot1;
|
||||
|
||||
uint8_t& slot2 = secondSlot(hash);
|
||||
if (MOZ_LIKELY(!full(slot2)))
|
||||
--slot2;
|
||||
uint8_t& slot2 = secondSlot(hash);
|
||||
if (MOZ_LIKELY(!full(slot2)))
|
||||
--slot2;
|
||||
}
|
||||
|
||||
template<unsigned KeySize, class T>
|
||||
MOZ_ALWAYS_INLINE void
|
||||
BloomFilter<KeySize, T>::remove(const T* t)
|
||||
{
|
||||
uint32_t hash = t->hash();
|
||||
remove(hash);
|
||||
uint32_t hash = t->hash();
|
||||
remove(hash);
|
||||
}
|
||||
|
||||
template<unsigned KeySize, class T>
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
BloomFilter<KeySize, T>::mightContain(uint32_t hash) const
|
||||
{
|
||||
// Check that all the slots for this hash contain something
|
||||
return firstSlot(hash) && secondSlot(hash);
|
||||
// Check that all the slots for this hash contain something
|
||||
return firstSlot(hash) && secondSlot(hash);
|
||||
}
|
||||
|
||||
template<unsigned KeySize, class T>
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
BloomFilter<KeySize, T>::mightContain(const T* t) const
|
||||
{
|
||||
uint32_t hash = t->hash();
|
||||
return mightContain(hash);
|
||||
uint32_t hash = t->hash();
|
||||
return mightContain(hash);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set ts=8 sw=4 et tw=99 ft=cpp: */
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
@ -18,6 +17,7 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace detail {
|
||||
|
||||
/*
|
||||
* The following classes are designed to cause assertions to detect
|
||||
* inadvertent use of guard objects as temporaries. In other words,
|
||||
@ -25,11 +25,11 @@ namespace detail {
|
||||
* destructor (and is never otherwise referenced), the intended use
|
||||
* might be:
|
||||
*
|
||||
* AutoRestore savePainting(mIsPainting);
|
||||
* AutoRestore savePainting(mIsPainting);
|
||||
*
|
||||
* but is is easy to accidentally write:
|
||||
*
|
||||
* AutoRestore(mIsPainting);
|
||||
* AutoRestore(mIsPainting);
|
||||
*
|
||||
* which compiles just fine, but runs the destructor well before the
|
||||
* intended time.
|
||||
@ -72,14 +72,14 @@ class MOZ_EXPORT_API(GuardObjectNotifier)
|
||||
bool* statementDone;
|
||||
|
||||
public:
|
||||
GuardObjectNotifier() : statementDone(NULL) {}
|
||||
GuardObjectNotifier() : statementDone(NULL) { }
|
||||
|
||||
~GuardObjectNotifier() {
|
||||
*statementDone = true;
|
||||
*statementDone = true;
|
||||
}
|
||||
|
||||
void setStatementDone(bool* statementIsDone) {
|
||||
statementDone = statementIsDone;
|
||||
statementDone = statementIsDone;
|
||||
}
|
||||
};
|
||||
|
||||
@ -89,25 +89,24 @@ class MOZ_EXPORT_API(GuardObjectNotificationReceiver)
|
||||
bool statementDone;
|
||||
|
||||
public:
|
||||
GuardObjectNotificationReceiver() : statementDone(false) {}
|
||||
GuardObjectNotificationReceiver() : statementDone(false) { }
|
||||
|
||||
~GuardObjectNotificationReceiver() {
|
||||
/*
|
||||
* Assert that the guard object was not used as a temporary.
|
||||
* (Note that this assert might also fire if init is not called
|
||||
* because the guard object's implementation is not using the
|
||||
* above macros correctly.)
|
||||
*/
|
||||
MOZ_ASSERT(statementDone);
|
||||
/*
|
||||
* Assert that the guard object was not used as a temporary. (Note that
|
||||
* this assert might also fire if init is not called because the guard
|
||||
* object's implementation is not using the above macros correctly.)
|
||||
*/
|
||||
MOZ_ASSERT(statementDone);
|
||||
}
|
||||
|
||||
void init(const GuardObjectNotifier& constNotifier) {
|
||||
/*
|
||||
* constNotifier is passed as a const reference so that we can pass a
|
||||
* temporary, but we really intend it as non-const.
|
||||
*/
|
||||
GuardObjectNotifier& notifier = const_cast<GuardObjectNotifier&>(constNotifier);
|
||||
notifier.setStatementDone(&statementDone);
|
||||
/*
|
||||
* constNotifier is passed as a const reference so that we can pass a
|
||||
* temporary, but we really intend it as non-const.
|
||||
*/
|
||||
GuardObjectNotifier& notifier = const_cast<GuardObjectNotifier&>(constNotifier);
|
||||
notifier.setStatementDone(&statementDone);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,13 +1,12 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
/* Implementations of hash functions */
|
||||
/* Implementations of hash functions. */
|
||||
|
||||
#include "mozilla/HashFunctions.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace mozilla {
|
||||
@ -29,9 +28,8 @@ HashBytes(const void* bytes, size_t length)
|
||||
}
|
||||
|
||||
/* Get the remaining bytes. */
|
||||
for (; i < length; i++) {
|
||||
for (; i < length; i++)
|
||||
hash = AddToHash(hash, b[i]);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
@ -1,11 +1,9 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
/* Utilities for hashing */
|
||||
/* Utilities for hashing. */
|
||||
|
||||
/*
|
||||
* This file exports functions for hashing data down to a 32-bit value,
|
||||
@ -26,16 +24,18 @@
|
||||
*
|
||||
* You can chain these functions together to hash complex objects. For example:
|
||||
*
|
||||
* class ComplexObject {
|
||||
* char* str;
|
||||
* uint32_t uint1, uint2;
|
||||
* void (*callbackFn)();
|
||||
* class ComplexObject
|
||||
* {
|
||||
* char* str;
|
||||
* uint32_t uint1, uint2;
|
||||
* void (*callbackFn)();
|
||||
*
|
||||
* uint32_t Hash() {
|
||||
* uint32_t hash = HashString(str);
|
||||
* hash = AddToHash(hash, uint1, uint2);
|
||||
* return AddToHash(hash, callbackFn);
|
||||
* }
|
||||
* public:
|
||||
* uint32_t hash() {
|
||||
* uint32_t hash = HashString(str);
|
||||
* hash = AddToHash(hash, uint1, uint2);
|
||||
* return AddToHash(hash, callbackFn);
|
||||
* }
|
||||
* };
|
||||
*
|
||||
* If you want to hash an nsAString or nsACString, use the HashString functions
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
@ -7,8 +8,8 @@
|
||||
* boolean predicate should be branch-predicted.
|
||||
*/
|
||||
|
||||
#ifndef Likely_h_
|
||||
#define Likely_h_
|
||||
#ifndef mozilla_Likely_h_
|
||||
#define mozilla_Likely_h_
|
||||
|
||||
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 2))
|
||||
# define MOZ_LIKELY(x) (__builtin_expect((x), 1))
|
||||
@ -18,4 +19,4 @@
|
||||
# define MOZ_UNLIKELY(x) (x)
|
||||
#endif
|
||||
|
||||
#endif /* Likely_h_ */
|
||||
#endif /* mozilla_Likely_h_ */
|
||||
|
@ -1,7 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=4 sw=4 tw=80 et cin:
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
@ -20,36 +18,30 @@
|
||||
*
|
||||
* class Observer : public LinkedListElement<Observer>
|
||||
* {
|
||||
* void observe(char* topic) { ... }
|
||||
* public:
|
||||
* void observe(char* topic) { ... }
|
||||
* };
|
||||
*
|
||||
* class ObserverContainer
|
||||
* {
|
||||
* private:
|
||||
* LinkedList<Observer> list;
|
||||
* private:
|
||||
* LinkedList<Observer> list;
|
||||
*
|
||||
* public:
|
||||
*
|
||||
* void addObserver(Observer* observer)
|
||||
* {
|
||||
* // Will assert if |observer| is part of another list.
|
||||
* list.insertBack(observer);
|
||||
* }
|
||||
*
|
||||
* void removeObserver(Observer* observer)
|
||||
* {
|
||||
* // Will assert if |observer| is not part of some list.
|
||||
* observer.remove();
|
||||
* }
|
||||
*
|
||||
* void notifyObservers(char* topic)
|
||||
* {
|
||||
* for (Observer* o = list.getFirst();
|
||||
* o != NULL;
|
||||
* o = o->getNext()) {
|
||||
* o->Observe(topic);
|
||||
* public:
|
||||
* void addObserver(Observer* observer) {
|
||||
* // Will assert if |observer| is part of another list.
|
||||
* list.insertBack(observer);
|
||||
* }
|
||||
*
|
||||
* void removeObserver(Observer* observer) {
|
||||
* // Will assert if |observer| is not part of some list.
|
||||
* observer.remove();
|
||||
* }
|
||||
*
|
||||
* void notifyObservers(char* topic) {
|
||||
* for (Observer* o = list.getFirst(); o != NULL; o = o->getNext())
|
||||
* o->Observe(topic);
|
||||
* }
|
||||
* }
|
||||
* };
|
||||
*
|
||||
*/
|
||||
@ -104,51 +96,41 @@ class LinkedListElement
|
||||
* lists, and supporting this painlessly was a key design criterion.
|
||||
*/
|
||||
|
||||
private:
|
||||
private:
|
||||
LinkedListElement* next;
|
||||
LinkedListElement* prev;
|
||||
const bool isSentinel;
|
||||
|
||||
public:
|
||||
LinkedListElement()
|
||||
: next(this)
|
||||
, prev(this)
|
||||
, isSentinel(false)
|
||||
{
|
||||
}
|
||||
public:
|
||||
LinkedListElement() : next(this), prev(this), isSentinel(false) { }
|
||||
|
||||
/*
|
||||
* Get the next element in the list, or NULL if this is the last element in
|
||||
* the list.
|
||||
*/
|
||||
T* getNext()
|
||||
{
|
||||
return next->asT();
|
||||
T* getNext() {
|
||||
return next->asT();
|
||||
}
|
||||
const T* getNext() const
|
||||
{
|
||||
return next->asT();
|
||||
const T* getNext() const {
|
||||
return next->asT();
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the previous element in the list, or NULL if this is the first element
|
||||
* in the list.
|
||||
*/
|
||||
T* getPrevious()
|
||||
{
|
||||
return prev->asT();
|
||||
T* getPrevious() {
|
||||
return prev->asT();
|
||||
}
|
||||
const T* getPrevious() const
|
||||
{
|
||||
return prev->asT();
|
||||
const T* getPrevious() const {
|
||||
return prev->asT();
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert elem after this element in the list. |this| must be part of a
|
||||
* linked list when you call setNext(); otherwise, this method will assert.
|
||||
*/
|
||||
void setNext(T* elem)
|
||||
{
|
||||
void setNext(T* elem) {
|
||||
MOZ_ASSERT(isInList());
|
||||
setNextUnsafe(elem);
|
||||
}
|
||||
@ -158,50 +140,44 @@ public:
|
||||
* linked list when you call setPrevious(); otherwise, this method will
|
||||
* assert.
|
||||
*/
|
||||
void setPrevious(T* elem)
|
||||
{
|
||||
MOZ_ASSERT(isInList());
|
||||
setPreviousUnsafe(elem);
|
||||
void setPrevious(T* elem) {
|
||||
MOZ_ASSERT(isInList());
|
||||
setPreviousUnsafe(elem);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove this element from the list which contains it. If this element is
|
||||
* not currently part of a linked list, this method asserts.
|
||||
*/
|
||||
void remove()
|
||||
{
|
||||
MOZ_ASSERT(isInList());
|
||||
void remove() {
|
||||
MOZ_ASSERT(isInList());
|
||||
|
||||
prev->next = next;
|
||||
next->prev = prev;
|
||||
next = this;
|
||||
prev = this;
|
||||
prev->next = next;
|
||||
next->prev = prev;
|
||||
next = this;
|
||||
prev = this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if |this| part is of a linked list, and false otherwise.
|
||||
*/
|
||||
bool isInList() const
|
||||
{
|
||||
MOZ_ASSERT((next == this) == (prev == this));
|
||||
return next != this;
|
||||
bool isInList() const {
|
||||
MOZ_ASSERT((next == this) == (prev == this));
|
||||
return next != this;
|
||||
}
|
||||
|
||||
private:
|
||||
LinkedListElement& operator=(const LinkedList<T>& other) MOZ_DELETE;
|
||||
LinkedListElement(const LinkedList<T>& other) MOZ_DELETE;
|
||||
|
||||
private:
|
||||
friend class LinkedList<T>;
|
||||
|
||||
enum NodeKind {
|
||||
NODE_KIND_NORMAL,
|
||||
NODE_KIND_SENTINEL
|
||||
NODE_KIND_NORMAL,
|
||||
NODE_KIND_SENTINEL
|
||||
};
|
||||
|
||||
LinkedListElement(NodeKind nodeKind)
|
||||
: next(this)
|
||||
, prev(this)
|
||||
, isSentinel(nodeKind == NODE_KIND_SENTINEL)
|
||||
: next(this),
|
||||
prev(this),
|
||||
isSentinel(nodeKind == NODE_KIND_SENTINEL)
|
||||
{
|
||||
}
|
||||
|
||||
@ -209,140 +185,123 @@ private:
|
||||
* Return |this| cast to T* if we're a normal node, or return NULL if we're
|
||||
* a sentinel node.
|
||||
*/
|
||||
T* asT()
|
||||
{
|
||||
if (isSentinel)
|
||||
return NULL;
|
||||
T* asT() {
|
||||
if (isSentinel)
|
||||
return NULL;
|
||||
|
||||
return static_cast<T*>(this);
|
||||
return static_cast<T*>(this);
|
||||
}
|
||||
const T* asT() const
|
||||
{
|
||||
if (isSentinel)
|
||||
return NULL;
|
||||
const T* asT() const {
|
||||
if (isSentinel)
|
||||
return NULL;
|
||||
|
||||
return static_cast<const T*>(this);
|
||||
return static_cast<const T*>(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert elem after this element, but don't check that this element is in
|
||||
* the list. This is called by LinkedList::insertFront().
|
||||
*/
|
||||
void setNextUnsafe(T* elem)
|
||||
{
|
||||
LinkedListElement *listElem = static_cast<LinkedListElement*>(elem);
|
||||
MOZ_ASSERT(!listElem->isInList());
|
||||
void setNextUnsafe(T* elem) {
|
||||
LinkedListElement *listElem = static_cast<LinkedListElement*>(elem);
|
||||
MOZ_ASSERT(!listElem->isInList());
|
||||
|
||||
listElem->next = this->next;
|
||||
listElem->prev = this;
|
||||
this->next->prev = listElem;
|
||||
this->next = listElem;
|
||||
listElem->next = this->next;
|
||||
listElem->prev = this;
|
||||
this->next->prev = listElem;
|
||||
this->next = listElem;
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert elem before this element, but don't check that this element is in
|
||||
* the list. This is called by LinkedList::insertBack().
|
||||
*/
|
||||
void setPreviousUnsafe(T* elem)
|
||||
{
|
||||
LinkedListElement<T>* listElem = static_cast<LinkedListElement<T>*>(elem);
|
||||
MOZ_ASSERT(!listElem->isInList());
|
||||
void setPreviousUnsafe(T* elem) {
|
||||
LinkedListElement<T>* listElem = static_cast<LinkedListElement<T>*>(elem);
|
||||
MOZ_ASSERT(!listElem->isInList());
|
||||
|
||||
listElem->next = this;
|
||||
listElem->prev = this->prev;
|
||||
this->prev->next = listElem;
|
||||
this->prev = listElem;
|
||||
listElem->next = this;
|
||||
listElem->prev = this->prev;
|
||||
this->prev->next = listElem;
|
||||
this->prev = listElem;
|
||||
}
|
||||
|
||||
private:
|
||||
LinkedListElement& operator=(const LinkedList<T>& other) MOZ_DELETE;
|
||||
LinkedListElement(const LinkedList<T>& other) MOZ_DELETE;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class LinkedList
|
||||
{
|
||||
private:
|
||||
private:
|
||||
LinkedListElement<T> sentinel;
|
||||
|
||||
public:
|
||||
LinkedList& operator=(const LinkedList<T>& other) MOZ_DELETE;
|
||||
LinkedList(const LinkedList<T>& other) MOZ_DELETE;
|
||||
|
||||
LinkedList()
|
||||
: sentinel(LinkedListElement<T>::NODE_KIND_SENTINEL)
|
||||
{
|
||||
}
|
||||
public:
|
||||
LinkedList() : sentinel(LinkedListElement<T>::NODE_KIND_SENTINEL) { }
|
||||
|
||||
/*
|
||||
* Add elem to the front of the list.
|
||||
*/
|
||||
void insertFront(T* elem)
|
||||
{
|
||||
/* Bypass setNext()'s this->isInList() assertion. */
|
||||
sentinel.setNextUnsafe(elem);
|
||||
void insertFront(T* elem) {
|
||||
/* Bypass setNext()'s this->isInList() assertion. */
|
||||
sentinel.setNextUnsafe(elem);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add elem to the back of the list.
|
||||
*/
|
||||
void insertBack(T* elem)
|
||||
{
|
||||
sentinel.setPreviousUnsafe(elem);
|
||||
void insertBack(T* elem) {
|
||||
sentinel.setPreviousUnsafe(elem);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the first element of the list, or NULL if the list is empty.
|
||||
*/
|
||||
T* getFirst()
|
||||
{
|
||||
return sentinel.getNext();
|
||||
T* getFirst() {
|
||||
return sentinel.getNext();
|
||||
}
|
||||
const T* getFirst() const
|
||||
{
|
||||
return sentinel.getNext();
|
||||
const T* getFirst() const {
|
||||
return sentinel.getNext();
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the last element of the list, or NULL if the list is empty.
|
||||
*/
|
||||
T* getLast()
|
||||
{
|
||||
return sentinel.getPrevious();
|
||||
T* getLast() {
|
||||
return sentinel.getPrevious();
|
||||
}
|
||||
const T* getLast() const
|
||||
{
|
||||
return sentinel.getPrevious();
|
||||
const T* getLast() const {
|
||||
return sentinel.getPrevious();
|
||||
}
|
||||
|
||||
/*
|
||||
* Get and remove the first element of the list. If the list is empty,
|
||||
* return NULL.
|
||||
*/
|
||||
T* popFirst()
|
||||
{
|
||||
T* ret = sentinel.getNext();
|
||||
if (ret)
|
||||
static_cast<LinkedListElement<T>*>(ret)->remove();
|
||||
|
||||
return ret;
|
||||
T* popFirst() {
|
||||
T* ret = sentinel.getNext();
|
||||
if (ret)
|
||||
static_cast<LinkedListElement<T>*>(ret)->remove();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get and remove the last element of the list. If the list is empty,
|
||||
* return NULL.
|
||||
*/
|
||||
T* popLast()
|
||||
{
|
||||
T* ret = sentinel.getPrevious();
|
||||
if (ret)
|
||||
static_cast<LinkedListElement<T>*>(ret)->remove();
|
||||
|
||||
return ret;
|
||||
T* popLast() {
|
||||
T* ret = sentinel.getPrevious();
|
||||
if (ret)
|
||||
static_cast<LinkedListElement<T>*>(ret)->remove();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if the list is empty, or false otherwise.
|
||||
*/
|
||||
bool isEmpty() const
|
||||
{
|
||||
return !sentinel.isInList();
|
||||
bool isEmpty() const {
|
||||
return !sentinel.isInList();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -351,71 +310,73 @@ public:
|
||||
* This runs in time linear to the list's length, because we have to mark
|
||||
* each element as not in the list.
|
||||
*/
|
||||
void clear()
|
||||
{
|
||||
while (popFirst())
|
||||
continue;
|
||||
void clear() {
|
||||
while (popFirst())
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* In a debug build, make sure that the list is sane (no cycles, consistent
|
||||
* next/prev pointers, only one sentinel). Has no effect in release builds.
|
||||
*/
|
||||
void debugAssertIsSane() const
|
||||
{
|
||||
void debugAssertIsSane() const {
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Check for cycles in the forward singly-linked list using the
|
||||
* tortoise/hare algorithm.
|
||||
*/
|
||||
for (const LinkedListElement<T>* slow = sentinel.next,
|
||||
* fast1 = sentinel.next->next,
|
||||
* fast2 = sentinel.next->next->next;
|
||||
slow != sentinel && fast1 != sentinel && fast2 != sentinel;
|
||||
slow = slow->next,
|
||||
fast1 = fast2->next,
|
||||
fast2 = fast1->next) {
|
||||
const LinkedListElement<T>* slow;
|
||||
const LinkedListElement<T>* fast1;
|
||||
const LinkedListElement<T>* fast2;
|
||||
|
||||
MOZ_ASSERT(slow != fast1);
|
||||
MOZ_ASSERT(slow != fast2);
|
||||
}
|
||||
/*
|
||||
* Check for cycles in the forward singly-linked list using the
|
||||
* tortoise/hare algorithm.
|
||||
*/
|
||||
for (slow = sentinel.next,
|
||||
fast1 = sentinel.next->next,
|
||||
fast2 = sentinel.next->next->next;
|
||||
slow != sentinel && fast1 != sentinel && fast2 != sentinel;
|
||||
slow = slow->next, fast1 = fast2->next, fast2 = fast1->next)
|
||||
{
|
||||
MOZ_ASSERT(slow != fast1);
|
||||
MOZ_ASSERT(slow != fast2);
|
||||
}
|
||||
|
||||
/* Check for cycles in the backward singly-linked list. */
|
||||
for (const LinkedListElement<T>* slow = sentinel.prev,
|
||||
* fast1 = sentinel.prev->prev,
|
||||
* fast2 = sentinel.prev->prev->prev;
|
||||
slow != sentinel && fast1 != sentinel && fast2 != sentinel;
|
||||
slow = slow->prev,
|
||||
fast1 = fast2->prev,
|
||||
fast2 = fast1->prev) {
|
||||
/* Check for cycles in the backward singly-linked list. */
|
||||
for (slow = sentinel.prev,
|
||||
fast1 = sentinel.prev->prev,
|
||||
fast2 = sentinel.prev->prev->prev;
|
||||
slow != sentinel && fast1 != sentinel && fast2 != sentinel;
|
||||
slow = slow->prev, fast1 = fast2->prev, fast2 = fast1->prev)
|
||||
{
|
||||
MOZ_ASSERT(slow != fast1);
|
||||
MOZ_ASSERT(slow != fast2);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(slow != fast1);
|
||||
MOZ_ASSERT(slow != fast2);
|
||||
}
|
||||
/*
|
||||
* Check that |sentinel| is the only node in the list with
|
||||
* isSentinel == true.
|
||||
*/
|
||||
for (const LinkedListElement<T>* elem = sentinel.next;
|
||||
elem != sentinel;
|
||||
elem = elem->next)
|
||||
{
|
||||
MOZ_ASSERT(!elem->isSentinel);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that |sentinel| is the only node in the list with
|
||||
* isSentinel == true.
|
||||
*/
|
||||
for (const LinkedListElement<T>* elem = sentinel.next;
|
||||
elem != sentinel;
|
||||
elem = elem->next) {
|
||||
/* Check that the next/prev pointers match up. */
|
||||
const LinkedListElement<T>* prev = sentinel;
|
||||
const LinkedListElement<T>* cur = sentinel.next;
|
||||
do {
|
||||
MOZ_ASSERT(cur->prev == prev);
|
||||
MOZ_ASSERT(prev->next == cur);
|
||||
|
||||
MOZ_ASSERT(!elem->isSentinel);
|
||||
}
|
||||
|
||||
/* Check that the next/prev pointers match up. */
|
||||
const LinkedListElement<T>* prev = sentinel;
|
||||
const LinkedListElement<T>* cur = sentinel.next;
|
||||
do {
|
||||
MOZ_ASSERT(cur->prev == prev);
|
||||
MOZ_ASSERT(prev->next == cur);
|
||||
|
||||
prev = cur;
|
||||
cur = cur->next;
|
||||
} while (cur != sentinel);
|
||||
prev = cur;
|
||||
cur = cur->next;
|
||||
} while (cur != sentinel);
|
||||
#endif /* ifdef DEBUG */
|
||||
}
|
||||
|
||||
private:
|
||||
LinkedList& operator=(const LinkedList<T>& other) MOZ_DELETE;
|
||||
LinkedList(const LinkedList<T>& other) MOZ_DELETE;
|
||||
};
|
||||
|
||||
} /* namespace mozilla */
|
||||
|
120
mfbt/RangedPtr.h
120
mfbt/RangedPtr.h
@ -1,7 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
@ -38,7 +36,7 @@ namespace mozilla {
|
||||
* explicitly convert to T*. Keep in mind that the raw pointer of course won't
|
||||
* implement bounds checking in debug builds.
|
||||
*/
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
class RangedPtr
|
||||
{
|
||||
T* ptr;
|
||||
@ -49,16 +47,16 @@ class RangedPtr
|
||||
#endif
|
||||
|
||||
void checkSanity() {
|
||||
MOZ_ASSERT(rangeStart <= ptr);
|
||||
MOZ_ASSERT(ptr <= rangeEnd);
|
||||
MOZ_ASSERT(rangeStart <= ptr);
|
||||
MOZ_ASSERT(ptr <= rangeEnd);
|
||||
}
|
||||
|
||||
/* Creates a new pointer for |ptr|, restricted to this pointer's range. */
|
||||
RangedPtr<T> create(T *ptr) const {
|
||||
#ifdef DEBUG
|
||||
return RangedPtr<T>(ptr, rangeStart, rangeEnd);
|
||||
return RangedPtr<T>(ptr, rangeStart, rangeEnd);
|
||||
#else
|
||||
return RangedPtr<T>(ptr, NULL, size_t(0));
|
||||
return RangedPtr<T>(ptr, NULL, size_t(0));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -69,8 +67,8 @@ class RangedPtr
|
||||
, rangeStart(start), rangeEnd(end)
|
||||
#endif
|
||||
{
|
||||
MOZ_ASSERT(rangeStart <= rangeEnd);
|
||||
checkSanity();
|
||||
MOZ_ASSERT(rangeStart <= rangeEnd);
|
||||
checkSanity();
|
||||
}
|
||||
RangedPtr(T* p, T* start, size_t length)
|
||||
: ptr(p)
|
||||
@ -78,9 +76,9 @@ class RangedPtr
|
||||
, rangeStart(start), rangeEnd(start + length)
|
||||
#endif
|
||||
{
|
||||
MOZ_ASSERT(length <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(uintptr_t(rangeStart) + length * sizeof(T) >= uintptr_t(rangeStart));
|
||||
checkSanity();
|
||||
MOZ_ASSERT(length <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(uintptr_t(rangeStart) + length * sizeof(T) >= uintptr_t(rangeStart));
|
||||
checkSanity();
|
||||
}
|
||||
|
||||
/* Equivalent to RangedPtr(p, p, length). */
|
||||
@ -90,9 +88,9 @@ class RangedPtr
|
||||
, rangeStart(p), rangeEnd(p + length)
|
||||
#endif
|
||||
{
|
||||
MOZ_ASSERT(length <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(uintptr_t(rangeStart) + length * sizeof(T) >= uintptr_t(rangeStart));
|
||||
checkSanity();
|
||||
MOZ_ASSERT(length <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(uintptr_t(rangeStart) + length * sizeof(T) >= uintptr_t(rangeStart));
|
||||
checkSanity();
|
||||
}
|
||||
|
||||
/* Equivalent to RangedPtr(arr, arr, N). */
|
||||
@ -107,7 +105,7 @@ class RangedPtr
|
||||
}
|
||||
|
||||
T* get() const {
|
||||
return ptr;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -121,23 +119,23 @@ class RangedPtr
|
||||
* p1 = RangedPtr<char>(arr2, 3); // asserts
|
||||
*/
|
||||
RangedPtr<T>& operator=(const RangedPtr<T>& other) {
|
||||
MOZ_ASSERT(rangeStart == other.rangeStart);
|
||||
MOZ_ASSERT(rangeEnd == other.rangeEnd);
|
||||
ptr = other.ptr;
|
||||
checkSanity();
|
||||
return *this;
|
||||
MOZ_ASSERT(rangeStart == other.rangeStart);
|
||||
MOZ_ASSERT(rangeEnd == other.rangeEnd);
|
||||
ptr = other.ptr;
|
||||
checkSanity();
|
||||
return *this;
|
||||
}
|
||||
|
||||
RangedPtr<T> operator+(size_t inc) {
|
||||
MOZ_ASSERT(inc <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(ptr + inc > ptr);
|
||||
return create(ptr + inc);
|
||||
MOZ_ASSERT(inc <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(ptr + inc > ptr);
|
||||
return create(ptr + inc);
|
||||
}
|
||||
|
||||
RangedPtr<T> operator-(size_t dec) {
|
||||
MOZ_ASSERT(dec <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(ptr - dec < ptr);
|
||||
return create(ptr - dec);
|
||||
MOZ_ASSERT(dec <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(ptr - dec < ptr);
|
||||
return create(ptr - dec);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -146,97 +144,97 @@ class RangedPtr
|
||||
*/
|
||||
template <typename U>
|
||||
RangedPtr<T>& operator=(U* p) {
|
||||
*this = create(p);
|
||||
return *this;
|
||||
*this = create(p);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
RangedPtr<T>& operator=(const RangedPtr<U>& p) {
|
||||
MOZ_ASSERT(rangeStart <= p.ptr);
|
||||
MOZ_ASSERT(p.ptr <= rangeEnd);
|
||||
ptr = p.ptr;
|
||||
checkSanity();
|
||||
return *this;
|
||||
MOZ_ASSERT(rangeStart <= p.ptr);
|
||||
MOZ_ASSERT(p.ptr <= rangeEnd);
|
||||
ptr = p.ptr;
|
||||
checkSanity();
|
||||
return *this;
|
||||
}
|
||||
|
||||
RangedPtr<T>& operator++() {
|
||||
return (*this += 1);
|
||||
return (*this += 1);
|
||||
}
|
||||
|
||||
RangedPtr<T> operator++(int) {
|
||||
RangedPtr<T> rcp = *this;
|
||||
++*this;
|
||||
return rcp;
|
||||
RangedPtr<T> rcp = *this;
|
||||
++*this;
|
||||
return rcp;
|
||||
}
|
||||
|
||||
RangedPtr<T>& operator--() {
|
||||
return (*this -= 1);
|
||||
return (*this -= 1);
|
||||
}
|
||||
|
||||
RangedPtr<T> operator--(int) {
|
||||
RangedPtr<T> rcp = *this;
|
||||
--*this;
|
||||
return rcp;
|
||||
RangedPtr<T> rcp = *this;
|
||||
--*this;
|
||||
return rcp;
|
||||
}
|
||||
|
||||
RangedPtr<T>& operator+=(size_t inc) {
|
||||
this->operator=<T>(*this + inc);
|
||||
return *this;
|
||||
*this = *this + inc;
|
||||
return *this;
|
||||
}
|
||||
|
||||
RangedPtr<T>& operator-=(size_t dec) {
|
||||
this->operator=<T>(*this - dec);
|
||||
return *this;
|
||||
*this = *this - dec;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T& operator[](int index) const {
|
||||
MOZ_ASSERT(size_t(index > 0 ? index : -index) <= size_t(-1) / sizeof(T));
|
||||
return *create(ptr + index);
|
||||
MOZ_ASSERT(size_t(index > 0 ? index : -index) <= size_t(-1) / sizeof(T));
|
||||
return *create(ptr + index);
|
||||
}
|
||||
|
||||
T& operator*() const {
|
||||
return *ptr;
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
bool operator==(const RangedPtr<U>& other) const {
|
||||
return ptr == other.ptr;
|
||||
return ptr == other.ptr;
|
||||
}
|
||||
template <typename U>
|
||||
bool operator!=(const RangedPtr<U>& other) const {
|
||||
return !(*this == other);
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
bool operator==(const U* u) const {
|
||||
return ptr == u;
|
||||
return ptr == u;
|
||||
}
|
||||
template<typename U>
|
||||
bool operator!=(const U* u) const {
|
||||
return !(*this == u);
|
||||
return !(*this == u);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
bool operator<(const RangedPtr<U>& other) const {
|
||||
return ptr < other.ptr;
|
||||
return ptr < other.ptr;
|
||||
}
|
||||
template <typename U>
|
||||
bool operator<=(const RangedPtr<U>& other) const {
|
||||
return ptr <= other.ptr;
|
||||
return ptr <= other.ptr;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
bool operator>(const RangedPtr<U>& other) const {
|
||||
return ptr > other.ptr;
|
||||
return ptr > other.ptr;
|
||||
}
|
||||
template <typename U>
|
||||
bool operator>=(const RangedPtr<U>& other) const {
|
||||
return ptr >= other.ptr;
|
||||
return ptr >= other.ptr;
|
||||
}
|
||||
|
||||
size_t operator-(const RangedPtr<T>& other) const {
|
||||
MOZ_ASSERT(ptr >= other.ptr);
|
||||
return PointerRangeSize(other.ptr, ptr);
|
||||
MOZ_ASSERT(ptr >= other.ptr);
|
||||
return PointerRangeSize(other.ptr, ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
|
256
mfbt/RefPtr.h
256
mfbt/RefPtr.h
@ -1,7 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
@ -47,24 +45,24 @@ class RefCounted
|
||||
{
|
||||
friend class RefPtr<T>;
|
||||
|
||||
public:
|
||||
public:
|
||||
RefCounted() : refCnt(0) { }
|
||||
~RefCounted() { MOZ_ASSERT(refCnt == -0xdead); }
|
||||
|
||||
// Compatibility with nsRefPtr.
|
||||
void AddRef() {
|
||||
MOZ_ASSERT(refCnt >= 0);
|
||||
++refCnt;
|
||||
MOZ_ASSERT(refCnt >= 0);
|
||||
++refCnt;
|
||||
}
|
||||
|
||||
void Release() {
|
||||
MOZ_ASSERT(refCnt > 0);
|
||||
if (0 == --refCnt) {
|
||||
MOZ_ASSERT(refCnt > 0);
|
||||
if (0 == --refCnt) {
|
||||
#ifdef DEBUG
|
||||
refCnt = -0xdead;
|
||||
refCnt = -0xdead;
|
||||
#endif
|
||||
delete static_cast<T*>(this);
|
||||
}
|
||||
delete static_cast<T*>(this);
|
||||
}
|
||||
}
|
||||
|
||||
// Compatibility with wtf::RefPtr.
|
||||
@ -72,11 +70,11 @@ public:
|
||||
void deref() { Release(); }
|
||||
int refCount() const { return refCnt; }
|
||||
bool hasOneRef() const {
|
||||
MOZ_ASSERT(refCnt > 0);
|
||||
return refCnt == 1;
|
||||
MOZ_ASSERT(refCnt > 0);
|
||||
return refCnt == 1;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
int refCnt;
|
||||
};
|
||||
|
||||
@ -97,9 +95,9 @@ class RefPtr
|
||||
friend class TemporaryRef<T>;
|
||||
friend class OutParamRef<T>;
|
||||
|
||||
struct dontRef {};
|
||||
struct DontRef {};
|
||||
|
||||
public:
|
||||
public:
|
||||
RefPtr() : ptr(0) { }
|
||||
RefPtr(const RefPtr& o) : ptr(ref(o.ptr)) {}
|
||||
RefPtr(const TemporaryRef<T>& o) : ptr(o.drop()) {}
|
||||
@ -111,28 +109,28 @@ public:
|
||||
~RefPtr() { unref(ptr); }
|
||||
|
||||
RefPtr& operator=(const RefPtr& o) {
|
||||
assign(ref(o.ptr));
|
||||
return *this;
|
||||
assign(ref(o.ptr));
|
||||
return *this;
|
||||
}
|
||||
RefPtr& operator=(const TemporaryRef<T>& o) {
|
||||
assign(o.drop());
|
||||
return *this;
|
||||
assign(o.drop());
|
||||
return *this;
|
||||
}
|
||||
RefPtr& operator=(T* t) {
|
||||
assign(ref(t));
|
||||
return *this;
|
||||
assign(ref(t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
RefPtr& operator=(const RefPtr<U>& o) {
|
||||
assign(ref(o.get()));
|
||||
return *this;
|
||||
assign(ref(o.get()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
TemporaryRef<T> forget() {
|
||||
T* tmp = ptr;
|
||||
ptr = 0;
|
||||
return TemporaryRef<T>(tmp, dontRef());
|
||||
T* tmp = ptr;
|
||||
ptr = 0;
|
||||
return TemporaryRef<T>(tmp, DontRef());
|
||||
}
|
||||
|
||||
T* get() const { return ptr; }
|
||||
@ -142,25 +140,23 @@ public:
|
||||
template<typename U>
|
||||
operator TemporaryRef<U>() { return TemporaryRef<U>(ptr); }
|
||||
|
||||
private:
|
||||
private:
|
||||
void assign(T* t) {
|
||||
unref(ptr);
|
||||
ptr = t;
|
||||
unref(ptr);
|
||||
ptr = t;
|
||||
}
|
||||
|
||||
T* ptr;
|
||||
|
||||
static MOZ_ALWAYS_INLINE T* ref(T* t) {
|
||||
if (t) {
|
||||
t->AddRef();
|
||||
}
|
||||
return t;
|
||||
if (t)
|
||||
t->AddRef();
|
||||
return t;
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE void unref(T* t) {
|
||||
if (t) {
|
||||
t->Release();
|
||||
}
|
||||
if (t)
|
||||
t->Release();
|
||||
}
|
||||
};
|
||||
|
||||
@ -176,9 +172,9 @@ class TemporaryRef
|
||||
// To allow it to construct TemporaryRef from a bare T*
|
||||
friend class RefPtr<T>;
|
||||
|
||||
typedef typename RefPtr<T>::dontRef dontRef;
|
||||
typedef typename RefPtr<T>::DontRef DontRef;
|
||||
|
||||
public:
|
||||
public:
|
||||
TemporaryRef(T* t) : ptr(RefPtr<T>::ref(t)) {}
|
||||
TemporaryRef(const TemporaryRef& o) : ptr(o.drop()) {}
|
||||
|
||||
@ -188,18 +184,18 @@ public:
|
||||
~TemporaryRef() { RefPtr<T>::unref(ptr); }
|
||||
|
||||
T* drop() const {
|
||||
T* tmp = ptr;
|
||||
ptr = 0;
|
||||
return tmp;
|
||||
T* tmp = ptr;
|
||||
ptr = 0;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
private:
|
||||
TemporaryRef(T* t, const dontRef&) : ptr(t) {}
|
||||
private:
|
||||
TemporaryRef(T* t, const DontRef&) : ptr(t) {}
|
||||
|
||||
mutable T* ptr;
|
||||
|
||||
TemporaryRef();
|
||||
TemporaryRef& operator=(const TemporaryRef&);
|
||||
TemporaryRef() MOZ_DELETE;
|
||||
void operator=(const TemporaryRef&) MOZ_DELETE;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -221,15 +217,15 @@ class OutParamRef
|
||||
{
|
||||
friend OutParamRef byRef<T>(RefPtr<T>&);
|
||||
|
||||
public:
|
||||
public:
|
||||
~OutParamRef() {
|
||||
RefPtr<T>::unref(refPtr.ptr);
|
||||
refPtr.ptr = tmp;
|
||||
RefPtr<T>::unref(refPtr.ptr);
|
||||
refPtr.ptr = tmp;
|
||||
}
|
||||
|
||||
operator T**() { return &tmp; }
|
||||
|
||||
private:
|
||||
private:
|
||||
OutParamRef(RefPtr<T>& p) : refPtr(p), tmp(p.get()) {}
|
||||
|
||||
RefPtr<T>& refPtr;
|
||||
@ -246,7 +242,7 @@ template<typename T>
|
||||
OutParamRef<T>
|
||||
byRef(RefPtr<T>& ptr)
|
||||
{
|
||||
return OutParamRef<T>(ptr);
|
||||
return OutParamRef<T>(ptr);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
@ -264,15 +260,15 @@ using namespace mozilla;
|
||||
|
||||
struct Foo : public RefCounted<Foo>
|
||||
{
|
||||
Foo() : dead(false) { }
|
||||
~Foo() {
|
||||
MOZ_ASSERT(!dead);
|
||||
dead = true;
|
||||
numDestroyed++;
|
||||
}
|
||||
Foo() : dead(false) { }
|
||||
~Foo() {
|
||||
MOZ_ASSERT(!dead);
|
||||
dead = true;
|
||||
numDestroyed++;
|
||||
}
|
||||
|
||||
bool dead;
|
||||
static int numDestroyed;
|
||||
bool dead;
|
||||
static int numDestroyed;
|
||||
};
|
||||
int Foo::numDestroyed;
|
||||
|
||||
@ -281,34 +277,34 @@ struct Bar : public Foo { };
|
||||
TemporaryRef<Foo>
|
||||
NewFoo()
|
||||
{
|
||||
return RefPtr<Foo>(new Foo());
|
||||
return RefPtr<Foo>(new Foo());
|
||||
}
|
||||
|
||||
TemporaryRef<Foo>
|
||||
NewBar()
|
||||
{
|
||||
return new Bar();
|
||||
return new Bar();
|
||||
}
|
||||
|
||||
void
|
||||
GetNewFoo(Foo** f)
|
||||
{
|
||||
*f = new Bar();
|
||||
// Kids, don't try this at home
|
||||
(*f)->AddRef();
|
||||
*f = new Bar();
|
||||
// Kids, don't try this at home
|
||||
(*f)->AddRef();
|
||||
}
|
||||
|
||||
void
|
||||
GetPassedFoo(Foo** f)
|
||||
{
|
||||
// Kids, don't try this at home
|
||||
(*f)->AddRef();
|
||||
// Kids, don't try this at home
|
||||
(*f)->AddRef();
|
||||
}
|
||||
|
||||
void
|
||||
GetNewFoo(RefPtr<Foo>* f)
|
||||
{
|
||||
*f = new Bar();
|
||||
*f = new Bar();
|
||||
}
|
||||
|
||||
void
|
||||
@ -318,93 +314,93 @@ GetPassedFoo(RefPtr<Foo>* f)
|
||||
TemporaryRef<Foo>
|
||||
GetNullFoo()
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
// This should blow up
|
||||
// This should blow up
|
||||
// Foo* f = new Foo(); delete f;
|
||||
|
||||
MOZ_ASSERT(0 == Foo::numDestroyed);
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
MOZ_ASSERT(f->refCount() == 1);
|
||||
}
|
||||
MOZ_ASSERT(0 == Foo::numDestroyed);
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
MOZ_ASSERT(f->refCount() == 1);
|
||||
}
|
||||
MOZ_ASSERT(1 == Foo::numDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> f1 = NewFoo();
|
||||
RefPtr<Foo> f2(NewFoo());
|
||||
MOZ_ASSERT(1 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(3 == Foo::numDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> f1 = NewFoo();
|
||||
RefPtr<Foo> f2(NewFoo());
|
||||
MOZ_ASSERT(1 == Foo::numDestroyed);
|
||||
}
|
||||
{
|
||||
RefPtr<Foo> b = NewBar();
|
||||
MOZ_ASSERT(3 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(4 == Foo::numDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> f1;
|
||||
{
|
||||
RefPtr<Foo> b = NewBar();
|
||||
MOZ_ASSERT(3 == Foo::numDestroyed);
|
||||
f1 = new Foo();
|
||||
RefPtr<Foo> f2(f1);
|
||||
RefPtr<Foo> f3 = f2;
|
||||
MOZ_ASSERT(4 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(4 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(5 == Foo::numDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> f1;
|
||||
{
|
||||
f1 = new Foo();
|
||||
RefPtr<Foo> f2(f1);
|
||||
RefPtr<Foo> f3 = f2;
|
||||
MOZ_ASSERT(4 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(4 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(5 == Foo::numDestroyed);
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
f.forget();
|
||||
MOZ_ASSERT(6 == Foo::numDestroyed);
|
||||
}
|
||||
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
f.forget();
|
||||
MOZ_ASSERT(6 == Foo::numDestroyed);
|
||||
}
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
GetNewFoo(byRef(f));
|
||||
MOZ_ASSERT(7 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(8 == Foo::numDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
GetNewFoo(byRef(f));
|
||||
MOZ_ASSERT(7 == Foo::numDestroyed);
|
||||
}
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
GetPassedFoo(byRef(f));
|
||||
MOZ_ASSERT(8 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(9 == Foo::numDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
GetPassedFoo(byRef(f));
|
||||
MOZ_ASSERT(8 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(9 == Foo::numDestroyed);
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
GetNewFoo(&f);
|
||||
MOZ_ASSERT(10 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(11 == Foo::numDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
GetNewFoo(&f);
|
||||
MOZ_ASSERT(10 == Foo::numDestroyed);
|
||||
}
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
GetPassedFoo(&f);
|
||||
MOZ_ASSERT(11 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(12 == Foo::numDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
GetPassedFoo(&f);
|
||||
MOZ_ASSERT(11 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(12 == Foo::numDestroyed);
|
||||
{
|
||||
RefPtr<Foo> f1 = new Bar();
|
||||
}
|
||||
MOZ_ASSERT(13 == Foo::numDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> f1 = new Bar();
|
||||
}
|
||||
{
|
||||
RefPtr<Foo> f = GetNullFoo();
|
||||
MOZ_ASSERT(13 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(13 == Foo::numDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> f = GetNullFoo();
|
||||
MOZ_ASSERT(13 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(13 == Foo::numDestroyed);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
196
mfbt/Scoped.h
196
mfbt/Scoped.h
@ -66,87 +66,87 @@
|
||||
* const static void release(type);
|
||||
* }
|
||||
*/
|
||||
template <typename Traits>
|
||||
template<typename Traits>
|
||||
class Scoped
|
||||
{
|
||||
public:
|
||||
typedef typename Traits::type Resource;
|
||||
public:
|
||||
typedef typename Traits::type Resource;
|
||||
|
||||
explicit Scoped(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
|
||||
: value(Traits::empty())
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
explicit Scoped(const Resource& value
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: value(value)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
~Scoped() {
|
||||
Traits::release(value);
|
||||
}
|
||||
explicit Scoped(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
|
||||
: value(Traits::empty())
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
explicit Scoped(const Resource& value
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: value(value)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
~Scoped() {
|
||||
Traits::release(value);
|
||||
}
|
||||
|
||||
// Constant getter
|
||||
operator const Resource&() const { return value; }
|
||||
const Resource& operator->() const { return value; }
|
||||
const Resource& get() const { return value; }
|
||||
// Non-constant getter.
|
||||
Resource& rwget() { return value; }
|
||||
// Constant getter
|
||||
operator const Resource&() const { return value; }
|
||||
const Resource& operator->() const { return value; }
|
||||
const Resource& get() const { return value; }
|
||||
// Non-constant getter.
|
||||
Resource& rwget() { return value; }
|
||||
|
||||
/*
|
||||
* Forget the resource.
|
||||
*
|
||||
* Once |forget| has been called, the |Scoped| is neutralized, i.e. it will
|
||||
* have no effect at destruction (unless it is reset to another resource by
|
||||
* |operator=|).
|
||||
*
|
||||
* @return The original resource.
|
||||
*/
|
||||
Resource forget() {
|
||||
Resource tmp = value;
|
||||
value = Traits::empty();
|
||||
return tmp;
|
||||
}
|
||||
/*
|
||||
* Forget the resource.
|
||||
*
|
||||
* Once |forget| has been called, the |Scoped| is neutralized, i.e. it will
|
||||
* have no effect at destruction (unless it is reset to another resource by
|
||||
* |operator=|).
|
||||
*
|
||||
* @return The original resource.
|
||||
*/
|
||||
Resource forget() {
|
||||
Resource tmp = value;
|
||||
value = Traits::empty();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform immediate clean-up of this |Scoped|.
|
||||
*
|
||||
* If this |Scoped| is currently empty, this method has no effect.
|
||||
*/
|
||||
void dispose() {
|
||||
Traits::release(value);
|
||||
value = Traits::empty();
|
||||
}
|
||||
/*
|
||||
* Perform immediate clean-up of this |Scoped|.
|
||||
*
|
||||
* If this |Scoped| is currently empty, this method has no effect.
|
||||
*/
|
||||
void dispose() {
|
||||
Traits::release(value);
|
||||
value = Traits::empty();
|
||||
}
|
||||
|
||||
bool operator==(const Resource& other) const {
|
||||
return value == other;
|
||||
}
|
||||
bool operator==(const Resource& other) const {
|
||||
return value == other;
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace the resource with another resource.
|
||||
*
|
||||
* Calling |operator=| has the side-effect of triggering clean-up. If you do
|
||||
* not want to trigger clean-up, you should first invoke |forget|.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
Scoped<Traits>& operator=(const Resource& other) {
|
||||
return reset(other);
|
||||
}
|
||||
Scoped<Traits>& reset(const Resource& other) {
|
||||
Traits::release(value);
|
||||
value = other;
|
||||
return *this;
|
||||
}
|
||||
/*
|
||||
* Replace the resource with another resource.
|
||||
*
|
||||
* Calling |operator=| has the side-effect of triggering clean-up. If you do
|
||||
* not want to trigger clean-up, you should first invoke |forget|.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
Scoped<Traits>& operator=(const Resource& other) {
|
||||
return reset(other);
|
||||
}
|
||||
Scoped<Traits>& reset(const Resource& other) {
|
||||
Traits::release(value);
|
||||
value = other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
explicit Scoped(const Scoped<Traits>& value) MOZ_DELETE;
|
||||
Scoped<Traits>& operator=(const Scoped<Traits>& value) MOZ_DELETE;
|
||||
private:
|
||||
explicit Scoped(const Scoped<Traits>& value) MOZ_DELETE;
|
||||
Scoped<Traits>& operator=(const Scoped<Traits>& value) MOZ_DELETE;
|
||||
|
||||
private:
|
||||
Resource value;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
private:
|
||||
Resource value;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
/*
|
||||
@ -158,25 +158,25 @@ private:
|
||||
* for more details.
|
||||
*/
|
||||
#define SCOPED_TEMPLATE(name, Traits) \
|
||||
template <typename Type> \
|
||||
template<typename Type> \
|
||||
struct name : public Scoped<Traits<Type> > \
|
||||
{ \
|
||||
typedef Scoped<Traits<Type> > Super; \
|
||||
typedef typename Super::Resource Resource; \
|
||||
name& operator=(Resource ptr) { \
|
||||
Super::operator=(ptr); \
|
||||
return *this; \
|
||||
} \
|
||||
explicit name(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) \
|
||||
: Super(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT) \
|
||||
{} \
|
||||
explicit name(Resource ptr \
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \
|
||||
: Super(ptr MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \
|
||||
{} \
|
||||
private: \
|
||||
explicit name(name& source) MOZ_DELETE; \
|
||||
name& operator=(name& source) MOZ_DELETE; \
|
||||
typedef Scoped<Traits<Type> > Super; \
|
||||
typedef typename Super::Resource Resource; \
|
||||
name& operator=(Resource ptr) { \
|
||||
Super::operator=(ptr); \
|
||||
return *this; \
|
||||
} \
|
||||
explicit name(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) \
|
||||
: Super(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT) \
|
||||
{} \
|
||||
explicit name(Resource ptr \
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) \
|
||||
: Super(ptr MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT) \
|
||||
{} \
|
||||
private: \
|
||||
explicit name(name& source) MOZ_DELETE; \
|
||||
name& operator=(name& source) MOZ_DELETE; \
|
||||
};
|
||||
|
||||
/*
|
||||
@ -186,12 +186,12 @@ private: \
|
||||
* ScopedFreePtr<S> foo = malloc(sizeof(S));
|
||||
* ScopedFreePtr<char> bar = strdup(str);
|
||||
*/
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
struct ScopedFreePtrTraits
|
||||
{
|
||||
typedef T* type;
|
||||
static T* empty() { return NULL; }
|
||||
static void release(T* ptr) { free(ptr); }
|
||||
typedef T* type;
|
||||
static T* empty() { return NULL; }
|
||||
static void release(T* ptr) { free(ptr); }
|
||||
};
|
||||
SCOPED_TEMPLATE(ScopedFreePtr, ScopedFreePtrTraits)
|
||||
|
||||
@ -201,9 +201,10 @@ SCOPED_TEMPLATE(ScopedFreePtr, ScopedFreePtrTraits)
|
||||
* struct S { ... };
|
||||
* ScopedDeletePtr<S> foo = new S();
|
||||
*/
|
||||
template <typename T>
|
||||
struct ScopedDeletePtrTraits : public ScopedFreePtrTraits<T> {
|
||||
static void release(T* ptr) { delete ptr; }
|
||||
template<typename T>
|
||||
struct ScopedDeletePtrTraits : public ScopedFreePtrTraits<T>
|
||||
{
|
||||
static void release(T* ptr) { delete ptr; }
|
||||
};
|
||||
SCOPED_TEMPLATE(ScopedDeletePtr, ScopedDeletePtrTraits)
|
||||
|
||||
@ -213,12 +214,11 @@ SCOPED_TEMPLATE(ScopedDeletePtr, ScopedDeletePtrTraits)
|
||||
* struct S { ... };
|
||||
* ScopedDeleteArray<S> foo = new S[42];
|
||||
*/
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
struct ScopedDeleteArrayTraits : public ScopedFreePtrTraits<T>
|
||||
{
|
||||
static void release(T* ptr) { delete [] ptr; }
|
||||
static void release(T* ptr) { delete [] ptr; }
|
||||
};
|
||||
SCOPED_TEMPLATE(ScopedDeleteArray, ScopedDeleteArrayTraits)
|
||||
|
||||
|
||||
#endif // mozilla_Scoped_h_
|
||||
|
@ -1,7 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
// Cross-platform lightweight thread local data wrappers
|
||||
/* Cross-platform lightweight thread local data wrappers. */
|
||||
|
||||
#ifndef mozilla_TLS_h_
|
||||
#define mozilla_TLS_h_
|
||||
@ -63,7 +64,7 @@ typedef sig_atomic_t sig_safe_t;
|
||||
* // Get the TLS value
|
||||
* int value = tlsKey.get();
|
||||
*/
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
class ThreadLocal
|
||||
{
|
||||
#if defined(XP_WIN)
|
||||
@ -73,7 +74,7 @@ class ThreadLocal
|
||||
#endif
|
||||
|
||||
union Helper {
|
||||
void *ptr;
|
||||
void* ptr;
|
||||
T value;
|
||||
};
|
||||
|
||||
@ -93,10 +94,13 @@ class ThreadLocal
|
||||
bool inited;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
inline bool
|
||||
ThreadLocal<T>::init() {
|
||||
MOZ_STATIC_ASSERT(sizeof(T) <= sizeof(void *), "mozilla::ThreadLocal can't be used for types larger than a pointer");
|
||||
ThreadLocal<T>::init()
|
||||
{
|
||||
MOZ_STATIC_ASSERT(sizeof(T) <= sizeof(void *),
|
||||
"mozilla::ThreadLocal can't be used for types larger than "
|
||||
"a pointer");
|
||||
MOZ_ASSERT(!initialized());
|
||||
#ifdef XP_WIN
|
||||
key = TlsAlloc();
|
||||
@ -107,9 +111,10 @@ ThreadLocal<T>::init() {
|
||||
return inited;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
inline T
|
||||
ThreadLocal<T>::get() const {
|
||||
ThreadLocal<T>::get() const
|
||||
{
|
||||
MOZ_ASSERT(initialized());
|
||||
Helper h;
|
||||
#ifdef XP_WIN
|
||||
@ -120,9 +125,10 @@ ThreadLocal<T>::get() const {
|
||||
return h.value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
inline bool
|
||||
ThreadLocal<T>::set(const T value) {
|
||||
ThreadLocal<T>::set(const T value)
|
||||
{
|
||||
MOZ_ASSERT(initialized());
|
||||
Helper h;
|
||||
h.value = value;
|
||||
|
@ -1,7 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
|
196
mfbt/Util.h
196
mfbt/Util.h
@ -1,7 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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,40 +20,37 @@
|
||||
namespace mozilla {
|
||||
|
||||
/**
|
||||
* DebugOnly contains a value of type T, but only in debug builds. In
|
||||
* release builds, it does not contain a value. This helper is
|
||||
* intended to be used along with ASSERT()-style macros, allowing one
|
||||
* to write
|
||||
* DebugOnly contains a value of type T, but only in debug builds. In release
|
||||
* builds, it does not contain a value. This helper is intended to be used with
|
||||
* MOZ_ASSERT()-style macros, allowing one to write:
|
||||
*
|
||||
* DebugOnly<bool> check = Func();
|
||||
* ASSERT(check);
|
||||
* DebugOnly<bool> check = func();
|
||||
* MOZ_ASSERT(check);
|
||||
*
|
||||
* more concisely than declaring |check| conditional on #ifdef DEBUG,
|
||||
* but also without allocating storage space for |check| in release
|
||||
* builds.
|
||||
* more concisely than declaring |check| conditional on #ifdef DEBUG, but also
|
||||
* without allocating storage space for |check| in release builds.
|
||||
*
|
||||
* DebugOnly instances can only be coerced to T in debug builds; in
|
||||
* release builds, they don't have a value so type coercion is not
|
||||
* well defined.
|
||||
* DebugOnly instances can only be coerced to T in debug builds. In release
|
||||
* builds they don't have a value, so type coercion is not well defined.
|
||||
*/
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
struct DebugOnly
|
||||
{
|
||||
#ifdef DEBUG
|
||||
T value;
|
||||
|
||||
DebugOnly() {}
|
||||
DebugOnly(const T& other) : value(other) {}
|
||||
DebugOnly(const DebugOnly& other) : value(other.value) {}
|
||||
DebugOnly() { }
|
||||
DebugOnly(const T& other) : value(other) { }
|
||||
DebugOnly(const DebugOnly& other) : value(other.value) { }
|
||||
DebugOnly& operator=(const T& rhs) {
|
||||
value = rhs;
|
||||
return *this;
|
||||
value = rhs;
|
||||
return *this;
|
||||
}
|
||||
void operator++(int) {
|
||||
value++;
|
||||
value++;
|
||||
}
|
||||
void operator--(int) {
|
||||
value--;
|
||||
value--;
|
||||
}
|
||||
|
||||
T *operator&() { return &value; }
|
||||
@ -66,12 +61,12 @@ struct DebugOnly
|
||||
T& operator->() { return value; }
|
||||
|
||||
#else
|
||||
DebugOnly() {}
|
||||
DebugOnly(const T&) {}
|
||||
DebugOnly(const DebugOnly&) {}
|
||||
DebugOnly() { }
|
||||
DebugOnly(const T&) { }
|
||||
DebugOnly(const DebugOnly&) { }
|
||||
DebugOnly& operator=(const T&) { return *this; }
|
||||
void operator++(int) {}
|
||||
void operator--(int) {}
|
||||
void operator++(int) { }
|
||||
void operator--(int) { }
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -87,17 +82,16 @@ struct DebugOnly
|
||||
* bytes of alignment a given type needs.
|
||||
*/
|
||||
template<class T>
|
||||
struct AlignmentFinder
|
||||
class AlignmentFinder
|
||||
{
|
||||
private:
|
||||
struct Aligner
|
||||
{
|
||||
char c;
|
||||
T t;
|
||||
};
|
||||
struct Aligner
|
||||
{
|
||||
char c;
|
||||
T t;
|
||||
};
|
||||
|
||||
public:
|
||||
static const int alignment = sizeof(Aligner) - sizeof(T);
|
||||
public:
|
||||
static const size_t alignment = sizeof(Aligner) - sizeof(T);
|
||||
};
|
||||
|
||||
#define MOZ_ALIGNOF(T) mozilla::AlignmentFinder<T>::alignment
|
||||
@ -124,7 +118,8 @@ public:
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AlignedElem<N> is a structure whose alignment is guaranteed to be at least N bytes.
|
||||
* AlignedElem<N> is a structure whose alignment is guaranteed to be at least N
|
||||
* bytes.
|
||||
*
|
||||
* We support 1, 2, 4, 8, and 16-bit alignment.
|
||||
*/
|
||||
@ -139,31 +134,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);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -176,28 +171,28 @@ struct AlignedElem<16>
|
||||
* false negatives when we cast from the char buffer to whatever type we've
|
||||
* constructed using the bytes.
|
||||
*/
|
||||
template <size_t nbytes>
|
||||
template<size_t nbytes>
|
||||
struct AlignedStorage
|
||||
{
|
||||
union U {
|
||||
char bytes[nbytes];
|
||||
uint64_t _;
|
||||
char bytes[nbytes];
|
||||
uint64_t _;
|
||||
} u;
|
||||
|
||||
const void *addr() const { return u.bytes; }
|
||||
void *addr() { return u.bytes; }
|
||||
const void* addr() const { return u.bytes; }
|
||||
void* addr() { return u.bytes; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
template<class T>
|
||||
struct AlignedStorage2
|
||||
{
|
||||
union U {
|
||||
char bytes[sizeof(T)];
|
||||
uint64_t _;
|
||||
char bytes[sizeof(T)];
|
||||
uint64_t _;
|
||||
} u;
|
||||
|
||||
const T *addr() const { return (const T *)u.bytes; }
|
||||
T *addr() { return (T *)(void *)u.bytes; }
|
||||
const T* addr() const { return reinterpret_cast<const T*>(u.bytes); }
|
||||
T* addr() { return static_cast<T*>(static_cast<void*>(u.bytes)); }
|
||||
};
|
||||
|
||||
/*
|
||||
@ -211,16 +206,13 @@ struct AlignedStorage2
|
||||
* N.B. GCC seems to miss some optimizations with Maybe and may generate extra
|
||||
* branches/loads/stores. Use with caution on hot paths.
|
||||
*/
|
||||
template <class T>
|
||||
template<class T>
|
||||
class Maybe
|
||||
{
|
||||
AlignedStorage2<T> storage;
|
||||
bool constructed;
|
||||
|
||||
T &asT() { return *storage.addr(); }
|
||||
|
||||
explicit Maybe(const Maybe &other);
|
||||
const Maybe &operator=(const Maybe &other);
|
||||
T& asT() { return *storage.addr(); }
|
||||
|
||||
public:
|
||||
Maybe() { constructed = false; }
|
||||
@ -229,63 +221,67 @@ class Maybe
|
||||
bool empty() const { return !constructed; }
|
||||
|
||||
void construct() {
|
||||
MOZ_ASSERT(!constructed);
|
||||
new(storage.addr()) T();
|
||||
constructed = true;
|
||||
MOZ_ASSERT(!constructed);
|
||||
new (storage.addr()) T();
|
||||
constructed = true;
|
||||
}
|
||||
|
||||
template <class T1>
|
||||
void construct(const T1 &t1) {
|
||||
MOZ_ASSERT(!constructed);
|
||||
new(storage.addr()) T(t1);
|
||||
constructed = true;
|
||||
template<class T1>
|
||||
void construct(const T1& t1) {
|
||||
MOZ_ASSERT(!constructed);
|
||||
new (storage.addr()) T(t1);
|
||||
constructed = true;
|
||||
}
|
||||
|
||||
template <class T1, class T2>
|
||||
void construct(const T1 &t1, const T2 &t2) {
|
||||
MOZ_ASSERT(!constructed);
|
||||
new(storage.addr()) T(t1, t2);
|
||||
constructed = true;
|
||||
template<class T1, class T2>
|
||||
void construct(const T1& t1, const T2& t2) {
|
||||
MOZ_ASSERT(!constructed);
|
||||
new (storage.addr()) T(t1, t2);
|
||||
constructed = true;
|
||||
}
|
||||
|
||||
template <class T1, class T2, class T3>
|
||||
void construct(const T1 &t1, const T2 &t2, const T3 &t3) {
|
||||
MOZ_ASSERT(!constructed);
|
||||
new(storage.addr()) T(t1, t2, t3);
|
||||
constructed = true;
|
||||
template<class T1, class T2, class T3>
|
||||
void construct(const T1& t1, const T2& t2, const T3& t3) {
|
||||
MOZ_ASSERT(!constructed);
|
||||
new (storage.addr()) T(t1, t2, t3);
|
||||
constructed = true;
|
||||
}
|
||||
|
||||
template <class T1, class T2, class T3, class T4>
|
||||
void construct(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4) {
|
||||
MOZ_ASSERT(!constructed);
|
||||
new(storage.addr()) T(t1, t2, t3, t4);
|
||||
constructed = true;
|
||||
template<class T1, class T2, class T3, class T4>
|
||||
void construct(const T1& t1, const T2& t2, const T3& t3, const T4& t4) {
|
||||
MOZ_ASSERT(!constructed);
|
||||
new (storage.addr()) T(t1, t2, t3, t4);
|
||||
constructed = true;
|
||||
}
|
||||
|
||||
T *addr() {
|
||||
MOZ_ASSERT(constructed);
|
||||
return &asT();
|
||||
T* addr() {
|
||||
MOZ_ASSERT(constructed);
|
||||
return &asT();
|
||||
}
|
||||
|
||||
T &ref() {
|
||||
MOZ_ASSERT(constructed);
|
||||
return asT();
|
||||
T& ref() {
|
||||
MOZ_ASSERT(constructed);
|
||||
return asT();
|
||||
}
|
||||
|
||||
const T &ref() const {
|
||||
MOZ_ASSERT(constructed);
|
||||
return const_cast<Maybe *>(this)->asT();
|
||||
const T& ref() const {
|
||||
MOZ_ASSERT(constructed);
|
||||
return const_cast<Maybe*>(this)->asT();
|
||||
}
|
||||
|
||||
void destroy() {
|
||||
ref().~T();
|
||||
constructed = false;
|
||||
ref().~T();
|
||||
constructed = false;
|
||||
}
|
||||
|
||||
void destroyIfConstructed() {
|
||||
if (!empty())
|
||||
destroy();
|
||||
if (!empty())
|
||||
destroy();
|
||||
}
|
||||
|
||||
private:
|
||||
Maybe(const Maybe& other) MOZ_DELETE;
|
||||
const Maybe& operator=(const Maybe& other) MOZ_DELETE;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -294,12 +290,12 @@ class Maybe
|
||||
* set, the unsigned subtraction followed by right shift will produce -1, or
|
||||
* size_t(-1), instead of the real difference.
|
||||
*/
|
||||
template <class T>
|
||||
template<class T>
|
||||
MOZ_ALWAYS_INLINE size_t
|
||||
PointerRangeSize(T* begin, T* end)
|
||||
{
|
||||
MOZ_ASSERT(end >= begin);
|
||||
return (size_t(end) - size_t(begin)) / sizeof(T);
|
||||
MOZ_ASSERT(end >= begin);
|
||||
return (size_t(end) - size_t(begin)) / sizeof(T);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -312,7 +308,7 @@ template<typename T, size_t N>
|
||||
size_t
|
||||
ArrayLength(T (&arr)[N])
|
||||
{
|
||||
return N;
|
||||
return N;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -324,7 +320,7 @@ template<typename T, size_t N>
|
||||
T*
|
||||
ArrayEnd(T (&arr)[N])
|
||||
{
|
||||
return arr + ArrayLength(arr);
|
||||
return arr + ArrayLength(arr);
|
||||
}
|
||||
|
||||
} /* namespace mozilla */
|
||||
|
Loading…
Reference in New Issue
Block a user