Title: [197622] trunk/Source/_javascript_Core
Revision
197622
Author
fpi...@apple.com
Date
2016-03-05 16:48:11 -0800 (Sat, 05 Mar 2016)

Log Message

The most aggressive form of RegExpTest/RegExpExec should speculate more aggressively than just cell
https://bugs.webkit.org/show_bug.cgi?id=154900

Reviewed by Saam Barati.

These old operations used to speculate cell. That's what they did when they were first
introduced. That was probably about as good as they could do back then because we didn't have
very powerful checks. Now we have powerful checks, so we can do this right.

The most profitable thing to check is that child1 is a RegExpObject and child2 is a JSString.
Sometimes though, we will not know what child2 is even though we know that child1 is a
RegExpObject. So, this patch means that RegExpExec/RegExpTest have the following overloads:

    RegExpExec(RegExpObject:, String:)
    RegExpExec(RegExpObject:, Untyped:)
    RegExpExec(Untyped:, Untyped:)

This shaves off some type checks in Octane/regexp. It also cleans up some problems in our
modeling of the effectfulness of these operations.

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileRegExpExec):
(JSC::FTL::DFG::LowerDFGToB3::compileRegExpTest):
* jit/JITOperations.h:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (197621 => 197622)


--- trunk/Source/_javascript_Core/ChangeLog	2016-03-06 00:40:09 UTC (rev 197621)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-03-06 00:48:11 UTC (rev 197622)
@@ -1,3 +1,44 @@
+2016-03-05  Filip Pizlo  <fpi...@apple.com>
+
+        The most aggressive form of RegExpTest/RegExpExec should speculate more aggressively than just cell
+        https://bugs.webkit.org/show_bug.cgi?id=154900
+
+        Reviewed by Saam Barati.
+
+        These old operations used to speculate cell. That's what they did when they were first
+        introduced. That was probably about as good as they could do back then because we didn't have
+        very powerful checks. Now we have powerful checks, so we can do this right.
+
+        The most profitable thing to check is that child1 is a RegExpObject and child2 is a JSString.
+        Sometimes though, we will not know what child2 is even though we know that child1 is a
+        RegExpObject. So, this patch means that RegExpExec/RegExpTest have the following overloads:
+
+            RegExpExec(RegExpObject:, String:)
+            RegExpExec(RegExpObject:, Untyped:)
+            RegExpExec(Untyped:, Untyped:)
+
+        This shaves off some type checks in Octane/regexp. It also cleans up some problems in our
+        modeling of the effectfulness of these operations.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileRegExpExec):
+        (JSC::FTL::DFG::LowerDFGToB3::compileRegExpTest):
+        * jit/JITOperations.h:
+
 2016-03-05  Yusuke Suzuki  <utatane....@gmail.com>
 
         [ES6] Support Reflect.construct

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (197621 => 197622)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2016-03-06 00:40:09 UTC (rev 197621)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2016-03-06 00:48:11 UTC (rev 197622)
@@ -1554,10 +1554,20 @@
     }
             
     case RegExpExec:
+        if (node->child1().useKind() == RegExpObjectUse
+            && node->child2().useKind() == StringUse) {
+            // This doesn't clobber the world since there are no conversions to perform.
+        } else
+            clobberWorld(node->origin.semantic, clobberLimit);
         forNode(node).makeHeapTop();
         break;
 
     case RegExpTest:
+        if (node->child1().useKind() == RegExpObjectUse
+            && node->child2().useKind() == StringUse) {
+            // This doesn't clobber the world since there are no conversions to perform.
+        } else
+            clobberWorld(node->origin.semantic, clobberLimit);
         forNode(node).setType(SpecBoolean);
         break;
             

Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (197621 => 197622)


--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2016-03-06 00:40:09 UTC (rev 197621)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2016-03-06 00:48:11 UTC (rev 197622)
@@ -1078,8 +1078,14 @@
 
     case RegExpExec:
     case RegExpTest:
-        read(RegExpState);
-        write(RegExpState);
+        if (node->child1().useKind() == RegExpObjectUse
+            && node->child2().useKind() == StringUse) {
+            read(RegExpState);
+            write(RegExpState);
+            return;
+        }
+        read(World);
+        write(Heap);
         return;
 
     case StringReplace:

Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (197621 => 197622)


