Changeset 171648 in webkit for trunk/Source/JavaScriptCore/dfg


Ignore:
Timestamp:
Jul 26, 2014, 12:06:44 PM (11 years ago)
Author:
[email protected]
Message:

Unreviewed, roll out r171641-r171644. It broke some tests; will investigate and
reland later.

Source/JavaScriptCore:

  • CMakeLists.txt:
  • JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
  • JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • bytecode/BytecodeList.json:
  • bytecode/BytecodeUseDef.h:

(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::finalizeUnconditionally):
(JSC::CodeBlock::printPutByIdCacheStatus): Deleted.

  • bytecode/CodeBlock.h:
  • bytecode/GetByIdStatus.cpp:

(JSC::GetByIdStatus::computeForStubInfo):
(JSC::GetByIdStatus::computeFor):

  • bytecode/GetByIdStatus.h:
  • bytecode/GetByIdVariant.cpp:

(JSC::GetByIdVariant::dumpInContext):

  • bytecode/GetByIdVariant.h:

(JSC::GetByIdVariant::structureSet):

  • bytecode/Instruction.h:
  • bytecode/PutByIdStatus.cpp:

(JSC::PutByIdStatus::appendVariant):
(JSC::PutByIdStatus::computeForStubInfo):
(JSC::PutByIdStatus::computeFor):

  • bytecode/PutByIdStatus.h:
  • bytecode/PutByIdVariant.cpp:

(JSC::PutByIdVariant::dumpInContext):
(JSC::PutByIdVariant::oldStructureForTransition): Deleted.
(JSC::PutByIdVariant::writesStructures): Deleted.
(JSC::PutByIdVariant::reallocatesStorage): Deleted.
(JSC::PutByIdVariant::attemptToMerge): Deleted.
(JSC::PutByIdVariant::attemptToMergeTransitionWithReplace): Deleted.

  • bytecode/PutByIdVariant.h:

(JSC::PutByIdVariant::PutByIdVariant):
(JSC::PutByIdVariant::replace):
(JSC::PutByIdVariant::transition):
(JSC::PutByIdVariant::structure):
(JSC::PutByIdVariant::oldStructure):
(JSC::PutByIdVariant::newStructure):
(JSC::PutByIdVariant::constantChecks):

  • bytecode/StructureSet.cpp:

(JSC::StructureSet::filter): Deleted.
(JSC::StructureSet::filterArrayModes): Deleted.

  • bytecode/StructureSet.h:

(JSC::StructureSet::onlyStructure):

  • bytecode/ToThisStatus.cpp: Removed.
  • bytecode/ToThisStatus.h: Removed.
  • bytecode/TypeLocation.h: Removed.
  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::emitMove):
(JSC::BytecodeGenerator::emitPutToScope):
(JSC::BytecodeGenerator::emitPutById):
(JSC::BytecodeGenerator::emitPutByVal):
(JSC::BytecodeGenerator::emitProfileTypesWithHighFidelity): Deleted.

  • bytecompiler/BytecodeGenerator.h:

(JSC::BytecodeGenerator::isProfilingTypesWithHighFidelity): Deleted.

  • bytecompiler/NodesCodegen.cpp:

(JSC::PostfixNode::emitResolve):
(JSC::PrefixNode::emitResolve):
(JSC::ReadModifyResolveNode::emitBytecode):
(JSC::AssignResolveNode::emitBytecode):
(JSC::ConstDeclNode::emitCodeSingle):
(JSC::ForInNode::emitBytecode):

  • debugger/DebuggerActivation.cpp: Added.

(JSC::DebuggerActivation::DebuggerActivation):
(JSC::DebuggerActivation::finishCreation):
(JSC::DebuggerActivation::visitChildren):
(JSC::DebuggerActivation::className):
(JSC::DebuggerActivation::getOwnPropertySlot):
(JSC::DebuggerActivation::put):
(JSC::DebuggerActivation::deleteProperty):
(JSC::DebuggerActivation::getOwnPropertyNames):
(JSC::DebuggerActivation::defineOwnProperty):

  • debugger/DebuggerActivation.h: Added.

(JSC::DebuggerActivation::create):
(JSC::DebuggerActivation::createStructure):

  • debugger/DebuggerScope.cpp: Removed.
  • debugger/DebuggerScope.h: Removed.
  • dfg/DFGAbstractInterpreterInlines.h:

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

  • dfg/DFGAbstractValue.cpp:

(JSC::DFG::AbstractValue::changeStructure): Deleted.
(JSC::DFG::AbstractValue::contains): Deleted.

  • dfg/DFGAbstractValue.h:

(JSC::DFG::AbstractValue::couldBeType):
(JSC::DFG::AbstractValue::isType):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::handlePutById):
(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGConstantFoldingPhase.cpp:

(JSC::DFG::ConstantFoldingPhase::foldConstants):
(JSC::DFG::ConstantFoldingPhase::emitGetByOffset):
(JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
(JSC::DFG::ConstantFoldingPhase::addBaseCheck): Deleted.
(JSC::DFG::ConstantFoldingPhase::addChecks): Deleted.

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • dfg/DFGFixupPhase.cpp:

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

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::visitChildren):
(JSC::DFG::Graph::freezeStrong):

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

(JSC::DFG::MultiPutByOffsetData::writesStructures):
(JSC::DFG::MultiPutByOffsetData::reallocatesStorage):

  • dfg/DFGNode.h:

(JSC::DFG::Node::convertToPutByOffset):
(JSC::DFG::Node::hasTransition):
(JSC::DFG::Node::convertToMultiGetByOffset): Deleted.
(JSC::DFG::Node::convertToMultiPutByOffset): Deleted.

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

(JSC::DFG::PredictionPropagationPhase::propagate):

  • dfg/DFGSafeToExecute.h:

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):

  • dfg/DFGSpeculativeJIT32_64.cpp:

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

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::fillJSValue):
(JSC::DFG::SpeculativeJIT::nonSpeculativeCompareNull):
(JSC::DFG::SpeculativeJIT::emitCall):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt32Strict):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compileLogicalNot):
(JSC::DFG::SpeculativeJIT::emitBranch):
(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGStructureAbstractValue.cpp:

(JSC::DFG::StructureAbstractValue::observeTransition):
(JSC::DFG::StructureAbstractValue::observeTransitions):

  • dfg/DFGStructureAbstractValue.h:

(JSC::DFG::StructureAbstractValue::onlyStructure):
(JSC::DFG::StructureAbstractValue::operator=): Deleted.
(JSC::DFG::StructureAbstractValue::set): Deleted.

  • dfg/DFGValidate.cpp:

(JSC::DFG::Validate::validate):

  • dfg/DFGWatchableStructureWatchingPhase.cpp:

(JSC::DFG::WatchableStructureWatchingPhase::run):

  • ftl/FTLAbbreviations.h:

(JSC::FTL::getLinkage): Deleted.

  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compilePhantomPutStructure):
(JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
(JSC::FTL::LowerDFGToLLVM::compileMultiPutByOffset):
(JSC::FTL::LowerDFGToLLVM::getModuleByPathForSymbol):

  • heap/Heap.cpp:

(JSC::Heap::collect):

  • inspector/agents/InspectorRuntimeAgent.cpp:

(Inspector::InspectorRuntimeAgent::getRuntimeTypeForVariableInTextRange): Deleted.

  • inspector/agents/InspectorRuntimeAgent.h:
  • inspector/protocol/Runtime.json:
  • jsc.cpp:

(GlobalObject::finishCreation):
(functionDumpTypesForAllVariables): Deleted.

  • llint/LLIntData.cpp:

(JSC::LLInt::Data::performAssertions):

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):
(JSC::LLInt::putToScopeCommon): Deleted.

  • llint/LLIntSlowPaths.h:
  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • runtime/ArrayBufferNeuteringWatchpoint.cpp:

(JSC::ArrayBufferNeuteringWatchpoint::createStructure):

  • runtime/CommonSlowPaths.cpp:

(JSC::SLOW_PATH_DECL):

  • runtime/Executable.h:

(JSC::ExecutableBase::createStructure):
(JSC::NativeExecutable::createStructure):

  • runtime/HighFidelityLog.cpp: Removed.
  • runtime/HighFidelityLog.h: Removed.
  • runtime/HighFidelityTypeProfiler.cpp: Removed.
  • runtime/HighFidelityTypeProfiler.h: Removed.
  • runtime/JSObject.cpp:

(JSC::JSObject::putDirectCustomAccessor):
(JSC::JSObject::putDirectNonIndexAccessor):
(JSC::JSObject::reifyStaticFunctionsForDelete):

  • runtime/JSPromiseDeferred.h:

(JSC::JSPromiseDeferred::createStructure):

  • runtime/JSPromiseReaction.h:

(JSC::JSPromiseReaction::createStructure):

  • runtime/JSPropertyNameIterator.h:

(JSC::JSPropertyNameIterator::createStructure):

  • runtime/JSType.h:
  • runtime/JSTypeInfo.h:

(JSC::TypeInfo::TypeInfo):

  • runtime/MapData.h:

(JSC::MapData::createStructure):

  • runtime/Options.h:
  • runtime/PropertyMapHashTable.h:

(JSC::PropertyTable::createStructure):

  • runtime/RegExp.h:

(JSC::RegExp::createStructure):

  • runtime/SparseArrayValueMap.cpp:

(JSC::SparseArrayValueMap::createStructure):

  • runtime/Structure.cpp:

