reduce mallocs when creating a new nsCookie, by storing member strings contiguously with the cookie object.

b=223289, r=caillon, sr=darin.
This commit is contained in:
dwitte%stanford.edu 2003-11-18 12:30:23 +00:00
Родитель cfa8f9884b
Коммит 5a51d4d50d
3 изменённых файлов: 128 добавлений и 101 удалений

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

@ -37,15 +37,15 @@
* ***** END LICENSE BLOCK ***** */
#include "nsCookie.h"
#include <stdlib.h>
/******************************************************************************
* nsCookie:
* string helper impl
******************************************************************************/
// allocate contiguous storage and copy aSource strings,
// copy aSource strings into contiguous storage provided in aDest1,
// providing terminating nulls for each destination string.
// XXX consider arena allocation here
static inline void
StrBlockCopy(const nsACString &aSource1,
const nsACString &aSource2,
@ -57,60 +57,56 @@ StrBlockCopy(const nsACString &aSource1,
char *&aDest4,
char *&aDestEnd)
{
// find the required buffer size, adding 4 for the terminating nulls
const PRUint32 totalLength = aSource1.Length() + aSource2.Length() + aSource3.Length() + aSource4.Length() + 4;
char *toBegin = aDest1;
nsACString::const_iterator fromBegin, fromEnd;
char *toBegin = NS_STATIC_CAST(char*, nsMemory::Alloc(totalLength * sizeof(char)));
NS_ASSERTION(toBegin, "out of memory allocating for nsCookie!");
aDest1 = toBegin;
if (toBegin) {
nsACString::const_iterator fromBegin, fromEnd;
*copy_string(aSource1.BeginReading(fromBegin), aSource1.EndReading(fromEnd), toBegin) = char(0);
aDest2 = ++toBegin;
*copy_string(aSource2.BeginReading(fromBegin), aSource2.EndReading(fromEnd), toBegin) = char(0);
aDest3 = ++toBegin;
*copy_string(aSource3.BeginReading(fromBegin), aSource3.EndReading(fromEnd), toBegin) = char(0);
aDest4 = ++toBegin;
*copy_string(aSource4.BeginReading(fromBegin), aSource4.EndReading(fromEnd), toBegin) = char(0);
aDestEnd = toBegin;
}
*copy_string(aSource1.BeginReading(fromBegin), aSource1.EndReading(fromEnd), toBegin) = char(0);
aDest2 = ++toBegin;
*copy_string(aSource2.BeginReading(fromBegin), aSource2.EndReading(fromEnd), toBegin) = char(0);
aDest3 = ++toBegin;
*copy_string(aSource3.BeginReading(fromBegin), aSource3.EndReading(fromEnd), toBegin) = char(0);
aDest4 = ++toBegin;
*copy_string(aSource4.BeginReading(fromBegin), aSource4.EndReading(fromEnd), toBegin) = char(0);
aDestEnd = toBegin;
}
/******************************************************************************
* nsCookie:
* ctor/dtor
* creation helper
******************************************************************************/
nsCookie::nsCookie(const nsACString &aName,
const nsACString &aValue,
const nsACString &aHost,
const nsACString &aPath,
nsInt64 aExpiry,
nsInt64 aLastAccessed,
PRBool aIsSession,
PRBool aIsSecure,
nsCookieStatus aStatus,
nsCookiePolicy aPolicy)
: mNext(nsnull)
, mExpiry(aExpiry)
, mLastAccessed(aLastAccessed)
, mRefCnt(0)
, mIsSession(aIsSession != PR_FALSE)
, mIsSecure(aIsSecure != PR_FALSE)
, mStatus(aStatus)
, mPolicy(aPolicy)
nsCookie *
nsCookie::Create(const nsACString &aName,
const nsACString &aValue,
const nsACString &aHost,
const nsACString &aPath,
nsInt64 aExpiry,
nsInt64 aLastAccessed,
PRBool aIsSession,
PRBool aIsSecure,
nsCookieStatus aStatus,
nsCookiePolicy aPolicy)
{
// allocate a new (contiguous) string, and assign string members
StrBlockCopy(aName, aValue, aHost, aPath,
mName, mValue, mHost, mPath, mEnd);
}
// find the required string buffer size, adding 4 for the terminating nulls
const PRUint32 stringLength = aName.Length() + aValue.Length() +
aHost.Length() + aPath.Length() + 4;
nsCookie::~nsCookie()
{
if (mName)
nsMemory::Free(mName);
// allocate contiguous space for the nsCookie and its strings -
// we store the strings in-line with the nsCookie to save allocations
void *place = ::operator new(sizeof(nsCookie) + stringLength);
if (!place)
return nsnull;
// assign string members
char *name, *value, *host, *path, *end;
name = NS_STATIC_CAST(char *, place) + sizeof(nsCookie);
StrBlockCopy(aName, aValue, aHost, aPath,
name, value, host, path, end);
// construct the cookie. placement new, oh yeah!
return new (place) nsCookie(name, value, host, path, end,
aExpiry, aLastAccessed, aIsSession,
aIsSecure, aStatus, aPolicy);
}
/******************************************************************************
@ -144,4 +140,4 @@ nsCookie::GetExpires(PRUint64 *aExpires)
return NS_OK;
}
NS_IMPL_ISUPPORTS2(nsCookie, nsICookie, nsICookie2)
NS_IMPL_ISUPPORTS2(nsCookie, nsICookie2, nsICookie)

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

@ -42,7 +42,6 @@
#include "nsICookie.h"
#include "nsICookie2.h"
#include "nsString.h"
#include "nsMemory.h"
#include "nsInt64.h"
/**
@ -58,7 +57,7 @@
class nsCookie : public nsICookie2
{
// this is required because we use a bitfield refcount member.
// break up the NS_DECL_ISUPPORTS macro, since we use a bitfield refcount member
public:
NS_DECL_ISUPPORTS_INHERITED
protected:
@ -69,18 +68,50 @@ class nsCookie : public nsICookie2
NS_DECL_NSICOOKIE
NS_DECL_NSICOOKIE2
nsCookie(const nsACString &aName,
const nsACString &aValue,
const nsACString &aHost,
const nsACString &aPath,
nsInt64 aExpiry,
nsInt64 aLastAccessed,
PRBool aIsSession,
PRBool aIsSecure,
nsCookieStatus aStatus,
nsCookiePolicy aPolicy);
private:
// for internal use only. see nsCookie::Create().
nsCookie(const char *aName,
const char *aValue,
const char *aHost,
const char *aPath,
const char *aEnd,
nsInt64 aExpiry,
nsInt64 aLastAccessed,
PRBool aIsSession,
PRBool aIsSecure,
nsCookieStatus aStatus,
nsCookiePolicy aPolicy)
: mNext(nsnull)
, mName(aName)
, mValue(aValue)
, mHost(aHost)
, mPath(aPath)
, mEnd(aEnd)
, mExpiry(aExpiry)
, mLastAccessed(aLastAccessed)
, mRefCnt(0)
, mIsSession(aIsSession != PR_FALSE)
, mIsSecure(aIsSecure != PR_FALSE)
, mStatus(aStatus)
, mPolicy(aPolicy)
{
}
virtual ~nsCookie();
public:
// public helper to create an nsCookie object. use |operator delete|
// to destroy an object created by this method.
static nsCookie * Create(const nsACString &aName,
const nsACString &aValue,
const nsACString &aHost,
const nsACString &aPath,
nsInt64 aExpiry,
nsInt64 aLastAccessed,
PRBool aIsSession,
PRBool aIsSecure,
nsCookieStatus aStatus,
nsCookiePolicy aPolicy);
virtual ~nsCookie() {};
// fast (inline, non-xpcom) getters
inline const nsDependentCString Name() const { return nsDependentCString(mName, mValue - 1); }
@ -111,19 +142,19 @@ class nsCookie : public nsICookie2
// store a terminating null for each string, so we can hand them
// out as nsAFlatCStrings.
nsCookie *mNext;
char *mName;
char *mValue;
char *mHost;
char *mPath;
char *mEnd;
nsInt64 mExpiry;
nsInt64 mLastAccessed;
PRUint32 mRefCnt : 16;
PRUint32 mIsSession : 1;
PRUint32 mIsSecure : 1;
PRUint32 mStatus : 3;
PRUint32 mPolicy : 3;
nsCookie *mNext;
const char *mName;
const char *mValue;
const char *mHost;
const char *mPath;
const char *mEnd;
nsInt64 mExpiry;
nsInt64 mLastAccessed;
PRUint32 mRefCnt : 16;
PRUint32 mIsSession : 1;
PRUint32 mIsSecure : 1;
PRUint32 mStatus : 3;
PRUint32 mPolicy : 3;
};
#endif // nsCookie_h__

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

@ -834,13 +834,13 @@ nsCookieService::Add(const nsACString &aDomain,
nsInt64 currentTime = NOW_IN_SECONDS;
nsRefPtr<nsCookie> cookie =
new nsCookie(aName, aValue, aDomain, aPath,
nsInt64(aExpiry),
currentTime,
aIsSession,
aIsSecure,
nsICookie::STATUS_UNKNOWN,
nsICookie::POLICY_UNKNOWN);
nsCookie::Create(aName, aValue, aDomain, aPath,
nsInt64(aExpiry),
currentTime,
aIsSession,
aIsSecure,
nsICookie::STATUS_UNKNOWN,
nsICookie::POLICY_UNKNOWN);
if (!cookie) {
return NS_ERROR_OUT_OF_MEMORY;
}
@ -970,16 +970,16 @@ nsCookieService::Read()
// create a new nsCookie and assign the data.
newCookie =
new nsCookie(Substring(buffer, nameIndex, cookieIndex - nameIndex - 1),
Substring(buffer, cookieIndex, buffer.Length() - cookieIndex),
host,
Substring(buffer, pathIndex, secureIndex - pathIndex - 1),
nsInt64(expires),
lastAccessedCounter,
PR_FALSE,
Substring(buffer, secureIndex, expiresIndex - secureIndex - 1).Equals(kTrue),
nsICookie::STATUS_UNKNOWN,
nsICookie::POLICY_UNKNOWN);
nsCookie::Create(Substring(buffer, nameIndex, cookieIndex - nameIndex - 1),
Substring(buffer, cookieIndex, buffer.Length() - cookieIndex),
host,
Substring(buffer, pathIndex, secureIndex - pathIndex - 1),
nsInt64(expires),
lastAccessedCounter,
PR_FALSE,
Substring(buffer, secureIndex, expiresIndex - secureIndex - 1).Equals(kTrue),
nsICookie::STATUS_UNKNOWN,
nsICookie::POLICY_UNKNOWN);
if (!newCookie) {
return NS_ERROR_OUT_OF_MEMORY;
}
@ -1155,16 +1155,16 @@ nsCookieService::SetCookieInternal(nsIURI *aHostURI,
// create a new nsCookie and copy attributes
nsRefPtr<nsCookie> cookie =
new nsCookie(cookieAttributes.name,
cookieAttributes.value,
cookieAttributes.host,
cookieAttributes.path,
cookieAttributes.expiryTime,
currentTime,
cookieAttributes.isSession,
cookieAttributes.isSecure,
aStatus,
aPolicy);
nsCookie::Create(cookieAttributes.name,
cookieAttributes.value,
cookieAttributes.host,
cookieAttributes.path,
cookieAttributes.expiryTime,
currentTime,
cookieAttributes.isSession,
cookieAttributes.isSecure,
aStatus,
aPolicy);
if (!cookie) {
return newCookie;
}