Title: [226269] trunk/Source/_javascript_Core
Revision
226269
Author
[email protected]
Date
2017-12-22 11:51:03 -0800 (Fri, 22 Dec 2017)

Log Message

[DFG] Cleaning up and unifying 32bit code more
https://bugs.webkit.org/show_bug.cgi?id=181124

Reviewed by Mark Lam.

This patch unifies DFG 32bit code into 64bit code more. In this patch, we move RegExp DFG nodes
from 32bit / 64bit code to the common code. We change some RegExp operations to returning JSCell*
instead of EncodedJSValue. This simplifies DFG implementation.

And we also move HasGenericProperty since we now have JSValueRegsFlushedCallResult. ToPrimive,
LogShadowChickenPrologue, and LogShadowChickenTail are almost the same in 32bit and 64bit.
Thus, it is unified easily.

And we also move some GPRFlushedCallResult from the original places to the places just after
`flushRegisters()` not to spill unnecessary registers.

* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileRegExpExec):
(JSC::DFG::SpeculativeJIT::compileRegExpTest):
(JSC::DFG::SpeculativeJIT::compileStringReplace):
(JSC::DFG::SpeculativeJIT::compileHasGenericProperty):
(JSC::DFG::SpeculativeJIT::compileToPrimitive):
(JSC::DFG::SpeculativeJIT::compileLogShadowChickenPrologue):
(JSC::DFG::SpeculativeJIT::compileLogShadowChickenTail):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::emitCall):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::speculateDoubleRepAnyInt):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileStringReplace):
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* runtime/StringPrototype.cpp:
(JSC::jsSpliceSubstrings):
(JSC::jsSpliceSubstringsWithSeparators):
(JSC::removeUsingRegExpSearch):
(JSC::replaceUsingRegExpSearch):
(JSC::operationStringProtoFuncReplaceRegExpEmptyStr):
(JSC::operationStringProtoFuncReplaceRegExpString):
(JSC::replaceUsingStringSearch):
(JSC::replace):
(JSC::stringProtoFuncReplaceUsingRegExp):
(JSC::stringProtoFuncReplaceUsingStringSearch):
(JSC::operationStringProtoFuncReplaceGeneric):
* runtime/StringPrototype.h:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (226268 => 226269)


--- trunk/Source/_javascript_Core/ChangeLog	2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-12-22 19:51:03 UTC (rev 226269)
@@ -1,3 +1,57 @@
+2017-12-22  Yusuke Suzuki  <[email protected]>
+
+        [DFG] Cleaning up and unifying 32bit code more
+        https://bugs.webkit.org/show_bug.cgi?id=181124
+
+        Reviewed by Mark Lam.
+
+        This patch unifies DFG 32bit code into 64bit code more. In this patch, we move RegExp DFG nodes
+        from 32bit / 64bit code to the common code. We change some RegExp operations to returning JSCell*
+        instead of EncodedJSValue. This simplifies DFG implementation.
+
+        And we also move HasGenericProperty since we now have JSValueRegsFlushedCallResult. ToPrimive,
+        LogShadowChickenPrologue, and LogShadowChickenTail are almost the same in 32bit and 64bit.
+        Thus, it is unified easily.
+
+        And we also move some GPRFlushedCallResult from the original places to the places just after
+        `flushRegisters()` not to spill unnecessary registers.
+
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileRegExpExec):
+        (JSC::DFG::SpeculativeJIT::compileRegExpTest):
+        (JSC::DFG::SpeculativeJIT::compileStringReplace):
+        (JSC::DFG::SpeculativeJIT::compileHasGenericProperty):
+        (JSC::DFG::SpeculativeJIT::compileToPrimitive):
+        (JSC::DFG::SpeculativeJIT::compileLogShadowChickenPrologue):
+        (JSC::DFG::SpeculativeJIT::compileLogShadowChickenTail):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        (JSC::DFG::SpeculativeJIT::speculateDoubleRepAnyInt):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileStringReplace):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * runtime/StringPrototype.cpp:
+        (JSC::jsSpliceSubstrings):
+        (JSC::jsSpliceSubstringsWithSeparators):
+        (JSC::removeUsingRegExpSearch):
+        (JSC::replaceUsingRegExpSearch):
+        (JSC::operationStringProtoFuncReplaceRegExpEmptyStr):
+        (JSC::operationStringProtoFuncReplaceRegExpString):
+        (JSC::replaceUsingStringSearch):
+        (JSC::replace):
+        (JSC::stringProtoFuncReplaceUsingRegExp):
+        (JSC::stringProtoFuncReplaceUsingStringSearch):
+        (JSC::operationStringProtoFuncReplaceGeneric):
+        * runtime/StringPrototype.h:
+
 2017-12-22  Michael Catanzaro  <[email protected]>
 
         [GTK] Duplicated symbols in libjavascriptcoregtk and libwebkit2gtk can cause crashes in production builds

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (226268 => 226269)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2017-12-22 19:51:03 UTC (rev 226269)
@@ -55,6 +55,7 @@
 #include "JSGlobalObjectFunctions.h"
 #include "JSLexicalEnvironment.h"
 #include "JSMap.h"
+#include "JSPropertyNameEnumerator.h"
 #include "JSSet.h"
 #include "ObjectConstructor.h"
 #include "Operations.h"
@@ -1800,6 +1801,20 @@
     return reinterpret_cast<char*>(asObject(cell)->ensureArrayStorage(vm));
 }
 
+EncodedJSValue JIT_OPERATION operationHasGenericProperty(ExecState* exec, EncodedJSValue encodedBaseValue, JSCell* propertyName)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    JSValue baseValue = JSValue::decode(encodedBaseValue);
+    if (baseValue.isUndefinedOrNull())
+        return JSValue::encode(jsBoolean(false));
+
+    JSObject* base = baseValue.toObject(exec);
+    if (!base)
+        return JSValue::encode(JSValue());
+    return JSValue::encode(jsBoolean(base->hasPropertyGeneric(exec, asString(propertyName)->toIdentifier(exec), PropertySlot::InternalMethodType::GetOwnProperty)));
+}
+
 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyByInt(ExecState* exec, JSCell* baseCell, int32_t subscript, int32_t internalMethodType)
 {
     VM& vm = exec->vm();
@@ -1812,6 +1827,43 @@
     return JSValue::encode(jsBoolean(object->hasPropertyGeneric(exec, subscript, static_cast<PropertySlot::InternalMethodType>(internalMethodType))));
 }
 
