bug 64696 (DOM UI events should be allocated from a recycler)
r=attinasi sr=waterson git-svn-id: svn://10.0.0.236/trunk@86808 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
f57f7ebd62
commit
0bce73b69f
@ -18,6 +18,7 @@
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Steve Clark (buster@netscape.com)
|
||||
*/
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
@ -56,7 +57,75 @@ static char* mEventNames[] = {
|
||||
"DOMAttrModified", "DOMCharacterDataModified"
|
||||
};
|
||||
|
||||
nsDOMEvent::nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent, const nsAReadableString& aEventType) {
|
||||
/* declare static class data */
|
||||
nsDOMEvent nsDOMEvent::gEventPool;
|
||||
PRBool nsDOMEvent::gEventPoolInUse=PR_FALSE;
|
||||
|
||||
#ifdef NS_DEBUG // metrics for measuring event pool use
|
||||
static PRInt32 numEvents=0;
|
||||
static PRInt32 numNewEvents=0;
|
||||
static PRInt32 numDelEvents=0;
|
||||
static PRInt32 numAllocFromPool=0;
|
||||
//#define NOISY_EVENT_LEAKS // define NOISY_EVENT_LEAKS to get metrics printed to stdout for all nsDOMEvent allocations
|
||||
#endif
|
||||
|
||||
// allocate the memory for the object from the recycler, if possible
|
||||
// otherwise, just grab it from the heap.
|
||||
void*
|
||||
nsDOMEvent::operator new(size_t aSize)
|
||||
{
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
numEvents++;
|
||||
#endif
|
||||
|
||||
void *result = nsnull;
|
||||
|
||||
if (!gEventPoolInUse) {
|
||||
#ifdef NS_DEBUG
|
||||
numAllocFromPool++;
|
||||
#endif
|
||||
result = &gEventPool;
|
||||
gEventPoolInUse = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
#ifdef NS_DEBUG
|
||||
numNewEvents++;
|
||||
#endif
|
||||
result = ::operator new(aSize);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
nsCRT::zero(result, aSize);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Overridden to prevent the global delete from being called on objects from
|
||||
// the recycler. Otherwise, just pass through to the global delete operator.
|
||||
void
|
||||
nsDOMEvent::operator delete(void* aPtr)
|
||||
{
|
||||
if (aPtr==&gEventPool) {
|
||||
gEventPoolInUse = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
#ifdef NS_DEBUG
|
||||
numDelEvents++;
|
||||
#endif
|
||||
::operator delete(aPtr);
|
||||
}
|
||||
#if defined(NS_DEBUG) && defined(NOISY_EVENT_LEAKS)
|
||||
printf("total events =%d, from pool = %d, concurrent live events = %d\n",
|
||||
numEvents, numAllocFromPool, numNewEvents-numDelEvents);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsDOMEvent::nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent, const nsAReadableString& aEventType)
|
||||
{
|
||||
mPresContext = aPresContext;
|
||||
if (mPresContext)
|
||||
NS_ADDREF(mPresContext);
|
||||
@ -123,7 +192,15 @@ nsDOMEvent::nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent, const nsAR
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsDOMEvent::~nsDOMEvent() {
|
||||
nsDOMEvent::~nsDOMEvent()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(nsDOMEvent);
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
if (mPresContext)
|
||||
{ // we were arena-allocated, prepare to recycle myself
|
||||
mPresContext->GetShell(getter_AddRefs(shell));
|
||||
}
|
||||
NS_IF_RELEASE(mPresContext);
|
||||
NS_IF_RELEASE(mTarget);
|
||||
NS_IF_RELEASE(mCurrentTarget);
|
||||
@ -592,10 +669,6 @@ NS_METHOD nsDOMEvent::GetCharCode(PRUint32* aCharCode)
|
||||
break;
|
||||
case NS_KEY_PRESS:
|
||||
*aCharCode = ((nsKeyEvent*)mEvent)->charCode;
|
||||
#if defined(NS_DEBUG) && defined(DEBUG_buster)
|
||||
if (0==*aCharCode)
|
||||
printf("GetCharCode used correctly but no valid key!\n");
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1213,6 +1286,7 @@ nsresult NS_NewDOMUIEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsEvent *aEvent)
|
||||
{
|
||||
nsDOMEvent* it = new nsDOMEvent(aPresContext, aEvent, aEventType);
|
||||
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@ -172,8 +172,32 @@ public:
|
||||
NS_IMETHOD GetCompositionReply(nsTextEventReply** aReply);
|
||||
NS_IMETHOD GetReconversionReply(nsReconversionEventReply** aReply);
|
||||
|
||||
/** Overloaded new operator. Initializes the memory to 0.
|
||||
* Relies on a recycler to perform the allocation,
|
||||
* optionally from a pool.
|
||||
*/
|
||||
void* operator new(size_t sz);
|
||||
|
||||
/** Overloaded delete operator. Relies on a recycler to either
|
||||
* recycle the object or call the global delete operator, as needed.
|
||||
*/
|
||||
void operator delete(void* aPtr);
|
||||
|
||||
protected:
|
||||
|
||||
nsDOMEvent() {}; // private constructor for pool, not for general use
|
||||
|
||||
/** event pool used as a simple recycler for objects of this class */
|
||||
static nsDOMEvent gEventPool;
|
||||
|
||||
/** bit to say whether the event pool is in use or not.
|
||||
* note that it would be trivial to make this a bitmap if we ever
|
||||
* wanted to increase the size of the pool from one. But with our
|
||||
* current usage pattern, we almost never have more than a single
|
||||
* nsDOMEvent active in memory at a time under normal circumstances.
|
||||
*/
|
||||
static PRBool gEventPoolInUse;
|
||||
|
||||
//Internal helper funcs
|
||||
nsresult GetScrollInfo(nsIScrollableView** aScrollableView, float* aP2T, float* aT2P);
|
||||
nsresult SetEventType(const nsAReadableString& aEventTypeArg);
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Steve Clark (buster@netscape.com)
|
||||
*/
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
@ -56,7 +57,75 @@ static char* mEventNames[] = {
|
||||
"DOMAttrModified", "DOMCharacterDataModified"
|
||||
};
|
||||
|
||||
nsDOMEvent::nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent, const nsAReadableString& aEventType) {
|
||||
/* declare static class data */
|
||||
nsDOMEvent nsDOMEvent::gEventPool;
|
||||
PRBool nsDOMEvent::gEventPoolInUse=PR_FALSE;
|
||||
|
||||
#ifdef NS_DEBUG // metrics for measuring event pool use
|
||||
static PRInt32 numEvents=0;
|
||||
static PRInt32 numNewEvents=0;
|
||||
static PRInt32 numDelEvents=0;
|
||||
static PRInt32 numAllocFromPool=0;
|
||||
//#define NOISY_EVENT_LEAKS // define NOISY_EVENT_LEAKS to get metrics printed to stdout for all nsDOMEvent allocations
|
||||
#endif
|
||||
|
||||
// allocate the memory for the object from the recycler, if possible
|
||||
// otherwise, just grab it from the heap.
|
||||
void*
|
||||
nsDOMEvent::operator new(size_t aSize)
|
||||
{
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
numEvents++;
|
||||
#endif
|
||||
|
||||
void *result = nsnull;
|
||||
|
||||
if (!gEventPoolInUse) {
|
||||
#ifdef NS_DEBUG
|
||||
numAllocFromPool++;
|
||||
#endif
|
||||
result = &gEventPool;
|
||||
gEventPoolInUse = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
#ifdef NS_DEBUG
|
||||
numNewEvents++;
|
||||
#endif
|
||||
result = ::operator new(aSize);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
nsCRT::zero(result, aSize);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Overridden to prevent the global delete from being called on objects from
|
||||
// the recycler. Otherwise, just pass through to the global delete operator.
|
||||
void
|
||||
nsDOMEvent::operator delete(void* aPtr)
|
||||
{
|
||||
if (aPtr==&gEventPool) {
|
||||
gEventPoolInUse = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
#ifdef NS_DEBUG
|
||||
numDelEvents++;
|
||||
#endif
|
||||
::operator delete(aPtr);
|
||||
}
|
||||
#if defined(NS_DEBUG) && defined(NOISY_EVENT_LEAKS)
|
||||
printf("total events =%d, from pool = %d, concurrent live events = %d\n",
|
||||
numEvents, numAllocFromPool, numNewEvents-numDelEvents);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsDOMEvent::nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent, const nsAReadableString& aEventType)
|
||||
{
|
||||
mPresContext = aPresContext;
|
||||
if (mPresContext)
|
||||
NS_ADDREF(mPresContext);
|
||||
@ -123,7 +192,15 @@ nsDOMEvent::nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent, const nsAR
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsDOMEvent::~nsDOMEvent() {
|
||||
nsDOMEvent::~nsDOMEvent()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(nsDOMEvent);
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
if (mPresContext)
|
||||
{ // we were arena-allocated, prepare to recycle myself
|
||||
mPresContext->GetShell(getter_AddRefs(shell));
|
||||
}
|
||||
NS_IF_RELEASE(mPresContext);
|
||||
NS_IF_RELEASE(mTarget);
|
||||
NS_IF_RELEASE(mCurrentTarget);
|
||||
@ -592,10 +669,6 @@ NS_METHOD nsDOMEvent::GetCharCode(PRUint32* aCharCode)
|
||||
break;
|
||||
case NS_KEY_PRESS:
|
||||
*aCharCode = ((nsKeyEvent*)mEvent)->charCode;
|
||||
#if defined(NS_DEBUG) && defined(DEBUG_buster)
|
||||
if (0==*aCharCode)
|
||||
printf("GetCharCode used correctly but no valid key!\n");
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1213,6 +1286,7 @@ nsresult NS_NewDOMUIEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsEvent *aEvent)
|
||||
{
|
||||
nsDOMEvent* it = new nsDOMEvent(aPresContext, aEvent, aEventType);
|
||||
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@ -172,8 +172,32 @@ public:
|
||||
NS_IMETHOD GetCompositionReply(nsTextEventReply** aReply);
|
||||
NS_IMETHOD GetReconversionReply(nsReconversionEventReply** aReply);
|
||||
|
||||
/** Overloaded new operator. Initializes the memory to 0.
|
||||
* Relies on a recycler to perform the allocation,
|
||||
* optionally from a pool.
|
||||
*/
|
||||
void* operator new(size_t sz);
|
||||
|
||||
/** Overloaded delete operator. Relies on a recycler to either
|
||||
* recycle the object or call the global delete operator, as needed.
|
||||
*/
|
||||
void operator delete(void* aPtr);
|
||||
|
||||
protected:
|
||||
|
||||
nsDOMEvent() {}; // private constructor for pool, not for general use
|
||||
|
||||
/** event pool used as a simple recycler for objects of this class */
|
||||
static nsDOMEvent gEventPool;
|
||||
|
||||
/** bit to say whether the event pool is in use or not.
|
||||
* note that it would be trivial to make this a bitmap if we ever
|
||||
* wanted to increase the size of the pool from one. But with our
|
||||
* current usage pattern, we almost never have more than a single
|
||||
* nsDOMEvent active in memory at a time under normal circumstances.
|
||||
*/
|
||||
static PRBool gEventPoolInUse;
|
||||
|
||||
//Internal helper funcs
|
||||
nsresult GetScrollInfo(nsIScrollableView** aScrollableView, float* aP2T, float* aT2P);
|
||||
nsresult SetEventType(const nsAReadableString& aEventTypeArg);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user