Changeset 94981 in webkit


Ignore:
Timestamp:
Sep 12, 2011 3:17:53 PM (13 years ago)
Author:
msaboff@apple.com
Message:

Update RegExp and related classes to use 8 bit strings when available
https://bugs.webkit.org/show_bug.cgi?id=67337

Source/JavaScriptCore:

Modified both the Yarr interpreter and JIT to handle 8 bit subject strings.
The code paths are triggered by the UString::is8bit() method which currently
returns false. Implemented JIT changes for all current architectures.
Tested X86_64 and ARM v7.

This includes some code that will likely change as we complete the
8 bit string changes. This includes the way the raw buffer pointers
are accessed as well as replacing the CharAccess class with a
string interator returned from UString.

Fixed build breakage in testRegExp.cpp due to globalObject construction
changes.

Reviewed by Gavin Barraclough.

(GlobalObject::finishCreation):
(GlobalObject::GlobalObject):

  • assembler/ARMAssembler.cpp:

(JSC::ARMAssembler::baseIndexTransfer32):

  • assembler/ARMAssembler.h:
  • assembler/ARMv7Assembler.h:

(JSC::ARMv7Assembler::ubfx):
(JSC::ARMv7Assembler::ARMInstructionFormatter::twoWordOp12Reg40Imm3Reg4Imm20Imm5):

  • assembler/MacroAssemblerARM.h:

(JSC::MacroAssemblerARM::load8):
(JSC::MacroAssemblerARM::branch8):
(JSC::MacroAssemblerARM::branch16):

  • assembler/MacroAssemblerARMv7.h:

(JSC::MacroAssemblerARMv7::load8):
(JSC::MacroAssemblerARMv7::branch16):
(JSC::MacroAssemblerARMv7::branch8):

  • assembler/MacroAssemblerMIPS.h:

(JSC::MacroAssemblerMIPS::load8):
(JSC::MacroAssemblerMIPS::branch8):
(JSC::MacroAssemblerMIPS::branch16):

  • assembler/MacroAssemblerSH4.h:

(JSC::MacroAssemblerSH4::load8):
(JSC::MacroAssemblerSH4::branch8):
(JSC::MacroAssemblerSH4::branch16):

  • assembler/MacroAssemblerX86Common.h:

(JSC::MacroAssemblerX86Common::load8):
(JSC::MacroAssemblerX86Common::branch16):
(JSC::MacroAssemblerX86Common::branch8):

  • assembler/SH4Assembler.h:

(JSC::SH4Assembler::extub):
(JSC::SH4Assembler::printInstr):

  • assembler/X86Assembler.h:

(JSC::X86Assembler::cmpw_ir):
(JSC::X86Assembler::movzbl_mr):

  • runtime/RegExp.cpp:

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

  • runtime/RegExp.h:
  • runtime/UString.h:

(JSC::UString::is8Bit):

  • yarr/Yarr.h:
  • yarr/YarrInterpreter.cpp:

(JSC::Yarr::Interpreter::CharAccess::CharAccess):
(JSC::Yarr::Interpreter::CharAccess::~CharAccess):
(JSC::Yarr::Interpreter::CharAccess::operator[]):
(JSC::Yarr::Interpreter::InputStream::InputStream):
(JSC::Yarr::Interpreter::Interpreter):
(JSC::Yarr::interpret):

  • yarr/YarrJIT.cpp:

(JSC::Yarr::YarrGenerator::jumpIfCharNotEquals):
(JSC::Yarr::YarrGenerator::readCharacter):
(JSC::Yarr::YarrGenerator::generatePatternCharacterOnce):
(JSC::Yarr::YarrGenerator::generatePatternCharacterFixed):
(JSC::Yarr::YarrGenerator::generatePatternCharacterGreedy):
(JSC::Yarr::YarrGenerator::backtrackPatternCharacterNonGreedy):
(JSC::Yarr::YarrGenerator::generateCharacterClassFixed):
(JSC::Yarr::YarrGenerator::generateDotStarEnclosure):
(JSC::Yarr::YarrGenerator::YarrGenerator):
(JSC::Yarr::YarrGenerator::compile):
(JSC::Yarr::jitCompile):
(JSC::Yarr::execute):

  • yarr/YarrJIT.h:

(JSC::Yarr::YarrCodeBlock::has8BitCode):
(JSC::Yarr::YarrCodeBlock::has16BitCode):
(JSC::Yarr::YarrCodeBlock::set8BitCode):
(JSC::Yarr::YarrCodeBlock::set16BitCode):
(JSC::Yarr::YarrCodeBlock::execute):

  • yarr/YarrParser.h:

(JSC::Yarr::Parser::Parser):

Source/WebCore:

Updated call to match to use UString& instead of UChar*.

Reviewed by Gavin Barraclough.

No new tests, Covered by existing tests.

  • platform/text/RegularExpression.cpp:

(WebCore::RegularExpression::match):

