Changeset 207369 in webkit


Ignore:
Timestamp:
Oct 14, 2016 7:19:16 PM (8 years ago)
Author:
commit-queue@webkit.org
Message:

[JSC] op_negate should with any type
https://bugs.webkit.org/show_bug.cgi?id=162587

Patch by Benjamin Poulain <bpoulain@apple.com> on 2016-10-14
Reviewed by Saam Barati.

JSTests:

  • stress/arith-abs-to-arith-negate-range-optimizaton.js: Added.

Cover OSR Exits when converting Math.abs() into ArithNegate.

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

Cover ArithNegate with all types.

Source/JavaScriptCore:

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
ArithNegate is quite simple. If the input is double, the output
is double. The other cases are set from the LLInt slow case.

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::makeSafe):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGFixupPhase.cpp:

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

  • dfg/DFGIntegerRangeOptimizationPhase.cpp:

Tweak a bit the IntegerRangeOptimizationPhase when simplifying
ArithAbs to ArithNegate.
We should not do the conversion if the target nodes OSR Exits
on different input than the source node.

In particular, Checked ArithNegate exits on zero while
ArithAbs has not problem with it.
Unchecked ArithAbs() do not OSR Exit on INT_MIN, ArithNeg
should not either.

  • dfg/DFGPredictionPropagationPhase.cpp:
  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileArithNegate):
(JSC::DFG::SpeculativeJIT::compileMathIC):

  • dfg/DFGSpeculativeJIT.h:

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

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileMathIC):
(JSC::FTL::DFG::LowerDFGToB3::compileArithNegate):

  • jit/JITNegGenerator.cpp:

(JSC::JITNegGenerator::generateFastPath):

  • jit/JITOperations.cpp:

Add result profiling in baseline to have types we can use
in DFG and FTL.

