Changeset 197760 in webkit


Ignore:
Timestamp:
Mar 8, 2016 5:57:58 AM (8 years ago)
Author:
Carlos Garcia Campos
Message:

Merge r197520 - DFG should be able to compile StringReplace
https://bugs.webkit.org/show_bug.cgi?id=154979

Reviewed by Benjamin Poulain.

Source/JavaScriptCore:

Adds support for StringReplace to the DFG tier. This is a 3% speed-up on Octane/regexp.

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::handleIntrinsicCall):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::speculateFinalObject):
(JSC::DFG::SpeculativeJIT::speculateRegExpObject):
(JSC::DFG::SpeculativeJIT::speculateObjectOrOther):

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::callOperation):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • jit/JITOperations.h:

LayoutTests:

Add a microbenchmark for a case of StringReplace that we hadn't covered with a microbenchmark
yet: using something absurd for the replace value. This is interesting for implementing the
32_64 version of StringReplace, which gets really weird in the absurd case because of how it
consumes the entire register file while making the call on x86-32.

  • js/regress/script-tests/string-replace-generic.js: Added.
  • js/regress/string-replace-generic-expected.txt: Added.
  • js/regress/string-replace-generic.html: Added.
Location:
releases/WebKitGTK/webkit-2.12
Files:
3 added
8 edited

Legend:

