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)();