(JSC::StructureTransitionTable::contains):
(JSC::StructureTransitionTable::get):
(JSC::StructureTransitionTable::add):
(JSC::Structure::Structure):
(JSC::Structure::materializePropertyMap):
(JSC::Structure::addPropertyTransition):
(JSC::Structure::despecifyFunctionTransition):
(JSC::Structure::toDictionaryTransition):
(JSC::Structure::freezeTransition):
(JSC::Structure::preventExtensionsTransition):
(JSC::Structure::takePropertyTableOrCloneIfPinned):
(JSC::Structure::nonPropertyTransition):
(JSC::Structure::flattenDictionaryStructure):
(JSC::Structure::addPropertyWithoutTransition):
(JSC::Structure::pin):
(JSC::Structure::allocateRareData):
(JSC::Structure::cloneRareDataFrom):
(JSC::Structure::getConcurrently):
(JSC::Structure::putSpecificValue):
(JSC::Structure::getPropertyNamesFromStructure):
(JSC::Structure::visitChildren):
(JSC::Structure::checkConsistency):
(JSC::Structure::toStructureShape): Deleted.

  • runtime/Structure.h:

(JSC::Structure::isExtensible):
(JSC::Structure::didTransition):
(JSC::Structure::isDictionary):
(JSC::Structure::isUncacheableDictionary):
(JSC::Structure::hasBeenFlattenedBefore):
(JSC::Structure::propertyAccessesAreCacheable):
(JSC::Structure::previousID):
(JSC::Structure::hasGetterSetterProperties):
(JSC::Structure::hasReadOnlyOrGetterSetterPropertiesExcludingProto):
(JSC::Structure::setHasGetterSetterProperties):
(JSC::Structure::hasCustomGetterSetterProperties):
(JSC::Structure::setHasCustomGetterSetterProperties):
(JSC::Structure::setContainsReadOnlyProperties):
(JSC::Structure::hasNonEnumerableProperties):
(JSC::Structure::disableSpecificFunctionTracking):
(JSC::Structure::objectToStringValue):
(JSC::Structure::setObjectToStringValue):
(JSC::Structure::staticFunctionsReified):
(JSC::Structure::setStaticFunctionsReified):
(JSC::Structure::transitionWatchpointSet):
(JSC::Structure::setPreviousID):
(JSC::Structure::clearPreviousID):
(JSC::Structure::previous):
(JSC::Structure::rareData):
(JSC::Structure::setHasGetterSetterPropertiesWithProtoCheck): Deleted.
(JSC::Structure::setHasCustomGetterSetterPropertiesWithProtoCheck): Deleted.

  • runtime/StructureChain.h:

(JSC::StructureChain::createStructure):

  • runtime/StructureInlines.h:

(JSC::Structure::setEnumerationCache):
(JSC::Structure::enumerationCache):
(JSC::Structure::checkOffsetConsistency):

  • runtime/StructureRareData.cpp:

(JSC::StructureRareData::createStructure):

  • runtime/SymbolTable.cpp:

(JSC::SymbolTable::SymbolTable):
(JSC::SymbolTable::cloneCapturedNames):
(JSC::SymbolTable::uniqueIDForVariable): Deleted.
(JSC::SymbolTable::uniqueIDForRegister): Deleted.
(JSC::SymbolTable::globalTypeSetForRegister): Deleted.
(JSC::SymbolTable::globalTypeSetForVariable): Deleted.

  • runtime/SymbolTable.h:

(JSC::SymbolTable::createStructure):
(JSC::SymbolTable::add):
(JSC::SymbolTable::set):

  • runtime/TypeSet.cpp: Removed.
  • runtime/TypeSet.h: Removed.
  • runtime/VM.cpp:

(JSC::VM::VM):
(JSC::VM::getTypesForVariableInRange): Deleted.
(JSC::VM::updateHighFidelityTypeProfileState): Deleted.
(JSC::VM::dumpHighFidelityProfilingTypes): Deleted.

  • runtime/VM.h:

(JSC::VM::isProfilingTypesWithHighFidelity): Deleted.
(JSC::VM::highFidelityLog): Deleted.
(JSC::VM::highFidelityTypeProfiler): Deleted.
(JSC::VM::nextLocation): Deleted.
(JSC::VM::getNextUniqueVariableID): Deleted.

  • runtime/WeakMapData.h:

(JSC::WeakMapData::createStructure):

  • tests/stress/fold-multi-get-by-offset-to-get-by-offset-without-folding-the-structure-check.js: Removed.
  • tests/stress/fold-multi-put-by-offset-to-put-by-offset-without-folding-the-structure-check.js: Removed.
  • tests/stress/prune-multi-put-by-offset-replace-or-transition-variant.js: Removed.

Source/WebCore:

  • ForwardingHeaders/debugger/DebuggerActivation.h: Added.

Source/WebKit/mac:

  • WebView/WebScriptDebugDelegate.mm:

Source/WTF:

  • wtf/text/WTFString.h:

LayoutTests:

  • js/regress/fold-get-by-id-to-multi-get-by-offset-expected.txt: Removed.
  • js/regress/fold-get-by-id-to-multi-get-by-offset-rare-int-expected.txt: Removed.
  • js/regress/fold-get-by-id-to-multi-get-by-offset-rare-int.html: Removed.
  • js/regress/fold-get-by-id-to-multi-get-by-offset.html: Removed.
  • js/regress/fold-multi-get-by-offset-to-get-by-offset-expected.txt: Removed.
  • js/regress/fold-multi-get-by-offset-to-get-by-offset.html: Removed.
  • js/regress/fold-multi-get-by-offset-to-poly-get-by-offset-expected.txt: Removed.
  • js/regress/fold-multi-get-by-offset-to-poly-get-by-offset.html: Removed.
  • js/regress/fold-multi-put-by-offset-to-poly-put-by-offset-expected.txt: Removed.
  • js/regress/fold-multi-put-by-offset-to-poly-put-by-offset.html: Removed.
  • js/regress/fold-multi-put-by-offset-to-put-by-offset-expected.txt: Removed.
  • js/regress/fold-multi-put-by-offset-to-put-by-offset.html: Removed.
  • js/regress/fold-multi-put-by-offset-to-replace-or-transition-put-by-offset-expected.txt: Removed.
  • js/regress/fold-multi-put-by-offset-to-replace-or-transition-put-by-offset.html: Removed.
  • js/regress/fold-put-by-id-to-multi-put-by-offset-expected.txt: Removed.
  • js/regress/fold-put-by-id-to-multi-put-by-offset.html: Removed.
  • js/regress/fold-put-structure-expected.txt: Removed.
  • js/regress/fold-put-structure.html: Removed.
  • js/regress/hoist-poly-check-structure-effectful-loop-expected.txt: Removed.
  • js/regress/hoist-poly-check-structure-effectful-loop.html: Removed.
  • js/regress/hoist-poly-check-structure-expected.txt: Removed.
  • js/regress/hoist-poly-check-structure.html: Removed.
  • js/regress/put-by-id-replace-and-transition-expected.txt: Removed.
  • js/regress/put-by-id-replace-and-transition.html: Removed.
  • js/regress/put-by-id-slightly-polymorphic-expected.txt: Removed.
  • js/regress/put-by-id-slightly-polymorphic.html: Removed.
  • js/regress/script-tests/fold-get-by-id-to-multi-get-by-offset-rare-int.js: Removed.
  • js/regress/script-tests/fold-get-by-id-to-multi-get-by-offset.js: Removed.
  • js/regress/script-tests/fold-multi-get-by-offset-to-get-by-offset.js: Removed.
  • js/regress/script-tests/fold-multi-get-by-offset-to-poly-get-by-offset.js: Removed.
  • js/regress/script-tests/fold-multi-put-by-offset-to-poly-put-by-offset.js: Removed.
  • js/regress/script-tests/fold-multi-put-by-offset-to-put-by-offset.js: Removed.
  • js/regress/script-tests/fold-multi-put-by-offset-to-replace-or-transition-put-by-offset.js: Removed.
  • js/regress/script-tests/fold-put-by-id-to-multi-put-by-offset.js: Removed.
  • js/regress/script-tests/fold-put-structure.js: Removed.
  • js/regress/script-tests/hoist-poly-check-structure-effectful-loop.js: Removed.
  • js/regress/script-tests/hoist-poly-check-structure.js: Removed.
  • js/regress/script-tests/put-by-id-replace-and-transition.js: Removed.
  • js/regress/script-tests/put-by-id-slightly-polymorphic.js: Removed.
