Ensure correct alignment for nsCSSValue objects inside nsCSSValue::Array. (Bug 476345) r+sr=bzbarsky

This commit is contained in:
L. David Baron 2009-02-04 21:15:52 -08:00
parent a06171d763
commit 2d053d16f1

View File

@ -327,104 +327,6 @@ public:
// failure.
static nsStringBuffer* BufferFromString(const nsString& aValue);
struct Array {
// return |Array| with reference count of zero
static Array* Create(PRUint16 aItemCount) {
return new (aItemCount) Array(aItemCount);
}
nsCSSValue& operator[](PRUint16 aIndex) {
NS_ASSERTION(aIndex < mCount, "out of range");
return *(First() + aIndex);
}
const nsCSSValue& operator[](PRUint16 aIndex) const {
NS_ASSERTION(aIndex < mCount, "out of range");
return *(First() + aIndex);
}
nsCSSValue& Item(PRUint16 aIndex) { return (*this)[aIndex]; }
const nsCSSValue& Item(PRUint16 aIndex) const { return (*this)[aIndex]; }
PRUint16 Count() const { return mCount; }
PRBool operator==(const Array& aOther) const
{
if (mCount != aOther.mCount)
return PR_FALSE;
for (PRUint16 i = 0; i < mCount; ++i)
if ((*this)[i] != aOther[i])
return PR_FALSE;
return PR_TRUE;
}
void AddRef() {
if (mRefCnt == PR_UINT16_MAX) {
NS_WARNING("refcount overflow, leaking nsCSSValue::Array");
return;
}
++mRefCnt;
NS_LOG_ADDREF(this, mRefCnt, "nsCSSValue::Array", sizeof(*this));
}
void Release() {
if (mRefCnt == PR_UINT16_MAX) {
NS_WARNING("refcount overflow, leaking nsCSSValue::Array");
return;
}
--mRefCnt;
NS_LOG_RELEASE(this, mRefCnt, "nsCSSValue::Array");
if (mRefCnt == 0)
delete this;
}
private:
PRUint16 mRefCnt;
PRUint16 mCount;
void* operator new(size_t aSelfSize, PRUint16 aItemCount) CPP_THROW_NEW {
return ::operator new(aSelfSize + sizeof(nsCSSValue)*aItemCount);
}
void operator delete(void* aPtr) { ::operator delete(aPtr); }
nsCSSValue* First() {
return (nsCSSValue*) (((char*)this) + sizeof(*this));
}
const nsCSSValue* First() const {
return (const nsCSSValue*) (((const char*)this) + sizeof(*this));
}
#define CSSVALUE_LIST_FOR_VALUES(var) \
for (nsCSSValue *var = First(), *var##_end = var + mCount; \
var != var##_end; ++var)
Array(PRUint16 aItemCount)
: mRefCnt(0)
, mCount(aItemCount)
{
MOZ_COUNT_CTOR(nsCSSValue::Array);
CSSVALUE_LIST_FOR_VALUES(val) {
new (val) nsCSSValue();
}
}
~Array()
{
MOZ_COUNT_DTOR(nsCSSValue::Array);
CSSVALUE_LIST_FOR_VALUES(val) {
val->~nsCSSValue();
}
}
#undef CSSVALUE_LIST_FOR_VALUES
private:
Array(const Array& aOther); // not to be implemented
};
struct URL {
// Methods are not inline because using an nsIPrincipal means requiring
// caps, which leads to REQUIRES hell, since this header is included all
@ -514,5 +416,104 @@ protected:
} mValue;
};
struct nsCSSValue::Array {
// return |Array| with reference count of zero
static Array* Create(PRUint16 aItemCount) {
return new (aItemCount) Array(aItemCount);
}
nsCSSValue& operator[](PRUint16 aIndex) {
NS_ASSERTION(aIndex < mCount, "out of range");
return mArray[aIndex];
}
const nsCSSValue& operator[](PRUint16 aIndex) const {
NS_ASSERTION(aIndex < mCount, "out of range");
return mArray[aIndex];
}
nsCSSValue& Item(PRUint16 aIndex) { return (*this)[aIndex]; }
const nsCSSValue& Item(PRUint16 aIndex) const { return (*this)[aIndex]; }
PRUint16 Count() const { return mCount; }
PRBool operator==(const Array& aOther) const
{
if (mCount != aOther.mCount)
return PR_FALSE;
for (PRUint16 i = 0; i < mCount; ++i)
if ((*this)[i] != aOther[i])
return PR_FALSE;
return PR_TRUE;
}
void AddRef() {
if (mRefCnt == PR_UINT16_MAX) {
NS_WARNING("refcount overflow, leaking nsCSSValue::Array");
return;
}
++mRefCnt;
NS_LOG_ADDREF(this, mRefCnt, "nsCSSValue::Array", sizeof(*this));
}
void Release() {
if (mRefCnt == PR_UINT16_MAX) {
NS_WARNING("refcount overflow, leaking nsCSSValue::Array");
return;
}
--mRefCnt;
NS_LOG_RELEASE(this, mRefCnt, "nsCSSValue::Array");
if (mRefCnt == 0)
delete this;
}
private:
PRUint16 mRefCnt;
const PRUint16 mCount;
// This must be the last sub-object, since we extend this array to
// be of size mCount; it needs to be a sub-object so it gets proper
// alignment.
nsCSSValue mArray[1];
void* operator new(size_t aSelfSize, PRUint16 aItemCount) CPP_THROW_NEW {
NS_ABORT_IF_FALSE(aItemCount > 0, "cannot have a 0 item count");
return ::operator new(aSelfSize + sizeof(nsCSSValue) * (aItemCount - 1));
}
void operator delete(void* aPtr) { ::operator delete(aPtr); }
nsCSSValue* First() { return mArray; }
const nsCSSValue* First() const { return mArray; }
#define CSSVALUE_LIST_FOR_EXTRA_VALUES(var) \
for (nsCSSValue *var = First() + 1, *var##_end = First() + mCount; \
var != var##_end; ++var)
Array(PRUint16 aItemCount)
: mRefCnt(0)
, mCount(aItemCount)
{
MOZ_COUNT_CTOR(nsCSSValue::Array);
CSSVALUE_LIST_FOR_EXTRA_VALUES(val) {
new (val) nsCSSValue();
}
}
~Array()
{
MOZ_COUNT_DTOR(nsCSSValue::Array);
CSSVALUE_LIST_FOR_EXTRA_VALUES(val) {
val->~nsCSSValue();
}
}
#undef CSSVALUE_LIST_FOR_EXTRA_VALUES
private:
Array(const Array& aOther); // not to be implemented
};
#endif /* nsCSSValue_h___ */