Bug 634594 - Ensure XPCCallContext string cache is aligned (r=mrbkap,a=pavlov)

This commit is contained in:
Luke Wagner 2011-02-16 16:43:15 -08:00
Родитель 1e706f35e0
Коммит bef0e932ca
2 изменённых файлов: 15 добавлений и 46 удалений

Просмотреть файл

@ -98,18 +98,6 @@ XPCCallContext::Init(XPCContext::LangType callerLanguage,
jsval *argv, jsval *argv,
jsval *rval) jsval *rval)
{ {
// Mark our internal string wrappers as not used. Make sure we do
// this before any early returns, as the destructor will assert
// based on this.
StringWrapperEntry *se =
reinterpret_cast<StringWrapperEntry*>(&mStringWrapperData);
PRUint32 i;
for(i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i)
{
se[i].mInUse = PR_FALSE;
}
if(!mXPC) if(!mXPC)
return; return;
@ -424,15 +412,9 @@ XPCCallContext::~XPCCallContext()
} }
#ifdef DEBUG #ifdef DEBUG
for(PRUint32 i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i)
{ {
StringWrapperEntry *se = NS_ASSERTION(!mScratchStrings[i].mInUse, "Uh, string wrapper still in use!");
reinterpret_cast<StringWrapperEntry*>(&mStringWrapperData);
PRUint32 i;
for(i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i)
{
NS_ASSERTION(!se[i].mInUse, "Uh, string wrapper still in use!");
}
} }
#endif #endif
@ -443,13 +425,9 @@ XPCCallContext::~XPCCallContext()
XPCReadableJSStringWrapper * XPCReadableJSStringWrapper *
XPCCallContext::NewStringWrapper(const PRUnichar *str, PRUint32 len) XPCCallContext::NewStringWrapper(const PRUnichar *str, PRUint32 len)
{ {
StringWrapperEntry *se = for(PRUint32 i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i)
reinterpret_cast<StringWrapperEntry*>(&mStringWrapperData);
PRUint32 i;
for(i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i)
{ {
StringWrapperEntry& ent = se[i]; StringWrapperEntry& ent = mScratchStrings[i];
if(!ent.mInUse) if(!ent.mInUse)
{ {
@ -457,7 +435,7 @@ XPCCallContext::NewStringWrapper(const PRUnichar *str, PRUint32 len)
// Construct the string using placement new. // Construct the string using placement new.
return new (&ent.mString) XPCReadableJSStringWrapper(str, len); return new (ent.mString.addr()) XPCReadableJSStringWrapper(str, len);
} }
} }
@ -469,20 +447,16 @@ XPCCallContext::NewStringWrapper(const PRUnichar *str, PRUint32 len)
void void
XPCCallContext::DeleteString(nsAString *string) XPCCallContext::DeleteString(nsAString *string)
{ {
StringWrapperEntry *se = for(PRUint32 i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i)
reinterpret_cast<StringWrapperEntry*>(&mStringWrapperData);
PRUint32 i;
for(i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i)
{ {
StringWrapperEntry& ent = se[i]; StringWrapperEntry& ent = mScratchStrings[i];
if(string == &ent.mString) if(string == ent.mString.addr())
{ {
// One of our internal strings is no longer in use, mark // One of our internal strings is no longer in use, mark
// it as such and destroy the string. // it as such and destroy the string.
ent.mInUse = PR_FALSE; ent.mInUse = PR_FALSE;
ent.mString.~XPCReadableJSStringWrapper(); ent.mString.addr()->~XPCReadableJSStringWrapper();
return; return;
} }

Просмотреть файл

@ -1254,23 +1254,18 @@ private:
// String wrapper entry, holds a string, and a boolean that tells // String wrapper entry, holds a string, and a boolean that tells
// whether the string is in use or not. // 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 struct StringWrapperEntry
{ {
StringWrapperEntry() StringWrapperEntry() : mInUse(PR_FALSE) { }
: mInUse(PR_FALSE)
{
}
XPCReadableJSStringWrapper mString; js::AlignedStorage2<XPCReadableJSStringWrapper> mString;
PRBool mInUse; PRBool mInUse;
}; };
// Reserve space for XPCCCX_STRING_CACHE_SIZE string wrapper StringWrapperEntry mScratchStrings[XPCCCX_STRING_CACHE_SIZE];
// entries for use on demand. It's important to not make this be
// string class members since we don't want to pay the cost of
// calling the constructors and destructors when the strings
// aren't being used.
char mStringWrapperData[sizeof(StringWrapperEntry) * XPCCCX_STRING_CACHE_SIZE];
}; };
class XPCLazyCallContext class XPCLazyCallContext