Reviewed by Maciej Stachowiak (and revised slightly)
RegExp::match to be optimized
https://bugs.webkit.org/show_bug.cgi?id=26957
Allow regexp matching to use Vectors with inline capacity instead of
allocating a new ovector buffer every time.
~5% speedup on SunSpider string-unpack-code test, 0.3% on SunSpider overall.
* runtime/RegExp.cpp:
(JSC::RegExp::match):
* runtime/RegExp.h:
* runtime/RegExpConstructor.cpp:
(JSC::RegExpConstructorPrivate::RegExpConstructorPrivate):
(JSC::RegExpConstructorPrivate::lastOvector):
(JSC::RegExpConstructorPrivate::tempOvector):
(JSC::RegExpConstructorPrivate::changeLastOvector):
(JSC::RegExpConstructor::performMatch):
(JSC::RegExpMatchesArray::RegExpMatchesArray):
(JSC::RegExpMatchesArray::fillArrayInstance):
(JSC::RegExpConstructor::getBackref):
(JSC::RegExpConstructor::getLastParen):
(JSC::RegExpConstructor::getLeftContext):
(JSC::RegExpConstructor::getRightContext):
* runtime/StringPrototype.cpp:
(JSC::stringProtoFuncSplit):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@45545
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2009-07-03 Yong Li <yong.li@torchmobile.com>
+
+ Reviewed by Maciej Stachowiak (and revised slightly)
+
+ RegExp::match to be optimized
+ https://bugs.webkit.org/show_bug.cgi?id=26957
+
+ Allow regexp matching to use Vectors with inline capacity instead of
+ allocating a new ovector buffer every time.
+
+ ~5% speedup on SunSpider string-unpack-code test, 0.3% on SunSpider overall.
+
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::match):
+ * runtime/RegExp.h:
+ * runtime/RegExpConstructor.cpp:
+ (JSC::RegExpConstructorPrivate::RegExpConstructorPrivate):
+ (JSC::RegExpConstructorPrivate::lastOvector):
+ (JSC::RegExpConstructorPrivate::tempOvector):
+ (JSC::RegExpConstructorPrivate::changeLastOvector):
+ (JSC::RegExpConstructor::performMatch):
+ (JSC::RegExpMatchesArray::RegExpMatchesArray):
+ (JSC::RegExpMatchesArray::fillArrayInstance):
+ (JSC::RegExpConstructor::getBackref):
+ (JSC::RegExpConstructor::getLastParen):
+ (JSC::RegExpConstructor::getLeftContext):
+ (JSC::RegExpConstructor::getRightContext):
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncSplit):
+
2009-06-30 Kwang Yul Seo <skyul@company100.net>
Reviewed by Eric Seidel.
/*
* Copyright (C) 1999-2001, 2004 Harri Porten (porten@kde.org)
* Copyright (c) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Torch Mobile, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#endif
}
-int RegExp::match(const UString& s, int startOffset, OwnArrayPtr<int>* ovector)
+int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
{
if (startOffset < 0)
startOffset = 0;
if (m_regExpBytecode) {
#endif
int offsetVectorSize = (m_numSubpatterns + 1) * 3; // FIXME: should be 2 - but adding temporary fallback to pcre.
- int* offsetVector = new int [offsetVectorSize];
+ int* offsetVector;
+ Vector<int, 32> nonReturnedOvector;
+ if (ovector) {
+ ovector->resize(offsetVectorSize);
+ offsetVector = ovector->data();
+ } else {
+ nonReturnedOvector.resize(offsetVectorSize);
+ offsetVector = nonReturnedOvector.data();
+ }
+
ASSERT(offsetVector);
for (int j = 0; j < offsetVectorSize; ++j)
offsetVector[j] = -1;
- OwnArrayPtr<int> nonReturnedOvector;
- if (!ovector)
- nonReturnedOvector.set(offsetVector);
- else
- ovector->set(offsetVector);
#if ENABLE(YARR_JIT)
int result = Yarr::executeRegex(m_regExpJITCode, s.data(), startOffset, s.size(), offsetVector, offsetVectorSize);
m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(m_pattern.data()), m_pattern.size(), ignoreCaseOption, multilineOption, &m_numSubpatterns, &m_constructionError);
}
-int RegExp::match(const UString& s, int startOffset, OwnArrayPtr<int>* ovector)
+int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
{
if (startOffset < 0)
startOffset = 0;
#if ENABLE(WREC)
if (m_wrecFunction) {
int offsetVectorSize = (m_numSubpatterns + 1) * 2;
- int* offsetVector = new int [offsetVectorSize];
+ int* offsetVector;
+ Vector<int, 32> nonReturnedOvector;
+ if (ovector) {
+ ovector->resize(offsetVectorSize);
+ offsetVector = ovector->data();
+ } else {
+ nonReturnedOvector.resize(offsetVectorSize);
+ offsetVector = nonReturnedOvector.data();
+ }
ASSERT(offsetVector);
for (int j = 0; j < offsetVectorSize; ++j)
offsetVector[j] = -1;
- OwnArrayPtr<int> nonReturnedOvector;
- if (!ovector)
- nonReturnedOvector.set(offsetVector);
- else
- ovector->set(offsetVector);
-
int result = m_wrecFunction(s.data(), startOffset, s.size(), offsetVector);
if (result < 0) {
offsetVector = fixedSizeOffsetVector;
} else {
offsetVectorSize = (m_numSubpatterns + 1) * 3;
- offsetVector = new int [offsetVectorSize];
- ovector->set(offsetVector);
+ ovector->resize(offsetVectorSize);
+ offsetVector = ovector->data();
}
int numMatches = jsRegExpExecute(m_regExp, reinterpret_cast<const UChar*>(s.data()), s.size(), startOffset, offsetVector, offsetVectorSize);
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
* Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Torch Mobile, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
bool isValid() const { return !m_constructionError; }
const char* errorMessage() const { return m_constructionError; }
- int match(const UString&, int startOffset, OwnArrayPtr<int>* ovector = 0);
+ int match(const UString&, int startOffset, Vector<int, 32>* ovector = 0);
unsigned numSubpatterns() const { return m_numSubpatterns; }
private:
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
* Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Torch Mobile, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
RegExpConstructorPrivate()
: lastNumSubPatterns(0)
, multiline(false)
+ , lastOvectorIndex(0)
{
}
+ const Vector<int, 32>& lastOvector() const { return ovector[lastOvectorIndex]; }
+ Vector<int, 32>& lastOvector() { return ovector[lastOvectorIndex]; }
+ Vector<int, 32>& tempOvector() { return ovector[lastOvectorIndex ? 0 : 1]; }
+ void changeLastOvector() { lastOvectorIndex = lastOvectorIndex ? 0 : 1; }
+
UString input;
UString lastInput;
- OwnArrayPtr<int> lastOvector;
- unsigned lastNumSubPatterns : 31;
+ Vector<int, 32> ovector[2];
+ unsigned lastNumSubPatterns : 30;
bool multiline : 1;
+ unsigned lastOvectorIndex : 1;
};
RegExpConstructor::RegExpConstructor(ExecState* exec, PassRefPtr<Structure> structure, RegExpPrototype* regExpPrototype)
*/
void RegExpConstructor::performMatch(RegExp* r, const UString& s, int startOffset, int& position, int& length, int** ovector)
{
- OwnArrayPtr<int> tmpOvector;
- position = r->match(s, startOffset, &tmpOvector);
+ position = r->match(s, startOffset, &d->tempOvector());
if (ovector)
- *ovector = tmpOvector.get();
+ *ovector = d->tempOvector().data();
if (position != -1) {
- ASSERT(tmpOvector);
+ ASSERT(!d->tempOvector().isEmpty());
- length = tmpOvector[1] - tmpOvector[0];
+ length = d->tempOvector()[1] - d->tempOvector()[0];
d->input = s;
d->lastInput = s;
- d->lastOvector.set(tmpOvector.release());
+ d->changeLastOvector();
d->lastNumSubPatterns = r->numSubpatterns();
}
}
d->lastInput = data->lastInput;
d->lastNumSubPatterns = data->lastNumSubPatterns;
unsigned offsetVectorSize = (data->lastNumSubPatterns + 1) * 2; // only copying the result part of the vector
- d->lastOvector.set(new int[offsetVectorSize]);
- memcpy(d->lastOvector.get(), data->lastOvector.get(), offsetVectorSize * sizeof(int));
+ d->lastOvector().resize(offsetVectorSize);
+ memcpy(d->lastOvector().data(), data->lastOvector().data(), offsetVectorSize * sizeof(int));
// d->multiline is not needed, and remains uninitialized
setLazyCreationData(d);
unsigned lastNumSubpatterns = d->lastNumSubPatterns;
for (unsigned i = 0; i <= lastNumSubpatterns; ++i) {
- int start = d->lastOvector[2 * i];
+ int start = d->lastOvector()[2 * i];
if (start >= 0)
- JSArray::put(exec, i, jsSubstring(exec, d->lastInput, start, d->lastOvector[2 * i + 1] - start));
+ JSArray::put(exec, i, jsSubstring(exec, d->lastInput, start, d->lastOvector()[2 * i + 1] - start));
}
PutPropertySlot slot;
- JSArray::put(exec, exec->propertyNames().index, jsNumber(exec, d->lastOvector[0]), slot);
+ JSArray::put(exec, exec->propertyNames().index, jsNumber(exec, d->lastOvector()[0]), slot);
JSArray::put(exec, exec->propertyNames().input, jsString(exec, d->input), slot);
delete d;
JSValue RegExpConstructor::getBackref(ExecState* exec, unsigned i) const
{
- if (d->lastOvector && i <= d->lastNumSubPatterns) {
- int start = d->lastOvector[2 * i];
+ if (!d->lastOvector().isEmpty() && i <= d->lastNumSubPatterns) {
+ int start = d->lastOvector()[2 * i];
if (start >= 0)
- return jsSubstring(exec, d->lastInput, start, d->lastOvector[2 * i + 1] - start);
+ return jsSubstring(exec, d->lastInput, start, d->lastOvector()[2 * i + 1] - start);
}
return jsEmptyString(exec);
}
unsigned i = d->lastNumSubPatterns;
if (i > 0) {
ASSERT(d->lastOvector);
- int start = d->lastOvector[2 * i];
+ int start = d->lastOvector()[2 * i];
if (start >= 0)
- return jsSubstring(exec, d->lastInput, start, d->lastOvector[2 * i + 1] - start);
+ return jsSubstring(exec, d->lastInput, start, d->lastOvector()[2 * i + 1] - start);
}
return jsEmptyString(exec);
}
JSValue RegExpConstructor::getLeftContext(ExecState* exec) const
{
- if (d->lastOvector)
- return jsSubstring(exec, d->lastInput, 0, d->lastOvector[0]);
+ if (!d->lastOvector().isEmpty())
+ return jsSubstring(exec, d->lastInput, 0, d->lastOvector()[0]);
return jsEmptyString(exec);
}
JSValue RegExpConstructor::getRightContext(ExecState* exec) const
{
- if (d->lastOvector)
- return jsSubstring(exec, d->lastInput, d->lastOvector[1], d->lastInput.size() - d->lastOvector[1]);
+ if (!d->lastOvector().isEmpty())
+ return jsSubstring(exec, d->lastInput, d->lastOvector()[1], d->lastInput.size() - d->lastOvector()[1]);
return jsEmptyString(exec);
}
/*
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
* Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Torch Mobile, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
}
int pos = 0;
while (i != limit && pos < s.size()) {
- OwnArrayPtr<int> ovector;
+ Vector<int, 32> ovector;
int mpos = reg->match(s, pos, &ovector);
if (mpos < 0)
break;