Unmodified
Added
Removed
  • releases/WebKitGTK/webkit-2.12/LayoutTests/ChangeLog

    r197755 r197760  
     12016-03-03  Filip Pizlo  <fpizlo@apple.com>
     2
     3        DFG should be able to compile StringReplace
     4        https://bugs.webkit.org/show_bug.cgi?id=154979
     5
     6        Reviewed by Benjamin Poulain.
     7
     8        Add a microbenchmark for a case of StringReplace that we hadn't covered with a microbenchmark
     9        yet: using something absurd for the replace value. This is interesting for implementing the
     10        32_64 version of StringReplace, which gets really weird in the absurd case because of how it
     11        consumes the entire register file while making the call on x86-32.
     12
     13        * js/regress/script-tests/string-replace-generic.js: Added.
     14        * js/regress/string-replace-generic-expected.txt: Added.
     15        * js/regress/string-replace-generic.html: Added.
     16
    1172016-03-02  Zalan Bujtas  <zalan@apple.com>
    218
  • releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ChangeLog

    r197758 r197760  
     12016-03-03  Filip Pizlo  <fpizlo@apple.com>
     2
     3        DFG should be able to compile StringReplace
     4        https://bugs.webkit.org/show_bug.cgi?id=154979
     5
     6        Reviewed by Benjamin Poulain.
     7
     8        Adds support for StringReplace to the DFG tier. This is a 3% speed-up on Octane/regexp.
     9
     10        * dfg/DFGByteCodeParser.cpp:
     11        (JSC::DFG::ByteCodeParser::handleIntrinsicCall):
     12        * dfg/DFGSpeculativeJIT.cpp:
     13        (JSC::DFG::SpeculativeJIT::speculateFinalObject):
     14        (JSC::DFG::SpeculativeJIT::speculateRegExpObject):
     15        (JSC::DFG::SpeculativeJIT::speculateObjectOrOther):
     16        * dfg/DFGSpeculativeJIT.h:
     17        (JSC::DFG::SpeculativeJIT::callOperation):
     18        * dfg/DFGSpeculativeJIT32_64.cpp:
     19        (JSC::DFG::SpeculativeJIT::compile):
     20        * dfg/DFGSpeculativeJIT64.cpp:
     21        (JSC::DFG::SpeculativeJIT::compile):
     22        * jit/JITOperations.h:
     23
    1242016-03-02  Filip Pizlo  <fpizlo@apple.com>
    225
  • releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r197679 r197760  
    21912191
    21922192    case StringPrototypeReplaceIntrinsic: {
    2193         if (!isFTL(m_graph.m_plan.mode)) {
    2194             // This is a marginally profitable intrinsic. We've only the work to make it an
    2195             // intrinsic on the fourth tier.
    2196             return false;
    2197         }
    2198 
    21992193        if (argumentCountIncludingThis != 3)
    22002194            return false;
  • releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r197679 r197760  
    66246624}
    66256625
     6626void SpeculativeJIT::speculateRegExpObject(Edge edge, GPRReg cell)
     6627{
     6628    speculateCellType(edge, cell, SpecRegExpObject, RegExpObjectType);
     6629}
     6630
    66266631void SpeculativeJIT::speculateRegExpObject(Edge edge)
    66276632{
     
    66306635   
    66316636    SpeculateCellOperand operand(this, edge);
    6632     speculateCellType(edge, operand.gpr(), SpecRegExpObject, RegExpObjectType);
     6637    speculateRegExpObject(edge, operand.gpr());
    66336638}
    66346639
  • releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r197679 r197760  
    12731273        return appendCallSetResult(operation, result);
    12741274    }
     1275    JITCompiler::Call callOperation(J_JITOperation_EJssReo operation, GPRReg result, GPRReg arg1, GPRReg arg2)
     1276    {
     1277        m_jit.setupArgumentsWithExecState(arg1, arg2);
     1278        return appendCallSetResult(operation, result);
     1279    }
     1280    JITCompiler::Call callOperation(J_JITOperation_EJssReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
     1281    {
     1282        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
     1283        return appendCallSetResult(operation, result);
     1284    }
    12751285    JITCompiler::Call callOperation(J_JITOperation_EJssZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
    12761286    {
     
    14361446        return appendCallSetResult(operation, result);
    14371447    }
    1438     JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, MacroAssembler::TrustedImm32 imm)
    1439     {
    1440         m_jit.setupArgumentsWithExecState(arg1, MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm.m_value))));
    1441         return appendCallSetResult(operation, result);
    1442     }
    1443     JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, MacroAssembler::TrustedImm32 imm, GPRReg arg2)
    1444     {
    1445         m_jit.setupArgumentsWithExecState(MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm.m_value))), arg2);
     1448    JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, int32_t imm)
     1449    {
     1450        m_jit.setupArgumentsWithExecState(arg1, MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm))));
     1451        return appendCallSetResult(operation, result);
     1452    }
     1453    JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, int32_t imm, GPRReg arg2)
     1454    {
     1455        m_jit.setupArgumentsWithExecState(MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm))), arg2);
    14461456        return appendCallSetResult(operation, result);
    14471457    }
     
    14491459    {
    14501460        return callOperation(operation, result.payloadGPR(), arg1.payloadGPR(), arg2.payloadGPR());
     1461    }
     1462    JITCompiler::Call callOperation(J_JITOperation_EJJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
     1463    {
     1464        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
     1465        return appendCallSetResult(operation, result);
    14511466    }
    14521467    JITCompiler::Call callOperation(J_JITOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
     
    16351650        return appendCallSetResult(operation, resultPayload, resultTag);
    16361651    }
     1652    JITCompiler::Call callOperation(J_JITOperation_EJssReo operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
     1653    {
     1654        m_jit.setupArgumentsWithExecState(arg1, arg2);
     1655        return appendCallSetResult(operation, resultPayload, resultTag);
     1656    }
     1657    JITCompiler::Call callOperation(J_JITOperation_EJssReoJss operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2, GPRReg arg3)
     1658    {
     1659        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
     1660        return appendCallSetResult(operation, resultPayload, resultTag);
     1661    }
    16371662    JITCompiler::Call callOperation(J_JITOperation_EPS operation, GPRReg resultTag, GPRReg resultPayload, void* pointer, size_t size)
    16381663    {
     
    17911816    {
    17921817        return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1.tagGPR(), arg1.payloadGPR(), arg2.tagGPR(), arg2.payloadGPR());
     1818    }
     1819    JITCompiler::Call callOperation(J_JITOperation_EJJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload)
     1820    {
     1821        m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2Payload, arg2Tag, arg3Payload, arg3Tag);
     1822        return appendCallSetResult(operation, resultPayload, resultTag);
    17931823    }
    17941824
     
    24712501    void speculateFunction(Edge);
    24722502    void speculateFinalObject(Edge);
     2503    void speculateRegExpObject(Edge, GPRReg cell);
    24732504    void speculateRegExpObject(Edge);
    24742505    void speculateObjectOrOther(Edge);
  • releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r197758 r197760  
    29032903        break;
    29042904    }
     2905
     2906    case StringReplace: {
     2907        if (node->child1().useKind() == StringUse
     2908            && node->child2().useKind() == RegExpObjectUse
     2909            && node->child3().useKind() == StringUse) {
     2910            if (JSString* replace = node->child3()->dynamicCastConstant<JSString*>()) {
     2911                if (!replace->length()) {
     2912                    SpeculateCellOperand string(this, node->child1());
     2913                    SpeculateCellOperand regExp(this, node->child2());
     2914                    GPRReg stringGPR = string.gpr();
     2915                    GPRReg regExpGPR = regExp.gpr();
     2916                    speculateString(node->child1(), stringGPR);
     2917                    speculateRegExpObject(node->child2(), regExpGPR);
     2918
     2919                    flushRegisters();
     2920                    GPRFlushedCallResult2 resultTag(this);
     2921                    GPRFlushedCallResult resultPayload(this);
     2922                    callOperation(
     2923                        operationStringProtoFuncReplaceRegExpEmptyStr, resultTag.gpr(),
     2924                        resultPayload.gpr(), stringGPR, regExpGPR);
     2925                    m_jit.exceptionCheck();
     2926                    cellResult(resultPayload.gpr(), node);
     2927                    break;
     2928                }
     2929            }
     2930           
     2931            SpeculateCellOperand string(this, node->child1());
     2932            SpeculateCellOperand regExp(this, node->child2());
     2933            SpeculateCellOperand replace(this, node->child3());
     2934            GPRReg stringGPR = string.gpr();
     2935            GPRReg regExpGPR = regExp.gpr();
     2936            GPRReg replaceGPR = replace.gpr();
     2937            speculateString(node->child1(), stringGPR);
     2938            speculateRegExpObject(node->child2(), regExpGPR);
     2939            speculateString(node->child3(), replaceGPR);
     2940           
     2941            flushRegisters();
     2942            GPRFlushedCallResult2 resultTag(this);
     2943            GPRFlushedCallResult resultPayload(this);
     2944            callOperation(
     2945                operationStringProtoFuncReplaceRegExpString, resultTag.gpr(), resultPayload.gpr(),
     2946                stringGPR, regExpGPR, replaceGPR);
     2947            m_jit.exceptionCheck();
     2948            cellResult(resultPayload.gpr(), node);
     2949            break;
     2950        }
     2951       
     2952        JSValueOperand string(this, node->child1());
     2953        JSValueOperand regExp(this, node->child2());
     2954        JSValueOperand replace(this, node->child3());
     2955        GPRReg stringTagGPR = string.tagGPR();
     2956        GPRReg stringPayloadGPR = string.payloadGPR();
     2957        GPRReg regExpTagGPR = regExp.tagGPR();
     2958        GPRReg regExpPayloadGPR = regExp.payloadGPR();
     2959        GPRReg replaceTagGPR = replace.tagGPR();
     2960        GPRReg replacePayloadGPR = replace.payloadGPR();
     2961       
     2962        flushRegisters();
     2963        GPRFlushedCallResult2 resultTag(this);
     2964        GPRFlushedCallResult resultPayload(this);
     2965        callOperation(
     2966            operationStringProtoFuncReplaceGeneric, resultTag.gpr(), resultPayload.gpr(),
     2967            stringTagGPR, stringPayloadGPR, regExpTagGPR, regExpPayloadGPR, replaceTagGPR,
     2968            replacePayloadGPR);
     2969        m_jit.exceptionCheck();
     2970        cellResult(resultPayload.gpr(), node);
     2971        break;
     2972    }
    29052973       
    29062974    case ArrayPush: {
     
    48634931    case GetStack:
    48644932    case GetMyArgumentByVal:
    4865     case StringReplace:
    48664933        DFG_CRASH(m_jit.graph(), node, "unexpected node in DFG backend");
    48674934        break;
  • releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r197758 r197760  
    4545#include "SetupVarargsFrame.h"
    4646#include "SpillRegistersMode.h"
     47#include "StringPrototype.h"
    4748#include "TypeProfilerLog.h"
    4849#include "Watchdog.h"
     
    30243025        m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
    30253026        jsValueResult(result.gpr(), node, DataFormatJSBoolean);
     3027        break;
     3028    }
     3029
     3030    case StringReplace: {
     3031        if (node->child1().useKind() == StringUse
     3032            && node->child2().useKind() == RegExpObjectUse
     3033            && node->child3().useKind() == StringUse) {
     3034            if (JSString* replace = node->child3()->dynamicCastConstant<JSString*>()) {
     3035                if (!replace->length()) {
     3036                    SpeculateCellOperand string(this, node->child1());
     3037                    SpeculateCellOperand regExp(this, node->child2());
     3038                    GPRReg stringGPR = string.gpr();
     3039                    GPRReg regExpGPR = regExp.gpr();
     3040                    speculateString(node->child1(), stringGPR);
     3041                    speculateRegExpObject(node->child2(), regExpGPR);
     3042
     3043                    flushRegisters();
     3044                    GPRFlushedCallResult result(this);
     3045                    callOperation(
     3046                        operationStringProtoFuncReplaceRegExpEmptyStr, result.gpr(), stringGPR,
     3047                        regExpGPR);
     3048                    m_jit.exceptionCheck();
     3049                    cellResult(result.gpr(), node);
     3050                    break;
     3051                }
     3052            }
     3053           
     3054            SpeculateCellOperand string(this, node->child1());
     3055            SpeculateCellOperand regExp(this, node->child2());
     3056            SpeculateCellOperand replace(this, node->child3());
     3057            GPRReg stringGPR = string.gpr();
     3058            GPRReg regExpGPR = regExp.gpr();
     3059            GPRReg replaceGPR = replace.gpr();
     3060            speculateString(node->child1(), stringGPR);
     3061            speculateRegExpObject(node->child2(), regExpGPR);
     3062            speculateString(node->child3(), replaceGPR);
     3063           
     3064            flushRegisters();
     3065            GPRFlushedCallResult result(this);
     3066            callOperation(
     3067                operationStringProtoFuncReplaceRegExpString, result.gpr(), stringGPR, regExpGPR,
     3068                replaceGPR);
     3069            m_jit.exceptionCheck();
     3070            cellResult(result.gpr(), node);
     3071            break;
     3072        }
     3073       
     3074        JSValueOperand string(this, node->child1());
     3075        JSValueOperand regExp(this, node->child2());
     3076        JSValueOperand replace(this, node->child3());
     3077        GPRReg stringGPR = string.gpr();
     3078        GPRReg regExpGPR = regExp.gpr();
     3079        GPRReg replaceGPR = replace.gpr();
     3080       
     3081        flushRegisters();
     3082        GPRFlushedCallResult result(this);
     3083        callOperation(
     3084            operationStringProtoFuncReplaceGeneric, result.gpr(), stringGPR, regExpGPR,
     3085            replaceGPR);
     3086        m_jit.exceptionCheck();
     3087        cellResult(result.gpr(), node);
    30263088        break;
    30273089    }
     
    49154977    case KillStack:
    49164978    case GetStack:
    4917     case StringReplace:
    49184979        DFG_CRASH(m_jit.graph(), node, "Unexpected node");
    49194980        break;
  • releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/jit/JITOperations.h

    r197736 r197760  
    4646class JSLexicalEnvironment;
    4747class JSScope;
     48class RegExpObject;
    4849class Register;
    4950class StructureStubInfo;
     
    9596    Q: int64_t
    9697    R: Register
     98    Reo: RegExpObject*
    9799    S: size_t
    98100    Sprt: SlowPathReturnType
     
    129131typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJIdc)(ExecState*, EncodedJSValue, const Identifier*);
    130132typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJJ)(ExecState*, EncodedJSValue, EncodedJSValue);
     133typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJJJ)(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue);
    131134typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJJAp)(ExecState*, EncodedJSValue, EncodedJSValue, ArrayProfile*);
    132135typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJJBy)(ExecState*, EncodedJSValue, EncodedJSValue, ByValInfo*);
     136typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJJJ)(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue);
    133137typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJssZ)(ExecState*, JSString*, int32_t);
     138typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJssReo)(ExecState*, JSString*, RegExpObject*);
     139typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJssReoJss)(ExecState*, JSString*, RegExpObject*, JSString*);
    134140typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJP)(ExecState*, EncodedJSValue, void*);
    135141typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EP)(ExecState*, void*);
Note: See TracChangeset for help on using the changeset viewer.