Title: [226775] trunk/Source/_javascript_Core
Revision
226775
Author
[email protected]
Date
2018-01-11 06:20:40 -0800 (Thu, 11 Jan 2018)

Log Message

[DFG][FTL] regExpMatchFast should be handled
https://bugs.webkit.org/show_bug.cgi?id=180988

Reviewed by Mark Lam.

RegExp.prototype.@@match has a fast path, @regExpMatchFast. This patch annotates this function
with RegExpMatchFastIntrinsic, and introduces RegExpMatch DFG node. This paves the way to
make NewRegexp PhantomNewRegexp if it is not used except for setting/getting its lastIndex property.

To improve RegExp.prototype.@@match's performance more, we make this builtin function small by moving
slow path part to `@matchSlow()` private function.

It improves SixSpeed regex-u.{es5,es6} largely since they stress String.prototype.match, which calls
this regExpMatchFast function.

                         baseline                  patched

regex-u.es5          55.3835+-6.3002     ^     36.2431+-2.0797        ^ definitely 1.5281x faster
regex-u.es6         110.4624+-6.2896     ^     94.1012+-7.2433        ^ definitely 1.1739x faster

* builtins/RegExpPrototype.js:
(globalPrivate.matchSlow):
(overriddenName.string_appeared_here.match):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleIntrinsicCall):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasHeapPrediction):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileRegExpMatch):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileRegExpMatch):
* runtime/Intrinsic.cpp:
(JSC::intrinsicName):
* runtime/Intrinsic.h:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
* runtime/RegExpPrototype.cpp:
(JSC::regExpProtoFuncMatchFast):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (226774 => 226775)


--- trunk/Source/_javascript_Core/ChangeLog	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-01-11 14:20:40 UTC (rev 226775)
@@ -1,3 +1,66 @@
+2018-01-11  Yusuke Suzuki  <[email protected]>
+
+        [DFG][FTL] regExpMatchFast should be handled
+        https://bugs.webkit.org/show_bug.cgi?id=180988
+
+        Reviewed by Mark Lam.
+
+        RegExp.prototype.@@match has a fast path, @regExpMatchFast. This patch annotates this function
+        with RegExpMatchFastIntrinsic, and introduces RegExpMatch DFG node. This paves the way to
+        make NewRegexp PhantomNewRegexp if it is not used except for setting/getting its lastIndex property.
+
+        To improve RegExp.prototype.@@match's performance more, we make this builtin function small by moving
+        slow path part to `@matchSlow()` private function.
+
+        It improves SixSpeed regex-u.{es5,es6} largely since they stress String.prototype.match, which calls
+        this regExpMatchFast function.
+
+                                 baseline                  patched
+
+        regex-u.es5          55.3835+-6.3002     ^     36.2431+-2.0797        ^ definitely 1.5281x faster
+        regex-u.es6         110.4624+-6.2896     ^     94.1012+-7.2433        ^ definitely 1.1739x faster
+
+        * builtins/RegExpPrototype.js:
+        (globalPrivate.matchSlow):
+        (overriddenName.string_appeared_here.match):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsicCall):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasHeapPrediction):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileRegExpMatch):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileRegExpMatch):
+        * runtime/Intrinsic.cpp:
+        (JSC::intrinsicName):
+        * runtime/Intrinsic.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/RegExpPrototype.cpp:
+        (JSC::regExpProtoFuncMatchFast):
+
 2018-01-11  Saam Barati  <[email protected]>
 
         Our for-in caching is wrong when we add indexed properties on things in the prototype chain

Modified: trunk/Source/_javascript_Core/builtins/RegExpPrototype.js (226774 => 226775)


--- trunk/Source/_javascript_Core/builtins/RegExpPrototype.js	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/builtins/RegExpPrototype.js	2018-01-11 14:20:40 UTC (rev 226775)
@@ -79,22 +79,11 @@
     return !@isRegExpObject(regexp);
 }
 
-@overriddenName="[Symbol.match]"
-function match(strArg)
+@globalPrivate
+function matchSlow(regexp, str)
 {
     "use strict";
 
-    if (!@isObject(this))
-        @throwTypeError("RegExp.prototype.@@match requires that |this| be an Object");
-
-    let regexp = this;
-
-    // Check for observable side effects and call the fast path if there aren't any.
-    if (!@hasObservableSideEffectsForRegExpMatch(regexp))
-        return @regExpMatchFast.@call(regexp, strArg);
-
-    let str = @toString(strArg);
-
     if (!regexp.global)
         return @regExpExec(regexp, str);
     
@@ -131,6 +120,22 @@
     }
 }
 
