mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Somewhat reduce the amount of memory an nsPrincipal allocates in the common case. Bug 397733, r+sr+a=jst
This commit is contained in:
parent
d6e8ce696e
commit
e252fc2b15
@ -41,11 +41,13 @@
|
||||
#include "jsapi.h"
|
||||
#include "nsIPrincipal.h"
|
||||
|
||||
class nsCString;
|
||||
|
||||
struct nsJSPrincipals : JSPrincipals
|
||||
{
|
||||
static nsresult Startup();
|
||||
nsJSPrincipals();
|
||||
nsresult Init(nsIPrincipal* aPrincipal, const char *aCodebase);
|
||||
nsresult Init(nsIPrincipal* aPrincipal, const nsCString& aCodebase);
|
||||
~nsJSPrincipals(void);
|
||||
|
||||
nsIPrincipal *nsIPrincipalPtr; // [WEAK] it owns us.
|
||||
|
@ -103,7 +103,7 @@ public:
|
||||
protected:
|
||||
nsJSPrincipals mJSPrincipals;
|
||||
nsTArray< nsAutoPtr<nsHashtable> > mAnnotations;
|
||||
nsHashtable mCapabilities;
|
||||
nsHashtable* mCapabilities;
|
||||
nsCString mPrefName;
|
||||
static PRInt32 sCapabilitiesOrdinal;
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "nsIJSRuntimeService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsStringBuffer.h"
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(void *)
|
||||
nsGetPrincipalArray(JSContext *cx, JSPrincipals *prin)
|
||||
@ -198,7 +199,7 @@ nsJSPrincipals::nsJSPrincipals()
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJSPrincipals::Init(nsIPrincipal *aPrincipal, const char *aCodebase)
|
||||
nsJSPrincipals::Init(nsIPrincipal *aPrincipal, const nsCString& aCodebase)
|
||||
{
|
||||
if (nsIPrincipalPtr) {
|
||||
NS_ERROR("Init called twice!");
|
||||
@ -206,15 +207,30 @@ nsJSPrincipals::Init(nsIPrincipal *aPrincipal, const char *aCodebase)
|
||||
}
|
||||
|
||||
nsIPrincipalPtr = aPrincipal;
|
||||
codebase = PL_strdup(aCodebase);
|
||||
if (!codebase)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
nsStringBuffer* buf = nsStringBuffer::FromString(aCodebase);
|
||||
char* data;
|
||||
if (buf) {
|
||||
buf->AddRef();
|
||||
data = static_cast<char*>(buf->Data());
|
||||
} else {
|
||||
PRUint32 len = aCodebase.Length();
|
||||
buf = nsStringBuffer::Alloc(len + 1); // addrefs
|
||||
if (!buf) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
data = static_cast<char*>(buf->Data());
|
||||
memcpy(data, aCodebase.get(), len);
|
||||
data[len] = '\0';
|
||||
}
|
||||
|
||||
codebase = data;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsJSPrincipals::~nsJSPrincipals()
|
||||
{
|
||||
if (codebase)
|
||||
PL_strfree(codebase);
|
||||
if (codebase) {
|
||||
nsStringBuffer::FromData(codebase)->Release();
|
||||
}
|
||||
}
|
||||
|
@ -90,6 +90,8 @@ nsNullPrincipal::~nsNullPrincipal()
|
||||
{
|
||||
}
|
||||
|
||||
#define NS_NULLPRINCIPAL_PREFIX NS_NULLPRINCIPAL_SCHEME ":"
|
||||
|
||||
nsresult
|
||||
nsNullPrincipal::Init()
|
||||
{
|
||||
@ -106,15 +108,21 @@ nsNullPrincipal::Init()
|
||||
char* chars = id.ToString();
|
||||
NS_ENSURE_TRUE(chars, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsCAutoString str(NS_NULLPRINCIPAL_SCHEME ":");
|
||||
PRUint32 prefixLen = str.Length();
|
||||
PRUint32 suffixLen = strlen(chars);
|
||||
PRUint32 prefixLen = NS_ARRAY_LENGTH(NS_NULLPRINCIPAL_PREFIX) - 1;
|
||||
|
||||
// Use an nsCString so we only do the allocation once here and then share
|
||||
// with nsJSPrincipals
|
||||
nsCString str;
|
||||
str.SetCapacity(prefixLen + suffixLen);
|
||||
|
||||
str.Append(NS_NULLPRINCIPAL_PREFIX);
|
||||
str.Append(chars);
|
||||
|
||||
PR_Free(chars);
|
||||
|
||||
if (str.Length() != prefixLen + suffixLen) {
|
||||
NS_WARNING("Out of memory allocating null-principal URI");
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@ -129,7 +137,7 @@ nsNullPrincipal::Init()
|
||||
|
||||
NS_TryToSetImmutable(mURI);
|
||||
|
||||
return mJSPrincipals.Init(this, str.get());
|
||||
return mJSPrincipals.Init(this, str);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,7 +103,7 @@ nsPrincipal::Release()
|
||||
}
|
||||
|
||||
nsPrincipal::nsPrincipal()
|
||||
: mCapabilities(7),
|
||||
: mCapabilities(nsnull),
|
||||
mSecurityPolicy(nsnull),
|
||||
mTrusted(PR_FALSE),
|
||||
mInitialized(PR_FALSE),
|
||||
@ -134,14 +134,14 @@ nsPrincipal::Init(const nsACString& aCertFingerprint,
|
||||
if (!aCertFingerprint.IsEmpty()) {
|
||||
rv = SetCertificate(aCertFingerprint, aSubjectName, aPrettyName, aCert);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = mJSPrincipals.Init(this, mCert->fingerprint.get());
|
||||
rv = mJSPrincipals.Init(this, mCert->fingerprint);
|
||||
}
|
||||
}
|
||||
else {
|
||||
nsCAutoString spec;
|
||||
rv = mCodebase->GetSpec(spec);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = mJSPrincipals.Init(this, spec.get());
|
||||
rv = mJSPrincipals.Init(this, spec);
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,6 +153,7 @@ nsPrincipal::Init(const nsACString& aCertFingerprint,
|
||||
nsPrincipal::~nsPrincipal(void)
|
||||
{
|
||||
SetSecurityPolicy(nsnull);
|
||||
delete mCapabilities;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -309,11 +310,13 @@ NS_IMETHODIMP
|
||||
nsPrincipal::CanEnableCapability(const char *capability, PRInt16 *result)
|
||||
{
|
||||
// If this principal is marked invalid, can't enable any capabilities
|
||||
nsCStringKey invalidKey(sInvalid);
|
||||
if (mCapabilities.Exists(&invalidKey)) {
|
||||
*result = nsIPrincipal::ENABLE_DENIED;
|
||||
if (mCapabilities) {
|
||||
nsCStringKey invalidKey(sInvalid);
|
||||
if (mCapabilities->Exists(&invalidKey)) {
|
||||
*result = nsIPrincipal::ENABLE_DENIED;
|
||||
|
||||
return NS_OK;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mCert && !mTrusted) {
|
||||
@ -353,7 +356,8 @@ nsPrincipal::CanEnableCapability(const char *capability, PRInt16 *result)
|
||||
PRInt32 len = space ? space - start : strlen(start);
|
||||
nsCAutoString capString(start, len);
|
||||
nsCStringKey key(capString);
|
||||
PRInt16 value = (PRInt16)NS_PTR_TO_INT32(mCapabilities.Get(&key));
|
||||
PRInt16 value =
|
||||
mCapabilities ? (PRInt16)NS_PTR_TO_INT32(mCapabilities->Get(&key)) : 0;
|
||||
if (value == 0 || value == nsIPrincipal::ENABLE_UNKNOWN) {
|
||||
// We don't know whether we can enable this capability,
|
||||
// so we should ask the user.
|
||||
@ -379,14 +383,18 @@ nsPrincipal::SetCanEnableCapability(const char *capability,
|
||||
PRInt16 canEnable)
|
||||
{
|
||||
// If this principal is marked invalid, can't enable any capabilities
|
||||
if (!mCapabilities) {
|
||||
mCapabilities = new nsHashtable(7); // XXXbz gets bumped up to 16 anyway
|
||||
NS_ENSURE_TRUE(mCapabilities, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
nsCStringKey invalidKey(sInvalid);
|
||||
if (mCapabilities.Exists(&invalidKey)) {
|
||||
if (mCapabilities->Exists(&invalidKey)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (PL_strcmp(capability, sInvalid) == 0) {
|
||||
mCapabilities.Reset();
|
||||
mCapabilities->Reset();
|
||||
}
|
||||
|
||||
const char *start = capability;
|
||||
@ -395,7 +403,7 @@ nsPrincipal::SetCanEnableCapability(const char *capability,
|
||||
int len = space ? space - start : strlen(start);
|
||||
nsCAutoString capString(start, len);
|
||||
nsCStringKey key(capString);
|
||||
mCapabilities.Put(&key, NS_INT32_TO_PTR(canEnable));
|
||||
mCapabilities->Put(&key, NS_INT32_TO_PTR(canEnable));
|
||||
if (!space) {
|
||||
break;
|
||||
}
|
||||
@ -667,7 +675,7 @@ nsPrincipal::InitFromPersistent(const char* aPrefName,
|
||||
PRBool aIsCert,
|
||||
PRBool aTrusted)
|
||||
{
|
||||
NS_PRECONDITION(mCapabilities.Count() == 0,
|
||||
NS_PRECONDITION(!mCapabilities || mCapabilities->Count() == 0,
|
||||
"mCapabilities was already initialized?");
|
||||
NS_PRECONDITION(mAnnotations.Length() == 0,
|
||||
"mAnnotations was already initialized?");
|
||||
@ -699,7 +707,7 @@ nsPrincipal::InitFromPersistent(const char* aPrefName,
|
||||
mOrigin = nsnull;
|
||||
}
|
||||
|
||||
rv = mJSPrincipals.Init(this, aToken.get());
|
||||
rv = mJSPrincipals.Init(this, aToken);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
//-- Save the preference name
|
||||
@ -836,10 +844,12 @@ nsPrincipal::GetPreferences(char** aPrefName, char** aID,
|
||||
|
||||
//-- Capabilities
|
||||
nsCAutoString grantedListStr, deniedListStr;
|
||||
CapabilityList capList = CapabilityList();
|
||||
capList.granted = &grantedListStr;
|
||||
capList.denied = &deniedListStr;
|
||||
mCapabilities.Enumerate(AppendCapability, (void*)&capList);
|
||||
if (mCapabilities) {
|
||||
CapabilityList capList = CapabilityList();
|
||||
capList.granted = &grantedListStr;
|
||||
capList.denied = &deniedListStr;
|
||||
mCapabilities->Enumerate(AppendCapability, (void*)&capList);
|
||||
}
|
||||
|
||||
if (!grantedListStr.IsEmpty()) {
|
||||
grantedListStr.Truncate(grantedListStr.Length() - 1);
|
||||
@ -910,12 +920,9 @@ nsPrincipal::Read(nsIObjectInputStream* aStream)
|
||||
PRBool hasCapabilities;
|
||||
nsresult rv = aStream->ReadBoolean(&hasCapabilities);
|
||||
if (NS_SUCCEEDED(rv) && hasCapabilities) {
|
||||
// We want to use one of the nsHashtable constructors, but don't want to
|
||||
// generally have mCapabilities be a pointer... and nsHashtable has no
|
||||
// reasonable copy-constructor. Placement-new to the rescue!
|
||||
mCapabilities.~nsHashtable();
|
||||
new (&mCapabilities) nsHashtable(aStream, ReadAnnotationEntry,
|
||||
FreeAnnotationEntry, &rv);
|
||||
mCapabilities = new nsHashtable(aStream, ReadAnnotationEntry,
|
||||
FreeAnnotationEntry, &rv);
|
||||
NS_ENSURE_TRUE(mCapabilities, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
@ -1008,10 +1015,10 @@ nsPrincipal::Write(nsIObjectOutputStream* aStream)
|
||||
// mAnnotations is transient data associated to specific JS stack frames. We
|
||||
// don't want to serialize that.
|
||||
|
||||
PRBool hasCapabilities = (mCapabilities.Count() > 0);
|
||||
PRBool hasCapabilities = (mCapabilities && mCapabilities->Count() > 0);
|
||||
nsresult rv = aStream->WriteBoolean(hasCapabilities);
|
||||
if (NS_SUCCEEDED(rv) && hasCapabilities) {
|
||||
rv = mCapabilities.Write(aStream, WriteScalarValue);
|
||||
rv = mCapabilities->Write(aStream, WriteScalarValue);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -280,10 +280,20 @@ nsSystemPrincipal::nsSystemPrincipal()
|
||||
{
|
||||
}
|
||||
|
||||
#define SYSTEM_PRINCIPAL_SPEC "[System Principal]"
|
||||
|
||||
nsresult
|
||||
nsSystemPrincipal::Init()
|
||||
{
|
||||
return mJSPrincipals.Init(this, "[System Principal]");
|
||||
// Use an nsCString so we only do the allocation once here and then
|
||||
// share with nsJSPrincipals
|
||||
nsCString str(SYSTEM_PRINCIPAL_SPEC);
|
||||
if (!str.EqualsLiteral(SYSTEM_PRINCIPAL_SPEC)) {
|
||||
NS_WARNING("Out of memory initializing system principal");
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return mJSPrincipals.Init(this, str);
|
||||
}
|
||||
|
||||
nsSystemPrincipal::~nsSystemPrincipal(void)
|
||||
|
Loading…
Reference in New Issue
Block a user