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


Ignore:
Timestamp:
Aug 6, 2014, 2:32:55 PM (11 years ago)
Author:
[email protected]
Message:

Merge r171389, r171495, r171508, r171510, r171605, r171606, r171611, r171614, r171763 from ftlopt.

Source/JavaScriptCore:

2014-07-28 Mark Hahnenberg <[email protected]>


Support for-in in the FTL
https://bugs.webkit.org/show_bug.cgi?id=134140


Reviewed by Filip Pizlo.


  • dfg/DFGSSALoweringPhase.cpp: (JSC::DFG::SSALoweringPhase::handleNode):
  • ftl/FTLAbstractHeapRepository.cpp:
  • ftl/FTLAbstractHeapRepository.h:
  • ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile):
  • ftl/FTLIntrinsicRepository.h:
  • ftl/FTLLowerDFGToLLVM.cpp: (JSC::FTL::LowerDFGToLLVM::compileNode): (JSC::FTL::LowerDFGToLLVM::compileHasIndexedProperty): (JSC::FTL::LowerDFGToLLVM::compileHasGenericProperty): (JSC::FTL::LowerDFGToLLVM::compileHasStructureProperty): (JSC::FTL::LowerDFGToLLVM::compileGetDirectPname): (JSC::FTL::LowerDFGToLLVM::compileGetEnumerableLength): (JSC::FTL::LowerDFGToLLVM::compileGetStructurePropertyEnumerator): (JSC::FTL::LowerDFGToLLVM::compileGetGenericPropertyEnumerator): (JSC::FTL::LowerDFGToLLVM::compileGetEnumeratorPname): (JSC::FTL::LowerDFGToLLVM::compileToIndexString):


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


Remove JSPropertyNameIterator
https://bugs.webkit.org/show_bug.cgi?id=135066


Reviewed by Geoffrey Garen.


It has been replaced by JSPropertyNameEnumerator.


  • JavaScriptCore.order:
  • bytecode/BytecodeBasicBlock.cpp: (JSC::isBranch):
  • bytecode/BytecodeList.json:
  • bytecode/BytecodeUseDef.h: (JSC::computeUsesForBytecodeOffset): (JSC::computeDefsForBytecodeOffset):
  • bytecode/CodeBlock.cpp: (JSC::CodeBlock::dumpBytecode):
  • bytecode/PreciseJumpTargets.cpp: (JSC::getJumpTargetsForBytecodeOffset):
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitGetPropertyNames): Deleted. (JSC::BytecodeGenerator::emitNextPropertyName): Deleted.
  • bytecompiler/BytecodeGenerator.h:
  • interpreter/Interpreter.cpp:
  • interpreter/Register.h:
  • jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): (JSC::JIT::privateCompileSlowCases):
  • jit/JIT.h:
  • jit/JITOpcodes.cpp: (JSC::JIT::emit_op_get_pnames): Deleted. (JSC::JIT::emit_op_next_pname): Deleted.
  • jit/JITOpcodes32_64.cpp: (JSC::JIT::emit_op_get_pnames): Deleted. (JSC::JIT::emit_op_next_pname): Deleted.
  • jit/JITOperations.cpp:
  • jit/JITPropertyAccess.cpp: (JSC::JIT::emit_op_get_by_pname): Deleted. (JSC::JIT::emitSlow_op_get_by_pname): Deleted.
  • jit/JITPropertyAccess32_64.cpp: (JSC::JIT::emit_op_get_by_pname): Deleted. (JSC::JIT::emitSlow_op_get_by_pname): Deleted.
  • llint/LLIntOffsetsExtractor.cpp:
  • llint/LLIntSlowPaths.cpp: (JSC::LLInt::LLINT_SLOW_PATH_DECL): Deleted.
  • llint/LLIntSlowPaths.h:
  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • runtime/CommonSlowPaths.cpp:
  • runtime/JSPropertyNameIterator.cpp: (JSC::JSPropertyNameIterator::JSPropertyNameIterator): Deleted. (JSC::JSPropertyNameIterator::create): Deleted. (JSC::JSPropertyNameIterator::destroy): Deleted. (JSC::JSPropertyNameIterator::get): Deleted. (JSC::JSPropertyNameIterator::visitChildren): Deleted.
  • runtime/JSPropertyNameIterator.h: (JSC::JSPropertyNameIterator::createStructure): Deleted. (JSC::JSPropertyNameIterator::size): Deleted. (JSC::JSPropertyNameIterator::setCachedStructure): Deleted. (JSC::JSPropertyNameIterator::cachedStructure): Deleted. (JSC::JSPropertyNameIterator::setCachedPrototypeChain): Deleted. (JSC::JSPropertyNameIterator::cachedPrototypeChain): Deleted. (JSC::JSPropertyNameIterator::finishCreation): Deleted. (JSC::Register::propertyNameIterator): Deleted. (JSC::StructureRareData::enumerationCache): Deleted. (JSC::StructureRareData::setEnumerationCache): Deleted.
  • runtime/Structure.cpp: (JSC::Structure::addPropertyWithoutTransition): (JSC::Structure::removePropertyWithoutTransition):
  • runtime/Structure.h:
  • runtime/StructureInlines.h: (JSC::Structure::setEnumerationCache): Deleted. (JSC::Structure::enumerationCache): Deleted.
  • runtime/StructureRareData.cpp: (JSC::StructureRareData::visitChildren):
  • runtime/StructureRareData.h:
  • runtime/VM.cpp: (JSC::VM::VM):


2014-07-25 Saam Barati <[email protected]>


Fix 32-bit build breakage for type profiling
https://bugs.webkit.org/process_bug.cgi


Reviewed by Mark Hahnenberg.


32-bit builds currently break because global variable IDs for high
fidelity type profiling are int64_t. Change this to intptr_t so that
it's 32 bits on 32-bit platforms and 64 bits on 64-bit platforms.


  • bytecode/CodeBlock.cpp: (JSC::CodeBlock::CodeBlock): (JSC::CodeBlock::scopeDependentProfile):
  • bytecode/TypeLocation.h:
  • runtime/SymbolTable.cpp: (JSC::SymbolTable::uniqueIDForVariable): (JSC::SymbolTable::uniqueIDForRegister):
  • runtime/SymbolTable.h:
  • runtime/TypeLocationCache.cpp: (JSC::TypeLocationCache::getTypeLocation):
  • runtime/TypeLocationCache.h:
  • runtime/VM.h: (JSC::VM::getNextUniqueVariableID):


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


Reindent PropertyNameArray.h
https://bugs.webkit.org/show_bug.cgi?id=135067


Reviewed by Geoffrey Garen.


  • runtime/PropertyNameArray.h: (JSC::RefCountedIdentifierSet::contains): (JSC::RefCountedIdentifierSet::size): (JSC::RefCountedIdentifierSet::add): (JSC::PropertyNameArrayData::create): (JSC::PropertyNameArrayData::propertyNameVector): (JSC::PropertyNameArrayData::PropertyNameArrayData): (JSC::PropertyNameArray::PropertyNameArray): (JSC::PropertyNameArray::vm): (JSC::PropertyNameArray::add): (JSC::PropertyNameArray::addKnownUnique): (JSC::PropertyNameArray::operator[]): (JSC::PropertyNameArray::setData): (JSC::PropertyNameArray::data): (JSC::PropertyNameArray::releaseData): (JSC::PropertyNameArray::identifierSet): (JSC::PropertyNameArray::canAddKnownUniqueForStructure): (JSC::PropertyNameArray::size): (JSC::PropertyNameArray::begin): (JSC::PropertyNameArray::end): (JSC::PropertyNameArray::numCacheableSlots): (JSC::PropertyNameArray::setNumCacheableSlotsForObject): (JSC::PropertyNameArray::setBaseObject): (JSC::PropertyNameArray::setPreviouslyEnumeratedLength):


2014-07-23 Mark Hahnenberg <[email protected]>


Refactor our current implementation of for-in
https://bugs.webkit.org/show_bug.cgi?id=134142


Reviewed by Filip Pizlo.


This patch splits for-in loops into three distinct parts:


  • Iterating over the indexed properties in the base object.
  • Iterating over the Structure properties in the base object.
  • Iterating over any other enumerable properties for that object and any objects in the prototype chain.


