зеркало из https://github.com/mozilla/pjs.git
bug 116023 Parser recycling buffers r=harishd, sr=sfraser, a=asa
This commit is contained in:
Родитель
70fb488334
Коммит
813ba6f7c2
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче