Ignore:
Timestamp:
Nov 19, 2019, 7:41:57 PM (6 years ago)
Author:
[email protected]
Message:

[ESNext][BigInt] Add support for op_inc
https://bugs.webkit.org/show_bug.cgi?id=193240

Reviewed by Yusuke Suzuki.

JSTests:

Some parts of these tests are inspired by tests in a WIP patch by Caio Lima.
Thanks to him for allowing their reuse.

  • stress/inc-osr-exit-from-big-int.js: Added.

(let.assert.sameValue):
(postInc):
(preInc):
(postDec):
(preDec):

  • stress/inc-osr-exit-to-big-int.js: Added.

(let.assert.sameValue):
(postInc):
(preInc):
(postDec):
(preDec):
(o.valueOf):

Source/JavaScriptCore:

This patch adds support for both ++ and -- on BigInts.

It required the following secondary changes:

  • teaching FixupPhase how to replace it by ArithAdd/ArithSub/ValueAdd/ValueSub when the type is Int32/Double/BigInt
  • pulling ObservedResults out of UnaryArithProfile/BinaryArithProfile, so that it can be used by ArithAdd regardless of whether it comes from an Inc or from an Add
  • adding the constant 1n to the VM object so that it can be used by FixupPhase since it cannot allocate a new JSValue.
  • adding an UnaryArithProfile to op_inc and op_dec, and teaching the llint to update them.
  • adding ToNumeric (identity on bigints, same as toNumber on everything else) to all tiers
  • bytecode/ArithProfile.cpp:

(JSC::ArithProfile<BitfieldType>::shouldEmitSetDouble const):
(JSC::ArithProfile<BitfieldType>::emitSetDouble const):
(JSC::ArithProfile<BitfieldType>::shouldEmitSetNonNumeric const):
(JSC::ArithProfile<BitfieldType>::shouldEmitSetBigInt const):
(JSC::ArithProfile<BitfieldType>::emitSetNonNumeric const):
(JSC::ArithProfile<BitfieldType>::emitSetBigInt const):

  • bytecode/ArithProfile.h:

(JSC::ObservedResults::ObservedResults):
(JSC::ObservedResults::didObserveNonInt32):
(JSC::ObservedResults::didObserveDouble):
(JSC::ObservedResults::didObserveNonNegZeroDouble):
(JSC::ObservedResults::didObserveNegZeroDouble):
(JSC::ObservedResults::didObserveNonNumeric):
(JSC::ObservedResults::didObserveBigInt):
(JSC::ObservedResults::didObserveInt32Overflow):
(JSC::ObservedResults::didObserveInt52Overflow):
(JSC::ArithProfile::observedResults const):
(JSC::ArithProfile::didObserveNonInt32 const):
(JSC::ArithProfile::didObserveDouble const):
(JSC::ArithProfile::didObserveNonNegZeroDouble const):
(JSC::ArithProfile::didObserveNegZeroDouble const):
(JSC::ArithProfile::didObserveNonNumeric const):
(JSC::ArithProfile::didObserveBigInt const):
(JSC::ArithProfile::didObserveInt32Overflow const):
(JSC::ArithProfile::didObserveInt52Overflow const):
(JSC::ArithProfile::setObservedNonNegZeroDouble):
(JSC::ArithProfile::setObservedNegZeroDouble):
(JSC::ArithProfile::setObservedNonNumeric):
(JSC::ArithProfile::setObservedBigInt):
(JSC::ArithProfile::setObservedInt32Overflow):
(JSC::ArithProfile::setObservedInt52Overflow):
(JSC::ArithProfile::observeResult):

  • bytecode/BytecodeList.rb:
  • bytecode/BytecodeUseDef.h:

(JSC::computeUsesForBytecodeIndex):
(JSC::computeDefsForBytecodeIndex):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::unaryArithProfileForPC):

  • bytecode/ExitKind.h:
  • bytecode/SpeculatedType.h:

(JSC::isInt32SpeculationForArithmetic):
(JSC::isInt32OrBooleanSpeculationForArithmetic):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitUnaryOp):
(JSC::BytecodeGenerator::emitToNumeric):

  • bytecompiler/BytecodeGenerator.h:
  • bytecompiler/NodesCodegen.cpp:

(JSC::emitPostIncOrDec):

  • dfg/DFGAbstractInterpreterInlines.h:

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

  • dfg/DFGBackwardsPropagationPhase.cpp:

(JSC::DFG::BackwardsPropagationPhase::propagate):

  • dfg/DFGByteCodeParser.cpp:

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

  • dfg/DFGCapabilities.cpp:

(JSC::DFG::capabilityLevel):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGConstantFoldingPhase.cpp:

(JSC::DFG::ConstantFoldingPhase::foldConstants):

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • dfg/DFGFixupPhase.cpp:

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

  • dfg/DFGMayExit.cpp:
  • dfg/DFGNode.h:

(JSC::DFG::Node::hasHeapPrediction):

  • dfg/DFGNodeType.h:
  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • dfg/DFGPredictionPropagationPhase.cpp:
  • dfg/DFGSafeToExecute.h:

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileIncOrDec):
(JSC::DFG::SpeculativeJIT::compileToPrimitive):
(JSC::DFG::SpeculativeJIT::compileToNumeric):

  • dfg/DFGSpeculativeJIT.h:
  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileIncOrDec):

  • jit/JIT.cpp:

(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):

  • jit/JIT.h:
  • jit/JITMathIC.h:

(JSC::JITMathIC::generateInline):

  • jit/JITMulGenerator.cpp:

(JSC::JITMulGenerator::generateFastPath):

  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_to_numeric):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_to_numeric):

  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • runtime/CommonSlowPaths.cpp:

(JSC::SLOW_PATH_DECL):

  • runtime/CommonSlowPaths.h:
  • runtime/JSBigInt.cpp:

(JSC::JSBigInt::inc):
(JSC::JSBigInt::dec):

  • runtime/JSBigInt.h:
  • runtime/VM.cpp:

(JSC::VM::VM):

  • runtime/VM.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r252422 r252680  
    947947        case ArithSub:
    948948        case ValueAdd: {
    949             BinaryArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->binaryArithProfileForBytecodeIndex(m_currentIndex);
    950             if (!arithProfile)
     949            ObservedResults observed;
     950            if (BinaryArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->binaryArithProfileForBytecodeIndex(m_currentIndex))
     951                observed = arithProfile->observedResults();
     952            else if (UnaryArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->unaryArithProfileForBytecodeIndex(m_currentIndex)) {
     953                // Happens for OpInc/OpDec
     954                observed = arithProfile->observedResults();
     955            } else
    951956                break;
    952             if (arithProfile->didObserveDouble())
     957
     958            if (observed.didObserveDouble())
    953959                node->mergeFlags(NodeMayHaveDoubleResult);
    954             if (arithProfile->didObserveNonNumeric())
     960            if (observed.didObserveNonNumeric())
    955961                node->mergeFlags(NodeMayHaveNonNumericResult);
    956             if (arithProfile->didObserveBigInt())
     962            if (observed.didObserveBigInt())
    957963                node->mergeFlags(NodeMayHaveBigIntResult);
    958964            break;
     
    978984        }
    979985        case ValueNegate:
    980         case ArithNegate: {
     986        case ArithNegate:
     987        case Inc:
     988        case Dec: {
    981989            UnaryArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->unaryArithProfileForBytecodeIndex(m_currentIndex);
    982990            if (!arithProfile)
     
    52165224            auto bytecode = currentInstruction->as<OpInc>();
    52175225            Node* op = get(bytecode.m_srcDst);
    5218             set(bytecode.m_srcDst, makeSafe(addToGraph(ArithAdd, op, addToGraph(JSConstant, OpInfo(m_constantOne)))));
     5226            // FIXME: we can replace the Inc by either ArithAdd with m_constantOne or ArithAdd with the equivalent BigInt in many cases.
     5227            // For now we only do so in DFGFixupPhase.
     5228            // We could probably do it earlier in some cases, but it is not clearly worth the trouble.
     5229            set(bytecode.m_srcDst, makeSafe(addToGraph(Inc, op)));
    52195230            NEXT_OPCODE(op_inc);
    52205231        }
     
    52235234            auto bytecode = currentInstruction->as<OpDec>();
    52245235            Node* op = get(bytecode.m_srcDst);
    5225             set(bytecode.m_srcDst, makeSafe(addToGraph(ArithSub, op, addToGraph(JSConstant, OpInfo(m_constantOne)))));
     5236            // FIXME: we can replace the Inc by either ArithSub with m_constantOne or ArithSub with the equivalent BigInt in many cases.
     5237            // For now we only do so in DFGFixupPhase.
     5238            // We could probably do it earlier in some cases, but it is not clearly worth the trouble.
     5239            set(bytecode.m_srcDst, makeSafe(addToGraph(Dec, op)));
    52265240            NEXT_OPCODE(op_dec);
    52275241        }
     
    69726986        }
    69736987
     6988        case op_to_numeric: {
     6989            auto bytecode = currentInstruction->as<OpToNumeric>();
     6990            SpeculatedType prediction = getPrediction();
     6991            Node* value = get(bytecode.m_operand);
     6992            set(bytecode.m_dst, addToGraph(ToNumeric, OpInfo(0), OpInfo(prediction), value));
     6993            NEXT_OPCODE(op_to_numeric);
     6994        }
     6995
    69746996        case op_to_string: {
    69756997            auto bytecode = currentInstruction->as<OpToString>();
Note: See TracChangeset for help on using the changeset viewer.