bug 116023 Parser recycling buffers r=harishd, sr=sfraser, a=asa

This commit is contained in:
dp%netscape.com 2002-03-02 23:09:52 +00:00
Родитель 70fb488334
Коммит 813ba6f7c2
4 изменённых файлов: 206 добавлений и 62 удалений

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

@ -46,9 +46,48 @@
#include "nsFileSpec.h"
#include "nsReadableUtils.h"
nsScannerString::nsScannerString(PRUnichar* aStorageStart,
PRUnichar* aDataEnd,
PRUnichar* aStorageEnd) : nsSlidingString(aStorageStart, aDataEnd, aStorageEnd)
nsRecyclingAllocator* nsScanner::gAllocator = nsnull;
static void nsScannerRecycle(void *aPtr, void *aClientData)
{
nsScanner::gAllocator->Free(aPtr);
}
static void *nsScannerAllocate(PRUint32 size)
{
return nsScanner::gAllocator->Malloc(size);
}
/**
* Helper funciton to convert raw 8bit char * to unicode
*
* aStr : input 8bit string
* aLen : length of input string aStr
* aDest : Destination unicode buffer. Null terminated.
* aDestLength : size of destination buffer. Must be atleast aLen+1.
*
* return 0 if conversion succeeded
* returns -1, if there is not enough space in destination buffer,
*/
static int RawToUnicode(const char *aStr, PRInt32 aLen, PRUnichar *aDest, PRUint32 aDestLength)
{
// Alert if someone if passing null buffers to us
NS_ASSERTION(aStr && aDest, "Null buffers");
// Error checking
if (!aStr || !aDest || (PRInt32)aDestLength < aLen+1)
return -1;
while (*aStr)
*aDest++ = (unsigned char) *aStr++;
*aDest = 0;
return 0;
}
nsScannerString::nsScannerString(PRUnichar* aStorageStart, PRUnichar* aDataEnd,
PRUnichar* aStorageEnd, nsFreeProc *aFreeProc)
: nsSlidingString(aStorageStart, aDataEnd, aStorageEnd, aFreeProc)
{
}
@ -107,13 +146,15 @@ MOZ_DECL_CTOR_COUNTER(nsScanner)
nsScanner::nsScanner(const nsAString& anHTMLString, const nsString& aCharset, PRInt32 aSource)
{
MOZ_COUNT_CTOR(nsScanner);
PRUnichar* buffer = ToNewUnicode(anHTMLString);
mTotalRead = anHTMLString.Length();
InitAllocator();
mSlidingBuffer = nsnull;
mTotalRead = anHTMLString.Length();
if (mTotalRead)
{
AppendToBuffer(anHTMLString);
mSlidingBuffer->BeginReading(mCurrentPosition);
}
mCountRemaining = 0;
AppendToBuffer(buffer, buffer+mTotalRead, buffer+mTotalRead);
mSlidingBuffer->BeginReading(mCurrentPosition);
mMarkPosition = mCurrentPosition;
mIncremental=PR_FALSE;
mOwnsStream=PR_FALSE;
@ -137,7 +178,7 @@ nsScanner::nsScanner(nsString& aFilename,PRBool aCreateStream, const nsString& a
mFilename(aFilename)
{
MOZ_COUNT_CTOR(nsScanner);
InitAllocator();
mSlidingBuffer = nsnull;
mIncremental=PR_TRUE;
mCountRemaining = 0;
@ -166,7 +207,7 @@ nsScanner::nsScanner(const nsAString& aFilename,nsInputStream& aStream,const nsS
mFilename(aFilename)
{
MOZ_COUNT_CTOR(nsScanner);
InitAllocator();
mSlidingBuffer = nsnull;
mIncremental=PR_FALSE;
mCountRemaining = 0;
@ -309,12 +350,8 @@ PRBool nsScanner::UngetReadable(const nsAReadableString& aBuffer) {
* @return error code
*/
nsresult nsScanner::Append(const nsAReadableString& aBuffer) {
PRUnichar* buffer = ToNewUnicode(aBuffer);
PRUint32 bufLen = aBuffer.Length();
mTotalRead += bufLen;
AppendToBuffer(buffer, buffer+bufLen, buffer+bufLen);
AppendToBuffer(aBuffer);
mTotalRead += aBuffer.Length();
return NS_OK;
}
@ -332,8 +369,8 @@ nsresult nsScanner::Append(const char* aBuffer, PRUint32 aLen){
if(mUnicodeDecoder) {
PRInt32 unicharBufLen = 0;
mUnicodeDecoder->GetMaxLength(aBuffer, aLen, &unicharBufLen);
start = unichars = (PRUnichar*)nsMemory::Alloc((unicharBufLen+1) * sizeof(PRUnichar));
NS_ENSURE_TRUE(unichars,NS_ERROR_OUT_OF_MEMORY);
start = unichars = (PRUnichar*) nsScannerAllocate((unicharBufLen+1) * sizeof(PRUnichar));
NS_ENSURE_TRUE(unichars, NS_ERROR_OUT_OF_MEMORY);
PRInt32 totalChars = 0;
PRInt32 unicharLength = unicharBufLen;
@ -375,9 +412,7 @@ nsresult nsScanner::Append(const char* aBuffer, PRUint32 aLen){
res = NS_OK;
}
else {
nsDependentCString str(aBuffer, aLen);
unichars = ToNewUnicode(str);
AppendToBuffer(unichars, unichars+aLen, unichars+aLen);
AppendToBuffer(aBuffer, aLen);
mTotalRead+=aLen;
}
@ -411,23 +446,18 @@ nsresult nsScanner::FillBuffer(void) {
}
else {
PRInt32 numread=0;
char* buf = new char[kBufsize+1];
char buf[kBufsize+1];
buf[kBufsize]=0;
if(mInputStream) {
numread = mInputStream->read(buf, kBufsize);
if (0 == numread) {
delete [] buf;
if (0 == numread)
return kEOF;
}
}
if((0<numread) && (0==result)) {
nsDependentCString str(buf, numread);
PRUnichar* unichars = ToNewUnicode(str);
AppendToBuffer(unichars, unichars+numread, unichars+kBufsize+1);
AppendToBuffer(buf, numread);
}
delete [] buf;
mTotalRead+=numread;
}
@ -1392,12 +1422,32 @@ void nsScanner::ReplaceCharacter(nsReadingIterator<PRUnichar>& aPosition,
}
}
void nsScanner::AppendToBuffer(const nsAString &aData)
{
PRUint32 len = aData.Length();
PRUnichar* buffer = (PRUnichar *) nsScannerAllocate(len * sizeof(PRUnichar));
if (buffer) {
CopyUnicodeTo(aData, 0, buffer, len);
AppendToBuffer(buffer, buffer+len, buffer+len);
}
}
void nsScanner::AppendToBuffer(const char *aData, PRUint32 aLen)
{
PRUnichar *buffer = (PRUnichar*) nsScannerAllocate((aLen+1) * sizeof(PRUnichar));
if (buffer)
{
RawToUnicode(aData, aLen, buffer, aLen+1);
AppendToBuffer(buffer, buffer+aLen, buffer+aLen);
}
}
void nsScanner::AppendToBuffer(PRUnichar* aStorageStart,
PRUnichar* aDataEnd,
PRUnichar* aStorageEnd)
{
if (!mSlidingBuffer) {
mSlidingBuffer = new nsScannerString(aStorageStart, aDataEnd, aStorageEnd);
mSlidingBuffer = new nsScannerString(aStorageStart, aDataEnd, aStorageEnd, nsScannerRecycle);
mSlidingBuffer->BeginReading(mCurrentPosition);
mMarkPosition = mCurrentPosition;
mSlidingBuffer->EndReading(mEndPosition);

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

@ -58,12 +58,17 @@
#include "nsIUnicodeDecoder.h"
#include "nsFileStream.h"
#include "nsSlidingString.h"
#include "nsRecyclingAllocator.h"
// Recycling memory used by scanner
#define NS_SCANNER_BUCKETS 10
class nsScannerString : public nsSlidingString {
public:
nsScannerString(PRUnichar* aStorageStart,
PRUnichar* aDataEnd,
PRUnichar* aStorageEnd);
PRUnichar* aStorageEnd,
nsFreeProc* aFreeProc);
virtual void UngetReadable(const nsAReadableString& aReadable, const nsReadingIterator<PRUnichar>& aCurrentPosition) { InsertReadable(aReadable,aCurrentPosition); }
virtual void ReplaceCharacter(nsReadingIterator<PRUnichar>& aPosition,
@ -382,6 +387,19 @@ class nsScanner {
PRUnichar* aDataEnd,
PRUnichar* aStorageEnd);
/**
* These versions of AppendToBuffer allocate from the recyclingallocator,
* convert to unicode if necessary and then add the buffer into the sliding
* string
*/
void AppendToBuffer(const nsAString &aData);
void AppendToBuffer(const char* aData, PRUint32 aLen);
static void InitAllocator() {
if (!gAllocator)
gAllocator = new nsRecyclingAllocator(NS_SCANNER_BUCKETS, NS_DEFAULT_RECYCLE_TIMEOUT, "parser");
}
nsInputStream* mInputStream;
nsScannerString* mSlidingBuffer;
nsReadingIterator<PRUnichar> mCurrentPosition; // The position we will next read from in the scanner buffer
@ -397,6 +415,10 @@ class nsScanner {
nsString mCharset;
nsIUnicodeDecoder *mUnicodeDecoder;
PRInt32 mNewlinesSkipped;
public:
// Allocator to recycle memory used by scanner
static nsRecyclingAllocator *gAllocator;
};
#endif

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

@ -46,9 +46,48 @@
#include "nsFileSpec.h"
#include "nsReadableUtils.h"
nsScannerString::nsScannerString(PRUnichar* aStorageStart,
PRUnichar* aDataEnd,
PRUnichar* aStorageEnd) : nsSlidingString(aStorageStart, aDataEnd, aStorageEnd)
nsRecyclingAllocator* nsScanner::gAllocator = nsnull;
static void nsScannerRecycle(void *aPtr, void *aClientData)
{
nsScanner::gAllocator->Free(aPtr);
}
static void *nsScannerAllocate(PRUint32 size)
{
return nsScanner::gAllocator->Malloc(size);
}
/**
* Helper funciton to convert raw 8bit char * to unicode
*
* aStr : input 8bit string
* aLen : length of input string aStr
* aDest : Destination unicode buffer. Null terminated.
* aDestLength : size of destination buffer. Must be atleast aLen+1.
*
* return 0 if conversion succeeded
* returns -1, if there is not enough space in destination buffer,
*/
static int RawToUnicode(const char *aStr, PRInt32 aLen, PRUnichar *aDest, PRUint32 aDestLength)
{
// Alert if someone if passing null buffers to us
NS_ASSERTION(aStr && aDest, "Null buffers");
// Error checking
if (!aStr || !aDest || (PRInt32)aDestLength < aLen+1)
return -1;
while (*aStr)
*aDest++ = (unsigned char) *aStr++;
*aDest = 0;
return 0;
}
nsScannerString::nsScannerString(PRUnichar* aStorageStart, PRUnichar* aDataEnd,
PRUnichar* aStorageEnd, nsFreeProc *aFreeProc)
: nsSlidingString(aStorageStart, aDataEnd, aStorageEnd, aFreeProc)
{
}
@ -107,13 +146,15 @@ MOZ_DECL_CTOR_COUNTER(nsScanner)
nsScanner::nsScanner(const nsAString& anHTMLString, const nsString& aCharset, PRInt32 aSource)
{
MOZ_COUNT_CTOR(nsScanner);
PRUnichar* buffer = ToNewUnicode(anHTMLString);
mTotalRead = anHTMLString.Length();
InitAllocator();
mSlidingBuffer = nsnull;
mTotalRead = anHTMLString.Length();
if (mTotalRead)
{
AppendToBuffer(anHTMLString);
mSlidingBuffer->BeginReading(mCurrentPosition);
}
mCountRemaining = 0;
AppendToBuffer(buffer, buffer+mTotalRead, buffer+mTotalRead);
mSlidingBuffer->BeginReading(mCurrentPosition);
mMarkPosition = mCurrentPosition;
mIncremental=PR_FALSE;
mOwnsStream=PR_FALSE;
@ -137,7 +178,7 @@ nsScanner::nsScanner(nsString& aFilename,PRBool aCreateStream, const nsString& a
mFilename(aFilename)
{
MOZ_COUNT_CTOR(nsScanner);
InitAllocator();
mSlidingBuffer = nsnull;
mIncremental=PR_TRUE;
mCountRemaining = 0;
@ -166,7 +207,7 @@ nsScanner::nsScanner(const nsAString& aFilename,nsInputStream& aStream,const nsS
mFilename(aFilename)
{
MOZ_COUNT_CTOR(nsScanner);
InitAllocator();
mSlidingBuffer = nsnull;
mIncremental=PR_FALSE;
mCountRemaining = 0;
@ -309,12 +350,8 @@ PRBool nsScanner::UngetReadable(const nsAReadableString& aBuffer) {
* @return error code
*/
nsresult nsScanner::Append(const nsAReadableString& aBuffer) {
PRUnichar* buffer = ToNewUnicode(aBuffer);
PRUint32 bufLen = aBuffer.Length();
mTotalRead += bufLen;
AppendToBuffer(buffer, buffer+bufLen, buffer+bufLen);
AppendToBuffer(aBuffer);
mTotalRead += aBuffer.Length();
return NS_OK;
}
@ -332,8 +369,8 @@ nsresult nsScanner::Append(const char* aBuffer, PRUint32 aLen){
if(mUnicodeDecoder) {
PRInt32 unicharBufLen = 0;
mUnicodeDecoder->GetMaxLength(aBuffer, aLen, &unicharBufLen);
start = unichars = (PRUnichar*)nsMemory::Alloc((unicharBufLen+1) * sizeof(PRUnichar));
NS_ENSURE_TRUE(unichars,NS_ERROR_OUT_OF_MEMORY);
start = unichars = (PRUnichar*) nsScannerAllocate((unicharBufLen+1) * sizeof(PRUnichar));
NS_ENSURE_TRUE(unichars, NS_ERROR_OUT_OF_MEMORY);
PRInt32 totalChars = 0;
PRInt32 unicharLength = unicharBufLen;
@ -375,9 +412,7 @@ nsresult nsScanner::Append(const char* aBuffer, PRUint32 aLen){
res = NS_OK;
}
else {
nsDependentCString str(aBuffer, aLen);
unichars = ToNewUnicode(str);
AppendToBuffer(unichars, unichars+aLen, unichars+aLen);
AppendToBuffer(aBuffer, aLen);
mTotalRead+=aLen;
}
@ -411,23 +446,18 @@ nsresult nsScanner::FillBuffer(void) {
}
else {
PRInt32 numread=0;
char* buf = new char[kBufsize+1];
char buf[kBufsize+1];
buf[kBufsize]=0;
if(mInputStream) {
numread = mInputStream->read(buf, kBufsize);
if (0 == numread) {
delete [] buf;
if (0 == numread)
return kEOF;
}
}
if((0<numread) && (0==result)) {
nsDependentCString str(buf, numread);
PRUnichar* unichars = ToNewUnicode(str);
AppendToBuffer(unichars, unichars+numread, unichars+kBufsize+1);
AppendToBuffer(buf, numread);
}
delete [] buf;
mTotalRead+=numread;
}
@ -1392,12 +1422,32 @@ void nsScanner::ReplaceCharacter(nsReadingIterator<PRUnichar>& aPosition,
}
}
void nsScanner::AppendToBuffer(const nsAString &aData)
{
PRUint32 len = aData.Length();
PRUnichar* buffer = (PRUnichar *) nsScannerAllocate(len * sizeof(PRUnichar));
if (buffer) {
CopyUnicodeTo(aData, 0, buffer, len);
AppendToBuffer(buffer, buffer+len, buffer+len);
}
}
void nsScanner::AppendToBuffer(const char *aData, PRUint32 aLen)
{
PRUnichar *buffer = (PRUnichar*) nsScannerAllocate((aLen+1) * sizeof(PRUnichar));
if (buffer)
{
RawToUnicode(aData, aLen, buffer, aLen+1);
AppendToBuffer(buffer, buffer+aLen, buffer+aLen);
}
}
void nsScanner::AppendToBuffer(PRUnichar* aStorageStart,
PRUnichar* aDataEnd,
PRUnichar* aStorageEnd)
{
if (!mSlidingBuffer) {
mSlidingBuffer = new nsScannerString(aStorageStart, aDataEnd, aStorageEnd);
mSlidingBuffer = new nsScannerString(aStorageStart, aDataEnd, aStorageEnd, nsScannerRecycle);
mSlidingBuffer->BeginReading(mCurrentPosition);
mMarkPosition = mCurrentPosition;
mSlidingBuffer->EndReading(mEndPosition);

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

@ -58,12 +58,17 @@
#include "nsIUnicodeDecoder.h"
#include "nsFileStream.h"
#include "nsSlidingString.h"
#include "nsRecyclingAllocator.h"
// Recycling memory used by scanner
#define NS_SCANNER_BUCKETS 10
class nsScannerString : public nsSlidingString {
public:
nsScannerString(PRUnichar* aStorageStart,
PRUnichar* aDataEnd,
PRUnichar* aStorageEnd);
PRUnichar* aStorageEnd,
nsFreeProc* aFreeProc);
virtual void UngetReadable(const nsAReadableString& aReadable, const nsReadingIterator<PRUnichar>& aCurrentPosition) { InsertReadable(aReadable,aCurrentPosition); }
virtual void ReplaceCharacter(nsReadingIterator<PRUnichar>& aPosition,
@ -382,6 +387,19 @@ class nsScanner {
PRUnichar* aDataEnd,
PRUnichar* aStorageEnd);
/**
* These versions of AppendToBuffer allocate from the recyclingallocator,
* convert to unicode if necessary and then add the buffer into the sliding
* string
*/
void AppendToBuffer(const nsAString &aData);
void AppendToBuffer(const char* aData, PRUint32 aLen);
static void InitAllocator() {
if (!gAllocator)
gAllocator = new nsRecyclingAllocator(NS_SCANNER_BUCKETS, NS_DEFAULT_RECYCLE_TIMEOUT, "parser");
}
nsInputStream* mInputStream;
nsScannerString* mSlidingBuffer;
nsReadingIterator<PRUnichar> mCurrentPosition; // The position we will next read from in the scanner buffer
@ -397,6 +415,10 @@ class nsScanner {
nsString mCharset;
nsIUnicodeDecoder *mUnicodeDecoder;
PRInt32 mNewlinesSkipped;
public:
// Allocator to recycle memory used by scanner
static nsRecyclingAllocator *gAllocator;
};
#endif