Ignore:
Timestamp:
Jul 27, 2014, 4:14:40 PM (11 years ago)
Author:
[email protected]
Message:

Merge r170090, r170092, r170129, r170141, r170161, r170215, r170275, r170375, r170376, r170382, r170383, r170399, r170436, r170489, r170490, r170556 from ftlopt.

Source/JavaScriptCore:

This fixes the previous mismerge and adds test coverage for the thing that went wrong.

Additional changes listed here:

  • jsc.cpp:

(functionHasCustomProperties): Expose a way of checking hasCustomProperties(), which the DOM relies on. The regression I previously introduced was because this didn't work right. Now we can test it!

  • runtime/Structure.cpp:

(JSC::Structure::Structure): This was supposed to be setDidTransition(true); the last merge had it set to false.

  • tests/stress/has-custom-properties.js: Added. This test failed with the mismerge.

2014-06-27 Michael Saboff <[email protected]>


Unreviewed build fix after r169795.


Fixed ASSERT for 32 bit build.


  • dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):


2014-06-24 Saam Barati <[email protected]>


Web Inspector: debugger should be able to show variable types
https://bugs.webkit.org/show_bug.cgi?id=133395


Reviewed by Filip Pizlo.


Increase the amount of type information the VM gathers when directed
to do so. This initial commit is working towards the goal of
capturing, and then showing (via the Web Inspector) type information for all
assignment and load operations. This patch doesn't have the feature fully
implemented, but it ensures the VM has no performance regressions
unless the feature is specifically turned on.


  • 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):
  • bytecode/CodeBlock.h:
  • bytecode/Instruction.h:
  • bytecode/TypeLocation.h: Added. (JSC::TypeLocation::TypeLocation):
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitMove): (JSC::BytecodeGenerator::emitProfileTypesWithHighFidelity): (JSC::BytecodeGenerator::emitPutToScope): (JSC::BytecodeGenerator::emitPutById): (JSC::BytecodeGenerator::emitPutByVal):
  • bytecompiler/BytecodeGenerator.h: (JSC::BytecodeGenerator::isProfilingTypesWithHighFidelity):
  • bytecompiler/NodesCodegen.cpp: (JSC::PostfixNode::emitResolve): (JSC::PrefixNode::emitResolve): (JSC::ReadModifyResolveNode::emitBytecode): (JSC::AssignResolveNode::emitBytecode): (JSC::ConstDeclNode::emitCodeSingle): (JSC::ForInNode::emitBytecode):
  • heap/Heap.cpp: (JSC::Heap::collect):
  • inspector/agents/InspectorRuntimeAgent.cpp: (Inspector::InspectorRuntimeAgent::getRuntimeTypeForVariableInTextRange):
  • inspector/agents/InspectorRuntimeAgent.h:
  • inspector/protocol/Runtime.json:
  • jsc.cpp: (GlobalObject::finishCreation): (functionDumpTypesForAllVariables):
  • llint/LLIntSlowPaths.cpp: (JSC::LLInt::LLINT_SLOW_PATH_DECL): (JSC::LLInt::putToScopeCommon):
  • llint/LLIntSlowPaths.h:
  • llint/LowLevelInterpreter.asm:
  • runtime/HighFidelityLog.cpp: Added. (JSC::HighFidelityLog::initializeHighFidelityLog): (JSC::HighFidelityLog::~HighFidelityLog): (JSC::HighFidelityLog::recordTypeInformationForLocation): (JSC::HighFidelityLog::processHighFidelityLog): (JSC::HighFidelityLog::actuallyProcessLogThreadFunction):
  • runtime/HighFidelityLog.h: Added. (JSC::HighFidelityLog::HighFidelityLog):
  • runtime/HighFidelityTypeProfiler.cpp: Added. (JSC::HighFidelityTypeProfiler::getTypesForVariableInRange): (JSC::HighFidelityTypeProfiler::getGlobalTypesForVariableInRange): (JSC::HighFidelityTypeProfiler::getLocalTypesForVariableInRange): (JSC::HighFidelityTypeProfiler::insertNewLocation): (JSC::HighFidelityTypeProfiler::getLocationBasedHash):
  • runtime/HighFidelityTypeProfiler.h: Added.
  • runtime/Options.h:
  • runtime/Structure.cpp: (JSC::Structure::toStructureShape):
  • runtime/Structure.h:
  • runtime/SymbolTable.cpp: (JSC::SymbolTable::SymbolTable): (JSC::SymbolTable::cloneCapturedNames): (JSC::SymbolTable::uniqueIDForVariable): (JSC::SymbolTable::uniqueIDForRegister): (JSC::SymbolTable::globalTypeSetForRegister): (JSC::SymbolTable::globalTypeSetForVariable):
  • runtime/SymbolTable.h: (JSC::SymbolTable::add): (JSC::SymbolTable::set):
  • runtime/TypeSet.cpp: Added. (JSC::TypeSet::TypeSet): (JSC::TypeSet::getRuntimeTypeForValue): (JSC::TypeSet::addTypeForValue): (JSC::TypeSet::removeDuplicatesInStructureHistory): (JSC::TypeSet::seenTypes): (JSC::TypeSet::dumpSeenTypes): (JSC::StructureShape::StructureShape): (JSC::StructureShape::markAsFinal): (JSC::StructureShape::addProperty): (JSC::StructureShape::propertyHash): (JSC::StructureShape::leastUpperBound): (JSC::StructureShape::stringRepresentation):
  • runtime/TypeSet.h: Added. (JSC::StructureShape::create): (JSC::TypeSet::create):
  • runtime/VM.cpp: (JSC::VM::VM): (JSC::VM::getTypesForVariableInRange): (JSC::VM::updateHighFidelityTypeProfileState): (JSC::VM::dumpHighFidelityProfilingTypes):
  • runtime/VM.h: (JSC::VM::isProfilingTypesWithHighFidelity): (JSC::VM::highFidelityLog): (JSC::VM::highFidelityTypeProfiler): (JSC::VM::nextLocation): (JSC::VM::getNextUniqueVariableID):