+@overriddenName="[Symbol.match]"
+function match(strArg)
+{
+    "use strict";
+
+    if (!@isObject(this))
+        @throwTypeError("RegExp.prototype.@@match requires that |this| be an Object");
+
+    let str = @toString(strArg);
+
+    // Check for observable side effects and call the fast path if there aren't any.
+    if (!@hasObservableSideEffectsForRegExpMatch(this))
+        return @regExpMatchFast.@call(this, str);
+    return @matchSlow(this, str);
+}
+
 @overriddenName="[Symbol.replace]"
 function replace(strArg, replace)
 {

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (226774 => 226775)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2018-01-11 14:20:40 UTC (rev 226775)
@@ -1964,6 +1964,12 @@
             clobberWorld(node->origin.semantic, clobberLimit);
         forNode(node).setType(SpecBoolean);
         break;
+
+    case RegExpMatchFast:
+        ASSERT(node->child2().useKind() == RegExpObjectUse);
+        ASSERT(node->child3().useKind() == StringUse);
+        forNode(node).setType(m_graph, SpecOther | SpecArray);
+        break;
             
     case StringReplace:
     case StringReplaceRegExp:

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (226774 => 226775)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2018-01-11 14:20:40 UTC (rev 226775)
@@ -2620,6 +2620,15 @@
         return true;
     }
 
