Changeset 112454 in webkit


Ignore:
Timestamp:
Mar 28, 2012 3:18:20 PM (12 years ago)
Author:
barraclough@apple.com
Message:

Yarr: if we're not using the output array, don't populate it!
https://bugs.webkit.org/show_bug.cgi?id=82519

Reviewed by Sam Weinig.

../JavaScriptCore:

Add a new variant of the match method to RegExp that returns a MatchResult,
and modify YarrJIT to be able to compile code that doesn't use an output vector.

This is a 3% progression on v8-regexp.

  • JavaScriptCore.xcodeproj/project.pbxproj:
    • Moved MatchResult into its own header.
  • assembler/AbstractMacroAssembler.h:
    • Added missing include.
  • runtime/MatchResult.h: Added.

(MatchResult::MatchResult):
(MatchResult):
(MatchResult::failed):
(MatchResult::operator bool):
(MatchResult::empty):

  • Moved MatchResult into its own header.
  • runtime/RegExp.cpp:

(JSC::RegExp::compile):
(JSC::RegExp::compileIfNecessary):
(JSC::RegExp::match):

  • Changed due to execute & representation changes.

(JSC::RegExp::compileMatchOnly):
(JSC::RegExp::compileIfNecessaryMatchOnly):

  • Added helper to compile MatchOnly code.

(JSC::RegExp::invalidateCode):
(JSC::RegExp::matchCompareWithInterpreter):
(JSC::RegExp::printTraceData):

  • Changed due representation changes.
  • runtime/RegExp.h:

(RegExp):
(JSC::RegExp::hasCode):

  • Made YarrCodeBlock a member.
  • runtime/RegExpConstructor.h:

(RegExpConstructor):
(JSC::RegExpConstructor::performMatch):

  • Added no-ovector form.
  • runtime/RegExpMatchesArray.cpp:

(JSC::RegExpMatchesArray::reifyAllProperties):

  • Match now takes a reference to ovector, not a pointer.
  • runtime/RegExpObject.h:

(JSC):

  • Moved MatchResult into its own header.
  • runtime/StringPrototype.cpp:

(JSC::stringProtoFuncSplit):

  • Match now takes a reference to ovector, not a pointer.
  • testRegExp.cpp:

(testOneRegExp):

  • Match now takes a reference to ovector, not a pointer.
  • yarr/YarrJIT.cpp:

(Yarr):
(YarrGenerator):
(JSC::Yarr::YarrGenerator::initCallFrame):
(JSC::Yarr::YarrGenerator::removeCallFrame):
(JSC::Yarr::YarrGenerator::setSubpatternStart):
(JSC::Yarr::YarrGenerator::setSubpatternEnd):
(JSC::Yarr::YarrGenerator::clearSubpatternStart):
(JSC::Yarr::YarrGenerator::setMatchStart):
(JSC::Yarr::YarrGenerator::getMatchStart):

  • Added helper functions to intermediate access to output.

(JSC::Yarr::YarrGenerator::generateDotStarEnclosure):
(JSC::Yarr::YarrGenerator::generate):
(JSC::Yarr::YarrGenerator::backtrack):
(JSC::Yarr::YarrGenerator::generateEnter):
(JSC::Yarr::YarrGenerator::compile):

  • Changed to use the new helpers, only generate subpatterns if IncludeSubpatterns.

(JSC::Yarr::jitCompile):

  • Needs to template of MatchOnly or IncludeSubpatterns.
  • yarr/YarrJIT.h:

(YarrCodeBlock):
(JSC::Yarr::YarrCodeBlock::set8BitCode):
(JSC::Yarr::YarrCodeBlock::set16BitCode):
(JSC::Yarr::YarrCodeBlock::has8BitCodeMatchOnly):
(JSC::Yarr::YarrCodeBlock::has16BitCodeMatchOnly):
(JSC::Yarr::YarrCodeBlock::set8BitCodeMatchOnly):
(JSC::Yarr::YarrCodeBlock::set16BitCodeMatchOnly):
(JSC::Yarr::YarrCodeBlock::execute):
(JSC::Yarr::YarrCodeBlock::clear):

  • Added a second set of CodeRefs, so that we can compile RexExps with/without subpattern matching.

../WebCore:

  • ForwardingHeaders/runtime/MatchResult.h: Added.
  • ForwardingHeaders/yarr/YarrJIT.h: Added.
    • Added forwarding headers.
