Changeset 88076 in webkit


Ignore:
Timestamp:
Jun 3, 2011 4:30:22 PM (13 years ago)
Author:
oliver@apple.com
Message:

2011-06-03 Oliver Hunt <oliver@apple.com>

Reviewed by Geoffrey Garen.

Improve keyword lookup
https://bugs.webkit.org/show_bug.cgi?id=61913

Rather than doing multiple hash lookups as we currently
do when trying to identify keywords we now use an
automatically generated decision tree (essentially it's
a hard coded patricia trie). We still use the regular
lookup table for the last few characters of an input as
this allows us to completely skip all bounds checks.

  • CMakeLists.txt:
  • DerivedSources.make:
  • DerivedSources.pro:
  • GNUmakefile.am:
  • JavaScriptCore.gyp/JavaScriptCore.gyp:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • KeywordLookupGenerator.py: Added.
  • make-generated-sources.sh:
  • parser/Lexer.cpp: (JSC::Lexer::internalShift): (JSC::Lexer::shift): (JSC::Lexer::parseIdentifier):
  • parser/Lexer.h:
Location:
trunk/Source/JavaScriptCore
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r87061 r88076  
    220220
    221221
     222#GENERATOR: "KeywordLookup.h": keyword decision tree used by the lexer
     223ADD_CUSTOM_COMMAND(
     224    OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/KeywordLookup.h
     225    MAIN_DEPENDENCY ${JAVASCRIPTCORE_DIR}/KeywordLookupGenerator.py
     226    COMMAND ${PYTHON_EXECUTABLE} ${JAVASCRIPTCORE_DIR}/KeywordLookupGenerator.py ${JAVASCRIPTCORE_DIR}/parser/Keywords.table > ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/KeywordLookup.h
     227    VERBATIM)
     228ADD_SOURCE_DEPENDENCIES(${JAVASCRIPTCORE_DIR}/parser/Lexer.cpp ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/KeywordLookup.h)
    222229
    223230IF (WTF_CPU_ARM)
  • trunk/Source/JavaScriptCore/ChangeLog

    r88016 r88076  
     12011-06-03  Oliver Hunt  <oliver@apple.com>
     2
     3        Reviewed by Geoffrey Garen.
     4
     5        Improve keyword lookup
     6        https://bugs.webkit.org/show_bug.cgi?id=61913
     7
     8        Rather than doing multiple hash lookups as we currently
     9        do when trying to identify keywords we now use an
     10        automatically generated decision tree (essentially it's
     11        a hard coded patricia trie).  We still use the regular
     12        lookup table for the last few characters of an input as
     13        this allows us to completely skip all bounds checks.
     14
     15        * CMakeLists.txt:
     16        * DerivedSources.make:
     17        * DerivedSources.pro:
     18        * GNUmakefile.am:
     19        * JavaScriptCore.gyp/JavaScriptCore.gyp:
     20        * JavaScriptCore.xcodeproj/project.pbxproj:
     21        * KeywordLookupGenerator.py: Added.
     22        * make-generated-sources.sh:
     23        * parser/Lexer.cpp:
     24        (JSC::Lexer::internalShift):
     25        (JSC::Lexer::shift):
     26        (JSC::Lexer::parseIdentifier):
     27        * parser/Lexer.h:
     28
    1292011-06-03  Siddharth Mathur  <siddharth.mathur@nokia.com>
    230
  • trunk/Source/JavaScriptCore/DerivedSources.make

    r86727 r88076  
    4747    JavaScriptCore.JSVALUE64.exp \
    4848    JSGlobalObject.lut.h \
     49    KeywordLookup.h \
    4950    Lexer.lut.h \
    5051    MathObject.lut.h \
     
    7778        python $^ > $@
    7879
     80KeywordLookup.h: KeywordLookupGenerator.py Keywords.table
     81        python $^ > $@
     82
    7983# export files
    8084
  • trunk/Source/JavaScriptCore/DerivedSources.pro

    r86727 r88076  
    100100retgen.commands = python $$retgen.wkScript > ${QMAKE_FILE_OUT}
    101101addExtraCompiler(retgen)
     102
     103#GENERATOR: "KeywordLookup.h": decision tree used by the lexer
     104klgen.output = $$JSC_GENERATED_SOURCES_DIR/KeywordLookup.h
     105klgen.wkScript = $$PWD/KeywordLookupGenerator.py
     106klgen.input = KEYWORDLUT_FILES
     107klgen.commands = python $$klgen.wkScript ${QMAKE_FILE_NAME} > ${QMAKE_FILE_OUT}
     108addExtraCompiler(klgen)
  • trunk/Source/JavaScriptCore/GNUmakefile.am

    r86727 r88076  
    7878
    7979Source/JavaScriptCore/RegExpJitTables.h: $(srcdir)/Source/JavaScriptCore/create_regex_tables
     80        $(AM_V_GEN)$(PYTHON) $^ > $@
     81
     82Source/JavaScriptCore/KeywordLookup.h: $(srcdir)/Source/JavaScriptCore/KeywordLookupGenerator.py $(srcdir)/Source/JavaScriptCore/parser/Keywords.table
    8083        $(AM_V_GEN)$(PYTHON) $^ > $@
    8184
  • trunk/Source/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp

    r87089 r88076  
    215215          'action': ['python', '<@(_inputs)', '<@(_arguments)', '<@(_outputs)'],
    216216        },
     217        {
     218          'action_name': 'klgen',
     219          'inputs': [
     220            '../KeywordLookupGenerator.py',
     221            '../parser/Keywords.table'
     222          ],
     223          'arguments': [
     224          ],
     225          'outputs': [
     226            '<(INTERMEDIATE_DIR)/KeywordLookup.h',
     227          ],
     228          'action': ['python', '<@(_inputs)', '<@(_arguments)', '<@(_outputs)'],
     229        },
    217230      ],
    218231      'include_dirs': [
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r87431 r88076  
    382382                A727FF6B0DA3092200E548D7 /* JSPropertyNameIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A727FF660DA3053B00E548D7 /* JSPropertyNameIterator.cpp */; };
    383383                A7280A2811557E3000D56957 /* JSObjectRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A79EDB0811531CD60019E912 /* JSObjectRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
     384                A72FFD64139985A800E5365A /* KeywordLookup.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C225CD1399849C00FF1662 /* KeywordLookup.h */; };
    384385                A730B6121250068F009D25B1 /* StrictEvalActivation.h in Headers */ = {isa = PBXBuildFile; fileRef = A730B6101250068F009D25B1 /* StrictEvalActivation.h */; };
    385386                A730B6131250068F009D25B1 /* StrictEvalActivation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A730B6111250068F009D25B1 /* StrictEvalActivation.cpp */; };
     
    11201121                A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocator.cpp; sourceTree = "<group>"; };
    11211122                A7C1E8C8112E701C00A37F98 /* JITPropertyAccess32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITPropertyAccess32_64.cpp; sourceTree = "<group>"; };
     1123                A7C225CC139981F100FF1662 /* KeywordLookupGenerator.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = KeywordLookupGenerator.py; sourceTree = "<group>"; };
     1124                A7C225CD1399849C00FF1662 /* KeywordLookup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeywordLookup.h; sourceTree = "<group>"; };
    11221125                A7C40C07130B057D00D002A1 /* BlockStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockStack.h; sourceTree = "<group>"; };
    11231126                A7C40C08130B057D00D002A1 /* SentinelLinkedList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentinelLinkedList.h; sourceTree = "<group>"; };
     
    13751378                                A718F8211178EB4B002465A7 /* create_regex_tables */,
    13761379                                937B63CC09E766D200A671DD /* DerivedSources.make */,
     1380                                A7C225CC139981F100FF1662 /* KeywordLookupGenerator.py */,
    13771381                                F692A8540255597D01FF60F7 /* create_hash_table */,
    13781382                                14B8ECA60A5653980062BE54 /* JavaScriptCore.exp */,
     
    16091613                                BC8149AF12F89F53007B2C32 /* HeaderDetection.h */,
    16101614                                BC87CDB810712ACA000614CF /* JSONObject.lut.h */,
     1615                                A7C225CD1399849C00FF1662 /* KeywordLookup.h */,
    16111616                                BC18C52D0E16FCE100B34460 /* Lexer.lut.h */,
    16121617                                BC18C5290E16FCC200B34460 /* MathObject.lut.h */,
     
    25482553                                14F97447138C853E00DA1C67 /* HeapRootVisitor.h in Headers */,
    25492554                                86BB09C1138E381B0056702F /* DFGRepatch.h in Headers */,
     2555                                A72FFD64139985A800E5365A /* KeywordLookup.h in Headers */,
    25502556                        );
    25512557                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/Source/JavaScriptCore/make-generated-sources.sh

    r57937 r88076  
    55export CREATE_HASH_TABLE="$SRCROOT/create_hash_table"
    66export CREATE_REGEXP_TABLES="$SRCROOT/create_regex_tables"
     7export CREATE_KEYWORD_LOOKUP="$SRCROOT/KeywordLookupGenerator.py"
    78
    89mkdir -p DerivedSources/JavaScriptCore
  • trunk/Source/JavaScriptCore/parser/Lexer.cpp

    r87177 r88076  
    4141
    4242#include "JSParser.h"
     43#include "KeywordLookup.h"
    4344#include "Lookup.h"
    4445#include "Lexer.lut.h"
     
    272273}
    273274
     275template <int shiftAmount, Lexer::ShiftType shouldBoundsCheck> ALWAYS_INLINE void Lexer::internalShift()
     276{
     277    if (shouldBoundsCheck == DoBoundsCheck) {
     278        // Faster than an if-else sequence
     279        ASSERT(m_current != -1);
     280        m_current = -1;
     281        m_code += shiftAmount;
     282        if (LIKELY(m_code < m_codeEnd))
     283            m_current = *m_code;
     284    } else {
     285        m_code += shiftAmount;
     286        m_current = *m_code;
     287    }
     288}
     289
    274290ALWAYS_INLINE void Lexer::shift()
    275291{
    276     // Faster than an if-else sequence
    277     ASSERT(m_current != -1);
    278     m_current = -1;
    279     ++m_code;
    280     if (LIKELY(m_code < m_codeEnd))
    281         m_current = *m_code;
     292    internalShift<1, DoBoundsCheck>();
    282293}
    283294
     
    402413template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer::parseIdentifier(JSTokenData* lvalp, unsigned lexType)
    403414{
     415    static const ptrdiff_t remaining = m_codeEnd - m_code;
     416    if ((remaining >= maxTokenLength) && !(lexType & IgnoreReservedWords)) {
     417        JSTokenType keyword = parseKeyword();
     418        if (keyword != IDENT)
     419            return keyword;
     420    }
     421    const UChar* identifierStart = currentCharacter();
    404422    bool bufferRequired = false;
    405     const UChar* identifierStart = currentCharacter();
    406     int identifierLength;
    407423
    408424    while (true) {
     
    431447        identifierStart = currentCharacter();
    432448    }
    433 
     449   
     450    int identifierLength;
    434451    const Identifier* ident = 0;
    435452    if (shouldCreateIdentifier) {
     
    453470        ASSERT(shouldCreateIdentifier);
    454471        // Keywords must not be recognized if there was an \uXXXX in the identifier.
    455         const HashEntry* entry = m_keywordTable.entry(m_globalData, *ident);
    456         return entry ? static_cast<JSTokenType>(entry->lexerValue()) : IDENT;
     472        if (remaining < maxTokenLength) {
     473            const HashEntry* entry = m_keywordTable.entry(m_globalData, *ident);
     474            ASSERT((remaining < maxTokenLength) || !entry);
     475            return entry ? static_cast<JSTokenType>(entry->lexerValue()) : IDENT;
     476        }
     477        return IDENT;
    457478    }
    458479
  • trunk/Source/JavaScriptCore/parser/Lexer.h

    r87177 r88076  
    114114        ALWAYS_INLINE bool lastTokenWasRestrKeyword() const;
    115115
     116        enum ShiftType { DoBoundsCheck, DoNotBoundsCheck };
     117        template <int shiftAmount, ShiftType shouldBoundsCheck> void internalShift();
     118        ALWAYS_INLINE JSTokenType parseKeyword();
    116119        template <bool shouldBuildIdentifiers> ALWAYS_INLINE JSTokenType parseIdentifier(JSTokenData*, unsigned);
    117120        template <bool shouldBuildStrings> ALWAYS_INLINE bool parseString(JSTokenData* lvalp, bool strictMode);
Note: See TracChangeset for help on using the changeset viewer.