2014-06-26 Mark Lam <[email protected]>


Remove unused instantiation of the WithScope structure.
<https://webkit.org/b/134331>


Reviewed by Oliver Hunt.


The WithScope structure instance is the VM is unused, and is now removed.


  • runtime/VM.cpp: (JSC::VM::VM):
  • runtime/VM.h:


2014-06-25 Mark Hahnenberg <[email protected]>


Structure bit fields should have a consistent format
https://bugs.webkit.org/show_bug.cgi?id=134307


Reviewed by Filip Pizlo.


Currently we use C-style bit fields for a number of member variables in Structure to save space.
This makes it difficult to load these fields in the JIT. We should instead use our own bitfield
format to make it easy to load and test these variables in JIT code.


  • runtime/JSObject.cpp: (JSC::JSObject::putDirectNonIndexAccessor): (JSC::JSObject::reifyStaticFunctionsForDelete):
  • 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):
  • runtime/Structure.h: (JSC::Structure::isExtensible): (JSC::Structure::isDictionary): (JSC::Structure::isUncacheableDictionary): (JSC::Structure::propertyAccessesAreCacheable): (JSC::Structure::previousID): (JSC::Structure::setHasGetterSetterPropertiesWithProtoCheck): (JSC::Structure::setContainsReadOnlyProperties): (JSC::Structure::disableSpecificFunctionTracking): (JSC::Structure::objectToStringValue): (JSC::Structure::setObjectToStringValue): (JSC::Structure::setPreviousID): (JSC::Structure::clearPreviousID): (JSC::Structure::previous): (JSC::Structure::rareData): (JSC::Structure::didTransition): Deleted. (JSC::Structure::hasGetterSetterProperties): Deleted. (JSC::Structure::hasReadOnlyOrGetterSetterPropertiesExcludingProto): Deleted. (JSC::Structure::setHasGetterSetterProperties): Deleted. (JSC::Structure::hasNonEnumerableProperties): Deleted. (JSC::Structure::staticFunctionsReified): Deleted. (JSC::Structure::setStaticFunctionsReified): Deleted.
  • runtime/StructureInlines.h: (JSC::Structure::setEnumerationCache): (JSC::Structure::enumerationCache): (JSC::Structure::checkOffsetConsistency):


