+2009-05-02 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ - speed up the lexer in various ways
+
+ ~2% command-line SunSpider speedup
+
+ * parser/Lexer.cpp:
+ (JSC::Lexer::setCode): Moved below shift() so it can inline.
+ (JSC::Lexer::scanRegExp): Use resize(0) instead of clear() on Vectors, since the intent
+ here is not to free the underlying buffer.
+ (JSC::Lexer::lex): ditto; also, change the loop logic a bit for the main lexing loop
+ to avoid branching on !m_done twice per iteration. Now we only check it once.
+ (JSC::Lexer::shift): Make this ALWAYS_INLINE and tag an unusual branch as UNLIKELY
+ * parser/Lexer.h:
+ (JSC::Lexer::makeIdentifier): force to be ALWAYS_INLINE
+ * wtf/Vector.h:
+ (WTF::::append): force to be ALWAYS_INLINE (may have helped in ways other than parsing but it wasn't
+ getting inlined in a hot code path in the lexer)
+
2009-05-01 Steve Falkenburg <sfalken@apple.com>
Windows build fix.
m_mainTable.deleteTable();
}
-void Lexer::setCode(const SourceCode& source)
-{
- yylineno = source.firstLine();
- m_restrKeyword = false;
- m_delimited = false;
- m_eatNextIdentifier = false;
- m_stackToken = -1;
- m_lastToken = -1;
-
- m_position = source.startOffset();
- m_source = &source;
- m_code = source.provider()->data();
- m_length = source.endOffset();
- m_skipLF = false;
- m_skipCR = false;
- m_error = false;
- m_atLineStart = true;
-
- // read first characters
- shift(4);
-}
-
-void Lexer::shift(unsigned p)
+ALWAYS_INLINE void Lexer::shift(unsigned p)
{
// ECMA-262 calls for stripping Cf characters here, but we only do this for BOM,
// see <https://bugs.webkit.org/show_bug.cgi?id=4931>.
}
m_nextOffset3 = m_position;
m_next3 = m_code[m_position++];
- } while (m_next3 == 0xFEFF);
+ } while (UNLIKELY(m_next3 == 0xFEFF));
}
}
+void Lexer::setCode(const SourceCode& source)
+{
+ yylineno = source.firstLine();
+ m_restrKeyword = false;
+ m_delimited = false;
+ m_eatNextIdentifier = false;
+ m_stackToken = -1;
+ m_lastToken = -1;
+
+ m_position = source.startOffset();
+ m_source = &source;
+ m_code = source.provider()->data();
+ m_length = source.endOffset();
+ m_skipLF = false;
+ m_skipCR = false;
+ m_error = false;
+ m_atLineStart = true;
+
+ // read first characters
+ shift(4);
+}
+
// called on each new line
void Lexer::nextLine()
{
int token = 0;
m_state = Start;
unsigned short stringType = 0; // either single or double quotes
- m_buffer8.clear();
- m_buffer16.clear();
+ m_buffer8.resize(0);
+ m_buffer16.resize(0);
m_done = false;
m_terminator = false;
m_skipLF = false;
m_stackToken = 0;
}
int startOffset = m_currentOffset;
- while (!m_done) {
+ if (!m_done) {
+ while (true) {
if (m_skipLF && m_current != '\n') // found \r but not \n afterwards
m_skipLF = false;
if (m_skipCR && m_current != '\r') // found \n but not \r afterwards
ASSERT(!"Unhandled state in switch statement");
}
- // move on to the next character
- if (!m_done)
- shift(1);
if (m_state != Start && m_state != InSingleLineComment)
m_atLineStart = false;
+ if (m_done)
+ break;
+
+ shift(1);
+ }
}
// no identifiers allowed directly after numeric literal, e.g. "3in" is bad
bool Lexer::scanRegExp()
{
- m_buffer16.clear();
+ m_buffer16.resize(0);
bool lastWasEscape = false;
bool inBrackets = false;
!lastWasEscape && (m_current == '\\');
} else { // end of regexp
m_pattern = UString(m_buffer16);
- m_buffer16.clear();
+ m_buffer16.resize(0);
shift(1);
break;
}