--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2016-03-06 00:40:09 UTC (rev 197621)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2016-03-06 00:48:11 UTC (rev 197622)
@@ -879,13 +879,11 @@
             
         case RegExpExec:
         case RegExpTest: {
-            // FIXME: These should probably speculate something stronger than cell.
-            // https://bugs.webkit.org/show_bug.cgi?id=154900
-            if (node->child1()->shouldSpeculateCell()
-                && node->child2()->shouldSpeculateCell()) {
-                fixEdge<CellUse>(node->child1());
-                fixEdge<CellUse>(node->child2());
-                break;
+            if (node->child1()->shouldSpeculateRegExpObject()) {
+                fixEdge<RegExpObjectUse>(node->child1());
+
+                if (node->child2()->shouldSpeculateString())
+                    fixEdge<StringUse>(node->child2());
             }
             break;
         }

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (197621 => 197622)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2016-03-06 00:40:09 UTC (rev 197621)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2016-03-06 00:48:11 UTC (rev 197622)
@@ -619,23 +619,25 @@
     return JSValue::encode(array->pop(exec));
 }
         
-EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState* exec, JSCell* base, JSCell* argument)
+EncodedJSValue JIT_OPERATION operationRegExpExecString(ExecState* exec, RegExpObject* regExpObject, JSString* argument)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
     
-    if (!base->inherits(RegExpObject::info()))
-        return throwVMTypeError(exec);
+    return JSValue::encode(regExpObject->exec(exec, argument));
+}
+        
+EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState* exec, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    
+    JSValue argument = JSValue::decode(encodedArgument);
 
-    JSString* input;
-    if (argument->isString())
-        input = asString(argument);
-    else {
-        input = JSValue(argument).toStringOrNull(exec);
-        if (!input)
-            return JSValue::encode(jsUndefined());
-    }
-    return JSValue::encode(asRegExpObject(base)->exec(exec, input));
+    JSString* input = argument.toStringOrNull(exec);
+    if (!input)
+        return JSValue::encode(jsUndefined());
+    return JSValue::encode(regExpObject->exec(exec, input));
 }
         
 EncodedJSValue JIT_OPERATION operationRegExpExecGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)
@@ -655,25 +657,25 @@
     return JSValue::encode(asRegExpObject(base)->exec(exec, input));
 }
         
-size_t JIT_OPERATION operationRegExpTest(ExecState* exec, JSCell* base, JSCell* argument)
+size_t JIT_OPERATION operationRegExpTestString(ExecState* exec, RegExpObject* regExpObject, JSString* input)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
 
-    if (!base->inherits(RegExpObject::info())) {
-        throwTypeError(exec);
+    return regExpObject->test(exec, input);
+}
+
+size_t JIT_OPERATION operationRegExpTest(ExecState* exec, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+
+    JSValue argument = JSValue::decode(encodedArgument);
+
+    JSString* input = argument.toStringOrNull(exec);
+    if (!input)
         return false;
-    }
-
-    JSString* input;
-    if (argument->isString())
-        input = asString(argument);
-    else {
-        input = JSValue(argument).toStringOrNull(exec);
-        if (!input)
-            return false;
-    }
-    return asRegExpObject(base)->test(exec, input);
+    return regExpObject->test(exec, input);
 }
 
 size_t JIT_OPERATION operationRegExpTestGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.h (197621 => 197622)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.h	2016-03-06 00:40:09 UTC (rev 197621)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.h	2016-03-06 00:48:11 UTC (rev 197622)