2014-06-24 Mark Lam <[email protected]>


[ftlopt] Renamed DebuggerActivation to DebuggerScope.
<https://webkit.org/b/134273>


Reviewed by Michael Saboff.


  • CMakeLists.txt:
  • JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
  • JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • debugger/DebuggerActivation.cpp: Removed.
  • debugger/DebuggerActivation.h: Removed.
  • debugger/DebuggerScope.cpp: Copied from ../../trunk/Source/JavaScriptCore/debugger/DebuggerActivation.cpp. (JSC::DebuggerScope::DebuggerScope): (JSC::DebuggerScope::finishCreation): (JSC::DebuggerScope::visitChildren): (JSC::DebuggerScope::className): (JSC::DebuggerScope::getOwnPropertySlot): (JSC::DebuggerScope::put): (JSC::DebuggerScope::deleteProperty): (JSC::DebuggerScope::getOwnPropertyNames): (JSC::DebuggerScope::defineOwnProperty): (JSC::DebuggerActivation::DebuggerActivation): Deleted. (JSC::DebuggerActivation::finishCreation): Deleted. (JSC::DebuggerActivation::visitChildren): Deleted. (JSC::DebuggerActivation::className): Deleted. (JSC::DebuggerActivation::getOwnPropertySlot): Deleted. (JSC::DebuggerActivation::put): Deleted. (JSC::DebuggerActivation::deleteProperty): Deleted. (JSC::DebuggerActivation::getOwnPropertyNames): Deleted. (JSC::DebuggerActivation::defineOwnProperty): Deleted.
  • debugger/DebuggerScope.h: Copied from ../../trunk/Source/JavaScriptCore/debugger/DebuggerActivation.h. (JSC::DebuggerScope::create): (JSC::DebuggerActivation::create): Deleted.
  • runtime/VM.cpp: (JSC::VM::VM):
  • runtime/VM.h:


2014-06-24 Filip Pizlo <[email protected]>


[ftlopt] PutByIdFlush can also be converted to a PutByOffset so don't assert otherwise
https://bugs.webkit.org/show_bug.cgi?id=134265


Reviewed by Geoffrey Garen.


More assertion fallout from the PutById folding work.


  • dfg/DFGNode.h: (JSC::DFG::Node::convertToPutByOffset):


2014-06-24 Filip Pizlo <[email protected]>


[ftlopt] GC should notify us if it resets to_this
https://bugs.webkit.org/show_bug.cgi?id=128231


Reviewed by Geoffrey Garen.


  • CMakeLists.txt:
  • JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • bytecode/BytecodeList.json:
  • bytecode/CodeBlock.cpp: (JSC::CodeBlock::dumpBytecode): (JSC::CodeBlock::finalizeUnconditionally):
  • bytecode/Instruction.h:
  • bytecode/ToThisStatus.cpp: Added. (JSC::merge): (WTF::printInternal):
  • bytecode/ToThisStatus.h: Added.
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::BytecodeGenerator):
  • dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::parseBlock):
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • runtime/CommonSlowPaths.cpp: (JSC::SLOW_PATH_DECL):


2014-06-24 Filip Pizlo <[email protected]>


[ftlopt] StructureAbstractValue::onlyStructure() should return nullptr if isClobbered()
https://bugs.webkit.org/show_bug.cgi?id=134256


Reviewed by Michael Saboff.


This isn't testable right now (i.e. it's benign) but we should get it right anyway. The
point is to be able to precisely model what goes on in the snippets of code between a
side-effect and an InvalidationPoint.