It does this by emitting these explicit loops in bytecode, using a new set of bytecodes to
support the various operations required for each loop.


  • API/JSCallbackObjectFunctions.h: (JSC::JSCallbackObject<Parent>::getOwnNonIndexPropertyNames):
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • bytecode/BytecodeList.json:
  • bytecode/BytecodeUseDef.h: (JSC::computeUsesForBytecodeOffset): (JSC::computeDefsForBytecodeOffset):
  • bytecode/CallLinkStatus.h: (JSC::CallLinkStatus::CallLinkStatus):
  • bytecode/CodeBlock.cpp: (JSC::CodeBlock::dumpBytecode): (JSC::CodeBlock::CodeBlock):
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitGetByVal): (JSC::BytecodeGenerator::emitComplexPopScopes): (JSC::BytecodeGenerator::emitGetEnumerableLength): (JSC::BytecodeGenerator::emitHasGenericProperty): (JSC::BytecodeGenerator::emitHasIndexedProperty): (JSC::BytecodeGenerator::emitHasStructureProperty): (JSC::BytecodeGenerator::emitGetStructurePropertyEnumerator): (JSC::BytecodeGenerator::emitGetGenericPropertyEnumerator): (JSC::BytecodeGenerator::emitNextEnumeratorPropertyName): (JSC::BytecodeGenerator::emitToIndexString): (JSC::BytecodeGenerator::pushIndexedForInScope): (JSC::BytecodeGenerator::popIndexedForInScope): (JSC::BytecodeGenerator::pushStructureForInScope): (JSC::BytecodeGenerator::popStructureForInScope): (JSC::BytecodeGenerator::invalidateForInContextForLocal):
  • bytecompiler/BytecodeGenerator.h: (JSC::ForInContext::ForInContext): (JSC::ForInContext::~ForInContext): (JSC::ForInContext::isValid): (JSC::ForInContext::invalidate): (JSC::ForInContext::local): (JSC::StructureForInContext::StructureForInContext): (JSC::StructureForInContext::type): (JSC::StructureForInContext::index): (JSC::StructureForInContext::property): (JSC::StructureForInContext::enumerator): (JSC::IndexedForInContext::IndexedForInContext): (JSC::IndexedForInContext::type): (JSC::IndexedForInContext::index): (JSC::BytecodeGenerator::pushOptimisedForIn): Deleted. (JSC::BytecodeGenerator::popOptimisedForIn): Deleted.
  • bytecompiler/NodesCodegen.cpp: (JSC::ReadModifyResolveNode::emitBytecode): (JSC::AssignResolveNode::emitBytecode): (JSC::ForInNode::tryGetBoundLocal): (JSC::ForInNode::emitLoopHeader): (JSC::ForInNode::emitMultiLoopBytecode): (JSC::ForInNode::emitBytecode):
  • debugger/DebuggerScope.h:
  • dfg/DFGAbstractHeap.h:
  • dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
  • dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::parseBlock):
  • dfg/DFGCapabilities.cpp: (JSC::DFG::capabilityLevel):
  • dfg/DFGClobberize.h: (JSC::DFG::clobberize):
  • dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC):
  • dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode):
  • dfg/DFGHeapLocation.cpp: (WTF::printInternal):
  • dfg/DFGHeapLocation.h:
  • dfg/DFGNode.h: (JSC::DFG::Node::hasHeapPrediction): (JSC::DFG::Node::hasArrayMode):
  • dfg/DFGNodeType.h:
  • dfg/DFGPredictionPropagationPhase.cpp: (JSC::DFG::PredictionPropagationPhase::propagate):
  • dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute):
  • dfg/DFGSpeculativeJIT.h: (JSC::DFG::SpeculativeJIT::callOperation):
  • dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile):
  • dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile):
  • jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): (JSC::JIT::privateCompileSlowCases):
  • jit/JIT.h: (JSC::JIT::compileHasIndexedProperty): (JSC::JIT::emitInt32Load):
  • jit/JITInlines.h: (JSC::JIT::emitDoubleGetByVal): (JSC::JIT::emitLoadForArrayMode): (JSC::JIT::emitContiguousGetByVal): (JSC::JIT::emitArrayStorageGetByVal):
  • jit/JITOpcodes.cpp: (JSC::JIT::emit_op_get_enumerable_length): (JSC::JIT::emit_op_has_structure_property): (JSC::JIT::emitSlow_op_has_structure_property): (JSC::JIT::emit_op_has_generic_property): (JSC::JIT::privateCompileHasIndexedProperty): (JSC::JIT::emit_op_has_indexed_property): (JSC::JIT::emitSlow_op_has_indexed_property): (JSC::JIT::emit_op_get_direct_pname): (JSC::JIT::emitSlow_op_get_direct_pname): (JSC::JIT::emit_op_get_structure_property_enumerator): (JSC::JIT::emit_op_get_generic_property_enumerator): (JSC::JIT::emit_op_next_enumerator_pname): (JSC::JIT::emit_op_to_index_string):
  • jit/JITOpcodes32_64.cpp: (JSC::JIT::emit_op_get_enumerable_length): (JSC::JIT::emit_op_has_structure_property): (JSC::JIT::emitSlow_op_has_structure_property): (JSC::JIT::emit_op_has_generic_property): (JSC::JIT::privateCompileHasIndexedProperty): (JSC::JIT::emit_op_has_indexed_property): (JSC::JIT::emitSlow_op_has_indexed_property): (JSC::JIT::emit_op_get_direct_pname): (JSC::JIT::emitSlow_op_get_direct_pname): (JSC::JIT::emit_op_get_structure_property_enumerator): (JSC::JIT::emit_op_get_generic_property_enumerator): (JSC::JIT::emit_op_next_enumerator_pname): (JSC::JIT::emit_op_to_index_string):
  • jit/JITOperations.cpp:
  • jit/JITOperations.h:
  • jit/JITPropertyAccess.cpp: (JSC::JIT::emitDoubleLoad): (JSC::JIT::emitContiguousLoad): (JSC::JIT::emitArrayStorageLoad): (JSC::JIT::emitDoubleGetByVal): Deleted. (JSC::JIT::emitContiguousGetByVal): Deleted. (JSC::JIT::emitArrayStorageGetByVal): Deleted.
  • jit/JITPropertyAccess32_64.cpp: (JSC::JIT::emitContiguousLoad): (JSC::JIT::emitDoubleLoad): (JSC::JIT::emitArrayStorageLoad): (JSC::JIT::emitContiguousGetByVal): Deleted. (JSC::JIT::emitDoubleGetByVal): Deleted. (JSC::JIT::emitArrayStorageGetByVal): Deleted.
  • llint/LowLevelInterpreter.asm:
  • parser/Nodes.h:
  • runtime/Arguments.cpp: (JSC::Arguments::getOwnPropertyNames):
  • runtime/ClassInfo.h:
  • runtime/CommonSlowPaths.cpp: (JSC::SLOW_PATH_DECL):
  • runtime/CommonSlowPaths.h:
  • runtime/EnumerationMode.h: Added. (JSC::shouldIncludeDontEnumProperties): (JSC::shouldExcludeDontEnumProperties): (JSC::shouldIncludeJSObjectPropertyNames): (JSC::modeThatSkipsJSObject):
  • runtime/JSActivation.cpp: (JSC::JSActivation::getOwnNonIndexPropertyNames):
  • runtime/JSArray.cpp: (JSC::JSArray::getOwnNonIndexPropertyNames):
  • runtime/JSArrayBuffer.cpp: (JSC::JSArrayBuffer::getOwnNonIndexPropertyNames):
  • runtime/JSArrayBufferView.cpp: (JSC::JSArrayBufferView::getOwnNonIndexPropertyNames):
  • runtime/JSCell.cpp: (JSC::JSCell::getEnumerableLength): (JSC::JSCell::getStructurePropertyNames): (JSC::JSCell::getGenericPropertyNames):
  • runtime/JSCell.h:
  • runtime/JSFunction.cpp: (JSC::JSFunction::getOwnNonIndexPropertyNames):
  • runtime/JSGenericTypedArrayViewInlines.h: (JSC::JSGenericTypedArrayView<Adaptor>::getOwnNonIndexPropertyNames):
  • runtime/JSObject.cpp: (JSC::getClassPropertyNames): (JSC::JSObject::hasOwnProperty): (JSC::JSObject::getOwnPropertyNames): (JSC::JSObject::getOwnNonIndexPropertyNames): (JSC::JSObject::getEnumerableLength): (JSC::JSObject::getStructurePropertyNames): (JSC::JSObject::getGenericPropertyNames):
  • runtime/JSObject.h:
  • runtime/JSPropertyNameEnumerator.cpp: Added. (JSC::JSPropertyNameEnumerator::create): (JSC::JSPropertyNameEnumerator::JSPropertyNameEnumerator): (JSC::JSPropertyNameEnumerator::finishCreation): (JSC::JSPropertyNameEnumerator::destroy): (JSC::JSPropertyNameEnumerator::visitChildren):
  • runtime/JSPropertyNameEnumerator.h: Added. (JSC::JSPropertyNameEnumerator::createStructure): (JSC::JSPropertyNameEnumerator::propertyNameAtIndex): (JSC::JSPropertyNameEnumerator::identifierSet): (JSC::JSPropertyNameEnumerator::cachedPrototypeChain): (JSC::JSPropertyNameEnumerator::setCachedPrototypeChain): (JSC::JSPropertyNameEnumerator::cachedStructure): (JSC::JSPropertyNameEnumerator::cachedStructureID): (JSC::JSPropertyNameEnumerator::cachedInlineCapacity): (JSC::JSPropertyNameEnumerator::cachedStructureIDOffset): (JSC::JSPropertyNameEnumerator::cachedInlineCapacityOffset): (JSC::JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset): (JSC::JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset): (JSC::structurePropertyNameEnumerator): (JSC::genericPropertyNameEnumerator):
  • runtime/JSProxy.cpp: (JSC::JSProxy::getEnumerableLength): (JSC::JSProxy::getStructurePropertyNames): (JSC::JSProxy::getGenericPropertyNames):
  • runtime/JSProxy.h:
  • runtime/JSSymbolTableObject.cpp: (JSC::JSSymbolTableObject::getOwnNonIndexPropertyNames):
  • runtime/PropertyNameArray.cpp: (JSC::PropertyNameArray::add): (JSC::PropertyNameArray::setPreviouslyEnumeratedProperties):
  • runtime/PropertyNameArray.h: (JSC::RefCountedIdentifierSet::contains): (JSC::RefCountedIdentifierSet::size): (JSC::RefCountedIdentifierSet::add): (JSC::PropertyNameArray::PropertyNameArray): (JSC::PropertyNameArray::add): (JSC::PropertyNameArray::addKnownUnique): (JSC::PropertyNameArray::identifierSet): (JSC::PropertyNameArray::canAddKnownUniqueForStructure): (JSC::PropertyNameArray::setPreviouslyEnumeratedLength):
  • runtime/RegExpObject.cpp: (JSC::RegExpObject::getOwnNonIndexPropertyNames): (JSC::RegExpObject::getPropertyNames): (JSC::RegExpObject::getGenericPropertyNames):
  • runtime/RegExpObject.h:
  • runtime/StringObject.cpp: (JSC::StringObject::getOwnPropertyNames):
  • runtime/Structure.cpp: (JSC::Structure::getPropertyNamesFromStructure): (JSC::Structure::setCachedStructurePropertyNameEnumerator): (JSC::Structure::cachedStructurePropertyNameEnumerator): (JSC::Structure::setCachedGenericPropertyNameEnumerator): (JSC::Structure::cachedGenericPropertyNameEnumerator): (JSC::Structure::canCacheStructurePropertyNameEnumerator): (JSC::Structure::canCacheGenericPropertyNameEnumerator): (JSC::Structure::canAccessPropertiesQuickly):
  • runtime/Structure.h:
  • runtime/StructureRareData.cpp: (JSC::StructureRareData::visitChildren): (JSC::StructureRareData::cachedStructurePropertyNameEnumerator): (JSC::StructureRareData::setCachedStructurePropertyNameEnumerator): (JSC::StructureRareData::cachedGenericPropertyNameEnumerator): (JSC::StructureRareData::setCachedGenericPropertyNameEnumerator):
  • runtime/StructureRareData.h:
  • runtime/VM.cpp: (JSC::VM::VM):
  • runtime/VM.h:


2014-07-23 Saam Barati <[email protected]>


Make improvements to Type Profiling
https://bugs.webkit.org/show_bug.cgi?id=134860


Reviewed by Filip Pizlo.


I improved the API between the inspector and JSC. We no longer send one huge
string to the inspector. We now send structured data that represents the type
information that JSC has collected. I've also created a beginning implementation
of a type lattice that allows us to resolve a display name for a type that
consists of a single word.


I created a data structure that knows which functions have executed. This
solves the bug where types inside an un-executed function will resolve
to the type of the enclosing expression of that function. This data
structure may also be useful later if the inspector chooses to create a UI
around showing which functions have executed.


Better type information is gathered for objects. StructureShape now
represents an object's prototype chain. StructureShape also collects
the constructor name for an object.


Expression ranges are now zero indexed.


Removed some extraneous methods.


  • JavaScriptCore.xcodeproj/project.pbxproj:
  • bytecode/CodeBlock.cpp: (JSC::CodeBlock::CodeBlock): (JSC::CodeBlock::scopeDependentProfile):
  • bytecode/CodeBlock.h:
  • bytecode/TypeLocation.h: (JSC::TypeLocation::TypeLocation):
  • bytecode/UnlinkedCodeBlock.cpp: (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
  • bytecode/UnlinkedCodeBlock.h: (JSC::UnlinkedFunctionExecutable::highFidelityTypeProfilingStartOffset): (JSC::UnlinkedFunctionExecutable::highFidelityTypeProfilingEndOffset):
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::BytecodeGenerator): (JSC::BytecodeGenerator::emitHighFidelityTypeProfilingExpressionInfo):
  • bytecompiler/BytecodeGenerator.h: (JSC::BytecodeGenerator::emitHighFidelityTypeProfilingExpressionInfo): Deleted.
  • heap/Heap.cpp: (JSC::Heap::collect):
  • inspector/agents/InspectorRuntimeAgent.cpp: (Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets): (Inspector::InspectorRuntimeAgent::getRuntimeTypeForVariableAtOffset): Deleted.
  • inspector/agents/InspectorRuntimeAgent.h:
  • inspector/protocol/Runtime.json:
  • runtime/Executable.cpp: (JSC::ScriptExecutable::ScriptExecutable): (JSC::ProgramExecutable::ProgramExecutable): (JSC::FunctionExecutable::FunctionExecutable): (JSC::ProgramExecutable::initializeGlobalProperties):
  • runtime/Executable.h: (JSC::ScriptExecutable::highFidelityTypeProfilingStartOffset): (JSC::ScriptExecutable::highFidelityTypeProfilingEndOffset):
  • runtime/FunctionHasExecutedCache.cpp: Added. (JSC::FunctionHasExecutedCache::hasExecutedAtOffset): (JSC::FunctionHasExecutedCache::insertUnexecutedRange): (JSC::FunctionHasExecutedCache::removeUnexecutedRange):
  • runtime/FunctionHasExecutedCache.h: Added. (JSC::FunctionHasExecutedCache::FunctionRange::FunctionRange): (JSC::FunctionHasExecutedCache::FunctionRange::operator==): (JSC::FunctionHasExecutedCache::FunctionRange::hash):
  • runtime/HighFidelityLog.cpp: (JSC::HighFidelityLog::processHighFidelityLog): (JSC::HighFidelityLog::actuallyProcessLogThreadFunction): Deleted.
  • runtime/HighFidelityLog.h: (JSC::HighFidelityLog::recordTypeInformationForLocation):
  • runtime/HighFidelityTypeProfiler.cpp: (JSC::HighFidelityTypeProfiler::logTypesForTypeLocation): (JSC::HighFidelityTypeProfiler::insertNewLocation): (JSC::HighFidelityTypeProfiler::getTypesForVariableAtOffsetForInspector): (JSC::descriptorMatchesTypeLocation): (JSC::HighFidelityTypeProfiler::findLocation): (JSC::HighFidelityTypeProfiler::getTypesForVariableInAtOffset): Deleted. (JSC::HighFidelityTypeProfiler::getGlobalTypesForVariableAtOffset): Deleted. (JSC::HighFidelityTypeProfiler::getLocalTypesForVariableAtOffset): Deleted.
  • runtime/HighFidelityTypeProfiler.h: (JSC::QueryKey::QueryKey): (JSC::QueryKey::isHashTableDeletedValue): (JSC::QueryKey::operator==): (JSC::QueryKey::hash): (JSC::QueryKeyHash::hash): (JSC::QueryKeyHash::equal): (JSC::HighFidelityTypeProfiler::functionHasExecutedCache): (JSC::HighFidelityTypeProfiler::typeLocationCache):
  • runtime/Structure.cpp: (JSC::Structure::toStructureShape):
  • runtime/Structure.h:
  • runtime/TypeLocationCache.cpp: Added. (JSC::TypeLocationCache::getTypeLocation):
  • runtime/TypeLocationCache.h: Added. (JSC::TypeLocationCache::LocationKey::LocationKey): (JSC::TypeLocationCache::LocationKey::operator==): (JSC::TypeLocationCache::LocationKey::hash):
  • runtime/TypeSet.cpp: (JSC::TypeSet::getRuntimeTypeForValue): (JSC::TypeSet::addTypeForValue): (JSC::TypeSet::seenTypes): (JSC::TypeSet::doesTypeConformTo): (JSC::TypeSet::displayName): (JSC::TypeSet::allPrimitiveTypeNames): (JSC::TypeSet::allStructureRepresentations): (JSC::TypeSet::leastCommonAncestor): (JSC::StructureShape::StructureShape): (JSC::StructureShape::addProperty): (JSC::StructureShape::propertyHash): (JSC::StructureShape::leastCommonAncestor): (JSC::StructureShape::stringRepresentation): (JSC::StructureShape::inspectorRepresentation): (JSC::StructureShape::leastUpperBound): Deleted.
  • runtime/TypeSet.h: (JSC::StructureShape::setConstructorName): (JSC::StructureShape::constructorName): (JSC::StructureShape::setProto):
  • runtime/VM.cpp: (JSC::VM::dumpHighFidelityProfilingTypes): (JSC::VM::getTypesForVariableAtOffset): Deleted. (JSC::VM::updateHighFidelityTypeProfileState): Deleted.
  • runtime/VM.h: (JSC::VM::isProfilingTypesWithHighFidelity): (JSC::VM::highFidelityTypeProfiler):


