Bug 785096 - part1: Moving dom string cache from XPCCallContext to XPCJSRuntime. r=bz

This commit is contained in:
Gabor Krizsanits 2012-09-20 15:01:37 +02:00
parent 1fb64b56b6
commit 7ff94f298b
3 changed files with 93 additions and 94 deletions

View File

@ -324,57 +324,10 @@ XPCCallContext::~XPCCallContext()
}
}
#ifdef DEBUG
for (uint32_t i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i) {
NS_ASSERTION(!mScratchStrings[i].mInUse, "Uh, string wrapper still in use!");
}
#endif
if (shouldReleaseXPC && mXPC)
NS_RELEASE(mXPC);
}
XPCReadableJSStringWrapper *
XPCCallContext::NewStringWrapper(const PRUnichar *str, uint32_t len)
{
for (uint32_t i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i) {
StringWrapperEntry& ent = mScratchStrings[i];
if (!ent.mInUse) {
ent.mInUse = true;
// Construct the string using placement new.
return new (ent.mString.addr()) XPCReadableJSStringWrapper(str, len);
}
}
// All our internal string wrappers are used, allocate a new string.
return new XPCReadableJSStringWrapper(str, len);
}
void
XPCCallContext::DeleteString(nsAString *string)
{
for (uint32_t i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i) {
StringWrapperEntry& ent = mScratchStrings[i];
if (string == ent.mString.addr()) {
// One of our internal strings is no longer in use, mark
// it as such and destroy the string.
ent.mInUse = false;
ent.mString.addr()->~XPCReadableJSStringWrapper();
return;
}
}
// We're done with a string that's not one of our internal
// strings, delete it.
delete string;
}
/* readonly attribute nsISupports Callee; */
NS_IMETHODIMP
XPCCallContext::GetCallee(nsISupports * *aCallee)

View File

@ -996,6 +996,47 @@ XPCJSRuntime::SizeOfIncludingThis(nsMallocSizeOfFun mallocSizeOf)
return n;
}
XPCReadableJSStringWrapper *
XPCJSRuntime::NewStringWrapper(const PRUnichar *str, uint32_t len)
{
for (uint32_t i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i) {
StringWrapperEntry& ent = mScratchStrings[i];
if (!ent.mInUse) {
ent.mInUse = true;
// Construct the string using placement new.
return new (ent.mString.addr()) XPCReadableJSStringWrapper(str, len);
}
}
// All our internal string wrappers are used, allocate a new string.
return new XPCReadableJSStringWrapper(str, len);
}
void
XPCJSRuntime::DeleteString(nsAString *string)
{
for (uint32_t i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i) {
StringWrapperEntry& ent = mScratchStrings[i];
if (string == ent.mString.addr()) {
// One of our internal strings is no longer in use, mark
// it as such and destroy the string.
ent.mInUse = false;
ent.mString.addr()->~XPCReadableJSStringWrapper();
return;
}
}
// We're done with a string that's not one of our internal
// strings, delete it.
delete string;
}
/***************************************************************************/
#ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN
@ -1193,6 +1234,12 @@ XPCJSRuntime::~XPCJSRuntime()
fprintf(stderr, "nJRSI: destroyed runtime %p\n", (void *)mJSRuntime);
#endif
}
#ifdef DEBUG
for (uint32_t i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i) {
NS_ASSERTION(!mScratchStrings[i].mInUse, "Uh, string wrapper still in use!");
}
#endif
}
static void

View File

@ -631,6 +631,33 @@ private:
/***************************************************************************/
// class to export a JSString as an const nsAString, no refcounting :(
class XPCReadableJSStringWrapper : public nsDependentString
{
public:
typedef nsDependentString::char_traits char_traits;
XPCReadableJSStringWrapper(const PRUnichar *chars, size_t length) :
nsDependentString(chars, length)
{ }
XPCReadableJSStringWrapper() :
nsDependentString(char_traits::sEmptyBuffer, char_traits::sEmptyBuffer)
{ SetIsVoid(true); }
JSBool init(JSContext* aContext, JSString* str)
{
size_t length;
const jschar* chars = JS_GetStringCharsZAndLength(aContext, str, &length);
if (!chars)
return false;
NS_ASSERTION(IsEmpty(), "init() on initialized string");
new(static_cast<nsDependentString *>(this)) nsDependentString(chars, length);
return true;
}
};
// In the current xpconnect system there can only be one XPCJSRuntime.
// So, xpconnect can only be used on one JSRuntime within the process.
@ -823,6 +850,8 @@ public:
return false;
}
XPCReadableJSStringWrapper *NewStringWrapper(const PRUnichar *str, uint32_t len);
void DeleteString(nsAString *string);
#ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN
void DEBUG_AddWrappedNative(nsIXPConnectWrappedNative* wrapper)
@ -918,6 +947,23 @@ private:
nsCOMPtr<nsIExceptionManager> mExceptionManager;
bool mExceptionManagerNotAvailable;
#define XPCCCX_STRING_CACHE_SIZE 2
// String wrapper entry, holds a string, and a boolean that tells
// whether the string is in use or not.
//
// NB: The string is not stored by value so that we avoid the cost of
// construction/destruction.
struct StringWrapperEntry
{
StringWrapperEntry() : mInUse(false) { }
js::AlignedStorage2<XPCReadableJSStringWrapper> mString;
bool mInUse;
};
StringWrapperEntry mScratchStrings[XPCCCX_STRING_CACHE_SIZE];
friend class AutoLockWatchdog;
friend class XPCIncrementalReleaseRunnable;
};
@ -1044,33 +1090,6 @@ private:
#define NATIVE_CALLER XPCContext::LANG_NATIVE
#define JS_CALLER XPCContext::LANG_JS
// class to export a JSString as an const nsAString, no refcounting :(
class XPCReadableJSStringWrapper : public nsDependentString
{
public:
typedef nsDependentString::char_traits char_traits;
XPCReadableJSStringWrapper(const PRUnichar *chars, size_t length) :
nsDependentString(chars, length)
{ }
XPCReadableJSStringWrapper() :
nsDependentString(char_traits::sEmptyBuffer, char_traits::sEmptyBuffer)
{ SetIsVoid(true); }
JSBool init(JSContext* aContext, JSString* str)
{
size_t length;
const jschar* chars = JS_GetStringCharsZAndLength(aContext, str, &length);
if (!chars)
return false;
NS_ASSERTION(IsEmpty(), "init() on initialized string");
new(static_cast<nsDependentString *>(this)) nsDependentString(chars, length);
return true;
}
};
// No virtuals
// XPCCallContext is ALWAYS declared as a local variable in some function;
// i.e. instance lifetime is always controled by some C++ function returning.
@ -1181,9 +1200,6 @@ public:
operator JSContext*() const {return GetJSContext();}
XPCReadableJSStringWrapper *NewStringWrapper(const PRUnichar *str, uint32_t len);
void DeleteString(nsAString *string);
private:
// no copy ctor or assignment allowed
@ -1271,23 +1287,6 @@ private:
jsval* mRetVal;
uint16_t mMethodIndex;
#define XPCCCX_STRING_CACHE_SIZE 2
// String wrapper entry, holds a string, and a boolean that tells
// whether the string is in use or not.
//
// NB: The string is not stored by value so that we avoid the cost of
// construction/destruction.
struct StringWrapperEntry
{
StringWrapperEntry() : mInUse(false) { }
js::AlignedStorage2<XPCReadableJSStringWrapper> mString;
bool mInUse;
};
StringWrapperEntry mScratchStrings[XPCCCX_STRING_CACHE_SIZE];
};
class XPCLazyCallContext