Location:
trunk/Source/JavaScriptCore/dfg
Files:
22 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r171641 r171648  
    13891389           
    13901390    case GetById:
    1391     case GetByIdFlush: {
     1391    case GetByIdFlush:
    13921392        if (!node->prediction()) {
    13931393            m_state.setIsValid(false);
    13941394            break;
    13951395        }
    1396        
    1397         AbstractValue& value = forNode(node->child1());
    1398         if (!value.m_structure.isTop() && !value.m_structure.isClobbered()
    1399             && (node->child1().useKind() == CellUse || !(value.m_type & ~SpecCell))) {
    1400             GetByIdStatus status = GetByIdStatus::computeFor(
    1401                 m_graph.m_vm, value.m_structure.set(),
    1402                 m_graph.identifiers()[node->identifierNumber()]);
    1403             if (status.isSimple()) {
    1404                 // Figure out what the result is going to be - is it TOP, a constant, or maybe
    1405                 // something more subtle?
    1406                 AbstractValue result;
    1407                 for (unsigned i = status.numVariants(); i--;) {
    1408                     if (!status[i].specificValue()) {
    1409                         result.makeHeapTop();
    1410                         break;
    1411                     }
     1396        if (isCellSpeculation(node->child1()->prediction())) {
     1397            // This use of onlyStructure() should be replaced by giving GetByIdStatus the ability
     1398            // to compute things based on a StructureSet, and then to factor ByteCodeParser's
     1399            // ability to generate code based on a GetByIdStatus out of ByteCodeParser so that
     1400            // ConstantFoldingPhase can use it.
     1401            // https://bugs.webkit.org/show_bug.cgi?id=133229
     1402            if (Structure* structure = forNode(node->child1()).m_structure.onlyStructure()) {
     1403                GetByIdStatus status = GetByIdStatus::computeFor(
     1404                    m_graph.m_vm, structure,
     1405                    m_graph.identifiers()[node->identifierNumber()]);
     1406                if (status.isSimple() && status.numVariants() == 1) {
     1407                    // Assert things that we can't handle and that the computeFor() method
     1408                    // above won't be able to return.
     1409                    ASSERT(status[0].structureSet().size() == 1);
     1410                    ASSERT(status[0].constantChecks().isEmpty());
     1411                    ASSERT(!status[0].alternateBase());
    14121412                   
    1413                     AbstractValue thisResult;
    1414                     thisResult.set(
    1415                         m_graph, *m_graph.freeze(status[i].specificValue()),
    1416                         m_state.structureClobberState());
    1417                     result.merge(thisResult);
    1418                 }
    1419                 if (status.numVariants() == 1 || isFTL(m_graph.m_plan.mode))
     1413                    if (status[0].specificValue()) {
     1414                        if (status[0].specificValue().isCell()) {
     1415                            Structure* structure = status[0].specificValue().asCell()->structure();
     1416                            m_graph.watchpoints().consider(structure);
     1417                        }
     1418                        setConstant(node, *m_graph.freeze(status[0].specificValue()));
     1419                    } else
     1420                        forNode(node).makeHeapTop();
     1421                    filter(node->child1(), status[0].structureSet());
     1422                   
    14201423                    m_state.setFoundConstants(true);
    1421                 forNode(node) = result;
    1422                 break;
    1423             }
    1424         }
    1425 
     1424                    break;
     1425                }
     1426            }
     1427        }
    14261428        clobberWorld(node->origin.semantic, clobberLimit);
    14271429        forNode(node).makeHeapTop();
    14281430        break;
    1429     }
    14301431           
    14311432    case GetArrayLength:
     
    14621463       
    14631464    case PutStructure:
     1465    case PhantomPutStructure:
    14641466        if (!forNode(node->child1()).m_structure.isClear()) {
    1465             if (forNode(node->child1()).m_structure.onlyStructure() == node->transition()->next)
    1466                 m_state.setFoundConstants(true);
    1467             else {
    1468                 observeTransition(
    1469                     clobberLimit, node->transition()->previous, node->transition()->next);
    1470                 forNode(node->child1()).changeStructure(m_graph, node->transition()->next);
    1471             }
     1467            observeTransition(
     1468                clobberLimit, node->transition()->previous, node->transition()->next);
     1469            forNode(node->child1()).set(m_graph, node->transition()->next);
    14721470        }
    14731471        break;
     
    15981596       
    15991597    case MultiGetByOffset: {
    1600         // This code will filter the base value in a manner that is possibly different (either more
    1601         // or less precise) than the way it would be filtered if this was strength-reduced to a
    1602         // CheckStructure. This is fine. It's legal for different passes over the code to prove
    1603         // different things about the code, so long as all of them are sound. That even includes
    1604         // one guy proving that code should never execute (due to a contradiction) and another guy
    1605         // not finding that contradiction. If someone ever proved that there would be a
    1606         // contradiction then there must always be a contradiction even if subsequent passes don't
    1607         // realize it. This is the case here.
    1608        
    1609         // Ordinarily you have to be careful with calling setFoundConstants()
    1610         // because of the effect on compile times, but this node is FTL-only.
    1611         m_state.setFoundConstants(true);
    1612        
    1613         AbstractValue base = forNode(node->child1());
    1614         StructureSet baseSet;
    1615         AbstractValue result;
    1616         for (unsigned i = node->multiGetByOffsetData().variants.size(); i--;) {
    1617             GetByIdVariant& variant = node->multiGetByOffsetData().variants[i];
    1618             StructureSet set = variant.structureSet();
    1619             set.filter(base);
    1620             if (set.isEmpty())
    1621                 continue;
    1622             baseSet.merge(set);
    1623             if (!variant.specificValue()) {
    1624                 result.makeHeapTop();
    1625                 continue;
    1626             }
    1627             AbstractValue thisResult;
    1628             thisResult.set(
    1629                 m_graph,
    1630                 *m_graph.freeze(variant.specificValue()),
    1631                 m_state.structureClobberState());
    1632             result.merge(thisResult);
    1633         }
    1634        
    1635         if (forNode(node->child1()).changeStructure(m_graph, baseSet) == Contradiction)
    1636             m_state.setIsValid(false);
    1637        
    1638         forNode(node) = result;
     1598        AbstractValue& value = forNode(node->child1());
     1599        ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
     1600
     1601        // This should just filter down the cases in MultiGetByOffset. If that results in all
     1602        // cases having the same offset then we should strength reduce it to a CheckStructure +
     1603        // GetByOffset.
     1604        // https://bugs.webkit.org/show_bug.cgi?id=133229
     1605        if (Structure* structure = value.m_structure.onlyStructure()) {
     1606            bool done = false;
     1607            for (unsigned i = node->multiGetByOffsetData().variants.size(); i--;) {
     1608                const GetByIdVariant& variant = node->multiGetByOffsetData().variants[i];
     1609                if (!variant.structureSet().contains(structure))
     1610                    continue;
     1611               
     1612                if (variant.alternateBase())
     1613                    break;
     1614               
     1615                filter(value, structure);
     1616                forNode(node).makeHeapTop();
     1617                m_state.setFoundConstants(true);
     1618                done = true;
     1619                break;
     1620            }
     1621            if (done)
     1622                break;
     1623        }
     1624       
     1625        StructureSet set;
     1626        for (unsigned i = node->multiGetByOffsetData().variants.size(); i--;)
     1627            set.merge(node->multiGetByOffsetData().variants[i].structureSet());
     1628       
     1629        filter(node->child1(), set);
     1630        forNode(node).makeHeapTop();
    16391631        break;
    16401632    }
     
    16451637       
    16461638    case MultiPutByOffset: {
     1639        AbstractValue& value = forNode(node->child1());
     1640        ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
     1641
     1642        // This should just filter down the cases in MultiPutByOffset. If that results in either
     1643        // one case, or nothing but replace cases and they have the same offset, then we should
     1644        // just strength reduce it to the appropriate combination of CheckStructure,
     1645        // [Re]AllocatePropertyStorage, PutStructure, and PutByOffset.
     1646        // https://bugs.webkit.org/show_bug.cgi?id=133229
     1647        if (Structure* structure = value.m_structure.onlyStructure()) {
     1648            bool done = false;
     1649            for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
     1650                const PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
     1651                if (variant.oldStructure() != structure)
     1652                    continue;
     1653               
     1654                if (variant.kind() == PutByIdVariant::Replace) {
     1655                    filter(node->child1(), structure);
     1656                    m_state.setFoundConstants(true);
     1657                    done = true;
     1658                    break;
     1659                }
     1660               
     1661                ASSERT(variant.kind() == PutByIdVariant::Transition);
     1662                clobberStructures(clobberLimit);
     1663                forNode(node->child1()).set(m_graph, variant.newStructure());
     1664                m_state.setFoundConstants(true);
     1665                done = true;
     1666                break;
     1667            }
     1668            if (done)
     1669                break;
     1670        }
     1671       
     1672        StructureSet oldSet;
    16471673        StructureSet newSet;
    16481674        TransitionVector transitions;
    1649        
    1650         // Ordinarily you have to be careful with calling setFoundConstants()
    1651         // because of the effect on compile times, but this node is FTL-only.
    1652         m_state.setFoundConstants(true);
    1653        
    1654         AbstractValue base = forNode(node->child1());
    1655        
    16561675        for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
    16571676            const PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
    1658             StructureSet thisSet = variant.oldStructure();
    1659             thisSet.filter(base);
    1660             if (thisSet.isEmpty())
    1661                 continue;
     1677            oldSet.add(variant.oldStructure());
    16621678            if (variant.kind() == PutByIdVariant::Transition) {
    1663                 if (thisSet.onlyStructure() != variant.newStructure()) {
    1664                     transitions.append(
    1665                         Transition(variant.oldStructureForTransition(), variant.newStructure()));
    1666                 } // else this is really a replace.
     1679                transitions.append(Transition(variant.oldStructure(), variant.newStructure()));
    16671680                newSet.add(variant.newStructure());
    16681681            } else {
    16691682                ASSERT(variant.kind() == PutByIdVariant::Replace);
    1670                 newSet.merge(thisSet);
    1671             }
    1672         }
    1673        
     1683                newSet.add(variant.oldStructure());
     1684            }
     1685        }
     1686       
     1687        filter(node->child1(), oldSet);
    16741688        observeTransitions(clobberLimit, transitions);
    1675         if (forNode(node->child1()).changeStructure(m_graph, newSet) == Contradiction)
    1676             m_state.setIsValid(false);
     1689        forNode(node->child1()).set(m_graph, newSet);
    16771690        break;
    16781691    }
     
    17031716    case PutById:
    17041717    case PutByIdFlush:
    1705     case PutByIdDirect: {
    1706         AbstractValue& value = forNode(node->child1());
    1707         if (!value.m_structure.isTop() && !value.m_structure.isClobbered()) {
     1718    case PutByIdDirect:
     1719        // This use of onlyStructure() should be replaced by giving PutByIdStatus the ability
     1720        // to compute things based on a StructureSet, and then to factor ByteCodeParser's
     1721        // ability to generate code based on a PutByIdStatus out of ByteCodeParser so that
     1722        // ConstantFoldingPhase can use it.
     1723        // https://bugs.webkit.org/show_bug.cgi?id=133229
     1724        if (Structure* structure = forNode(node->child1()).m_structure.onlyStructure()) {
    17081725            PutByIdStatus status = PutByIdStatus::computeFor(
    17091726                m_graph.m_vm,
    17101727                m_graph.globalObjectFor(node->origin.semantic),
    1711                 value.m_structure.set(),
     1728                structure,
    17121729                m_graph.identifiers()[node->identifierNumber()],
    17131730                node->op() == PutByIdDirect);
    1714            
    1715             if (status.isSimple()) {
    1716                 StructureSet newSet;
    1717                 TransitionVector transitions;
    1718                
    1719                 for (unsigned i = status.numVariants(); i--;) {
    1720                     const PutByIdVariant& variant = status[i];
    1721                     if (variant.kind() == PutByIdVariant::Transition) {
    1722                         transitions.append(
    1723                             Transition(
    1724                                 variant.oldStructureForTransition(), variant.newStructure()));
    1725                         m_graph.watchpoints().consider(variant.newStructure());
    1726                         newSet.add(variant.newStructure());
    1727                     } else {
    1728                         ASSERT(variant.kind() == PutByIdVariant::Replace);
    1729                         newSet.merge(variant.oldStructure());
    1730                     }
    1731                 }
    1732                
    1733                 if (status.numVariants() == 1 || isFTL(m_graph.m_plan.mode))
     1731            if (status.isSimple() && status.numVariants() == 1) {
     1732                if (status[0].kind() == PutByIdVariant::Replace) {
     1733                    filter(node->child1(), structure);
    17341734                    m_state.setFoundConstants(true);
    1735                
    1736                 observeTransitions(clobberLimit, transitions);
    1737                 if (forNode(node->child1()).changeStructure(m_graph, newSet) == Contradiction)
    1738                     m_state.setIsValid(false);
    1739                 break;
    1740             }
    1741         }
    1742        
     1735                    break;
     1736                }
     1737                if (status[0].kind() == PutByIdVariant::Transition
     1738                    && structure->transitionWatchpointSetHasBeenInvalidated()) {
     1739                    m_graph.watchpoints().consider(status[0].newStructure());
     1740                    clobberStructures(clobberLimit);
     1741                    forNode(node->child1()).set(m_graph, status[0].newStructure());
     1742                    m_state.setFoundConstants(true);
     1743                    break;
     1744                }
     1745            }
     1746        }
    17431747        clobberWorld(node->origin.semantic, clobberLimit);
    17441748        break;
    1745     }
    17461749       
    17471750    case In:
     
    19461949    AbstractValue::TransitionObserver transitionObserver(from, to);
    19471950    forAllValues(clobberLimit, transitionObserver);
    1948    
    1949     ASSERT(!from->dfgShouldWatch()); // We don't need to claim to be in a clobbered state because 'from' was never watchable (during the time we were compiling), hence no constants ever introduced into the DFG IR that ever had a watchable structure would ever have the same structure as from.
     1951    setDidClobber();
    19501952}
    19511953
     
    19561958    AbstractValue::TransitionsObserver transitionsObserver(vector);
    19571959    forAllValues(clobberLimit, transitionsObserver);
    1958    
    1959     if (!ASSERT_DISABLED) {
    1960         // We don't need to claim to be in a clobbered state because none of the Transition::previous structures are watchable.
    1961         for (unsigned i = vector.size(); i--;)
    1962             ASSERT(!vector[i].previous->dfgShouldWatch());
    1963     }
     1960    setDidClobber();
    19641961}
    19651962
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp

    r171641 r171648  
    192192}
    193193
    194 FiltrationResult AbstractValue::changeStructure(Graph& graph, const StructureSet& other)
    195 {
    196     m_type &= other.speculationFromStructures();
    197     m_arrayModes = other.arrayModesFromStructures();
    198     m_structure = other;
    199    
    200     filterValueByType();
    201    
    202     return normalizeClarity(graph);
    203 }
    204 
    205194FiltrationResult AbstractValue::filterArrayModes(ArrayModes arrayModes)
    206195{
     
    253242}
    254243
    255 bool AbstractValue::contains(Structure* structure) const
    256 {
    257     return couldBeType(speculationFromStructure(structure))
    258         && (m_arrayModes & arrayModeFromStructure(structure))
    259         && m_structure.contains(structure);
    260 }
    261 
    262244FiltrationResult AbstractValue::filter(const AbstractValue& other)
    263245{
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h

    r171641 r171648  
    268268    }
    269269   
    270     bool couldBeType(SpeculatedType desiredType) const
     270    bool couldBeType(SpeculatedType desiredType)
    271271    {
    272272        return !!(m_type & desiredType);
    273273    }
    274274   
    275     bool isType(SpeculatedType desiredType) const
     275    bool isType(SpeculatedType desiredType)
    276276    {
    277277        return !(m_type & ~desiredType);
     
    283283    FiltrationResult filterByValue(const FrozenValue& value);
    284284    FiltrationResult filter(const AbstractValue&);
    285    
    286     FiltrationResult changeStructure(Graph&, const StructureSet&);
    287    
    288     bool contains(Structure*) const;
    289285   
    290286    bool validate(JSValue value) const
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r171641 r171648  
    18921892    emitChecks(variant.constantChecks());
    18931893
    1894     ASSERT(variant.oldStructureForTransition()->transitionWatchpointSetHasBeenInvalidated());
     1894    ASSERT(variant.oldStructure()->transitionWatchpointSetHasBeenInvalidated());
    18951895   
    18961896    Node* propertyStorage;
    18971897    Transition* transition = m_graph.m_transitions.add(
    1898         variant.oldStructureForTransition(), variant.newStructure());
    1899 
    1900     if (variant.reallocatesStorage()) {
     1898        variant.oldStructure(), variant.newStructure());
     1899
     1900    if (variant.oldStructure()->outOfLineCapacity()
     1901        != variant.newStructure()->outOfLineCapacity()) {
    19011902
    19021903        // If we're growing the property storage then it must be because we're
     
    19041905        ASSERT(!isInlineOffset(variant.offset()));
    19051906
    1906         if (!variant.oldStructureForTransition()->outOfLineCapacity()) {
     1907        if (!variant.oldStructure()->outOfLineCapacity()) {
    19071908            propertyStorage = addToGraph(
    19081909                AllocatePropertyStorage, OpInfo(transition), base);
     
    20362037            if (op1->op() != ToThis) {
    20372038                Structure* cachedStructure = currentInstruction[2].u.structure.get();
    2038                 if (currentInstruction[2].u.toThisStatus != ToThisOK
    2039                     || !cachedStructure
     2039                if (!cachedStructure
    20402040                    || cachedStructure->classInfo()->methodTable.toThis != JSObject::info()->methodTable.toThis
    20412041                    || m_inlineStackTop->m_profiledBlock->couldTakeSlowCase(m_currentIndex)
     
    28872887                SpeculatedType prediction = getPrediction();
    28882888                GetByIdStatus status = GetByIdStatus::computeFor(*m_vm, structure, uid);
    2889                 if (status.state() != GetByIdStatus::Simple
    2890                     || status.numVariants() != 1
    2891                     || status[0].structureSet().size() != 1) {
     2889                if (status.state() != GetByIdStatus::Simple || status.numVariants() != 1) {
    28922890                    set(VirtualRegister(dst), addToGraph(GetByIdFlush, OpInfo(identifierNumber), OpInfo(prediction), get(VirtualRegister(scope))));
    28932891                    break;
     
    29742972            case GlobalPropertyWithVarInjectionChecks: {
    29752973                PutByIdStatus status = PutByIdStatus::computeFor(*m_vm, globalObject, structure, uid, false);
    2976                 if (status.numVariants() != 1
    2977                     || status[0].kind() != PutByIdVariant::Replace
    2978                     || status[0].structure().size() != 1) {
     2974                if (status.numVariants() != 1 || status[0].kind() != PutByIdVariant::Replace) {
    29792975                    addToGraph(PutById, OpInfo(identifierNumber), get(VirtualRegister(scope)), get(VirtualRegister(value)));
    29802976                    break;
    29812977                }
    2982                 ASSERT(status[0].structure().onlyStructure() == structure);
    2983                 Node* base = cellConstantWithStructureCheck(globalObject, structure);
     2978                Node* base = cellConstantWithStructureCheck(globalObject, status[0].structure());
    29842979                addToGraph(Phantom, get(VirtualRegister(scope)));
    29852980                handlePutByOffset(base, identifierNumber, static_cast<PropertyOffset>(operand), get(VirtualRegister(value)));
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r171641 r171648  
    441441       
    442442    case PutStructure:
     443    case PhantomPutStructure:
    443444        write(JSCell_structureID);
    444445        write(JSCell_typeInfoType);
  • trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp

    r171641 r171648  
    133133            }
    134134               
    135             case PutStructure: {
    136                 if (m_state.forNode(node->child1()).m_structure.onlyStructure() != node->transition()->next)
    137                     break;
    138                
    139                 node->convertToPhantom();
    140                 eliminated = true;
    141                 break;
    142             }
    143                
    144135            case CheckFunction: {
    145136                if (m_state.forNode(node->child1()).value() != node->function()->value())
     
    164155               
    165156            case MultiGetByOffset: {
    166                 Edge baseEdge = node->child1();
    167                 Node* base = baseEdge.node();
     157                Edge childEdge = node->child1();
     158                Node* child = childEdge.node();
    168159                MultiGetByOffsetData& data = node->multiGetByOffsetData();
    169160
    170                 // First prune the variants, then check if the MultiGetByOffset can be
    171                 // strength-reduced to a GetByOffset.
    172                
    173                 AbstractValue baseValue = m_state.forNode(base);
    174                
    175                 m_interpreter.execute(indexInBlock); // Push CFA over this node after we get the state before.
    176                 eliminated = true; // Don't allow the default constant folder to do things to this.
    177                
    178                 for (unsigned i = 0; i < data.variants.size(); ++i) {
    179                     GetByIdVariant& variant = data.variants[i];
    180                     variant.structureSet().filter(baseValue);
    181                     if (variant.structureSet().isEmpty()) {
    182                         data.variants[i--] = data.variants.last();
    183                         data.variants.removeLast();
    184                     }
     161                Structure* structure = m_state.forNode(child).m_structure.onlyStructure();
     162                if (!structure)
     163                    break;
     164               
     165                for (unsigned i = data.variants.size(); i--;) {
     166                    const GetByIdVariant& variant = data.variants[i];
     167                    if (!variant.structureSet().contains(structure))
     168                        continue;
     169                   
     170                    if (variant.alternateBase())
     171                        break;
     172                   
     173                    emitGetByOffset(indexInBlock, node, structure, variant, data.identifierNumber);
     174                    eliminated = true;
     175                    break;
    185176                }
    186                
    187                 if (data.variants.size() != 1)
    188                     break;
    189                
    190                 emitGetByOffset(
    191                     indexInBlock, node, baseValue, data.variants[0], data.identifierNumber);
    192177                break;
    193178            }
    194179               
    195180            case MultiPutByOffset: {
    196                 Edge baseEdge = node->child1();
    197                 Node* base = baseEdge.node();
     181                Edge childEdge = node->child1();
     182                Node* child = childEdge.node();
    198183                MultiPutByOffsetData& data = node->multiPutByOffsetData();
    199                
    200                 AbstractValue baseValue = m_state.forNode(base);
    201 
    202                 m_interpreter.execute(indexInBlock); // Push CFA over this node after we get the state before.
    203                 eliminated = true; // Don't allow the default constant folder to do things to this.
    204                
    205 
    206                 for (unsigned i = 0; i < data.variants.size(); ++i) {
    207                     PutByIdVariant& variant = data.variants[i];
    208                     variant.oldStructure().filter(baseValue);
     184
     185                Structure* structure = m_state.forNode(child).m_structure.onlyStructure();
     186                if (!structure)
     187                    break;
     188               
     189                for (unsigned i = data.variants.size(); i--;) {
     190                    const PutByIdVariant& variant = data.variants[i];
     191                    if (variant.oldStructure() != structure)
     192                        continue;
    209193                   
    210                     if (variant.oldStructure().isEmpty()) {
    211                         data.variants[i--] = data.variants.last();
    212                         data.variants.removeLast();
    213                         continue;
    214                     }
    215                    
    216                     if (variant.kind() == PutByIdVariant::Transition
    217                         && variant.oldStructure().onlyStructure() == variant.newStructure()) {
    218                         variant = PutByIdVariant::replace(
    219                             variant.oldStructure(),
    220                             variant.offset());
    221                     }
     194                    emitPutByOffset(indexInBlock, node, structure, variant, data.identifierNumber);
     195                    eliminated = true;
     196                    break;
    222197                }
    223 
    224                 if (data.variants.size() != 1)
    225                     break;
    226                
    227                 emitPutByOffset(
    228                     indexInBlock, node, baseValue, data.variants[0], data.identifierNumber);
    229198                break;
    230199            }
     
    236205                unsigned identifierNumber = node->identifierNumber();
    237206               
    238                 AbstractValue baseValue = m_state.forNode(child);
    239 
    240                 m_interpreter.execute(indexInBlock); // Push CFA over this node after we get the state before.
    241                 eliminated = true; // Don't allow the default constant folder to do things to this.
    242 
    243                 if (baseValue.m_structure.isTop() || baseValue.m_structure.isClobbered()
    244                     || (node->child1().useKind() == UntypedUse || (baseValue.m_type & ~SpecCell)))
    245                     break;
    246                
     207                if (childEdge.useKind() != CellUse)
     208                    break;
     209               
     210                Structure* structure = m_state.forNode(child).m_structure.onlyStructure();
     211                if (!structure)
     212                    break;
     213
    247214                GetByIdStatus status = GetByIdStatus::computeFor(
    248                     vm(), baseValue.m_structure.set(), m_graph.identifiers()[identifierNumber]);
    249                 if (!status.isSimple())
    250                     break;
    251                
    252                 for (unsigned i = status.numVariants(); i--;) {
    253                     if (!status[i].constantChecks().isEmpty()
    254                         || status[i].alternateBase()) {
    255                         // FIXME: We could handle prototype cases.
    256                         // https://bugs.webkit.org/show_bug.cgi?id=110386
    257                         break;
    258                     }
     215                    vm(), structure, m_graph.identifiers()[identifierNumber]);
     216               
     217                if (!status.isSimple() || status.numVariants() != 1 ||
     218                    !status[0].constantChecks().isEmpty() || status[0].alternateBase()) {
     219                    // FIXME: We could handle prototype cases.
     220                    // https://bugs.webkit.org/show_bug.cgi?id=110386
     221                    break;
    259222                }
    260223               
    261                 if (status.numVariants() == 1) {
    262                     emitGetByOffset(indexInBlock, node, baseValue, status[0], identifierNumber);
    263                     break;
    264                 }
    265                
    266                 if (!isFTL(m_graph.m_plan.mode))
    267                     break;
    268                
    269                 MultiGetByOffsetData* data = m_graph.m_multiGetByOffsetData.add();
    270                 data->variants = status.variants();
    271                 data->identifierNumber = identifierNumber;
    272                 node->convertToMultiGetByOffset(data);
     224                emitGetByOffset(indexInBlock, node, structure, status[0], identifierNumber);
     225                eliminated = true;
    273226                break;
    274227            }
    275228               
    276229            case PutById:
    277             case PutByIdDirect:
    278             case PutByIdFlush: {
     230            case PutByIdDirect: {
    279231                NodeOrigin origin = node->origin;
    280232                Edge childEdge = node->child1();
     
    284236                ASSERT(childEdge.useKind() == CellUse);
    285237               
    286                 AbstractValue baseValue = m_state.forNode(child);
    287 
    288                 m_interpreter.execute(indexInBlock); // Push CFA over this node after we get the state before.
    289                 eliminated = true; // Don't allow the default constant folder to do things to this.
    290 
    291                 if (baseValue.m_structure.isTop() || baseValue.m_structure.isClobbered())
     238                Structure* structure = m_state.forNode(child).m_structure.onlyStructure();
     239                if (!structure)
    292240                    break;
    293241               
     
    295243                    vm(),
    296244                    m_graph.globalObjectFor(origin.semantic),
    297                     baseValue.m_structure.set(),
     245                    structure,
    298246                    m_graph.identifiers()[identifierNumber],
    299247                    node->op() == PutByIdDirect);
     
    301249                if (!status.isSimple())
    302250                    break;
    303                
    304                 for (unsigned i = status.numVariants(); i--;)
    305                     addChecks(origin, indexInBlock, status[i].constantChecks());
    306                
    307                 if (status.numVariants() == 1) {
    308                     emitPutByOffset(indexInBlock, node, baseValue, status[0], identifierNumber);
    309                     break;
    310                 }
    311                
    312                 if (!isFTL(m_graph.m_plan.mode))
    313                     break;
    314 
    315                 MultiPutByOffsetData* data = m_graph.m_multiPutByOffsetData.add();
    316                 data->variants = status.variants();
    317                 data->identifierNumber = identifierNumber;
    318                 node->convertToMultiPutByOffset(data);
     251                if (status.numVariants() != 1)
     252                    break;
     253               
     254                emitPutByOffset(indexInBlock, node, structure, status[0], identifierNumber);
     255                eliminated = true;
    319256                break;
    320257            }
     
    407344    }
    408345       
    409     void emitGetByOffset(unsigned indexInBlock, Node* node, const AbstractValue& baseValue, const GetByIdVariant& variant, unsigned identifierNumber)
     346    void emitGetByOffset(unsigned indexInBlock, Node* node, Structure* structure, const GetByIdVariant& variant, unsigned identifierNumber)
    410347    {
    411348        NodeOrigin origin = node->origin;
     
    413350        Node* child = childEdge.node();
    414351
    415         addBaseCheck(indexInBlock, node, baseValue, variant.structureSet());
     352        bool needsCellCheck = m_state.forNode(child).m_type & ~SpecCell;
     353       
     354        ASSERT(!variant.alternateBase());
     355        ASSERT_UNUSED(structure, variant.structureSet().contains(structure));
     356       
     357        // Now before we do anything else, push the CFA forward over the GetById
     358        // and make sure we signal to the loop that it should continue and not
     359        // do any eliminations.
     360        m_interpreter.execute(indexInBlock);
     361       
     362        if (needsCellCheck) {
     363            m_insertionSet.insertNode(
     364                indexInBlock, SpecNone, Phantom, origin, childEdge);
     365        }
    416366       
    417367        if (variant.specificValue()) {
     
    420370        }
    421371       
    422         if (variant.alternateBase()) {
    423             child = m_insertionSet.insertConstant(indexInBlock, origin, variant.alternateBase());
    424             childEdge = Edge(child, KnownCellUse);
    425         } else
    426             childEdge.setUseKind(KnownCellUse);
     372        childEdge.setUseKind(KnownCellUse);
    427373       
    428374        Edge propertyStorage;
     
    443389    }
    444390
    445     void emitPutByOffset(unsigned indexInBlock, Node* node, const AbstractValue& baseValue, const PutByIdVariant& variant, unsigned identifierNumber)
     391    void emitPutByOffset(unsigned indexInBlock, Node* node, Structure* structure, const PutByIdVariant& variant, unsigned identifierNumber)
    446392    {
    447393        NodeOrigin origin = node->origin;
    448394        Edge childEdge = node->child1();
    449        
    450         addBaseCheck(indexInBlock, node, baseValue, variant.oldStructure());
     395        Node* child = childEdge.node();
     396
     397        ASSERT(variant.oldStructure() == structure);
     398       
     399        bool needsCellCheck = m_state.forNode(child).m_type & ~SpecCell;
     400       
     401        // Now before we do anything else, push the CFA forward over the PutById
     402        // and make sure we signal to the loop that it should continue and not
     403        // do any eliminations.
     404        m_interpreter.execute(indexInBlock);
     405
     406        if (needsCellCheck) {
     407            m_insertionSet.insertNode(
     408                indexInBlock, SpecNone, Phantom, origin, childEdge);
     409        }
    451410
    452411        childEdge.setUseKind(KnownCellUse);
     
    454413        Transition* transition = 0;
    455414        if (variant.kind() == PutByIdVariant::Transition) {
    456             transition = m_graph.m_transitions.add(
    457                 variant.oldStructureForTransition(), variant.newStructure());
     415            transition = m_graph.m_transitions.add(structure, variant.newStructure());
     416
     417            for (unsigned i = 0; i < variant.constantChecks().size(); ++i) {
     418                addStructureTransitionCheck(
     419                    origin, indexInBlock,
     420                    variant.constantChecks()[i].constant(),
     421                    variant.constantChecks()[i].structure());
     422            }
    458423        }
    459424
     
    462427        if (isInlineOffset(variant.offset()))
    463428            propertyStorage = childEdge;
    464         else if (!variant.reallocatesStorage()) {
     429        else if (
     430            variant.kind() == PutByIdVariant::Replace
     431            || structure->outOfLineCapacity() == variant.newStructure()->outOfLineCapacity()) {
    465432            propertyStorage = Edge(m_insertionSet.insertNode(
    466433                indexInBlock, SpecNone, GetButterfly, origin, childEdge));
    467         } else if (!variant.oldStructureForTransition()->outOfLineCapacity()) {
     434        } else if (!structure->outOfLineCapacity()) {
    468435            ASSERT(variant.newStructure()->outOfLineCapacity());
    469436            ASSERT(!isInlineOffset(variant.offset()));
     
    474441            propertyStorage = Edge(allocatePropertyStorage);
    475442        } else {
    476             ASSERT(variant.oldStructureForTransition()->outOfLineCapacity());
    477             ASSERT(variant.newStructure()->outOfLineCapacity() > variant.oldStructureForTransition()->outOfLineCapacity());
     443            ASSERT(structure->outOfLineCapacity());
     444            ASSERT(variant.newStructure()->outOfLineCapacity() > structure->outOfLineCapacity());
    478445            ASSERT(!isInlineOffset(variant.offset()));
    479446
     
    503470        m_graph.m_storageAccessData.append(storageAccessData);
    504471    }
    505    
    506     void addBaseCheck(
    507         unsigned indexInBlock, Node* node, const AbstractValue& baseValue, const StructureSet& set)
    508     {
    509         if (!baseValue.m_structure.isSubsetOf(set)) {
    510             // Arises when we prune MultiGetByOffset. We could have a
    511             // MultiGetByOffset with a single variant that checks for structure S,
    512             // and the input has structures S and T, for example.
    513             m_insertionSet.insertNode(
    514                 indexInBlock, SpecNone, CheckStructure, node->origin,
    515                 OpInfo(m_graph.addStructureSet(set)), node->child1());
    516             return;
    517         }
    518        
    519         if (baseValue.m_type & ~SpecCell) {
    520             m_insertionSet.insertNode(
    521                 indexInBlock, SpecNone, Phantom, node->origin, node->child1());
    522         }
    523     }
    524    
    525     void addChecks(
    526         NodeOrigin origin, unsigned indexInBlock, const ConstantStructureCheckVector& checks)
    527     {
    528         for (unsigned i = 0; i < checks.size(); ++i) {
    529             addStructureTransitionCheck(
    530                 origin, indexInBlock, checks[i].constant(), checks[i].structure());
    531         }
    532     }
    533472
    534473    void addStructureTransitionCheck(NodeOrigin origin, unsigned indexInBlock, JSCell* cell, Structure* structure)
  • trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp

    r171641 r171648  
    187187    case PutByValAlias:
    188188    case PutStructure:
     189    case PhantomPutStructure:
    189190    case GetByOffset:
    190191    case GetGetterSetterByOffset:
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r171641 r171648  
    981981        case Upsilon:
    982982        case GetArgument:
     983        case PhantomPutStructure:
    983984        case GetIndexedPropertyStorage:
    984985        case GetTypedArrayByteOffset:
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp

    r171641 r171648  
    890890               
    891891            case PutStructure:
     892            case PhantomPutStructure:
    892893            case AllocatePropertyStorage:
    893894            case ReallocatePropertyStorage:
     
    917918                for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
    918919                    PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
    919                     const StructureSet& set = variant.oldStructure();
    920                     for (unsigned j = set.size(); j--;)
    921                         visitor.appendUnbarrieredReadOnlyPointer(set[j]);
     920                    visitor.appendUnbarrieredReadOnlyPointer(variant.oldStructure());
    922921                    if (variant.kind() == PutByIdVariant::Transition)
    923922                        visitor.appendUnbarrieredReadOnlyPointer(variant.newStructure());
     
    953952FrozenValue* Graph::freezeStrong(JSValue value)
    954953{
    955     FrozenValue* result = freezeFragile(value);
     954    FrozenValue* result = freeze(value);
    956955    result->strengthenTo(StrongValue);
    957956    return result;
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.h

    r171641 r171648  
    148148   
    149149    FrozenValue* freezeFragile(JSValue value);
    150     FrozenValue* freeze(JSValue value); // We use weak freezing by default. Shorthand for freezeFragile(value)->strengthenTo(WeakValue);
    151     FrozenValue* freezeStrong(JSValue value); // Shorthand for freezeFragile(value)->strengthenTo(StrongValue).
     150    FrozenValue* freeze(JSValue value); // We use weak freezing by default.
     151    FrozenValue* freezeStrong(JSValue value); // Shorthand for freeze(value)->markStrongly().
    152152   
    153153    void convertToConstant(Node* node, FrozenValue* value);
  • trunk/Source/JavaScriptCore/dfg/DFGNode.cpp

    r171641 r171648  
    3838{
    3939    for (unsigned i = variants.size(); i--;) {
    40         if (variants[i].writesStructures())
     40        if (variants[i].kind() == PutByIdVariant::Transition)
    4141            return true;
    4242    }
     
    4747{
    4848    for (unsigned i = variants.size(); i--;) {
    49         if (variants[i].reallocatesStorage())
    50             return true;
     49        if (variants[i].kind() != PutByIdVariant::Transition)
     50            continue;
     51       
     52        if (variants[i].oldStructure()->outOfLineCapacity() ==
     53            variants[i].newStructure()->outOfLineCapacity())
     54            continue;
     55       
     56        return true;
    5157    }
    5258    return false;
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r171641 r171648  
    459459    }
    460460   
    461     void convertToMultiGetByOffset(MultiGetByOffsetData* data)
    462     {
    463         ASSERT(m_op == GetById || m_op == GetByIdFlush);
    464         m_opInfo = bitwise_cast<intptr_t>(data);
    465         child1().setUseKind(CellUse);
    466         m_op = MultiGetByOffset;
    467         m_flags &= ~NodeClobbersWorld;
    468     }
    469    
    470461    void convertToPutByOffset(unsigned storageAccessDataIndex, Edge storage)
    471462    {
    472         ASSERT(m_op == PutById || m_op == PutByIdDirect || m_op == PutByIdFlush || m_op == MultiPutByOffset);
     463        ASSERT(m_op == PutById || m_op == PutByIdDirect || m_op == MultiPutByOffset);
    473464        m_opInfo = storageAccessDataIndex;
    474465        children.setChild3(children.child2());
     
    476467        children.setChild1(storage);
    477468        m_op = PutByOffset;
    478         m_flags &= ~NodeClobbersWorld;
    479     }
    480    
    481     void convertToMultiPutByOffset(MultiPutByOffsetData* data)
    482     {
    483         ASSERT(m_op == PutById || m_op == PutByIdDirect || m_op == PutByIdFlush);
    484         m_opInfo = bitwise_cast<intptr_t>(data);
    485         m_op = MultiPutByOffset;
    486469        m_flags &= ~NodeClobbersWorld;
    487470    }
     
    11251108        switch (op()) {
    11261109        case PutStructure:
     1110        case PhantomPutStructure:
    11271111        case AllocatePropertyStorage:
    11281112        case ReallocatePropertyStorage:
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r171641 r171648  
    156156    macro(CheckExecutable, NodeMustGenerate) \
    157157    macro(PutStructure, NodeMustGenerate) \
     158    macro(PhantomPutStructure, NodeMustGenerate) \
    158159    macro(AllocatePropertyStorage, NodeMustGenerate | NodeResultStorage) \
    159160    macro(ReallocatePropertyStorage, NodeMustGenerate | NodeResultStorage) \
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r171641 r171648  
    541541        case GetMyArgumentsLength:
    542542        case GetMyArgumentByVal:
     543        case PhantomPutStructure:
    543544        case PhantomArguments:
    544545        case CheckArray:
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r171641 r171648  
    284284
    285285    case PutStructure:
     286    case PhantomPutStructure:
    286287    case AllocatePropertyStorage:
    287288    case ReallocatePropertyStorage:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r171613 r171648  
    344344        ASSERT(info.gpr() == source);
    345345        if (node->hasConstant()) {
     346            DFG_ASSERT(m_jit.graph(), m_currentNode, node->isCellConstant());
    346347            node->asCell(); // To get the assertion.
    347348            fillAction = SetCellConstant;
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r171641 r171648  
    868868    VirtualRegister virtualRegister = edge->virtualRegister();
    869869    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
     870   
     871    if (edge->hasConstant() && !edge->isCellConstant()) {
     872        // Protect the silent spill/fill logic by failing early. If we "speculate" on
     873        // the constant then the silent filler may think that we have a cell and a
     874        // constant, so it will try to fill this as an cell constant. Bad things will
     875        // happen.
     876        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
     877        return allocate();
     878    }
    870879
    871880    switch (info.registerFormat()) {
     
    879888            JSValue jsValue = edge->asJSValue();
    880889            GPRReg gpr = allocate();
    881             if (jsValue.isCell()) {
    882                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
    883                 m_jit.move(MacroAssembler::TrustedImmPtr(jsValue.asCell()), gpr);
    884                 info.fillCell(*m_stream, gpr);
    885                 return gpr;
    886             }
    887             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
     890            m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
     891            m_jit.move(MacroAssembler::TrustedImmPtr(jsValue.asCell()), gpr);
     892            info.fillCell(*m_stream, gpr);
    888893            return gpr;
    889894        }
     
    37353740    }
    37363741       
     3742    case PhantomPutStructure: {
     3743        ASSERT(isKnownCell(node->child1().node()));
     3744        m_jit.jitCode()->common.notifyCompilingStructureTransition(m_jit.graph().m_plan, m_jit.codeBlock(), node);
     3745        noResult(node);
     3746        break;
     3747    }
     3748
    37373749    case PutStructure: {
    37383750        Structure* oldStructure = node->transition()->previous;
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r171641 r171648  
    9898            default:
    9999                m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
    100                 DFG_ASSERT(m_jit.graph(), m_currentNode, spillFormat & DataFormatJS);
     100                RELEASE_ASSERT(spillFormat & DataFormatJS);
    101101                break;
    102102            }
     
    138138    case DataFormatInt52:
    139139        // this type currently never occurs
    140         DFG_CRASH(m_jit.graph(), m_currentNode, "Bad data format");
     140        RELEASE_ASSERT_NOT_REACHED();
    141141       
    142142    default:
    143         DFG_CRASH(m_jit.graph(), m_currentNode, "Corrupt data format");
     143        RELEASE_ASSERT_NOT_REACHED();
    144144        return InvalidGPRReg;
    145145    }
     
    312312        Node* branchNode = m_block->at(branchIndexInBlock);
    313313
    314         DFG_ASSERT(m_jit.graph(), node, node->adjustedRefCount() == 1);
     314        RELEASE_ASSERT(node->adjustedRefCount() == 1);
    315315       
    316316        nonSpeculativePeepholeBranchNull(operand, branchNode, invert);
     
    629629    bool isCall = node->op() == Call;
    630630    if (!isCall)
    631         DFG_ASSERT(m_jit.graph(), node, node->op() == Construct);
    632    
     631        RELEASE_ASSERT(node->op() == Construct);
     632
    633633    // For constructors, the this argument is not passed but we have to make space
    634634    // for it.
     
    742742        DataFormat spillFormat = info.spillFormat();
    743743       
    744         DFG_ASSERT(m_jit.graph(), m_currentNode, (spillFormat & DataFormatJS) || spillFormat == DataFormatInt32);
     744        RELEASE_ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInt32);
    745745       
    746746        m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
     
    772772
    773773    case DataFormatJS: {
    774         DFG_ASSERT(m_jit.graph(), m_currentNode, !(type & SpecInt52));
     774        RELEASE_ASSERT(!(type & SpecInt52));
    775775        // Check the value is an integer.
    776776        GPRReg gpr = info.gpr();
     
    835835    case DataFormatInt52:
    836836    case DataFormatStrictInt52:
    837         DFG_CRASH(m_jit.graph(), m_currentNode, "Bad data format");
     837        RELEASE_ASSERT_NOT_REACHED();
    838838       
    839839    default:
    840         DFG_CRASH(m_jit.graph(), m_currentNode, "Corrupt data format");
     840        RELEASE_ASSERT_NOT_REACHED();
    841841        return InvalidGPRReg;
    842842    }
     
    855855    DataFormat mustBeDataFormatInt32;
    856856    GPRReg result = fillSpeculateInt32Internal<true>(edge, mustBeDataFormatInt32);
    857     DFG_ASSERT(m_jit.graph(), m_currentNode, mustBeDataFormatInt32 == DataFormatInt32);
     857    RELEASE_ASSERT(mustBeDataFormatInt32 == DataFormatInt32);
    858858    return result;
    859859}
     
    890890        DataFormat spillFormat = info.spillFormat();
    891891       
    892         DFG_ASSERT(m_jit.graph(), m_currentNode, spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52);
     892        RELEASE_ASSERT(spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52);
    893893       
    894894        m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
     
    942942
    943943    default:
    944         DFG_CRASH(m_jit.graph(), m_currentNode, "Bad data format");
     944        RELEASE_ASSERT_NOT_REACHED();
    945945        return InvalidGPRReg;
    946946    }
     
    973973       
    974974        DataFormat spillFormat = info.spillFormat();
    975         DFG_ASSERT(m_jit.graph(), m_currentNode, spillFormat == DataFormatDouble);
     975        RELEASE_ASSERT(spillFormat == DataFormatDouble);
    976976        FPRReg fpr = fprAllocate();
    977977        m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr);
     
    981981    }
    982982
    983     DFG_ASSERT(m_jit.graph(), m_currentNode, info.registerFormat() == DataFormatDouble);
     983    RELEASE_ASSERT(info.registerFormat() == DataFormatDouble);
    984984    FPRReg fpr = info.fpr();
    985985    m_fprs.lock(fpr);
     
    996996    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
    997997
     998    if (edge->hasConstant() && !edge->isCellConstant()) {
     999        // Better to fail early on constants.
     1000        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
     1001        return allocate();
     1002    }
     1003
    9981004    switch (info.registerFormat()) {
    9991005    case DataFormatNone: {
     
    10021008        if (edge->hasConstant()) {
    10031009            JSValue jsValue = edge->asJSValue();
    1004             if (jsValue.isCell()) {
    1005                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
    1006                 m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
    1007                 info.fillJSValue(*m_stream, gpr, DataFormatJSCell);
    1008                 return gpr;
    1009             }
    1010             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
     1010            m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
     1011            m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
     1012            info.fillJSValue(*m_stream, gpr, DataFormatJSCell);
    10111013            return gpr;
    10121014        }
     
    10611063    case DataFormatInt52:
    10621064    case DataFormatStrictInt52:
    1063         DFG_CRASH(m_jit.graph(), m_currentNode, "Bad data format");
     1065        RELEASE_ASSERT_NOT_REACHED();
    10641066       
    10651067    default:
    1066         DFG_CRASH(m_jit.graph(), m_currentNode, "Corrupt data format");
     1068        RELEASE_ASSERT_NOT_REACHED();
    10671069        return InvalidGPRReg;
    10681070    }
     
    10971099            return gpr;
    10981100        }
    1099         DFG_ASSERT(m_jit.graph(), m_currentNode, info.spillFormat() & DataFormatJS);
     1101        RELEASE_ASSERT(info.spillFormat() & DataFormatJS);
    11001102        m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
    11011103        m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
     
    11421144    case DataFormatInt52:
    11431145    case DataFormatStrictInt52:
    1144         DFG_CRASH(m_jit.graph(), m_currentNode, "Bad data format");
     1146        RELEASE_ASSERT_NOT_REACHED();
    11451147       
    11461148    default:
    1147         DFG_CRASH(m_jit.graph(), m_currentNode, "Corrupt data format");
     1149        RELEASE_ASSERT_NOT_REACHED();
    11481150        return InvalidGPRReg;
    11491151    }
     
    16091611
    16101612    default:
    1611         DFG_CRASH(m_jit.graph(), node, "Bad use kind");
     1613        RELEASE_ASSERT_NOT_REACHED();
    16121614        break;
    16131615    }
     
    17641766       
    17651767    default:
    1766         DFG_CRASH(m_jit.graph(), m_currentNode, "Bad use kind");
     1768        RELEASE_ASSERT_NOT_REACHED();
    17671769    }
    17681770}
     
    17891791    case Identity: {
    17901792        // CSE should always eliminate this.
    1791         DFG_CRASH(m_jit.graph(), node, "Unexpected Identity node");
     1793        RELEASE_ASSERT_NOT_REACHED();
    17921794        break;
    17931795    }
     
    18701872    case ZombieHint:
    18711873    case Check: {
    1872         DFG_CRASH(m_jit.graph(), node, "Unexpected node");
     1874        RELEASE_ASSERT_NOT_REACHED();
    18731875        break;
    18741876    }
     
    19301932           
    19311933        default:
    1932             DFG_CRASH(m_jit.graph(), node, "Bad flush format");
     1934            RELEASE_ASSERT_NOT_REACHED();
    19331935            break;
    19341936        }
     
    20682070           
    20692071        default:
    2070             DFG_CRASH(m_jit.graph(), node, "Bad use kind");
     2072            RELEASE_ASSERT_NOT_REACHED();
    20712073        }
    20722074        break;
     
    21482150           
    21492151        default:
    2150             DFG_CRASH(m_jit.graph(), node, "Bad use kind");
     2152            RELEASE_ASSERT_NOT_REACHED();
    21512153            break;
    21522154        }
     
    22152217           
    22162218        default:
    2217             DFG_CRASH(m_jit.graph(), node, "Bad use kind");
     2219            RELEASE_ASSERT_NOT_REACHED();
    22182220            break;
    22192221        }
     
    23372339        case Array::SelectUsingPredictions:
    23382340        case Array::ForceExit:
    2339             DFG_CRASH(m_jit.graph(), node, "Bad array mode type");
     2341            RELEASE_ASSERT_NOT_REACHED();
     2342            terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
    23402343            break;
    23412344        case Array::Generic: {
     
    25382541        case Array::SelectUsingPredictions:
    25392542        case Array::ForceExit:
    2540             DFG_CRASH(m_jit.graph(), node, "Bad array mode type");
     2543            RELEASE_ASSERT_NOT_REACHED();
     2544            terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
     2545            alreadyHandled = true;
    25412546            break;
    25422547        case Array::Generic: {
    2543             DFG_ASSERT(m_jit.graph(), node, node->op() == PutByVal);
     2548            RELEASE_ASSERT(node->op() == PutByVal);
    25442549           
    25452550            JSValueOperand arg1(this, child1);
     
    31143119           
    31153120        default:
    3116             DFG_CRASH(m_jit.graph(), node, "Bad use kind");
     3121            RELEASE_ASSERT_NOT_REACHED();
    31173122            break;
    31183123        }
     
    31213126       
    31223127    case ToPrimitive: {
    3123         DFG_ASSERT(m_jit.graph(), node, node->child1().useKind() == UntypedUse);
     3128        RELEASE_ASSERT(node->child1().useKind() == UntypedUse);
    31243129        JSValueOperand op1(this, node->child1());
    31253130        GPRTemporary result(this, Reuse, op1);
     
    31883193        if (!globalObject->isHavingABadTime() && !hasAnyArrayStorage(node->indexingType())) {
    31893194            Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType());
    3190             DFG_ASSERT(m_jit.graph(), node, structure->indexingType() == node->indexingType());
     3195            RELEASE_ASSERT(structure->indexingType() == node->indexingType());
    31913196            ASSERT(
    31923197                hasUndecided(structure->indexingType())
     
    34393444            emitAllocateJSArray(resultGPR, globalObject->arrayStructureForIndexingTypeDuringAllocation(indexingType), storageGPR, numElements);
    34403445           
    3441             DFG_ASSERT(m_jit.graph(), node, indexingType & IsArray);
     3446            RELEASE_ASSERT(indexingType & IsArray);
    34423447            JSValue* data = m_jit.codeBlock()->constantBuffer(node->startConstant());
    34433448            if (indexingType == ArrayWithDouble) {
     
    34933498        }
    34943499        default:
    3495             DFG_CRASH(m_jit.graph(), node, "Bad use kind");
     3500            RELEASE_ASSERT_NOT_REACHED();
    34963501            break;
    34973502        }
     
    37233728           
    37243729        default:
    3725             DFG_CRASH(m_jit.graph(), node, "Bad use kind");
     3730            RELEASE_ASSERT_NOT_REACHED();
    37263731            break;
    37273732        }
     
    37733778           
    37743779        default:
    3775             DFG_CRASH(m_jit.graph(), node, "Bad use kind");
     3780            RELEASE_ASSERT_NOT_REACHED();
    37763781            break;
    37773782        }
     
    38293834        }
    38303835       
     3836        noResult(node);
     3837        break;
     3838    }
     3839       
     3840    case PhantomPutStructure: {
     3841        ASSERT(isKnownCell(node->child1().node()));
     3842        m_jit.jitCode()->common.notifyCompilingStructureTransition(m_jit.graph().m_plan, m_jit.codeBlock(), node);
    38313843        noResult(node);
    38323844        break;
     
    42374249
    42384250    case CreateActivation: {
    4239         DFG_ASSERT(m_jit.graph(), node, !node->origin.semantic.inlineCallFrame);
     4251        RELEASE_ASSERT(!node->origin.semantic.inlineCallFrame);
    42404252       
    42414253        JSValueOperand value(this, node->child1());
     
    43104322
    43114323    case TearOffActivation: {
    4312         DFG_ASSERT(m_jit.graph(), node, !node->origin.semantic.inlineCallFrame);
     4324        RELEASE_ASSERT(!node->origin.semantic.inlineCallFrame);
    43134325
    43144326        JSValueOperand activationValue(this, node->child1());
     
    43824394        }
    43834395       
    4384         DFG_ASSERT(m_jit.graph(), node, !node->origin.semantic.inlineCallFrame);
     4396        RELEASE_ASSERT(!node->origin.semantic.inlineCallFrame);
    43854397        m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), resultGPR);
    43864398        m_jit.sub32(TrustedImm32(1), resultGPR);
     
    44584470        JITCompiler::JumpList slowArgumentOutOfBounds;
    44594471        if (m_jit.symbolTableFor(node->origin.semantic)->slowArguments()) {
    4460             DFG_ASSERT(m_jit.graph(), node, !node->origin.semantic.inlineCallFrame);
     4472            RELEASE_ASSERT(!node->origin.semantic.inlineCallFrame);
    44614473            const SlowArgument* slowArguments = m_jit.graph().m_slowArguments.get();
    44624474           
     
    45254537        JITCompiler::JumpList slowArgumentOutOfBounds;
    45264538        if (m_jit.symbolTableFor(node->origin.semantic)->slowArguments()) {
    4527             DFG_ASSERT(m_jit.graph(), node, !node->origin.semantic.inlineCallFrame);
     4539            RELEASE_ASSERT(!node->origin.semantic.inlineCallFrame);
    45284540            const SlowArgument* slowArguments = m_jit.graph().m_slowArguments.get();
    45294541
     
    46604672
    46614673    case Unreachable:
    4662         DFG_CRASH(m_jit.graph(), node, "Unexpected Unreachable node");
     4674        RELEASE_ASSERT_NOT_REACHED();
    46634675        break;
    46644676
     
    47284740    case CheckTierUpAtReturn:
    47294741    case CheckTierUpAndOSREnter:
    4730         DFG_CRASH(m_jit.graph(), node, "Unexpected tier-up node");
     4742        RELEASE_ASSERT_NOT_REACHED();
    47314743        break;
    47324744#endif // ENABLE(FTL_JIT)
     
    47444756    case MultiPutByOffset:
    47454757    case FiatInt52:
    4746         DFG_CRASH(m_jit.graph(), node, "Unexpected FTL node");
     4758        RELEASE_ASSERT_NOT_REACHED();
    47474759        break;
    47484760    }
  • trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.cpp

    r171641 r171648  
    8484{
    8585    SAMPLE("StructureAbstractValue observeTransition");
    86    
    87     ASSERT(!from->dfgShouldWatch());
    8886
    8987    if (isTop())
     
    9290    if (!m_set.contains(from))
    9391        return;
     92   
     93    if (from->dfgShouldWatch()) {
     94        setClobbered(true);
     95        return;
     96    }
    9497   
    9598    if (!m_set.add(to))
     
    109112    StructureSet newStructures;
    110113    for (unsigned i = vector.size(); i--;) {
    111         ASSERT(!vector[i].previous->dfgShouldWatch());
    112 
    113114        if (!m_set.contains(vector[i].previous))
    114115            continue;
    115116       
    116         newStructures.add(vector[i].next);
     117        if (vector[i].previous->dfgShouldWatch())
     118            setClobbered(true);
     119        else
     120            newStructures.add(vector[i].next);
    117121    }
    118122   
  • trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h

    r171641 r171648  
    5656    }
    5757   
    58     ALWAYS_INLINE StructureAbstractValue& operator=(Structure* structure)
    59     {
    60         m_set = structure;
    61         setClobbered(false);
    62         return *this;
    63     }
    64     ALWAYS_INLINE StructureAbstractValue& operator=(const StructureSet& other)
    65     {
    66         m_set = other;
    67         setClobbered(false);
    68         return *this;
    69     }
    7058    ALWAYS_INLINE StructureAbstractValue& operator=(const StructureAbstractValue& other)
    7159    {
     
    162150    }
    163151   
    164     const StructureSet& set() const
    165     {
    166         ASSERT(!isTop());
    167         return m_set;
    168     }
    169    
    170152    size_t size() const
    171153    {
     
    182164    Structure* operator[](size_t i) const { return at(i); }
    183165   
    184     // In most cases, what you really want to do is verify whether the set is top or clobbered, and
    185     // if not, enumerate the set of structures. Use this only in cases where the singleton case is
    186     // meaningfully special, like for transitions.
     166    // FIXME: Eliminate all uses of this method. There shouldn't be any
     167    // special-casing for the one-structure case.
     168    // https://bugs.webkit.org/show_bug.cgi?id=133229
    187169    Structure* onlyStructure() const
    188170    {
    189         if (isTop() || isClobbered())
     171        if (isTop() || size() != 1)
    190172            return nullptr;
    191         return m_set.onlyStructure();
     173        return at(0);
    192174    }
    193175   
  • trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp

    r171641 r171648  
    234234                    VALIDATE((node), !!node->child2());
    235235                    break;
    236                 case PutStructure:
    237                     VALIDATE((node), !node->transition()->previous->dfgShouldWatch());
    238                     break;
    239                 case MultiPutByOffset:
    240                     for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
    241                         const PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
    242                         if (variant.kind() != PutByIdVariant::Transition)
    243                             continue;
    244                         VALIDATE((node), !variant.oldStructureForTransition()->dfgShouldWatch());
    245                     }
    246                     break;
    247236                default:
    248237                    break;
  • trunk/Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp

    r171641 r171648  
    7878               
    7979                case PutStructure:
     80                case PhantomPutStructure:
    8081                case AllocatePropertyStorage:
    8182                case ReallocatePropertyStorage:
Note: See TracChangeset for help on using the changeset viewer.