2014-07-23 Filip Pizlo <[email protected]>


Fix debug build.


  • bytecode/CallLinkStatus.h: (JSC::CallLinkStatus::CallLinkStatus):


2014-07-20 Filip Pizlo <[email protected]>


[ftlopt] Phantoms in SSA form should be aggressively hoisted
https://bugs.webkit.org/show_bug.cgi?id=135111


Reviewed by Oliver Hunt.


In CPS form, Phantom means three things: (1) that the children should be kept alive so long
as they are relevant to OSR (due to a MovHint), (2) that the children are live-in-bytecode
at the point of the Phantom, and (3) that some checks should be performed. In SSA, the
second meaning is not used but the other two stay.


The fact that a Phantom that is used to keep a node alive could be anywhere in the graph,
even in a totally different basic block, complicates some SSA transformations. It's not
possible to just jettison some successor, since tha successor could have a Phantom that we
care about.


This change rationalizes how Phantoms work so that:


1) Phantoms keep children alive so long as those children are relevant to OSR. This is true

in both CPS and SSA. This was true before and it's true now.


2) Phantoms are used for live-in-bytecode only in CPS. This was true before and it's true

now, except that now we also don't bother preserving the live-in-bytecode information
that Phantoms convey, when we are in SSA.


3) Phantoms may incidentally have checks, but in cases where we only want checks, we now

use Check instead of Phantom. Notably, DCE phase has dead nodes decay to Check, not
Phantom.


The biggest part of this change is that in SSA, we canonicalize Phantoms:


  • All Phantoms are replaced with Check nodes that include only those edges that have checks.


  • Nodes that were the children of any Phantoms have a Phantom right after them.


For example, the following code:


5: ArithAdd(@1, @2)
6: ArithSub(@5, @3)
7: Phantom(Int32:@5)


would be turned into the following:


5: ArithAdd(@1, @2)
8: Phantom(@5) @5 was the child of a Phantom, so we create a new Phantom right after

@5. This is the only Phantom we will have for @5.

6: ArithSub(@5, @3)
7: Check(Int32:@5) We replace the Phantom with a Check; in this case since Int32: is

a checking edge, we leave it.


This is a slight speed-up across the board, presumably because we now do a better job of
reducing the size of the graph during compilation. It could also be a fluke, though. The
main purpose of this is to unlock some other work (like CFG simplification in SSA). It will
become a requirement to run phantom canonicalization prior to some SSA phases. None of the
current phases need it, but future phases probably will.


  • CMakeLists.txt:
  • JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
  • dfg/DFGConstantFoldingPhase.cpp: (JSC::DFG::ConstantFoldingPhase::foldConstants):
  • dfg/DFGDCEPhase.cpp: (JSC::DFG::DCEPhase::run): (JSC::DFG::DCEPhase::findTypeCheckRoot): (JSC::DFG::DCEPhase::countEdge): (JSC::DFG::DCEPhase::fixupBlock): (JSC::DFG::DCEPhase::eliminateIrrelevantPhantomChildren):
  • dfg/DFGEdge.cpp: (JSC::DFG::Edge::dump):
  • dfg/DFGEdge.h: (JSC::DFG::Edge::isProved): (JSC::DFG::Edge::needsCheck): Deleted.
  • dfg/DFGNodeFlags.h:
  • dfg/DFGPhantomCanonicalizationPhase.cpp: Added. (JSC::DFG::PhantomCanonicalizationPhase::PhantomCanonicalizationPhase): (JSC::DFG::PhantomCanonicalizationPhase::run): (JSC::DFG::performPhantomCanonicalization):
  • dfg/DFGPhantomCanonicalizationPhase.h: Added.
  • dfg/DFGPhantomRemovalPhase.cpp: (JSC::DFG::PhantomRemovalPhase::run):
  • dfg/DFGPhantomRemovalPhase.h:
  • dfg/DFGPlan.cpp: (JSC::DFG::Plan::compileInThreadImpl):
  • ftl/FTLLowerDFGToLLVM.cpp: (JSC::FTL::LowerDFGToLLVM::lowJSValue): (JSC::FTL::LowerDFGToLLVM::speculateObjectOrOther):


2014-07-22 Filip Pizlo <[email protected]>


[ftlopt] Get rid of structure checks as a way of checking if a function is in fact a function
https://bugs.webkit.org/show_bug.cgi?id=135146


Reviewed by Oliver Hunt.


This greatly simplifies our closure call optimizations by taking advantage of the type
bits available in the cell header.


  • bytecode/CallLinkInfo.cpp: (JSC::CallLinkInfo::visitWeak):
  • bytecode/CallLinkStatus.cpp: (JSC::CallLinkStatus::CallLinkStatus): (JSC::CallLinkStatus::computeFor): (JSC::CallLinkStatus::dump):
  • bytecode/CallLinkStatus.h: (JSC::CallLinkStatus::CallLinkStatus): (JSC::CallLinkStatus::executable): (JSC::CallLinkStatus::structure): Deleted.
  • dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::emitFunctionChecks):
  • dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): (JSC::DFG::FixupPhase::observeUseKindOnNode):
  • dfg/DFGSafeToExecute.h: (JSC::DFG::SafeToExecuteEdge::operator()):
  • dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::checkArray): (JSC::DFG::SpeculativeJIT::speculateCellTypeWithoutTypeFiltering): (JSC::DFG::SpeculativeJIT::speculateCellType): (JSC::DFG::SpeculativeJIT::speculateFunction): (JSC::DFG::SpeculativeJIT::speculateFinalObject): (JSC::DFG::SpeculativeJIT::speculate):
  • dfg/DFGSpeculativeJIT.h:
  • dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile):
  • dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile):
  • dfg/DFGUseKind.cpp: (WTF::printInternal):
  • dfg/DFGUseKind.h: (JSC::DFG::typeFilterFor): (JSC::DFG::isCell):
  • ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile):
  • ftl/FTLLowerDFGToLLVM.cpp: (JSC::FTL::LowerDFGToLLVM::compileCheckExecutable): (JSC::FTL::LowerDFGToLLVM::speculate): (JSC::FTL::LowerDFGToLLVM::isFunction): (JSC::FTL::LowerDFGToLLVM::isNotFunction): (JSC::FTL::LowerDFGToLLVM::speculateFunction):
  • jit/ClosureCallStubRoutine.cpp: (JSC::ClosureCallStubRoutine::ClosureCallStubRoutine): (JSC::ClosureCallStubRoutine::markRequiredObjectsInternal):
  • jit/ClosureCallStubRoutine.h: (JSC::ClosureCallStubRoutine::structure): Deleted.
  • jit/JIT.h: (JSC::JIT::compileClosureCall): Deleted.
  • jit/JITCall.cpp: (JSC::JIT::privateCompileClosureCall): Deleted.
  • jit/JITCall32_64.cpp: (JSC::JIT::privateCompileClosureCall): Deleted.
  • jit/JITOperations.cpp:
  • jit/Repatch.cpp: (JSC::linkClosureCall):
  • jit/Repatch.h:

Source/WebCore:

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


Refactor our current implementation of for-in
https://bugs.webkit.org/show_bug.cgi?id=134142


Reviewed by Filip Pizlo.


No new tests.


This patch splits for-in loops into three distinct parts:


  • Iterating over the indexed properties in the base object.
  • Iterating over the Structure properties in the base object.
  • Iterating over any other enumerable properties for that object and any objects in the prototype chain.


It does this by emitting these explicit loops in bytecode, using a new set of bytecodes to
support the various operations required for each loop.


  • bindings/js/JSDOMWindowCustom.cpp: (WebCore::JSDOMWindow::getEnumerableLength): (WebCore::JSDOMWindow::getStructurePropertyNames): (WebCore::JSDOMWindow::getGenericPropertyNames):
  • bindings/scripts/CodeGeneratorJS.pm: (GenerateHeader):
  • bridge/runtime_array.cpp: (JSC::RuntimeArray::getOwnPropertyNames):

Source/WebKit2:

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


Refactor our current implementation of for-in
https://bugs.webkit.org/show_bug.cgi?id=134142


Reviewed by Filip Pizlo.


  • WebProcess/Plugins/Netscape/JSNPObject.cpp: (WebKit::JSNPObject::invalidate): Fixed an invalid ASSERT that was crashing in debug builds.
Location:
trunk/Source/JavaScriptCore/dfg
Files:
2 added
29 edited

