Ignore:
Timestamp:
May 28, 2020, 11:38:48 AM (5 years ago)
Author:
[email protected]
Message:

for-of should check the iterable is a JSArray for FastArray in DFG iterator_open
https://bugs.webkit.org/show_bug.cgi?id=212383

Reviewed by Saam Barati.

JSTests:

  • stress/check-sub-class.js:
  • stress/for-of-iterator-open-fast-array-should-check-js-type.js: Added.

(foo):

Source/JavaScriptCore:

This patch fixes an issue where we didn't check that the iterable operand to
iterator_open was a JSArray when lowering the FastArray only variant of the bytecode to the DFG.
This meant we would OSR exit at the iterator_next's lowering then assertion failure in the
checkpoint OSR exit helper. To make this work, this patch extends (and renames from CheckSubClass)
CheckJSCast to use the same JSType information that we use for the jsCast function. In order to
get the JSType range from a ClassInfo* the macro that autogenerates MethodTable now also fills
a Optional<JSTypeRange> into the ClassInfo as well.

Lastly, speculationFromClassInfo was misused by AI. This patch
renames it to speculationFromClassInfoInheritance to better
reflect how AI was using it. The only other user of
speculationFromClassInfo was speculationFromStructure. Any case
where speculationFromClassInfoInteritance would differ from what a
Structure would tell you has been hoisted to
speculationFromStructure.

  • assembler/testmasm.cpp:

(JSC::testBranchIfType):
(JSC::testBranchIfNotType):

  • bytecode/SpeculatedType.cpp:

(JSC::speculationFromClassInfoInheritance):
(JSC::speculationFromStructure):
(JSC::speculationFromClassInfo): Deleted.

  • bytecode/SpeculatedType.h:
  • dfg/DFGAbstractInterpreterInlines.h:

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

  • dfg/DFGAbstractValue.cpp:

(JSC::DFG::AbstractValue::filterClassInfo):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::handleDOMJITGetter):
(JSC::DFG::ByteCodeParser::parseBlock):

  • 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::attemptToMakeCallDOM):
(JSC::DFG::FixupPhase::fixupCheckJSCast):
(JSC::DFG::FixupPhase::fixupCheckSubClass): Deleted.

  • dfg/DFGNode.h:

(JSC::DFG::Node::hasClassInfo const):

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

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::checkArray):
(JSC::DFG::SpeculativeJIT::compileCheckJSCast):
(JSC::DFG::SpeculativeJIT::compileCheckSubClass): Deleted.

  • 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::compileCheckJSCast):
(JSC::FTL::DFG::LowerDFGToB3::isCellWithType):
(JSC::FTL::DFG::LowerDFGToB3::isTypedArrayView):
(JSC::FTL::DFG::LowerDFGToB3::compileCheckSubClass): Deleted.

  • jit/AssemblyHelpers.h:

(JSC::AssemblyHelpers::branchIfType):
(JSC::AssemblyHelpers::branchIfNotType):

  • runtime/ClassInfo.h:
  • runtime/JSCast.h:

(JSC::JSTypeRange::contains const):
(JSC::JSCastingHelpers::inheritsJSTypeImpl):

  • runtime/JSFunction.cpp:

(JSC::JSFunction::assertTypeInfoFlagInvariants):

  • tools/JSDollarVM.cpp:

(JSC::functionCreateDOMJITCheckJSCastObject):
(JSC::JSDollarVM::finishCreation):
(JSC::functionCreateDOMJITCheckSubClassObject): Deleted.

Source/WebCore:

Update various InheritsTraits specializations to contain a typeRange member.
Also, change the inherits function to use inheritsJSTypeImpl like the JSC
variants.

  • bindings/js/JSDocumentCustom.h:

(JSC::JSCastingHelpers::InheritsTraits<WebCore::JSDocument>::inherits):

  • bindings/js/JSElementCustom.h:

(JSC::JSCastingHelpers::InheritsTraits<WebCore::JSElement>::inherits):

  • bindings/js/JSEventCustom.h:

(JSC::JSCastingHelpers::InheritsTraits<WebCore::JSEvent>::inherits):

  • bindings/js/JSNodeCustom.h:

(JSC::JSCastingHelpers::InheritsTraits<WebCore::JSNode>::inherits):

  • bindings/scripts/CodeGeneratorJS.pm:

(GenerateHeader):

Source/WTF:

Optional should be able to copy/move constructor itself as long as <T> is
trivially copyable. This lets us copy Optionals into const globals without
global constructors.

  • wtf/Optional.h:

(WTF::Optional::Optional):
(WTF::Optional::NOEXCEPT_):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r262233 r262252  
    15901590            compileNumberToStringWithValidRadixConstant();
    15911591            break;
    1592         case CheckSubClass:
    1593             compileCheckSubClass();
     1592        case CheckJSCast:
     1593            compileCheckJSCast();
    15941594            break;
    15951595        case CallDOM:
     
    1394013940    }
    1394113941
    13942     void compileCheckSubClass()
     13942    void compileCheckJSCast()
    1394313943    {
    1394413944        LValue cell = lowCell(m_node->child1());
    1394513945
    1394613946        const ClassInfo* classInfo = m_node->classInfo();
     13947
     13948        if (classInfo->inheritsJSTypeRange) {
     13949            LValue hasType = isCellWithType(cell, classInfo->inheritsJSTypeRange.value(), speculationFromClassInfoInheritance(classInfo));
     13950            speculate(BadType, jsValueValue(cell), m_node->child1().node(), m_out.bitNot(hasType));
     13951            return;
     13952        }
     13953
    1394713954        if (!classInfo->checkSubClassSnippet) {
    1394813955            LBasicBlock loop = m_out.newBlock();
     
    1770917716    }
    1771017717
    17711     LValue isCellWithType(LValue cell, JSType queriedType, Optional<SpeculatedType> speculatedTypeForQuery, SpeculatedType type = SpecFullTop)
     17718    LValue isCellWithType(LValue cell, JSTypeRange queriedTypeRange, Optional<SpeculatedType> speculatedTypeForQuery, SpeculatedType type = SpecFullTop)
    1771217719    {
    1771317720        if (speculatedTypeForQuery) {
     
    1771517722                return proven;
    1771617723        }
    17717         return m_out.equal(
     17724        if (queriedTypeRange.first == queriedTypeRange.last) {
     17725            return m_out.equal(
     17726                m_out.load8ZeroExt32(cell, m_heaps.JSCell_typeInfoType),
     17727                m_out.constInt32(queriedTypeRange.first));
     17728        }
     17729
     17730        ASSERT(queriedTypeRange.last > queriedTypeRange.first);
     17731        LValue first = m_out.sub(
    1771817732            m_out.load8ZeroExt32(cell, m_heaps.JSCell_typeInfoType),
    17719             m_out.constInt32(queriedType));
     17733            m_out.constInt32(queriedTypeRange.first));
     17734        return m_out.belowOrEqual(first, m_out.constInt32(queriedTypeRange.last - queriedTypeRange.first));
     17735    }
     17736
     17737    LValue isCellWithType(LValue cell, JSType queriedType, Optional<SpeculatedType> speculatedTypeForQuery, SpeculatedType type = SpecFullTop)
     17738    {
     17739        return isCellWithType(cell, JSTypeRange { queriedType, queriedType }, speculatedTypeForQuery, type);
    1772017740    }
    1772117741
    1772217742    LValue isTypedArrayView(LValue cell, SpeculatedType type = SpecFullTop)
    1772317743    {
    17724         if (LValue proven = isProvenValue(type & SpecCell, SpecTypedArrayView))
    17725             return proven;
    17726         LValue jsType = m_out.sub(
    17727             m_out.load8ZeroExt32(cell, m_heaps.JSCell_typeInfoType),
    17728             m_out.constInt32(FirstTypedArrayType));
    17729         return m_out.below(
    17730             jsType,
    17731             m_out.constInt32(NumberOfTypedArrayTypesExcludingDataView));
     17744        return isCellWithType(cell, JSTypeRange { static_cast<JSType>(FirstTypedArrayType), static_cast<JSType>(LastTypedArrayTypeExcludingDataView) }, SpecTypedArrayView, type);
    1773217745    }
    1773317746   
Note: See TracChangeset for help on using the changeset viewer.