This patch also cleans up onlyStructure() by delegating more work to
StructureSet::onlyStructure().


  • dfg/DFGStructureAbstractValue.h: (JSC::DFG::StructureAbstractValue::onlyStructure):


2014-06-24 Filip Pizlo <[email protected]>


[ftlopt][REGRESSION] PutById AI is introducing watchable structures without watching them
https://bugs.webkit.org/show_bug.cgi?id=134260


Reviewed by Geoffrey Garen.


This was causing loads of assertion failures in debug builds.


  • dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):


2014-06-21 Filip Pizlo <[email protected]>


[ftlopt] Fold GetById/PutById to MultiGetByOffset/GetByOffset or MultiPutByOffset/PutByOffset, which implies handling non-singleton sets
https://bugs.webkit.org/show_bug.cgi?id=134090


Reviewed by Oliver Hunt.


This pretty much finishes off the work to eliminate the special-casing of singleton
structure sets by making it possible to fold GetById and PutById to various polymorphic
forms of the ByOffset nodes.


  • bytecode/GetByIdStatus.cpp: (JSC::GetByIdStatus::computeForStubInfo): (JSC::GetByIdStatus::computeFor):
  • bytecode/GetByIdStatus.h:
  • bytecode/PutByIdStatus.cpp: (JSC::PutByIdStatus::computeFor):
  • bytecode/PutByIdStatus.h:
  • bytecode/PutByIdVariant.h: (JSC::PutByIdVariant::constantChecks):
  • dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
  • dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::parseBlock):
  • dfg/DFGConstantFoldingPhase.cpp: (JSC::DFG::ConstantFoldingPhase::foldConstants): (JSC::DFG::ConstantFoldingPhase::emitPutByOffset): (JSC::DFG::ConstantFoldingPhase::addChecks):
  • dfg/DFGNode.h: (JSC::DFG::Node::convertToMultiGetByOffset): (JSC::DFG::Node::convertToMultiPutByOffset):
  • dfg/DFGSpeculativeJIT64.cpp: Also convert all release assertions to DFG assertions in this file, because I was hitting some of them while debugging. (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.h: (JSC::DFG::StructureAbstractValue::set):


2014-06-19 Filip Pizlo <[email protected]>


[ftlopt] StructureSet::onlyStructure() should return nullptr if it's not a singleton (instead of asserting)
https://bugs.webkit.org/show_bug.cgi?id=134077


Reviewed by Sam Weinig.


This makes StructureSet and StructureAbstractValue more consistent and fixes a debug assert
in the abstract interpreter.


  • bytecode/StructureSet.h: (JSC::StructureSet::onlyStructure):


2014-06-18 Filip Pizlo <[email protected]>


DFG AI and constant folder should be able to precisely prune MultiGetByOffset/MultiPutByOffset even if the base structure abstract value is not a singleton
https://bugs.webkit.org/show_bug.cgi?id=133918


Reviewed by Mark Hahnenberg.


This also adds pruning of PutStructure, since I basically had no choice but
to implement such logic within MultiPutByOffset.


Also adds a bunch of PutById cache status dumping to bytecode dumping.


  • bytecode/GetByIdVariant.cpp: (JSC::GetByIdVariant::dumpInContext):
  • bytecode/GetByIdVariant.h: (JSC::GetByIdVariant::structureSet):
  • bytecode/PutByIdVariant.h: (JSC::PutByIdVariant::oldStructure):
  • bytecode/StructureSet.cpp: (JSC::StructureSet::filter): (JSC::StructureSet::filterArrayModes):
  • bytecode/StructureSet.h:
  • dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
  • dfg/DFGAbstractValue.cpp: (JSC::DFG::AbstractValue::changeStructure): (JSC::DFG::AbstractValue::contains):
  • dfg/DFGAbstractValue.h: (JSC::DFG::AbstractValue::couldBeType): (JSC::DFG::AbstractValue::isType):
  • dfg/DFGConstantFoldingPhase.cpp: (JSC::DFG::ConstantFoldingPhase::foldConstants): (JSC::DFG::ConstantFoldingPhase::emitGetByOffset): (JSC::DFG::ConstantFoldingPhase::emitPutByOffset): (JSC::DFG::ConstantFoldingPhase::addBaseCheck):
  • dfg/DFGGraph.cpp: (JSC::DFG::Graph::freezeStrong):
  • dfg/DFGGraph.h:
  • dfg/DFGStructureAbstractValue.h: (JSC::DFG::StructureAbstractValue::operator=):
  • ftl/FTLLowerDFGToLLVM.cpp: (JSC::FTL::LowerDFGToLLVM::compileMultiGetByOffset):
  • tests/stress/fold-multi-get-by-offset-to-get-by-offset-without-folding-the-structure-check.js: Added. (foo): (fu): (bar): (baz): (.bar): (.baz):
  • tests/stress/fold-multi-put-by-offset-to-put-by-offset-without-folding-the-structure-check.js: Added. (foo): (fu): (bar): (baz): (.bar): (.baz):
  • tests/stress/prune-multi-put-by-offset-replace-or-transition-variant.js: Added. (foo): (fu): (bar): (baz): (.bar): (.baz):


2014-06-18 Mark Hahnenberg <[email protected]>


Remove CompoundType and LeafType
https://bugs.webkit.org/show_bug.cgi?id=134037


Reviewed by Filip Pizlo.


We don't use them for anything. We'll replace them with a generic CellType type for all
the objects that are JSCells, aren't JSObjects, and for which we generally don't care about
their JSType at runtime.


  • llint/LLIntData.cpp: (JSC::LLInt::Data::performAssertions):
  • runtime/ArrayBufferNeuteringWatchpoint.cpp: (JSC::ArrayBufferNeuteringWatchpoint::createStructure):
  • runtime/Executable.h: (JSC::ExecutableBase::createStructure): (JSC::NativeExecutable::createStructure):
  • 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/PropertyMapHashTable.h: (JSC::PropertyTable::createStructure):
  • runtime/RegExp.h: (JSC::RegExp::createStructure):
  • runtime/SparseArrayValueMap.cpp: (JSC::SparseArrayValueMap::createStructure):
  • runtime/Structure.cpp: (JSC::Structure::Structure):
  • runtime/StructureChain.h: (JSC::StructureChain::createStructure):
  • runtime/StructureRareData.cpp: (JSC::StructureRareData::createStructure):
  • runtime/SymbolTable.h: (JSC::SymbolTable::createStructure):
  • runtime/WeakMapData.h: (JSC::WeakMapData::createStructure):


2014-06-17 Filip Pizlo <[email protected]>


[ftlopt] PutStructure and PhantomPutStructure shouldn't leave the world in a clobbered state
https://bugs.webkit.org/show_bug.cgi?id=134002


Reviewed by Mark Hahnenberg.


The effect of this bug was that if we had a PutStructure or PhantomPutStructure then any
JSConstants would be in a Clobbered state, so we wouldn't take advantage of our knowledge
of the structure if that structure was watchable.


Also kill PhantomPutStructure.


  • dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): (JSC::DFG::AbstractInterpreter<AbstractStateType>::observeTransition): (JSC::DFG::AbstractInterpreter<AbstractStateType>::observeTransitions):
  • dfg/DFGClobberize.h: (JSC::DFG::clobberize):
  • dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC):
  • dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode):
  • dfg/DFGGraph.cpp: (JSC::DFG::Graph::visitChildren):
  • dfg/DFGNode.h: (JSC::DFG::Node::hasTransition):
  • dfg/DFGNodeType.h:
  • dfg/DFGPredictionPropagationPhase.cpp: (JSC::DFG::PredictionPropagationPhase::propagate):
  • dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute):
  • dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile):
  • dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile):
  • dfg/DFGStructureAbstractValue.cpp: (JSC::DFG::StructureAbstractValue::observeTransition): (JSC::DFG::StructureAbstractValue::observeTransitions):
  • dfg/DFGValidate.cpp: (JSC::DFG::Validate::validate):
  • dfg/DFGWatchableStructureWatchingPhase.cpp: (JSC::DFG::WatchableStructureWatchingPhase::run):
  • ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile):
  • ftl/FTLLowerDFGToLLVM.cpp: (JSC::FTL::LowerDFGToLLVM::compileNode): (JSC::FTL::LowerDFGToLLVM::compilePhantomPutStructure): Deleted.