Legend:

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

    r172129 r172176  
    5454    macro(JSObject_butterfly) \
    5555    macro(JSVariableObject_registers) \
     56    macro(JSPropertyNameEnumerator_cachedPropertyNames) \
    5657    macro(NamedProperties) \
    5758    macro(IndexedInt32Properties) \
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r172129 r172176  
    17961796    }
    17971797       
    1798     case In:
     1798    case In: {
    17991799        // FIXME: We can determine when the property definitely exists based on abstract
    18001800        // value information.
     
    18021802        forNode(node).setType(SpecBoolean);
    18031803        break;
    1804            
     1804    }
     1805           
     1806    case GetEnumerableLength: {
     1807        forNode(node).setType(SpecInt32);
     1808        break;
     1809    }
     1810    case HasGenericProperty: {
     1811        forNode(node).setType(SpecBoolean);
     1812        break;
     1813    }
     1814    case HasStructureProperty: {
     1815        forNode(node).setType(SpecBoolean);
     1816        break;
     1817    }
     1818    case HasIndexedProperty: {
     1819        ArrayMode mode = node->arrayMode();
     1820        switch (mode.type()) {
     1821        case Array::Int32:
     1822        case Array::Double:
     1823        case Array::Contiguous:
     1824        case Array::ArrayStorage: {
     1825            break;
     1826        }
     1827        default: {
     1828            clobberWorld(node->origin.semantic, clobberLimit);
     1829            break;
     1830        }
     1831        }
     1832        forNode(node).setType(SpecBoolean);
     1833        break;
     1834    }
     1835    case GetDirectPname: {
     1836        clobberWorld(node->origin.semantic, clobberLimit);
     1837        forNode(node).makeHeapTop();
     1838        break;
     1839    }
     1840    case GetStructurePropertyEnumerator: {
     1841        forNode(node).setType(SpecCell);
     1842        break;
     1843    }
     1844    case GetGenericPropertyEnumerator: {
     1845        forNode(node).setType(SpecCell);
     1846        break;
     1847    }
     1848    case GetEnumeratorPname: {
     1849        forNode(node).setType(SpecString | SpecOther);
     1850        break;
     1851    }
     1852    case ToIndexString: {
     1853        forNode(node).setType(SpecString);
     1854        break;
     1855    }
     1856
    18051857    case GetGlobalVar:
    18061858        forNode(node).makeHeapTop();
     
    18671919    case Phantom:
    18681920    case HardPhantom:
    1869     case Check:
    18701921    case CountExecution:
    18711922    case CheckTierUpInLoop:
    18721923    case CheckTierUpAtReturn:
    18731924        break;
     1925
     1926    case Check: {
     1927        // Simplify out checks that don't actually do checking.
     1928        for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
     1929            Edge edge = node->children.child(i);
     1930            if (!edge)
     1931                break;
     1932            if (edge.isProved() || edge.willNotHaveCheck()) {
     1933                m_state.setFoundConstants(true);
     1934                break;
     1935            }
     1936        }
     1937        break;
     1938    }
    18741939
    18751940    case StoreBarrier: {
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r172149 r172176  
    11081108        addToGraph(CheckFunction, OpInfo(m_graph.freeze(function)), callTarget, thisArgument);
    11091109    else {
    1110         ASSERT(callLinkStatus.structure());
    11111110        ASSERT(callLinkStatus.executable());
    11121111       
    1113         addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(callLinkStatus.structure())), callTarget);
    11141112        addToGraph(CheckExecutable, OpInfo(callLinkStatus.executable()), callTarget, thisArgument);
    11151113    }
     
    32093207        }
    32103208
     3209        case op_get_enumerable_length: {
     3210            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetEnumerableLength,
     3211                get(VirtualRegister(currentInstruction[2].u.operand))));
     3212            NEXT_OPCODE(op_get_enumerable_length);
     3213        }
     3214
     3215        case op_has_generic_property: {
     3216            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(HasGenericProperty,
     3217                get(VirtualRegister(currentInstruction[2].u.operand)),
     3218                get(VirtualRegister(currentInstruction[3].u.operand))));
     3219            NEXT_OPCODE(op_has_generic_property);
     3220        }
     3221
     3222        case op_has_structure_property: {
     3223            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(HasStructureProperty,
     3224                get(VirtualRegister(currentInstruction[2].u.operand)),
     3225                get(VirtualRegister(currentInstruction[3].u.operand)),
     3226                get(VirtualRegister(currentInstruction[4].u.operand))));
     3227            NEXT_OPCODE(op_has_structure_property);
     3228        }
     3229
     3230        case op_has_indexed_property: {
     3231            Node* base = get(VirtualRegister(currentInstruction[2].u.operand));
     3232            ArrayMode arrayMode = getArrayModeConsideringSlowPath(currentInstruction[4].u.arrayProfile, Array::Read);
     3233            Node* property = get(VirtualRegister(currentInstruction[3].u.operand));
     3234            Node* hasIterableProperty = addToGraph(HasIndexedProperty, OpInfo(arrayMode.asWord()), base, property);
     3235            set(VirtualRegister(currentInstruction[1].u.operand), hasIterableProperty);
     3236            NEXT_OPCODE(op_has_indexed_property);
     3237        }
     3238
     3239        case op_get_direct_pname: {
     3240            SpeculatedType prediction = getPredictionWithoutOSRExit();
     3241           
     3242            Node* base = get(VirtualRegister(currentInstruction[2].u.operand));
     3243            Node* property = get(VirtualRegister(currentInstruction[3].u.operand));
     3244            Node* index = get(VirtualRegister(currentInstruction[4].u.operand));
     3245            Node* enumerator = get(VirtualRegister(currentInstruction[5].u.operand));
     3246
     3247            addVarArgChild(base);
     3248            addVarArgChild(property);
     3249            addVarArgChild(index);
     3250            addVarArgChild(enumerator);
     3251            set(VirtualRegister(currentInstruction[1].u.operand),
     3252                addToGraph(Node::VarArg, GetDirectPname, OpInfo(0), OpInfo(prediction)));
     3253
     3254            NEXT_OPCODE(op_get_direct_pname);
     3255        }
     3256
     3257        case op_get_structure_property_enumerator: {
     3258            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetStructurePropertyEnumerator,
     3259                get(VirtualRegister(currentInstruction[2].u.operand)),
     3260                get(VirtualRegister(currentInstruction[3].u.operand))));
     3261            NEXT_OPCODE(op_get_structure_property_enumerator);
     3262        }
     3263
     3264        case op_get_generic_property_enumerator: {
     3265            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetGenericPropertyEnumerator,
     3266                get(VirtualRegister(currentInstruction[2].u.operand)),
     3267                get(VirtualRegister(currentInstruction[3].u.operand)),
     3268                get(VirtualRegister(currentInstruction[4].u.operand))));
     3269            NEXT_OPCODE(op_get_generic_property_enumerator);
     3270        }
     3271
     3272        case op_next_enumerator_pname: {
     3273            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetEnumeratorPname,
     3274                get(VirtualRegister(currentInstruction[2].u.operand)),
     3275                get(VirtualRegister(currentInstruction[3].u.operand))));
     3276            NEXT_OPCODE(op_next_enumerator_pname);
     3277        }
     3278
     3279        case op_to_index_string: {
     3280            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(ToIndexString,
     3281                get(VirtualRegister(currentInstruction[2].u.operand))));
     3282            NEXT_OPCODE(op_to_index_string);
     3283        }
     3284
    32113285        default:
    32123286            // Parse failed! This should not happen because the capabilities checker
  • trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp

    r172129 r172176  
    194194    case op_in:
    195195    case op_get_from_scope:
     196    case op_get_enumerable_length:
     197    case op_has_generic_property:
     198    case op_has_structure_property:
     199    case op_has_indexed_property:
     200    case op_get_direct_pname:
     201    case op_get_structure_property_enumerator:
     202    case op_get_generic_property_enumerator:
     203    case op_next_enumerator_pname:
     204    case op_to_index_string:
    196205        return CanCompileAndInline;
    197206
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r172129 r172176  
    148148        return;
    149149       
     150    case HasGenericProperty:
     151    case HasStructureProperty:
     152    case GetEnumerableLength:
     153    case GetStructurePropertyEnumerator:
     154    case GetGenericPropertyEnumerator: {
     155        read(World);
     156        write(SideState);
     157        return;
     158    }
     159
     160    case GetDirectPname: {
     161        // This reads and writes world because it can end up calling a generic getByVal
     162        // if the Structure changed, which could in turn end up calling a getter.
     163        read(World);
     164        write(World);
     165        return;
     166    }
     167
     168    case ToIndexString:
     169    case GetEnumeratorPname: {
     170        def(PureValue(node));
     171        return;
     172    }
     173
     174    case HasIndexedProperty: {
     175        read(JSObject_butterfly);
     176        ArrayMode mode = node->arrayMode();
     177        switch (mode.type()) {
     178        case Array::Int32: {
     179            if (mode.isInBounds()) {
     180                read(Butterfly_publicLength);
     181                read(IndexedInt32Properties);
     182                def(HeapLocation(HasIndexedPropertyLoc, IndexedInt32Properties, node->child1(), node->child2()), node);
     183                return;
     184            }
     185            read(World);
     186            return;
     187        }
     188           
     189        case Array::Double: {
     190            if (mode.isInBounds()) {
     191                read(Butterfly_publicLength);
     192                read(IndexedDoubleProperties);
     193                def(HeapLocation(HasIndexedPropertyLoc, IndexedDoubleProperties, node->child1(), node->child2()), node);
     194                return;
     195            }
     196            read(World);
     197            return;
     198        }
     199           
     200        case Array::Contiguous: {
     201            if (mode.isInBounds()) {
     202                read(Butterfly_publicLength);
     203                read(IndexedContiguousProperties);
     204                def(HeapLocation(HasIndexedPropertyLoc, IndexedContiguousProperties, node->child1(), node->child2()), node);
     205                return;
     206            }
     207            read(World);
     208            return;
     209        }
     210
     211        case Array::ArrayStorage: {
     212            if (mode.isInBounds()) {
     213                read(Butterfly_vectorLength);
     214                read(IndexedArrayStorageProperties);
     215                return;
     216            }
     217            read(World);
     218            return;
     219        }
     220
     221        default: {
     222            read(World);
     223            write(World);
     224            return;
     225        }
     226        }
     227        RELEASE_ASSERT_NOT_REACHED();
     228        return;
     229    }
     230
    150231    case ArithAdd:
    151232    case ArithSub:
  • trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp

    r172129 r172176  
    8787            Node* node = block->at(indexInBlock);
    8888
     89            bool alreadyHandled = false;
    8990            bool eliminated = false;
    9091                   
     
    174175               
    175176                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                alreadyHandled = true; // Don't allow the default constant folder to do things to this.
    177178               
    178179                for (unsigned i = 0; i < data.variants.size(); ++i) {
     
    182183                        data.variants[i--] = data.variants.last();
    183184                        data.variants.removeLast();
     185                        changed = true;
    184186                    }
    185187                }
     
    190192                emitGetByOffset(
    191193                    indexInBlock, node, baseValue, data.variants[0], data.identifierNumber);
     194                changed = true;
    192195                break;
    193196            }
     
    201204
    202205                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.
     206                alreadyHandled = true; // Don't allow the default constant folder to do things to this.
    204207               
    205208
     
    211214                        data.variants[i--] = data.variants.last();
    212215                        data.variants.removeLast();
     216                        changed = true;
    213217                        continue;
    214218                    }
     
    219223                            variant.oldStructure(),
    220224                            variant.offset());
     225                        changed = true;
    221226                    }
    222227                }
     
    227232                emitPutByOffset(
    228233                    indexInBlock, node, baseValue, data.variants[0], data.identifierNumber);
     234                changed = true;
    229235                break;
    230236            }
     
    239245
    240246                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.
     247                alreadyHandled = true; // Don't allow the default constant folder to do things to this.
    242248
    243249                if (baseValue.m_structure.isTop() || baseValue.m_structure.isClobbered()
     
    261267                if (status.numVariants() == 1) {
    262268                    emitGetByOffset(indexInBlock, node, baseValue, status[0], identifierNumber);
     269                    changed = true;
    263270                    break;
    264271                }
     
    271278                data->identifierNumber = identifierNumber;
    272279                node->convertToMultiGetByOffset(data);
     280                changed = true;
    273281                break;
    274282            }
     
    287295
    288296                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.
     297                alreadyHandled = true; // Don't allow the default constant folder to do things to this.
    290298
    291299                if (baseValue.m_structure.isTop() || baseValue.m_structure.isClobbered())
     
    302310                    break;
    303311               
     312                ASSERT(status.numVariants());
     313               
     314                if (status.numVariants() > 1 && !isFTL(m_graph.m_plan.mode))
     315                    break;
     316               
     317                changed = true;
     318               
    304319                for (unsigned i = status.numVariants(); i--;)
    305320                    addChecks(origin, indexInBlock, status[i].constantChecks());
     
    310325                }
    311326               
    312                 if (!isFTL(m_graph.m_plan.mode))
    313                     break;
     327                ASSERT(isFTL(m_graph.m_plan.mode));
    314328
    315329                MultiPutByOffsetData* data = m_graph.m_multiPutByOffsetData.add();
     
    325339               
    326340                node->convertToIdentity();
     341                changed = true;
    327342                break;
    328343            }
     
    355370                break;
    356371            }
     372               
     373            case Check: {
     374                alreadyHandled = true;
     375                m_interpreter.execute(indexInBlock);
     376                for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
     377                    Edge edge = node->children.child(i);
     378                    if (!edge)
     379                        break;
     380                    if (edge.isProved() || edge.willNotHaveCheck()) {
     381                        node->children.removeEdge(i--);
     382                        changed = true;
     383                    }
     384                }
     385                break;
     386            }
    357387
    358388            default:
    359389                break;
    360390            }
    361                
     391           
    362392            if (eliminated) {
    363393                changed = true;
     
    365395            }
    366396               
     397            if (alreadyHandled)
     398                continue;
     399           
    367400            m_interpreter.execute(indexInBlock);
    368401            if (!m_state.isValid()) {
  • trunk/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp

    r172129 r172176  
    5050       
    5151        // First reset the counts to 0 for all nodes.
     52        //
     53        // Also take this opportunity to pretend that Check nodes are not NodeMustGenerate. Check
     54        // nodes are MustGenerate because they are executed for effect, but they follow the same
     55        // DCE rules as nodes that aren't MustGenerate: they only contribute to the ref count of
     56        // their children if the edges require checks. Non-checking edges are removed. Note that
     57        // for any Checks left over, this phase will turn them back into NodeMustGenerate.
    5258        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
    5359            BasicBlock* block = m_graph.block(blockIndex);
    5460            if (!block)
    5561                continue;
    56             for (unsigned indexInBlock = block->size(); indexInBlock--;)
    57                 block->at(indexInBlock)->setRefCount(0);
     62            for (unsigned indexInBlock = block->size(); indexInBlock--;) {
     63                Node* node = block->at(indexInBlock);
     64                if (node->op() == Check)
     65                    node->clearFlags(NodeMustGenerate);
     66                node->setRefCount(0);
     67            }
    5868            for (unsigned phiIndex = block->phis.size(); phiIndex--;)
    5969                block->phis[phiIndex]->setRefCount(0);
     
    120130        }
    121131       
     132        // Just do a basic HardPhantom/Phantom/Check clean-up.
     133        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
     134            BasicBlock* block = m_graph.block(blockIndex);
     135            if (!block)
     136                continue;
     137            unsigned sourceIndex = 0;
     138            unsigned targetIndex = 0;
     139            while (sourceIndex < block->size()) {
     140                Node* node = block->at(sourceIndex++);
     141                switch (node->op()) {
     142                case Check:
     143                case HardPhantom:
     144                case Phantom:
     145                    if (node->children.isEmpty())
     146                        continue;
     147                    break;
     148                default:
     149                    break;
     150                }
     151                block->at(targetIndex++) = node;
     152            }
     153            block->resize(targetIndex);
     154        }
     155       
    122156        m_graph.m_refCountState = ExactRefCount;
    123157       
     
    130164        // We may have an "unproved" untyped use for code that is unreachable. The CFA
    131165        // will just not have gotten around to it.
    132         if (edge.willNotHaveCheck())
     166        if (edge.isProved() || edge.willNotHaveCheck())
    133167            return;
    134168        if (!edge->postfixRef())
     
    146180    {
    147181        // Don't count edges that are already counted for their type checks.
    148         if (edge.willHaveCheck())
     182        if (!(edge.isProved() || edge.willNotHaveCheck()))
    149183            return;
    150184        countNode(edge.node());
     
    215249                        Edge edge = m_graph.m_varArgChildren[childIdx];
    216250
    217                         if (!edge || edge.willNotHaveCheck())
     251                        if (!edge || edge.isProved() || edge.willNotHaveCheck())
    218252                            continue;
    219253
    220                         m_insertionSet.insertNode(indexInBlock, SpecNone, Phantom, node->origin, edge);
     254                        m_insertionSet.insertNode(indexInBlock, SpecNone, Check, node->origin, edge);
    221255                    }
    222256
     
    227261                }
    228262
    229                 node->convertToPhantom();
    230                 eliminateIrrelevantPhantomChildren(node);
     263                node->convertToCheck();
     264                for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
     265                    Edge edge = node->children.child(i);
     266                    if (!edge)
     267                        continue;
     268                    if (edge.isProved() || edge.willNotHaveCheck())
     269                        node->children.removeEdge(i--);
     270                }
    231271                node->setRefCount(1);
    232272                break;
     
    237277    }
    238278   
    239     void eliminateIrrelevantPhantomChildren(Node* node)
    240     {
    241         for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
    242             Edge edge = node->children.child(i);
    243             if (!edge)
    244                 continue;
    245             if (edge.willNotHaveCheck())
    246                 node->children.removeEdge(i--);
    247         }
    248     }
    249    
    250279    template<typename VariablesVectorType>
    251280    void cleanVariables(VariablesVectorType& variables)
     
    255284            if (!node)
    256285                continue;
    257             if (node->op() != Phantom && node->shouldGenerate())
     286            if (node->op() != Phantom && node->op() != Check && node->shouldGenerate())
    258287                continue;
    259288            if (node->op() == GetLocal) {
  • trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp

    r171660 r172176  
    190190    case GetGetterSetterByOffset:
    191191    case PutByOffset:
     192    case GetEnumerableLength:
     193    case HasGenericProperty:
     194    case HasStructureProperty:
     195    case HasIndexedProperty:
     196    case GetDirectPname:
    192197    case FiatInt52:
    193198    case BooleanToNumber:
     
    214219    case NewTypedArray:
    215220    case ThrowReferenceError:
     221    case GetStructurePropertyEnumerator:
     222    case GetGenericPropertyEnumerator:
     223    case GetEnumeratorPname:
     224    case ToIndexString:
    216225        return true;
    217226       
  • trunk/Source/JavaScriptCore/dfg/DFGEdge.cpp

    r164229 r172176  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3737{
    3838    if (useKindUnchecked() != UntypedUse) {
    39         if (needsCheck())
     39        if (!isProved())
    4040            out.print("Check:");
    4141        out.print(useKind(), ":");
  • trunk/Source/JavaScriptCore/dfg/DFGEdge.h

    r167325 r172176  
    116116        return proofStatus() == IsProved;
    117117    }
    118     bool needsCheck() const
    119     {
    120         return proofStatus() == NeedsCheck;
    121     }
    122118   
    123119    bool willNotHaveCheck() const
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r172129 r172176  
    899899        }
    900900
    901         case CheckExecutable:
     901        case CheckExecutable: {
     902            fixEdge<FunctionUse>(node->child1());
     903            break;
     904        }
     905           
    902906        case CheckStructure:
    903907        case CheckFunction:
     
    10411045            }
    10421046            break;
     1047
     1048        case GetEnumerableLength: {
     1049            fixEdge<CellUse>(node->child1());
     1050            break;
     1051        }
     1052        case HasGenericProperty: {
     1053            fixEdge<StringUse>(node->child2());
     1054            break;
     1055        }
     1056        case HasStructureProperty: {
     1057            fixEdge<StringUse>(node->child2());
     1058            fixEdge<KnownCellUse>(node->child3());
     1059            break;
     1060        }
     1061        case HasIndexedProperty: {
     1062            node->setArrayMode(
     1063                node->arrayMode().refine(
     1064                    m_graph, node,
     1065                    node->child1()->prediction(),
     1066                    node->child2()->prediction(),
     1067                    SpecNone, node->flags()));
     1068           
     1069            blessArrayOperation(node->child1(), node->child2(), node->child3());
     1070            fixEdge<CellUse>(node->child1());
     1071            fixEdge<KnownInt32Use>(node->child2());
     1072            break;
     1073        }
     1074        case GetDirectPname: {
     1075            Edge& base = m_graph.varArgChild(node, 0);
     1076            Edge& property = m_graph.varArgChild(node, 1);
     1077            Edge& index = m_graph.varArgChild(node, 2);
     1078            Edge& enumerator = m_graph.varArgChild(node, 3);
     1079            fixEdge<CellUse>(base);
     1080            fixEdge<KnownCellUse>(property);
     1081            fixEdge<KnownInt32Use>(index);
     1082            fixEdge<KnownCellUse>(enumerator);
     1083            break;
     1084        }
     1085        case GetStructurePropertyEnumerator: {
     1086            fixEdge<CellUse>(node->child1());
     1087            fixEdge<KnownInt32Use>(node->child2());
     1088            break;
     1089        }
     1090        case GetGenericPropertyEnumerator: {
     1091            fixEdge<CellUse>(node->child1());
     1092            fixEdge<KnownInt32Use>(node->child2());
     1093            fixEdge<KnownCellUse>(node->child3());
     1094            break;
     1095        }
     1096        case GetEnumeratorPname: {
     1097            fixEdge<KnownCellUse>(node->child1());
     1098            fixEdge<KnownInt32Use>(node->child2());
     1099            break;
     1100        }
     1101        case ToIndexString: {
     1102            fixEdge<KnownInt32Use>(node->child1());
     1103            break;
     1104        }
    10431105           
    10441106#if !ASSERT_DISABLED
     
    15441606        case KnownCellUse:
    15451607        case ObjectUse:
     1608        case FunctionUse:
    15461609        case StringUse:
    15471610        case KnownStringUse:
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp

    r172129 r172176  
    158158
    159159    unsigned refCount = node->refCount();
    160     bool skipped = !refCount;
    161160    bool mustGenerate = node->mustGenerate();
    162161    if (mustGenerate)
     
    182181    //         id#  - the index in the CodeBlock of an identifier { if codeBlock is passed to dump(), the string representation is displayed }.
    183182    //         var# - the index of a var on the global object, used by GetGlobalVar/PutGlobalVar operations.
    184     out.printf("% 4d:%s<%c%u:", (int)node->index(), skipped ? "  skipped  " : "           ", mustGenerate ? '!' : ' ', refCount);
    185     if (node->hasResult() && !skipped && node->hasVirtualRegister())
     183    out.printf("% 4d:<%c%u:", (int)node->index(), mustGenerate ? '!' : ' ', refCount);
     184    if (node->hasResult() && node->hasVirtualRegister() && node->virtualRegister().isValid())
    186185        out.print(node->virtualRegister());
    187186    else
     
    353352    out.print(")");
    354353
    355     if (!skipped) {
    356         if (node->hasVariableAccessData(*this) && node->tryGetVariableAccessData())
    357             out.print("  predicting ", SpeculationDump(node->tryGetVariableAccessData()->prediction()));
    358         else if (node->hasHeapPrediction())
    359             out.print("  predicting ", SpeculationDump(node->getHeapPrediction()));
    360     }
     354    if (node->hasVariableAccessData(*this) && node->tryGetVariableAccessData())
     355        out.print("  predicting ", SpeculationDump(node->tryGetVariableAccessData()->prediction()));
     356    else if (node->hasHeapPrediction())
     357        out.print("  predicting ", SpeculationDump(node->getHeapPrediction()));
    361358   
    362359    out.print("\n");
  • trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp

    r172129 r172176  
    109109        return;
    110110       
     111    case HasIndexedPropertyLoc:
     112        out.print("HasIndexedPorpertyLoc");
     113        return;
     114       
    111115    case IndexedPropertyLoc:
    112116        out.print("IndexedPorpertyLoc");
  • trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.h

    r172129 r172176  
    4545    GetterLoc,
    4646    GlobalVariableLoc,
     47    HasIndexedPropertyLoc,
    4748    IndexedPropertyLoc,
    4849    IndexedPropertyStorageLoc,
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r172129 r172176  
    10021002    {
    10031003        switch (op()) {
     1004        case GetDirectPname:
    10041005        case GetById:
    10051006        case GetByIdFlush:
     
    12681269        case ArrayPush:
    12691270        case ArrayPop:
     1271        case HasIndexedProperty:
    12701272            return true;
    12711273        default:
  • trunk/Source/JavaScriptCore/dfg/DFGNodeFlags.h

    r171613 r172176  
    7070
    7171#define NodeIsFlushed                   0x20000 // Used by Graph::computeIsFlushed(), will tell you which local nodes are backwards-reachable from a Flush.
     72
     73#define NodeMiscFlag1                   0x40000
     74#define NodeMiscFlag2                   0x80000
    7275
    7376typedef uint32_t NodeFlags;
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r171660 r172176  
    6262    macro(Phantom, NodeMustGenerate) \
    6363    macro(HardPhantom, NodeMustGenerate) /* Like Phantom, but we never remove any of its children. */ \
    64     macro(Check, 0) /* Used if we want just a type check but not liveness. DCE eithers kills this or converts it to Phantom. */\
     64    macro(Check, NodeMustGenerate) /* Used if we want just a type check but not liveness. Non-checking uses will be removed. */\
    6565    macro(Upsilon, NodeRelevantToOSR) \
    6666    macro(Phi, NodeRelevantToOSR) \
     
    294294    macro(StoreBarrier, NodeMustGenerate) \
    295295    macro(StoreBarrierWithNullCheck, NodeMustGenerate) \
     296    \
     297    /* For-in enumeration opcodes */\
     298    macro(GetEnumerableLength, NodeMustGenerate | NodeResultJS) \
     299    macro(HasIndexedProperty, NodeResultBoolean) \
     300    macro(HasStructureProperty, NodeResultBoolean) \
     301    macro(HasGenericProperty, NodeResultBoolean) \
     302    macro(GetDirectPname, NodeMustGenerate | NodeHasVarArgs | NodeResultJS) \
     303    macro(GetStructurePropertyEnumerator, NodeMustGenerate | NodeResultJS) \
     304    macro(GetGenericPropertyEnumerator, NodeMustGenerate | NodeResultJS) \
     305    macro(GetEnumeratorPname, NodeMustGenerate | NodeResultJS) \
     306    macro(ToIndexString, NodeResultJS)
    296307
    297308// This enum generates a monotonically increasing id for all Node types,
  • trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp

    r172129 r172176  
    9797            while (sourceIndex < block->size()) {
    9898                Node* node = block->at(sourceIndex++);
    99                 if (node->op() == Phantom) {
     99                switch (node->op()) {
     100                case Phantom: {
    100101                    if (lastNode && (lastNode->origin.forExit != node->origin.forExit || (lastNode->flags() & NodeHasVarArgs)))
    101102                        lastNode = nullptr;
     
    104105                        if (!edge)
    105106                            break;
    106                         if (edge.useKind() != UntypedUse)
     107                        if (edge.willHaveCheck())
    107108                            continue; // Keep the type check.
    108109                        if (edge->flags() & NodeRelevantToOSR) {
     
    124125                    }
    125126                   
     127                    if (node->children.isEmpty()) {
     128                        changed = true;
     129                        continue;
     130                    }
     131                    break;
     132                }
     133                   
     134                case Check: {
     135                    for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
     136                        Edge edge = node->children.child(i);
     137                        if (!edge)
     138                            break;
     139                        if (edge.willHaveCheck())
     140                            continue;
     141                        node->children.removeEdge(i--);
     142                        changed = true;
     143                    }
     144                    if (node->children.isEmpty()) {
     145                        changed = true;
     146                        continue;
     147                    }
     148                    break;
     149                }
     150                   
     151                case HardPhantom: {
    126152                    if (node->children.isEmpty())
    127153                        continue;
     154                    break;
     155                }
     156                   
     157                default:
     158                    break;
    128159                }
    129160                lastNode = node;
  • trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.h

    r172129 r172176  
    3535// Cleans up unnecessary Phantoms and Phanton children. This reduces live ranges, but also, it
    3636// eliminates many Phantoms entirely. This invalidates liveness analysis.
     37//
     38// This should work over all IR forms; however, in SSA form it's better to run
     39// PhantomCanonicalizationPhase since it's more powerful.
    3740
    3841bool performPhantomRemoval(Graph&);
  • trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp

    r172129 r172176  
    5050#include "DFGOSRAvailabilityAnalysisPhase.h"
    5151#include "DFGOSREntrypointCreationPhase.h"
     52#include "DFGPhantomCanonicalizationPhase.h"
    5253#include "DFGPhantomRemovalPhase.h"
    5354#include "DFGPredictionInjectionPhase.h"
     
    312313        }
    313314       
    314         performPhantomRemoval(dfg);
     315        performPhantomRemoval(dfg); // Reduce the graph size a bit.
    315316        performCriticalEdgeBreaking(dfg);
    316317        performLoopPreHeaderCreation(dfg);
     
    322323        performCFA(dfg);
    323324        performConstantFolding(dfg);
     325        performPhantomCanonicalization(dfg); // Reduce the graph size a lot.
    324326        if (performStrengthReduction(dfg)) {
    325327            // State-at-tail and state-at-head will be invalid if we did strength reduction since
     
    329331        }
    330332        performLICM(dfg);
    331         performPhantomRemoval(dfg);
     333        performPhantomCanonicalization(dfg);
    332334        performIntegerCheckCombining(dfg);
    333335        performGlobalCSE(dfg);
     
    338340       
    339341        performStoreBarrierElision(dfg);
    340         performPhantomRemoval(dfg);
     342        performPhantomCanonicalization(dfg);
    341343        performLivenessAnalysis(dfg);
    342344        performCFA(dfg);
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r171660 r172176  
    186186        case GetByOffset:
    187187        case MultiGetByOffset:
     188        case GetDirectPname:
    188189        case Call:
    189190        case Construct:
     
    584585            changed |= setPrediction(SpecBoolean);
    585586            break;
     587
     588        case GetEnumerableLength: {
     589            changed |= setPrediction(SpecInt32);
     590            break;
     591        }
     592        case HasGenericProperty: {
     593            changed |= setPrediction(SpecBoolean);
     594            break;
     595        }
     596        case HasStructureProperty: {
     597            changed |= setPrediction(SpecBoolean);
     598            break;
     599        }
     600        case HasIndexedProperty: {
     601            changed |= setPrediction(SpecBoolean);
     602            break;
     603        }
     604        case GetStructurePropertyEnumerator: {
     605            changed |= setPrediction(SpecCell);
     606            break;
     607        }
     608        case GetGenericPropertyEnumerator: {
     609            changed |= setPrediction(SpecCell);
     610            break;
     611        }
     612        case GetEnumeratorPname: {
     613            changed |= setPrediction(SpecCell | SpecOther);
     614            break;
     615        }
     616        case ToIndexString: {
     617            changed |= setPrediction(SpecString);
     618            break;
     619        }
    586620
    587621#ifndef NDEBUG
  • trunk/Source/JavaScriptCore/dfg/DFGSSALoweringPhase.cpp

    r164229 r172176  
    7070        switch (m_node->op()) {
    7171        case GetByVal:
     72        case HasIndexedProperty:
    7273            lowerBoundsCheck(m_node->child1(), m_node->child2(), m_node->child3());
    7374            break;
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r171660 r172176  
    5454        case CellUse:
    5555        case ObjectUse:
     56        case FunctionUse:
    5657        case FinalObjectUse:
    5758        case ObjectOrOtherUse:
     
    259260    case GetGetter:
    260261    case GetSetter:
     262    case GetEnumerableLength:
     263    case HasGenericProperty:
     264    case HasStructureProperty:
     265    case HasIndexedProperty:
     266    case GetDirectPname:
     267    case GetStructurePropertyEnumerator:
     268    case GetGenericPropertyEnumerator:
     269    case GetEnumeratorPname:
     270    case ToIndexString:
    261271        return true;
    262272
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r171662 r172176  
    713713    }
    714714    case Array::Arguments:
    715         speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node,
    716             m_jit.branch8(
    717                 MacroAssembler::NotEqual,
    718                 MacroAssembler::Address(baseReg, JSCell::typeInfoTypeOffset()),
    719                 MacroAssembler::TrustedImm32(ArgumentsType)));
     715        speculateCellTypeWithoutTypeFiltering(node->child1(), baseReg, ArgumentsType);
    720716
    721717        noResult(m_currentNode);
    722718        return;
    723719    default:
    724         speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node,
    725             m_jit.branch8(
    726                 MacroAssembler::NotEqual,
    727                 MacroAssembler::Address(baseReg, JSCell::typeInfoTypeOffset()),
    728                 MacroAssembler::TrustedImm32(typeForTypedArrayType(node->arrayMode().typedArrayType()))));
     720        speculateCellTypeWithoutTypeFiltering(
     721            node->child1(), baseReg,
     722            typeForTypedArrayType(node->arrayMode().typedArrayType()));
    729723        noResult(m_currentNode);
    730724        return;
     
    45094503}
    45104504
     4505void SpeculativeJIT::speculateCellTypeWithoutTypeFiltering(
     4506    Edge edge, GPRReg cellGPR, JSType jsType)
     4507{
     4508    speculationCheck(
     4509        BadType, JSValueSource::unboxedCell(cellGPR), edge,
     4510        m_jit.branch8(
     4511            MacroAssembler::NotEqual,
     4512            MacroAssembler::Address(cellGPR, JSCell::typeInfoTypeOffset()),
     4513            MacroAssembler::TrustedImm32(jsType)));
     4514}
     4515
     4516void SpeculativeJIT::speculateCellType(
     4517    Edge edge, GPRReg cellGPR, SpeculatedType specType, JSType jsType)
     4518{
     4519    DFG_TYPE_CHECK(
     4520        JSValueSource::unboxedCell(cellGPR), edge, specType,
     4521        m_jit.branch8(
     4522            MacroAssembler::NotEqual,
     4523            MacroAssembler::Address(cellGPR, JSCell::typeInfoTypeOffset()),
     4524            TrustedImm32(jsType)));
     4525}
     4526
    45114527void SpeculativeJIT::speculateInt32(Edge edge)
    45124528{
     
    45824598}
    45834599
     4600void SpeculativeJIT::speculateFunction(Edge edge)
     4601{
     4602    if (!needsTypeCheck(edge, SpecFunction))
     4603        return;
     4604   
     4605    SpeculateCellOperand operand(this, edge);
     4606    speculateCellType(edge, operand.gpr(), SpecFunction, JSFunctionType);
     4607}
     4608
    45844609void SpeculativeJIT::speculateFinalObject(Edge edge)
    45854610{
     
    45884613   
    45894614    SpeculateCellOperand operand(this, edge);
    4590     GPRReg gpr = operand.gpr();
    4591     DFG_TYPE_CHECK(
    4592         JSValueSource::unboxedCell(gpr), edge, SpecFinalObject, m_jit.branch8(
    4593             MacroAssembler::NotEqual,
    4594             MacroAssembler::Address(gpr, JSCell::typeInfoTypeOffset()),
    4595             TrustedImm32(FinalObjectType)));
     4615    speculateCellType(edge, operand.gpr(), SpecFinalObject, FinalObjectType);
    45964616}
    45974617
     
    48364856    case ObjectUse:
    48374857        speculateObject(edge);
     4858        break;
     4859    case FunctionUse:
     4860        speculateFunction(edge);
    48384861        break;
    48394862    case FinalObjectUse:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r171613 r172176  
    10351035        return appendCallWithExceptionCheckSetResult(operation, result);
    10361036    }
     1037    JITCompiler::Call callOperation(C_JITOperation_ECZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
     1038    {
     1039        m_jit.setupArgumentsWithExecState(arg1, arg2);
     1040        return appendCallWithExceptionCheckSetResult(operation, result);
     1041    }
     1042    JITCompiler::Call callOperation(C_JITOperation_ECZC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
     1043    {
     1044        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
     1045        return appendCallWithExceptionCheckSetResult(operation, result);
     1046    }
    10371047    JITCompiler::Call callOperation(C_JITOperation_ECC operation, GPRReg result, GPRReg arg1, JSCell* cell)
    10381048    {
     
    11321142        m_jit.setupArgumentsExecState();
    11331143        return appendCallWithCallFrameRollbackOnExceptionSetResult(operation, result);
     1144    }
     1145    JITCompiler::Call callOperation(Z_JITOperation_EC operation, GPRReg result, GPRReg arg1)
     1146    {
     1147        m_jit.setupArgumentsWithExecState(arg1);
     1148        return appendCallWithExceptionCheckSetResult(operation, result);
    11341149    }
    11351150
     
    12591274        return appendCallWithExceptionCheckSetResult(operation, result);
    12601275    }
     1276    JITCompiler::Call callOperation(J_JITOperation_ECZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
     1277    {
     1278        m_jit.setupArgumentsWithExecState(arg1, arg2);
     1279        return appendCallWithExceptionCheckSetResult(operation, result);
     1280    }
    12611281    JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg result, StructureStubInfo* stubInfo, GPRReg arg1, const StringImpl* uid)
    12621282    {
     
    12701290    }
    12711291    JITCompiler::Call callOperation(J_JITOperation_EDA operation, GPRReg result, FPRReg arg1, GPRReg arg2)
     1292    {
     1293        m_jit.setupArgumentsWithExecState(arg1, arg2);
     1294        return appendCallWithExceptionCheckSetResult(operation, result);
     1295    }
     1296    JITCompiler::Call callOperation(J_JITOperation_EJC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
     1297    {
     1298        m_jit.setupArgumentsWithExecState(arg1, arg2);
     1299        return appendCallWithExceptionCheckSetResult(operation, result);
     1300    }
     1301    JITCompiler::Call callOperation(J_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
    12721302    {
    12731303        m_jit.setupArgumentsWithExecState(arg1, arg2);
     
    13201350    {
    13211351        m_jit.setupArgumentsWithExecState(arg1);
     1352        return appendCallWithExceptionCheckSetResult(operation, result);
     1353    }
     1354    JITCompiler::Call callOperation(C_JITOperation_EJJC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
     1355    {
     1356        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
     1357        return appendCallWithExceptionCheckSetResult(operation, result);
     1358    }
     1359    JITCompiler::Call callOperation(C_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
     1360    {
     1361        m_jit.setupArgumentsWithExecState(arg1, arg2);
     1362        return appendCallWithExceptionCheckSetResult(operation, result);
     1363    }
     1364    JITCompiler::Call callOperation(C_JITOperation_EJZC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
     1365    {
     1366        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
    13221367        return appendCallWithExceptionCheckSetResult(operation, result);
    13231368    }
     
    14951540        return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
    14961541    }
     1542    JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg resultPayload, GPRReg resultTag, GPRReg arg1)
     1543    {
     1544        m_jit.setupArgumentsWithExecState(arg1);
     1545        return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
     1546    }
     1547    JITCompiler::Call callOperation(J_JITOperation_EJC operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
     1548    {
     1549        m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
     1550        return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
     1551    }
    14971552    JITCompiler::Call callOperation(J_JITOperation_EJssZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
    14981553    {
     
    15241579    {
    15251580        m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
     1581        return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
     1582    }
     1583    JITCompiler::Call callOperation(J_JITOperation_ECZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
     1584    {
     1585        m_jit.setupArgumentsWithExecState(arg1, arg2);
    15261586        return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
    15271587    }
     
    22122272    void typeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail);
    22132273   
     2274    void speculateCellTypeWithoutTypeFiltering(Edge, GPRReg cellGPR, JSType);
     2275    void speculateCellType(Edge, GPRReg cellGPR, SpeculatedType, JSType);
     2276   
    22142277    void speculateInt32(Edge);
    22152278#if USE(JSVALUE64)
     
    22232286    void speculateCell(Edge);
    22242287    void speculateObject(Edge);
     2288    void speculateFunction(Edge);
    22252289    void speculateFinalObject(Edge);
    22262290    void speculateObjectOrOther(Edge);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r171662 r172176  
    3838#include "GetterSetter.h"
    3939#include "JSActivation.h"
     40#include "JSPropertyNameEnumerator.h"
    4041#include "ObjectPrototype.h"
    4142#include "JSCInlines.h"
     
    17851786
    17861787    case MovHint:
    1787     case ZombieHint:
    1788     case Check: {
     1788    case ZombieHint: {
    17891789        RELEASE_ASSERT_NOT_REACHED();
    17901790        break;
     
    37013701    case CheckExecutable: {
    37023702        SpeculateCellOperand function(this, node->child1());
     3703        speculateCellType(node->child1(), function.gpr(), SpecFunction, JSFunctionType);
    37033704        speculationCheck(BadExecutable, JSValueSource::unboxedCell(function.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, JITCompiler::Address(function.gpr(), JSFunction::offsetOfExecutable()), node->executable()));
    37043705        noResult(node);
     
    46024603    }
    46034604
     4605    case GetEnumerableLength: {
     4606        SpeculateCellOperand base(this, node->child1());
     4607        GPRResult result(this);
     4608        GPRReg resultGPR = result.gpr();
     4609
     4610        flushRegisters();
     4611        callOperation(operationGetEnumerableLength, resultGPR, base.gpr());
     4612        int32Result(resultGPR, node);
     4613        break;
     4614    }
     4615    case HasGenericProperty: {
     4616        JSValueOperand base(this, node->child1());
     4617        SpeculateCellOperand property(this, node->child2());
     4618        GPRResult resultPayload(this);
     4619        GPRResult2 resultTag(this);
     4620        GPRReg basePayloadGPR = base.payloadGPR();
     4621        GPRReg baseTagGPR = base.tagGPR();
     4622        GPRReg resultPayloadGPR = resultPayload.gpr();
     4623        GPRReg resultTagGPR = resultTag.gpr();
     4624
     4625        flushRegisters();
     4626        callOperation(operationHasGenericProperty, resultTagGPR, resultPayloadGPR, baseTagGPR, basePayloadGPR, property.gpr());
     4627        booleanResult(resultPayloadGPR, node);
     4628        break;
     4629    }
     4630    case HasStructureProperty: {
     4631        JSValueOperand base(this, node->child1());
     4632        SpeculateCellOperand property(this, node->child2());
     4633        SpeculateCellOperand enumerator(this, node->child3());
     4634        GPRTemporary scratch(this);
     4635        GPRResult resultPayload(this);
     4636        GPRResult2 resultTag(this);
     4637
     4638        GPRReg baseTagGPR = base.tagGPR();
     4639        GPRReg basePayloadGPR = base.payloadGPR();
     4640        GPRReg propertyGPR = property.gpr();
     4641        GPRReg scratchGPR = scratch.gpr();
     4642        GPRReg resultPayloadGPR = resultPayload.gpr();
     4643        GPRReg resultTagGPR = resultTag.gpr();
     4644
     4645        m_jit.load32(MacroAssembler::Address(basePayloadGPR, JSCell::structureIDOffset()), scratchGPR);
     4646        MacroAssembler::Jump wrongStructure = m_jit.branch32(MacroAssembler::NotEqual,
     4647            scratchGPR,
     4648            MacroAssembler::Address(enumerator.gpr(), JSPropertyNameEnumerator::cachedStructureIDOffset()));
     4649
     4650        moveTrueTo(resultPayloadGPR);
     4651        MacroAssembler::Jump done = m_jit.jump();
     4652
     4653        done.link(&m_jit);
     4654
     4655        addSlowPathGenerator(slowPathCall(wrongStructure, this, operationHasGenericProperty, resultTagGPR, resultPayloadGPR, baseTagGPR, basePayloadGPR, propertyGPR));
     4656        booleanResult(resultPayloadGPR, node);
     4657        break;
     4658    }
     4659    case HasIndexedProperty: {
     4660        SpeculateCellOperand base(this, node->child1());
     4661        SpeculateInt32Operand index(this, node->child2());
     4662        GPRResult resultPayload(this);
     4663        GPRResult2 resultTag(this);
     4664
     4665        GPRReg baseGPR = base.gpr();
     4666        GPRReg indexGPR = index.gpr();
     4667        GPRReg resultPayloadGPR = resultPayload.gpr();
     4668        GPRReg resultTagGPR = resultTag.gpr();
     4669
     4670        MacroAssembler::JumpList slowCases;
     4671        ArrayMode mode = node->arrayMode();
     4672        switch (mode.type()) {
     4673        case Array::Int32:
     4674        case Array::Contiguous: {
     4675            ASSERT(!!node->child3());
     4676            StorageOperand storage(this, node->child3());
     4677            GPRTemporary scratch(this);
     4678           
     4679            GPRReg storageGPR = storage.gpr();
     4680            GPRReg scratchGPR = scratch.gpr();
     4681
     4682            slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())));
     4683            m_jit.load32(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), scratchGPR);
     4684            slowCases.append(m_jit.branch32(MacroAssembler::Equal, scratchGPR, TrustedImm32(JSValue::EmptyValueTag)));
     4685            break;
     4686        }
     4687        case Array::Double: {
     4688            ASSERT(!!node->child3());
     4689            StorageOperand storage(this, node->child3());
     4690            FPRTemporary scratch(this);
     4691            FPRReg scratchFPR = scratch.fpr();
     4692            GPRReg storageGPR = storage.gpr();
     4693
     4694            slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())));
     4695            m_jit.loadDouble(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight), scratchFPR);
     4696            slowCases.append(m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, scratchFPR, scratchFPR));
     4697            break;
     4698        }
     4699        case Array::ArrayStorage: {
     4700            ASSERT(!!node->child3());
     4701            StorageOperand storage(this, node->child3());
     4702            GPRTemporary scratch(this);
     4703
     4704            GPRReg storageGPR = storage.gpr();
     4705            GPRReg scratchGPR = scratch.gpr();
     4706
     4707            slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset())));
     4708            m_jit.load32(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), scratchGPR);
     4709            slowCases.append(m_jit.branch32(MacroAssembler::Equal, scratchGPR, TrustedImm32(JSValue::EmptyValueTag)));
     4710            break;
     4711        }
     4712        default: {
     4713            slowCases.append(m_jit.jump());
     4714            break;
     4715        }
     4716        }
     4717
     4718        moveTrueTo(resultPayloadGPR);
     4719        MacroAssembler::Jump done = m_jit.jump();
     4720
     4721        addSlowPathGenerator(slowPathCall(slowCases, this, operationHasIndexedProperty, resultTagGPR, resultPayloadGPR, baseGPR, indexGPR));
     4722       
     4723        done.link(&m_jit);
     4724        booleanResult(resultPayloadGPR, node);
     4725        break;
     4726    }
     4727    case GetDirectPname: {
     4728        Edge& baseEdge = m_jit.graph().varArgChild(node, 0);
     4729        Edge& propertyEdge = m_jit.graph().varArgChild(node, 1);
     4730        Edge& indexEdge = m_jit.graph().varArgChild(node, 2);
     4731        Edge& enumeratorEdge = m_jit.graph().varArgChild(node, 3);
     4732
     4733        SpeculateCellOperand base(this, baseEdge);
     4734        SpeculateCellOperand property(this, propertyEdge);
     4735        SpeculateInt32Operand index(this, indexEdge);
     4736        SpeculateCellOperand enumerator(this, enumeratorEdge);
     4737        GPRResult resultPayload(this);
     4738        GPRResult2 resultTag(this);
     4739        GPRTemporary scratch(this);
     4740
     4741        GPRReg baseGPR = base.gpr();
     4742        GPRReg propertyGPR = property.gpr();
     4743        GPRReg indexGPR = index.gpr();
     4744        GPRReg enumeratorGPR = enumerator.gpr();
     4745        GPRReg resultTagGPR = resultTag.gpr();
     4746        GPRReg resultPayloadGPR = resultPayload.gpr();
     4747        GPRReg scratchGPR = scratch.gpr();
     4748
     4749        // Check the structure
     4750        m_jit.load32(MacroAssembler::Address(baseGPR, JSCell::structureIDOffset()), scratchGPR);
     4751        MacroAssembler::Jump wrongStructure = m_jit.branch32(MacroAssembler::NotEqual,
     4752            scratchGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedStructureIDOffset()));
     4753       
     4754        // Compute the offset
     4755        // If index is less than the enumerator's cached inline storage, then it's an inline access
     4756        MacroAssembler::Jump outOfLineAccess = m_jit.branch32(MacroAssembler::AboveOrEqual,
     4757            indexGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset()));
     4758
     4759        m_jit.move(indexGPR, scratchGPR);
     4760        m_jit.signExtend32ToPtr(scratchGPR, scratchGPR);
     4761        m_jit.load32(MacroAssembler::BaseIndex(baseGPR, scratchGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTagGPR);
     4762        m_jit.load32(MacroAssembler::BaseIndex(baseGPR, scratchGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayloadGPR);
     4763
     4764        MacroAssembler::Jump done = m_jit.jump();
     4765       
     4766        // Otherwise it's out of line
     4767        outOfLineAccess.link(&m_jit);
     4768        m_jit.move(indexGPR, scratchGPR);
     4769        m_jit.sub32(MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset()), scratchGPR);
     4770        m_jit.neg32(scratchGPR);
     4771        m_jit.signExtend32ToPtr(scratchGPR, scratchGPR);
     4772        // We use resultPayloadGPR as a temporary here. We have to make sure clobber it after getting the
     4773        // value out of indexGPR and enumeratorGPR because resultPayloadGPR could reuse either of those registers.
     4774        m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), resultPayloadGPR);
     4775        int32_t offsetOfFirstProperty = static_cast<int32_t>(offsetInButterfly(firstOutOfLineOffset)) * sizeof(EncodedJSValue);
     4776        m_jit.load32(MacroAssembler::BaseIndex(resultPayloadGPR, scratchGPR, MacroAssembler::TimesEight, offsetOfFirstProperty + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTagGPR);
     4777        m_jit.load32(MacroAssembler::BaseIndex(resultPayloadGPR, scratchGPR, MacroAssembler::TimesEight, offsetOfFirstProperty + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayloadGPR);
     4778
     4779        done.link(&m_jit);
     4780
     4781        m_jit.move(MacroAssembler::TrustedImm32(JSValue::CellTag), scratchGPR);
     4782        addSlowPathGenerator(slowPathCall(wrongStructure, this, operationGetByValCell, resultTagGPR, resultPayloadGPR, baseGPR, scratchGPR, propertyGPR));
     4783
     4784        jsValueResult(resultTagGPR, resultPayloadGPR, node);
     4785        break;
     4786    }
     4787    case GetStructurePropertyEnumerator: {
     4788        SpeculateCellOperand base(this, node->child1());
     4789        SpeculateInt32Operand length(this, node->child2());
     4790        GPRResult result(this);
     4791        GPRReg resultGPR = result.gpr();
     4792
     4793        flushRegisters();
     4794        callOperation(operationGetStructurePropertyEnumerator, resultGPR, base.gpr(), length.gpr());
     4795        cellResult(resultGPR, node);
     4796        break;
     4797    }
     4798    case GetGenericPropertyEnumerator: {
     4799        SpeculateCellOperand base(this, node->child1());
     4800        SpeculateInt32Operand length(this, node->child2());
     4801        SpeculateCellOperand enumerator(this, node->child3());
     4802        GPRResult result(this);
     4803        GPRReg resultGPR = result.gpr();
     4804
     4805        flushRegisters();
     4806        callOperation(operationGetGenericPropertyEnumerator, resultGPR, base.gpr(), length.gpr(), enumerator.gpr());
     4807        cellResult(resultGPR, node);
     4808        break;
     4809    }
     4810    case GetEnumeratorPname: {
     4811        SpeculateCellOperand enumerator(this, node->child1());
     4812        SpeculateInt32Operand index(this, node->child2());
     4813        GPRTemporary scratch(this);
     4814        GPRResult resultPayload(this);
     4815        GPRResult2 resultTag(this);
     4816
     4817        GPRReg enumeratorGPR = enumerator.gpr();
     4818        GPRReg indexGPR = index.gpr();
     4819        GPRReg scratchGPR = scratch.gpr();
     4820        GPRReg resultTagGPR = resultTag.gpr();
     4821        GPRReg resultPayloadGPR = resultPayload.gpr();
     4822
     4823        MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below,
     4824            indexGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset()));
     4825
     4826        m_jit.move(MacroAssembler::TrustedImm32(JSValue::NullTag), resultTagGPR);
     4827        m_jit.move(MacroAssembler::TrustedImm32(0), resultPayloadGPR);
     4828
     4829        MacroAssembler::Jump done = m_jit.jump();
     4830        inBounds.link(&m_jit);
     4831
     4832        m_jit.loadPtr(MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()), scratchGPR);
     4833        m_jit.loadPtr(MacroAssembler::BaseIndex(scratchGPR, indexGPR, MacroAssembler::ScalePtr), resultPayloadGPR);
     4834        m_jit.move(MacroAssembler::TrustedImm32(JSValue::CellTag), resultTagGPR);
     4835
     4836        done.link(&m_jit);
     4837        jsValueResult(resultTagGPR, resultPayloadGPR, node);
     4838        break;
     4839    }
     4840    case ToIndexString: {
     4841        SpeculateInt32Operand index(this, node->child1());
     4842        GPRResult result(this);
     4843        GPRReg resultGPR = result.gpr();
     4844
     4845        flushRegisters();
     4846        callOperation(operationToIndexString, resultGPR, index.gpr());
     4847        cellResult(resultGPR, node);
     4848        break;
     4849    }
     4850
    46044851    case ForceOSRExit: {
    46054852        terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
     
    46264873    case Phantom:
    46274874    case HardPhantom:
     4875    case Check:
    46284876        DFG_NODE_DO_TO_CHILDREN(m_jit.graph(), node, speculate);
    46294877        noResult(node);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r171662 r172176  
    3838#include "GetterSetter.h"
    3939#include "JSCInlines.h"
     40#include "JSPropertyNameEnumerator.h"
    4041#include "ObjectPrototype.h"
    4142#include "SpillRegistersMode.h"
     
    18701871       
    18711872    case MovHint:
    1872     case ZombieHint:
    1873     case Check: {
     1873    case ZombieHint: {
    18741874        DFG_CRASH(m_jit.graph(), node, "Unexpected node");
    18751875        break;
     
    37943794    case CheckExecutable: {
    37953795        SpeculateCellOperand function(this, node->child1());
     3796        speculateCellType(node->child1(), function.gpr(), SpecFunction, JSFunctionType);
    37963797        speculationCheck(BadExecutable, JSValueSource::unboxedCell(function.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, JITCompiler::Address(function.gpr(), JSFunction::offsetOfExecutable()), node->executable()));
    37973798        noResult(node);
     
    46484649    case Phantom:
    46494650    case HardPhantom:
     4651    case Check:
    46504652        DFG_NODE_DO_TO_CHILDREN(m_jit.graph(), node, speculate);
    46514653        noResult(node);
     
    46684670    case StoreBarrierWithNullCheck: {
    46694671        compileStoreBarrier(node);
     4672        break;
     4673    }
     4674
     4675    case GetEnumerableLength: {
     4676        SpeculateCellOperand base(this, node->child1());
     4677        GPRResult result(this);
     4678        GPRReg resultGPR = result.gpr();
     4679
     4680        flushRegisters();
     4681        callOperation(operationGetEnumerableLength, resultGPR, base.gpr());
     4682        int32Result(resultGPR, node);
     4683        break;
     4684    }
     4685    case HasGenericProperty: {
     4686        JSValueOperand base(this, node->child1());
     4687        SpeculateCellOperand property(this, node->child2());
     4688        GPRResult result(this);
     4689        GPRReg resultGPR = result.gpr();
     4690
     4691        flushRegisters();
     4692        callOperation(operationHasGenericProperty, resultGPR, base.gpr(), property.gpr());
     4693        jsValueResult(resultGPR, node, DataFormatJSBoolean);
     4694        break;
     4695    }
     4696    case HasStructureProperty: {
     4697        JSValueOperand base(this, node->child1());
     4698        SpeculateCellOperand property(this, node->child2());
     4699        SpeculateCellOperand enumerator(this, node->child3());
     4700        GPRTemporary scratch(this);
     4701        GPRResult result(this);
     4702
     4703        GPRReg baseGPR = base.gpr();
     4704        GPRReg propertyGPR = property.gpr();
     4705        GPRReg scratchGPR = scratch.gpr();
     4706        GPRReg resultGPR = result.gpr();
     4707
     4708        m_jit.load32(MacroAssembler::Address(baseGPR, JSCell::structureIDOffset()), scratchGPR);
     4709        MacroAssembler::Jump wrongStructure = m_jit.branch32(MacroAssembler::NotEqual,
     4710            scratchGPR,
     4711            MacroAssembler::Address(enumerator.gpr(), JSPropertyNameEnumerator::cachedStructureIDOffset()));
     4712
     4713        moveTrueTo(resultGPR);
     4714        MacroAssembler::Jump done = m_jit.jump();
     4715
     4716        done.link(&m_jit);
     4717
     4718        addSlowPathGenerator(slowPathCall(wrongStructure, this, operationHasGenericProperty, resultGPR, baseGPR, propertyGPR));
     4719        jsValueResult(resultGPR, node, DataFormatJSBoolean);
     4720        break;
     4721    }
     4722    case HasIndexedProperty: {
     4723        SpeculateCellOperand base(this, node->child1());
     4724        SpeculateInt32Operand index(this, node->child2());
     4725        GPRResult result(this);
     4726
     4727        GPRReg baseGPR = base.gpr();
     4728        GPRReg indexGPR = index.gpr();
     4729        GPRReg resultGPR = result.gpr();
     4730
     4731        MacroAssembler::JumpList slowCases;
     4732        ArrayMode mode = node->arrayMode();
     4733        switch (mode.type()) {
     4734        case Array::Int32:
     4735        case Array::Contiguous: {
     4736            ASSERT(!!node->child3());
     4737            StorageOperand storage(this, node->child3());
     4738            GPRTemporary scratch(this);
     4739           
     4740            GPRReg storageGPR = storage.gpr();
     4741            GPRReg scratchGPR = scratch.gpr();
     4742
     4743            MacroAssembler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
     4744            if (mode.isInBounds())
     4745                speculationCheck(OutOfBounds, JSValueRegs(), 0, outOfBounds);
     4746            else
     4747                slowCases.append(outOfBounds);
     4748
     4749            m_jit.load64(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight), scratchGPR);
     4750            slowCases.append(m_jit.branchTest64(MacroAssembler::Zero, scratchGPR));
     4751            moveTrueTo(resultGPR);
     4752            break;
     4753        }
     4754        case Array::Double: {
     4755            ASSERT(!!node->child3());
     4756            StorageOperand storage(this, node->child3());
     4757            FPRTemporary scratch(this);
     4758            FPRReg scratchFPR = scratch.fpr();
     4759            GPRReg storageGPR = storage.gpr();
     4760
     4761            MacroAssembler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
     4762            if (mode.isInBounds())
     4763                speculationCheck(OutOfBounds, JSValueRegs(), 0, outOfBounds);
     4764            else
     4765                slowCases.append(outOfBounds);
     4766
     4767            m_jit.loadDouble(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight), scratchFPR);
     4768            slowCases.append(m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, scratchFPR, scratchFPR));
     4769            break;
     4770        }
     4771        case Array::ArrayStorage: {
     4772            ASSERT(!!node->child3());
     4773            StorageOperand storage(this, node->child3());
     4774            GPRTemporary scratch(this);
     4775
     4776            GPRReg storageGPR = storage.gpr();
     4777            GPRReg scratchGPR = scratch.gpr();
     4778
     4779            MacroAssembler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset()));
     4780            if (mode.isInBounds())
     4781                speculationCheck(OutOfBounds, JSValueRegs(), 0, outOfBounds);
     4782            else   
     4783                slowCases.append(outOfBounds);
     4784
     4785            m_jit.load64(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset()), scratchGPR);
     4786            slowCases.append(m_jit.branchTest64(MacroAssembler::Zero, scratchGPR));
     4787            moveTrueTo(resultGPR);
     4788            break;
     4789        }
     4790        default: {
     4791            slowCases.append(m_jit.jump());
     4792            break;
     4793        }
     4794        }
     4795
     4796        addSlowPathGenerator(slowPathCall(slowCases, this, operationHasIndexedProperty, resultGPR, baseGPR, indexGPR));
     4797       
     4798        jsValueResult(resultGPR, node, DataFormatJSBoolean);
     4799        break;
     4800    }
     4801    case GetDirectPname: {
     4802        Edge& baseEdge = m_jit.graph().varArgChild(node, 0);
     4803        Edge& propertyEdge = m_jit.graph().varArgChild(node, 1);
     4804        Edge& indexEdge = m_jit.graph().varArgChild(node, 2);
     4805        Edge& enumeratorEdge = m_jit.graph().varArgChild(node, 3);
     4806
     4807        SpeculateCellOperand base(this, baseEdge);
     4808        SpeculateCellOperand property(this, propertyEdge);
     4809        SpeculateInt32Operand index(this, indexEdge);
     4810        SpeculateCellOperand enumerator(this, enumeratorEdge);
     4811        GPRResult result(this);
     4812        GPRTemporary scratch1(this);
     4813        GPRTemporary scratch2(this);
     4814
     4815        GPRReg baseGPR = base.gpr();
     4816        GPRReg propertyGPR = property.gpr();
     4817        GPRReg indexGPR = index.gpr();
     4818        GPRReg enumeratorGPR = enumerator.gpr();
     4819        GPRReg resultGPR = result.gpr();
     4820        GPRReg scratch1GPR = scratch1.gpr();
     4821        GPRReg scratch2GPR = scratch2.gpr();
     4822
     4823        // Check the structure
     4824        m_jit.load32(MacroAssembler::Address(baseGPR, JSCell::structureIDOffset()), scratch1GPR);
     4825        MacroAssembler::Jump wrongStructure = m_jit.branch32(MacroAssembler::NotEqual,
     4826            scratch1GPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedStructureIDOffset()));
     4827       
     4828        // Compute the offset
     4829        // If index is less than the enumerator's cached inline storage, then it's an inline access
     4830        MacroAssembler::Jump outOfLineAccess = m_jit.branch32(MacroAssembler::AboveOrEqual,
     4831            indexGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset()));
     4832
     4833        m_jit.load64(MacroAssembler::BaseIndex(baseGPR, indexGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage()), resultGPR);
     4834
     4835        MacroAssembler::Jump done = m_jit.jump();
     4836       
     4837        // Otherwise it's out of line
     4838        outOfLineAccess.link(&m_jit);
     4839        m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), scratch2GPR);
     4840        m_jit.move(indexGPR, scratch1GPR);
     4841        m_jit.sub32(MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset()), scratch1GPR);
     4842        m_jit.neg32(scratch1GPR);
     4843        m_jit.signExtend32ToPtr(scratch1GPR, scratch1GPR);
     4844        int32_t offsetOfFirstProperty = static_cast<int32_t>(offsetInButterfly(firstOutOfLineOffset)) * sizeof(EncodedJSValue);
     4845        m_jit.load64(MacroAssembler::BaseIndex(scratch2GPR, scratch1GPR, MacroAssembler::TimesEight, offsetOfFirstProperty), resultGPR);
     4846
     4847        done.link(&m_jit);
     4848
     4849        addSlowPathGenerator(slowPathCall(wrongStructure, this, operationGetByVal, resultGPR, baseGPR, propertyGPR));
     4850
     4851        jsValueResult(resultGPR, node);
     4852        break;
     4853    }
     4854    case GetStructurePropertyEnumerator: {
     4855        SpeculateCellOperand base(this, node->child1());
     4856        SpeculateInt32Operand length(this, node->child2());
     4857        GPRResult result(this);
     4858        GPRReg resultGPR = result.gpr();
     4859
     4860        flushRegisters();
     4861        callOperation(operationGetStructurePropertyEnumerator, resultGPR, base.gpr(), length.gpr());
     4862        cellResult(resultGPR, node);
     4863        break;
     4864    }
     4865    case GetGenericPropertyEnumerator: {
     4866        SpeculateCellOperand base(this, node->child1());
     4867        SpeculateInt32Operand length(this, node->child2());
     4868        SpeculateCellOperand enumerator(this, node->child3());
     4869        GPRResult result(this);
     4870        GPRReg resultGPR = result.gpr();
     4871
     4872        flushRegisters();
     4873        callOperation(operationGetGenericPropertyEnumerator, resultGPR, base.gpr(), length.gpr(), enumerator.gpr());
     4874        cellResult(resultGPR, node);
     4875        break;
     4876    }
     4877    case GetEnumeratorPname: {
     4878        SpeculateCellOperand enumerator(this, node->child1());
     4879        SpeculateInt32Operand index(this, node->child2());
     4880        GPRTemporary scratch1(this);
     4881        GPRTemporary scratch2(this);
     4882        GPRResult result(this);
     4883
     4884        GPRReg enumeratorGPR = enumerator.gpr();
     4885        GPRReg indexGPR = index.gpr();
     4886        GPRReg scratch1GPR = scratch1.gpr();
     4887        GPRReg scratch2GPR = scratch2.gpr();
     4888        GPRReg resultGPR = result.gpr();
     4889
     4890        MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below,
     4891            indexGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset()));
     4892
     4893        m_jit.move(MacroAssembler::TrustedImm32(ValueNull), resultGPR);
     4894
     4895        MacroAssembler::Jump done = m_jit.jump();
     4896        inBounds.link(&m_jit);
     4897
     4898        m_jit.loadPtr(MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()), scratch1GPR);
     4899        m_jit.move(indexGPR, scratch2GPR);
     4900        m_jit.signExtend32ToPtr(scratch2GPR, scratch2GPR);
     4901        m_jit.load64(MacroAssembler::BaseIndex(scratch1GPR, scratch2GPR, MacroAssembler::TimesEight), resultGPR);
     4902
     4903        done.link(&m_jit);
     4904        jsValueResult(resultGPR, node);
     4905        break;
     4906    }
     4907    case ToIndexString: {
     4908        SpeculateInt32Operand index(this, node->child1());
     4909        GPRResult result(this);
     4910        GPRReg resultGPR = result.gpr();
     4911
     4912        flushRegisters();
     4913        callOperation(operationToIndexString, resultGPR, index.gpr());
     4914        cellResult(resultGPR, node);
    46704915        break;
    46714916    }
  • trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp

    r171096 r172176  
    4040    case UntypedUse:
    4141        out.print("Untyped");
    42         break;
     42        return;
    4343    case Int32Use:
    4444        out.print("Int32");
    45         break;
     45        return;
    4646    case KnownInt32Use:
    4747        out.print("KnownInt32");
    48         break;
     48        return;
    4949    case Int52RepUse:
    5050        out.print("Int52Rep");
    51         break;
     51        return;
    5252    case MachineIntUse:
    5353        out.print("MachineInt");
    54         break;
     54        return;
    5555    case NumberUse:
    5656        out.print("Number");
    57         break;
     57        return;
    5858    case DoubleRepUse:
    5959        out.print("DoubleRep");
    60         break;
     60        return;
    6161    case DoubleRepRealUse:
    6262        out.print("DoubleRepReal");
    63         break;
     63        return;
    6464    case DoubleRepMachineIntUse:
    6565        out.print("DoubleRepMachineInt");
    66         break;
     66        return;
    6767    case BooleanUse:
    6868        out.print("Boolean");
    69         break;
     69        return;
    7070    case CellUse:
    7171        out.print("Cell");
    72         break;
     72        return;
    7373    case KnownCellUse:
    7474        out.print("KnownCell");
    75         break;
     75        return;
    7676    case ObjectUse:
    7777        out.print("Object");
    78         break;
     78        return;
     79    case FunctionUse:
     80        out.print("Function");
     81        return;
    7982    case FinalObjectUse:
    8083        out.print("FinalObject");
    81         break;
     84        return;
    8285    case ObjectOrOtherUse:
    8386        out.print("ObjectOrOther");
    84         break;
     87        return;
    8588    case StringIdentUse:
    8689        out.print("StringIdent");
    87         break;
     90        return;
    8891    case StringUse:
    8992        out.print("String");
    90         break;
     93        return;
    9194    case KnownStringUse:
    9295        out.print("KnownString");
    93         break;
     96        return;
    9497    case StringObjectUse:
    9598        out.print("StringObject");
    96         break;
     99        return;
    97100    case StringOrStringObjectUse:
    98101        out.print("StringOrStringObject");
    99         break;
     102        return;
    100103    case NotStringVarUse:
    101104        out.print("NotStringVar");
    102         break;
     105        return;
    103106    case NotCellUse:
    104107        out.print("NotCell");
    105         break;
     108        return;
    106109    case OtherUse:
    107110        out.print("Other");
    108         break;
     111        return;
    109112    case MiscUse:
    110113        out.print("Misc");
    111         break;
    112     default:
     114        return;
     115    case LastUseKind:
    113116        RELEASE_ASSERT_NOT_REACHED();
    114         break;
     117        return;
    115118    }
     119    RELEASE_ASSERT_NOT_REACHED();
    116120}
    117121
  • trunk/Source/JavaScriptCore/dfg/DFGUseKind.h

    r171096 r172176  
    4949    KnownCellUse,
    5050    ObjectUse,
     51    FunctionUse,
    5152    FinalObjectUse,
    5253    ObjectOrOtherUse,
     
    9091    case ObjectUse:
    9192        return SpecObject;
     93    case FunctionUse:
     94        return SpecFunction;
    9295    case FinalObjectUse:
    9396        return SpecFinalObject;
     
    172175    case KnownCellUse:
    173176    case ObjectUse:
     177    case FunctionUse:
    174178    case FinalObjectUse:
    175179    case StringIdentUse:
Note: See TracChangeset for help on using the changeset viewer.