2009-05-02 Maciej Stachowiak <mjs@apple.com>
authormjs@apple.com <mjs@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 2 May 2009 11:33:56 +0000 (11:33 +0000)
committermjs@apple.com <mjs@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 2 May 2009 11:33:56 +0000 (11:33 +0000)
        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)

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@43144 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/parser/Lexer.cpp
JavaScriptCore/parser/Lexer.h
JavaScriptCore/wtf/Vector.h

index caef04117db778c78cb83a158327363e5fc95833..d62b79b4d9334a353130db11b95cebc3a7acc46d 100644 (file)
@@ -1,3 +1,24 @@
+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.
index 6f650966d0b3a0045f9e3c10649a6d731f2a2ecb..a5c44b004d8cb3b080327d36f3882731d6c3cb55 100644 (file)
@@ -88,29 +88,7 @@ Lexer::~Lexer()
     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>.
@@ -131,10 +109,32 @@ void Lexer::shift(unsigned p)
             }
             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()
 {
@@ -155,8 +155,8 @@ int Lexer::lex(void* p1, void* p2)
     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;
@@ -170,7 +170,8 @@ int Lexer::lex(void* p1, void* p2)
         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
@@ -451,11 +452,13 @@ int Lexer::lex(void* p1, void* p2)
                 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
@@ -842,7 +845,7 @@ void Lexer::record16(UChar c)
 
 bool Lexer::scanRegExp()
 {
-    m_buffer16.clear();
+    m_buffer16.resize(0);
     bool lastWasEscape = false;
     bool inBrackets = false;
 
@@ -862,7 +865,7 @@ bool Lexer::scanRegExp()
             !lastWasEscape && (m_current == '\\');
         } else { // end of regexp
             m_pattern = UString(m_buffer16);
-            m_buffer16.clear();
+            m_buffer16.resize(0);
             shift(1);
             break;
         }
index 63c2da926eaa6d0c03d731930ab805cbfd995a8e..6e327ec82d1499f1680960aebf0eb6f62a8d5c55 100644 (file)
@@ -123,7 +123,7 @@ namespace JSC {
         void record16(int);
         void record16(UChar);
 
-        JSC::Identifier* makeIdentifier(const Vector<UChar>& buffer)
+        ALWAYS_INLINE JSC::Identifier* makeIdentifier(const Vector<UChar>& buffer)
         {
             m_identifiers.append(JSC::Identifier(m_globalData, buffer.data(), buffer.size()));
             return &m_identifiers.last();
index 2daf79b0602102aefff5adc2b39fafe3211f9746..af91a641de2cb391390d9c9ec61bc16dff0d9e00 100644 (file)
@@ -790,7 +790,7 @@ namespace WTF {
     }
 
     template<typename T, size_t inlineCapacity> template<typename U>
-    inline void Vector<T, inlineCapacity>::append(const U& val)
+    ALWAYS_INLINE void Vector<T, inlineCapacity>::append(const U& val)
     {
         const U* ptr = &val;
         if (size() == capacity()) {