+    case RegExpMatchFastIntrinsic: {
+        RELEASE_ASSERT(argumentCountIncludingThis == 2);
+
+        insertChecks();
+        Node* regExpMatch = addToGraph(RegExpMatchFast, OpInfo(0), OpInfo(prediction), addToGraph(GetGlobalObject, callee), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)));
+        set(VirtualRegister(resultOperand), regExpMatch);
+        return true;
+    }
+
     case ObjectGetPrototypeOfIntrinsic: {
         if (argumentCountIncludingThis != 2)
             return false;

Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (226774 => 226775)


--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2018-01-11 14:20:40 UTC (rev 226775)
@@ -1487,6 +1487,7 @@
 
     case RegExpExec:
     case RegExpTest:
+    case RegExpMatchFast:
         if (node->child2().useKind() == RegExpObjectUse
             && node->child3().useKind() == StringUse) {
             read(RegExpState);

Modified: trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp (226774 => 226775)


--- trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp	2018-01-11 14:20:40 UTC (rev 226775)
@@ -137,6 +137,7 @@
     case CheckStringIdent:
     case RegExpExec:
     case RegExpTest:
+    case RegExpMatchFast:
     case CompareLess:
     case CompareLessEq:
     case CompareGreater:

Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (226774 => 226775)


--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2018-01-11 14:20:40 UTC (rev 226775)
@@ -1095,6 +1095,13 @@
             break;
         }
 
+        case RegExpMatchFast: {
+            fixEdge<KnownCellUse>(node->child1());
+            fixEdge<RegExpObjectUse>(node->child2());
+            fixEdge<StringUse>(node->child3());
+            break;
+        }
+
         case StringReplace:
         case StringReplaceRegExp: {
             if (node->child2()->shouldSpeculateString()) {

Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (226774 => 226775)


--- trunk/Source/_javascript_Core/dfg/DFGNode.h	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h	2018-01-11 14:20:40 UTC (rev 226775)
@@ -1570,6 +1570,7 @@
         case ArrayPush:
         case RegExpExec:
         case RegExpTest:
+        case RegExpMatchFast:
         case GetGlobalVar:
         case GetGlobalLexicalVariable:
         case StringReplace:

Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (226774 => 226775)


--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2018-01-11 14:20:40 UTC (rev 226775)
@@ -268,6 +268,7 @@
     /* Optimizations for regular _expression_ matching. */\
     macro(RegExpExec, NodeResultJS | NodeMustGenerate) \
     macro(RegExpTest, NodeResultJS | NodeMustGenerate) \
+    macro(RegExpMatchFast, NodeResultJS | NodeMustGenerate) \
     macro(StringReplace, NodeResultJS | NodeMustGenerate) \
     macro(StringReplaceRegExp, NodeResultJS | NodeMustGenerate) \
     \

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (226774 => 226775)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2018-01-11 14:20:40 UTC (rev 226775)
@@ -1023,6 +1023,18 @@
     return JSValue::encode(asRegExpObject(base)->exec(exec, globalObject, input));
 }
 
+EncodedJSValue JIT_OPERATION operationRegExpMatchFastString(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, JSString* argument)
+{
+    SuperSamplerScope superSamplerScope(false);
+
+    VM& vm = globalObject->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+
+    if (!regExpObject->regExp()->global())
+        return JSValue::encode(regExpObject->execInline(exec, globalObject, argument));
+    return JSValue::encode(regExpObject->matchGlobal(exec, globalObject, argument));
+}
+
 EncodedJSValue JIT_OPERATION operationParseIntNoRadixGeneric(ExecState* exec, EncodedJSValue value)
 {
     VM& vm = exec->vm();

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.h (226774 => 226775)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.h	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.h	2018-01-11 14:20:40 UTC (rev 226775)
@@ -151,6 +151,7 @@
 EncodedJSValue JIT_OPERATION operationRegExpExecString(ExecState*, JSGlobalObject*, RegExpObject*, JSString*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState*, JSGlobalObject*, RegExpObject*, EncodedJSValue) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationRegExpExecGeneric(ExecState*, JSGlobalObject*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationRegExpMatchFastString(ExecState*, JSGlobalObject*, RegExpObject*, JSString*) WTF_INTERNAL;
 // These comparisons return a boolean within a size_t such that the value is zero extended to fill the register.
 size_t JIT_OPERATION operationRegExpTestString(ExecState*, JSGlobalObject*, RegExpObject*, JSString*) WTF_INTERNAL;
 size_t JIT_OPERATION operationRegExpTest(ExecState*, JSGlobalObject*, RegExpObject*, EncodedJSValue) WTF_INTERNAL;

Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (226774 => 226775)


--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2018-01-11 14:20:40 UTC (rev 226775)
@@ -697,6 +697,7 @@
         case ArrayPush:
         case RegExpExec:
         case RegExpTest:
+        case RegExpMatchFast:
         case StringReplace:
         case StringReplaceRegExp:
         case GetById:

Modified: trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h (226774 => 226775)


--- trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h	2018-01-11 14:20:40 UTC (rev 226775)
@@ -261,6 +261,7 @@
     case CheckStringIdent:
     case RegExpExec:
     case RegExpTest:
+    case RegExpMatchFast:
     case CompareLess:
     case CompareLessEq:
     case CompareGreater:

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (226774 => 226775)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2018-01-11 14:20:40 UTC (rev 226775)
@@ -10620,6 +10620,28 @@
         m_jit.decrementSuperSamplerCount();
 }
 
+void SpeculativeJIT::compileRegExpMatchFast(Node* node)
+{
+    SpeculateCellOperand globalObject(this, node->child1());
+    SpeculateCellOperand base(this, node->child2());
+    SpeculateCellOperand argument(this, node->child3());
+    GPRReg globalObjectGPR = globalObject.gpr();
+    GPRReg baseGPR = base.gpr();
+    GPRReg argumentGPR = argument.gpr();
+    speculateRegExpObject(node->child2(), baseGPR);
+    speculateString(node->child3(), argumentGPR);
+
+    flushRegisters();
+    JSValueRegsFlushedCallResult result(this);
+    JSValueRegs resultRegs = result.regs();
+    callOperation(
+        operationRegExpMatchFastString, resultRegs,
+        globalObjectGPR, baseGPR, argumentGPR);
+    m_jit.exceptionCheck();
+
+    jsValueResult(resultRegs, node);
+}
+
 void SpeculativeJIT::compileLazyJSConstant(Node* node)
 {
     JSValueRegsTemporary result(this);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (226774 => 226775)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2018-01-11 14:20:40 UTC (rev 226775)
@@ -3065,6 +3065,7 @@
     void compileArrayPush(Node*);
     void compileNotifyWrite(Node*);
     void compileRegExpExec(Node*);
+    void compileRegExpMatchFast(Node*);
     void compileRegExpTest(Node*);
     void compileStringReplace(Node*);
     void compileIsObjectOrNull(Node*);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (226774 => 226775)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2018-01-11 14:20:40 UTC (rev 226775)
@@ -3168,6 +3168,11 @@
         break;
     }
 
+    case RegExpMatchFast: {
+        compileRegExpMatchFast(node);
+        break;
+    }
+
     case StringReplace:
     case StringReplaceRegExp: {
         compileStringReplace(node);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (226774 => 226775)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2018-01-11 14:20:40 UTC (rev 226775)
@@ -3438,6 +3438,11 @@
         break;
     }
 
+    case RegExpMatchFast: {
+        compileRegExpMatchFast(node);
+        break;
+    }
+
     case StringReplace:
     case StringReplaceRegExp: {
         compileStringReplace(node);

Modified: trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp (226774 => 226775)


--- trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp	2018-01-11 14:20:40 UTC (rev 226775)
@@ -276,6 +276,7 @@
     case GetRestLength:
     case RegExpExec:
     case RegExpTest:
+    case RegExpMatchFast:
     case NewRegexp:
     case StringReplace:
     case StringReplaceRegExp: 

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (226774 => 226775)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2018-01-11 14:20:40 UTC (rev 226775)
@@ -1182,6 +1182,9 @@
         case RegExpTest:
             compileRegExpTest();
             break;
+        case RegExpMatchFast:
+            compileRegExpMatchFast();
+            break;
         case NewRegexp:
             compileNewRegexp();
             break;
@@ -10270,6 +10273,17 @@
         setBoolean(result);
     }
 
+    void compileRegExpMatchFast()
+    {
+        LValue globalObject = lowCell(m_node->child1());
+        LValue base = lowRegExpObject(m_node->child2());
+        LValue argument = lowString(m_node->child3());
+        LValue result = vmCall(
+            Int64, m_out.operation(operationRegExpMatchFastString), m_callFrame, globalObject,
+            base, argument);
+        setJSValue(result);
+    }
+
     void compileNewRegexp()
     {
         FrozenValue* regexp = m_node->cellOperand();

Modified: trunk/Source/_javascript_Core/runtime/Intrinsic.cpp (226774 => 226775)


--- trunk/Source/_javascript_Core/runtime/Intrinsic.cpp	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/runtime/Intrinsic.cpp	2018-01-11 14:20:40 UTC (rev 226775)
@@ -111,6 +111,8 @@
         return "RegExpTestIntrinsic";
     case RegExpTestFastIntrinsic:
         return "RegExpTestFastIntrinsic";
+    case RegExpMatchFastIntrinsic:
+        return "RegExpMatchFastIntrinsic";
     case ObjectGetPrototypeOfIntrinsic:
         return "ObjectGetPrototypeOfIntrinsic";
     case ReflectGetPrototypeOfIntrinsic:

Modified: trunk/Source/_javascript_Core/runtime/Intrinsic.h (226774 => 226775)


--- trunk/Source/_javascript_Core/runtime/Intrinsic.h	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/runtime/Intrinsic.h	2018-01-11 14:20:40 UTC (rev 226775)
@@ -68,6 +68,7 @@
     RegExpExecIntrinsic,
     RegExpTestIntrinsic,
     RegExpTestFastIntrinsic,
+    RegExpMatchFastIntrinsic,
     ObjectGetPrototypeOfIntrinsic,
     ReflectGetPrototypeOfIntrinsic,
     StringPrototypeValueOfIntrinsic,

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (226774 => 226775)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2018-01-11 14:20:40 UTC (rev 226775)
@@ -907,7 +907,7 @@
         // RegExp.prototype helpers.
         GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpBuiltinExecPrivateName(), builtinRegExpExec, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpCreatePrivateName(), JSFunction::create(vm, this, 2, String(), esSpecRegExpCreate, NoIntrinsic), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
-        GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpMatchFastPrivateName(), JSFunction::create(vm, this, 1, String(), regExpProtoFuncMatchFast), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpMatchFastPrivateName(), JSFunction::create(vm, this, 1, String(), regExpProtoFuncMatchFast, RegExpMatchFastIntrinsic), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpSearchFastPrivateName(), JSFunction::create(vm, this, 1, String(), regExpProtoFuncSearchFast), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpSplitFastPrivateName(), JSFunction::create(vm, this, 2, String(), regExpProtoFuncSplitFast), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpPrototypeSymbolReplacePrivateName(), m_regExpPrototype->getDirect(vm, vm.propertyNames->replaceSymbol), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),

Modified: trunk/Source/_javascript_Core/runtime/RegExpPrototype.cpp (226774 => 226775)


--- trunk/Source/_javascript_Core/runtime/RegExpPrototype.cpp	2018-01-11 14:06:18 UTC (rev 226774)
+++ trunk/Source/_javascript_Core/runtime/RegExpPrototype.cpp	2018-01-11 14:20:40 UTC (rev 226775)
@@ -131,22 +131,11 @@
 
 EncodedJSValue JSC_HOST_CALL regExpProtoFuncMatchFast(ExecState* exec)
 {
-    VM& vm = exec->vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    JSValue thisValue = exec->thisValue();
-    if (!thisValue.inherits(vm, RegExpObject::info()))
-        return throwVMTypeError(exec, scope);
-    JSString* string = exec->argument(0).toStringOrNull(exec);
-    EXCEPTION_ASSERT(!!scope.exception() == !string);
-    if (!string)
-        return encodedJSValue();
-    if (!asRegExpObject(thisValue)->regExp()->global()) {
-        scope.release();
-        return JSValue::encode(asRegExpObject(thisValue)->exec(exec, exec->lexicalGlobalObject(), string));
-    }
-    scope.release();
-    return JSValue::encode(asRegExpObject(thisValue)->matchGlobal(exec, exec->lexicalGlobalObject(), string));
+    RegExpObject* thisObject = asRegExpObject(exec->thisValue());
+    JSString* string = jsCast<JSString*>(exec->uncheckedArgument(0));
+    if (!thisObject->regExp()->global())
+        return JSValue::encode(thisObject->exec(exec, exec->lexicalGlobalObject(), string));
+    return JSValue::encode(thisObject->matchGlobal(exec, exec->lexicalGlobalObject(), string));
 }
 
 EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to