2014-06-17 Filip Pizlo <[email protected]>


[ftlopt] DFG put_by_id should inline accesses with a slightly polymorphic base
https://bugs.webkit.org/show_bug.cgi?id=133964


Reviewed by Mark Hahnenberg.


  • bytecode/PutByIdStatus.cpp: (JSC::PutByIdStatus::appendVariant): (JSC::PutByIdStatus::computeForStubInfo):
  • bytecode/PutByIdVariant.cpp: (JSC::PutByIdVariant::oldStructureForTransition): (JSC::PutByIdVariant::writesStructures): (JSC::PutByIdVariant::reallocatesStorage): (JSC::PutByIdVariant::attemptToMerge): (JSC::PutByIdVariant::attemptToMergeTransitionWithReplace): (JSC::PutByIdVariant::dumpInContext):
  • bytecode/PutByIdVariant.h: (JSC::PutByIdVariant::PutByIdVariant): (JSC::PutByIdVariant::replace): (JSC::PutByIdVariant::transition): (JSC::PutByIdVariant::structure): (JSC::PutByIdVariant::oldStructure):
  • dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
  • dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::handlePutById): (JSC::DFG::ByteCodeParser::parseBlock):
  • dfg/DFGConstantFoldingPhase.cpp: (JSC::DFG::ConstantFoldingPhase::foldConstants): (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
  • dfg/DFGGraph.cpp: (JSC::DFG::Graph::visitChildren):
  • dfg/DFGNode.cpp: (JSC::DFG::MultiPutByOffsetData::writesStructures): (JSC::DFG::MultiPutByOffsetData::reallocatesStorage):
  • ftl/FTLAbbreviations.h: (JSC::FTL::getLinkage):
  • ftl/FTLLowerDFGToLLVM.cpp: (JSC::FTL::LowerDFGToLLVM::compileMultiPutByOffset): (JSC::FTL::LowerDFGToLLVM::getModuleByPathForSymbol):

Source/WebCore:

This fixes the previous mismerge and adds test coverage for the thing that went wrong.
Also, this adds some helpers for making it easier to inspect JavaScript values.

  • testing/Internals.cpp:

(WebCore::Internals::description):

  • testing/Internals.h:
  • testing/Internals.idl:

2014-07-25 Mark Lam <[email protected]>


[ftlopt] Renamed DebuggerActivation to DebuggerScope.
<https://webkit.org/b/134273>


Reviewed by Michael Saboff.


No new tests.


  • ForwardingHeaders/debugger/DebuggerActivation.h: Removed.
  • Removed because this is not used.

Source/WebKit/mac:

2014-07-25 Mark Lam <[email protected]>


[ftlopt] Renamed DebuggerActivation to DebuggerScope.
<https://webkit.org/b/134273>


Reviewed by Michael Saboff.


  • WebView/WebScriptDebugDelegate.mm:
  • Removed unneeded #include.

Source/WTF:

  • wtf/text/WTFString.h:

LayoutTests:

  • js/regress/fold-get-by-id-to-multi-get-by-offset-expected.txt: Added.
  • js/regress/fold-get-by-id-to-multi-get-by-offset-rare-int-expected.txt: Added.
  • js/regress/fold-get-by-id-to-multi-get-by-offset-rare-int.html: Added.
  • js/regress/fold-get-by-id-to-multi-get-by-offset.html: Added.
  • js/regress/fold-multi-get-by-offset-to-get-by-offset-expected.txt: Added.
  • js/regress/fold-multi-get-by-offset-to-get-by-offset.html: Added.
  • js/regress/fold-multi-get-by-offset-to-poly-get-by-offset-expected.txt: Added.
  • js/regress/fold-multi-get-by-offset-to-poly-get-by-offset.html: Added.
  • js/regress/fold-multi-put-by-offset-to-poly-put-by-offset-expected.txt: Added.
  • js/regress/fold-multi-put-by-offset-to-poly-put-by-offset.html: Added.
  • js/regress/fold-multi-put-by-offset-to-put-by-offset-expected.txt: Added.
  • js/regress/fold-multi-put-by-offset-to-put-by-offset.html: Added.
  • js/regress/fold-multi-put-by-offset-to-replace-or-transition-put-by-offset-expected.txt: Added.
  • js/regress/fold-multi-put-by-offset-to-replace-or-transition-put-by-offset.html: Added.
  • js/regress/fold-put-by-id-to-multi-put-by-offset-expected.txt: Added.
  • js/regress/fold-put-by-id-to-multi-put-by-offset.html: Added.
  • js/regress/fold-put-structure-expected.txt: Added.
  • js/regress/fold-put-structure.html: Added.
  • js/regress/hoist-poly-check-structure-effectful-loop-expected.txt: Added.
  • js/regress/hoist-poly-check-structure-effectful-loop.html: Added.
  • js/regress/hoist-poly-check-structure-expected.txt: Added.
  • js/regress/hoist-poly-check-structure.html: Added.
  • js/regress/put-by-id-replace-and-transition-expected.txt: Added.
  • js/regress/put-by-id-replace-and-transition.html: Added.
  • js/regress/put-by-id-slightly-polymorphic-expected.txt: Added.
  • js/regress/put-by-id-slightly-polymorphic.html: Added.
  • js/regress/script-tests/fold-get-by-id-to-multi-get-by-offset-rare-int.js: Added.

(foo):
(fu):
(bar):
(.bar):
(Number):

  • js/regress/script-tests/fold-get-by-id-to-multi-get-by-offset.js: Added.

(foo):
(fu):
(bar):
(.bar):
(Number):

  • js/regress/script-tests/fold-multi-get-by-offset-to-get-by-offset.js: Added.

(foo):
(fu):
(bar):
(.bar):

  • js/regress/script-tests/fold-multi-get-by-offset-to-poly-get-by-offset.js: Added.

(foo):
(fu):
(bar):
(.bar):

  • js/regress/script-tests/fold-multi-put-by-offset-to-poly-put-by-offset.js: Added.

(foo):
(fu):
(bar):
(.bar):

  • js/regress/script-tests/fold-multi-put-by-offset-to-put-by-offset.js: Added.

(foo):
(fu):
(bar):
(.bar):

  • js/regress/script-tests/fold-multi-put-by-offset-to-replace-or-transition-put-by-offset.js: Added.

(foo):
(fu):
(bar):
(.bar):

  • js/regress/script-tests/fold-put-by-id-to-multi-put-by-offset.js: Added.

(foo):
(fu):
(bar):
(.bar):

  • js/regress/script-tests/fold-put-structure.js: Added.

(foo):
(fu):
(bar):
(.bar):

  • js/regress/script-tests/hoist-poly-check-structure-effectful-loop.js: Added.

(foo):
(test):

  • js/regress/script-tests/hoist-poly-check-structure.js: Added.

(foo):
(test):

  • js/regress/script-tests/put-by-id-replace-and-transition.js: Added.
  • js/regress/script-tests/put-by-id-slightly-polymorphic.js: Added.
File:
1 edited

Legend:

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

    r171648 r171660  
    13891389           
    13901390    case GetById:
    1391     case GetByIdFlush:
     1391    case GetByIdFlush: {
    13921392        if (!node->prediction()) {
    13931393            m_state.setIsValid(false);
    13941394            break;
    13951395        }
    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());
     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                    }
    14121412                   
    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                    
     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))
    14231420                    m_state.setFoundConstants(true);
    1424                     break;
    1425                 }
    1426             }
    1427         }
     1421                forNode(node) = result;
     1422                break;
     1423            }
     1424        }
     1425
    14281426        clobberWorld(node->origin.semantic, clobberLimit);
    14291427        forNode(node).makeHeapTop();
    14301428        break;
     1429    }
    14311430           
    14321431    case GetArrayLength:
     
    14631462       
    14641463    case PutStructure:
    1465     case PhantomPutStructure:
    14661464        if (!forNode(node->child1()).m_structure.isClear()) {
    1467             observeTransition(
    1468                 clobberLimit, node->transition()->previous, node->transition()->next);
    1469             forNode(node->child1()).set(m_graph, node->transition()->next);
     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            }
    14701472        }
    14711473        break;
     
    15961598       
    15971599    case MultiGetByOffset: {
    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();
     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;
    16311639        break;
    16321640    }
     
    16371645       
    16381646    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;
    16731647        StructureSet newSet;
    16741648        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       
    16751656        for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
    16761657            const PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
    1677             oldSet.add(variant.oldStructure());
     1658            StructureSet thisSet = variant.oldStructure();
     1659            thisSet.filter(base);
     1660            if (thisSet.isEmpty())
     1661                continue;
    16781662            if (variant.kind() == PutByIdVariant::Transition) {
    1679                 transitions.append(Transition(variant.oldStructure(), variant.newStructure()));
     1663                if (thisSet.onlyStructure() != variant.newStructure()) {
     1664                    transitions.append(
     1665                        Transition(variant.oldStructureForTransition(), variant.newStructure()));
     1666                } // else this is really a replace.
    16801667                newSet.add(variant.newStructure());
    16811668            } else {
    16821669                ASSERT(variant.kind() == PutByIdVariant::Replace);
    1683                 newSet.add(variant.oldStructure());
    1684             }
    1685         }
    1686        
    1687         filter(node->child1(), oldSet);
     1670                newSet.merge(thisSet);
     1671            }
     1672        }
     1673       
    16881674        observeTransitions(clobberLimit, transitions);
    1689         forNode(node->child1()).set(m_graph, newSet);
     1675        if (forNode(node->child1()).changeStructure(m_graph, newSet) == Contradiction)
     1676            m_state.setIsValid(false);
    16901677        break;
    16911678    }
     
    17161703    case PutById:
    17171704    case PutByIdFlush:
    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()) {
     1705    case PutByIdDirect: {
     1706        AbstractValue& value = forNode(node->child1());
     1707        if (!value.m_structure.isTop() && !value.m_structure.isClobbered()) {
    17251708            PutByIdStatus status = PutByIdStatus::computeFor(
    17261709                m_graph.m_vm,
    17271710                m_graph.globalObjectFor(node->origin.semantic),
    1728                 structure,
     1711                value.m_structure.set(),
    17291712                m_graph.identifiers()[node->identifierNumber()],
    17301713                node->op() == PutByIdDirect);
    1731             if (status.isSimple() && status.numVariants() == 1) {
    1732                 if (status[0].kind() == PutByIdVariant::Replace) {
    1733                     filter(node->child1(), structure);
     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))
    17341734                    m_state.setFoundConstants(true);
    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         }
     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       
    17471743        clobberWorld(node->origin.semantic, clobberLimit);
    17481744        break;
     1745    }
    17491746       
    17501747    case In:
     
    19491946    AbstractValue::TransitionObserver transitionObserver(from, to);
    19501947    forAllValues(clobberLimit, transitionObserver);
    1951     setDidClobber();
     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.
    19521950}
    19531951
     
    19581956    AbstractValue::TransitionsObserver transitionsObserver(vector);
    19591957    forAllValues(clobberLimit, transitionsObserver);
    1960     setDidClobber();
     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    }
    19611964}
    19621965
Note: See TracChangeset for help on using the changeset viewer.