+JSCell* JIT_OPERATION operationGetPropertyEnumerator(ExecState* exec, EncodedJSValue encodedBase)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    JSValue base = JSValue::decode(encodedBase);
+    if (base.isUndefinedOrNull())
+        return JSPropertyNameEnumerator::create(vm);
+
+    JSObject* baseObject = base.toObject(exec);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    scope.release();
+    return propertyNameEnumerator(exec, baseObject);
+}
+
+JSCell* JIT_OPERATION operationGetPropertyEnumeratorCell(ExecState* exec, JSCell* cell)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    JSObject* base = cell->toObject(exec, exec->lexicalGlobalObject());
+    RETURN_IF_EXCEPTION(scope, { });
+
+    scope.release();
+    return propertyNameEnumerator(exec, base);
+}
+
+JSCell* JIT_OPERATION operationToIndexString(ExecState* exec, int32_t index)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    return jsString(exec, Identifier::from(exec, index).string());
+}
+
 StringImpl* JIT_OPERATION operationResolveRope(ExecState* exec, JSString* string)
 {
     VM& vm = exec->vm();

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.h (226268 => 226269)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.h	2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.h	2017-12-22 19:51:03 UTC (rev 226269)
@@ -80,7 +80,11 @@
 EncodedJSValue JIT_OPERATION operationGetByValWithThis(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationGetPrototypeOf(ExecState*, EncodedJSValue) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationGetPrototypeOfObject(ExecState*, JSObject*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationHasGenericProperty(ExecState*, EncodedJSValue, JSCell*);
 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyByInt(ExecState*, JSCell*, int32_t, int32_t);
+JSCell* JIT_OPERATION operationGetPropertyEnumerator(ExecState*, EncodedJSValue);
+JSCell* JIT_OPERATION operationGetPropertyEnumeratorCell(ExecState*, JSCell*);
+JSCell* JIT_OPERATION operationToIndexString(ExecState*, int32_t);
 char* JIT_OPERATION operationNewArray(ExecState*, Structure*, void*, size_t) WTF_INTERNAL;
 char* JIT_OPERATION operationNewEmptyArray(ExecState*, Structure*) WTF_INTERNAL;
 char* JIT_OPERATION operationNewArrayWithSize(ExecState*, Structure*, int32_t, Butterfly*) WTF_INTERNAL;

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (226268 => 226269)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2017-12-22 19:51:03 UTC (rev 226269)
@@ -10423,6 +10423,195 @@
     noResult(node);
 }
 
+void SpeculativeJIT::compileRegExpExec(Node* node)
+{
+    bool sample = false;
+    if (sample)
+        m_jit.incrementSuperSamplerCount();
+
+    SpeculateCellOperand globalObject(this, node->child1());
+    GPRReg globalObjectGPR = globalObject.gpr();
+
+    if (node->child2().useKind() == RegExpObjectUse) {
+        if (node->child3().useKind() == StringUse) {
+            SpeculateCellOperand base(this, node->child2());
+            SpeculateCellOperand argument(this, node->child3());
+            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(operationRegExpExecString, resultRegs, globalObjectGPR, baseGPR, argumentGPR);
+            m_jit.exceptionCheck();
+
+            jsValueResult(resultRegs, node);
+
+            if (sample)
+                m_jit.decrementSuperSamplerCount();
+            return;
+        }
+
+        SpeculateCellOperand base(this, node->child2());
+        JSValueOperand argument(this, node->child3());
+        GPRReg baseGPR = base.gpr();
+        JSValueRegs argumentRegs = argument.jsValueRegs();
+        speculateRegExpObject(node->child2(), baseGPR);
+
+        flushRegisters();
+        JSValueRegsFlushedCallResult result(this);
+        JSValueRegs resultRegs = result.regs();
+        callOperation(operationRegExpExec, resultRegs, globalObjectGPR, baseGPR, argumentRegs);
+        m_jit.exceptionCheck();
+
+        jsValueResult(resultRegs, node);
+
+        if (sample)
+            m_jit.decrementSuperSamplerCount();
+        return;
+    }
+
+    JSValueOperand base(this, node->child2());
+    JSValueOperand argument(this, node->child3());
+    JSValueRegs baseRegs = base.jsValueRegs();
+    JSValueRegs argumentRegs = argument.jsValueRegs();
+
+    flushRegisters();
+    JSValueRegsFlushedCallResult result(this);
+    JSValueRegs resultRegs = result.regs();
+    callOperation(operationRegExpExecGeneric, resultRegs, globalObjectGPR, baseRegs, argumentRegs);
+    m_jit.exceptionCheck();
+
+    jsValueResult(resultRegs, node);
+
+    if (sample)
+        m_jit.decrementSuperSamplerCount();
+}
+
+void SpeculativeJIT::compileRegExpTest(Node* node)
+{
+    SpeculateCellOperand globalObject(this, node->child1());
+    GPRReg globalObjectGPR = globalObject.gpr();
+
+    if (node->child2().useKind() == RegExpObjectUse) {
+        if (node->child3().useKind() == StringUse) {
+            SpeculateCellOperand base(this, node->child2());
+            SpeculateCellOperand argument(this, node->child3());
+            GPRReg baseGPR = base.gpr();
+            GPRReg argumentGPR = argument.gpr();
+            speculateRegExpObject(node->child2(), baseGPR);
+            speculateString(node->child3(), argumentGPR);
+
+            flushRegisters();
+            GPRFlushedCallResult result(this);
+            callOperation(operationRegExpTestString, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
+            m_jit.exceptionCheck();
+
+            unblessedBooleanResult(result.gpr(), node);
+            return;
+        }
+
+        SpeculateCellOperand base(this, node->child2());
+        JSValueOperand argument(this, node->child3());
+        GPRReg baseGPR = base.gpr();
+        JSValueRegs argumentRegs = argument.jsValueRegs();
+        speculateRegExpObject(node->child2(), baseGPR);
+
+        flushRegisters();
+        GPRFlushedCallResult result(this);
+        callOperation(operationRegExpTest, result.gpr(), globalObjectGPR, baseGPR, argumentRegs);
+        m_jit.exceptionCheck();
+
+        unblessedBooleanResult(result.gpr(), node);
+        return;
+    }
+
+    JSValueOperand base(this, node->child2());
+    JSValueOperand argument(this, node->child3());
+    JSValueRegs baseRegs = base.jsValueRegs();
+    JSValueRegs argumentRegs = argument.jsValueRegs();
+
+    flushRegisters();
+    GPRFlushedCallResult result(this);
+    callOperation(operationRegExpTestGeneric, result.gpr(), globalObjectGPR, baseRegs, argumentRegs);
+    m_jit.exceptionCheck();
+
+    unblessedBooleanResult(result.gpr(), node);
+}
+
+void SpeculativeJIT::compileStringReplace(Node* node)
+{
+    ASSERT(node->op() == StringReplace || node->op() == StringReplaceRegExp);
+    bool sample = false;
+    if (sample)
+        m_jit.incrementSuperSamplerCount();
+
+    if (node->child1().useKind() == StringUse
+        && node->child2().useKind() == RegExpObjectUse
+        && node->child3().useKind() == StringUse) {
+        if (JSString* replace = node->child3()->dynamicCastConstant<JSString*>(*m_jit.vm())) {
+            if (!replace->length()) {
+                SpeculateCellOperand string(this, node->child1());
+                SpeculateCellOperand regExp(this, node->child2());
+                GPRReg stringGPR = string.gpr();
+                GPRReg regExpGPR = regExp.gpr();
+                speculateString(node->child1(), stringGPR);
+                speculateRegExpObject(node->child2(), regExpGPR);
+
+                flushRegisters();
+                GPRFlushedCallResult result(this);
+                callOperation(operationStringProtoFuncReplaceRegExpEmptyStr, result.gpr(), stringGPR, regExpGPR);
+                m_jit.exceptionCheck();
+                cellResult(result.gpr(), node);
+                if (sample)
+                    m_jit.decrementSuperSamplerCount();
+                return;
+            }
+        }
+
+        SpeculateCellOperand string(this, node->child1());
+        SpeculateCellOperand regExp(this, node->child2());
+        SpeculateCellOperand replace(this, node->child3());
+        GPRReg stringGPR = string.gpr();
+        GPRReg regExpGPR = regExp.gpr();
+        GPRReg replaceGPR = replace.gpr();
+        speculateString(node->child1(), stringGPR);
+        speculateRegExpObject(node->child2(), regExpGPR);
+        speculateString(node->child3(), replaceGPR);
+
+        flushRegisters();
+        GPRFlushedCallResult result(this);
+        callOperation(operationStringProtoFuncReplaceRegExpString, result.gpr(), stringGPR, regExpGPR, replaceGPR);
+        m_jit.exceptionCheck();
+        cellResult(result.gpr(), node);
+        if (sample)
+            m_jit.decrementSuperSamplerCount();
+        return;
+    }
+
+    // If we fixed up the edge of child2, we inserted a Check(@child2, String).
+    OperandSpeculationMode child2SpeculationMode = AutomaticOperandSpeculation;
+    if (node->child2().useKind() == StringUse)
+        child2SpeculationMode = ManualOperandSpeculation;
+
+    JSValueOperand string(this, node->child1());
+    JSValueOperand search(this, node->child2(), child2SpeculationMode);
+    JSValueOperand replace(this, node->child3());
+    JSValueRegs stringRegs = string.jsValueRegs();
+    JSValueRegs searchRegs = search.jsValueRegs();
+    JSValueRegs replaceRegs = replace.jsValueRegs();
+
+    flushRegisters();
+    GPRFlushedCallResult result(this);
+    callOperation(operationStringProtoFuncReplaceGeneric, result.gpr(), stringRegs, searchRegs, replaceRegs);
+    m_jit.exceptionCheck();
+    cellResult(result.gpr(), node);
+    if (sample)
+        m_jit.decrementSuperSamplerCount();
+}
+
 void SpeculativeJIT::compileLazyJSConstant(Node* node)
 {
     JSValueRegsTemporary result(this);
@@ -10905,6 +11094,22 @@
     int32Result(resultGPR, node);
 }
 
+void SpeculativeJIT::compileHasGenericProperty(Node* node)
+{
+    JSValueOperand base(this, node->child1());
+    SpeculateCellOperand property(this, node->child2());
+
+    JSValueRegs baseRegs = base.jsValueRegs();
+    GPRReg propertyGPR = property.gpr();
+
+    flushRegisters();
+    JSValueRegsFlushedCallResult result(this);
+    JSValueRegs resultRegs = result.regs();
+    callOperation(operationHasGenericProperty, resultRegs, baseRegs, propertyGPR);
+    m_jit.exceptionCheck();
+    blessedBooleanResult(resultRegs.payloadGPR(), node);
+}
+
 void SpeculativeJIT::compileToIndexString(Node* node)
 {
     SpeculateInt32Operand index(this, node->child1());
@@ -11227,6 +11432,74 @@
     cellResult(resultGPR, node);
 }
 
+void SpeculativeJIT::compileToPrimitive(Node* node)
+{
+    DFG_ASSERT(m_jit.graph(), node, node->child1().useKind() == UntypedUse);
+    JSValueOperand argument(this, node->child1());
+    JSValueRegsTemporary result(this, Reuse, argument);
+
+    JSValueRegs argumentRegs = argument.jsValueRegs();
+    JSValueRegs resultRegs = result.regs();
+
+    argument.use();
+
+    MacroAssembler::Jump alreadyPrimitive = m_jit.branchIfNotCell(argumentRegs);
+    MacroAssembler::Jump notPrimitive = m_jit.branchIfObject(argumentRegs.payloadGPR());
+
+    alreadyPrimitive.link(&m_jit);
+    m_jit.moveValueRegs(argumentRegs, resultRegs);
+
+    addSlowPathGenerator(slowPathCall(notPrimitive, this, operationToPrimitive, resultRegs, argumentRegs));
+
+    jsValueResult(resultRegs, node, DataFormatJS, UseChildrenCalledExplicitly);
+}
+
+void SpeculativeJIT::compileLogShadowChickenPrologue(Node* node)
+{
+    flushRegisters();
+    prepareForExternalCall();
+    m_jit.emitStoreCodeOrigin(node->origin.semantic);
+
+    GPRTemporary scratch1(this, GPRInfo::nonArgGPR0); // This must be a non-argument GPR.
+    GPRReg scratch1Reg = scratch1.gpr();
+    GPRTemporary scratch2(this);
+    GPRReg scratch2Reg = scratch2.gpr();
+    GPRTemporary shadowPacket(this);
+    GPRReg shadowPacketReg = shadowPacket.gpr();
+
+    m_jit.ensureShadowChickenPacket(*m_jit.vm(), shadowPacketReg, scratch1Reg, scratch2Reg);
+
+    SpeculateCellOperand scope(this, node->child1());
+    GPRReg scopeReg = scope.gpr();
+
+    m_jit.logShadowChickenProloguePacket(shadowPacketReg, scratch1Reg, scopeReg);
+    noResult(node);
+}
+
+void SpeculativeJIT::compileLogShadowChickenTail(Node* node)
+{
+    flushRegisters();
+    prepareForExternalCall();
+    CallSiteIndex callSiteIndex = m_jit.emitStoreCodeOrigin(node->origin.semantic);
+
+    GPRTemporary scratch1(this, GPRInfo::nonArgGPR0); // This must be a non-argument GPR.
+    GPRReg scratch1Reg = scratch1.gpr();
+    GPRTemporary scratch2(this);
+    GPRReg scratch2Reg = scratch2.gpr();
+    GPRTemporary shadowPacket(this);
+    GPRReg shadowPacketReg = shadowPacket.gpr();
+
+    m_jit.ensureShadowChickenPacket(*m_jit.vm(), shadowPacketReg, scratch1Reg, scratch2Reg);
+
+    JSValueOperand thisValue(this, node->child1());
+    JSValueRegs thisRegs = thisValue.jsValueRegs();
+    SpeculateCellOperand scope(this, node->child2());
+    GPRReg scopeReg = scope.gpr();
+
+    m_jit.logShadowChickenTailPacket(shadowPacketReg, thisRegs, scopeReg, m_jit.codeBlock(), callSiteIndex);
+    noResult(node);
+}
+
 void SpeculativeJIT::compileSetAdd(Node* node)
 {
     SpeculateCellOperand set(this, node->child1());

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (226268 => 226269)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2017-12-22 19:51:03 UTC (rev 226269)
@@ -1347,18 +1347,6 @@
         return appendCallSetResult(operation, result);
     }
 
-    JITCompiler::Call callOperation(J_JITOperation_EGReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
-    {
-        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
-        return appendCallSetResult(operation, result);
-    }
-
-    JITCompiler::Call callOperation(J_JITOperation_EGReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
-    {
-        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
-        return appendCallSetResult(operation, result);
-    }
-
     JITCompiler::Call callOperation(V_JITOperation_EWs operation, WatchpointSet* watchpointSet)
     {
         m_jit.setupArgumentsWithExecState(TrustedImmPtr(watchpointSet));
@@ -1570,12 +1558,22 @@
         m_jit.setupArgumentsWithExecState(arg1, arg2);
         return appendCallSetResult(operation, result);
     }
-    JITCompiler::Call callOperation(J_JITOperation_EJssReo operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+    JITCompiler::Call callOperation(J_JITOperation_EGReoJ operation, JSValueRegs result, GPRReg arg1, GPRReg arg2, JSValueRegs arg3)
     {
+        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3.payloadGPR());
+        return appendCallSetResult(operation, result.payloadGPR());
+    }
+    JITCompiler::Call callOperation(J_JITOperation_EGReoJss operation, JSValueRegs result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
+        return appendCallSetResult(operation, result.payloadGPR());
+    }
+    JITCompiler::Call callOperation(C_JITOperation_EJssReo operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+    {
         m_jit.setupArgumentsWithExecState(arg1, arg2);
         return appendCallSetResult(operation, result);
     }
-    JITCompiler::Call callOperation(J_JITOperation_EJssReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+    JITCompiler::Call callOperation(C_JITOperation_EJssReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
     {
         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
         return appendCallSetResult(operation, result);
@@ -1826,14 +1824,14 @@
     {
         return callOperation(operation, result, arg1.gpr(), arg2.gpr());
     }
-    JITCompiler::Call callOperation(S_JITOperation_EGJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+    JITCompiler::Call callOperation(S_JITOperation_EGJJ operation, GPRReg result, GPRReg arg1, JSValueRegs arg2, JSValueRegs arg3)
     {
-        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
+        m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg3.payloadGPR());
         return appendCallSetResult(operation, result);
     }
-    JITCompiler::Call callOperation(S_JITOperation_EGReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+    JITCompiler::Call callOperation(S_JITOperation_EGReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, JSValueRegs arg3)
     {
-        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
+        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3.payloadGPR());
         return appendCallSetResult(operation, result);
     }
     JITCompiler::Call callOperation(S_JITOperation_EGReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
@@ -1872,10 +1870,10 @@
         m_jit.setupArgumentsWithExecState(arg1, arg2);
         return appendCallSetResult(operation, result);
     }
-    JITCompiler::Call callOperation(J_JITOperation_EGJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+    JITCompiler::Call callOperation(J_JITOperation_EGJJ operation, JSValueRegs result, GPRReg arg1, JSValueRegs arg2, JSValueRegs arg3)
     {
-        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
-        return appendCallSetResult(operation, result);
+        m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg3.payloadGPR());
+        return appendCallSetResult(operation, result.payloadGPR());
     }
     JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, int32_t imm)
     {
@@ -2247,15 +2245,15 @@
         m_jit.setupArgumentsWithExecState(arg1, arg2);
         return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR());
     }
-    JITCompiler::Call callOperation(J_JITOperation_EJssReo operation, JSValueRegs result, GPRReg arg1, GPRReg arg2)
+    JITCompiler::Call callOperation(C_JITOperation_EJssReo operation, GPRReg result, GPRReg arg1, GPRReg arg2)
     {
         m_jit.setupArgumentsWithExecState(arg1, arg2);
-        return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR());
+        return appendCallSetResult(operation, result);
     }
-    JITCompiler::Call callOperation(J_JITOperation_EJssReoJss operation, JSValueRegs result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+    JITCompiler::Call callOperation(C_JITOperation_EJssReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
     {
         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
-        return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR());
+        return appendCallSetResult(operation, result);
     }
     JITCompiler::Call callOperation(J_JITOperation_EPS operation, JSValueRegs result, void* pointer, size_t size)
     {
@@ -3051,7 +3049,9 @@
     void compileArrayIndexOf(Node*);
     void compileArrayPush(Node*);
     void compileNotifyWrite(Node*);
-    bool compileRegExpExec(Node*);
+    void compileRegExpExec(Node*);
+    void compileRegExpTest(Node*);
+    void compileStringReplace(Node*);
     void compileIsObjectOrNull(Node*);
     void compileIsFunction(Node*);
     void compileTypeOf(Node*);
@@ -3078,6 +3078,7 @@
     void compileThrow(Node*);
     void compileThrowStaticError(Node*);
     void compileGetEnumerableLength(Node*);
+    void compileHasGenericProperty(Node*);
     void compileToIndexString(Node*);
     void compilePutByIdWithThis(Node*);
     void compileHasStructureProperty(Node*);
@@ -3092,6 +3093,9 @@
     void compileNewTypedArray(Node*);
     void compileCreateThis(Node*);
     void compileNewObject(Node*);
+    void compileToPrimitive(Node*);
+    void compileLogShadowChickenPrologue(Node*);
+    void compileLogShadowChickenTail(Node*);
 
     void moveTrueTo(GPRReg);
     void moveFalseTo(GPRReg);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (226268 => 226269)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2017-12-22 19:51:03 UTC (rev 226269)
@@ -987,14 +987,12 @@
     info->setUpCall(callType, node->origin.semantic, calleePayloadGPR);
     
     auto setResultAndResetStack = [&] () {
-        GPRFlushedCallResult resultPayload(this);
-        GPRFlushedCallResult2 resultTag(this);
-        GPRReg resultPayloadGPR = resultPayload.gpr();
-        GPRReg resultTagGPR = resultTag.gpr();
-        
-        m_jit.setupResults(resultPayloadGPR, resultTagGPR);
+        JSValueRegsFlushedCallResult result(this);
+        JSValueRegs resultRegs = result.regs();
 
-        jsValueResult(resultTagGPR, resultPayloadGPR, node, DataFormatJS, UseChildrenCalledExplicitly);
+        m_jit.setupResults(resultRegs);
+
+        jsValueResult(resultRegs, node, DataFormatJS, UseChildrenCalledExplicitly);
         // After the calls are done, we need to reestablish our stack
         // pointer. We rely on this for varargs calls, calls with arity
         // mismatch (the callframe is slided) and tail calls.
@@ -2590,12 +2588,12 @@
             JSValueRegs propertyRegs = property.jsValueRegs();
             
             flushRegisters();
-            GPRFlushedCallResult2 resultTag(this);
-            GPRFlushedCallResult resultPayload(this);
-            callOperation(operationGetByValCell, JSValueRegs(resultTag.gpr(), resultPayload.gpr()), baseGPR, propertyRegs);
+            JSValueRegsFlushedCallResult result(this);
+            JSValueRegs resultRegs = result.regs();
+            callOperation(operationGetByValCell, resultRegs, baseGPR, propertyRegs);
             m_jit.exceptionCheck();
             
-            jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
+            jsValueResult(resultRegs, node);
             break;
         }
         case Array::Int32:
@@ -2852,16 +2850,13 @@
         JSValueOperand subscript(this, node->child3());
         JSValueRegs subscriptRegs = subscript.jsValueRegs();
 
-        GPRFlushedCallResult resultPayload(this);
-        GPRFlushedCallResult2 resultTag(this);
-        GPRReg resultPayloadGPR = resultPayload.gpr();
-        GPRReg resultTagGPR = resultTag.gpr();
-
         flushRegisters();
-        callOperation(operationGetByValWithThis, JSValueRegs(resultTagGPR, resultPayloadGPR), baseRegs, thisValueRegs, subscriptRegs);
+        JSValueRegsFlushedCallResult result(this);
+        JSValueRegs resultRegs = result.regs();
+        callOperation(operationGetByValWithThis, resultRegs, baseRegs, thisValueRegs, subscriptRegs);
         m_jit.exceptionCheck();
 
-        jsValueResult(resultTagGPR, resultPayloadGPR, node);
+        jsValueResult(resultRegs, node);
         break;
     }
 
@@ -3164,183 +3159,18 @@
     }
 
     case RegExpExec: {
-        SpeculateCellOperand globalObject(this, node->child1());
-        GPRReg globalObjectGPR = globalObject.gpr();
-        
-        if (node->child2().useKind() == RegExpObjectUse) {
-            if (node->child3().useKind() == StringUse) {
-                SpeculateCellOperand base(this, node->child2());
-                SpeculateCellOperand argument(this, node->child3());
-                GPRReg baseGPR = base.gpr();
-                GPRReg argumentGPR = argument.gpr();
-                speculateRegExpObject(node->child2(), baseGPR);
-                speculateString(node->child3(), argumentGPR);
-                
-                flushRegisters();
-                GPRFlushedCallResult2 resultTag(this);
-                GPRFlushedCallResult resultPayload(this);
-                callOperation(
-                    operationRegExpExecString, JSValueRegs(resultTag.gpr(), resultPayload.gpr()),
-                    globalObjectGPR, baseGPR, argumentGPR);
-                m_jit.exceptionCheck();
-                
-                jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
-                break;
-            }
-            
-            SpeculateCellOperand base(this, node->child2());
-            JSValueOperand argument(this, node->child3());
-            GPRReg baseGPR = base.gpr();
-            JSValueRegs argumentRegs = argument.jsValueRegs();
-            speculateRegExpObject(node->child2(), baseGPR);
-        
-            flushRegisters();
-            GPRFlushedCallResult2 resultTag(this);
-            GPRFlushedCallResult resultPayload(this);
-            callOperation(
-                operationRegExpExec, JSValueRegs(resultTag.gpr(), resultPayload.gpr()), globalObjectGPR, baseGPR, argumentRegs);
-            m_jit.exceptionCheck();
-        
-            jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
-            break;
-        }
-        
-        JSValueOperand base(this, node->child2());
-        JSValueOperand argument(this, node->child3());
-        JSValueRegs baseRegs = base.jsValueRegs();
-        JSValueRegs argumentRegs = argument.jsValueRegs();
-        
-        flushRegisters();
-        GPRFlushedCallResult2 resultTag(this);
-        GPRFlushedCallResult resultPayload(this);
-        callOperation(
-            operationRegExpExecGeneric, JSValueRegs(resultTag.gpr(), resultPayload.gpr()), globalObjectGPR, baseRegs, argumentRegs);
-        m_jit.exceptionCheck();
-        
-        jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
+        compileRegExpExec(node);
         break;
     }
         
     case RegExpTest: {
-        SpeculateCellOperand globalObject(this, node->child1());
-        GPRReg globalObjectGPR = globalObject.gpr();
-        
-        if (node->child2().useKind() == RegExpObjectUse) {
-            if (node->child3().useKind() == StringUse) {
-                SpeculateCellOperand base(this, node->child2());
-                SpeculateCellOperand argument(this, node->child3());
-                GPRReg baseGPR = base.gpr();
-                GPRReg argumentGPR = argument.gpr();
-                speculateRegExpObject(node->child2(), baseGPR);
-                speculateString(node->child3(), argumentGPR);
-                
-                flushRegisters();
-                GPRFlushedCallResult result(this);
-                callOperation(
-                    operationRegExpTestString, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
-                m_jit.exceptionCheck();
-                
-                booleanResult(result.gpr(), node);
-                break;
-            }
-            
-            SpeculateCellOperand base(this, node->child2());
-            JSValueOperand argument(this, node->child3());
-            GPRReg baseGPR = base.gpr();
-            JSValueRegs argumentRegs = argument.jsValueRegs();
-            speculateRegExpObject(node->child2(), baseGPR);
-        
-            flushRegisters();
-            GPRFlushedCallResult result(this);
-            callOperation(
-                operationRegExpTest, result.gpr(), globalObjectGPR, baseGPR, argumentRegs);
-            m_jit.exceptionCheck();
-        
-            booleanResult(result.gpr(), node);
-            break;
-        }
-        
-        JSValueOperand base(this, node->child2());
-        JSValueOperand argument(this, node->child3());
-        JSValueRegs baseRegs = base.jsValueRegs();
-        JSValueRegs argumentRegs = argument.jsValueRegs();
-
-        flushRegisters();
-        GPRFlushedCallResult result(this);
-        callOperation(
-            operationRegExpTestGeneric, result.gpr(), globalObjectGPR, baseRegs, argumentRegs);
-        m_jit.exceptionCheck();
-        
-        booleanResult(result.gpr(), node);
+        compileRegExpTest(node);
         break;
     }
 
     case StringReplace:
     case StringReplaceRegExp: {
-        if (node->child1().useKind() == StringUse
-            && node->child2().useKind() == RegExpObjectUse
-            && node->child3().useKind() == StringUse) {
-            if (JSString* replace = node->child3()->dynamicCastConstant<JSString*>(*m_jit.vm())) {
-                if (!replace->length()) {
-                    SpeculateCellOperand string(this, node->child1());
-                    SpeculateCellOperand regExp(this, node->child2());
-                    GPRReg stringGPR = string.gpr();
-                    GPRReg regExpGPR = regExp.gpr();
-                    speculateString(node->child1(), stringGPR);
-                    speculateRegExpObject(node->child2(), regExpGPR);
-
-                    flushRegisters();
-                    GPRFlushedCallResult2 resultTag(this);
-                    GPRFlushedCallResult resultPayload(this);
-                    callOperation(
-                        operationStringProtoFuncReplaceRegExpEmptyStr, JSValueRegs(resultTag.gpr(), resultPayload.gpr()), stringGPR, regExpGPR);
-                    m_jit.exceptionCheck();
-                    cellResult(resultPayload.gpr(), node);
-                    break;
-                }
-            }
-            
-            SpeculateCellOperand string(this, node->child1());
-            SpeculateCellOperand regExp(this, node->child2());
-            SpeculateCellOperand replace(this, node->child3());
-            GPRReg stringGPR = string.gpr();
-            GPRReg regExpGPR = regExp.gpr();
-            GPRReg replaceGPR = replace.gpr();
-            speculateString(node->child1(), stringGPR);
-            speculateRegExpObject(node->child2(), regExpGPR);
-            speculateString(node->child3(), replaceGPR);
-            
-            flushRegisters();
-            GPRFlushedCallResult2 resultTag(this);
-            GPRFlushedCallResult resultPayload(this);
-            callOperation(
-                operationStringProtoFuncReplaceRegExpString, JSValueRegs(resultTag.gpr(), resultPayload.gpr()),
-                stringGPR, regExpGPR, replaceGPR);
-            m_jit.exceptionCheck();
-            cellResult(resultPayload.gpr(), node);
-            break;
-        }
-
-        // If we fixed up the edge of child2, we inserted a Check(@child2, String).
-        OperandSpeculationMode child2SpeculationMode = AutomaticOperandSpeculation;
-        if (node->child2().useKind() == StringUse)
-            child2SpeculationMode = ManualOperandSpeculation;
-        
-        JSValueOperand string(this, node->child1());
-        JSValueOperand search(this, node->child2(), child2SpeculationMode);
-        JSValueOperand replace(this, node->child3());
-        JSValueRegs stringRegs = string.jsValueRegs();
-        JSValueRegs searchRegs = search.jsValueRegs();
-        JSValueRegs replaceRegs = replace.jsValueRegs();
-        
-        flushRegisters();
-        GPRFlushedCallResult2 resultTag(this);
-        GPRFlushedCallResult resultPayload(this);
-        callOperation(
-            operationStringProtoFuncReplaceGeneric, JSValueRegs(resultTag.gpr(), resultPayload.gpr()),
-            stringRegs, searchRegs, replaceRegs); 
-        m_jit.exceptionCheck();
-        cellResult(resultPayload.gpr(), node);
+        compileStringReplace(node);
         break;
     }
 
@@ -3615,31 +3445,7 @@
     }
         
     case ToPrimitive: {
-        RELEASE_ASSERT(node->child1().useKind() == UntypedUse);
-        JSValueOperand argument(this, node->child1());
-        GPRTemporary resultTag(this, Reuse, argument, TagWord);
-        GPRTemporary resultPayload(this, Reuse, argument, PayloadWord);
-        
-        GPRReg argumentTagGPR = argument.tagGPR();
-        GPRReg argumentPayloadGPR = argument.payloadGPR();
-        GPRReg resultTagGPR = resultTag.gpr();
-        GPRReg resultPayloadGPR = resultPayload.gpr();
-        
-        argument.use();
-        
-        MacroAssembler::Jump alreadyPrimitive = m_jit.branchIfNotCell(argument.jsValueRegs());
-        MacroAssembler::Jump notPrimitive = m_jit.branchIfObject(argumentPayloadGPR);
-        
-        alreadyPrimitive.link(&m_jit);
-        m_jit.move(argumentTagGPR, resultTagGPR);
-        m_jit.move(argumentPayloadGPR, resultPayloadGPR);
-        
-        addSlowPathGenerator(
-            slowPathCall(
-                notPrimitive, this, operationToPrimitive,
-                JSValueRegs(resultTagGPR, resultPayloadGPR), JSValueRegs(argumentTagGPR, argumentPayloadGPR)));
-        
-        jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
+        compileToPrimitive(node);
         break;
     }
 
@@ -4635,10 +4441,9 @@
 
         JSValueRegs inputRegs = input.jsValueRegs();
 
+        flushRegisters();
         GPRFlushedCallResult result(this);
         GPRReg resultGPR = result.gpr();
-
-        flushRegisters();
         callOperation(operationMapHash, resultGPR, inputRegs);
         m_jit.exceptionCheck();
         int32Result(resultGPR, node);
@@ -4654,12 +4459,10 @@
         SpeculateCellOperand map(this, node->child1());
         JSValueOperand key(this, node->child2());
         SpeculateInt32Operand hash(this, node->child3());
-        GPRFlushedCallResult result(this);
 
         GPRReg mapGPR = map.gpr();
         JSValueRegs keyRegs = key.jsValueRegs();
         GPRReg hashGPR = hash.gpr();
-        GPRReg resultGPR = result.gpr();
 
         if (node->child1().useKind() == MapObjectUse)
             speculateMapObject(node->child1(), mapGPR);
@@ -4669,6 +4472,8 @@
             RELEASE_ASSERT_NOT_REACHED();
 
         flushRegisters();
+        GPRFlushedCallResult result(this);
+        GPRReg resultGPR = result.gpr();
         if (node->child1().useKind() == MapObjectUse)
             callOperation(operationJSMapFindBucket, resultGPR, mapGPR, keyRegs, hashGPR);
         else
@@ -4990,18 +4795,7 @@
         break;
     }
     case HasGenericProperty: {
-        JSValueOperand base(this, node->child1());
-        SpeculateCellOperand property(this, node->child2());
-        GPRFlushedCallResult resultPayload(this);
-        GPRFlushedCallResult2 resultTag(this);
-        JSValueRegs baseRegs = base.jsValueRegs();
-        GPRReg resultPayloadGPR = resultPayload.gpr();
-        GPRReg resultTagGPR = resultTag.gpr();
-
-        flushRegisters();
-        callOperation(operationHasGenericProperty, JSValueRegs(resultTagGPR, resultPayloadGPR), baseRegs, property.gpr());
-        m_jit.exceptionCheck();
-        booleanResult(resultPayloadGPR, node);
+        compileHasGenericProperty(node);
         break;
     }
     case HasStructureProperty: {
@@ -5086,27 +4880,23 @@
         GPRReg propertyGPR = property.gpr();
 
 #if CPU(X86)
-        GPRFlushedCallResult resultPayload(this);
-        GPRFlushedCallResult2 resultTag(this);
         GPRTemporary scratch(this);
 
-        GPRReg resultTagGPR = resultTag.gpr();
-        GPRReg resultPayloadGPR = resultPayload.gpr();
         GPRReg scratchGPR = scratch.gpr();
 
         // Not enough registers on X86 for this code, so always use the slow path.
         flushRegisters();
+        JSValueRegsFlushedCallResult result(this);
+        JSValueRegs resultRegs = result.regs();
         m_jit.move(MacroAssembler::TrustedImm32(JSValue::CellTag), scratchGPR);
-        callOperation(operationGetByValCell, JSValueRegs(resultTagGPR, resultPayloadGPR), baseGPR, JSValueRegs(scratchGPR, propertyGPR));
+        callOperation(operationGetByValCell, resultRegs, baseGPR, JSValueRegs(scratchGPR, propertyGPR));
         m_jit.exceptionCheck();
 #else
-        GPRTemporary resultPayload(this);
-        GPRTemporary resultTag(this);
         GPRTemporary scratch(this);
+        JSValueRegsFlushedCallResult result(this);
 
-        GPRReg resultTagGPR = resultTag.gpr();
-        GPRReg resultPayloadGPR = resultPayload.gpr();
         GPRReg scratchGPR = scratch.gpr();
+        JSValueRegs resultRegs = result.regs();
 
         Edge& indexEdge = m_jit.graph().varArgChild(node, 2);
         Edge& enumeratorEdge = m_jit.graph().varArgChild(node, 3);
@@ -5135,8 +4925,8 @@
 
         m_jit.move(indexGPR, scratchGPR);
         m_jit.signExtend32ToPtr(scratchGPR, scratchGPR);
-        m_jit.load32(MacroAssembler::BaseIndex(baseGPR, scratchGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTagGPR);
-        m_jit.load32(MacroAssembler::BaseIndex(baseGPR, scratchGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayloadGPR);
+        m_jit.load32(MacroAssembler::BaseIndex(baseGPR, scratchGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultRegs.tagGPR());
+        m_jit.load32(MacroAssembler::BaseIndex(baseGPR, scratchGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultRegs.payloadGPR());
 
         MacroAssembler::Jump done = m_jit.jump();
         
@@ -5146,19 +4936,19 @@
         m_jit.sub32(MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset()), scratchGPR);
         m_jit.neg32(scratchGPR);
         m_jit.signExtend32ToPtr(scratchGPR, scratchGPR);
-        // We use resultPayloadGPR as a temporary here. We have to make sure clobber it after getting the 
-        // value out of indexGPR and enumeratorGPR because resultPayloadGPR could reuse either of those registers.
-        m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), resultPayloadGPR);
+        // We use resultRegs.payloadGPR() as a temporary here. We have to make sure clobber it after getting the 
+        // value out of indexGPR and enumeratorGPR because resultRegs.payloadGPR() could reuse either of those registers.
+        m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), resultRegs.payloadGPR());
         int32_t offsetOfFirstProperty = static_cast<int32_t>(offsetInButterfly(firstOutOfLineOffset)) * sizeof(EncodedJSValue);
-        m_jit.load32(MacroAssembler::BaseIndex(resultPayloadGPR, scratchGPR, MacroAssembler::TimesEight, offsetOfFirstProperty + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTagGPR);
-        m_jit.load32(MacroAssembler::BaseIndex(resultPayloadGPR, scratchGPR, MacroAssembler::TimesEight, offsetOfFirstProperty + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayloadGPR);
+        m_jit.load32(MacroAssembler::BaseIndex(resultRegs.payloadGPR(), scratchGPR, MacroAssembler::TimesEight, offsetOfFirstProperty + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultRegs.tagGPR());
+        m_jit.load32(MacroAssembler::BaseIndex(resultRegs.payloadGPR(), scratchGPR, MacroAssembler::TimesEight, offsetOfFirstProperty + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultRegs.payloadGPR());
 
         done.link(&m_jit);
 
-        addSlowPathGenerator(slowPathCall(slowPath, this, operationGetByValCell, JSValueRegs(resultTagGPR, resultPayloadGPR), baseGPR, propertyGPR));
+        addSlowPathGenerator(slowPathCall(slowPath, this, operationGetByValCell, resultRegs, baseGPR, propertyGPR));
 #endif
 
-        jsValueResult(resultTagGPR, resultPayloadGPR, node);
+        jsValueResult(resultRegs, node);
         break;
     }
     case GetPropertyEnumerator: {
@@ -5232,48 +5022,12 @@
     }
 
     case LogShadowChickenPrologue: {
-        flushRegisters();
-        prepareForExternalCall();
-        m_jit.emitStoreCodeOrigin(node->origin.semantic);
-
-        GPRTemporary scratch1(this, GPRInfo::nonArgGPR0); // This must be a non-argument GPR.
-        GPRReg scratch1Reg = scratch1.gpr();
-        GPRTemporary shadowPacket(this);
-        GPRReg shadowPacketReg = shadowPacket.gpr();
-        GPRTemporary scratch2(this);
-        GPRReg scratch2Reg = scratch2.gpr();
-
-        m_jit.ensureShadowChickenPacket(*m_jit.vm(), shadowPacketReg, scratch1Reg, scratch2Reg);
-
-        SpeculateCellOperand scope(this, node->child1());
-        GPRReg scopeReg = scope.gpr();
-
-        m_jit.logShadowChickenProloguePacket(shadowPacketReg, scratch1Reg, scopeReg);
-        noResult(node);
+        compileLogShadowChickenPrologue(node);
         break;
     }
 
     case LogShadowChickenTail: {
-        flushRegisters();
-        prepareForExternalCall();
-        CallSiteIndex callSiteIndex = m_jit.emitStoreCodeOrigin(node->origin.semantic);
-
-        GPRTemporary scratch1(this, GPRInfo::nonArgGPR0); // This must be a non-argument GPR.
-        GPRReg scratch1Reg = scratch1.gpr();
-        GPRTemporary shadowPacket(this);
-        GPRReg shadowPacketReg = shadowPacket.gpr();
-        GPRTemporary scratch2(this);
-        GPRReg scratch2Reg = scratch2.gpr();
-
-        m_jit.ensureShadowChickenPacket(*m_jit.vm(), shadowPacketReg, scratch1Reg, scratch2Reg);
-
-        JSValueOperand thisValue(this, node->child1());
-        JSValueRegs thisRegs = thisValue.jsValueRegs();
-        SpeculateCellOperand scope(this, node->child2());
-        GPRReg scopeReg = scope.gpr();
-
-        m_jit.logShadowChickenTailPacket(shadowPacketReg, thisRegs, scopeReg, m_jit.codeBlock(), callSiteIndex);
-        noResult(node);
+        compileLogShadowChickenTail(node);
         break;
     }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (226268 => 226269)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2017-12-22 19:51:03 UTC (rev 226269)
@@ -2446,11 +2446,9 @@
             SpeculateDoubleOperand value(this, node->child1());
             FPRReg valueFPR = value.fpr();
             
+            flushRegisters();
             GPRFlushedCallResult result(this);
             GPRReg resultGPR = result.gpr();
-            
-            flushRegisters();
-            
             callOperation(operationConvertDoubleToInt52, resultGPR, valueFPR);
             
             DFG_TYPE_CHECK_WITH_EXIT_KIND(Int52Overflow,
@@ -2934,10 +2932,9 @@
         JSValueOperand subscript(this, node->child3());
         GPRReg subscriptGPR = subscript.gpr();
 
+        flushRegisters();
         GPRFlushedCallResult result(this);
         GPRReg resultGPR = result.gpr();
-
-        flushRegisters();
         callOperation(operationGetByValWithThis, resultGPR, baseGPR, thisValueGPR, subscriptGPR);
         m_jit.exceptionCheck();
 
@@ -3255,10 +3252,9 @@
                 argGPRs[i] = args[i]->gpr();
             }
             
+            flushRegisters();
             GPRFlushedCallResult result(this);
             resultGPR = result.gpr();
-            
-            flushRegisters();
             callSlowPath();
             m_jit.exceptionCheck();
             
@@ -3404,9 +3400,9 @@
         if (node->child1().useKind() != Int32Use) {
             JSValueOperand operand(this, node->child1());
             GPRReg operandGPR = operand.gpr();
+            flushRegisters();
             GPRFlushedCallResult result(this);
             GPRReg resultGPR = result.gpr();
-            flushRegisters();
             callOperation(operationAtomicsIsLockFree, resultGPR, operandGPR);
             m_jit.exceptionCheck();
             jsValueResult(resultGPR, node);
@@ -3429,199 +3425,18 @@
     }
 
     case RegExpExec: {
-        bool sample = false;
-
-        if (sample)
-            m_jit.incrementSuperSamplerCount();
-        
-        SpeculateCellOperand globalObject(this, node->child1());
-        GPRReg globalObjectGPR = globalObject.gpr();
-        
-        if (node->child2().useKind() == RegExpObjectUse) {
-            if (node->child3().useKind() == StringUse) {
-                SpeculateCellOperand base(this, node->child2());
-                SpeculateCellOperand argument(this, node->child3());
-                GPRReg baseGPR = base.gpr();
-                GPRReg argumentGPR = argument.gpr();
-                speculateRegExpObject(node->child2(), baseGPR);
-                speculateString(node->child3(), argumentGPR);
-                
-                flushRegisters();
-                GPRFlushedCallResult result(this);
-                callOperation(operationRegExpExecString, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
-                m_jit.exceptionCheck();
-                
-                jsValueResult(result.gpr(), node);
-
-                if (sample)
-                    m_jit.decrementSuperSamplerCount();
-                break;
-            }
-            
-            SpeculateCellOperand base(this, node->child2());
-            JSValueOperand argument(this, node->child3());
-            GPRReg baseGPR = base.gpr();
-            GPRReg argumentGPR = argument.gpr();
-            speculateRegExpObject(node->child2(), baseGPR);
-        
-            flushRegisters();
-            GPRFlushedCallResult result(this);
-            callOperation(operationRegExpExec, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
-            m_jit.exceptionCheck();
-        
-            jsValueResult(result.gpr(), node);
-
-            if (sample)
-                m_jit.decrementSuperSamplerCount();
-            break;
-        }
-        
-        JSValueOperand base(this, node->child2());
-        JSValueOperand argument(this, node->child3());
-        GPRReg baseGPR = base.gpr();
-        GPRReg argumentGPR = argument.gpr();
-        
-        flushRegisters();
-        GPRFlushedCallResult result(this);
-        callOperation(operationRegExpExecGeneric, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
-        m_jit.exceptionCheck();
-        
-        jsValueResult(result.gpr(), node);
-
-        if (sample)
-            m_jit.decrementSuperSamplerCount();
+        compileRegExpExec(node);
         break;
     }
 
     case RegExpTest: {
-        SpeculateCellOperand globalObject(this, node->child1());
-        GPRReg globalObjectGPR = globalObject.gpr();
-        
-        if (node->child2().useKind() == RegExpObjectUse) {
-            if (node->child3().useKind() == StringUse) {
-                SpeculateCellOperand base(this, node->child2());
-                SpeculateCellOperand argument(this, node->child3());
-                GPRReg baseGPR = base.gpr();
-                GPRReg argumentGPR = argument.gpr();
-                speculateRegExpObject(node->child2(), baseGPR);
-                speculateString(node->child3(), argumentGPR);
-                
-                flushRegisters();
-                GPRFlushedCallResult result(this);
-                callOperation(operationRegExpTestString, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
-                m_jit.exceptionCheck();
-                
-                m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
-                jsValueResult(result.gpr(), node);
-                break;
-            }
-            
-            SpeculateCellOperand base(this, node->child2());
-            JSValueOperand argument(this, node->child3());
-            GPRReg baseGPR = base.gpr();
-            GPRReg argumentGPR = argument.gpr();
-            speculateRegExpObject(node->child2(), baseGPR);
-        
-            flushRegisters();
-            GPRFlushedCallResult result(this);
-            callOperation(operationRegExpTest, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
-            m_jit.exceptionCheck();
-        
-            m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
-            jsValueResult(result.gpr(), node);
-            break;
-        }
-        
-        JSValueOperand base(this, node->child2());
-        JSValueOperand argument(this, node->child3());
-        GPRReg baseGPR = base.gpr();
-        GPRReg argumentGPR = argument.gpr();
-        
-        flushRegisters();
-        GPRFlushedCallResult result(this);
-        callOperation(operationRegExpTestGeneric, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
-        m_jit.exceptionCheck();
-        
-        m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
-        jsValueResult(result.gpr(), node, DataFormatJSBoolean);
+        compileRegExpTest(node);
         break;
     }
 
     case StringReplace:
     case StringReplaceRegExp: {
-        bool sample = false;
-
-        if (sample)
-            m_jit.incrementSuperSamplerCount();
-        
-        if (node->child1().useKind() == StringUse
-            && node->child2().useKind() == RegExpObjectUse
-            && node->child3().useKind() == StringUse) {
-            if (JSString* replace = node->child3()->dynamicCastConstant<JSString*>(*m_jit.vm())) {
-                if (!replace->length()) {
-                    SpeculateCellOperand string(this, node->child1());
-                    SpeculateCellOperand regExp(this, node->child2());
-                    GPRReg stringGPR = string.gpr();
-                    GPRReg regExpGPR = regExp.gpr();
-                    speculateString(node->child1(), stringGPR);
-                    speculateRegExpObject(node->child2(), regExpGPR);
-
-                    flushRegisters();
-                    GPRFlushedCallResult result(this);
-                    callOperation(
-                        operationStringProtoFuncReplaceRegExpEmptyStr, result.gpr(), stringGPR,
-                        regExpGPR);
-                    m_jit.exceptionCheck();
-                    cellResult(result.gpr(), node);
-                    if (sample)
-                        m_jit.decrementSuperSamplerCount();
-                    break;
-                }
-            }
-            
-            SpeculateCellOperand string(this, node->child1());
-            SpeculateCellOperand regExp(this, node->child2());
-            SpeculateCellOperand replace(this, node->child3());
-            GPRReg stringGPR = string.gpr();
-            GPRReg regExpGPR = regExp.gpr();
-            GPRReg replaceGPR = replace.gpr();
-            speculateString(node->child1(), stringGPR);
-            speculateRegExpObject(node->child2(), regExpGPR);
-            speculateString(node->child3(), replaceGPR);
-            
-            flushRegisters();
-            GPRFlushedCallResult result(this);
-            callOperation(
-                operationStringProtoFuncReplaceRegExpString, result.gpr(), stringGPR, regExpGPR,
-                replaceGPR);
-            m_jit.exceptionCheck();
-            cellResult(result.gpr(), node);
-            if (sample)
-                m_jit.decrementSuperSamplerCount();
-            break;
-        }
-
-        // If we fixed up the edge of child2, we inserted a Check(@child2, String).
-        OperandSpeculationMode child2SpeculationMode = AutomaticOperandSpeculation;
-        if (node->child2().useKind() == StringUse)
-            child2SpeculationMode = ManualOperandSpeculation;
-
-        JSValueOperand string(this, node->child1());
-        JSValueOperand search(this, node->child2(), child2SpeculationMode);
-        JSValueOperand replace(this, node->child3());
-        GPRReg stringGPR = string.gpr();
-        GPRReg searchGPR = search.gpr();
-        GPRReg replaceGPR = replace.gpr();
-        
-        flushRegisters();
-        GPRFlushedCallResult result(this);
-        callOperation(
-            operationStringProtoFuncReplaceGeneric, result.gpr(), stringGPR, searchGPR,
-            replaceGPR);
-        m_jit.exceptionCheck();
-        cellResult(result.gpr(), node);
-        if (sample)
-            m_jit.decrementSuperSamplerCount();
+        compileStringReplace(node);
         break;
     }
         
@@ -3845,25 +3660,7 @@
     }
         
     case ToPrimitive: {
-        DFG_ASSERT(m_jit.graph(), node, node->child1().useKind() == UntypedUse);
-        JSValueOperand argument(this, node->child1());
-        GPRTemporary result(this, Reuse, argument);
-        
-        GPRReg argumentGPR = argument.gpr();
-        GPRReg resultGPR = result.gpr();
-        
-        argument.use();
-        
-        MacroAssembler::Jump alreadyPrimitive = m_jit.branchIfNotCell(JSValueRegs(argumentGPR));
-        MacroAssembler::Jump notPrimitive = m_jit.branchIfObject(argumentGPR);
-        
-        alreadyPrimitive.link(&m_jit);
-        m_jit.move(argumentGPR, resultGPR);
-        
-        addSlowPathGenerator(
-            slowPathCall(notPrimitive, this, operationToPrimitive, resultGPR, argumentGPR));
-        
-        jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
+        compileToPrimitive(node);
         break;
     }
 
@@ -5452,18 +5249,7 @@
         break;
     }
     case HasGenericProperty: {
-        JSValueOperand base(this, node->child1());
-        SpeculateCellOperand property(this, node->child2());
-
-        JSValueRegs baseRegs = base.jsValueRegs();
-        GPRReg propertyGPR = property.gpr();
-
-        flushRegisters();
-        GPRFlushedCallResult result(this);
-        GPRReg resultGPR = result.gpr();
-        callOperation(operationHasGenericProperty, resultGPR, baseRegs, propertyGPR);
-        m_jit.exceptionCheck();
-        jsValueResult(resultGPR, node, DataFormatJSBoolean);
+        compileHasGenericProperty(node);
         break;
     }
     case HasStructureProperty: {
@@ -5701,48 +5487,12 @@
     }
         
     case LogShadowChickenPrologue: {
-        flushRegisters();
-        prepareForExternalCall();
-        m_jit.emitStoreCodeOrigin(node->origin.semantic);
-
-        GPRTemporary scratch1(this, GPRInfo::nonArgGPR0); // This must be a non-argument GPR.
-        GPRReg scratch1Reg = scratch1.gpr();
-        GPRTemporary scratch2(this);
-        GPRReg scratch2Reg = scratch2.gpr();
-        GPRTemporary shadowPacket(this);
-        GPRReg shadowPacketReg = shadowPacket.gpr();
-
-        m_jit.ensureShadowChickenPacket(*m_jit.vm(), shadowPacketReg, scratch1Reg, scratch2Reg);
-
-        SpeculateCellOperand scope(this, node->child1());
-        GPRReg scopeReg = scope.gpr();
-
-        m_jit.logShadowChickenProloguePacket(shadowPacketReg, scratch1Reg, scopeReg);
-        noResult(node);
+        compileLogShadowChickenPrologue(node);
         break;
     }
 
     case LogShadowChickenTail: {
-        flushRegisters();
-        prepareForExternalCall();
-        CallSiteIndex callSiteIndex = m_jit.emitStoreCodeOrigin(node->origin.semantic);
-
-        GPRTemporary scratch1(this, GPRInfo::nonArgGPR0); // This must be a non-argument GPR.
-        GPRReg scratch1Reg = scratch1.gpr();
-        GPRTemporary scratch2(this);
-        GPRReg scratch2Reg = scratch2.gpr();
-        GPRTemporary shadowPacket(this);
-        GPRReg shadowPacketReg = shadowPacket.gpr();
-
-        m_jit.ensureShadowChickenPacket(*m_jit.vm(), shadowPacketReg, scratch1Reg, scratch2Reg);
-
-        JSValueOperand thisValue(this, node->child1());
-        JSValueRegs thisRegs = JSValueRegs(thisValue.gpr());
-        SpeculateCellOperand scope(this, node->child2());
-        GPRReg scopeReg = scope.gpr();
-
-        m_jit.logShadowChickenTailPacket(shadowPacketReg, thisRegs, scopeReg, m_jit.codeBlock(), callSiteIndex);
-        noResult(node);
+        compileLogShadowChickenTail(node);
         break;
     }
 
@@ -5975,11 +5725,9 @@
     SpeculateDoubleOperand value(this, edge);
     FPRReg valueFPR = value.fpr();
     
+    flushRegisters();
     GPRFlushedCallResult result(this);
     GPRReg resultGPR = result.gpr();
-    
-    flushRegisters();
-    
     callOperation(operationConvertDoubleToInt52, resultGPR, valueFPR);
     
     DFG_TYPE_CHECK(

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (226268 => 226269)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2017-12-22 19:51:03 UTC (rev 226269)
@@ -10320,7 +10320,7 @@
                     LValue regExp = lowRegExpObject(m_node->child2());
 
                     LValue result = vmCall(
-                        Int64, m_out.operation(operationStringProtoFuncReplaceRegExpEmptyStr),
+                        pointerType(), m_out.operation(operationStringProtoFuncReplaceRegExpEmptyStr),
                         m_callFrame, string, regExp);
 
                     setJSValue(result);
@@ -10333,7 +10333,7 @@
             LValue replace = lowString(m_node->child3());
 
             LValue result = vmCall(
-                Int64, m_out.operation(operationStringProtoFuncReplaceRegExpString),
+                pointerType(), m_out.operation(operationStringProtoFuncReplaceRegExpString),
                 m_callFrame, string, regExp, replace);
 
             setJSValue(result);
@@ -10347,7 +10347,7 @@
             search = lowJSValue(m_node->child2());
 
         LValue result = vmCall(
-            Int64, m_out.operation(operationStringProtoFuncReplaceGeneric), m_callFrame,
+            pointerType(), m_out.operation(operationStringProtoFuncReplaceGeneric), m_callFrame,
             lowJSValue(m_node->child1()), search,
             lowJSValue(m_node->child3()));
 

Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (226268 => 226269)


--- trunk/Source/_javascript_Core/jit/JITOperations.cpp	2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp	2017-12-22 19:51:03 UTC (rev 226269)
@@ -58,7 +58,6 @@
 #include "JSGeneratorFunction.h"
 #include "JSGlobalObjectFunctions.h"
 #include "JSLexicalEnvironment.h"
-#include "JSPropertyNameEnumerator.h"
 #include "JSWithScope.h"
 #include "ModuleProgramCodeBlock.h"
 #include "ObjectConstructor.h"
@@ -2372,66 +2371,6 @@
 #endif // COMPILER(GCC_OR_CLANG)
 }
 
-EncodedJSValue JIT_OPERATION operationHasGenericProperty(ExecState* exec, EncodedJSValue encodedBaseValue, JSCell* propertyName)
-{
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-    JSValue baseValue = JSValue::decode(encodedBaseValue);
-    if (baseValue.isUndefinedOrNull())
-        return JSValue::encode(jsBoolean(false));
-
-    JSObject* base = baseValue.toObject(exec);
-    if (!base)
-        return JSValue::encode(JSValue());
-    return JSValue::encode(jsBoolean(base->hasPropertyGeneric(exec, asString(propertyName)->toIdentifier(exec), PropertySlot::InternalMethodType::GetOwnProperty)));
-}
-
-JSCell* JIT_OPERATION operationGetPropertyEnumeratorCell(ExecState* exec, JSCell* cell)
-{
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    JSObject* base = cell->toObject(exec, exec->lexicalGlobalObject());
-    RETURN_IF_EXCEPTION(scope, { });
-
-    scope.release();
-    return propertyNameEnumerator(exec, base);
-}
-
-JSCell* JIT_OPERATION operationGetPropertyEnumerator(ExecState* exec, EncodedJSValue encodedBase)
-{
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    JSValue base = JSValue::decode(encodedBase);
-    if (base.isUndefinedOrNull())
-        return JSPropertyNameEnumerator::create(vm);
-
-    JSObject* baseObject = base.toObject(exec);
-    RETURN_IF_EXCEPTION(scope, { });
-
-    scope.release();
-    return propertyNameEnumerator(exec, baseObject);
-}
-
-EncodedJSValue JIT_OPERATION operationNextEnumeratorPname(ExecState* exec, JSCell* enumeratorCell, int32_t index)
-{
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-    JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(enumeratorCell);
-    JSString* propertyName = enumerator->propertyNameAtIndex(index);
-    return JSValue::encode(propertyName ? propertyName : jsNull());
-}
-
-JSCell* JIT_OPERATION operationToIndexString(ExecState* exec, int32_t index)
-{
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-    return jsString(exec, Identifier::from(exec, index).string());
-}
-
 ALWAYS_INLINE static EncodedJSValue unprofiledAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
 {
     VM* vm = &exec->vm();

Modified: trunk/Source/_javascript_Core/jit/JITOperations.h (226268 => 226269)


--- trunk/Source/_javascript_Core/jit/JITOperations.h	2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/jit/JITOperations.h	2017-12-22 19:51:03 UTC (rev 226269)
@@ -220,6 +220,8 @@
 typedef JSCell* (JIT_OPERATION *C_JITOperation_ECJZ)(ExecState*, JSCell*, EncodedJSValue, int32_t);
 typedef JSCell* (JIT_OPERATION *C_JITOperation_ECJ)(ExecState*, JSCell*, EncodedJSValue);
 typedef JSCell* (JIT_OPERATION *C_JITOperation_ECO)(ExecState*, JSCell*, JSObject*);
+typedef JSCell* (JIT_OPERATION *C_JITOperation_EJssReo)(ExecState*, JSString*, RegExpObject*);
+typedef JSCell* (JIT_OPERATION *C_JITOperation_EJssReoJss)(ExecState*, JSString*, RegExpObject*, JSString*);
 typedef double (JIT_OPERATION *D_JITOperation_D)(double);
 typedef double (JIT_OPERATION *D_JITOperation_G)(JSGlobalObject*);
 typedef double (JIT_OPERATION *D_JITOperation_DD)(double, double);
@@ -460,12 +462,6 @@
 int32_t JIT_OPERATION operationCheckIfExceptionIsUncatchableAndNotifyProfiler(ExecState*);
 int32_t JIT_OPERATION operationInstanceOfCustom(ExecState*, EncodedJSValue encodedValue, JSObject* constructor, EncodedJSValue encodedHasInstance) WTF_INTERNAL;
 
-EncodedJSValue JIT_OPERATION operationHasGenericProperty(ExecState*, EncodedJSValue, JSCell*);
-JSCell* JIT_OPERATION operationGetPropertyEnumeratorCell(ExecState*, JSCell*);
-JSCell* JIT_OPERATION operationGetPropertyEnumerator(ExecState*, EncodedJSValue);
-EncodedJSValue JIT_OPERATION operationNextEnumeratorPname(ExecState*, JSCell*, int32_t);
-JSCell* JIT_OPERATION operationToIndexString(ExecState*, int32_t);
-
 EncodedJSValue JIT_OPERATION operationValueAdd(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueAddProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueAddProfiledOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*) WTF_INTERNAL;

Modified: trunk/Source/_javascript_Core/runtime/StringPrototype.cpp (226268 => 226269)


--- trunk/Source/_javascript_Core/runtime/StringPrototype.cpp	2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/runtime/StringPrototype.cpp	2017-12-22 19:51:03 UTC (rev 226269)
@@ -307,7 +307,7 @@
     int length;
 };
 
-static ALWAYS_INLINE JSValue jsSpliceSubstrings(ExecState* exec, JSString* sourceVal, const String& source, const StringRange* substringRanges, int rangeCount)
+static ALWAYS_INLINE JSString* jsSpliceSubstrings(ExecState* exec, JSString* sourceVal, const String& source, const StringRange* substringRanges, int rangeCount)
 {
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -334,8 +334,10 @@
         LChar* buffer;
         const LChar* sourceData = source.characters8();
         auto impl = StringImpl::tryCreateUninitialized(totalLength, buffer);
-        if (!impl)
-            return throwOutOfMemoryError(exec, scope);
+        if (!impl) {
+            throwOutOfMemoryError(exec, scope);
+            return nullptr;
+        }
 
         int bufferPos = 0;
         for (int i = 0; i < rangeCount; i++) {
@@ -353,8 +355,10 @@
     const UChar* sourceData = source.characters16();
 
     auto impl = StringImpl::tryCreateUninitialized(totalLength, buffer);
-    if (!impl)
-        return throwOutOfMemoryError(exec, scope);
+    if (!impl) {
+        throwOutOfMemoryError(exec, scope);
+        return nullptr;
+    }
 
     int bufferPos = 0;
     for (int i = 0; i < rangeCount; i++) {
@@ -368,7 +372,7 @@
     return jsString(exec, WTFMove(impl));
 }
 
-static ALWAYS_INLINE JSValue jsSpliceSubstringsWithSeparators(ExecState* exec, JSString* sourceVal, const String& source, const StringRange* substringRanges, int rangeCount, const String* separators, int separatorCount)
+static ALWAYS_INLINE JSString* jsSpliceSubstringsWithSeparators(ExecState* exec, JSString* sourceVal, const String& source, const StringRange* substringRanges, int rangeCount, const String* separators, int separatorCount)
 {
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -393,8 +397,10 @@
         if (separators[i].length() && !separators[i].is8Bit())
             allSeparators8Bit = false;
     }
-    if (totalLength.hasOverflowed())
-        return throwOutOfMemoryError(exec, scope);
+    if (totalLength.hasOverflowed()) {
+        throwOutOfMemoryError(exec, scope);
+        return nullptr;
+    }
 
     if (!totalLength)
         return jsEmptyString(exec);
@@ -404,8 +410,10 @@
         const LChar* sourceData = source.characters8();
 
         auto impl = StringImpl::tryCreateUninitialized(totalLength.unsafeGet(), buffer);
-        if (!impl)
-            return throwOutOfMemoryError(exec, scope);
+        if (!impl) {
+            throwOutOfMemoryError(exec, scope);
+            return nullptr;
+        }
 
         int maxCount = std::max(rangeCount, separatorCount);
         int bufferPos = 0;
@@ -430,8 +438,10 @@
 
     UChar* buffer;
     auto impl = StringImpl::tryCreateUninitialized(totalLength.unsafeGet(), buffer);
-    if (!impl)
-        return throwOutOfMemoryError(exec, scope);
+    if (!impl) {
+        throwOutOfMemoryError(exec, scope);
+        return nullptr;
+    }
 
     int maxCount = std::max(rangeCount, separatorCount);
     int bufferPos = 0;
@@ -463,10 +473,10 @@
 #define OUT_OF_MEMORY(exec__, scope__) \
     do { \
         throwOutOfMemoryError(exec__, scope__); \
-        return encodedJSValue(); \
+        return nullptr; \
     } while (false)
 
-static ALWAYS_INLINE EncodedJSValue removeUsingRegExpSearch(VM& vm, ExecState* exec, JSString* string, const String& source, RegExp* regExp)
+static ALWAYS_INLINE JSString* removeUsingRegExpSearch(VM& vm, ExecState* exec, JSString* string, const String& source, RegExp* regExp)
 {
     auto scope = DECLARE_THROW_SCOPE(vm);
     SuperSamplerScope superSamplerScope(false);
@@ -499,7 +509,7 @@
     }
 
     if (!lastIndex)
-        return JSValue::encode(string);
+        return string;
 
     if (static_cast<unsigned>(lastIndex) < sourceLen) {
         if (UNLIKELY(!sourceRanges.tryConstructAndAppend(lastIndex, sourceLen - lastIndex)))
@@ -506,10 +516,10 @@
             OUT_OF_MEMORY(exec, scope);
     }
     scope.release();
-    return JSValue::encode(jsSpliceSubstrings(exec, string, source, sourceRanges.data(), sourceRanges.size()));
+    return jsSpliceSubstrings(exec, string, source, sourceRanges.data(), sourceRanges.size());
 }
 
-static ALWAYS_INLINE EncodedJSValue replaceUsingRegExpSearch(
+static ALWAYS_INLINE JSString* replaceUsingRegExpSearch(
     VM& vm, ExecState* exec, JSString* string, JSValue searchValue, CallData& callData,
     CallType callType, String& replacementString, JSValue replaceValue)
 {
@@ -517,7 +527,7 @@
 
     const String& source = string->value(exec);
     unsigned sourceLen = source.length();
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+    RETURN_IF_EXCEPTION(scope, nullptr);
     RegExpObject* regExpObject = asRegExpObject(searchValue);
     RegExp* regExp = regExpObject->regExp();
     bool global = regExp->global();
@@ -526,7 +536,7 @@
     if (global) {
         // ES5.1 15.5.4.10 step 8.a.
         regExpObject->setLastIndex(exec, 0);
-        RETURN_IF_EXCEPTION(scope, encodedJSValue());
+        RETURN_IF_EXCEPTION(scope, nullptr);
 
         if (callType == CallType::None && !replacementString.length()) {
             scope.release();
@@ -550,7 +560,7 @@
         int argCount = regExp->numSubpatterns() + 1 + 2;
         JSFunction* func = jsCast<JSFunction*>(replaceValue);
         CachedCall cachedCall(exec, func, argCount);
-        RETURN_IF_EXCEPTION(scope, encodedJSValue());
+        RETURN_IF_EXCEPTION(scope, nullptr);
         if (source.is8Bit()) {
             while (true) {
                 int* ovector;
@@ -599,13 +609,13 @@
                 cachedCall.setThis(jsUndefined());
                 if (UNLIKELY(cachedCall.hasOverflowedArguments())) {
                     throwOutOfMemoryError(exec, scope);
-                    return encodedJSValue();
+                    return nullptr;
                 }
 
                 JSValue jsResult = cachedCall.call();
-                RETURN_IF_EXCEPTION(scope, encodedJSValue());
+                RETURN_IF_EXCEPTION(scope, nullptr);
                 replacements.append(jsResult.toWTFString(exec));
-                RETURN_IF_EXCEPTION(scope, encodedJSValue());
+                RETURN_IF_EXCEPTION(scope, nullptr);
 
                 lastIndex = result.end;
                 startPosition = lastIndex;
@@ -665,13 +675,13 @@
                 cachedCall.setThis(jsUndefined());
                 if (UNLIKELY(cachedCall.hasOverflowedArguments())) {
                     throwOutOfMemoryError(exec, scope);
-                    return encodedJSValue();
+                    return nullptr;
                 }
 
                 JSValue jsResult = cachedCall.call();
-                RETURN_IF_EXCEPTION(scope, encodedJSValue());
+                RETURN_IF_EXCEPTION(scope, nullptr);
                 replacements.append(jsResult.toWTFString(exec));
-                RETURN_IF_EXCEPTION(scope, encodedJSValue());
+                RETURN_IF_EXCEPTION(scope, nullptr);
 
                 lastIndex = result.end;
                 startPosition = lastIndex;
@@ -730,15 +740,15 @@
                     args.append(groups);
                 if (UNLIKELY(args.hasOverflowed())) {
                     throwOutOfMemoryError(exec, scope);
-                    return encodedJSValue();
+                    return nullptr;
                 }
 
                 JSValue replacement = call(exec, replaceValue, callType, callData, jsUndefined(), args);
-                RETURN_IF_EXCEPTION(scope, encodedJSValue());
+                RETURN_IF_EXCEPTION(scope, nullptr);
                 String replacementString = replacement.toWTFString(exec);
-                RETURN_IF_EXCEPTION(scope, encodedJSValue());
+                RETURN_IF_EXCEPTION(scope, nullptr);
                 replacements.append(replacementString);
-                RETURN_IF_EXCEPTION(scope, encodedJSValue());
+                RETURN_IF_EXCEPTION(scope, nullptr);
             } else {
                 int replLen = replacementString.length();
                 if (lastIndex < result.start || replLen) {
@@ -765,7 +775,7 @@
     }
 
     if (!lastIndex && replacements.isEmpty())
-        return JSValue::encode(string);
+        return string;
 
     if (static_cast<unsigned>(lastIndex) < sourceLen) {
         if (UNLIKELY(!sourceRanges.tryConstructAndAppend(lastIndex, sourceLen - lastIndex)))
@@ -772,10 +782,10 @@
             OUT_OF_MEMORY(exec, scope);
     }
     scope.release();
-    return JSValue::encode(jsSpliceSubstringsWithSeparators(exec, string, source, sourceRanges.data(), sourceRanges.size(), replacements.data(), replacements.size()));
+    return jsSpliceSubstringsWithSeparators(exec, string, source, sourceRanges.data(), sourceRanges.size(), replacements.data(), replacements.size());
 }
 
-EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceRegExpEmptyStr(
+JSCell* JIT_OPERATION operationStringProtoFuncReplaceRegExpEmptyStr(
     ExecState* exec, JSString* thisValue, RegExpObject* searchValue)
 {
     VM& vm = exec->vm();
@@ -786,7 +796,7 @@
     if (regExp->global()) {
         // ES5.1 15.5.4.10 step 8.a.
         searchValue->setLastIndex(exec, 0);
-        RETURN_IF_EXCEPTION(scope, encodedJSValue());
+        RETURN_IF_EXCEPTION(scope, nullptr);
         scope.release();
         return removeUsingRegExpSearch(vm, exec, thisValue, thisValue->value(exec), regExp);
     }
@@ -798,7 +808,7 @@
         vm, exec, thisValue, searchValue, callData, CallType::None, replacementString, JSValue());
 }
 
-EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceRegExpString(
+JSCell* JIT_OPERATION operationStringProtoFuncReplaceRegExpString(
     ExecState* exec, JSString* thisValue, RegExpObject* searchValue, JSString* replaceString)
 {
     VM& vm = exec->vm();
@@ -810,7 +820,7 @@
         vm, exec, thisValue, searchValue, callData, CallType::None, replacementString, replaceString);
 }
 
-static ALWAYS_INLINE EncodedJSValue replaceUsingRegExpSearch(VM& vm, ExecState* exec, JSString* string, JSValue searchValue, JSValue replaceValue)
+static ALWAYS_INLINE JSString* replaceUsingRegExpSearch(VM& vm, ExecState* exec, JSString* string, JSValue searchValue, JSValue replaceValue)
 {
     auto scope = DECLARE_THROW_SCOPE(vm);
 
@@ -819,7 +829,7 @@
     CallType callType = getCallData(replaceValue, callData);
     if (callType == CallType::None) {
         replacementString = replaceValue.toWTFString(exec);
-        RETURN_IF_EXCEPTION(scope, encodedJSValue());
+        RETURN_IF_EXCEPTION(scope, nullptr);
     }
 
     scope.release();
@@ -827,19 +837,19 @@
         vm, exec, string, searchValue, callData, callType, replacementString, replaceValue);
 }
 
-static ALWAYS_INLINE EncodedJSValue replaceUsingStringSearch(VM& vm, ExecState* exec, JSString* jsString, JSValue searchValue, JSValue replaceValue)
+static ALWAYS_INLINE JSString* replaceUsingStringSearch(VM& vm, ExecState* exec, JSString* jsString, JSValue searchValue, JSValue replaceValue)
 {
     auto scope = DECLARE_THROW_SCOPE(vm);
 
     const String& string = jsString->value(exec);
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+    RETURN_IF_EXCEPTION(scope, nullptr);
     String searchString = searchValue.toWTFString(exec);
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+    RETURN_IF_EXCEPTION(scope, nullptr);
 
     size_t matchStart = string.find(searchString);
 
     if (matchStart == notFound)
-        return JSValue::encode(jsString);
+        return jsString;
 
     CallData callData;
     CallType callType = getCallData(replaceValue, callData);
@@ -850,11 +860,11 @@
         args.append(jsString);
         ASSERT(!args.hasOverflowed());
         replaceValue = call(exec, replaceValue, callType, callData, jsUndefined(), args);
-        RETURN_IF_EXCEPTION(scope, encodedJSValue());
+        RETURN_IF_EXCEPTION(scope, nullptr);
     }
 
     String replaceString = replaceValue.toWTFString(exec);
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+    RETURN_IF_EXCEPTION(scope, nullptr);
 
     StringImpl* stringImpl = string.impl();
     String leftPart(StringImpl::createSubstringSharingImpl(*stringImpl, 0, matchStart));
@@ -866,7 +876,7 @@
     size_t leftLength = stringImpl->length() - matchEnd;
     String rightPart(StringImpl::createSubstringSharingImpl(*stringImpl, matchEnd, leftLength));
     scope.release();
-    return JSValue::encode(JSC::jsString(exec, leftPart, middlePart, rightPart));
+    return JSC::jsString(exec, leftPart, middlePart, rightPart);
 }
 
 static inline bool checkObjectCoercible(JSValue thisValue)
@@ -936,7 +946,7 @@
     return JSValue::encode(repeatCharacter(*exec, character, repeatCount));
 }
 
-ALWAYS_INLINE EncodedJSValue replace(
+ALWAYS_INLINE JSString* replace(
     VM& vm, ExecState* exec, JSString* string, JSValue searchValue, JSValue replaceValue)
 {
     if (searchValue.inherits(vm, RegExpObject::info()))
@@ -944,15 +954,17 @@
     return replaceUsingStringSearch(vm, exec, string, searchValue, replaceValue);
 }
 
-ALWAYS_INLINE EncodedJSValue replace(
+ALWAYS_INLINE JSString* replace(
     VM& vm, ExecState* exec, JSValue thisValue, JSValue searchValue, JSValue replaceValue)
 {
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    if (!checkObjectCoercible(thisValue))
-        return throwVMTypeError(exec, scope);
+    if (!checkObjectCoercible(thisValue)) {
+        throwVMTypeError(exec, scope);
+        return nullptr;
+    }
     JSString* string = thisValue.toString(exec);
-    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+    RETURN_IF_EXCEPTION(scope, nullptr);
     scope.release();
     return replace(vm, exec, string, searchValue, replaceValue);
 }
@@ -970,7 +982,7 @@
         return JSValue::encode(jsUndefined());
 
     scope.release();
-    return replaceUsingRegExpSearch(vm, exec, string, searchValue, exec->argument(1));
+    return JSValue::encode(replaceUsingRegExpSearch(vm, exec, string, searchValue, exec->argument(1)));
 }
 
 EncodedJSValue JSC_HOST_CALL stringProtoFuncReplaceUsingStringSearch(ExecState* exec)
@@ -982,10 +994,10 @@
     RETURN_IF_EXCEPTION(scope, encodedJSValue());
 
     scope.release();
-    return replaceUsingStringSearch(vm, exec, string, exec->argument(0), exec->argument(1));
+    return JSValue::encode(replaceUsingStringSearch(vm, exec, string, exec->argument(0), exec->argument(1)));
 }
 
-EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceGeneric(
+JSCell* JIT_OPERATION operationStringProtoFuncReplaceGeneric(
     ExecState* exec, EncodedJSValue thisValue, EncodedJSValue searchValue,
     EncodedJSValue replaceValue)
 {

Modified: trunk/Source/_javascript_Core/runtime/StringPrototype.h (226268 => 226269)


--- trunk/Source/_javascript_Core/runtime/StringPrototype.h	2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/runtime/StringPrototype.h	2017-12-22 19:51:03 UTC (rev 226269)
@@ -50,13 +50,13 @@
     void finishCreation(VM&, JSGlobalObject*, JSString*);
 };
 
-EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceGeneric(
+JSCell* JIT_OPERATION operationStringProtoFuncReplaceGeneric(
     ExecState*, EncodedJSValue thisValue, EncodedJSValue searchValue, EncodedJSValue replaceValue);
 
-EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceRegExpEmptyStr(
+JSCell* JIT_OPERATION operationStringProtoFuncReplaceRegExpEmptyStr(
     ExecState*, JSString* thisValue, RegExpObject* searchValue);
 
-EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceRegExpString(
+JSCell* JIT_OPERATION operationStringProtoFuncReplaceRegExpString(
     ExecState*, JSString* thisValue, RegExpObject* searchValue, JSString* replaceValue);
 
 String substituteBackreferences(const String& replacement, StringView source, const int* ovector, RegExp* reg);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to