Changeset 230516 in webkit


Ignore:
Timestamp:
Apr 10, 2018 10:49:31 PM (6 years ago)
Author:
Caio Lima
Message:

[ESNext][BigInt] Add support for BigInt in SpeculatedType
https://bugs.webkit.org/show_bug.cgi?id=182470

Reviewed by Saam Barati.

JSTests:

  • stress/big-int-spec-to-primitive.js: Added.
  • stress/big-int-spec-to-this.js: Added.
  • stress/big-int-strict-equals-jit.js: Added.
  • stress/big-int-strict-spec-to-this.js: Added.
  • stress/big-int-type-of-proven-type.js: Added.

Source/JavaScriptCore:

This patch introduces the SpecBigInt type to DFG to enable BigInt
speculation into DFG and FTL.

With SpecBigInt introduction, we can then specialize "===" operations
to BigInts. As we are doing for some cells, we first check if operands
are pointing to the same JSCell, and if it is false, we
fallback to "operationCompareStrictEqCell". The idea in further
patches is to implement BigInt equality check directly in
assembly.

We are also adding support for BigInt constant folding into
TypeOf operation.

  • bytecode/SpeculatedType.cpp:

(JSC::dumpSpeculation):
(JSC::speculationFromClassInfo):
(JSC::speculationFromStructure):
(JSC::speculationFromJSType):
(JSC::speculationFromString):

  • bytecode/SpeculatedType.h:

(JSC::isBigIntSpeculation):

  • dfg/DFGAbstractInterpreterInlines.h:

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

  • dfg/DFGAbstractValue.cpp:

(JSC::DFG::AbstractValue::set):

  • dfg/DFGConstantFoldingPhase.cpp:

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

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::fixupToThis):
(JSC::DFG::FixupPhase::observeUseKindOnNode):

  • dfg/DFGInferredTypeCheck.cpp:

(JSC::DFG::insertInferredTypeCheck):

  • dfg/DFGNode.h:

(JSC::DFG::Node::shouldSpeculateBigInt):

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

(JSC::DFG::SafeToExecuteEdge::operator()):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileStrictEq):
(JSC::DFG::SpeculativeJIT::speculateBigInt):
(JSC::DFG::SpeculativeJIT::speculate):

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

(JSC::DFG::SpeculativeJIT::compileBigIntEquality):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compileBigIntEquality):

  • dfg/DFGUseKind.cpp:

(WTF::printInternal):

  • dfg/DFGUseKind.h:

(JSC::DFG::typeFilterFor):
(JSC::DFG::isCell):

  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
(JSC::FTL::DFG::LowerDFGToB3::checkInferredType):
(JSC::FTL::DFG::LowerDFGToB3::speculate):
(JSC::FTL::DFG::LowerDFGToB3::isNotBigInt):
(JSC::FTL::DFG::LowerDFGToB3::speculateBigInt):

  • jit/AssemblyHelpers.cpp:

(JSC::AssemblyHelpers::branchIfNotType):

  • jit/AssemblyHelpers.h:

(JSC::AssemblyHelpers::branchIfBigInt):
(JSC::AssemblyHelpers::branchIfNotBigInt):

  • runtime/InferredType.cpp:

(JSC::InferredType::Descriptor::forValue):
(JSC::InferredType::Descriptor::putByIdFlags const):
(JSC::InferredType::Descriptor::merge):
(WTF::printInternal):

  • runtime/InferredType.h:
  • runtime/JSBigInt.h:
Location:
trunk
Files:
5 added
27 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r230488 r230516  
     12018-04-10  Caio Lima  <ticaiolima@gmail.com>
     2
     3        [ESNext][BigInt] Add support for BigInt in SpeculatedType
     4        https://bugs.webkit.org/show_bug.cgi?id=182470
     5
     6        Reviewed by Saam Barati.
     7
     8        * stress/big-int-spec-to-primitive.js: Added.
     9        * stress/big-int-spec-to-this.js: Added.
     10        * stress/big-int-strict-equals-jit.js: Added.
     11        * stress/big-int-strict-spec-to-this.js: Added.
     12        * stress/big-int-type-of-proven-type.js: Added.
     13
    1142018-04-10  Filip Pizlo  <fpizlo@apple.com>
    215
  • trunk/Source/JavaScriptCore/ChangeLog

    r230494 r230516  
     12018-04-10  Caio Lima  <ticaiolima@gmail.com>
     2
     3        [ESNext][BigInt] Add support for BigInt in SpeculatedType
     4        https://bugs.webkit.org/show_bug.cgi?id=182470
     5
     6        Reviewed by Saam Barati.
     7
     8        This patch introduces the SpecBigInt type to DFG to enable BigInt
     9        speculation into DFG and FTL.
     10
     11        With SpecBigInt introduction, we can then specialize "===" operations
     12        to BigInts. As we are doing for some cells, we first check if operands
     13        are pointing to the same JSCell, and if it is false, we
     14        fallback to "operationCompareStrictEqCell". The idea in further
     15        patches is to implement BigInt equality check directly in
     16        assembly.
     17
     18        We are also adding support for BigInt constant folding into
     19        TypeOf operation.
     20
     21        * bytecode/SpeculatedType.cpp:
     22        (JSC::dumpSpeculation):
     23        (JSC::speculationFromClassInfo):
     24        (JSC::speculationFromStructure):
     25        (JSC::speculationFromJSType):
     26        (JSC::speculationFromString):
     27        * bytecode/SpeculatedType.h:
     28        (JSC::isBigIntSpeculation):
     29        * dfg/DFGAbstractInterpreterInlines.h:
     30        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     31        * dfg/DFGAbstractValue.cpp:
     32        (JSC::DFG::AbstractValue::set):
     33        * dfg/DFGConstantFoldingPhase.cpp:
     34        (JSC::DFG::ConstantFoldingPhase::foldConstants):
     35        * dfg/DFGFixupPhase.cpp:
     36        (JSC::DFG::FixupPhase::fixupNode):
     37        (JSC::DFG::FixupPhase::fixupToThis):
     38        (JSC::DFG::FixupPhase::observeUseKindOnNode):
     39        * dfg/DFGInferredTypeCheck.cpp:
     40        (JSC::DFG::insertInferredTypeCheck):
     41        * dfg/DFGNode.h:
     42        (JSC::DFG::Node::shouldSpeculateBigInt):
     43        * dfg/DFGPredictionPropagationPhase.cpp:
     44        * dfg/DFGSafeToExecute.h:
     45        (JSC::DFG::SafeToExecuteEdge::operator()):
     46        * dfg/DFGSpeculativeJIT.cpp:
     47        (JSC::DFG::SpeculativeJIT::compileStrictEq):
     48        (JSC::DFG::SpeculativeJIT::speculateBigInt):
     49        (JSC::DFG::SpeculativeJIT::speculate):
     50        * dfg/DFGSpeculativeJIT.h:
     51        * dfg/DFGSpeculativeJIT32_64.cpp:
     52        (JSC::DFG::SpeculativeJIT::compileBigIntEquality):
     53        * dfg/DFGSpeculativeJIT64.cpp:
     54        (JSC::DFG::SpeculativeJIT::compileBigIntEquality):
     55        * dfg/DFGUseKind.cpp:
     56        (WTF::printInternal):
     57        * dfg/DFGUseKind.h:
     58        (JSC::DFG::typeFilterFor):
     59        (JSC::DFG::isCell):
     60        * ftl/FTLCapabilities.cpp:
     61        (JSC::FTL::canCompile):
     62        * ftl/FTLLowerDFGToB3.cpp:
     63        (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
     64        (JSC::FTL::DFG::LowerDFGToB3::checkInferredType):
     65        (JSC::FTL::DFG::LowerDFGToB3::speculate):
     66        (JSC::FTL::DFG::LowerDFGToB3::isNotBigInt):
     67        (JSC::FTL::DFG::LowerDFGToB3::speculateBigInt):
     68        * jit/AssemblyHelpers.cpp:
     69        (JSC::AssemblyHelpers::branchIfNotType):
     70        * jit/AssemblyHelpers.h:
     71        (JSC::AssemblyHelpers::branchIfBigInt):
     72        (JSC::AssemblyHelpers::branchIfNotBigInt):
     73        * runtime/InferredType.cpp:
     74        (JSC::InferredType::Descriptor::forValue):
     75        (JSC::InferredType::Descriptor::putByIdFlags const):
     76        (JSC::InferredType::Descriptor::merge):
     77        (WTF::printInternal):
     78        * runtime/InferredType.h:
     79        * runtime/JSBigInt.h:
     80
    1812018-04-10  Filip Pizlo  <fpizlo@apple.com>
    282
  • trunk/Source/JavaScriptCore/bytecode/SpeculatedType.cpp

    r221959 r230516  
    3232#include "DirectArguments.h"
    3333#include "JSArray.h"
     34#include "JSBigInt.h"
    3435#include "JSCInlines.h"
    3536#include "JSFunction.h"
     
    220221        if (value & SpecSymbol)
    221222            strOut.print("Symbol");
     223        else
     224            isTop = false;
     225
     226        if (value & SpecBigInt)
     227            strOut.print("BigInt");
    222228        else
    223229            isTop = false;
     
    390396    if (classInfo == Symbol::info())
    391397        return SpecSymbol;
     398   
     399    if (classInfo == JSBigInt::info())
     400        return SpecBigInt;
    392401
    393402    if (classInfo == JSFinalObject::info())
     
    445454    if (structure->typeInfo().type() == SymbolType)
    446455        return SpecSymbol;
     456    if (structure->typeInfo().type() == BigIntType)
     457        return SpecBigInt;
    447458    if (structure->typeInfo().type() == DerivedArrayType)
    448459        return SpecDerivedArray;
     
    527538    case SymbolType:
    528539        return SpecSymbol;
     540    case BigIntType:
     541        return SpecBigInt;
    529542    case ArrayType:
    530543        return SpecArray;
     
    744757    if (!strncmp(speculation, "SpecSymbol", strlen("SpecSymbol")))
    745758        return SpecSymbol;
     759    if (!strncmp(speculation, "SpecBigInt", strlen("SpecBigInt")))
     760        return SpecBigInt;
    746761    if (!strncmp(speculation, "SpecCellOther", strlen("SpecCellOther")))
    747762        return SpecCellOther;
  • trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h

    r221959 r230516  
    6969static const SpeculatedType SpecString             = SpecStringIdent | SpecStringVar; // It's definitely a JSString.
    7070static const SpeculatedType SpecSymbol             = 1ull << 25; // It's definitely a Symbol.
    71 static const SpeculatedType SpecCellOther          = 1ull << 26; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString or a Symbol.
    72 static const SpeculatedType SpecCell               = SpecObject | SpecString | SpecSymbol | SpecCellOther; // It's definitely a JSCell.
     71static const SpeculatedType SpecCellOther          = 1ull << 26; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString, BigInt, or Symbol.
    7372static const SpeculatedType SpecBoolInt32          = 1ull << 27; // It's definitely an Int32 with value 0 or 1.
    7473static const SpeculatedType SpecNonBoolInt32       = 1ull << 28; // It's definitely an Int32 with value other than 0 or 1.
     
    9190static const SpeculatedType SpecOther              = 1ull << 35; // It's definitely either Null or Undefined.
    9291static const SpeculatedType SpecMisc               = SpecBoolean | SpecOther; // It's definitely either a boolean, Null, or Undefined.
     92static const SpeculatedType SpecEmpty              = 1ull << 36; // It's definitely an empty value marker.
     93static const SpeculatedType SpecBigInt             = 1ull << 37; // It's definitely a BigInt.
     94static const SpeculatedType SpecPrimitive          = SpecString | SpecSymbol | SpecBytecodeNumber | SpecMisc | SpecBigInt; // It's any non-Object JSValue.
     95static const SpeculatedType SpecCell               = SpecObject | SpecString | SpecSymbol | SpecCellOther | SpecBigInt; // It's definitely a JSCell.
    9396static const SpeculatedType SpecHeapTop            = SpecCell | SpecBytecodeNumber | SpecMisc; // It can be any of the above, except for SpecInt52Only and SpecDoubleImpureNaN.
    94 static const SpeculatedType SpecPrimitive          = SpecString | SpecSymbol | SpecBytecodeNumber | SpecMisc; // It's any non-Object JSValue.
    95 static const SpeculatedType SpecEmpty              = 1ull << 36; // It's definitely an empty value marker.
    9697static const SpeculatedType SpecBytecodeTop        = SpecHeapTop | SpecEmpty; // It can be any of the above, except for SpecInt52Only and SpecDoubleImpureNaN. Corresponds to what could be found in a bytecode local.
    9798static const SpeculatedType SpecFullTop            = SpecBytecodeTop | SpecFullNumber; // It can be anything that bytecode could see plus exotic encodings of numbers.
     
    173174{
    174175    return value == SpecSymbol;
     176}
     177
     178inline bool isBigIntSpeculation(SpeculatedType value)
     179{
     180    return value == SpecBigInt;
    175181}
    176182
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r230488 r230516  
    14841484        if (isSymbolSpeculation(abstractChild.m_type)) {
    14851485            setConstant(node, *m_graph.freeze(m_vm.smallStrings.symbolString()));
     1486            break;
     1487        }
     1488
     1489        if (isBigIntSpeculation(abstractChild.m_type)) {
     1490            setConstant(node, *m_graph.freeze(m_vm.smallStrings.bigintString()));
    14861491            break;
    14871492        }
     
    21152120        ASSERT(node->child1().useKind() == UntypedUse);
    21162121       
    2117         if (!(forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean | SpecString | SpecSymbol))) {
     2122        if (!(forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean | SpecString | SpecSymbol | SpecBigInt))) {
    21182123            m_state.setFoundConstants(true);
    21192124            didFoldClobberWorld();
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp

    r211237 r230516  
    151151        set(graph, graph.m_vm.symbolStructure.get());
    152152        return;
     153    case InferredType::BigInt:
     154        set(graph, graph.m_vm.bigIntStructure.get());
     155        return;
    153156    case InferredType::ObjectWithStructure:
    154157        set(graph, descriptor.structure());
  • trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp

    r230488 r230516  
    616616
    617617            case ToPrimitive: {
    618                 if (m_state.forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean | SpecString | SpecSymbol))
     618                if (m_state.forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean | SpecString | SpecSymbol | SpecBigInt))
    619619                    break;
    620620               
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r230488 r230516  
    615615                fixEdge<SymbolUse>(node->child1());
    616616                fixEdge<SymbolUse>(node->child2());
     617                break;
     618            }
     619            if (Node::shouldSpeculateBigInt(node->child1().node(), node->child2().node())) {
     620                fixEdge<BigIntUse>(node->child1());
     621                fixEdge<BigIntUse>(node->child2());
    617622                break;
    618623            }
     
    24982503                return;
    24992504            }
     2505           
     2506            if (node->child1()->shouldSpeculateBigInt()) {
     2507                fixEdge<BigIntUse>(node->child1());
     2508                node->convertToIdentity();
     2509                return;
     2510            }
    25002511        }
    25012512
     
    29943005        case KnownStringUse:
    29953006        case SymbolUse:
     3007        case BigIntUse:
    29963008        case StringObjectUse:
    29973009        case StringOrStringObjectUse:
  • trunk/Source/JavaScriptCore/dfg/DFGInferredTypeCheck.cpp

    r190916 r230516  
    6868        return;
    6969
     70    case InferredType::BigInt:
     71        insertionSet.insertNode(nodeIndex, SpecNone, Check, origin, Edge(baseNode, BigIntUse));
     72        return;
     73
    7074    case InferredType::ObjectWithStructure:
    7175        insertionSet.insertNode(
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r230376 r230516  
    23452345    }
    23462346   
     2347    bool shouldSpeculateBigInt()
     2348    {
     2349        return isBigIntSpeculation(prediction());
     2350    }
     2351   
    23472352    bool shouldSpeculateFinalObject()
    23482353    {
     
    25332538    {
    25342539        return op1->shouldSpeculateSymbol() && op2->shouldSpeculateSymbol();
     2540    }
     2541   
     2542    static bool shouldSpeculateBigInt(Node* op1, Node* op2)
     2543    {
     2544        return op1->shouldSpeculateBigInt() && op2->shouldSpeculateBigInt();
    25352545    }
    25362546   
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r230376 r230516  
    12301230}
    12311231
    1232 size_t JIT_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
    1233 {
    1234     VM* vm = &exec->vm();
    1235     NativeCallFrameTracer tracer(vm, exec);
    1236    
    1237     JSValue op1 = JSValue::decode(encodedOp1);
    1238     JSValue op2 = JSValue::decode(encodedOp2);
    1239    
    1240     ASSERT(op1.isCell());
    1241     ASSERT(op2.isCell());
     1232size_t JIT_OPERATION operationCompareStrictEqCell(ExecState* exec, JSCell* op1, JSCell* op2)
     1233{
     1234    VM* vm = &exec->vm();
     1235    NativeCallFrameTracer tracer(vm, exec);
    12421236   
    12431237    return JSValue::strictEqualSlowCaseInline(exec, op1, op2);
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r230376 r230516  
    161161size_t JIT_OPERATION operationRegExpTest(ExecState*, JSGlobalObject*, RegExpObject*, EncodedJSValue) WTF_INTERNAL;
    162162size_t JIT_OPERATION operationRegExpTestGeneric(ExecState*, JSGlobalObject*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
    163 size_t JIT_OPERATION operationCompareStrictEqCell(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
     163size_t JIT_OPERATION operationCompareStrictEqCell(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL;
    164164JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState*, Structure*, JSScope*, SymbolTable*, EncodedJSValue);
    165165JSCell* JIT_OPERATION operationCreateDirectArguments(ExecState*, Structure*, uint32_t length, uint32_t minCapacity);
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r230376 r230516  
    423423                if (node->child1()->shouldSpeculateSymbol()) {
    424424                    changed |= mergePrediction(SpecSymbol);
     425                    break;
     426                }
     427               
     428                if (node->child1()->shouldSpeculateBigInt()) {
     429                    changed |= mergePrediction(SpecBigInt);
    425430                    break;
    426431                }
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r230376 r230516  
    7171        case StringOrOtherUse:
    7272        case SymbolUse:
     73        case BigIntUse:
    7374        case StringObjectUse:
    7475        case StringOrStringObjectUse:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r230376 r230516  
    59515951    }
    59525952   
     5953    if (node->isBinaryUseKind(BigIntUse)) {
     5954        compileBigIntEquality(node);
     5955        return false;
     5956    }
     5957   
    59535958    if (node->isBinaryUseKind(SymbolUse, UntypedUse)) {
    59545959        compileSymbolUntypedEquality(node, node->child1(), node->child2());
     
    98979902}
    98989903
     9904void SpeculativeJIT::speculateBigInt(Edge edge, GPRReg cell)
     9905{
     9906    DFG_TYPE_CHECK(JSValueSource::unboxedCell(cell), edge, ~SpecCellCheck | SpecBigInt, m_jit.branchIfNotBigInt(cell));
     9907}
     9908
     9909void SpeculativeJIT::speculateBigInt(Edge edge)
     9910{
     9911    if (!needsTypeCheck(edge, SpecBigInt))
     9912        return;
     9913
     9914    SpeculateCellOperand operand(this, edge);
     9915    speculateBigInt(edge, operand.gpr());
     9916}
     9917
    98999918void SpeculativeJIT::speculateNotCell(Edge edge, JSValueRegs regs)
    99009919{
     
    1006210081    case SymbolUse:
    1006310082        speculateSymbol(edge);
     10083        break;
     10084    case BigIntUse:
     10085        speculateBigInt(edge);
    1006410086        break;
    1006510087    case StringObjectUse:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r230376 r230516  
    12621262
    12631263    void compileSymbolEquality(Node*);
     1264    void compileBigIntEquality(Node*);
    12641265    void compilePeepHoleSymbolEquality(Node*, Node* branchNode);
    12651266    void compileSymbolUntypedEquality(Node*, Edge symbolEdge, Edge untypedEdge);
     
    16621663    void speculateSymbol(Edge, GPRReg cell);
    16631664    void speculateSymbol(Edge);
     1665    void speculateBigInt(Edge, GPRReg cell);
     1666    void speculateBigInt(Edge);
    16641667    void speculateNotCell(Edge, JSValueRegs);
    16651668    void speculateNotCell(Edge);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r230379 r230516  
    602602       
    603603        silentSpillAllRegisters(resultPayloadGPR);
    604         callOperation(operationCompareStrictEqCell, resultPayloadGPR, arg1Regs, arg2Regs);
     604        callOperation(operationCompareStrictEqCell, resultPayloadGPR, arg1PayloadGPR, arg2PayloadGPR);
    605605        m_jit.exceptionCheck();
    606606        silentFillAllRegisters();
     
    648648       
    649649        silentSpillAllRegisters(resultPayloadGPR);
    650         callOperation(operationCompareStrictEqCell, resultPayloadGPR, arg1Regs, arg2Regs);
     650        callOperation(operationCompareStrictEqCell, resultPayloadGPR, arg1PayloadGPR, arg2PayloadGPR);
    651651        m_jit.exceptionCheck();
    652652        silentFillAllRegisters();
     
    47594759}
    47604760
     4761void SpeculativeJIT::compileBigIntEquality(Node* node)
     4762{
     4763    // FIXME: [ESNext][BigInt] Create specialized version of strict equals for BigIntUse
     4764    // https://bugs.webkit.org/show_bug.cgi?id=182895
     4765    SpeculateCellOperand left(this, node->child1());
     4766    SpeculateCellOperand right(this, node->child2());
     4767    GPRReg leftPayloadGPR = left.gpr();
     4768    GPRReg rightPayloadGPR = right.gpr();
     4769
     4770    GPRTemporary resultPayload(this, Reuse, left);
     4771    GPRReg resultPayloadGPR = resultPayload.gpr();
     4772
     4773    left.use();
     4774    right.use();
     4775
     4776    speculateBigInt(node->child1(), leftPayloadGPR);
     4777    speculateBigInt(node->child2(), rightPayloadGPR);
     4778
     4779    JITCompiler::Jump notEqualCase = m_jit.branchPtr(JITCompiler::NotEqual, leftPayloadGPR, rightPayloadGPR);
     4780
     4781    m_jit.move(JITCompiler::TrustedImm32(true), resultPayloadGPR);
     4782    JITCompiler::Jump done = m_jit.jump();
     4783
     4784    notEqualCase.link(&m_jit);
     4785
     4786    silentSpillAllRegisters(resultPayloadGPR);
     4787    callOperation(operationCompareStrictEqCell, resultPayloadGPR, leftPayloadGPR, rightPayloadGPR);
     4788    silentFillAllRegisters();
     4789
     4790    m_jit.andPtr(JITCompiler::TrustedImm32(1), resultPayloadGPR);
     4791
     4792    done.link(&m_jit);
     4793
     4794    booleanResult(resultPayloadGPR, node, UseChildrenCalledExplicitly);
     4795}
     4796
    47614797void SpeculativeJIT::emitInitializeButterfly(GPRReg storageGPR, GPRReg sizeGPR, JSValueRegs emptyValueRegs, GPRReg scratchGPR)
    47624798{
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r230465 r230516  
    53795379}
    53805380
     5381void SpeculativeJIT::compileBigIntEquality(Node* node)
     5382{
     5383    // FIXME: [ESNext][BigInt] Create specialized version of strict equals for BigIntUse
     5384    // https://bugs.webkit.org/show_bug.cgi?id=182895
     5385    SpeculateCellOperand left(this, node->child1());
     5386    SpeculateCellOperand right(this, node->child2());
     5387    GPRTemporary result(this);
     5388    GPRReg leftGPR = left.gpr();
     5389    GPRReg rightGPR = right.gpr();
     5390    GPRReg resultGPR = result.gpr();
     5391
     5392    left.use();
     5393    right.use();
     5394
     5395    speculateBigInt(node->child1(), leftGPR);
     5396    speculateBigInt(node->child2(), rightGPR);
     5397
     5398    JITCompiler::Jump notEqualCase = m_jit.branch64(JITCompiler::NotEqual, leftGPR, rightGPR);
     5399
     5400    m_jit.move(JITCompiler::TrustedImm64(JSValue::encode(jsBoolean(true))), resultGPR);
     5401
     5402    JITCompiler::Jump done = m_jit.jump();
     5403
     5404    notEqualCase.link(&m_jit);
     5405
     5406    silentSpillAllRegisters(resultGPR);
     5407    callOperation(operationCompareStrictEqCell, resultGPR, leftGPR, rightGPR);
     5408    silentFillAllRegisters();
     5409
     5410    m_jit.and64(JITCompiler::TrustedImm32(1), resultGPR);
     5411    m_jit.or32(JITCompiler::TrustedImm32(ValueFalse), resultGPR);
     5412
     5413    done.link(&m_jit);
     5414
     5415    jsValueResult(resultGPR, m_currentNode, DataFormatJSBoolean, UseChildrenCalledExplicitly);
     5416}
     5417
    53815418void SpeculativeJIT::compileAllocateNewArrayWithSize(JSGlobalObject* globalObject, GPRReg resultGPR, GPRReg sizeGPR, IndexingType indexingType, bool shouldConvertLargeSizeToArrayStorage)
    53825419{
  • trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp

    r224735 r230516  
    137137        out.print("Symbol");
    138138        return;
     139    case BigIntUse:
     140        out.print("BigInt");
     141        return;
    139142    case StringObjectUse:
    140143        out.print("StringObject");
  • trunk/Source/JavaScriptCore/dfg/DFGUseKind.h

    r224735 r230516  
    6666    KnownPrimitiveUse, // This bizarre type arises for op_strcat, which has a bytecode guarantee that it will only see primitives (i.e. not objects).
    6767    SymbolUse,
     68    BigIntUse,
    6869    MapObjectUse,
    6970    SetObjectUse,
     
    149150    case SymbolUse:
    150151        return SpecSymbol;
     152    case BigIntUse:
     153        return SpecBigInt;
    151154    case MapObjectUse:
    152155        return SpecMapObject;
     
    247250    case KnownStringUse:
    248251    case SymbolUse:
     252    case BigIntUse:
    249253    case StringObjectUse:
    250254    case StringOrStringObjectUse:
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r230376 r230516  
    430430                case StringOrStringObjectUse:
    431431                case SymbolUse:
     432                case BigIntUse:
    432433                case MapObjectUse:
    433434                case SetObjectUse:
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r230465 r230516  
    68646864        }
    68656865       
     6866        if (m_node->isBinaryUseKind(BigIntUse)) {
     6867            // FIXME: [ESNext][BigInt] Create specialized version of strict equals for BigIntUse
     6868            // https://bugs.webkit.org/show_bug.cgi?id=182895
     6869            LValue left = lowBigInt(m_node->child1());
     6870            LValue right = lowBigInt(m_node->child2());
     6871
     6872            LBasicBlock notTriviallyEqualCase = m_out.newBlock();
     6873            LBasicBlock continuation = m_out.newBlock();
     6874
     6875            ValueFromBlock fastResult = m_out.anchor(m_out.booleanTrue);
     6876            m_out.branch(m_out.equal(left, right), rarely(continuation), usually(notTriviallyEqualCase));
     6877
     6878            LBasicBlock lastNext = m_out.appendTo(notTriviallyEqualCase, continuation);
     6879
     6880            ValueFromBlock slowResult = m_out.anchor(m_out.notNull(vmCall(
     6881                pointerType(), m_out.operation(operationCompareStrictEq), m_callFrame, left, right)));
     6882            m_out.jump(continuation);
     6883
     6884            m_out.appendTo(continuation, lastNext);
     6885            setBoolean(m_out.phi(Int32, fastResult, slowResult));
     6886            return;
     6887        }
     6888
    68666889        if (m_node->isBinaryUseKind(SymbolUse, UntypedUse)
    68676890            || m_node->isBinaryUseKind(UntypedUse, SymbolUse)) {
     
    1110711130            speculate(BadType, jsValueValue(value), edge.node(), isNotCell(value, provenType(edge)));
    1110811131            speculate(BadType, jsValueValue(value), edge.node(), isNotSymbol(value, provenType(edge)));
     11132            return;
     11133
     11134        case InferredType::BigInt:
     11135            speculate(BadType, jsValueValue(value), edge.node(), isNotCell(value, provenType(edge)));
     11136            speculate(BadType, jsValueValue(value), edge.node(), isNotBigInt(value, provenType(edge)));
    1110911137            return;
    1111011138
     
    1425814286        return result;
    1425914287    }
     14288
     14289    LValue lowBigInt(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     14290    {
     14291        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BigIntUse);
     14292
     14293        LValue result = lowCell(edge, mode);
     14294        speculateBigInt(edge, result);
     14295        return result;
     14296    }
    1426014297   
    1426114298    LValue lowNonNullObject(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     
    1472814765            speculateBoolean(edge);
    1472914766            break;
     14767        case BigIntUse:
     14768            speculateBigInt(edge);
     14769            break;
    1473014770        case NotStringVarUse:
    1473114771            speculateNotStringVar(edge);
     
    1487214912    }
    1487314913
     14914    LValue isNotBigInt(LValue cell, SpeculatedType type = SpecFullTop)
     14915    {
     14916        if (LValue proven = isProvenValue(type & SpecCell, ~SpecBigInt))
     14917            return proven;
     14918        return m_out.notEqual(
     14919            m_out.load32(cell, m_heaps.JSCell_structureID),
     14920            m_out.constInt32(vm().bigIntStructure->id()));
     14921    }
     14922
    1487414923    LValue isArrayTypeForArrayify(LValue cell, ArrayMode arrayMode)
    1487514924    {
     
    1528715336    {
    1528815337        speculateSymbol(edge, lowCell(edge));
     15338    }
     15339
     15340    void speculateBigInt(Edge edge, LValue cell)
     15341    {
     15342        FTL_TYPE_CHECK(jsValueValue(cell), edge, SpecBigInt, isNotBigInt(cell));
     15343    }
     15344
     15345    void speculateBigInt(Edge edge)
     15346    {
     15347        speculateBigInt(edge, lowCell(edge));
    1528915348    }
    1529015349
  • trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp

    r230294 r230516  
    9999        result.append(branchIfNotCell(regs, mode));
    100100        result.append(branchIfNotSymbol(regs.payloadGPR()));
     101        break;
     102
     103    case InferredType::BigInt:
     104        result.append(branchIfNotCell(regs, mode));
     105        result.append(branchIfNotBigInt(regs.payloadGPR()));
    101106        break;
    102107
  • trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h

    r230144 r230516  
    900900    Jump branchIfSymbol(GPRReg cellGPR) { return branchIfType(cellGPR, SymbolType); }
    901901    Jump branchIfNotSymbol(GPRReg cellGPR) { return branchIfNotType(cellGPR, SymbolType); }
     902    Jump branchIfBigInt(GPRReg cellGPR) { return branchIfType(cellGPR, BigIntType); }
     903    Jump branchIfNotBigInt(GPRReg cellGPR) { return branchIfNotType(cellGPR, BigIntType); }
    902904    Jump branchIfFunction(GPRReg cellGPR) { return branchIfType(cellGPR, JSFunctionType); }
    903905    Jump branchIfNotFunction(GPRReg cellGPR) { return branchIfNotType(cellGPR, JSFunctionType); }
  • trunk/Source/JavaScriptCore/runtime/InferredType.cpp

    r225831 r230516  
    146146        if (cell->isSymbol())
    147147            return Symbol;
     148        if (cell->isBigInt())
     149            return BigInt;
    148150        if (cell->isObject()) {
    149151            if (cell->structure()->transitionWatchpointSetIsStillValid())
     
    185187    case Object:
    186188        return static_cast<PutByIdFlags>(PutByIdPrimaryTypeSecondary | PutByIdSecondaryTypeObject);
     189    case BigInt:
    187190    case ObjectOrOther:
    188191        return static_cast<PutByIdFlags>(PutByIdPrimaryTypeSecondary | PutByIdSecondaryTypeObjectOrOther);
     
    215218    case String:
    216219    case Symbol:
     220    case BigInt:
    217221        *this = Top;
    218222        return;
     
    534538        out.print("Symbol");
    535539        return;
     540    case InferredType::BigInt:
     541        out.print("BigInt");
     542        return;
    536543    case InferredType::ObjectWithStructure:
    537544        out.print("ObjectWithStructure");
  • trunk/Source/JavaScriptCore/runtime/InferredType.h

    r228500 r230516  
    7070        String,
    7171        Symbol,
     72        BigInt,
    7273        ObjectWithStructure,
    7374        ObjectWithStructureOrOther,
     
    137138            case Symbol:
    138139                return value.isSymbol();
     140            case BigInt:
     141                return value.isBigInt();
    139142            case ObjectWithStructure:
    140143                return value.isCell() && value.asCell()->structure() == m_structure;
  • trunk/Source/JavaScriptCore/runtime/JSBigInt.h

    r229413 r230516  
    3838class JSBigInt final : public JSCell {
    3939    using Base = JSCell;
     40    static const unsigned StructureFlags = Base::StructureFlags | OverridesToThis;
    4041
    4142public:
Note: See TracChangeset for help on using the changeset viewer.