Bug 905230 - Use LinkedList for nsXBLJSClass; r=mrbkap

This commit is contained in:
Ms2ger 2013-08-22 08:34:44 +02:00
parent f021b01688
commit 930728b3e2
3 changed files with 23 additions and 26 deletions

View File

@ -94,9 +94,11 @@ uint64_t nsXBLJSClass::sIdCount = 0;
nsXBLJSClass::nsXBLJSClass(const nsAFlatCString& aClassName,
const nsCString& aKey)
: LinkedListElement<nsXBLJSClass>()
, mRefCnt(0)
, mKey(aKey)
{
memset(this, 0, sizeof(nsXBLJSClass));
next = prev = static_cast<JSCList*>(this);
memset(static_cast<JSClass*>(this), 0, sizeof(JSClass));
name = ToNewCString(aClassName);
flags =
JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS |
@ -110,13 +112,12 @@ nsXBLJSClass::nsXBLJSClass(const nsAFlatCString& aClassName,
resolve = JS_ResolveStub;
convert = ::JS_ConvertStub;
finalize = XBLFinalize;
mKey = aKey;
}
nsrefcnt
nsXBLJSClass::Destroy()
{
NS_ASSERTION(next == prev && prev == static_cast<JSCList*>(this),
NS_ASSERTION(!isInList(),
"referenced nsXBLJSClass is on LRU list already!?");
if (nsXBLService::gClassTable) {
@ -130,8 +131,7 @@ nsXBLJSClass::Destroy()
delete this;
} else {
// Put this most-recently-used class on end of the LRU-sorted freelist.
JSCList* mru = static_cast<JSCList*>(this);
JS_APPEND_LINK(mru, &nsXBLService::gClassLRUList);
nsXBLService::gClassLRUList->insertBack(this);
nsXBLService::gClassLRUListLength++;
}
@ -957,27 +957,21 @@ nsXBLBinding::DoInitJSClass(JSContext *cx, JS::Handle<JSObject*> global,
c = static_cast<nsXBLJSClass*>(nsXBLService::gClassTable->Get(&key));
}
if (c) {
// If c is on the LRU list (i.e., not linked to itself), remove it now!
JSCList* link = static_cast<JSCList*>(c);
if (c->next != link) {
JS_REMOVE_AND_INIT_LINK(link);
// If c is on the LRU list, remove it now!
if (c->isInList()) {
c->remove();
nsXBLService::gClassLRUListLength--;
}
} else {
if (JS_CLIST_IS_EMPTY(&nsXBLService::gClassLRUList)) {
if (nsXBLService::gClassLRUList->isEmpty()) {
// We need to create a struct for this class.
c = new nsXBLJSClass(className, xblKey);
if (!c)
return NS_ERROR_OUT_OF_MEMORY;
} else {
// Pull the least recently used class struct off the list.
JSCList* lru = (nsXBLService::gClassLRUList).next;
JS_REMOVE_AND_INIT_LINK(lru);
c = nsXBLService::gClassLRUList->popFirst();
nsXBLService::gClassLRUListLength--;
// Remove any mapping from the old name to the class struct.
c = static_cast<nsXBLJSClass*>(lru);
nsCStringKey oldKey(c->Key());
(nsXBLService::gClassTable)->Remove(&oldKey);

View File

@ -369,7 +369,7 @@ bool nsXBLService::gAllowDataURIs = false;
nsHashtable* nsXBLService::gClassTable = nullptr;
JSCList nsXBLService::gClassLRUList = JS_INIT_STATIC_CLIST(&nsXBLService::gClassLRUList);
LinkedList<nsXBLJSClass>* nsXBLService::gClassLRUList = nullptr;
uint32_t nsXBLService::gClassLRUListLength = 0;
uint32_t nsXBLService::gClassLRUListQuota = 64;
@ -393,6 +393,7 @@ nsXBLService::Init()
nsXBLService::nsXBLService(void)
{
gClassTable = new nsHashtable();
gClassLRUList = new LinkedList<nsXBLJSClass>();
Preferences::AddBoolVarCache(&gAllowDataURIs, "layout.debug.enable_data_xbl");
}
@ -406,6 +407,8 @@ nsXBLService::~nsXBLService(void)
// created for bindings will be deleted when those objects are finalized
// (and not put on gClassLRUList, because length >= quota).
gClassLRUListLength = gClassLRUListQuota = 0;
delete gClassLRUList;
gClassLRUList = nullptr;
// At this point, the only hash table entries should be for referenced
// XBL class structs held by unfinalized JS binding objects.
@ -642,11 +645,8 @@ nsXBLService::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar
nsresult
nsXBLService::FlushMemory()
{
while (!JS_CLIST_IS_EMPTY(&gClassLRUList)) {
JSCList* lru = gClassLRUList.next;
nsXBLJSClass* c = static_cast<nsXBLJSClass*>(lru);
JS_REMOVE_AND_INIT_LINK(lru);
while (!gClassLRUList->isEmpty()) {
nsXBLJSClass* c = gClassLRUList->popFirst();
delete c;
gClassLRUListLength--;
}

View File

@ -8,15 +8,16 @@
#ifndef nsXBLService_h_
#define nsXBLService_h_
#include "mozilla/LinkedList.h"
#include "nsString.h"
#include "nsIObserver.h"
#include "nsWeakReference.h"
#include "jsapi.h" // nsXBLJSClass derives from JSClass
#include "jsclist.h" // nsXBLJSClass derives from JSCList
#include "nsTArray.h"
class nsXBLBinding;
class nsXBLDocumentInfo;
class nsXBLJSClass;
class nsIContent;
class nsIDocument;
class nsString;
@ -124,7 +125,8 @@ public:
static nsHashtable* gClassTable; // A table of nsXBLJSClass objects.
static JSCList gClassLRUList; // LRU list of cached classes.
static mozilla::LinkedList<nsXBLJSClass>* gClassLRUList;
// LRU list of cached classes.
static uint32_t gClassLRUListLength; // Number of classes on LRU list.
static uint32_t gClassLRUListQuota; // Quota on class LRU list.
static bool gAllowDataURIs; // Whether we should allow data
@ -132,7 +134,8 @@ public:
// testing.
};
class nsXBLJSClass : public JSCList, public JSClass
class nsXBLJSClass : public mozilla::LinkedListElement<nsXBLJSClass>
, public JSClass
{
private:
nsrefcnt mRefCnt;