@@ -101,10 +101,12 @@
 EncodedJSValue JIT_OPERATION operationArrayPushDouble(ExecState*, double value, JSArray*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationArrayPop(ExecState*, JSArray*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationArrayPopAndRecoverLength(ExecState*, JSArray*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState*, JSCell*, JSCell*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationRegExpExecString(ExecState*, RegExpObject*, JSString*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState*, RegExpObject*, EncodedJSValue) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationRegExpExecGeneric(ExecState*, EncodedJSValue, EncodedJSValue) 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 operationRegExpTest(ExecState*, JSCell*, JSCell*) WTF_INTERNAL;
+size_t JIT_OPERATION operationRegExpTestString(ExecState*, RegExpObject*, JSString*) WTF_INTERNAL;
+size_t JIT_OPERATION operationRegExpTest(ExecState*, RegExpObject*, EncodedJSValue) WTF_INTERNAL;
 size_t JIT_OPERATION operationRegExpTestGeneric(ExecState*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
 size_t JIT_OPERATION operationCompareStrictEqCell(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
 size_t JIT_OPERATION operationCompareStrictEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (197621 => 197622)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2016-03-06 00:40:09 UTC (rev 197621)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2016-03-06 00:48:11 UTC (rev 197622)
@@ -1217,6 +1217,18 @@
         return appendCallSetResult(operation, result);
     }
 
+    JITCompiler::Call callOperation(J_JITOperation_EReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2);
+        return appendCallSetResult(operation, result);
+    }
+
+    JITCompiler::Call callOperation(J_JITOperation_EReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2);
+        return appendCallSetResult(operation, result);
+    }
+
     JITCompiler::Call callOperation(V_JITOperation_EWs operation, WatchpointSet* watchpointSet)
     {
         m_jit.setupArgumentsWithExecState(TrustedImmPtr(watchpointSet));
@@ -1434,6 +1446,16 @@
         m_jit.setupArgumentsWithExecState(arg1, arg2);
         return appendCallSetResult(operation, result);
     }
+    JITCompiler::Call callOperation(S_JITOperation_EReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2);
+        return appendCallSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(S_JITOperation_EReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2);
+        return appendCallSetResult(operation, result);
+    }
 
     JITCompiler::Call callOperation(J_JITOperation_EPP operation, GPRReg result, GPRReg arg1, GPRReg arg2)
     {
@@ -1700,6 +1722,16 @@
         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell), EABI_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
         return appendCallSetResult(operation, result);
     }
+    JITCompiler::Call callOperation(J_JITOperation_EReoJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag);
+        return appendCallSetResult(operation, resultPayload, resultTag);
+    }
+    JITCompiler::Call callOperation(J_JITOperation_EReoJss operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2);
+        return appendCallSetResult(operation, resultPayload, resultTag);
+    }
     JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, GPRReg arg1, const UniquedStringImpl* uid)
     {
         m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
@@ -1797,6 +1829,16 @@
         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
         return appendCallSetResult(operation, result);
     }
