Backout 57d8f6cd245a (bug 803669), fb673c95d56b (bug 803665), 24d8e0cb73f2 (bug 803665), ac46bd0d9fba (bug 803669), c9c67b62799b (bug 803666), b3314c0ddaac (bug 803668) for debug build test failures

This commit is contained in:
Nathan Froyd 2012-10-31 13:23:17 -04:00
parent f68c1576f8
commit 24b0d73288
8 changed files with 174 additions and 141 deletions

View File

@ -722,6 +722,9 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
// Initialize the PRCList (this). // Initialize the PRCList (this).
PR_INIT_CLIST(this); PR_INIT_CLIST(this);
// Initialize timeout storage
PR_INIT_CLIST(&mTimeouts);
if (aOuterWindow) { if (aOuterWindow) {
// |this| is an inner window, add this inner window to the outer // |this| is an inner window, add this inner window to the outer
// window list of inners. // window list of inners.
@ -1310,9 +1313,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mListenerManager, NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mListenerManager,
nsEventListenerManager) nsEventListenerManager)
for (nsTimeout* timeout = tmp->mTimeouts.getFirst(); for (nsTimeout* timeout = tmp->FirstTimeout();
timeout; tmp->IsTimeout(timeout);
timeout = timeout->getNext()) { timeout = timeout->Next()) {
cb.NoteNativeChild(timeout, NS_CYCLE_COLLECTION_PARTICIPANT(nsTimeout)); cb.NoteNativeChild(timeout, NS_CYCLE_COLLECTION_PARTICIPANT(nsTimeout));
} }
@ -1417,9 +1420,9 @@ nsGlobalWindow::IsBlackForCC()
void void
nsGlobalWindow::UnmarkGrayTimers() nsGlobalWindow::UnmarkGrayTimers()
{ {
for (nsTimeout* timeout = mTimeouts.getFirst(); for (nsTimeout* timeout = FirstTimeout();
timeout; timeout && IsTimeout(timeout);
timeout = timeout->getNext()) { timeout = timeout->Next()) {
if (timeout->mScriptHandler) { if (timeout->mScriptHandler) {
JSObject* o = timeout->mScriptHandler->GetScriptObject(); JSObject* o = timeout->mScriptHandler->GetScriptObject();
xpc_UnmarkGrayObject(o); xpc_UnmarkGrayObject(o);
@ -2317,7 +2320,8 @@ nsGlobalWindow::DetachFromDocShell()
// (mJSObject) so that it can be retrieved later (until it is // (mJSObject) so that it can be retrieved later (until it is
// finalized by the JS GC). // finalized by the JS GC).
NS_ASSERTION(mTimeouts.isEmpty(), "Uh, outer window holds timeouts!"); NS_ASSERTION(PR_CLIST_IS_EMPTY(&mTimeouts),
"Uh, outer window holds timeouts!");
// Call FreeInnerObjects on all inner windows, not just the current // Call FreeInnerObjects on all inner windows, not just the current
// one, since some could be held by WindowStateHolder objects that // one, since some could be held by WindowStateHolder objects that
@ -9898,7 +9902,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
// timeout events fire "early", so we need to test the timer as well // timeout events fire "early", so we need to test the timer as well
// as the deadline. // as the deadline.
last_expired_timeout = nullptr; last_expired_timeout = nullptr;
for (timeout = mTimeouts.getFirst(); timeout; timeout = timeout->getNext()) { for (timeout = FirstTimeout(); IsTimeout(timeout); timeout = timeout->Next()) {
if (((timeout == aTimeout) || (timeout->mWhen <= deadline)) && if (((timeout == aTimeout) || (timeout->mWhen <= deadline)) &&
(timeout->mFiringDepth == 0)) { (timeout->mFiringDepth == 0)) {
// Mark any timeouts that are on the list to be fired with the // Mark any timeouts that are on the list to be fired with the
@ -9932,7 +9936,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
// list for any timeouts inserted as a result of running a timeout. // list for any timeouts inserted as a result of running a timeout.
dummy_timeout.mFiringDepth = firingDepth; dummy_timeout.mFiringDepth = firingDepth;
dummy_timeout.mWhen = now; dummy_timeout.mWhen = now;
last_expired_timeout->setNext(&dummy_timeout); PR_INSERT_AFTER(&dummy_timeout, last_expired_timeout);
// Don't let ClearWindowTimeouts throw away our stack-allocated // Don't let ClearWindowTimeouts throw away our stack-allocated
// dummy timeout. // dummy timeout.
@ -9946,10 +9950,10 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
Telemetry::AutoCounter<Telemetry::DOM_TIMERS_FIRED_PER_NATIVE_TIMEOUT> timeoutsRan; Telemetry::AutoCounter<Telemetry::DOM_TIMERS_FIRED_PER_NATIVE_TIMEOUT> timeoutsRan;
for (timeout = mTimeouts.getFirst(); for (timeout = FirstTimeout();
timeout != &dummy_timeout && !IsFrozen(); timeout != &dummy_timeout && !IsFrozen();
timeout = nextTimeout) { timeout = nextTimeout) {
nextTimeout = timeout->getNext(); nextTimeout = timeout->Next();
if (timeout->mFiringDepth != firingDepth) { if (timeout->mFiringDepth != firingDepth) {
// We skip the timeout since it's on the list to run at another // We skip the timeout since it's on the list to run at another
@ -10013,9 +10017,9 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
// Running a timeout can cause another timeout to be deleted, so // Running a timeout can cause another timeout to be deleted, so
// we need to reset the pointer to the following timeout. // we need to reset the pointer to the following timeout.
nextTimeout = timeout->getNext(); nextTimeout = timeout->Next();
timeout->remove(); PR_REMOVE_LINK(timeout);
if (needsReinsertion) { if (needsReinsertion) {
// Insert interval timeout onto list sorted in deadline order. // Insert interval timeout onto list sorted in deadline order.
@ -10028,7 +10032,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
} }
// Take the dummy timeout off the head of the list // Take the dummy timeout off the head of the list
dummy_timeout.remove(); PR_REMOVE_LINK(&dummy_timeout);
mTimeoutInsertionPoint = last_insertion_point; mTimeoutInsertionPoint = last_insertion_point;
} }
@ -10066,7 +10070,9 @@ nsGlobalWindow::ClearTimeoutOrInterval(int32_t aTimerID)
uint32_t public_id = (uint32_t)aTimerID; uint32_t public_id = (uint32_t)aTimerID;
nsTimeout *timeout; nsTimeout *timeout;
for (timeout = mTimeouts.getFirst(); timeout; timeout = timeout->getNext()) { for (timeout = FirstTimeout();
IsTimeout(timeout);
timeout = timeout->Next()) {
if (timeout->mPublicId == public_id) { if (timeout->mPublicId == public_id) {
if (timeout->mRunning) { if (timeout->mRunning) {
/* We're running from inside the timeout. Mark this /* We're running from inside the timeout. Mark this
@ -10076,7 +10082,7 @@ nsGlobalWindow::ClearTimeoutOrInterval(int32_t aTimerID)
} }
else { else {
/* Delete the timeout from the pending timeout list */ /* Delete the timeout from the pending timeout list */
timeout->remove(); PR_REMOVE_LINK(timeout);
if (timeout->mTimer) { if (timeout->mTimer) {
timeout->mTimer->Cancel(); timeout->mTimer->Cancel();
@ -10111,13 +10117,13 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
// start at the timer after mTimeoutInsertionPoint, if there is one. // start at the timer after mTimeoutInsertionPoint, if there is one.
// Otherwise, start at the beginning of the list. // Otherwise, start at the beginning of the list.
for (nsTimeout *timeout = mTimeoutInsertionPoint ? for (nsTimeout *timeout = mTimeoutInsertionPoint ?
mTimeoutInsertionPoint->getNext() : mTimeouts.getFirst(); mTimeoutInsertionPoint->Next() : FirstTimeout();
timeout; ) { IsTimeout(timeout); ) {
// It's important that this check be <= so that we guarantee that // It's important that this check be <= so that we guarantee that
// taking NS_MAX with |now| won't make a quantity equal to // taking NS_MAX with |now| won't make a quantity equal to
// timeout->mWhen below. // timeout->mWhen below.
if (timeout->mWhen <= now) { if (timeout->mWhen <= now) {
timeout = timeout->getNext(); timeout = timeout->Next();
continue; continue;
} }
@ -10154,14 +10160,14 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
// Get the pointer to the next timeout now, before we move the // Get the pointer to the next timeout now, before we move the
// current timeout in the list. // current timeout in the list.
nsTimeout* nextTimeout = timeout->getNext(); nsTimeout* nextTimeout = timeout->Next();
// It is safe to remove and re-insert because mWhen is now // It is safe to remove and re-insert because mWhen is now
// strictly smaller than it used to be, so we know we'll insert // strictly smaller than it used to be, so we know we'll insert
// |timeout| before nextTimeout. // |timeout| before nextTimeout.
NS_ASSERTION(!nextTimeout || NS_ASSERTION(!IsTimeout(nextTimeout) ||
timeout->mWhen < nextTimeout->mWhen, "How did that happen?"); timeout->mWhen < nextTimeout->mWhen, "How did that happen?");
timeout->remove(); PR_REMOVE_LINK(timeout);
// InsertTimeoutIntoList will addref |timeout| and reset // InsertTimeoutIntoList will addref |timeout| and reset
// mFiringDepth. Make sure to undo that after calling it. // mFiringDepth. Make sure to undo that after calling it.
uint32_t firingDepth = timeout->mFiringDepth; uint32_t firingDepth = timeout->mFiringDepth;
@ -10178,7 +10184,7 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
timeout = nextTimeout; timeout = nextTimeout;
} else { } else {
timeout = timeout->getNext(); timeout = timeout->Next();
} }
} }
@ -10190,7 +10196,7 @@ nsGlobalWindow::ClearAllTimeouts()
{ {
nsTimeout *timeout, *nextTimeout; nsTimeout *timeout, *nextTimeout;
for (timeout = mTimeouts.getFirst(); timeout; timeout = nextTimeout) { for (timeout = FirstTimeout(); IsTimeout(timeout); timeout = nextTimeout) {
/* If RunTimeout() is higher up on the stack for this /* If RunTimeout() is higher up on the stack for this
window, e.g. as a result of document.write from a timeout, window, e.g. as a result of document.write from a timeout,
then we need to reset the list insertion point for then we need to reset the list insertion point for
@ -10199,7 +10205,7 @@ nsGlobalWindow::ClearAllTimeouts()
if (mRunningTimeout == timeout) if (mRunningTimeout == timeout)
mTimeoutInsertionPoint = nullptr; mTimeoutInsertionPoint = nullptr;
nextTimeout = timeout->getNext(); nextTimeout = timeout->Next();
if (timeout->mTimer) { if (timeout->mTimer) {
timeout->mTimer->Cancel(); timeout->mTimer->Cancel();
@ -10219,7 +10225,7 @@ nsGlobalWindow::ClearAllTimeouts()
} }
// Clear out our list // Clear out our list
mTimeouts.clear(); PR_INIT_CLIST(&mTimeouts);
} }
void void
@ -10232,19 +10238,19 @@ nsGlobalWindow::InsertTimeoutIntoList(nsTimeout *aTimeout)
// mTimeoutInsertionPoint, though. This optimizes for the common case of // mTimeoutInsertionPoint, though. This optimizes for the common case of
// insertion at the end. // insertion at the end.
nsTimeout* prevSibling; nsTimeout* prevSibling;
for (prevSibling = mTimeouts.getLast(); for (prevSibling = LastTimeout();
prevSibling && prevSibling != mTimeoutInsertionPoint && IsTimeout(prevSibling) && prevSibling != mTimeoutInsertionPoint &&
// This condition needs to match the one in SetTimeoutOrInterval that // This condition needs to match the one in SetTimeoutOrInterval that
// determines whether to set mWhen or mTimeRemaining. // determines whether to set mWhen or mTimeRemaining.
((IsFrozen() || mTimeoutsSuspendDepth) ? ((IsFrozen() || mTimeoutsSuspendDepth) ?
prevSibling->mTimeRemaining > aTimeout->mTimeRemaining : prevSibling->mTimeRemaining > aTimeout->mTimeRemaining :
prevSibling->mWhen > aTimeout->mWhen); prevSibling->mWhen > aTimeout->mWhen);
prevSibling = prevSibling->getPrevious()) { prevSibling = prevSibling->Prev()) {
/* Do nothing; just searching */ /* Do nothing; just searching */
} }
// Now link in aTimeout after prevSibling // Now link in aTimeout after prevSibling.
prevSibling->setNext(aTimeout); PR_INSERT_AFTER(aTimeout, prevSibling);
aTimeout->mFiringDepth = 0; aTimeout->mFiringDepth = 0;
@ -10536,7 +10542,7 @@ nsGlobalWindow::SuspendTimeouts(uint32_t aIncrease,
mozilla::dom::workers::SuspendWorkersForWindow(cx, this); mozilla::dom::workers::SuspendWorkersForWindow(cx, this);
TimeStamp now = TimeStamp::Now(); TimeStamp now = TimeStamp::Now();
for (nsTimeout *t = mTimeouts.getFirst(); t; t = t->getNext()) { for (nsTimeout *t = FirstTimeout(); IsTimeout(t); t = t->Next()) {
// Set mTimeRemaining to be the time remaining for this timer. // Set mTimeRemaining to be the time remaining for this timer.
if (t->mWhen > now) if (t->mWhen > now)
t->mTimeRemaining = t->mWhen - now; t->mTimeRemaining = t->mWhen - now;
@ -10624,7 +10630,7 @@ nsGlobalWindow::ResumeTimeouts(bool aThawChildren)
bool _seenDummyTimeout = false; bool _seenDummyTimeout = false;
#endif #endif
for (nsTimeout *t = mTimeouts.getFirst(); t; t = t->getNext()) { for (nsTimeout *t = FirstTimeout(); IsTimeout(t); t = t->Next()) {
// There's a chance we're being called with RunTimeout on the stack in which // There's a chance we're being called with RunTimeout on the stack in which
// case we have a dummy timeout in the list that *must not* be resumed. It // case we have a dummy timeout in the list that *must not* be resumed. It
// can be identified by a null mWindow. // can be identified by a null mWindow.

View File

@ -59,7 +59,6 @@
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIIDBFactory.h" #include "nsIIDBFactory.h"
#include "nsFrameMessageManager.h" #include "nsFrameMessageManager.h"
#include "mozilla/LinkedList.h"
#include "mozilla/TimeStamp.h" #include "mozilla/TimeStamp.h"
#include "nsIDOMTouchEvent.h" #include "nsIDOMTouchEvent.h"
#include "nsIInlineEventHandlers.h" #include "nsIInlineEventHandlers.h"
@ -134,7 +133,7 @@ NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
* timeout. Holds a strong reference to an nsIScriptTimeoutHandler, which * timeout. Holds a strong reference to an nsIScriptTimeoutHandler, which
* abstracts the language specific cruft. * abstracts the language specific cruft.
*/ */
struct nsTimeout : mozilla::LinkedListElement<nsTimeout> struct nsTimeout : PRCList
{ {
nsTimeout(); nsTimeout();
~nsTimeout(); ~nsTimeout();
@ -144,6 +143,16 @@ struct nsTimeout : mozilla::LinkedListElement<nsTimeout>
nsrefcnt Release(); nsrefcnt Release();
nsrefcnt AddRef(); nsrefcnt AddRef();
nsTimeout* Next() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
return static_cast<nsTimeout*>(PR_NEXT_LINK(this));
}
nsTimeout* Prev() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
return static_cast<nsTimeout*>(PR_PREV_LINK(this));
}
nsresult InitTimer(nsTimerCallbackFunc aFunc, uint64_t delay) { nsresult InitTimer(nsTimerCallbackFunc aFunc, uint64_t delay) {
return mTimer->InitWithFuncCallback(aFunc, this, delay, return mTimer->InitWithFuncCallback(aFunc, this, delay,
nsITimer::TYPE_ONE_SHOT); nsITimer::TYPE_ONE_SHOT);
@ -860,6 +869,20 @@ protected:
bool IsInModalState(); bool IsInModalState();
nsTimeout* FirstTimeout() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
return static_cast<nsTimeout*>(PR_LIST_HEAD(&mTimeouts));
}
nsTimeout* LastTimeout() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
return static_cast<nsTimeout*>(PR_LIST_TAIL(&mTimeouts));
}
bool IsTimeout(PRCList* aList) {
return aList != &mTimeouts;
}
// Convenience functions for the many methods that need to scale // Convenience functions for the many methods that need to scale
// from device to CSS pixels or vice versa. Note: if a presentation // from device to CSS pixels or vice versa. Note: if a presentation
// context is not available, they will assume a 1:1 ratio. // context is not available, they will assume a 1:1 ratio.
@ -1027,7 +1050,7 @@ protected:
// non-null. In that case, the dummy timeout pointed to by // non-null. In that case, the dummy timeout pointed to by
// mTimeoutInsertionPoint may have a later mWhen than some of the timeouts // mTimeoutInsertionPoint may have a later mWhen than some of the timeouts
// that come after it. // that come after it.
mozilla::LinkedList<nsTimeout> mTimeouts; PRCList mTimeouts;
// If mTimeoutInsertionPoint is non-null, insertions should happen after it. // If mTimeoutInsertionPoint is non-null, insertions should happen after it.
// This is a dummy timeout at the moment; if that ever changes, the logic in // This is a dummy timeout at the moment; if that ever changes, the logic in
// ResetTimersForNonBackgroundWindow needs to change. // ResetTimersForNonBackgroundWindow needs to change.

View File

@ -501,7 +501,8 @@ nsresult nsExtensibleStringBundle::GetSimpleEnumeration(nsISimpleEnumerator ** a
#define MAX_CACHED_BUNDLES 16 #define MAX_CACHED_BUNDLES 16
struct bundleCacheEntry_t : public LinkedListElement<bundleCacheEntry_t> { struct bundleCacheEntry_t {
PRCList list;
nsCStringKey *mHashKey; nsCStringKey *mHashKey;
// do not use a nsCOMPtr - this is a struct not a class! // do not use a nsCOMPtr - this is a struct not a class!
nsIStringBundle* mBundle; nsIStringBundle* mBundle;
@ -515,6 +516,7 @@ nsStringBundleService::nsStringBundleService() :
printf("\n++ nsStringBundleService::nsStringBundleService ++\n"); printf("\n++ nsStringBundleService::nsStringBundleService ++\n");
#endif #endif
PR_INIT_CLIST(&mBundleCache);
PL_InitArenaPool(&mCacheEntryPool, "srEntries", PL_InitArenaPool(&mCacheEntryPool, "srEntries",
sizeof(bundleCacheEntry_t)*MAX_CACHED_BUNDLES, sizeof(bundleCacheEntry_t)*MAX_CACHED_BUNDLES,
sizeof(bundleCacheEntry_t)); sizeof(bundleCacheEntry_t));
@ -580,10 +582,16 @@ nsStringBundleService::flushBundleCache()
// release all bundles in the cache // release all bundles in the cache
mBundleMap.Reset(); mBundleMap.Reset();
while (!mBundleCache.isEmpty()) { PRCList *current = PR_LIST_HEAD(&mBundleCache);
bundleCacheEntry_t *cacheEntry = mBundleCache.popFirst(); while (current != &mBundleCache) {
bundleCacheEntry_t *cacheEntry = (bundleCacheEntry_t*)current;
recycleEntry(cacheEntry); recycleEntry(cacheEntry);
PRCList *oldItem = current;
current = PR_NEXT_LINK(current);
// will be freed in PL_FreeArenaPool
PR_REMOVE_LINK(oldItem);
} }
PL_FreeArenaPool(&mCacheEntryPool); PL_FreeArenaPool(&mCacheEntryPool);
} }
@ -608,7 +616,7 @@ nsStringBundleService::getStringBundle(const char *aURLSpec,
// cache hit! // cache hit!
// remove it from the list, it will later be reinserted // remove it from the list, it will later be reinserted
// at the head of the list // at the head of the list
cacheEntry->remove(); PR_REMOVE_LINK((PRCList*)cacheEntry);
} else { } else {
@ -625,7 +633,8 @@ nsStringBundleService::getStringBundle(const char *aURLSpec,
// at this point the cacheEntry should exist in the hashtable, // at this point the cacheEntry should exist in the hashtable,
// but is not in the LRU cache. // but is not in the LRU cache.
// put the cache entry at the front of the list // put the cache entry at the front of the list
mBundleCache.insertFront(cacheEntry);
PR_INSERT_LINK((PRCList *)cacheEntry, &mBundleCache);
// finally, return the value // finally, return the value
*aResult = cacheEntry->mBundle; *aResult = cacheEntry->mBundle;
@ -650,7 +659,7 @@ nsStringBundleService::insertIntoCache(nsIStringBundle* aBundle,
} else { } else {
// cache is full // cache is full
// take the last entry in the list, and recycle it. // take the last entry in the list, and recycle it.
cacheEntry = mBundleCache.getLast(); cacheEntry = (bundleCacheEntry_t*)PR_LIST_TAIL(&mBundleCache);
// remove it from the hash table and linked list // remove it from the hash table and linked list
NS_ASSERTION(mBundleMap.Exists(cacheEntry->mHashKey), NS_ASSERTION(mBundleMap.Exists(cacheEntry->mHashKey),
@ -661,7 +670,7 @@ nsStringBundleService::insertIntoCache(nsIStringBundle* aBundle,
aHashKey->GetString()).get()); aHashKey->GetString()).get());
#endif #endif
mBundleMap.Remove(cacheEntry->mHashKey); mBundleMap.Remove(cacheEntry->mHashKey);
cacheEntry->remove(); PR_REMOVE_LINK((PRCList*)cacheEntry);
// free up excess memory // free up excess memory
recycleEntry(cacheEntry); recycleEntry(cacheEntry);

View File

@ -6,6 +6,7 @@
#ifndef nsStringBundleService_h__ #ifndef nsStringBundleService_h__
#define nsStringBundleService_h__ #define nsStringBundleService_h__
#include "prclist.h"
#include "plarena.h" #include "plarena.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
@ -17,8 +18,6 @@
#include "nsIErrorService.h" #include "nsIErrorService.h"
#include "nsIStringBundleOverride.h" #include "nsIStringBundleOverride.h"
#include "mozilla/LinkedList.h"
struct bundleCacheEntry_t; struct bundleCacheEntry_t;
class nsStringBundleService : public nsIStringBundleService, class nsStringBundleService : public nsIStringBundleService,
@ -49,7 +48,7 @@ private:
static void recycleEntry(bundleCacheEntry_t*); static void recycleEntry(bundleCacheEntry_t*);
nsHashtable mBundleMap; nsHashtable mBundleMap;
mozilla::LinkedList<bundleCacheEntry_t> mBundleCache; PRCList mBundleCache;
PLArenaPool mCacheEntryPool; PLArenaPool mCacheEntryPool;
nsCOMPtr<nsIErrorService> mErrorService; nsCOMPtr<nsIErrorService> mErrorService;

View File

@ -9,7 +9,7 @@
#include "nsString.h" #include "nsString.h"
#include "nsUnicharUtils.h" // for nsCaseInsensitiveStringComparator #include "nsUnicharUtils.h" // for nsCaseInsensitiveStringComparator
#include "mozilla/LinkedList.h" #include "prclist.h"
/** /**
@ -60,7 +60,7 @@ class nsScannerBufferList
* of the data segment is determined by increment the |this| pointer * of the data segment is determined by increment the |this| pointer
* by 1 unit. * by 1 unit.
*/ */
class Buffer : public mozilla::LinkedListElement<Buffer> class Buffer : public PRCList
{ {
public: public:
@ -75,11 +75,11 @@ class nsScannerBufferList
const PRUnichar* DataEnd() const { return mDataEnd; } const PRUnichar* DataEnd() const { return mDataEnd; }
PRUnichar* DataEnd() { return mDataEnd; } PRUnichar* DataEnd() { return mDataEnd; }
const Buffer* Next() const { return getNext(); } const Buffer* Next() const { return static_cast<const Buffer*>(next); }
Buffer* Next() { return getNext(); } Buffer* Next() { return static_cast<Buffer*>(next); }
const Buffer* Prev() const { return getPrevious(); } const Buffer* Prev() const { return static_cast<const Buffer*>(prev); }
Buffer* Prev() { return getPrevious(); } Buffer* Prev() { return static_cast<Buffer*>(prev); }
uint32_t DataLength() const { return mDataEnd - DataStart(); } uint32_t DataLength() const { return mDataEnd - DataStart(); }
void SetDataLength(uint32_t len) { mDataEnd = DataStart() + len; } void SetDataLength(uint32_t len) { mDataEnd = DataStart() + len; }
@ -126,22 +126,23 @@ class nsScannerBufferList
nsScannerBufferList( Buffer* buf ) nsScannerBufferList( Buffer* buf )
: mRefCnt(0) : mRefCnt(0)
{ {
mBuffers.insertBack(buf); PR_INIT_CLIST(&mBuffers);
PR_APPEND_LINK(buf, &mBuffers);
} }
void AddRef() { ++mRefCnt; } void AddRef() { ++mRefCnt; }
void Release() { if (--mRefCnt == 0) delete this; } void Release() { if (--mRefCnt == 0) delete this; }
void Append( Buffer* buf ) { mBuffers.insertBack(buf); } void Append( Buffer* buf ) { PR_APPEND_LINK(buf, &mBuffers); }
void InsertAfter( Buffer* buf, Buffer* prev ) { prev->setNext(buf); } void InsertAfter( Buffer* buf, Buffer* prev ) { PR_INSERT_AFTER(buf, prev); }
void SplitBuffer( const Position& ); void SplitBuffer( const Position& );
void DiscardUnreferencedPrefix( Buffer* ); void DiscardUnreferencedPrefix( Buffer* );
Buffer* Head() { return mBuffers.getFirst(); } Buffer* Head() { return static_cast<Buffer*>(PR_LIST_HEAD(&mBuffers)); }
const Buffer* Head() const { return mBuffers.getFirst(); } const Buffer* Head() const { return static_cast<const Buffer*>(PR_LIST_HEAD(&mBuffers)); }
Buffer* Tail() { return mBuffers.getLast(); } Buffer* Tail() { return static_cast<Buffer*>(PR_LIST_TAIL(&mBuffers)); }
const Buffer* Tail() const { return mBuffers.getLast(); } const Buffer* Tail() const { return static_cast<const Buffer*>(PR_LIST_TAIL(&mBuffers)); }
private: private:
@ -151,7 +152,7 @@ class nsScannerBufferList
void ReleaseAll(); void ReleaseAll();
int32_t mRefCnt; int32_t mRefCnt;
mozilla::LinkedList<Buffer> mBuffers; PRCList mBuffers;
}; };

View File

@ -66,11 +66,12 @@ nsScannerBufferList::AllocBuffer( uint32_t capacity )
void void
nsScannerBufferList::ReleaseAll() nsScannerBufferList::ReleaseAll()
{ {
while (!mBuffers.isEmpty()) while (!PR_CLIST_IS_EMPTY(&mBuffers))
{ {
Buffer* node = mBuffers.popFirst(); PRCList* node = PR_LIST_HEAD(&mBuffers);
PR_REMOVE_LINK(node);
//printf(">>> freeing buffer @%p\n", node); //printf(">>> freeing buffer @%p\n", node);
free(node); free(static_cast<Buffer*>(node));
} }
} }
@ -105,10 +106,10 @@ nsScannerBufferList::DiscardUnreferencedPrefix( Buffer* aBuf )
{ {
if (aBuf == Head()) if (aBuf == Head())
{ {
while (!mBuffers.isEmpty() && !Head()->IsInUse()) while (!PR_CLIST_IS_EMPTY(&mBuffers) && !Head()->IsInUse())
{ {
Buffer* buffer = Head(); Buffer* buffer = Head();
buffer->remove(); PR_REMOVE_LINK(buffer);
free(buffer); free(buffer);
} }
} }
@ -275,7 +276,7 @@ nsScannerSubstring::GetNextFragment( nsScannerFragment& frag ) const
if (frag.mBuffer == mEnd.mBuffer) if (frag.mBuffer == mEnd.mBuffer)
return false; return false;
frag.mBuffer = frag.mBuffer->getNext(); frag.mBuffer = static_cast<const Buffer*>(PR_NEXT_LINK(frag.mBuffer));
if (frag.mBuffer == mStart.mBuffer) if (frag.mBuffer == mStart.mBuffer)
frag.mFragmentStart = mStart.mPosition; frag.mFragmentStart = mStart.mPosition;
@ -297,7 +298,7 @@ nsScannerSubstring::GetPrevFragment( nsScannerFragment& frag ) const
if (frag.mBuffer == mStart.mBuffer) if (frag.mBuffer == mStart.mBuffer)
return false; return false;
frag.mBuffer = frag.mBuffer->getPrevious(); frag.mBuffer = static_cast<const Buffer*>(PR_PREV_LINK(frag.mBuffer));
if (frag.mBuffer == mStart.mBuffer) if (frag.mBuffer == mStart.mBuffer)
frag.mFragmentStart = mStart.mPosition; frag.mFragmentStart = mStart.mPosition;

View File

@ -62,21 +62,64 @@ void GetURIStringFromRequest(nsIRequest* request, nsACString &name)
} }
#endif /* DEBUG */ #endif /* DEBUG */
struct nsStatusInfo : public PRCList
{
nsString mStatusMessage;
nsresult mStatusCode;
// Weak mRequest is ok; we'll be told if it decides to go away.
nsIRequest * const mRequest;
nsStatusInfo(nsIRequest *aRequest) :
mRequest(aRequest)
{
MOZ_COUNT_CTOR(nsStatusInfo);
PR_INIT_CLIST(this);
}
~nsStatusInfo()
{
MOZ_COUNT_DTOR(nsStatusInfo);
PR_REMOVE_LINK(this);
}
};
struct nsRequestInfo : public PLDHashEntryHdr
{
nsRequestInfo(const void *key)
: mKey(key), mCurrentProgress(0), mMaxProgress(0), mUploading(false)
, mLastStatus(nullptr)
{
MOZ_COUNT_CTOR(nsRequestInfo);
}
~nsRequestInfo()
{
MOZ_COUNT_DTOR(nsRequestInfo);
}
nsIRequest* Request() {
return static_cast<nsIRequest*>(const_cast<void*>(mKey));
}
const void* mKey; // Must be first for the pldhash stubs to work
int64_t mCurrentProgress;
int64_t mMaxProgress;
bool mUploading;
nsAutoPtr<nsStatusInfo> mLastStatus;
};
bool static bool
nsDocLoader::RequestInfoHashInitEntry(PLDHashTable* table, RequestInfoHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
PLDHashEntryHdr* entry, const void *key)
const void* key)
{ {
// Initialize the entry with placement new // Initialize the entry with placement new
new (entry) nsRequestInfo(key); new (entry) nsRequestInfo(key);
return true; return true;
} }
void static void
nsDocLoader::RequestInfoHashClearEntry(PLDHashTable* table, RequestInfoHashClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
PLDHashEntryHdr* entry)
{ {
nsRequestInfo* info = static_cast<nsRequestInfo *>(entry); nsRequestInfo* info = static_cast<nsRequestInfo *>(entry);
info->~nsRequestInfo(); info->~nsRequestInfo();
@ -135,6 +178,8 @@ nsDocLoader::nsDocLoader()
ClearInternalProgress(); ClearInternalProgress();
PR_INIT_CLIST(&mStatusInfoList);
PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
("DocLoader:%p: created.\n", this)); ("DocLoader:%p: created.\n", this));
} }
@ -847,8 +892,9 @@ void nsDocLoader::doStopURLLoad(nsIRequest *request, nsresult aStatus)
// Fire a status change message for the most recent unfinished // Fire a status change message for the most recent unfinished
// request to make sure that the displayed status is not outdated. // request to make sure that the displayed status is not outdated.
if (!mStatusInfoList.isEmpty()) { if (!PR_CLIST_IS_EMPTY(&mStatusInfoList)) {
nsStatusInfo* statusInfo = mStatusInfoList.getFirst(); nsStatusInfo* statusInfo =
static_cast<nsStatusInfo*>(PR_LIST_HEAD(&mStatusInfoList));
FireOnStatusChange(this, statusInfo->mRequest, FireOnStatusChange(this, statusInfo->mRequest,
statusInfo->mStatusCode, statusInfo->mStatusCode,
statusInfo->mStatusMessage.get()); statusInfo->mStatusMessage.get());
@ -1133,12 +1179,12 @@ NS_IMETHODIMP nsDocLoader::OnStatus(nsIRequest* aRequest, nsISupports* ctxt,
} else { } else {
// We're going to move it to the front of the list, so remove // We're going to move it to the front of the list, so remove
// it from wherever it is now. // it from wherever it is now.
info->mLastStatus->remove(); PR_REMOVE_LINK(info->mLastStatus);
} }
info->mLastStatus->mStatusMessage = msg; info->mLastStatus->mStatusMessage = msg;
info->mLastStatus->mStatusCode = aStatus; info->mLastStatus->mStatusCode = aStatus;
// Put the info at the front of the list // Put the info at the front of the list
mStatusInfoList.insertFront(info->mLastStatus); PR_INSERT_LINK(info->mLastStatus, &mStatusInfoList);
} }
FireOnStatusChange(this, aRequest, aStatus, msg); FireOnStatusChange(this, aRequest, aStatus, msg);
} }
@ -1489,10 +1535,10 @@ void nsDocLoader::RemoveRequestInfo(nsIRequest *aRequest)
PL_DHashTableOperate(&mRequestInfoHash, aRequest, PL_DHASH_REMOVE); PL_DHashTableOperate(&mRequestInfoHash, aRequest, PL_DHASH_REMOVE);
} }
nsDocLoader::nsRequestInfo* nsDocLoader::GetRequestInfo(nsIRequest* aRequest) nsRequestInfo * nsDocLoader::GetRequestInfo(nsIRequest *aRequest)
{ {
nsRequestInfo* info = nsRequestInfo *info =
static_cast<nsRequestInfo*> static_cast<nsRequestInfo *>
(PL_DHashTableOperate(&mRequestInfoHash, aRequest, (PL_DHashTableOperate(&mRequestInfoHash, aRequest,
PL_DHASH_LOOKUP)); PL_DHASH_LOOKUP));
@ -1528,12 +1574,12 @@ void nsDocLoader::ClearRequestInfoHash(void)
} }
// PLDHashTable enumeration callback that calculates the max progress. // PLDHashTable enumeration callback that calculates the max progress.
PLDHashOperator static PLDHashOperator
nsDocLoader::CalcMaxProgressCallback(PLDHashTable* table, PLDHashEntryHdr* hdr, CalcMaxProgressCallback(PLDHashTable *table, PLDHashEntryHdr *hdr,
uint32_t number, void* arg) uint32_t number, void *arg)
{ {
const nsRequestInfo* info = static_cast<const nsRequestInfo*>(hdr); const nsRequestInfo *info = static_cast<const nsRequestInfo *>(hdr);
int64_t* max = static_cast<int64_t* >(arg); int64_t *max = static_cast<int64_t *>(arg);
if (info->mMaxProgress < info->mCurrentProgress) { if (info->mMaxProgress < info->mCurrentProgress) {
*max = int64_t(-1); *max = int64_t(-1);

View File

@ -27,10 +27,10 @@
#include "nsISupportsPriority.h" #include "nsISupportsPriority.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "pldhash.h" #include "pldhash.h"
#include "prclist.h"
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
#include "mozilla/LinkedList.h" struct nsRequestInfo;
struct nsListenerInfo; struct nsListenerInfo;
/**************************************************************************** /****************************************************************************
@ -194,55 +194,6 @@ protected:
} }
protected: protected:
struct nsStatusInfo : public mozilla::LinkedListElement<nsStatusInfo>
{
nsString mStatusMessage;
nsresult mStatusCode;
// Weak mRequest is ok; we'll be told if it decides to go away.
nsIRequest * const mRequest;
nsStatusInfo(nsIRequest* aRequest) :
mRequest(aRequest)
{
MOZ_COUNT_CTOR(nsStatusInfo);
}
~nsStatusInfo()
{
MOZ_COUNT_DTOR(nsStatusInfo);
this->remove();
}
};
struct nsRequestInfo : public PLDHashEntryHdr
{
nsRequestInfo(const void* key)
: mKey(key), mCurrentProgress(0), mMaxProgress(0), mUploading(false)
, mLastStatus(nullptr)
{
MOZ_COUNT_CTOR(nsRequestInfo);
}
~nsRequestInfo()
{
MOZ_COUNT_DTOR(nsRequestInfo);
}
nsIRequest* Request() {
return static_cast<nsIRequest*>(const_cast<void*>(mKey));
}
const void* mKey; // Must be first for the pldhash stubs to work
int64_t mCurrentProgress;
int64_t mMaxProgress;
bool mUploading;
nsAutoPtr<nsStatusInfo> mLastStatus;
};
static bool RequestInfoHashInitEntry(PLDHashTable* table, PLDHashEntryHdr* entry,
const void* key);
static void RequestInfoHashClearEntry(PLDHashTable* table, PLDHashEntryHdr* entry);
// IMPORTANT: The ownership implicit in the following member // IMPORTANT: The ownership implicit in the following member
// variables has been explicitly checked and set using nsCOMPtr // variables has been explicitly checked and set using nsCOMPtr
// for owning pointers and raw COM interface pointers for weak // for owning pointers and raw COM interface pointers for weak
@ -272,7 +223,7 @@ protected:
PLDHashTable mRequestInfoHash; PLDHashTable mRequestInfoHash;
int64_t mCompletedTotalProgress; int64_t mCompletedTotalProgress;
mozilla::LinkedList<nsStatusInfo> mStatusInfoList; PRCList mStatusInfoList;
/* /*
* This flag indicates that the loader is loading a document. It is set * This flag indicates that the loader is loading a document. It is set
@ -317,9 +268,6 @@ private:
nsRequestInfo *GetRequestInfo(nsIRequest* aRequest); nsRequestInfo *GetRequestInfo(nsIRequest* aRequest);
void ClearRequestInfoHash(); void ClearRequestInfoHash();
int64_t CalculateMaxProgress(); int64_t CalculateMaxProgress();
static PLDHashOperator CalcMaxProgressCallback(PLDHashTable* table,
PLDHashEntryHdr* hdr,
uint32_t number, void* arg);
/// void DumpChannelInfo(void); /// void DumpChannelInfo(void);
// used to clear our internal progress state between loads... // used to clear our internal progress state between loads...