Location:
trunk
Files:
2 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r207363 r207369  
     12016-10-14  Benjamin Poulain  <bpoulain@apple.com>
     2
     3        [JSC] op_negate should with any type
     4        https://bugs.webkit.org/show_bug.cgi?id=162587
     5
     6        Reviewed by Saam Barati.
     7
     8        * stress/arith-abs-to-arith-negate-range-optimizaton.js: Added.
     9        Cover OSR Exits when converting Math.abs() into ArithNegate.
     10
     11        * stress/arith-negate-on-various-types.js: Added.
     12        Cover ArithNegate with all types.
     13
    1142016-10-14  JF Bastien  <jfbastien@apple.com>
    215
  • trunk/Source/JavaScriptCore/ChangeLog

    r207360 r207369  
     12016-10-14  Benjamin Poulain  <bpoulain@apple.com>
     2
     3        [JSC] op_negate should with any type
     4        https://bugs.webkit.org/show_bug.cgi?id=162587
     5
     6        Reviewed by Saam Barati.
     7
     8        * dfg/DFGAbstractInterpreterInlines.h:
     9        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     10        ArithNegate is quite simple. If the input is double, the output
     11        is double. The other cases are set from the LLInt slow case.
     12
     13        * dfg/DFGByteCodeParser.cpp:
     14        (JSC::DFG::ByteCodeParser::makeSafe):
     15        * dfg/DFGClobberize.h:
     16        (JSC::DFG::clobberize):
     17        * dfg/DFGFixupPhase.cpp:
     18        (JSC::DFG::FixupPhase::fixupNode):
     19
     20        * dfg/DFGIntegerRangeOptimizationPhase.cpp:
     21        Tweak a bit the IntegerRangeOptimizationPhase when simplifying
     22        ArithAbs to ArithNegate.
     23        We should not do the conversion if the target nodes OSR Exits
     24        on different input than the source node.
     25
     26        In particular, Checked ArithNegate exits on zero while
     27        ArithAbs has not problem with it.
     28        Unchecked ArithAbs() do not OSR Exit on INT_MIN, ArithNeg
     29        should not either.
     30
     31        * dfg/DFGPredictionPropagationPhase.cpp:
     32        * dfg/DFGSpeculativeJIT.cpp:
     33        (JSC::DFG::SpeculativeJIT::compileArithNegate):
     34        (JSC::DFG::SpeculativeJIT::compileMathIC):
     35        * dfg/DFGSpeculativeJIT.h:
     36        (JSC::DFG::SpeculativeJIT::callOperation):
     37        * ftl/FTLLowerDFGToB3.cpp:
     38        (JSC::FTL::DFG::LowerDFGToB3::compileMathIC):
     39        (JSC::FTL::DFG::LowerDFGToB3::compileArithNegate):
     40
     41        * jit/JITNegGenerator.cpp:
     42        (JSC::JITNegGenerator::generateFastPath):
     43        * jit/JITOperations.cpp:
     44        Add result profiling in baseline to have types we can use
     45        in DFG and FTL.
     46
    1472016-10-14  Keith Miller  <keith_miller@apple.com>
    248
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r206853 r207369  
    658658            break;
    659659        default:
    660             RELEASE_ASSERT_NOT_REACHED();
     660            DFG_ASSERT(m_graph, node, node->child1().useKind() == UntypedUse);
     661            forNode(node).setType(SpecBytecodeNumber);
    661662            break;
    662663        }
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r207239 r207369  
    975975                    break;
    976976                }
     977                case ArithNegate: {
     978                    ASSERT_WITH_MESSAGE(!arithProfile->didObserveNonNumber(), "op_negate starts with a toNumber() on the argument, it should only produce numbers.");
     979
     980                    if (arithProfile->lhsObservedType().sawNumber() || arithProfile->didObserveDouble())
     981                        node->mergeFlags(NodeMayHaveDoubleResult);
     982                    if (arithProfile->didObserveNegZeroDouble() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero))
     983                        node->mergeFlags(NodeMayNegZeroInBaseline);
     984                    if (arithProfile->didObserveInt32Overflow() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
     985                        node->mergeFlags(NodeMayOverflowInt32InBaseline);
     986                    break;
     987                }
    977988               
    978989                default:
     
    9901001            case ArithMod: // for ArithMod "MayOverflow" means we tried to divide by zero, or we saw double.
    9911002                node->mergeFlags(NodeMayOverflowInt32InBaseline);
    992                 break;
    993                
    994             case ArithNegate:
    995                 // Currently we can't tell the difference between a negation overflowing
    996                 // (i.e. -(1 << 31)) or generating negative zero (i.e. -0). If it took slow
    997                 // path then we assume that it did both of those things.
    998                 node->mergeFlags(NodeMayOverflowInt32InBaseline);
    999                 node->mergeFlags(NodeMayNegZeroInBaseline);
    10001003                break;
    10011004               
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r206955 r207369  
    212212        return;
    213213
     214    case ArithNegate:
     215        if (node->child1().useKind() == Int32Use
     216            || node->child1().useKind() == DoubleRepUse
     217            || node->child1().useKind() == Int52RepUse)
     218            def(PureValue(node));
     219        else {
     220            read(World);
     221            write(Heap);
     222        }
     223        return;
     224
    214225    case IsCellWithType:
    215226        def(PureValue(node, node->queriedType()));
     
    335346
    336347    case ArithAdd:
    337     case ArithNegate:
    338348    case ArithMod:
    339349    case DoubleAsInt32:
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r207239 r207369  
    210210           
    211211        case ArithNegate: {
    212             if (m_graph.unaryArithShouldSpeculateInt32(node, FixupPass)) {
     212            if (node->child1()->shouldSpeculateInt32OrBoolean() && node->canSpeculateInt32(FixupPass)) {
    213213                fixIntOrBooleanEdge(node->child1());
    214214                if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
     
    218218                else
    219219                    node->setArithMode(Arith::CheckOverflowAndNegativeZero);
     220                node->setResult(NodeResultInt32);
     221                node->clearFlags(NodeMustGenerate);
    220222                break;
    221223            }
     
    227229                    node->setArithMode(Arith::CheckOverflowAndNegativeZero);
    228230                node->setResult(NodeResultInt52);
    229                 break;
    230             }
    231             fixDoubleOrBooleanEdge(node->child1());
    232             node->setResult(NodeResultDouble);
     231                node->clearFlags(NodeMustGenerate);
     232                break;
     233            }
     234            if (node->child1()->shouldSpeculateNotCell()) {
     235                fixDoubleOrBooleanEdge(node->child1());
     236                node->setResult(NodeResultDouble);
     237                node->clearFlags(NodeMustGenerate);
     238            } else
     239                fixEdge<UntypedUse>(node->child1());
    233240            break;
    234241        }
  • trunk/Source/JavaScriptCore/dfg/DFGIntegerRangeOptimizationPhase.cpp

    r198621 r207369  
    12531253                        break;
    12541254                    }
    1255                     if (maxValue <= 0) {
     1255                    bool absIsUnchecked = !shouldCheckOverflow(node->arithMode());
     1256                    if (maxValue < 0 || (absIsUnchecked && maxValue <= 0)) {
    12561257                        node->convertToArithNegate();
    1257                         if (minValue > std::numeric_limits<int>::min())
     1258                        if (absIsUnchecked || minValue > std::numeric_limits<int>::min())
    12581259                            node->setArithMode(Arith::Unchecked);
    12591260                        changed = true;
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r206853 r207369  
    246246        }
    247247
    248         case ArithNegate:
    249             if (node->child1()->prediction()) {
    250                 if (m_graph.unaryArithShouldSpeculateInt32(node, m_pass))
     248        case ArithNegate: {
     249            SpeculatedType prediction = node->child1()->prediction();
     250            if (prediction) {
     251                if (isInt32OrBooleanSpeculation(prediction) && node->canSpeculateInt32(m_pass))
    251252                    changed |= mergePrediction(SpecInt32Only);
    252253                else if (m_graph.unaryArithShouldSpeculateAnyInt(node, m_pass))
    253254                    changed |= mergePrediction(SpecInt52Only);
    254                 else
     255                else if (isBytecodeNumberSpeculation(prediction))
    255256                    changed |= mergePrediction(speculatedDoubleTypeForPrediction(node->child1()->prediction()));
    256             }
    257             break;
    258            
     257                else {
     258                    changed |= mergePrediction(SpecInt32Only);
     259                    if (node->mayHaveDoubleResult())
     260                        changed |= mergePrediction(SpecBytecodeDouble);
     261                }
     262            }
     263            break;
     264        }
    259265        case ArithMin:
    260266        case ArithMax: {
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r207239 r207369  
    42384238    }
    42394239       
    4240     default:
    4241         RELEASE_ASSERT_NOT_REACHED();
    4242         return;
    4243     }
    4244 }
     4240    default: {
     4241        ArithProfile* arithProfile = m_jit.graph().baselineCodeBlockFor(node->origin.semantic)->arithProfileForBytecodeOffset(node->origin.semantic.bytecodeIndex);
     4242        JITNegIC* negIC = m_jit.codeBlock()->addJITNegIC(arithProfile);
     4243        auto repatchingFunction = operationArithNegateOptimize;
     4244        auto nonRepatchingFunction = operationArithNegate;
     4245        bool needsScratchGPRReg = true;
     4246        compileMathIC(node, negIC, needsScratchGPRReg, repatchingFunction, nonRepatchingFunction);
     4247        return;
     4248    }
     4249    }
     4250}
     4251
     4252template <typename Generator, typename RepatchingFunction, typename NonRepatchingFunction>
     4253void SpeculativeJIT::compileMathIC(Node* node, JITUnaryMathIC<Generator>* mathIC, bool needsScratchGPRReg, RepatchingFunction repatchingFunction, NonRepatchingFunction nonRepatchingFunction)
     4254{
     4255    GPRReg scratchGPR = InvalidGPRReg;
     4256    Optional<GPRTemporary> gprScratch;
     4257    if (needsScratchGPRReg) {
     4258        gprScratch = GPRTemporary(this);
     4259        scratchGPR = gprScratch->gpr();
     4260    }
     4261    JSValueOperand childOperand(this, node->child1());
     4262    JSValueRegs childRegs = childOperand.jsValueRegs();
     4263#if USE(JSVALUE64)
     4264    GPRTemporary result(this, Reuse, childOperand);
     4265    JSValueRegs resultRegs(result.gpr());
     4266#else
     4267    GPRTemporary resultTag(this);
     4268    GPRTemporary resultPayload(this);
     4269    JSValueRegs resultRegs(resultPayload.gpr(), resultTag.gpr());
     4270#endif
     4271
     4272#if ENABLE(MATH_IC_STATS)
     4273    auto inlineStart = m_jit.label();
     4274#endif
     4275
     4276    Box<MathICGenerationState> icGenerationState = Box<MathICGenerationState>::create();
     4277    mathIC->m_generator = Generator(resultRegs, childRegs, scratchGPR);
     4278
     4279    bool shouldEmitProfiling = false;
     4280    bool generatedInline = mathIC->generateInline(m_jit, *icGenerationState, shouldEmitProfiling);
     4281
     4282    if (generatedInline) {
     4283        ASSERT(!icGenerationState->slowPathJumps.empty());
     4284
     4285        Vector<SilentRegisterSavePlan> savePlans;
     4286        silentSpillAllRegistersImpl(false, savePlans, resultRegs);
     4287
     4288        auto done = m_jit.label();
     4289
     4290        addSlowPathGenerator([=, savePlans = WTFMove(savePlans)] () {
     4291            icGenerationState->slowPathJumps.link(&m_jit);
     4292            icGenerationState->slowPathStart = m_jit.label();
     4293#if ENABLE(MATH_IC_STATS)
     4294            auto slowPathStart = m_jit.label();
     4295#endif
     4296
     4297            silentSpill(savePlans);
     4298
     4299            if (icGenerationState->shouldSlowPathRepatch)
     4300                icGenerationState->slowPathCall = callOperation(bitwise_cast<J_JITOperation_EJMic>(repatchingFunction), resultRegs, childRegs, TrustedImmPtr(mathIC));
     4301            else
     4302                icGenerationState->slowPathCall = callOperation(nonRepatchingFunction, resultRegs, childRegs);
     4303
     4304            silentFill(savePlans);
     4305            m_jit.exceptionCheck();
     4306            m_jit.jump().linkTo(done, &m_jit);
     4307
     4308            m_jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
     4309                mathIC->finalizeInlineCode(*icGenerationState, linkBuffer);
     4310            });
     4311
     4312#if ENABLE(MATH_IC_STATS)
     4313            auto slowPathEnd = m_jit.label();
     4314            m_jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
     4315                size_t size = static_cast<char*>(linkBuffer.locationOf(slowPathEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(slowPathStart).executableAddress());
     4316                mathIC->m_generatedCodeSize += size;
     4317            });
     4318#endif
     4319
     4320        });
     4321    } else {
     4322        flushRegisters();
     4323        callOperation(nonRepatchingFunction, resultRegs, childRegs);
     4324        m_jit.exceptionCheck();
     4325    }
     4326
     4327#if ENABLE(MATH_IC_STATS)
     4328    auto inlineEnd = m_jit.label();
     4329    m_jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
     4330        size_t size = static_cast<char*>(linkBuffer.locationOf(inlineEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(inlineStart).executableAddress());
     4331        mathIC->m_generatedCodeSize += size;
     4332    });
     4333#endif
     4334
     4335    jsValueResult(resultRegs, node);
     4336    return;
     4337}
     4338
     4339
    42454340void SpeculativeJIT::compileArithMul(Node* node)
    42464341{
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r207013 r207369  
    13131313        return appendCallSetResult(operation, result);
    13141314    }
     1315    JITCompiler::Call callOperation(J_JITOperation_EJMic operation, JSValueRegs result, JSValueRegs arg, TrustedImmPtr mathIC)
     1316    {
     1317        m_jit.setupArgumentsWithExecState(arg.gpr(), mathIC);
     1318        return appendCallSetResult(operation, result.gpr());
     1319    }
    13151320    JITCompiler::Call callOperation(J_JITOperation_EJJMic operation, JSValueRegs result, JSValueRegs arg1, JSValueRegs arg2, TrustedImmPtr mathIC)
    13161321    {
     
    18001805        return appendCallSetResult(operation, result);
    18011806    }
    1802 
     1807    JITCompiler::Call callOperation(J_JITOperation_EJMic operation, JSValueRegs result, JSValueRegs arg, TrustedImmPtr mathIC)
     1808    {
     1809        m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg.payloadGPR(), arg.tagGPR(), mathIC);
     1810        return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR());
     1811    }
    18031812    JITCompiler::Call callOperation(J_JITOperation_EJJMic operation, JSValueRegs result, JSValueRegs arg1, JSValueRegs arg2, TrustedImmPtr mathIC)
    18041813    {
     
    25962605    template <typename Generator, typename RepatchingFunction, typename NonRepatchingFunction>
    25972606    void compileMathIC(Node*, JITBinaryMathIC<Generator>*, bool needsScratchGPRReg, bool needsScratchFPRReg, RepatchingFunction, NonRepatchingFunction);
     2607    template <typename Generator, typename RepatchingFunction, typename NonRepatchingFunction>
     2608    void compileMathIC(Node*, JITUnaryMathIC<Generator>*, bool needsScratchGPRReg, RepatchingFunction, NonRepatchingFunction);
    25982609
    25992610    void compileArithDoubleUnaryOp(Node*, double (*doubleFunction)(double), double (*operation)(ExecState*, EncodedJSValue));
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r207239 r207369  
    15811581
    15821582    template <typename Generator>
     1583    void compileMathIC(JITUnaryMathIC<Generator>* mathIC, FunctionPtr repatchingFunction, FunctionPtr nonRepatchingFunction)
     1584    {
     1585        Node* node = m_node;
     1586
     1587        LValue operand = lowJSValue(node->child1());
     1588
     1589        PatchpointValue* patchpoint = m_out.patchpoint(Int64);
     1590        patchpoint->appendSomeRegister(operand);
     1591        patchpoint->append(m_tagMask, ValueRep::lateReg(GPRInfo::tagMaskRegister));
     1592        patchpoint->append(m_tagTypeNumber, ValueRep::lateReg(GPRInfo::tagTypeNumberRegister));
     1593        RefPtr<PatchpointExceptionHandle> exceptionHandle = preparePatchpointForExceptions(patchpoint);
     1594        patchpoint->numGPScratchRegisters = 1;
     1595        patchpoint->clobber(RegisterSet::macroScratchRegisters());
     1596        State* state = &m_ftlState;
     1597        patchpoint->setGenerator(
     1598            [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
     1599                AllowMacroScratchRegisterUsage allowScratch(jit);
     1600
     1601                Box<CCallHelpers::JumpList> exceptions =
     1602                    exceptionHandle->scheduleExitCreation(params)->jumps(jit);
     1603
     1604#if ENABLE(MATH_IC_STATS)
     1605                auto inlineStart = jit.label();
     1606#endif
     1607
     1608                Box<MathICGenerationState> mathICGenerationState = Box<MathICGenerationState>::create();
     1609                mathIC->m_generator = Generator(JSValueRegs(params[0].gpr()), JSValueRegs(params[1].gpr()), params.gpScratch(0));
     1610
     1611                bool shouldEmitProfiling = false;
     1612                bool generatedInline = mathIC->generateInline(jit, *mathICGenerationState, shouldEmitProfiling);
     1613
     1614                if (generatedInline) {
     1615                    ASSERT(!mathICGenerationState->slowPathJumps.empty());
     1616                    auto done = jit.label();
     1617                    params.addLatePath([=] (CCallHelpers& jit) {
     1618                        AllowMacroScratchRegisterUsage allowScratch(jit);
     1619                        mathICGenerationState->slowPathJumps.link(&jit);
     1620                        mathICGenerationState->slowPathStart = jit.label();
     1621#if ENABLE(MATH_IC_STATS)
     1622                        auto slowPathStart = jit.label();
     1623#endif
     1624
     1625                        if (mathICGenerationState->shouldSlowPathRepatch) {
     1626                            SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
     1627                                repatchingFunction, params[0].gpr(), params[1].gpr(), CCallHelpers::TrustedImmPtr(mathIC));
     1628                            mathICGenerationState->slowPathCall = call.call();
     1629                        } else {
     1630                            SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic,
     1631                                exceptions.get(), nonRepatchingFunction, params[0].gpr(), params[1].gpr());
     1632                            mathICGenerationState->slowPathCall = call.call();
     1633                        }
     1634                        jit.jump().linkTo(done, &jit);
     1635
     1636                        jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
     1637                            mathIC->finalizeInlineCode(*mathICGenerationState, linkBuffer);
     1638                        });
     1639
     1640#if ENABLE(MATH_IC_STATS)
     1641                        auto slowPathEnd = jit.label();
     1642                        jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
     1643                            size_t size = static_cast<char*>(linkBuffer.locationOf(slowPathEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(slowPathStart).executableAddress());
     1644                            mathIC->m_generatedCodeSize += size;
     1645                        });
     1646#endif
     1647                    });
     1648                } else {
     1649                    callOperation(
     1650                        *state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
     1651                        nonRepatchingFunction, params[0].gpr(), params[1].gpr());
     1652                }
     1653
     1654#if ENABLE(MATH_IC_STATS)
     1655                auto inlineEnd = jit.label();
     1656                jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
     1657                    size_t size = static_cast<char*>(linkBuffer.locationOf(inlineEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(inlineStart).executableAddress());
     1658                    mathIC->m_generatedCodeSize += size;
     1659                });
     1660#endif
     1661            });
     1662
     1663        setJSValue(patchpoint);
     1664    }
     1665
     1666    template <typename Generator>
    15831667    void compileMathIC(JITBinaryMathIC<Generator>* mathIC, FunctionPtr repatchingFunction, FunctionPtr nonRepatchingFunction)
    15841668    {
     
    24522536           
    24532537        default:
    2454             DFG_CRASH(m_graph, m_node, "Bad use kind");
     2538            DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
     2539            ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
     2540            JITNegIC* negIC = codeBlock()->addJITNegIC(arithProfile);
     2541            auto repatchingFunction = operationArithNegateOptimize;
     2542            auto nonRepatchingFunction = operationArithNegate;
     2543            compileMathIC(negIC, repatchingFunction, nonRepatchingFunction);
    24552544            break;
    24562545        }
  • trunk/Source/JavaScriptCore/jit/JITNegGenerator.cpp

    r206392 r207369  
    8383}
    8484
    85 bool JITNegGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile*, bool)
     85bool JITNegGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile* arithProfile, bool shouldEmitProfiling)
    8686{
    8787    ASSERT(m_scratchGPR != m_src.payloadGPR());
     
    116116    jit.xor32(CCallHelpers::TrustedImm32(1 << 31), m_result.tagGPR());
    117117#endif
     118    // The flags of ArithNegate are basic in DFG.
     119    // We only need to know if we ever produced a number.
     120    if (shouldEmitProfiling && arithProfile && !arithProfile->lhsObservedType().sawNumber() && !arithProfile->didObserveDouble())
     121        arithProfile->emitSetDouble(jit);
    118122    return true;
    119123}
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r206853 r207369  
    24712471    if (UNLIKELY(scope.exception()))
    24722472        return JSValue::encode(JSValue());
    2473     return JSValue::encode(jsNumber(-number));
     2473
     2474    JSValue result = jsNumber(-number);
     2475    arithProfile.observeResult(result);
     2476    return JSValue::encode(result);
    24742477}
    24752478
     
    25052508    if (UNLIKELY(scope.exception()))
    25062509        return JSValue::encode(JSValue());
    2507     return JSValue::encode(jsNumber(-number));
     2510    JSValue result = jsNumber(-number);
     2511    arithProfile->observeResult(result);
     2512    return JSValue::encode(result);
    25082513}
    25092514
Note: See TracChangeset for help on using the changeset viewer.