+    JITCompiler::Call callOperation(S_JITOperation_EReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag);
+        return appendCallSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(S_JITOperation_EReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2);
+        return appendCallSetResult(operation, result);
+    }
     JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
     {
         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (197621 => 197622)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2016-03-06 00:40:09 UTC (rev 197621)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2016-03-06 00:48:11 UTC (rev 197622)
@@ -2836,17 +2836,40 @@
     }
 
     case RegExpExec: {
-        if (node->child1().useKind() == CellUse
-            && node->child2().useKind() == CellUse) {
+        if (node->child1().useKind() == RegExpObjectUse) {
+            if (node->child2().useKind() == StringUse) {
+                SpeculateCellOperand base(this, node->child1());
+                SpeculateCellOperand argument(this, node->child2());
+                GPRReg baseGPR = base.gpr();
+                GPRReg argumentGPR = argument.gpr();
+                speculateRegExpObject(node->child1(), baseGPR);
+                speculateString(node->child2(), argumentGPR);
+                
+                flushRegisters();
+                GPRFlushedCallResult2 resultTag(this);
+                GPRFlushedCallResult resultPayload(this);
+                callOperation(
+                    operationRegExpExecString, resultTag.gpr(), resultPayload.gpr(), baseGPR,
+                    argumentGPR);
+                m_jit.exceptionCheck();
+                
+                jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
+                break;
+            }
+            
             SpeculateCellOperand base(this, node->child1());
-            SpeculateCellOperand argument(this, node->child2());
+            JSValueOperand argument(this, node->child2());
             GPRReg baseGPR = base.gpr();
-            GPRReg argumentGPR = argument.gpr();
+            GPRReg argumentTagGPR = argument.tagGPR();
+            GPRReg argumentPayloadGPR = argument.payloadGPR();
+            speculateRegExpObject(node->child1(), baseGPR);
         
             flushRegisters();
             GPRFlushedCallResult2 resultTag(this);
             GPRFlushedCallResult resultPayload(this);
-            callOperation(operationRegExpExec, resultTag.gpr(), resultPayload.gpr(), baseGPR, argumentGPR);
+            callOperation(
+                operationRegExpExec, resultTag.gpr(), resultPayload.gpr(), baseGPR, argumentTagGPR,
+                argumentPayloadGPR);
             m_jit.exceptionCheck();
         
             jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
@@ -2871,16 +2894,35 @@
     }
         
     case RegExpTest: {
-        if (node->child1().useKind() == CellUse
-            && node->child2().useKind() == CellUse) {
+        if (node->child1().useKind() == RegExpObjectUse) {
+            if (node->child2().useKind() == StringUse) {
+                SpeculateCellOperand base(this, node->child1());
+                SpeculateCellOperand argument(this, node->child2());
+                GPRReg baseGPR = base.gpr();
+                GPRReg argumentGPR = argument.gpr();
+                speculateRegExpObject(node->child1(), baseGPR);
+                speculateString(node->child2(), argumentGPR);
+                
+                flushRegisters();
+                GPRFlushedCallResult result(this);
+                callOperation(operationRegExpTestString, result.gpr(), baseGPR, argumentGPR);
+                m_jit.exceptionCheck();
+                
+                booleanResult(result.gpr(), node);
+                break;
+            }
+            
             SpeculateCellOperand base(this, node->child1());
-            SpeculateCellOperand argument(this, node->child2());
+            JSValueOperand argument(this, node->child2());
             GPRReg baseGPR = base.gpr();
-            GPRReg argumentGPR = argument.gpr();
+            GPRReg argumentTagGPR = argument.tagGPR();
+            GPRReg argumentPayloadGPR = argument.payloadGPR();
+            speculateRegExpObject(node->child1(), baseGPR);
         
             flushRegisters();
             GPRFlushedCallResult result(this);
-            callOperation(operationRegExpTest, result.gpr(), baseGPR, argumentGPR);
+            callOperation(
+                operationRegExpTest, result.gpr(), baseGPR, argumentTagGPR, argumentPayloadGPR);
             m_jit.exceptionCheck();
         
             booleanResult(result.gpr(), node);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (197621 => 197622)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2016-03-06 00:40:09 UTC (rev 197621)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2016-03-06 00:48:11 UTC (rev 197622)
@@ -2962,12 +2962,29 @@
     }
 
     case RegExpExec: {
-        if (node->child1().useKind() == CellUse
-            && node->child2().useKind() == CellUse) {
+        if (node->child1().useKind() == RegExpObjectUse) {
+            if (node->child2().useKind() == StringUse) {
+                SpeculateCellOperand base(this, node->child1());
+                SpeculateCellOperand argument(this, node->child2());
+                GPRReg baseGPR = base.gpr();
+                GPRReg argumentGPR = argument.gpr();
+                speculateRegExpObject(node->child1(), baseGPR);
+                speculateString(node->child2(), argumentGPR);
+                
+                flushRegisters();
+                GPRFlushedCallResult result(this);
+                callOperation(operationRegExpExecString, result.gpr(), baseGPR, argumentGPR);
+                m_jit.exceptionCheck();
+                
+                jsValueResult(result.gpr(), node);
+                break;
+            }
+            
             SpeculateCellOperand base(this, node->child1());
-            SpeculateCellOperand argument(this, node->child2());
+            JSValueOperand argument(this, node->child2());
             GPRReg baseGPR = base.gpr();
             GPRReg argumentGPR = argument.gpr();
+            speculateRegExpObject(node->child1(), baseGPR);
         
             flushRegisters();
             GPRFlushedCallResult result(this);
@@ -2993,21 +3010,38 @@
     }
 
     case RegExpTest: {
-        if (node->child1().useKind() == CellUse
-            && node->child2().useKind() == CellUse) {
+        if (node->child1().useKind() == RegExpObjectUse) {
+            if (node->child2().useKind() == StringUse) {
+                SpeculateCellOperand base(this, node->child1());
+                SpeculateCellOperand argument(this, node->child2());
+                GPRReg baseGPR = base.gpr();
+                GPRReg argumentGPR = argument.gpr();
+                speculateRegExpObject(node->child1(), baseGPR);
+                speculateString(node->child2(), argumentGPR);
+                
+                flushRegisters();
+                GPRFlushedCallResult result(this);
+                callOperation(operationRegExpTestString, result.gpr(), baseGPR, argumentGPR);
+                m_jit.exceptionCheck();
+                
+                m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
+                jsValueResult(result.gpr(), node);
+                break;
+            }
+            
             SpeculateCellOperand base(this, node->child1());
-            SpeculateCellOperand argument(this, node->child2());
+            JSValueOperand argument(this, node->child2());
             GPRReg baseGPR = base.gpr();
             GPRReg argumentGPR = argument.gpr();
+            speculateRegExpObject(node->child1(), baseGPR);
         
             flushRegisters();
             GPRFlushedCallResult result(this);
             callOperation(operationRegExpTest, result.gpr(), baseGPR, argumentGPR);
             m_jit.exceptionCheck();
         
-            // If we add a DataFormatBool, we should use it here.
             m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
-            jsValueResult(result.gpr(), node, DataFormatJSBoolean);
+            jsValueResult(result.gpr(), node);
             break;
         }
         
@@ -3021,7 +3055,6 @@
         callOperation(operationRegExpTestGeneric, result.gpr(), baseGPR, argumentGPR);
         m_jit.exceptionCheck();
         
-        // If we add a DataFormatBool, we should use it here.
         m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
         jsValueResult(result.gpr(), node, DataFormatJSBoolean);
         break;

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (197621 => 197622)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2016-03-06 00:40:09 UTC (rev 197621)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2016-03-06 00:48:11 UTC (rev 197622)
@@ -6440,10 +6440,18 @@
 
     void compileRegExpExec()
     {
-        if (m_node->child1().useKind() == CellUse
-            && m_node->child2().useKind() == CellUse) {
-            LValue base = lowCell(m_node->child1());
-            LValue argument = lowCell(m_node->child2());
+        if (m_node->child1().useKind() == RegExpObjectUse) {
+            LValue base = lowRegExpObject(m_node->child1());
+            
+            if (m_node->child2().useKind() == StringUse) {
+                LValue argument = lowString(m_node->child2());
+                LValue result = vmCall(
+                    Int64, m_out.operation(operationRegExpExecString), m_callFrame, base, argument);
+                setJSValue(result);
+                return;
+            }
+            
+            LValue argument = lowJSValue(m_node->child2());
             setJSValue(
                 vmCall(Int64, m_out.operation(operationRegExpExec), m_callFrame, base, argument));
             return;
@@ -6457,10 +6465,18 @@
 
     void compileRegExpTest()
     {
-        if (m_node->child1().useKind() == CellUse
-            && m_node->child2().useKind() == CellUse) {
-            LValue base = lowCell(m_node->child1());
-            LValue argument = lowCell(m_node->child2());
+        if (m_node->child1().useKind() == RegExpObjectUse) {
+            LValue base = lowRegExpObject(m_node->child1());
+            
+            if (m_node->child2().useKind() == StringUse) {
+                LValue argument = lowString(m_node->child2());
+                LValue result = vmCall(
+                    Int32, m_out.operation(operationRegExpTestString), m_callFrame, base, argument);
+                setBoolean(result);
+                return;
+            }
+
+            LValue argument = lowJSValue(m_node->child2());
             setBoolean(
                 vmCall(Int32, m_out.operation(operationRegExpTest), m_callFrame, base, argument));
             return;

Modified: trunk/Source/_javascript_Core/jit/JITOperations.h (197621 => 197622)


--- trunk/Source/_javascript_Core/jit/JITOperations.h	2016-03-06 00:40:09 UTC (rev 197621)
+++ trunk/Source/_javascript_Core/jit/JITOperations.h	2016-03-06 00:48:11 UTC (rev 197622)
@@ -144,6 +144,8 @@
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EPc)(ExecState*, Instruction*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJscC)(ExecState*, JSScope*, JSCell*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJscCJ)(ExecState*, JSScope*, JSCell*, EncodedJSValue);
+typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EReoJ)(ExecState*, RegExpObject*, EncodedJSValue);
+typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EReoJss)(ExecState*, RegExpObject*, JSString*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_ESS)(ExecState*, size_t, size_t);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_ESsiCI)(ExecState*, StructureStubInfo*, JSCell*, UniquedStringImpl*);
 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_ESsiJI)(ExecState*, StructureStubInfo*, EncodedJSValue, UniquedStringImpl*);
@@ -202,6 +204,8 @@
 typedef size_t JIT_OPERATION (*S_JITOperation_EJ)(ExecState*, EncodedJSValue);
 typedef size_t JIT_OPERATION (*S_JITOperation_EJJ)(ExecState*, EncodedJSValue, EncodedJSValue);
 typedef size_t JIT_OPERATION (*S_JITOperation_EOJss)(ExecState*, JSObject*, JSString*);
+typedef size_t JIT_OPERATION (*S_JITOperation_EReoJ)(ExecState*, RegExpObject*, EncodedJSValue);
+typedef size_t JIT_OPERATION (*S_JITOperation_EReoJss)(ExecState*, RegExpObject*, JSString*);
 typedef size_t JIT_OPERATION (*S_JITOperation_J)(EncodedJSValue);
 typedef SlowPathReturnType JIT_OPERATION (*Sprt_JITOperation_EZ)(ExecState*, int32_t);
 typedef void JIT_OPERATION (*V_JITOperation)();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to