Location:
trunk/Source
Files:
24 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r94954 r94981  
     12011-09-12  Michael Saboff  <msaboff@apple.com>
     2
     3        Update RegExp and related classes to use 8 bit strings when available
     4        https://bugs.webkit.org/show_bug.cgi?id=67337
     5
     6        Modified both the Yarr interpreter and JIT to handle 8 bit subject strings.
     7        The code paths are triggered by the UString::is8bit() method which currently
     8        returns false.  Implemented JIT changes for all current architectures.
     9        Tested X86_64 and ARM v7.
     10
     11        This includes some code that will likely change as we complete the
     12        8 bit string changes.  This includes the way the raw buffer pointers
     13        are accessed as well as replacing the CharAccess class with a
     14        string interator returned from UString.
     15
     16        Fixed build breakage in testRegExp.cpp due to globalObject construction
     17        changes.
     18
     19        Reviewed by Gavin Barraclough.
     20
     21        * JavaScriptCore.exp:
     22        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
     23        * testRegExp.cpp:
     24        (GlobalObject::finishCreation):
     25        (GlobalObject::GlobalObject):
     26        * assembler/ARMAssembler.cpp:
     27        (JSC::ARMAssembler::baseIndexTransfer32):
     28        * assembler/ARMAssembler.h:
     29        * assembler/ARMv7Assembler.h:
     30        (JSC::ARMv7Assembler::ubfx):
     31        (JSC::ARMv7Assembler::ARMInstructionFormatter::twoWordOp12Reg40Imm3Reg4Imm20Imm5):
     32        * assembler/MacroAssemblerARM.h:
     33        (JSC::MacroAssemblerARM::load8):
     34        (JSC::MacroAssemblerARM::branch8):
     35        (JSC::MacroAssemblerARM::branch16):
     36        * assembler/MacroAssemblerARMv7.h:
     37        (JSC::MacroAssemblerARMv7::load8):
     38        (JSC::MacroAssemblerARMv7::branch16):
     39        (JSC::MacroAssemblerARMv7::branch8):
     40        * assembler/MacroAssemblerMIPS.h:
     41        (JSC::MacroAssemblerMIPS::load8):
     42        (JSC::MacroAssemblerMIPS::branch8):
     43        (JSC::MacroAssemblerMIPS::branch16):
     44        * assembler/MacroAssemblerSH4.h:
     45        (JSC::MacroAssemblerSH4::load8):
     46        (JSC::MacroAssemblerSH4::branch8):
     47        (JSC::MacroAssemblerSH4::branch16):
     48        * assembler/MacroAssemblerX86Common.h:
     49        (JSC::MacroAssemblerX86Common::load8):
     50        (JSC::MacroAssemblerX86Common::branch16):
     51        (JSC::MacroAssemblerX86Common::branch8):
     52        * assembler/SH4Assembler.h:
     53        (JSC::SH4Assembler::extub):
     54        (JSC::SH4Assembler::printInstr):
     55        * assembler/X86Assembler.h:
     56        (JSC::X86Assembler::cmpw_ir):
     57        (JSC::X86Assembler::movzbl_mr):
     58        * runtime/RegExp.cpp:
     59        (JSC::RegExp::compile):
     60        (JSC::RegExp::compileIfNecessary):
     61        (JSC::RegExp::match):
     62        (JSC::RegExp::matchCompareWithInterpreter):
     63        * runtime/RegExp.h:
     64        * runtime/UString.h:
     65        (JSC::UString::is8Bit):
     66        * yarr/Yarr.h:
     67        * yarr/YarrInterpreter.cpp:
     68        (JSC::Yarr::Interpreter::CharAccess::CharAccess):
     69        (JSC::Yarr::Interpreter::CharAccess::~CharAccess):
     70        (JSC::Yarr::Interpreter::CharAccess::operator[]):
     71        (JSC::Yarr::Interpreter::InputStream::InputStream):
     72        (JSC::Yarr::Interpreter::Interpreter):
     73        (JSC::Yarr::interpret):
     74        * yarr/YarrJIT.cpp:
     75        (JSC::Yarr::YarrGenerator::jumpIfCharNotEquals):
     76        (JSC::Yarr::YarrGenerator::readCharacter):
     77        (JSC::Yarr::YarrGenerator::generatePatternCharacterOnce):
     78        (JSC::Yarr::YarrGenerator::generatePatternCharacterFixed):
     79        (JSC::Yarr::YarrGenerator::generatePatternCharacterGreedy):
     80        (JSC::Yarr::YarrGenerator::backtrackPatternCharacterNonGreedy):
     81        (JSC::Yarr::YarrGenerator::generateCharacterClassFixed):
     82        (JSC::Yarr::YarrGenerator::generateDotStarEnclosure):
     83        (JSC::Yarr::YarrGenerator::YarrGenerator):
     84        (JSC::Yarr::YarrGenerator::compile):
     85        (JSC::Yarr::jitCompile):
     86        (JSC::Yarr::execute):
     87        * yarr/YarrJIT.h:
     88        (JSC::Yarr::YarrCodeBlock::has8BitCode):
     89        (JSC::Yarr::YarrCodeBlock::has16BitCode):
     90        (JSC::Yarr::YarrCodeBlock::set8BitCode):
     91        (JSC::Yarr::YarrCodeBlock::set16BitCode):
     92        (JSC::Yarr::YarrCodeBlock::execute):
     93        * yarr/YarrParser.h:
     94        (JSC::Yarr::Parser::Parser):
     95
    1962011-09-12  Andras Becsi  <andras.becsi@nokia.com>
    297
  • trunk/Source/JavaScriptCore/JavaScriptCore.exp

    r94930 r94981  
    249249__ZN3JSC4Heap8capacityEv
    250250__ZN3JSC4Heap9unprotectENS_7JSValueE
     251__ZN3JSC4Yarr9interpretEPNS0_15BytecodePatternERKNS_7UStringEjjPi
    251252__ZN3JSC4Yarr11YarrPatternC1ERKNS_7UStringEbbPPKc
    252253__ZN3JSC4Yarr11byteCompileERNS0_11YarrPatternEPN3WTF20BumpPointerAllocatorE
    253 __ZN3JSC4Yarr9interpretEPNS0_15BytecodePatternEPKtjjPi
    254254__ZN3JSC4callEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataES2_RKNS_7ArgListE
    255255__ZN3JSC6JSCell11getCallDataERNS_8CallDataE
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def

    r94930 r94981  
    2323    ??0UString@JSC@@QAE@PBD@Z
    2424    ??0UString@JSC@@QAE@PBDI@Z
     25    ??0UString@JSC@@QAE@PB_W@Z
    2526    ??0UString@JSC@@QAE@PB_WI@Z
    2627    ??0WTFThreadData@WTF@@QAE@XZ
     
    232233    ?initializeThreading@JSC@@YAXXZ
    233234    ?initializeThreading@WTF@@YAXXZ
    234     ?interpret@Yarr@JSC@@YAHPAUBytecodePattern@12@PB_WIIPAH@Z
     235    ?interpret@Yarr@JSC@@YAHPAUBytecodePattern@12@ABVUString@2@IIPAH@Z
    235236    ?isAccessorDescriptor@PropertyDescriptor@JSC@@QBE_NXZ
    236237    ?isBusy@Heap@JSC@@QAE_NXZ
  • trunk/Source/JavaScriptCore/assembler/ARMAssembler.cpp

    r94922 r94981  
    289289}
    290290
    291 void ARMAssembler::baseIndexTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset)
     291void ARMAssembler::baseIndexTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset, bool bytes)
    292292{
    293293    ARMWord op2;
     294    ARMWord transferFlag = bytes ? DT_BYTE : 0;
    294295
    295296    ASSERT(scale >= 0 && scale <= 3);
     
    298299    if (offset >= 0 && offset <= 0xfff) {
    299300        add_r(ARMRegisters::S0, base, op2);
    300         dtr_u(isLoad, srcDst, ARMRegisters::S0, offset);
     301        dtr_u(isLoad, srcDst, ARMRegisters::S0, offset | transferFlag);
    301302        return;
    302303    }
    303304    if (offset <= 0 && offset >= -0xfff) {
    304305        add_r(ARMRegisters::S0, base, op2);
    305         dtr_d(isLoad, srcDst, ARMRegisters::S0, -offset);
     306        dtr_d(isLoad, srcDst, ARMRegisters::S0, (-offset & 0xfff) | transferFlag);
    306307        return;
    307308    }
     
    309310    ldr_un_imm(ARMRegisters::S0, offset);
    310311    add_r(ARMRegisters::S0, ARMRegisters::S0, op2);
    311     dtr_ur(isLoad, srcDst, base, ARMRegisters::S0);
     312    dtr_ur(isLoad, srcDst, base, ARMRegisters::S0 | transferFlag);
    312313}
    313314
  • trunk/Source/JavaScriptCore/assembler/ARMAssembler.h

    r94922 r94981  
    849849
    850850        void dataTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, int32_t offset, bool bytes = false);
    851         void baseIndexTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset);
     851        void baseIndexTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset, bool bytes = false);
    852852        void doubleTransfer(bool isLoad, FPRegisterID srcDst, RegisterID base, int32_t offset);
    853853
  • trunk/Source/JavaScriptCore/assembler/ARMv7Assembler.h

    r90586 r94981  
    601601        OP_SUB_imm_T4   = 0xF2A0,
    602602        OP_MOVT         = 0xF2C0,
     603        OP_UBFX_T1      = 0xF3C0,
    603604        OP_NOP_T2a      = 0xF3AF,
    604605        OP_LDRB_imm_T3  = 0xF810,
     
    14791480        else
    14801481            m_formatter.oneWordOp10Reg3Reg3(OP_TST_reg_T1, rm, rn);
     1482    }
     1483
     1484    ALWAYS_INLINE void ubfx(RegisterID rd, RegisterID rn, unsigned lsb, unsigned width)
     1485    {
     1486        ASSERT(lsb < 32);
     1487        ASSERT((width >= 1) && (width <= 32));
     1488        ASSERT((lsb + width) <= 32);
     1489        m_formatter.twoWordOp12Reg40Imm3Reg4Imm20Imm5(OP_UBFX_T1, rd, rn, (lsb & 0x1c) << 10, (lsb & 0x3) << 6, (width - 1) & 0x1f);
    14811490    }
    14821491
     
    22482257        }
    22492258
     2259        ALWAYS_INLINE void twoWordOp12Reg40Imm3Reg4Imm20Imm5(OpcodeID1 op, RegisterID reg1, RegisterID reg2, uint16_t imm1, uint16_t imm2, uint16_t imm3)
     2260        {
     2261            m_buffer.putShort(op | reg1);
     2262            m_buffer.putShort((imm1 << 12) | (reg2 << 8) | (imm2 << 6) | imm3);
     2263        }
     2264
    22502265        // Formats up instructions of the pattern:
    22512266        //    111111111B11aaaa:bbbb222SA2C2cccc
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM.h

    r94622 r94981  
    254254    }
    255255
     256    void load8(BaseIndex address, RegisterID dest)
     257    {
     258        m_assembler.baseIndexTransfer32(true, dest, address.base, address.index, static_cast<int>(address.scale), address.offset, true);
     259    }
     260
    256261    void load32(ImplicitAddress address, RegisterID dest)
    257262    {
     
    407412    {
    408413        load8(left, ARMRegisters::S1);
     414        return branch32(cond, ARMRegisters::S1, right);
     415    }
     416
     417    Jump branch8(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
     418    {
     419        ASSERT(!(right.m_value & 0xFFFFFF00));
     420        load8(left, ARMRegisters::S1);
     421        return branch32(cond, ARMRegisters::S1, right);
     422    }
     423
     424    Jump branch16(RelationalCondition cond, RegisterID left, TrustedImm32 right)
     425    {
     426        ASSERT(!(right.m_value & 0xFFFF0000));
     427        right.m_value <<= 16;
     428        m_assembler.mov_r(ARMRegisters::S1, left);
     429        lshift32(16, ARMRegisters::S1)
    409430        return branch32(cond, ARMRegisters::S1, right);
    410431    }
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h

    r91275 r94981  
    484484    }
    485485
     486    void load8(BaseIndex address, RegisterID dest)
     487    {
     488        load8(setupArmAddress(address), dest);
     489    }
     490   
    486491    DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest)
    487492    {
     
    964969    }
    965970
     971    Jump branch16(RelationalCondition cond, RegisterID left, TrustedImm32 right)
     972    {
     973        ASSERT(!(0xffff0000 & right.m_value));
     974        // Extract the lower 16 bits into a temp for comparison
     975        m_assembler.ubfx(dataTempRegister, left, 0, 16);
     976        return branch32(cond, dataTempRegister, right);
     977    }
     978   
    966979    Jump branch16(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
    967980    {
     
    980993    Jump branch8(RelationalCondition cond, Address left, TrustedImm32 right)
    981994    {
     995        ASSERT(!(0xffffff00 & right.m_value));
    982996        // use addressTempRegister incase the branch8 we call uses dataTempRegister. :-/
    983997        load8(left, addressTempRegister);
     
    985999    }
    9861000
     1001    Jump branch8(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
     1002    {
     1003        ASSERT(!(0xffffff00 & right.m_value));
     1004        // use addressTempRegister incase the branch32 we call uses dataTempRegister. :-/
     1005        load8(left, addressTempRegister);
     1006        return branch32(cond, addressTempRegister, right);
     1007    }
     1008   
    9871009    Jump branchTest32(ResultCondition cond, RegisterID reg, RegisterID mask)
    9881010    {
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h

    r90687 r94981  
    497497    }
    498498
     499    void load8(BaseIndex address, RegisterID dest)
     500    {
     501        if (address.offset >= -32768 && address.offset <= 32767
     502            && !m_fixedWidth) {
     503            /*
     504             sll     addrTemp, address.index, address.scale
     505             addu    addrTemp, addrTemp, address.base
     506             lbu     dest, address.offset(addrTemp)
     507             */
     508            m_assembler.sll(addrTempRegister, address.index, address.scale);
     509            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
     510            m_assembler.lbu(dest, addrTempRegister, address.offset);
     511        } else {
     512            /*
     513             sll     addrTemp, address.index, address.scale
     514             addu    addrTemp, addrTemp, address.base
     515             lui     immTemp, (address.offset + 0x8000) >> 16
     516             addu    addrTemp, addrTemp, immTemp
     517             lbu     dest, (address.offset & 0xffff)(at)
     518             */
     519            m_assembler.sll(addrTempRegister, address.index, address.scale);
     520            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
     521            m_assembler.lui(immTempRegister, (address.offset + 0x8000) >> 16);
     522            m_assembler.addu(addrTempRegister, addrTempRegister,
     523                             immTempRegister);
     524            m_assembler.lbu(dest, addrTempRegister, address.offset);
     525        }
     526    }
     527
    499528    void load32(ImplicitAddress address, RegisterID dest)
    500529    {
     
    933962    }
    934963
     964    Jump branch8(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
     965    {
     966        ASSERT(!(right.m_value & 0xFFFFFF00));
     967        load8(left, dataTempRegister);
     968        // Be careful that the previous load8() uses immTempRegister.
     969        // So, we need to put move() after load8().
     970        move(right, immTempRegister);
     971        return branch32(cond, dataTempRegister, immTempRegister);
     972    }
     973
    935974    Jump branch32(RelationalCondition cond, RegisterID left, RegisterID right)
    936975    {
     
    10311070        move(right, immTempRegister);
    10321071        return branch32(cond, dataTempRegister, immTempRegister);
     1072    }
     1073
     1074    Jump branch16(RelationalCondition cond, RegisterID left, TrustedImm32 right)
     1075    {
     1076        // Make sure the immediate value is unsigned 16 bits.
     1077        ASSERT(!(right.m_value & 0xFFFF0000));
     1078        m_assembler.andi(immTempRegister, left, 0xffff);
     1079        return branch32(cond, immTempRegister, right);
    10331080    }
    10341081
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h

    r93277 r94981  
    510510    }
    511511
     512    void load8(BaseIndex address, RegisterID dest)
     513    {
     514        RegisterID scr = claimScratch();
     515        move(address.index, scr);
     516        lshift32(TrustedImm32(address.scale), scr);
     517        add32(address.base, scr);
     518        load8(scr, address.offset, dest);
     519        releaseScratch(scr);
     520    }
     521
    512522    void load32(BaseIndex address, RegisterID dest)
    513523    {
     
    13531363    }
    13541364
     1365    Jump branch8(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
     1366    {
     1367        ASSERT(!(right.m_value & 0xFFFFFF00));
     1368        RegisterID scr = claimScratch();
     1369
     1370        move(left.index, scr);
     1371        lshift32(TrustedImm32(left.scale), scr);
     1372
     1373        if (left.offset)
     1374            add32(TrustedImm32(left.offset), scr);
     1375        add32(left.base, scr);
     1376        load8(scr, scr);
     1377        extub(scr, scr);
     1378        RegisterID scr1 = claimScratch();
     1379        m_assembler.loadConstant(right.m_value, scr1);
     1380        releaseScratch(scr);
     1381        releaseScratch(scr1);
     1382
     1383        return branch32(cond, scr, scr1);
     1384    }
     1385
     1386    Jump branch16(RelationalCondition cond, RegisterID left, TrustedImm32 right)
     1387    {
     1388        ASSERT(!(right.m_value & 0xFFFF0000));
     1389        RegisterID scr = claimScratch();
     1390
     1391        extuw(left, scr);
     1392        if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
     1393            m_assembler.testlRegReg(scr, scr);
     1394        else
     1395            compare32(right.m_value, scr, cond);
     1396
     1397        releaseScratch(scr);
     1398
     1399        if (cond == NotEqual)
     1400            return branchFalse();
     1401        return branchTrue();
     1402    }
     1403
    13551404    Jump branch16(RelationalCondition cond,  BaseIndex left, RegisterID right)
    13561405    {
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h

    r90352 r94981  
    476476    }
    477477
     478    void load8(BaseIndex address, RegisterID dest)
     479    {
     480        m_assembler.movzbl_mr(address.offset, address.base, address.index, address.scale, dest);
     481    }
     482
    478483    void load16(BaseIndex address, RegisterID dest)
    479484    {
     
    874879    }
    875880
     881    Jump branch16(RelationalCondition cond, RegisterID left, TrustedImm32 right)
     882    {
     883        if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
     884            m_assembler.testw_rr(left, left);
     885        else
     886            m_assembler.cmpw_ir(right.m_value, left);
     887        return Jump(m_assembler.jCC(x86Condition(cond)));
     888    }
     889
    876890    Jump branch16(RelationalCondition cond, BaseIndex left, RegisterID right)
    877891    {
     
    954968        else
    955969            m_assembler.testb_im(mask.m_value, address.offset, address.base, address.index, address.scale);
     970        return Jump(m_assembler.jCC(x86Condition(cond)));
     971    }
     972
     973    Jump branch8(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
     974    {
     975        ASSERT(!(right.m_value & 0xFFFFFF00));
     976
     977        m_assembler.cmpb_im(right.m_value, left.offset, left.base, left.index, left.scale);
    956978        return Jump(m_assembler.jCC(x86Condition(cond)));
    957979    }
  • trunk/Source/JavaScriptCore/assembler/SH4Assembler.h

    r93277 r94981  
    153153    TSTIMM_OPCODE = 0xc800,
    154154    TSTB_OPCODE = 0xcc00,
     155    EXTUB_OPCODE = 0x600c,
    155156    EXTUW_OPCODE = 0x600d,
    156157    XOR_OPCODE = 0x200a,
     
    759760    }
    760761
     762    void extub(RegisterID src, RegisterID dst)
     763    {
     764        uint16_t opc = getOpcodeGroup1(EXTUB_OPCODE, dst, src);
     765        oneShortOp(opc);
     766    }
     767   
    761768    void extuw(RegisterID src, RegisterID dst)
    762769    {
     
    18111818            format = "    MOV.W @(R0, R%d), R%d\n";
    18121819            break;
     1820        case EXTUB_OPCODE:
     1821            format = "    EXTU.B R%d, R%d\n";
     1822            break;
    18131823        case EXTUW_OPCODE:
    18141824            format = "    EXTU.W R%d, R%d\n";
  • trunk/Source/JavaScriptCore/assembler/X86Assembler.h

    r94920 r94981  
    843843#endif
    844844
     845    void cmpw_ir(int imm, RegisterID dst)
     846    {
     847        if (CAN_SIGN_EXTEND_8_32(imm)) {
     848            m_formatter.prefix(PRE_OPERAND_SIZE);
     849            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
     850            m_formatter.immediate8(imm);
     851        } else {
     852            m_formatter.prefix(PRE_OPERAND_SIZE);
     853            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
     854            m_formatter.immediate16(imm);
     855        }
     856    }
     857
    845858    void cmpw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
    846859    {
     
    11581171    {
    11591172        m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, index, scale, offset);
     1173    }
     1174
     1175    void movzbl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
     1176    {
     1177        m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, base, index, scale, offset);
    11601178    }
    11611179
  • trunk/Source/JavaScriptCore/runtime/RegExp.cpp

    r94468 r94981  
    268268}
    269269
    270 void RegExp::compile(JSGlobalData* globalData)
    271 {
    272     ASSERT(m_state == NotCompiled);
    273     m_representation = adoptPtr(new RegExpRepresentation);
     270void RegExp::compile(JSGlobalData* globalData, Yarr::YarrCharSize charSize)
     271{
    274272    Yarr::YarrPattern pattern(m_patternString, ignoreCase(), multiline(), &m_constructionError);
    275273    if (m_constructionError) {
     
    278276        return;
    279277    }
    280 
    281     globalData->regExpCache()->addToStrongCache(this);
    282 
    283278    ASSERT(m_numSubpatterns == pattern.m_numSubpatterns);
    284279
    285     m_state = ByteCode;
     280    if (!m_representation) {
     281        ASSERT(m_state == NotCompiled);
     282        m_representation = adoptPtr(new RegExpRepresentation);
     283        globalData->regExpCache()->addToStrongCache(this);
     284        m_state = ByteCode;
     285    }
    286286
    287287#if ENABLE(YARR_JIT)
    288288    if (!pattern.m_containsBackreferences && globalData->canUseJIT()) {
    289         Yarr::jitCompile(pattern, globalData, m_representation->m_regExpJITCode);
     289        Yarr::jitCompile(pattern, charSize, globalData, m_representation->m_regExpJITCode);
    290290#if ENABLE(YARR_JIT_DEBUG)
    291291        if (!m_representation->m_regExpJITCode.isFallBack())
     
    300300#endif
    301301    }
     302#else
     303    UNUSED_PARAM(charSize);
    302304#endif
    303305
    304306    m_representation->m_regExpBytecode = Yarr::byteCompile(pattern, &globalData->m_regExpAllocator);
    305307}
     308
     309void RegExp::compileIfNecessary(JSGlobalData& globalData, Yarr::YarrCharSize charSize)
     310{
     311    // If the state is NotCompiled or ParseError, then there is no representation.
     312    // If there is a representation, and the state must be either JITCode or ByteCode.
     313    ASSERT(!!m_representation == (m_state == JITCode || m_state == ByteCode));
     314   
     315    if (m_representation) {
     316#if ENABLE(YARR_JIT)
     317        if (m_state != JITCode)
     318            return;
     319        if ((charSize == Yarr::Char8) && (m_representation->m_regExpJITCode.has8BitCode()))
     320            return;
     321        if ((charSize == Yarr::Char16) && (m_representation->m_regExpJITCode.has16BitCode()))
     322            return;
     323#else
     324        return;
     325#endif
     326    }
     327
     328    compile(&globalData, charSize);
     329}
     330
    306331
    307332int RegExp::match(JSGlobalData& globalData, const UString& s, int startOffset, Vector<int, 32>* ovector)
     
    318343
    319344    if (m_state != ParseError) {
    320         compileIfNecessary(globalData);
     345        compileIfNecessary(globalData, s.is8Bit() ? Yarr::Char8 : Yarr::Char16);
    321346
    322347        int offsetVectorSize = (m_numSubpatterns + 1) * 2;
     
    341366#if ENABLE(YARR_JIT)
    342367        if (m_state == JITCode) {
    343             result = Yarr::execute(m_representation->m_regExpJITCode, s.characters(), startOffset, s.length(), offsetVector);
     368            if (s.is8Bit())
     369                result = Yarr::execute(m_representation->m_regExpJITCode, s.latin1().data(), startOffset, s.length(), offsetVector);
     370            else
     371                result = Yarr::execute(m_representation->m_regExpJITCode, s.characters(), startOffset, s.length(), offsetVector);
    344372#if ENABLE(YARR_JIT_DEBUG)
    345373            matchCompareWithInterpreter(s, startOffset, offsetVector, result);
     
    347375        } else
    348376#endif
    349             result = Yarr::interpret(m_representation->m_regExpBytecode.get(), s.characters(), startOffset, s.length(), offsetVector);
     377            result = Yarr::interpret(m_representation->m_regExpBytecode.get(), s, startOffset, s.length(), offsetVector);
    350378        ASSERT(result >= -1);
    351379
     
    389417        interpreterOffsetVector[j] = -1;
    390418
    391     interpreterResult = Yarr::interpret(m_representation->m_regExpBytecode.get(), s.characters(), startOffset, s.length(), interpreterOffsetVector);
     419    interpreterResult = Yarr::interpret(m_representation->m_regExpBytecode.get(), s, startOffset, s.length(), interpreterOffsetVector);
    392420
    393421    if (jitResult != interpreterResult)
  • trunk/Source/JavaScriptCore/runtime/RegExp.h

    r94929 r94981  
    2727#include "Structure.h"
    2828#include "RegExpKey.h"
     29#include "yarr/Yarr.h"
    2930#include <wtf/Forward.h>
    3031#include <wtf/RefCounted.h>
     
    9293        } m_state;
    9394
    94         void compile(JSGlobalData*);
    95         void compileIfNecessary(JSGlobalData& globalData)
    96         {
    97             if (m_representation)
    98                 return;
    99             compile(&globalData);
    100         }
     95        void compile(JSGlobalData*, Yarr::YarrCharSize);
     96        void compileIfNecessary(JSGlobalData&, Yarr::YarrCharSize);
    10197
    10298#if ENABLE(YARR_JIT_DEBUG)
  • trunk/Source/JavaScriptCore/runtime/UString.h

    r88355 r94981  
    7676        return m_impl->characters();
    7777    }
     78
     79    bool is8Bit() const { return false; }
    7880
    7981    CString ascii() const;
  • trunk/Source/JavaScriptCore/testRegExp.cpp

    r94470 r94981  
    121121    }
    122122    virtual UString className() const { return "global"; }
     123
     124protected:
     125    void finishCreation(JSGlobalData& globalData, const Vector<UString>& arguments)
     126    {
     127        Base::finishCreation(globalData, this);
     128        UNUSED_PARAM(arguments);
     129    }
    123130};
    124131
     
    129136    : JSGlobalObject(globalData, structure)
    130137{
    131     UNUSED_PARAM(arguments);
     138    finishCreation(globalData, arguments);
    132139}
    133140
  • trunk/Source/JavaScriptCore/yarr/Yarr.h

    r78042 r94981  
    5858};
    5959
     60enum YarrCharSize {
     61    Char8,
     62    Char16
     63};
     64
    6065PassOwnPtr<BytecodePattern> byteCompile(YarrPattern&, BumpPointerAllocator*);
    61 int interpret(BytecodePattern*, const UChar* input, unsigned start, unsigned length, int* output);
     66int interpret(BytecodePattern*, const UString& input, unsigned start, unsigned length, int* output);
    6267
    6368} } // namespace JSC::Yarr
  • trunk/Source/JavaScriptCore/yarr/YarrInterpreter.cpp

    r94207 r94981  
    2828#include "YarrInterpreter.h"
    2929
     30#include "UString.h"
    3031#include "Yarr.h"
    3132#include <wtf/BumpPointerAllocator.h>
     33#include <wtf/text/CString.h>
    3234
    3335#ifndef NDEBUG
     
    167169    }
    168170
     171    // This class is a placeholder for future character iterator, current
     172    // proposed name StringConstCharacterIterator.
     173    class CharAccess {
     174    public:
     175        CharAccess(const UString& s)
     176            : m_buffer(0)
     177        {
     178            if (s.is8Bit()) {
     179                m_charSize = Char8;
     180                unsigned length = s.length();
     181                m_ptr.ptr8 = m_buffer = static_cast<char *>(fastMalloc(length));
     182                memcpy(m_buffer, s.latin1().data(), length);
     183            } else {
     184                m_charSize = Char16;
     185                m_ptr.ptr16 = s.characters();
     186            }
     187        }
     188
     189        CharAccess(const char* ptr)
     190            : m_charSize(Char8)
     191            , m_buffer(0)
     192        {
     193            m_ptr.ptr8 = ptr;
     194        }
     195
     196        CharAccess(const UChar* ptr)
     197            : m_charSize(Char16)
     198            , m_buffer(0)
     199        {
     200            m_ptr.ptr16 = ptr;
     201        }
     202
     203        ~CharAccess()
     204        {
     205            if (m_charSize == Char8)
     206                fastFree(m_buffer);
     207        }
     208
     209        inline UChar operator[](unsigned index)
     210        {
     211            if (m_charSize == Char8)
     212                return m_ptr.ptr8[index];
     213            return m_ptr.ptr16[index];
     214        }
     215
     216    private:
     217        union {
     218            const char* ptr8;
     219            const UChar* ptr16;
     220        } m_ptr;
     221        YarrCharSize m_charSize;
     222        char* m_buffer;
     223    };
     224
    169225    class InputStream {
    170226    public:
    171         InputStream(const UChar* input, unsigned start, unsigned length)
     227        InputStream(const UString& input, unsigned start, unsigned length)
    172228            : input(input)
    173229            , pos(start)
     
    279335
    280336    private:
    281         const UChar* input;
     337        CharAccess input;
    282338        unsigned pos;
    283339        unsigned length;
     
    14211477    }
    14221478
    1423     Interpreter(BytecodePattern* pattern, int* output, const UChar* inputChar, unsigned start, unsigned length)
     1479    Interpreter(BytecodePattern* pattern, int* output, const UString input, unsigned start, unsigned length)
    14241480        : pattern(pattern)
    14251481        , output(output)
    1426         , input(inputChar, start, length)
     1482        , input(input, start, length)
    14271483        , allocatorPool(0)
    14281484        , remainingMatchCount(matchLimit)
     
    19111967}
    19121968
    1913 int interpret(BytecodePattern* bytecode, const UChar* input, unsigned start, unsigned length, int* output)
     1969int interpret(BytecodePattern* bytecode, const UString& input, unsigned start, unsigned length, int* output)
    19141970{
    19151971    return Interpreter(bytecode, output, input, start, length).interpret();
  • trunk/Source/JavaScriptCore/yarr/YarrJIT.cpp

    r94920 r94981  
    257257    }
    258258
    259     Jump jumpIfCharEquals(UChar ch, int inputPosition)
    260     {
    261         return branch16(Equal, BaseIndex(input, index, TimesTwo, inputPosition * sizeof(UChar)), Imm32(ch));
    262     }
    263 
    264259    Jump jumpIfCharNotEquals(UChar ch, int inputPosition)
    265260    {
     261        if (m_charSize == Char8)
     262            return branch8(NotEqual, BaseIndex(input, index, TimesOne, inputPosition * sizeof(char)), Imm32(ch));
    266263        return branch16(NotEqual, BaseIndex(input, index, TimesTwo, inputPosition * sizeof(UChar)), Imm32(ch));
    267264    }
     
    269266    void readCharacter(int inputPosition, RegisterID reg)
    270267    {
    271         load16(BaseIndex(input, index, TimesTwo, inputPosition * sizeof(UChar)), reg);
     268        if (m_charSize == Char8)
     269            load8(BaseIndex(input, index, TimesOne, inputPosition * sizeof(char)), reg);
     270        else
     271            load16(BaseIndex(input, index, TimesTwo, inputPosition * sizeof(UChar)), reg);
    272272    }
    273273
     
    659659        UChar ch = term->patternCharacter;
    660660
     661        if ((ch > 0xff) && (m_charSize == Char8)) {
     662            // Have a 16 bit pattern character and an 8 bit string - short circuit
     663            op.m_jumps.append(jump());
     664            return;
     665        }
     666
    661667        const RegisterID character = regT0;
    662668
     
    670676                UChar ch2 = nextTerm->patternCharacter;
    671677
     678                int shiftAmount = m_charSize == Char8 ? 8 : 16;
    672679                int mask = 0;
    673                 int chPair = ch | (ch2 << 16);
     680                int chPair = ch | (ch2 << shiftAmount);
    674681
    675682                if (m_pattern.m_ignoreCase) {
     
    677684                        mask |= 32;
    678685                    if (isASCIIAlpha(ch2))
    679                         mask |= 32 << 16;
    680                 }
    681 
    682                 BaseIndex address(input, index, TimesTwo, (term->inputPosition - m_checked) * sizeof(UChar));
    683                 if (mask) {
    684                     load32WithUnalignedHalfWords(address, character);
    685                     or32(Imm32(mask), character);
    686                     op.m_jumps.append(branch32(NotEqual, character, Imm32(chPair | mask)));
    687                 } else
    688                     op.m_jumps.append(branch32WithUnalignedHalfWords(NotEqual, address, Imm32(chPair)));
    689 
     686                        mask |= 32 << shiftAmount;
     687                }
     688
     689                if (m_charSize == Char8) {
     690                    BaseIndex address(input, index, TimesOne, (term->inputPosition - m_checked) * sizeof(char));
     691                    if (mask) {
     692                        load16(address, character);
     693                        or32(Imm32(mask), character);
     694                        op.m_jumps.append(branch16(NotEqual, character, Imm32(chPair | mask)));
     695                    } else
     696                        op.m_jumps.append(branch16(NotEqual, address, Imm32(chPair)));
     697                } else {
     698                    BaseIndex address(input, index, TimesTwo, (term->inputPosition - m_checked) * sizeof(UChar));
     699                    if (mask) {
     700                        load32WithUnalignedHalfWords(address, character);
     701                        or32(Imm32(mask), character);
     702                        op.m_jumps.append(branch32(NotEqual, character, Imm32(chPair | mask)));
     703                    } else
     704                        op.m_jumps.append(branch32WithUnalignedHalfWords(NotEqual, address, Imm32(chPair)));
     705                }
    690706                nextOp.m_isDeadCode = true;
    691707                return;
     
    720736
    721737        Label loop(this);
    722         BaseIndex address(input, countRegister, TimesTwo, (Checked<int>(term->inputPosition - m_checked + Checked<int64_t>(term->quantityCount)) * static_cast<int>(sizeof(UChar))).unsafeGet());
     738        BaseIndex address(input, countRegister, m_charScale, (Checked<int>(term->inputPosition - m_checked + Checked<int64_t>(term->quantityCount)) * static_cast<int>(m_charSize == Char8 ? sizeof(char) : sizeof(UChar))).unsafeGet());
    723739
    724740        if (m_pattern.m_ignoreCase && isASCIIAlpha(ch)) {
    725             load16(address, character);
     741            if (m_charSize == Char8)
     742                load8(address, character);
     743            else
     744                load16(address, character);
    726745            or32(TrustedImm32(32), character);
    727746            op.m_jumps.append(branch32(NotEqual, character, Imm32(Unicode::toLower(ch))));
    728747        } else {
    729748            ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch)));
    730             op.m_jumps.append(branch16(NotEqual, address, Imm32(ch)));
     749            if (m_charSize == Char8)
     750                op.m_jumps.append(branch8(NotEqual, address, Imm32(ch)));
     751            else
     752                op.m_jumps.append(branch16(NotEqual, address, Imm32(ch)));
    731753        }
    732754        add32(TrustedImm32(1), countRegister);
     
    749771        move(TrustedImm32(0), countRegister);
    750772
    751         JumpList failures;
    752         Label loop(this);
    753         failures.append(atEndOfInput());
    754         if (m_pattern.m_ignoreCase && isASCIIAlpha(ch)) {
    755             readCharacter(term->inputPosition - m_checked, character);
    756             or32(TrustedImm32(32), character);
    757             failures.append(branch32(NotEqual, character, Imm32(Unicode::toLower(ch))));
     773        if ((ch > 0xff) && (m_charSize == Char8)) {
     774            // Have a 16 bit pattern character and an 8 bit string - short circuit
     775            op.m_jumps.append(jump());
    758776        } else {
    759             ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch)));
    760             failures.append(jumpIfCharNotEquals(ch, term->inputPosition - m_checked));
    761         }
    762 
    763         add32(TrustedImm32(1), countRegister);
    764         add32(TrustedImm32(1), index);
    765         if (term->quantityCount == quantifyInfinite)
    766             jump(loop);
    767         else
    768             branch32(NotEqual, countRegister, Imm32(term->quantityCount.unsafeGet())).linkTo(loop, this);
    769 
    770         failures.link(this);
     777            JumpList failures;
     778            Label loop(this);
     779            failures.append(atEndOfInput());
     780            if (m_pattern.m_ignoreCase && isASCIIAlpha(ch)) {
     781                readCharacter(term->inputPosition - m_checked, character);
     782                or32(TrustedImm32(32), character);
     783                failures.append(branch32(NotEqual, character, Imm32(Unicode::toLower(ch))));
     784            } else {
     785                ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch)));
     786                failures.append(jumpIfCharNotEquals(ch, term->inputPosition - m_checked));
     787            }
     788
     789            add32(TrustedImm32(1), countRegister);
     790            add32(TrustedImm32(1), index);
     791            if (term->quantityCount == quantifyInfinite)
     792                jump(loop);
     793            else
     794                branch32(NotEqual, countRegister, Imm32(term->quantityCount.unsafeGet())).linkTo(loop, this);
     795
     796            failures.link(this);
     797        }
    771798        op.m_reentry = label();
    772799
     
    816843        loadFromFrame(term->frameLocation, countRegister);
    817844
    818         nonGreedyFailures.append(atEndOfInput());
    819         if (term->quantityCount != quantifyInfinite)
    820             nonGreedyFailures.append(branch32(Equal, countRegister, Imm32(term->quantityCount.unsafeGet())));
    821         if (m_pattern.m_ignoreCase && isASCIIAlpha(ch)) {
    822             readCharacter(term->inputPosition - m_checked, character);
    823             or32(TrustedImm32(32), character);
    824             nonGreedyFailures.append(branch32(NotEqual, character, Imm32(Unicode::toLower(ch))));
     845        if ((ch > 0xff) && (m_charSize == Char8)) {
     846            // Have a 16 bit pattern character and an 8 bit string - short circuit
     847            nonGreedyFailures.append(jump());
    825848        } else {
    826             ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch)));
    827             nonGreedyFailures.append(jumpIfCharNotEquals(ch, term->inputPosition - m_checked));
    828         }
    829 
    830         add32(TrustedImm32(1), countRegister);
    831         add32(TrustedImm32(1), index);
    832 
    833         jump(op.m_reentry);
    834 
     849            nonGreedyFailures.append(atEndOfInput());
     850            if (term->quantityCount != quantifyInfinite)
     851                nonGreedyFailures.append(branch32(Equal, countRegister, Imm32(term->quantityCount.unsafeGet())));
     852            if (m_pattern.m_ignoreCase && isASCIIAlpha(ch)) {
     853                readCharacter(term->inputPosition - m_checked, character);
     854                or32(TrustedImm32(32), character);
     855                nonGreedyFailures.append(branch32(NotEqual, character, Imm32(Unicode::toLower(ch))));
     856            } else {
     857                ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch)));
     858                nonGreedyFailures.append(jumpIfCharNotEquals(ch, term->inputPosition - m_checked));
     859            }
     860
     861            add32(TrustedImm32(1), countRegister);
     862            add32(TrustedImm32(1), index);
     863
     864            jump(op.m_reentry);
     865        }
    835866        nonGreedyFailures.link(this);
     867
    836868        sub32(countRegister, index);
    837869        m_backtrackingState.fallthrough();
     
    874906        Label loop(this);
    875907        JumpList matchDest;
    876         load16(BaseIndex(input, countRegister, TimesTwo, (Checked<int>(term->inputPosition - m_checked + Checked<int64_t>(term->quantityCount)) * static_cast<int>(sizeof(UChar))).unsafeGet()), character);
     908        if (m_charSize == Char8)
     909            load8(BaseIndex(input, countRegister, TimesOne, (Checked<int>(term->inputPosition - m_checked + Checked<int64_t>(term->quantityCount)) * static_cast<int>(sizeof(char))).unsafeGet()), character);
     910        else
     911            load16(BaseIndex(input, countRegister, TimesTwo, (Checked<int>(term->inputPosition - m_checked + Checked<int64_t>(term->quantityCount)) * static_cast<int>(sizeof(UChar))).unsafeGet()), character);
    877912        matchCharacterClass(character, matchDest, term->characterClass);
    878913
     
    10171052        Label findBOLLoop(this);
    10181053        sub32(TrustedImm32(1), matchPos);
    1019         load16(BaseIndex(input, matchPos, TimesTwo, 0), character);
     1054        if (m_charSize == Char8)
     1055            load8(BaseIndex(input, matchPos, TimesOne, 0), character);
     1056        else
     1057            load16(BaseIndex(input, matchPos, TimesTwo, 0), character);
    10201058        matchCharacterClass(character, foundBeginningNewLine, m_pattern.newlineCharacterClass());
    10211059        branchTest32(NonZero, matchPos).linkTo(findBOLLoop, this);
     
    10351073        Label findEOLLoop(this);       
    10361074        foundEndingNewLine.append(branch32(Equal, matchPos, length));
    1037         load16(BaseIndex(input, matchPos, TimesTwo, 0), character);
     1075        if (m_charSize == Char8)
     1076            load8(BaseIndex(input, matchPos, TimesOne, 0), character);
     1077        else
     1078            load16(BaseIndex(input, matchPos, TimesTwo, 0), character);
    10381079        matchCharacterClass(character, foundEndingNewLine, m_pattern.newlineCharacterClass());
    10391080        add32(TrustedImm32(1), matchPos);
     
    23992440
    24002441public:
    2401     YarrGenerator(YarrPattern& pattern)
     2442    YarrGenerator(YarrPattern& pattern, YarrCharSize charSize)
    24022443        : m_pattern(pattern)
     2444        , m_charSize(charSize)
     2445        , m_charScale(m_charSize == Char8 ? TimesOne: TimesTwo)
    24032446        , m_shouldFallBack(false)
    24042447        , m_checked(0)
     
    24322475        LinkBuffer linkBuffer(*globalData, this);
    24332476        m_backtrackingState.linkDataLabels(linkBuffer);
    2434         jitObject.set(linkBuffer.finalizeCode());
     2477        if (m_charSize == Char8)
     2478            jitObject.set8BitCode(linkBuffer.finalizeCode());
     2479        else
     2480            jitObject.set16BitCode(linkBuffer.finalizeCode());
    24352481        jitObject.setFallBack(m_shouldFallBack);
    24362482    }
     
    24382484private:
    24392485    YarrPattern& m_pattern;
     2486
     2487    YarrCharSize m_charSize;
     2488
     2489    Scale m_charScale;
    24402490
    24412491    // Used to detect regular expression constructs that are not currently
     
    24622512};
    24632513
    2464 void jitCompile(YarrPattern& pattern, JSGlobalData* globalData, YarrCodeBlock& jitObject)
     2514void jitCompile(YarrPattern& pattern, YarrCharSize charSize, JSGlobalData* globalData, YarrCodeBlock& jitObject)
    24652515{
    2466     YarrGenerator(pattern).compile(globalData, jitObject);
     2516    YarrGenerator(pattern, charSize).compile(globalData, jitObject);
     2517}
     2518
     2519int execute(YarrCodeBlock& jitObject, const char* input, unsigned start, unsigned length, int* output)
     2520{
     2521    return jitObject.execute(input, start, length, output);
    24672522}
    24682523
  • trunk/Source/JavaScriptCore/yarr/YarrJIT.h

    r94920 r94981  
    3232#include "MacroAssembler.h"
    3333#include "UString.h"
     34#include "Yarr.h"
    3435#include "YarrPattern.h"
    3536
     
    4849
    4950class YarrCodeBlock {
    50     typedef int (*YarrJITCode)(const UChar* input, unsigned start, unsigned length, int* output) YARR_CALL;
     51    typedef int (*YarrJITCode8)(const char* input, unsigned start, unsigned length, int* output) YARR_CALL;
     52    typedef int (*YarrJITCode16)(const UChar* input, unsigned start, unsigned length, int* output) YARR_CALL;
    5153
    5254public:
     
    6264    void setFallBack(bool fallback) { m_needFallBack = fallback; }
    6365    bool isFallBack() { return m_needFallBack; }
    64     void set(MacroAssembler::CodeRef ref) { m_ref = ref; }
     66    bool has8BitCode() { return m_ref8.size(); }
     67    bool has16BitCode() { return m_ref16.size(); }
     68    void set8BitCode(MacroAssembler::CodeRef ref) { m_ref8 = ref; }
     69    void set16BitCode(MacroAssembler::CodeRef ref) { m_ref16 = ref; }
     70
     71    int execute(const char* input, unsigned start, unsigned length, int* output)
     72    {
     73        ASSERT(has8BitCode());
     74        return reinterpret_cast<YarrJITCode8>(m_ref8.code().executableAddress())(input, start, length, output);
     75    }
    6576
    6677    int execute(const UChar* input, unsigned start, unsigned length, int* output)
    6778    {
    68         return reinterpret_cast<YarrJITCode>(m_ref.code().executableAddress())(input, start, length, output);
     79        ASSERT(has16BitCode());
     80        return reinterpret_cast<YarrJITCode16>(m_ref16.code().executableAddress())(input, start, length, output);
    6981    }
    70 
    7182#if ENABLE(REGEXP_TRACING)
    7283    void *getAddr() { return m_ref.code().executableAddress(); }
     
    7485
    7586private:
    76     MacroAssembler::CodeRef m_ref;
     87    MacroAssembler::CodeRef m_ref8;
     88    MacroAssembler::CodeRef m_ref16;
    7789    bool m_needFallBack;
    7890};
    7991
    80 void jitCompile(YarrPattern&, JSGlobalData*, YarrCodeBlock& jitObject);
     92void jitCompile(YarrPattern&, YarrCharSize, JSGlobalData*, YarrCodeBlock& jitObject);
    8193int execute(YarrCodeBlock& jitObject, const UChar* input, unsigned start, unsigned length, int* output);
     94int execute(YarrCodeBlock& jitObject, const char* input, unsigned start, unsigned length, int* output);
    8295
    8396} } // namespace JSC::Yarr
  • trunk/Source/JavaScriptCore/yarr/YarrParser.h

    r93012 r94981  
    232232        , m_backReferenceLimit(backReferenceLimit)
    233233        , m_err(NoError)
    234         , m_data(pattern.characters())
     234        , m_data(pattern)
    235235        , m_size(pattern.length())
    236236        , m_index(0)
     
    794794    unsigned m_backReferenceLimit;
    795795    ErrorCode m_err;
    796     const UChar* m_data;
     796    const UString& m_data;
    797797    unsigned m_size;
    798798    unsigned m_index;
  • trunk/Source/WebCore/ChangeLog

    r94980 r94981  
     12011-09-12  Michael Saboff  <msaboff@apple.com>
     2
     3        Update RegExp and related classes to use 8 bit strings when available
     4        https://bugs.webkit.org/show_bug.cgi?id=67337
     5
     6        Updated call to match to use UString& instead of UChar*.
     7
     8        Reviewed by Gavin Barraclough.
     9
     10        No new tests, Covered by existing tests.
     11
     12        * platform/text/RegularExpression.cpp:
     13        (WebCore::RegularExpression::match):
     14
    1152011-09-12  Beth Dakin  <bdakin@apple.com>
    216
  • trunk/Source/WebCore/platform/text/RegularExpression.cpp

    r85603 r94981  
    111111        offsetVector[j] = -1;
    112112
    113     int result = JSC::Yarr::interpret(d->m_regExpByteCode.get(), str.characters(), startFrom, str.length(), offsetVector);
     113    int result = JSC::Yarr::interpret(d->m_regExpByteCode.get(), JSC::UString(str.impl()), startFrom, str.length(), offsetVector);
    114114    ASSERT(result >= -1);
    115115
Note: See TracChangeset for help on using the changeset viewer.