Location:
trunk/Source
Files:
3 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r112320 r112454  
     12012-03-28  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Yarr: if we're not using the output array, don't populate it!
     4        https://bugs.webkit.org/show_bug.cgi?id=82519
     5
     6        Reviewed by Sam Weinig.
     7
     8        Add a new variant of the match method to RegExp that returns a MatchResult,
     9        and modify YarrJIT to be able to compile code that doesn't use an output vector.
     10
     11        This is a 3% progression on v8-regexp.
     12
     13        * JavaScriptCore.xcodeproj/project.pbxproj:
     14            - Moved MatchResult into its own header.
     15        * assembler/AbstractMacroAssembler.h:
     16            - Added missing include.
     17        * runtime/MatchResult.h: Added.
     18        (MatchResult::MatchResult):
     19        (MatchResult):
     20        (MatchResult::failed):
     21        (MatchResult::operator bool):
     22        (MatchResult::empty):
     23            - Moved MatchResult into its own header.
     24        * runtime/RegExp.cpp:
     25        (JSC::RegExp::compile):
     26        (JSC::RegExp::compileIfNecessary):
     27        (JSC::RegExp::match):
     28            - Changed due to execute & representation changes.
     29        (JSC::RegExp::compileMatchOnly):
     30        (JSC::RegExp::compileIfNecessaryMatchOnly):
     31            - Added helper to compile MatchOnly code.
     32        (JSC::RegExp::invalidateCode):
     33        (JSC::RegExp::matchCompareWithInterpreter):
     34        (JSC::RegExp::printTraceData):
     35            - Changed due representation changes.
     36        * runtime/RegExp.h:
     37        (RegExp):
     38        (JSC::RegExp::hasCode):
     39            - Made YarrCodeBlock a member.
     40        * runtime/RegExpConstructor.h:
     41        (RegExpConstructor):
     42        (JSC::RegExpConstructor::performMatch):
     43            - Added no-ovector form.
     44        * runtime/RegExpMatchesArray.cpp:
     45        (JSC::RegExpMatchesArray::reifyAllProperties):
     46            - Match now takes a reference to ovector, not a pointer.
     47        * runtime/RegExpObject.h:
     48        (JSC):
     49            - Moved MatchResult into its own header.
     50        * runtime/StringPrototype.cpp:
     51        (JSC::stringProtoFuncSplit):
     52            - Match now takes a reference to ovector, not a pointer.
     53        * testRegExp.cpp:
     54        (testOneRegExp):
     55            - Match now takes a reference to ovector, not a pointer.
     56        * yarr/YarrJIT.cpp:
     57        (Yarr):
     58        (YarrGenerator):
     59        (JSC::Yarr::YarrGenerator::initCallFrame):
     60        (JSC::Yarr::YarrGenerator::removeCallFrame):
     61        (JSC::Yarr::YarrGenerator::setSubpatternStart):
     62        (JSC::Yarr::YarrGenerator::setSubpatternEnd):
     63        (JSC::Yarr::YarrGenerator::clearSubpatternStart):
     64        (JSC::Yarr::YarrGenerator::setMatchStart):
     65        (JSC::Yarr::YarrGenerator::getMatchStart):
     66            - Added helper functions to intermediate access to output.
     67        (JSC::Yarr::YarrGenerator::generateDotStarEnclosure):
     68        (JSC::Yarr::YarrGenerator::generate):
     69        (JSC::Yarr::YarrGenerator::backtrack):
     70        (JSC::Yarr::YarrGenerator::generateEnter):
     71        (JSC::Yarr::YarrGenerator::compile):
     72            - Changed to use the new helpers, only generate subpatterns if IncludeSubpatterns.
     73        (JSC::Yarr::jitCompile):
     74            - Needs to template of MatchOnly or IncludeSubpatterns.
     75        * yarr/YarrJIT.h:
     76        (YarrCodeBlock):
     77        (JSC::Yarr::YarrCodeBlock::set8BitCode):
     78        (JSC::Yarr::YarrCodeBlock::set16BitCode):
     79        (JSC::Yarr::YarrCodeBlock::has8BitCodeMatchOnly):
     80        (JSC::Yarr::YarrCodeBlock::has16BitCodeMatchOnly):
     81        (JSC::Yarr::YarrCodeBlock::set8BitCodeMatchOnly):
     82        (JSC::Yarr::YarrCodeBlock::set16BitCodeMatchOnly):
     83        (JSC::Yarr::YarrCodeBlock::execute):
     84        (JSC::Yarr::YarrCodeBlock::clear):
     85            - Added a second set of CodeRefs, so that we can compile RexExps with/without subpattern matching.
     86
    1872012-03-27  Filip Pizlo  <fpizlo@apple.com>
    288
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def

    r112177 r112454  
    250250    ?lockAtomicallyInitializedStaticMutex@WTF@@YAXXZ
    251251    ?lockCount@JSLock@JSC@@SAHXZ
    252     ?match@RegExp@JSC@@QAEHAAVJSGlobalData@2@ABVUString@2@IPAV?$Vector@H$0CA@@WTF@@@Z
     252    ?match@RegExp@JSC@@QAEHAAVJSGlobalData@2@ABVUString@2@IAAV?$Vector@H$0CA@@WTF@@@Z
    253253    ?materializePropertyMap@Structure@JSC@@AAEXAAVJSGlobalData@2@@Z
    254254    ?monotonicallyIncreasingTime@WTF@@YANXZ
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r112313 r112454  
    338338                8604F505143CE1C200B295F5 /* JSGlobalThis.h in Headers */ = {isa = PBXBuildFile; fileRef = 8604F503143CE1C100B295F5 /* JSGlobalThis.h */; settings = {ATTRIBUTES = (Private, ); }; };
    339339                860BD801148EA6F200112B2F /* Intrinsic.h in Headers */ = {isa = PBXBuildFile; fileRef = 86BF642A148DB2B5004DE36A /* Intrinsic.h */; settings = {ATTRIBUTES = (Private, ); }; };
     340                8612E4CD152389EC00C836BE /* MatchResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 8612E4CB1522918400C836BE /* MatchResult.h */; settings = {ATTRIBUTES = (Private, ); }; };
    340341                863B23E00FC6118900703AA4 /* MacroAssemblerCodeRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */; settings = {ATTRIBUTES = (Private, ); }; };
    341342                863C6D9C1521111A00585E4E /* YarrCanonicalizeUCS2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 863C6D981521111200585E4E /* YarrCanonicalizeUCS2.cpp */; };
     
    351352                86704B8512DBA33700A9FE7B /* YarrInterpreter.h in Headers */ = {isa = PBXBuildFile; fileRef = 86704B7E12DBA33700A9FE7B /* YarrInterpreter.h */; settings = {ATTRIBUTES = (Private, ); }; };
    352353                86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86704B7F12DBA33700A9FE7B /* YarrJIT.cpp */; };
    353                 86704B8712DBA33700A9FE7B /* YarrJIT.h in Headers */ = {isa = PBXBuildFile; fileRef = 86704B8012DBA33700A9FE7B /* YarrJIT.h */; settings = {ATTRIBUTES = (); }; };
     354                86704B8712DBA33700A9FE7B /* YarrJIT.h in Headers */ = {isa = PBXBuildFile; fileRef = 86704B8012DBA33700A9FE7B /* YarrJIT.h */; settings = {ATTRIBUTES = (Private, ); }; };
    354355                86704B8812DBA33700A9FE7B /* YarrParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 86704B8112DBA33700A9FE7B /* YarrParser.h */; settings = {ATTRIBUTES = (); }; };
    355356                86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86704B8212DBA33700A9FE7B /* YarrPattern.cpp */; };
     
    464465                A75706DE118A2BCF0057F88F /* JITArithmetic32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A75706DD118A2BCF0057F88F /* JITArithmetic32_64.cpp */; };
    465466                A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
    466                 A76C51761182748D00715B05 /* JSInterfaceJIT.h in Headers */ = {isa = PBXBuildFile; fileRef = A76C51741182748D00715B05 /* JSInterfaceJIT.h */; };
     467                A76C51761182748D00715B05 /* JSInterfaceJIT.h in Headers */ = {isa = PBXBuildFile; fileRef = A76C51741182748D00715B05 /* JSInterfaceJIT.h */; settings = {ATTRIBUTES = (Private, ); }; };
    467468                A76F54A313B28AAB00EF2BCE /* JITWriteBarrier.h in Headers */ = {isa = PBXBuildFile; fileRef = A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */; };
    468469                A781E359141970C700094D90 /* StorageBarrier.h in Headers */ = {isa = PBXBuildFile; fileRef = A781E358141970C700094D90 /* StorageBarrier.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    977978                8604F4F2143A6C4400B295F5 /* ChangeLog */ = {isa = PBXFileReference; lastKnownFileType = text; path = ChangeLog; sourceTree = "<group>"; };
    978979                8604F503143CE1C100B295F5 /* JSGlobalThis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalThis.h; sourceTree = "<group>"; };
     980                8612E4CB1522918400C836BE /* MatchResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MatchResult.h; sourceTree = "<group>"; };
    979981                863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerCodeRef.h; sourceTree = "<group>"; };
    980982                863C6D981521111200585E4E /* YarrCanonicalizeUCS2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = YarrCanonicalizeUCS2.cpp; path = yarr/YarrCanonicalizeUCS2.cpp; sourceTree = "<group>"; };
     
    14861488                        isa = PBXGroup;
    14871489                        children = (
    1488                                 0F0776BD14FF002800102332 /* JITCompilationEffort.h */,
    1489                                 0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */,
    1490                                 0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */,
    1491                                 0F46807F14BA572700BFE272 /* JITExceptions.cpp */,
    1492                                 0F46808014BA572700BFE272 /* JITExceptions.h */,
    14931490                                0FD82E37141AB14200179C94 /* CompactJITCodeMap.h */,
    14941491                                A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */,
    14951492                                A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */,
    14961493                                86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */,
     1494                                0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */,
     1495                                0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */,
    14971496                                1429D92D0ED22D7000B89619 /* JIT.cpp */,
    14981497                                1429D92E0ED22D7000B89619 /* JIT.h */,
     
    15021501                                146FE51111A710430087AE66 /* JITCall32_64.cpp */,
    15031502                                86CCEFDD0F413F8900FD7F9E /* JITCode.h */,
     1503                                0F0776BD14FF002800102332 /* JITCompilationEffort.h */,
    15041504                                0F21C26614BE5F5E00ADC64B /* JITDriver.h */,
     1505                                0F46807F14BA572700BFE272 /* JITExceptions.cpp */,
     1506                                0F46808014BA572700BFE272 /* JITExceptions.h */,
    15051507                                86CC85A00EE79A4700288682 /* JITInlineMethods.h */,
    15061508                                BCDD51E90FB8DF74004A8BDC /* JITOpcodes.cpp */,
     
    18521854                                F692A8680255597D01FF60F7 /* Lookup.cpp */,
    18531855                                F692A8690255597D01FF60F7 /* Lookup.h */,
     1856                                8612E4CB1522918400C836BE /* MatchResult.h */,
    18541857                                F692A86A0255597D01FF60F7 /* MathObject.cpp */,
    18551858                                F692A86B0255597D01FF60F7 /* MathObject.h */,
     
    25132516                                0F2BDC21151E803B00CD8910 /* DFGInsertionSet.h in Headers */,
    25142517                                0F2BDC2C151FDE9100CD8910 /* Operands.h in Headers */,
     2518                                8612E4CD152389EC00C836BE /* MatchResult.h in Headers */,
    25152519                        );
    25162520                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h

    r112192 r112454  
    2727#define AbstractMacroAssembler_h
    2828
     29#include "AssemblerBuffer.h"
    2930#include "CodeLocation.h"
    3031#include "MacroAssemblerCodeRef.h"
  • trunk/Source/JavaScriptCore/runtime/RegExp.cpp

    r111889 r112454  
    219219
    220220struct RegExpRepresentation {
    221 #if ENABLE(YARR_JIT)
    222     Yarr::YarrCodeBlock m_regExpJITCode;
    223 #endif
    224     OwnPtr<Yarr::BytecodePattern> m_regExpBytecode;
    225221};
    226222
     
    280276    ASSERT(m_numSubpatterns == pattern.m_numSubpatterns);
    281277
    282     if (!m_representation) {
     278    if (!hasCode()) {
    283279        ASSERT(m_state == NotCompiled);
    284         m_representation = adoptPtr(new RegExpRepresentation);
    285280        globalData->regExpCache()->addToStrongCache(this);
    286281        m_state = ByteCode;
     
    289284#if ENABLE(YARR_JIT)
    290285    if (!pattern.m_containsBackreferences && globalData->canUseJIT()) {
    291         Yarr::jitCompile(pattern, charSize, globalData, m_representation->m_regExpJITCode);
     286        Yarr::jitCompile(pattern, charSize, globalData, m_regExpJITCode);
    292287#if ENABLE(YARR_JIT_DEBUG)
    293         if (!m_representation->m_regExpJITCode.isFallBack())
     288        if (!m_regExpJITCode.isFallBack())
    294289            m_state = JITCode;
    295290        else
    296291            m_state = ByteCode;
    297292#else
    298         if (!m_representation->m_regExpJITCode.isFallBack()) {
     293        if (!m_regExpJITCode.isFallBack()) {
    299294            m_state = JITCode;
    300295            return;
     
    306301#endif
    307302
    308     m_representation->m_regExpBytecode = Yarr::byteCompile(pattern, &globalData->m_regExpAllocator);
     303    m_regExpBytecode = Yarr::byteCompile(pattern, &globalData->m_regExpAllocator);
    309304}
    310305
    311306void RegExp::compileIfNecessary(JSGlobalData& globalData, Yarr::YarrCharSize charSize)
    312307{
    313     // If the state is NotCompiled or ParseError, then there is no representation.
    314     // If there is a representation, and the state must be either JITCode or ByteCode.
    315     ASSERT(!!m_representation == (m_state == JITCode || m_state == ByteCode));
    316    
    317     if (m_representation) {
     308    if (hasCode()) {
    318309#if ENABLE(YARR_JIT)
    319310        if (m_state != JITCode)
    320311            return;
    321         if ((charSize == Yarr::Char8) && (m_representation->m_regExpJITCode.has8BitCode()))
    322             return;
    323         if ((charSize == Yarr::Char16) && (m_representation->m_regExpJITCode.has16BitCode()))
     312        if ((charSize == Yarr::Char8) && (m_regExpJITCode.has8BitCode()))
     313            return;
     314        if ((charSize == Yarr::Char16) && (m_regExpJITCode.has16BitCode()))
    324315            return;
    325316#else
     
    331322}
    332323
    333 int RegExp::match(JSGlobalData& globalData, const UString& s, unsigned startOffset, Vector<int, 32>* ovector)
     324int RegExp::match(JSGlobalData& globalData, const UString& s, unsigned startOffset, Vector<int, 32>& ovector)
    334325{
    335326#if ENABLE(REGEXP_TRACING)
     
    341332
    342333    int offsetVectorSize = (m_numSubpatterns + 1) * 2;
    343     int* offsetVector;
    344     Vector<int, 32> nonReturnedOvector;
    345     if (ovector) {
    346         ovector->resize(offsetVectorSize);
    347         offsetVector = ovector->data();
    348     } else {
    349         nonReturnedOvector.resize(offsetVectorSize);
    350         offsetVector = nonReturnedOvector.data();
    351     }
    352     ASSERT(offsetVector);
     334    ovector.resize(offsetVectorSize);
     335    int* offsetVector = ovector.data();
    353336
    354337    int result;
     
    356339    if (m_state == JITCode) {
    357340        if (s.is8Bit())
    358             result = Yarr::execute(m_representation->m_regExpJITCode, s.characters8(), startOffset, s.length(), offsetVector);
     341            result = m_regExpJITCode.execute(s.characters8(), startOffset, s.length(), offsetVector).start;
    359342        else
    360             result = Yarr::execute(m_representation->m_regExpJITCode, s.characters16(), startOffset, s.length(), offsetVector);
     343            result = m_regExpJITCode.execute(s.characters16(), startOffset, s.length(), offsetVector).start;
    361344#if ENABLE(YARR_JIT_DEBUG)
    362345        matchCompareWithInterpreter(s, startOffset, offsetVector, result);
     
    364347    } else
    365348#endif
    366         result = Yarr::interpret(m_representation->m_regExpBytecode.get(), s, startOffset, s.length(), reinterpret_cast<unsigned*>(offsetVector));
     349        result = Yarr::interpret(m_regExpBytecode.get(), s, startOffset, s.length(), reinterpret_cast<unsigned*>(offsetVector));
    367350
    368351    // FIXME: The YARR engine should handle unsigned or size_t length matches.
     
    405388}
    406389
     390void RegExp::compileMatchOnly(JSGlobalData* globalData, Yarr::YarrCharSize charSize)
     391{
     392    Yarr::YarrPattern pattern(m_patternString, ignoreCase(), multiline(), &m_constructionError);
     393    if (m_constructionError) {
     394        ASSERT_NOT_REACHED();
     395        m_state = ParseError;
     396        return;
     397    }
     398    ASSERT(m_numSubpatterns == pattern.m_numSubpatterns);
     399
     400    if (!hasCode()) {
     401        ASSERT(m_state == NotCompiled);
     402        globalData->regExpCache()->addToStrongCache(this);
     403        m_state = ByteCode;
     404    }
     405
     406#if ENABLE(YARR_JIT)
     407    if (!pattern.m_containsBackreferences && globalData->canUseJIT()) {
     408        Yarr::jitCompile(pattern, charSize, globalData, m_regExpJITCode, Yarr::MatchOnly);
     409#if ENABLE(YARR_JIT_DEBUG)
     410        if (!m_regExpJITCode.isFallBack())
     411            m_state = JITCode;
     412        else
     413            m_state = ByteCode;
     414#else
     415        if (!m_regExpJITCode.isFallBack()) {
     416            m_state = JITCode;
     417            return;
     418        }
     419#endif
     420    }
     421#else
     422    UNUSED_PARAM(charSize);
     423#endif
     424
     425    m_regExpBytecode = Yarr::byteCompile(pattern, &globalData->m_regExpAllocator);
     426}
     427
     428void RegExp::compileIfNecessaryMatchOnly(JSGlobalData& globalData, Yarr::YarrCharSize charSize)
     429{
     430    if (hasCode()) {
     431#if ENABLE(YARR_JIT)
     432        if (m_state != JITCode)
     433            return;
     434        if ((charSize == Yarr::Char8) && (m_regExpJITCode.has8BitCodeMatchOnly()))
     435            return;
     436        if ((charSize == Yarr::Char16) && (m_regExpJITCode.has16BitCodeMatchOnly()))
     437            return;
     438#else
     439        return;
     440#endif
     441    }
     442
     443    compileMatchOnly(&globalData, charSize);
     444}
     445
     446MatchResult RegExp::match(JSGlobalData& globalData, const UString& s, unsigned startOffset)
     447{
     448#if ENABLE(REGEXP_TRACING)
     449    m_rtMatchCallCount++;
     450#endif
     451
     452    ASSERT(m_state != ParseError);
     453    compileIfNecessaryMatchOnly(globalData, s.is8Bit() ? Yarr::Char8 : Yarr::Char16);
     454
     455#if ENABLE(YARR_JIT)
     456    if (m_state == JITCode) {
     457        MatchResult result = s.is8Bit() ?
     458            m_regExpJITCode.execute(s.characters8(), startOffset, s.length()) :
     459            m_regExpJITCode.execute(s.characters16(), startOffset, s.length());
     460#if ENABLE(REGEXP_TRACING)
     461        if (!result)
     462            m_rtMatchFoundCount++;
     463#endif
     464        return result;
     465    }
     466#endif
     467
     468    int offsetVectorSize = (m_numSubpatterns + 1) * 2;
     469    int* offsetVector;
     470    Vector<int, 32> nonReturnedOvector;
     471    nonReturnedOvector.resize(offsetVectorSize);
     472    offsetVector = nonReturnedOvector.data();
     473    int r = Yarr::interpret(m_regExpBytecode.get(), s, startOffset, s.length(), reinterpret_cast<unsigned*>(offsetVector));
     474#if REGEXP_FUNC_TEST_DATA_GEN
     475    RegExpFunctionalTestCollector::get()->outputOneTest(this, s, startOffset, offsetVector, result);
     476#endif
     477
     478    if (r >= 0) {
     479#if ENABLE(REGEXP_TRACING)
     480        m_rtMatchFoundCount++;
     481#endif
     482        return MatchResult(r, reinterpret_cast<unsigned*>(offsetVector)[1]);
     483    }
     484
     485    return MatchResult::failed();
     486}
     487
    407488void RegExp::invalidateCode()
    408489{
    409     if (!m_representation)
     490    if (!hasCode())
    410491        return;
    411492    m_state = NotCompiled;
    412     m_representation.clear();
     493    m_regExpJITCode.clear();
     494    m_regExpBytecode.clear();
    413495}
    414496
     
    429511        interpreterOffsetVector[j] = -1;
    430512
    431     interpreterResult = Yarr::interpret(m_representation->m_regExpBytecode.get(), s, startOffset, s.length(), interpreterOffsetVector);
     513    interpreterResult = Yarr::interpret(m_regExpBytecode.get(), s, startOffset, s.length(), interpreterOffsetVector);
    432514
    433515    if (jitResult != interpreterResult)
     
    478560
    479561#if ENABLE(YARR_JIT)
    480         Yarr::YarrCodeBlock& codeBlock = m_representation->m_regExpJITCode;
     562        Yarr::YarrCodeBlock& codeBlock = m_regExpJITCode;
    481563
    482564        const size_t jitAddrSize = 20;
  • trunk/Source/JavaScriptCore/runtime/RegExp.h

    r106189 r112454  
    2323#define RegExp_h
    2424
     25#include "ExecutableAllocator.h"
     26#include "MatchResult.h"
     27#include "RegExpKey.h"
     28#include "Structure.h"
    2529#include "UString.h"
    26 #include "ExecutableAllocator.h"
    27 #include "Structure.h"
    28 #include "RegExpKey.h"
    2930#include "yarr/Yarr.h"
    3031#include <wtf/Forward.h>
    3132#include <wtf/RefCounted.h>
     33
     34#if ENABLE(YARR_JIT)
     35#include "yarr/YarrJIT.h"
     36#endif
    3237
    3338namespace JSC {
     
    5459        const char* errorMessage() const { return m_constructionError; }
    5560
    56         JS_EXPORT_PRIVATE int match(JSGlobalData&, const UString&, unsigned startOffset, Vector<int, 32>* ovector = 0);
     61        JS_EXPORT_PRIVATE int match(JSGlobalData&, const UString&, unsigned startOffset, Vector<int, 32>& ovector);
     62        MatchResult match(JSGlobalData&, const UString&, unsigned startOffset);
    5763        unsigned numSubpatterns() const { return m_numSubpatterns; }
    5864
    5965        bool hasCode()
    6066        {
    61             return m_representation;
     67            return m_state != NotCompiled;
    6268        }
    6369
     
    96102        void compileIfNecessary(JSGlobalData&, Yarr::YarrCharSize);
    97103
     104        void compileMatchOnly(JSGlobalData*, Yarr::YarrCharSize);
     105        void compileIfNecessaryMatchOnly(JSGlobalData&, Yarr::YarrCharSize);
     106
    98107#if ENABLE(YARR_JIT_DEBUG)
    99108        void matchCompareWithInterpreter(const UString&, int startOffset, int* offsetVector, int jitResult);
     
    109118#endif
    110119
    111         OwnPtr<RegExpRepresentation> m_representation;
     120#if ENABLE(YARR_JIT)
     121        Yarr::YarrCodeBlock m_regExpJITCode;
     122#endif
     123        OwnPtr<Yarr::BytecodePattern> m_regExpBytecode;
    112124    };
    113125
  • trunk/Source/JavaScriptCore/runtime/RegExpConstructor.h

    r111889 r112454  
    5656        static const ClassInfo s_info;
    5757
    58         MatchResult performMatch(JSGlobalData&, RegExp*, JSString*, const UString&, int startOffset, int** ovector = 0);
     58        MatchResult performMatch(JSGlobalData&, RegExp*, JSString*, const UString&, int startOffset, int** ovector);
     59        MatchResult performMatch(JSGlobalData&, RegExp*, JSString*, const UString&, int startOffset);
    5960
    6061        void setMultiline(bool multiline) { m_multiline = multiline; }
     
    103104    ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(JSGlobalData& globalData, RegExp* regExp, JSString* string, const UString& input, int startOffset, int** ovector)
    104105    {
    105         int position = regExp->match(globalData, input, startOffset, &m_ovector);
     106        int position = regExp->match(globalData, input, startOffset, m_ovector);
    106107
    107108        if (ovector)
     
    120121        return MatchResult(position, end);
    121122    }
     123    ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(JSGlobalData& globalData, RegExp* regExp, JSString* string, const UString& input, int startOffset)
     124    {
     125        MatchResult result = regExp->match(globalData, input, startOffset);
     126        if (result)
     127            m_cachedResult.record(globalData, this, regExp, string, result);
     128        return result;
     129    }
    122130
    123131} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp

    r111889 r112454  
    5959    if (unsigned numSubpatterns = m_regExp->numSubpatterns()) {
    6060        Vector<int, 32> subpatternResults;
    61         int position = m_regExp->match(exec->globalData(), m_input->value(exec), m_result.start, &subpatternResults);
     61        int position = m_regExp->match(exec->globalData(), m_input->value(exec), m_result.start, subpatternResults);
    6262        ASSERT_UNUSED(position, position >= 0 && static_cast<size_t>(position) == m_result.start);
    6363        ASSERT(m_result.start == static_cast<size_t>(subpatternResults[0]));
  • trunk/Source/JavaScriptCore/runtime/RegExpObject.h

    r111603 r112454  
    2626
    2727namespace JSC {
    28    
    29     struct MatchResult {
    30         ALWAYS_INLINE MatchResult(size_t start, size_t end)
    31             : start(start)
    32             , end(end)
    33         {
    34         }
    35         ALWAYS_INLINE static MatchResult failed()
    36         {
    37             return MatchResult(WTF::notFound, 0);
    38         }
    39         ALWAYS_INLINE operator bool()
    40         {
    41             return start != WTF::notFound;
    42         }
    43         ALWAYS_INLINE bool empty()
    44         {
    45             return start == end;
    46         }
    47         size_t start;
    48         size_t end;
    49     };
    5028   
    5129    class RegExpObject : public JSNonFinalObject {
  • trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp

    r111889 r112454  
    964964            //    Property Descriptor {[[Value]]: S, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
    965965            // d. Return A.
    966             if (reg->match(*globalData, input, 0) < 0)
     966            if (!reg->match(*globalData, input, 0))
    967967                result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input), false);
    968968            return JSValue::encode(result);
     
    975975            // a. Call SplitMatch(S, q, R) and let z be its MatchResult result.
    976976            Vector<int, 32> ovector;
    977             int mpos = reg->match(*globalData, input, matchPosition, &ovector);
     977            int mpos = reg->match(*globalData, input, matchPosition, ovector);
    978978            // b. If z is failure, then let q = q + 1.
    979979            if (mpos < 0)
  • trunk/Source/JavaScriptCore/testRegExp.cpp

    r111618 r112454  
    216216    Vector<int, 32> outVector;
    217217    outVector.resize(regExpTest->expectVector.size());
    218     int matchResult = regexp->match(globalData, regExpTest->subject, regExpTest->offset, &outVector);
     218    int matchResult = regexp->match(globalData, regExpTest->subject, regExpTest->offset, outVector);
    219219
    220220    if (matchResult != regExpTest->result) {
  • trunk/Source/JavaScriptCore/yarr/YarrJIT.cpp

    r112192 r112454  
    3838namespace JSC { namespace Yarr {
    3939
     40template<YarrJITCompileMode compileMode>
    4041class YarrGenerator : private MacroAssembler {
    4142    friend void jitCompile(JSGlobalData*, YarrCodeBlock& jitObject, const UString& pattern, unsigned& numSubpatterns, const char*& error, bool ignoreCase, bool multiline);
     
    5152
    5253    static const RegisterID returnRegister = ARMRegisters::r0;
     54    static const RegisterID returnRegister2 = ARMRegisters::r1;
    5355#elif CPU(MIPS)
    5456    static const RegisterID input = MIPSRegisters::a0;
     
    6163
    6264    static const RegisterID returnRegister = MIPSRegisters::v0;
     65    static const RegisterID returnRegister2 = MIPSRegisters::v1;
    6366#elif CPU(SH4)
    6467    static const RegisterID input = SH4Registers::r4;
     
    7174
    7275    static const RegisterID returnRegister = SH4Registers::r0;
     76    static const RegisterID returnRegister2 = SH4Registers::r1;
    7377#elif CPU(X86)
    7478    static const RegisterID input = X86Registers::eax;
     
    8185
    8286    static const RegisterID returnRegister = X86Registers::eax;
     87    static const RegisterID returnRegister2 = X86Registers::edx;
    8388#elif CPU(X86_64)
    8489    static const RegisterID input = X86Registers::edi;
     
    9196
    9297    static const RegisterID returnRegister = X86Registers::eax;
     98    static const RegisterID returnRegister2 = X86Registers::edx;
    9399#endif
    94100
     
    304310    {
    305311        jump(Address(stackPointerRegister, frameLocation * sizeof(void*)));
     312    }
     313
     314    void initCallFrame()
     315    {
     316        unsigned callFrameSize = m_pattern.m_body->m_callFrameSize;
     317        if (callFrameSize)
     318            subPtr(Imm32(callFrameSize * sizeof(void*)), stackPointerRegister);
     319    }
     320    void removeCallFrame()
     321    {
     322        unsigned callFrameSize = m_pattern.m_body->m_callFrameSize;
     323        if (callFrameSize)
     324            addPtr(Imm32(callFrameSize * sizeof(void*)), stackPointerRegister);
     325    }
     326
     327    // Used to record subpatters, should only be called if compileMode is IncludeSubpatterns.
     328    void setSubpatternStart(RegisterID reg, unsigned subpattern)
     329    {
     330        ASSERT(subpattern);
     331        ASSERT(compileMode == IncludeSubpatterns);
     332        store32(reg, Address(output, (subpattern << 1) * sizeof(int)));
     333    }
     334    void setSubpatternEnd(RegisterID reg, unsigned subpattern)
     335    {
     336        ASSERT(subpattern);
     337        ASSERT(compileMode == IncludeSubpatterns);
     338        store32(reg, Address(output, ((subpattern << 1) + 1) * sizeof(int)));
     339    }
     340    void clearSubpatternStart(unsigned subpattern)
     341    {
     342        ASSERT(subpattern);
     343        ASSERT(compileMode == IncludeSubpatterns);
     344        store32(TrustedImm32(-1), Address(output, (subpattern << 1) * sizeof(int)));
     345    }
     346
     347    // We use one of three different strategies to track the start of the current match,
     348    // while matching.
     349    // 1) If the pattern has a fixed size, do nothing! - we calculate the value lazily
     350    //    at the end of matching. This is irrespective of compileMode, and in this case
     351    //    these methods should never be called.
     352    // 2) If we're compiling IncludeSubpatterns, 'output' contains a pointer to an output
     353    //    vector, store the match start in the output vector.
     354    // 3) If we're compiling MatchOnly, 'output' is unused, store the match start directly
     355    //    in this register.
     356    void setMatchStart(RegisterID reg)
     357    {
     358        ASSERT(!m_pattern.m_body->m_hasFixedSize);
     359        if (compileMode == IncludeSubpatterns)
     360            store32(reg, output);
     361        else
     362            move(reg, output);
     363    }
     364    void getMatchStart(RegisterID reg)
     365    {
     366        ASSERT(!m_pattern.m_body->m_hasFixedSize);
     367        if (compileMode == IncludeSubpatterns)
     368            load32(output, reg);
     369        else
     370            move(output, reg);
    306371    }
    307372
     
    10701135        JumpList foundEndingNewLine;
    10711136
    1072         if (m_pattern.m_body->m_hasFixedSize) {
    1073             move(index, matchPos);
    1074             sub32(Imm32(m_checked), matchPos);
    1075         } else
    1076             load32(Address(output), matchPos);
     1137        ASSERT(!m_pattern.m_body->m_hasFixedSize);
     1138        getMatchStart(matchPos);
    10771139
    10781140        saveStartIndex.append(branchTest32(Zero, matchPos));
     
    10941156            op.m_jumps.append(branchTest32(NonZero, matchPos));
    10951157
    1096         store32(matchPos, Address(output));
     1158        ASSERT(!m_pattern.m_body->m_hasFixedSize);
     1159        setMatchStart(matchPos);
    10971160
    10981161        move(index, matchPos);
     
    13161379               
    13171380                // Adjust the stack pointer to remove the pattern's frame.
    1318                 if (m_pattern.m_body->m_callFrameSize)
    1319                     addPtr(Imm32(m_pattern.m_body->m_callFrameSize * sizeof(void*)), stackPointerRegister);
     1381                removeCallFrame();
    13201382
    13211383                // Load appropriate values into the return register and the first output
     
    13271389                    if (priorAlternative->m_minimumSize)
    13281390                        sub32(Imm32(priorAlternative->m_minimumSize), returnRegister);
    1329                     store32(returnRegister, output);
     1391                    if (compileMode == IncludeSubpatterns)
     1392                        store32(returnRegister, output);
    13301393                } else
    1331                     load32(Address(output), returnRegister);
    1332                 store32(index, Address(output, 4));
     1394                    getMatchStart(returnRegister);
     1395                if (compileMode == IncludeSubpatterns)
     1396                    store32(index, Address(output, 4));
     1397                move(index, returnRegister2);
     1398
    13331399                generateReturn();
    13341400
     
    15131579                // offsets only afterwards, at the point the results array is
    15141580                // being accessed.
    1515                 if (term->capture()) {
    1516                     int offsetId = term->parentheses.subpatternId << 1;
     1581                if (term->capture() && compileMode == IncludeSubpatterns) {
    15171582                    int inputOffset = term->inputPosition - m_checked;
    15181583                    if (term->quantityType == QuantifierFixedCount)
     
    15211586                        move(index, indexTemporary);
    15221587                        add32(Imm32(inputOffset), indexTemporary);
    1523                         store32(indexTemporary, Address(output, offsetId * sizeof(int)));
     1588                        setSubpatternStart(indexTemporary, term->parentheses.subpatternId);
    15241589                    } else
    1525                         store32(index, Address(output, offsetId * sizeof(int)));
     1590                        setSubpatternStart(index, term->parentheses.subpatternId);
    15261591                }
    15271592                break;
     
    15491614                // offsets only afterwards, at the point the results array is
    15501615                // being accessed.
    1551                 if (term->capture()) {
    1552                     int offsetId = (term->parentheses.subpatternId << 1) + 1;
     1616                if (term->capture() && compileMode == IncludeSubpatterns) {
    15531617                    int inputOffset = term->inputPosition - m_checked;
    15541618                    if (inputOffset) {
    15551619                        move(index, indexTemporary);
    15561620                        add32(Imm32(inputOffset), indexTemporary);
    1557                         store32(indexTemporary, Address(output, offsetId * sizeof(int)));
     1621                        setSubpatternEnd(indexTemporary, term->parentheses.subpatternId);
    15581622                    } else
    1559                         store32(index, Address(output, offsetId * sizeof(int)));
     1623                        setSubpatternEnd(index, term->parentheses.subpatternId);
    15601624                }
    15611625
     
    16471711
    16481712            case OpMatchFailed:
    1649                 if (m_pattern.m_body->m_callFrameSize)
    1650                     addPtr(Imm32(m_pattern.m_body->m_callFrameSize * sizeof(void*)), stackPointerRegister);
    1651                 move(TrustedImm32(-1), returnRegister);
     1713                removeCallFrame();
     1714                move(TrustedImmPtr((void*)WTF::notFound), returnRegister);
     1715                move(TrustedImm32(0), returnRegister2);
    16521716                generateReturn();
    16531717                break;
     
    17441808                        if (!m_pattern.m_body->m_hasFixedSize) {
    17451809                            if (alternative->m_minimumSize == 1)
    1746                                 store32(index, Address(output));
     1810                                setMatchStart(index);
    17471811                            else {
    17481812                                move(index, regT0);
     
    17511815                                else
    17521816                                    add32(TrustedImm32(1), regT0);
    1753                                 store32(regT0, Address(output));
     1817                                setMatchStart(regT0);
    17541818                            }
    17551819                        }
     
    18371901                if (needsToUpdateMatchStart && alternative->m_minimumSize == 1) {
    18381902                    // index is already incremented by 1, so just store it now!
    1839                     store32(index, Address(output));
     1903                    setMatchStart(index);
    18401904                    needsToUpdateMatchStart = false;
    18411905                }
     
    18611925                if (needsToUpdateMatchStart) {
    18621926                    if (!m_pattern.m_body->m_minimumSize)
    1863                         store32(index, Address(output));
     1927                        setMatchStart(index);
    18641928                    else {
    18651929                        move(index, regT0);
    18661930                        sub32(Imm32(m_pattern.m_body->m_minimumSize), regT0);
    1867                         store32(regT0, Address(output));
     1931                        setMatchStart(regT0);
    18681932                    }
    18691933                }
     
    18871951                matchFailed.link(this);
    18881952
    1889                 if (m_pattern.m_body->m_callFrameSize)
    1890                     addPtr(Imm32(m_pattern.m_body->m_callFrameSize * sizeof(void*)), stackPointerRegister);
    1891                 move(TrustedImm32(-1), returnRegister);
     1953                removeCallFrame();
     1954                move(TrustedImmPtr((void*)WTF::notFound), returnRegister);
     1955                move(TrustedImm32(0), returnRegister2);
    18921956                generateReturn();
    18931957                break;
     
    20562120
    20572121                // We only need to backtrack to thispoint if capturing or greedy.
    2058                 if (term->capture() || term->quantityType == QuantifierGreedy) {
     2122                if ((term->capture() && compileMode == IncludeSubpatterns) || term->quantityType == QuantifierGreedy) {
    20592123                    m_backtrackingState.link(this);
    20602124
    20612125                    // If capturing, clear the capture (we only need to reset start).
    2062                     if (term->capture())
    2063                         store32(TrustedImm32(-1), Address(output, (term->parentheses.subpatternId << 1) * sizeof(int)));
     2126                    if (term->capture() && compileMode == IncludeSubpatterns)
     2127                        clearSubpatternStart(term->parentheses.subpatternId);
    20642128
    20652129                    // If Greedy, jump to the end.
     
    24512515        loadPtr(Address(X86Registers::ebp, 3 * sizeof(void*)), index);
    24522516        loadPtr(Address(X86Registers::ebp, 4 * sizeof(void*)), length);
    2453         loadPtr(Address(X86Registers::ebp, 5 * sizeof(void*)), output);
     2517        if (compileMode == IncludeSubpatterns)
     2518            loadPtr(Address(X86Registers::ebp, 5 * sizeof(void*)), output);
    24542519    #else
    2455         loadPtr(Address(X86Registers::ebp, 2 * sizeof(void*)), output);
     2520        if (compileMode == IncludeSubpatterns)
     2521            loadPtr(Address(X86Registers::ebp, 2 * sizeof(void*)), output);
    24562522    #endif
    24572523#elif CPU(ARM)
     
    24622528        push(ARMRegisters::r8); // scratch register
    24632529#endif
    2464         move(ARMRegisters::r3, output);
     2530        if (compileMode == IncludeSubpatterns)
     2531            move(ARMRegisters::r3, output);
    24652532#elif CPU(SH4)
    24662533        push(SH4Registers::r11);
     
    25122579
    25132580        Jump hasInput = checkInput();
    2514         move(TrustedImm32(-1), returnRegister);
     2581        move(TrustedImmPtr((void*)WTF::notFound), returnRegister);
     2582        move(TrustedImm32(0), returnRegister2);
    25152583        generateReturn();
    25162584        hasInput.link(this);
    25172585
    2518         for (unsigned i = 0; i < m_pattern.m_numSubpatterns + 1; ++i)
    2519             store32(TrustedImm32(-1), Address(output, (i << 1) * sizeof(int)));
     2586        if (compileMode == IncludeSubpatterns) {
     2587            for (unsigned i = 0; i < m_pattern.m_numSubpatterns + 1; ++i)
     2588                store32(TrustedImm32(-1), Address(output, (i << 1) * sizeof(int)));
     2589        }
    25202590
    25212591        if (!m_pattern.m_body->m_hasFixedSize)
    2522             store32(index, Address(output));
    2523 
    2524         if (m_pattern.m_body->m_callFrameSize)
    2525             subPtr(Imm32(m_pattern.m_body->m_callFrameSize * sizeof(void*)), stackPointerRegister);
     2592            setMatchStart(index);
     2593
     2594        initCallFrame();
    25262595
    25272596        // Compile the pattern to the internal 'YarrOp' representation.
     
    25412610        LinkBuffer linkBuffer(*globalData, this, REGEXP_CODE_ID);
    25422611        m_backtrackingState.linkDataLabels(linkBuffer);
    2543         if (m_charSize == Char8)
    2544             jitObject.set8BitCode(linkBuffer.finalizeCode());
    2545         else
    2546             jitObject.set16BitCode(linkBuffer.finalizeCode());
     2612
     2613        if (compileMode == MatchOnly) {
     2614            if (m_charSize == Char8)
     2615                jitObject.set8BitCodeMatchOnly(linkBuffer.finalizeCode());
     2616            else
     2617                jitObject.set16BitCodeMatchOnly(linkBuffer.finalizeCode());
     2618        } else {
     2619            if (m_charSize == Char8)
     2620                jitObject.set8BitCode(linkBuffer.finalizeCode());
     2621            else
     2622                jitObject.set16BitCode(linkBuffer.finalizeCode());
     2623        }
    25472624        jitObject.setFallBack(m_shouldFallBack);
    25482625    }
     
    25782655};
    25792656
    2580 void jitCompile(YarrPattern& pattern, YarrCharSize charSize, JSGlobalData* globalData, YarrCodeBlock& jitObject)
     2657void jitCompile(YarrPattern& pattern, YarrCharSize charSize, JSGlobalData* globalData, YarrCodeBlock& jitObject, YarrJITCompileMode mode)
    25812658{
    2582     YarrGenerator(pattern, charSize).compile(globalData, jitObject);
     2659    if (mode == MatchOnly)
     2660        YarrGenerator<MatchOnly>(pattern, charSize).compile(globalData, jitObject);
     2661    else
     2662        YarrGenerator<IncludeSubpatterns>(pattern, charSize).compile(globalData, jitObject);
    25832663}
    25842664
  • trunk/Source/JavaScriptCore/yarr/YarrJIT.h

    r103641 r112454  
    3030
    3131#include "JSGlobalData.h"
    32 #include "MacroAssembler.h"
     32#include "MacroAssemblerCodeRef.h"
     33#include "MatchResult.h"
    3334#include "UString.h"
    3435#include "Yarr.h"
     
    4950
    5051class YarrCodeBlock {
    51     typedef int (*YarrJITCode8)(const LChar* input, unsigned start, unsigned length, int* output) YARR_CALL;
    52     typedef int (*YarrJITCode16)(const UChar* input, unsigned start, unsigned length, int* output) YARR_CALL;
     52#if CPU(X86_64)
     53    typedef MatchResult (*YarrJITCode8)(const LChar* input, unsigned start, unsigned length, int* output) YARR_CALL;
     54    typedef MatchResult (*YarrJITCode16)(const UChar* input, unsigned start, unsigned length, int* output) YARR_CALL;
     55    typedef MatchResult (*YarrJITCodeMatchOnly8)(const LChar* input, unsigned start, unsigned length) YARR_CALL;
     56    typedef MatchResult (*YarrJITCodeMatchOnly16)(const UChar* input, unsigned start, unsigned length) YARR_CALL;
     57#else
     58    typedef EncodedMatchResult (*YarrJITCode8)(const LChar* input, unsigned start, unsigned length, int* output) YARR_CALL;
     59    typedef EncodedMatchResult (*YarrJITCode16)(const UChar* input, unsigned start, unsigned length, int* output) YARR_CALL;
     60    typedef EncodedMatchResult (*YarrJITCodeMatchOnly8)(const LChar* input, unsigned start, unsigned length) YARR_CALL;
     61    typedef EncodedMatchResult (*YarrJITCodeMatchOnly16)(const UChar* input, unsigned start, unsigned length) YARR_CALL;
     62#endif
    5363
    5464public:
     
    6474    void setFallBack(bool fallback) { m_needFallBack = fallback; }
    6575    bool isFallBack() { return m_needFallBack; }
     76
    6677    bool has8BitCode() { return m_ref8.size(); }
    6778    bool has16BitCode() { return m_ref16.size(); }
    68     void set8BitCode(MacroAssembler::CodeRef ref) { m_ref8 = ref; }
    69     void set16BitCode(MacroAssembler::CodeRef ref) { m_ref16 = ref; }
     79    void set8BitCode(MacroAssemblerCodeRef ref) { m_ref8 = ref; }
     80    void set16BitCode(MacroAssemblerCodeRef ref) { m_ref16 = ref; }
    7081
    71     int execute(const LChar* input, unsigned start, unsigned length, int* output)
     82    bool has8BitCodeMatchOnly() { return m_matchOnly8.size(); }
     83    bool has16BitCodeMatchOnly() { return m_matchOnly16.size(); }
     84    void set8BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly8 = matchOnly; }
     85    void set16BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly16 = matchOnly; }
     86
     87    MatchResult execute(const LChar* input, unsigned start, unsigned length, int* output)
    7288    {
    7389        ASSERT(has8BitCode());
    74         return reinterpret_cast<YarrJITCode8>(m_ref8.code().executableAddress())(input, start, length, output);
     90        return MatchResult(reinterpret_cast<YarrJITCode8>(m_ref8.code().executableAddress())(input, start, length, output));
    7591    }
    7692
    77     int execute(const UChar* input, unsigned start, unsigned length, int* output)
     93    MatchResult execute(const UChar* input, unsigned start, unsigned length, int* output)
    7894    {
    7995        ASSERT(has16BitCode());
    80         return reinterpret_cast<YarrJITCode16>(m_ref16.code().executableAddress())(input, start, length, output);
     96        return MatchResult(reinterpret_cast<YarrJITCode16>(m_ref16.code().executableAddress())(input, start, length, output));
    8197    }
     98
     99    MatchResult execute(const LChar* input, unsigned start, unsigned length)
     100    {
     101        ASSERT(has8BitCodeMatchOnly());
     102        return MatchResult(reinterpret_cast<YarrJITCodeMatchOnly8>(m_matchOnly8.code().executableAddress())(input, start, length));
     103    }
     104
     105    MatchResult execute(const UChar* input, unsigned start, unsigned length)
     106    {
     107        ASSERT(has16BitCodeMatchOnly());
     108        return MatchResult(reinterpret_cast<YarrJITCodeMatchOnly16>(m_matchOnly16.code().executableAddress())(input, start, length));
     109    }
     110
    82111#if ENABLE(REGEXP_TRACING)
    83112    void *getAddr() { return m_ref.code().executableAddress(); }
    84113#endif
    85114
     115    void clear()
     116    {
     117        m_ref8 = MacroAssemblerCodeRef();
     118        m_ref16 = MacroAssemblerCodeRef();
     119        m_matchOnly8 = MacroAssemblerCodeRef();
     120        m_matchOnly16 = MacroAssemblerCodeRef();
     121        m_needFallBack = false;
     122    }
     123
    86124private:
    87     MacroAssembler::CodeRef m_ref8;
    88     MacroAssembler::CodeRef m_ref16;
     125    MacroAssemblerCodeRef m_ref8;
     126    MacroAssemblerCodeRef m_ref16;
     127    MacroAssemblerCodeRef m_matchOnly8;
     128    MacroAssemblerCodeRef m_matchOnly16;
    89129    bool m_needFallBack;
    90130};
    91131
    92 void jitCompile(YarrPattern&, YarrCharSize, JSGlobalData*, YarrCodeBlock& jitObject);
    93 
    94 inline int execute(YarrCodeBlock& jitObject, const LChar* input, unsigned start, unsigned length, int* output)
    95 {
    96     return jitObject.execute(input, start, length, output);
    97 }
    98 
    99 inline int execute(YarrCodeBlock& jitObject, const UChar* input, unsigned start, unsigned length, int* output)
    100 {
    101     return jitObject.execute(input, start, length, output);
    102 }
     132enum YarrJITCompileMode {
     133    MatchOnly,
     134    IncludeSubpatterns
     135};
     136void jitCompile(YarrPattern&, YarrCharSize, JSGlobalData*, YarrCodeBlock& jitObject, YarrJITCompileMode = IncludeSubpatterns);
    103137
    104138} } // namespace JSC::Yarr
  • trunk/Source/WebCore/ChangeLog

    r112453 r112454  
     12012-03-28  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Yarr: if we're not using the output array, don't populate it!
     4        https://bugs.webkit.org/show_bug.cgi?id=82519
     5
     6        Reviewed by Sam Weinig.
     7
     8        * ForwardingHeaders/runtime/MatchResult.h: Added.
     9        * ForwardingHeaders/yarr/YarrJIT.h: Added.
     10            - Added forwarding headers.
     11
    1122012-03-23  David Hyatt  <hyatt@apple.com>
    213
Note: See TracChangeset for help on using the changeset viewer.