Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (88718 => 88719)
--- trunk/Source/_javascript_Core/ChangeLog 2011-06-13 22:38:03 UTC (rev 88718)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-06-13 22:38:22 UTC (rev 88719)
@@ -1,3 +1,24 @@
+2011-06-13 Oliver Hunt <[email protected]>
+
+ Reviewed by Gavin Barraclough.
+
+ Make it possible to inline the common case of identifier lexing
+ https://bugs.webkit.org/show_bug.cgi?id=62600
+
+ Add a lexing function that expects to lex an "normal" alpha numeric
+ identifier (that ignores keywords) so it's possible to inline the
+ common parsing cases. This comes out as a reasonable parsing speed
+ boost.
+
+ * parser/JSParser.cpp:
+ (JSC::JSParser::nextExpectIdentifier):
+ (JSC::JSParser::parseProperty):
+ (JSC::JSParser::parseMemberExpression):
+ * parser/Lexer.cpp:
+ * parser/Lexer.h:
+ (JSC::Lexer::makeIdentifier):
+ (JSC::Lexer::lexExpectIdentifier):
+
2011-06-13 Xan Lopez <[email protected]>
Reviewed by Martin Robinson.
Modified: trunk/Source/_javascript_Core/parser/JSParser.cpp (88718 => 88719)
--- trunk/Source/_javascript_Core/parser/JSParser.cpp 2011-06-13 22:38:03 UTC (rev 88718)
+++ trunk/Source/_javascript_Core/parser/JSParser.cpp 2011-06-13 22:38:22 UTC (rev 88719)
@@ -107,6 +107,14 @@
m_token.m_type = m_lexer->lex(&m_token.m_data, &m_token.m_info, lexType, strictMode());
}
+ ALWAYS_INLINE void nextExpectIdentifier(unsigned lexType = 0)
+ {
+ m_lastLine = m_token.m_info.line;
+ m_lastTokenEnd = m_token.m_info.endOffset;
+ m_lexer->setLastLineNumber(m_lastLine);
+ m_token.m_type = m_lexer->lexExpectIdentifier(&m_token.m_data, &m_token.m_info, lexType, strictMode());
+ }
+
ALWAYS_INLINE bool nextTokenIsColon()
{
return m_lexer->nextTokenIsColon();
@@ -1707,9 +1715,9 @@
case STRING: {
const Identifier* ident = m_token.m_data.ident;
if (complete || (wasIdent && (*ident == m_globalData->propertyNames->get || *ident == m_globalData->propertyNames->set)))
- next(Lexer::IgnoreReservedWords);
+ nextExpectIdentifier(Lexer::IgnoreReservedWords);
else
- next(Lexer::IgnoreReservedWords | TreeBuilder::DontBuildKeywords);
+ nextExpectIdentifier(Lexer::IgnoreReservedWords | TreeBuilder::DontBuildKeywords);
if (match(COLON)) {
next();
@@ -2038,7 +2046,7 @@
case DOT: {
m_nonTrivialExpressionCount++;
int expressionEnd = lastTokenEnd();
- next(Lexer::IgnoreReservedWords | TreeBuilder::DontBuildKeywords);
+ nextExpectIdentifier(Lexer::IgnoreReservedWords | TreeBuilder::DontBuildKeywords);
matchOrFail(IDENT);
base = context.createDotAccess(base, m_token.m_data.ident, expressionStart, expressionEnd, tokenEnd());
next();
Modified: trunk/Source/_javascript_Core/parser/Lexer.cpp (88718 => 88719)
--- trunk/Source/_javascript_Core/parser/Lexer.cpp 2011-06-13 22:38:03 UTC (rev 88718)
+++ trunk/Source/_javascript_Core/parser/Lexer.cpp 2011-06-13 22:38:22 UTC (rev 88719)
@@ -331,11 +331,6 @@
++m_lineNumber;
}
-ALWAYS_INLINE const Identifier* Lexer::makeIdentifier(const UChar* characters, size_t length)
-{
- return &m_arena->makeIdentifier(m_globalData, characters, length);
-}
-
ALWAYS_INLINE bool Lexer::lastTokenWasRestrKeyword() const
{
return m_lastToken == CONTINUE || m_lastToken == BREAK || m_lastToken == RETURN || m_lastToken == THROW;
Modified: trunk/Source/_javascript_Core/parser/Lexer.h (88718 => 88719)
--- trunk/Source/_javascript_Core/parser/Lexer.h 2011-06-13 22:38:03 UTC (rev 88718)
+++ trunk/Source/_javascript_Core/parser/Lexer.h 2011-06-13 22:38:22 UTC (rev 88719)
@@ -88,7 +88,9 @@
}
SourceProvider* sourceProvider() const { return m_source->provider(); }
-
+
+ JSTokenType lexExpectIdentifier(JSTokenData* lvalp, JSTokenInfo* llocp, unsigned, bool strictMode);
+
private:
friend class JSGlobalData;
@@ -173,7 +175,56 @@
{
return (convertHex(c1, c2) << 8) | convertHex(c3, c4);
}
+
+ ALWAYS_INLINE const Identifier* Lexer::makeIdentifier(const UChar* characters, size_t length)
+ {
+ return &m_arena->makeIdentifier(m_globalData, characters, length);
+ }
+ ALWAYS_INLINE JSTokenType Lexer::lexExpectIdentifier(JSTokenData* lvalp, JSTokenInfo* llocp, unsigned lexType, bool strictMode)
+ {
+ ASSERT((lexType & IgnoreReservedWords));
+ const UChar* start = m_code;
+ const UChar* ptr = start;
+ const UChar* end = m_codeEnd;
+ if (ptr >= end) {
+ ASSERT(ptr == end);
+ goto slowCase;
+ }
+ if (!WTF::isASCIIAlpha(*ptr))
+ goto slowCase;
+ ++ptr;
+ while (ptr < end) {
+ if (!WTF::isASCIIAlphanumeric(*ptr))
+ break;
+ ++ptr;
+ }
+
+ // Here's the shift
+ if (ptr < end) {
+ if (!WTF::isASCII(*ptr) || (*ptr == '\\') || (*ptr == '_'))
+ goto slowCase;
+ m_current = *ptr;
+ } else
+ m_current = -1;
+
+ m_code = ptr;
+
+ // Create the identifier if needed
+ if (lexType & DontBuildKeywords)
+ lvalp->ident = 0;
+ else
+ lvalp->ident = makeIdentifier(start, ptr - start);
+ llocp->line = m_lineNumber;
+ llocp->startOffset = start - m_codeStart;
+ llocp->endOffset = currentOffset();
+ m_lastToken = IDENT;
+ return IDENT;
+
+ slowCase:
+ return lex(lvalp, llocp, lexType, strictMode);
+ }
+
} // namespace JSC
#endif // Lexer_h