Changeset 205511 in webkit


Ignore:
Timestamp:
Sep 6, 2016 2:54:11 PM (8 years ago)
Author:
commit-queue@webkit.org
Message:

[JSC] Make ArithClz32 work with Cell arguments
https://bugs.webkit.org/show_bug.cgi?id=161369

Patch by Benjamin Poulain <bpoulain@apple.com> on 2016-09-06
Reviewed by Geoffrey Garen.

JSTests:

  • stress/arith-clz32-on-various-types.js: Added.

Source/JavaScriptCore:

ArithClz32 was already working with all primitive types
thanks to the magic of ValueToInt32.
This patch adds support for cell arguments through a function
call.

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):

  • dfg/DFGNodeType.h:
  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileArithClz32):

  • dfg/DFGSpeculativeJIT.h:

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

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileArithClz32):

Location:
trunk
Files:
1 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r205507 r205511  
     12016-09-06  Benjamin Poulain  <bpoulain@apple.com>
     2
     3        [JSC] Make ArithClz32 work with Cell arguments
     4        https://bugs.webkit.org/show_bug.cgi?id=161369
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        * stress/arith-clz32-on-various-types.js: Added.
     9
    1102016-09-06  Commit Queue  <commit-queue@webkit.org>
    211
  • trunk/Source/JavaScriptCore/ChangeLog

    r205509 r205511  
     12016-09-06  Benjamin Poulain  <bpoulain@apple.com>
     2
     3        [JSC] Make ArithClz32 work with Cell arguments
     4        https://bugs.webkit.org/show_bug.cgi?id=161369
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        ArithClz32 was already working with all primitive types
     9        thanks to the magic of ValueToInt32.
     10        This patch adds support for cell arguments through a function
     11        call.
     12
     13        * dfg/DFGAbstractInterpreterInlines.h:
     14        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     15        * dfg/DFGClobberize.h:
     16        (JSC::DFG::clobberize):
     17        * dfg/DFGFixupPhase.cpp:
     18        (JSC::DFG::FixupPhase::fixupNode):
     19        * dfg/DFGNodeType.h:
     20        * dfg/DFGOperations.cpp:
     21        * dfg/DFGOperations.h:
     22        * dfg/DFGSpeculativeJIT.cpp:
     23        (JSC::DFG::SpeculativeJIT::compileArithClz32):
     24        * dfg/DFGSpeculativeJIT.h:
     25        (JSC::DFG::SpeculativeJIT::callOperation):
     26        * ftl/FTLLowerDFGToB3.cpp:
     27        (JSC::FTL::DFG::LowerDFGToB3::compileArithClz32):
     28
    1292016-09-06  Mark Lam  <mark.lam@apple.com>
    230
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r205507 r205511  
    548548    case ArithClz32: {
    549549        JSValue operand = forNode(node->child1()).value();
    550         if (operand && operand.isNumber()) {
    551             uint32_t value = toUInt32(operand.asNumber());
     550        if (Optional<double> number = operand.toNumberFromPrimitive()) {
     551            uint32_t value = toUInt32(*number);
    552552            setConstant(node, jsNumber(clz32(value)));
    553553            break;
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r205507 r205511  
    150150       
    151151    case ArithIMul:
    152     case ArithClz32:
    153152    case ArithMin:
    154153    case ArithMax:
     
    200199    case ArithAbs:
    201200        if (node->child1().useKind() == Int32Use || node->child1().useKind() == DoubleRepUse)
     201            def(PureValue(node));
     202        else {
     203            read(World);
     204            write(Heap);
     205        }
     206        return;
     207
     208    case ArithClz32:
     209        if (node->child1().useKind() == Int32Use || node->child1().useKind() == KnownInt32Use)
    202210            def(PureValue(node));
    203211        else {
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r205507 r205511  
    127127
    128128        case ArithClz32: {
    129             fixIntConvertingEdge(node->child1());
    130             node->setArithMode(Arith::Unchecked);
     129            if (node->child1()->shouldSpeculateNotCell()) {
     130                fixIntConvertingEdge(node->child1());
     131                node->clearFlags(NodeMustGenerate);
     132            } else
     133                fixEdge<UntypedUse>(node->child1());
    131134            break;
    132135        }
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r205507 r205511  
    143143    /* generally, we need to keep alive any operation whose checks cause filtration in AI. */\
    144144    macro(ArithAdd, NodeResultNumber | NodeMustGenerate) \
    145     macro(ArithClz32, NodeResultInt32) \
     145    macro(ArithClz32, NodeResultInt32 | NodeMustGenerate) \
    146146    macro(ArithSub, NodeResultNumber | NodeMustGenerate) \
    147147    macro(ArithNegate, NodeResultNumber | NodeMustGenerate) \
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r205508 r205511  
    333333    double a = op1.toNumber(exec);
    334334    if (UNLIKELY(vm->exception()))
    335         return JSValue::encode(JSValue());
     335        return PNaN;
    336336    return fabs(a);
     337}
     338
     339int32_t JIT_OPERATION operationArithClz32(ExecState* exec, EncodedJSValue encodedOp1)
     340{
     341    VM* vm = &exec->vm();
     342    NativeCallFrameTracer tracer(vm, exec);
     343
     344    JSValue op1 = JSValue::decode(encodedOp1);
     345    uint32_t value = op1.toUInt32(exec);
     346    if (UNLIKELY(vm->exception()))
     347        return 0;
     348    return clz32(value);
    337349}
    338350
     
    357369    double a = op1.toNumber(exec);
    358370    if (UNLIKELY(vm->exception()))
    359         return JSValue::encode(JSValue());
     371        return PNaN;
    360372    return static_cast<float>(a);
    361373}
     
    369381    double a = op1.toNumber(exec);
    370382    if (UNLIKELY(vm->exception()))
    371         return JSValue::encode(JSValue());
     383        return PNaN;
    372384    return log(a);
    373385}
     
    381393    double a = op1.toNumber(exec);
    382394    if (UNLIKELY(vm->exception()))
    383         return JSValue::encode(JSValue());
     395        return PNaN;
    384396    return sin(a);
    385397}
     
    393405    double a = op1.toNumber(exec);
    394406    if (UNLIKELY(vm->exception()))
    395         return JSValue::encode(JSValue());
     407        return PNaN;
    396408    return sqrt(a);
    397409}
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r205508 r205511  
    5555EncodedJSValue JIT_OPERATION operationValueDiv(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
    5656double JIT_OPERATION operationArithAbs(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
     57int32_t JIT_OPERATION operationArithClz32(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
    5758double JIT_OPERATION operationArithCos(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
    5859double JIT_OPERATION operationArithFRound(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r205508 r205511  
    39333933void SpeculativeJIT::compileArithClz32(Node* node)
    39343934{
    3935     ASSERT_WITH_MESSAGE(node->child1().useKind() == Int32Use || node->child1().useKind() == KnownInt32Use, "The Fixup phase should have enforced a Int32 operand.");
    3936     SpeculateInt32Operand value(this, node->child1());
    3937     GPRTemporary result(this, Reuse, value);
    3938     GPRReg valueReg = value.gpr();
     3935    if (node->child1().useKind() == Int32Use || node->child1().useKind() == KnownInt32Use) {
     3936        SpeculateInt32Operand value(this, node->child1());
     3937        GPRTemporary result(this, Reuse, value);
     3938        GPRReg valueReg = value.gpr();
     3939        GPRReg resultReg = result.gpr();
     3940        m_jit.countLeadingZeros32(valueReg, resultReg);
     3941        int32Result(resultReg, node);
     3942        return;
     3943    }
     3944    JSValueOperand op1(this, node->child1());
     3945    JSValueRegs op1Regs = op1.jsValueRegs();
     3946    GPRTemporary result(this);
    39393947    GPRReg resultReg = result.gpr();
    3940     m_jit.countLeadingZeros32(valueReg, resultReg);
     3948    flushRegisters();
     3949    callOperation(operationArithClz32, resultReg, op1Regs);
     3950    m_jit.exceptionCheck();
    39413951    int32Result(resultReg, node);
    39423952}
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r205508 r205511  
    16921692    }
    16931693
     1694    JITCompiler::Call callOperation(Z_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1)
     1695    {
     1696        m_jit.setupArgumentsWithExecState(arg1.payloadGPR());
     1697        return appendCallSetResult(operation, result);
     1698    }
     1699
    16941700    JITCompiler::Call callOperation(Z_JITOperation_EJZZ operation, GPRReg result, GPRReg arg1, unsigned arg2, unsigned arg3)
    16951701    {
     
    21332139        return appendCallSetResult(operation, result);
    21342140    }
    2135 
     2141    JITCompiler::Call callOperation(Z_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1)
     2142    {
     2143        m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG  arg1.payloadGPR(), arg1.tagGPR());
     2144        return appendCallSetResult(operation, result);
     2145    }
    21362146    JITCompiler::Call callOperation(Z_JITOperation_EJZZ operation, GPRReg result, JSValueRegs arg1, unsigned arg2, unsigned arg3)
    21372147    {
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r205508 r205511  
    17271727    void compileArithClz32()
    17281728    {
    1729         LValue operand = lowInt32(m_node->child1());
    1730         setInt32(m_out.ctlz32(operand));
     1729        if (m_node->child1().useKind() == Int32Use || m_node->child1().useKind() == KnownInt32Use) {
     1730            LValue operand = lowInt32(m_node->child1());
     1731            setInt32(m_out.ctlz32(operand));
     1732            return;
     1733        }
     1734        DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
     1735        LValue argument = lowJSValue(m_node->child1());
     1736        LValue result = vmCall(Int32, m_out.operation(operationArithClz32), m_callFrame, argument);
     1737        setInt32(result);
    17311738    }
    17321739   
Note: See TracChangeset for help on using the changeset viewer.