1. 29 Dec, 2013 1 commit
    • fpizlo@apple.com's avatar
      Get rid of DFG forward exiting · 9df7fef8
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=125531
      
      Reviewed by Oliver Hunt.
              
      This finally gets rid of forward exiting. Forward exiting was always a fragile concept
      since it involved the compiler trying to figure out how to "roll forward" the
      execution from some DFG node to the next bytecode index. It was always easy to find
      counterexamples where it broke, and it has always served as an obstacle to adding
      compiler improvements - the latest being http://webkit.org/b/125523, which tried to
      make DCE work for more things.
              
      This change finishes the work of removing forward exiting. A lot of forward exiting
      was already removed in some other bugs, but SetLocal still did forward exits. SetLocal
      is in many ways the hardest to remove, since the forward exiting of SetLocal also
      implied that any conversion nodes inserted before the SetLocal would then also be
      marked as forward-exiting. Hence SetLocal's forward-exiting made a bunch of other
      things also forward-exiting, and this was always a source of weirdo bugs.
              
      SetLocal must be able to exit in case it performs a hoisted type speculation. Nodes
      inserted just before SetLocal must also be able to exit - for example type check
      hoisting may insert a CheckStructure, or fixup phase may insert something like
      Int32ToDouble. But if any of those nodes tried to backward exit, then this could lead
      to the reexecution of a side-effecting operation, for example:
              
          a: Call(...)
          b: SetLocal(@a, r1)
              
      For a long time it seemed like SetLocal *had* to exit forward because of this. But
      this change side-steps the problem by changing the ByteCodeParser to always emit a
      kind of "two-phase commit" for stores to local variables. Now when the ByteCodeParser
      wishes to store to a local, it first emits a MovHint and then enqueues a SetLocal.
      The SetLocal isn't actually emitted until the beginning of the next bytecode
      instruction (which the exception of op_enter and op_ret, which emit theirs immediately
      since it's always safe to reexecute those bytecode instructions and since deferring
      SetLocals would be weird there - op_enter has many SetLocals and op_ret is a set
      followed by a jump in case of inlining, so we'd have to emit the SetLocal "after" the
      jump and that would be awkward). This means that the above IR snippet would look
      something like:
              
          a: Call(..., bc#42)
          b: MovHint(@a, r1, bc#42)
          c: SetLocal(@a, r1, bc#47)
              
      Where the SetLocal exits "backwards" but appears at the beginning of the next bytecode
      instruction. This means that by the time we get to that SetLocal, the OSR exit
      analysis already knows that r1 is associated with @a, and it means that the SetLocal
      or anything hoisted above it can exit backwards as normal.
              
      This change also means that the "forward rewiring" can be killed. Previously, we might
      have inserted a conversion node on SetLocal and then the SetLocal died (i.e. turned
      into a MovHint) and the conversion node either died completely or had its lifetime
      truncated to be less than the actual value's bytecode lifetime. This no longer happens
      since conversion nodes are only inserted at SetLocals.
              
      More precisely, this change introduces two laws that we were basically already
      following anyway:
              
      1) A MovHint's child should never be changed except if all other uses of that child
         are also replaced. Specifically, this prohibits insertion of conversion nodes at
         MovHints.
              
      2) Anytime any child is replaced with something else, and all other uses aren't also
         replaced, we must insert a Phantom use of the original child.
      
      This is a slight compile-time regression but has no effect on code-gen. It unlocks a
      bunch of optimization opportunities so I think it's worth it.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::dumpAssumingJITType):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::instructionCount):
      * dfg/DFGAbstractInterpreterInlines.h:
      (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
      * dfg/DFGArgumentsSimplificationPhase.cpp:
      (JSC::DFG::ArgumentsSimplificationPhase::run):
      * dfg/DFGArrayifySlowPathGenerator.h:
      (JSC::DFG::ArrayifySlowPathGenerator::ArrayifySlowPathGenerator):
      * dfg/DFGBackwardsPropagationPhase.cpp:
      (JSC::DFG::BackwardsPropagationPhase::propagate):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::setDirect):
      (JSC::DFG::ByteCodeParser::DelayedSetLocal::DelayedSetLocal):
      (JSC::DFG::ByteCodeParser::DelayedSetLocal::execute):
      (JSC::DFG::ByteCodeParser::handleInlining):
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::eliminate):
      * dfg/DFGClobberize.h:
      (JSC::DFG::clobberize):
      * dfg/DFGCommon.h:
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      * dfg/DFGDCEPhase.cpp:
      (JSC::DFG::DCEPhase::run):
      (JSC::DFG::DCEPhase::fixupBlock):
      (JSC::DFG::DCEPhase::cleanVariables):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::fixEdge):
      (JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
      * dfg/DFGLICMPhase.cpp:
      (JSC::DFG::LICMPhase::run):
      (JSC::DFG::LICMPhase::attemptHoist):
      * dfg/DFGMinifiedNode.cpp:
      (JSC::DFG::MinifiedNode::fromNode):
      * dfg/DFGMinifiedNode.h:
      (JSC::DFG::belongsInMinifiedGraph):
      (JSC::DFG::MinifiedNode::constantNumber):
      (JSC::DFG::MinifiedNode::weakConstant):
      * dfg/DFGNode.cpp:
      (JSC::DFG::Node::hasVariableAccessData):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::convertToPhantom):
      (JSC::DFG::Node::convertToPhantomUnchecked):
      (JSC::DFG::Node::convertToIdentity):
      (JSC::DFG::Node::containsMovHint):
      (JSC::DFG::Node::hasUnlinkedLocal):
      (JSC::DFG::Node::willHaveCodeGenOrOSR):
      * dfg/DFGNodeFlags.cpp:
      (JSC::DFG::dumpNodeFlags):
      * dfg/DFGNodeFlags.h:
      * dfg/DFGNodeType.h:
      * dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
      (JSC::DFG::OSRAvailabilityAnalysisPhase::run):
      * dfg/DFGOSREntrypointCreationPhase.cpp:
      (JSC::DFG::OSREntrypointCreationPhase::run):
      * dfg/DFGOSRExit.cpp:
      * dfg/DFGOSRExit.h:
      * dfg/DFGOSRExitBase.cpp:
      * dfg/DFGOSRExitBase.h:
      (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSite):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      (JSC::DFG::PredictionPropagationPhase::doDoubleVoting):
      * dfg/DFGSSAConversionPhase.cpp:
      (JSC::DFG::SSAConversionPhase::run):
      * dfg/DFGSafeToExecute.h:
      (JSC::DFG::safeToExecute):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::speculationCheck):
      (JSC::DFG::SpeculativeJIT::emitInvalidationPoint):
      (JSC::DFG::SpeculativeJIT::typeCheck):
      (JSC::DFG::SpeculativeJIT::compileMovHint):
      (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
      (JSC::DFG::SpeculativeJIT::checkArgumentTypes):
      (JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::detectPeepHoleBranch):
      (JSC::DFG::SpeculativeJIT::needsTypeCheck):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGTypeCheckHoistingPhase.cpp:
      (JSC::DFG::TypeCheckHoistingPhase::run):
      (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
      (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
      * dfg/DFGValidate.cpp:
      (JSC::DFG::Validate::validateCPS):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::VariableAccessData):
      * dfg/DFGVariableEventStream.cpp:
      (JSC::DFG::VariableEventStream::reconstruct):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileGetArgument):
      (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
      (JSC::FTL::LowerDFGToLLVM::compileMovHint):
      (JSC::FTL::LowerDFGToLLVM::compileZombieHint):
      (JSC::FTL::LowerDFGToLLVM::compileInt32ToDouble):
      (JSC::FTL::LowerDFGToLLVM::speculate):
      (JSC::FTL::LowerDFGToLLVM::typeCheck):
      (JSC::FTL::LowerDFGToLLVM::appendTypeCheck):
      (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
      (JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
      * ftl/FTLOSRExit.cpp:
      * ftl/FTLOSRExit.h:
      * tests/stress/dead-int32-to-double.js: Added.
      (foo):
      * tests/stress/dead-uint32-to-number.js: Added.
      (foo):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@161126 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      9df7fef8
  2. 25 Dec, 2013 1 commit
    • fpizlo@apple.com's avatar
      DFG PhantomArguments shouldn't rely on a dead Phi graph · 14721941
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=126218
      
      Source/JavaScriptCore: 
      
      Reviewed by Oliver Hunt.
              
      This change dramatically rationalizes our handling of PhantomArguments (i.e.
      speculative elision of arguments object allocation).
              
      It's now the case that if we decide that we can elide arguments allocation, we just
      turn the arguments-creating node into a PhantomArguments and mark all locals that
      it's stored to as being arguments aliases. Being an arguments alias and being a
      PhantomArguments means basically the same thing: in DFG execution you have the empty
      value, on OSR exit an arguments object is allocated in your place, and all operations
      that use the value now just refer directly to the actual arguments in the call frame
      header (or the arguments we know that we passed to the call, in case of inlining).
              
      This means that we no longer have arguments simplification creating a dead Phi graph
      that then has to be interpreted by the OSR exit logic. That sort of never made any
      sense.
              
      This means that PhantomArguments now has a clear story in SSA: basically SSA just
      gets rid of the "locals" but everything else is the same.
              
      Finally, this means that we can more easily get rid of forward exiting. As I was
      working on the code to get rid of forward exiting, I realized that I'd have to
      carefully preserve the special meanings of MovHint and SetLocal in the case of
      PhantomArguments. It was really bizarre: even the semantics of MovHint were tied to
      our specific treatment of PhantomArguments. After this change this is no longer the
      case.
              
      One of the really cool things about this change is that arguments reification now
      just becomes a special kind of FlushFormat. This further unifies things: it means
      that a MovHint(PhantomArguments) and a SetLocal(PhantomArguments) both have the same
      meaning, since both of them dictate that the way we recover the local on exit is by
      reifying arguments. Previously, the SetLocal(PhantomArguments) case needed some
      special handling to accomplish this.
              
      A downside of this approach is that we will now emit code to store the empty value
      into aliased arguments variables, and we will even emit code to load that empty value
      as well. As far as I can tell this doesn't cost anything, since PhantomArguments are
      most profitable in cases where it allows us to simplify control flow and kill the
      arguments locals entirely. Of course, this isn't an issue in SSA form since SSA form
      also eliminates the locals.
      
      * dfg/DFGArgumentsSimplificationPhase.cpp:
      (JSC::DFG::ArgumentsSimplificationPhase::run):
      (JSC::DFG::ArgumentsSimplificationPhase::detypeArgumentsReferencingPhantomChild):
      * dfg/DFGFlushFormat.cpp:
      (WTF::printInternal):
      * dfg/DFGFlushFormat.h:
      (JSC::DFG::resultFor):
      (JSC::DFG::useKindFor):
      (JSC::DFG::dataFormatFor):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGValueSource.h:
      (JSC::DFG::ValueSource::ValueSource):
      (JSC::DFG::ValueSource::forFlushFormat):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::flushFormat):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
      
      LayoutTests: 
      
      Reviewed by Oliver Hunt.
              
      Added a test for an obvious case that I don't think we had coverage for in
      microbenchmarks. Of course, this case was already covered by more complex tests.
      
      * js/regress/inline-arguments-aliased-access-expected.txt: Added.
      * js/regress/inline-arguments-aliased-access.html: Added.
      * js/regress/script-tests/inline-arguments-aliased-access.js: Added.
      (foo):
      (bar):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@161072 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      14721941
  3. 18 Dec, 2013 1 commit
    • mhahnenberg@apple.com's avatar
      DFG should have a separate StoreBarrier node · 4968e1a3
      mhahnenberg@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=125530
      
      Reviewed by Filip Pizlo.
      
      Source/JavaScriptCore: 
      
      This is in preparation for GenGC. We use a separate StoreBarrier node instead of making them implicitly 
      part of other nodes so that it's easier to run analyses on them, e.g. for the StoreBarrierElisionPhase. 
      They are inserted during the fixup phase. Initially they do not generate any code.
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * dfg/DFGAbstractHeap.h:
      * dfg/DFGAbstractInterpreter.h:
      (JSC::DFG::AbstractInterpreter::isKnownNotCell):
      * dfg/DFGAbstractInterpreterInlines.h:
      (JSC::DFG::::executeEffects):
      * dfg/DFGClobberize.h:
      (JSC::DFG::clobberizeForAllocation):
      (JSC::DFG::clobberize):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::foldConstants): Whenever we insert new nodes that require StoreBarriers,
      we have to add those new StoreBarriers too. It's important to note that AllocatePropertyStorage and 
      ReallocatePropertyStorage nodes require their StoreBarriers to come after them since they allocate first,
      which could cause a GC, and then store the resulting buffer into their JSCell, which requires the barrier.
      If we ever require that write barriers occur before stores, we'll have to split these nodes into 
      AllocatePropertyStorage + StoreBarrier + PutPropertyStorage.
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::insertStoreBarrier):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::isStoreBarrier):
      * dfg/DFGNodeType.h:
      * dfg/DFGOSRExitCompiler32_64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * dfg/DFGOSRExitCompiler64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGSafeToExecute.h:
      (JSC::DFG::safeToExecute):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage):
      (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
      (JSC::DFG::SpeculativeJIT::compileStoreBarrier):
      (JSC::DFG::SpeculativeJIT::genericWriteBarrier): The fast path write barrier check. It loads the 
      byte that contains the mark bit of the object. 
      (JSC::DFG::SpeculativeJIT::storeToWriteBarrierBuffer): If the fast path check fails we try to store the 
      cell in the WriteBarrierBuffer so as to avoid frequently flushing all registers in order to make a C call.
      (JSC::DFG::SpeculativeJIT::writeBarrier):
      (JSC::DFG::SpeculativeJIT::osrWriteBarrier): More barebones version of the write barrier to be executed 
      during an OSR exit into baseline code. We must do this so that the baseline JIT object and array profiles 
      are properly cleared during GC.
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::callOperation):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::cachedPutById):
      (JSC::DFG::SpeculativeJIT::compileBaseValueStoreBarrier):
      (JSC::DFG::SpeculativeJIT::compile):
      (JSC::DFG::SpeculativeJIT::writeBarrier):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::cachedPutById):
      (JSC::DFG::SpeculativeJIT::compileBaseValueStoreBarrier):
      (JSC::DFG::SpeculativeJIT::compile):
      (JSC::DFG::SpeculativeJIT::writeBarrier):
      * dfg/DFGStoreBarrierElisionPhase.cpp: Added. New DFG phase that does block-local elision of redundant
      StoreBarriers. Every time a StoreBarrier on a particular object is executed, a bit is set indicating that 
      that object doesn't need any more StoreBarriers. 
      (JSC::DFG::StoreBarrierElisionPhase::StoreBarrierElisionPhase):
      (JSC::DFG::StoreBarrierElisionPhase::couldCauseGC): Nodes that could cause a GC reset the bits for all of the 
      objects known in the current block. 
      (JSC::DFG::StoreBarrierElisionPhase::allocatesFreshObject): A node that creates a new object automatically 
      sets the bit for that object since if a GC occurred as the result of that object's allocation then that 
      object would not need a barrier since it would be guaranteed to be a young generation object until the 
      next GC point.
      (JSC::DFG::StoreBarrierElisionPhase::noticeFreshObject):
      (JSC::DFG::StoreBarrierElisionPhase::getBaseOfStore):
      (JSC::DFG::StoreBarrierElisionPhase::shouldBeElided):
      (JSC::DFG::StoreBarrierElisionPhase::elideBarrier):
      (JSC::DFG::StoreBarrierElisionPhase::handleNode):
      (JSC::DFG::StoreBarrierElisionPhase::handleBlock):
      (JSC::DFG::StoreBarrierElisionPhase::run):
      (JSC::DFG::performStoreBarrierElision):
      * dfg/DFGStoreBarrierElisionPhase.h: Added.
      * heap/Heap.cpp:
      (JSC::Heap::Heap):
      (JSC::Heap::flushWriteBarrierBuffer):
      * heap/Heap.h:
      (JSC::Heap::writeBarrier):
      * heap/MarkedBlock.h:
      (JSC::MarkedBlock::offsetOfMarks):
      * heap/WriteBarrierBuffer.cpp: Added. The WriteBarrierBuffer buffers a set of JSCells that are awaiting 
      a pending WriteBarrier. This buffer is used by the DFG to avoid the overhead of calling out to C repeatedly
      to invoke a write barrier on a single JSCell. Instead the DFG has inline code to fill the WriteBarrier buffer
      until its full, and then to call out to C to flush it. The WriteBarrierBuffer will also be flushed prior to 
      each EdenCollection.
      (JSC::WriteBarrierBuffer::WriteBarrierBuffer):
      (JSC::WriteBarrierBuffer::~WriteBarrierBuffer):
      (JSC::WriteBarrierBuffer::flush):
      (JSC::WriteBarrierBuffer::reset):
      (JSC::WriteBarrierBuffer::add):
      * heap/WriteBarrierBuffer.h: Added.
      (JSC::WriteBarrierBuffer::currentIndexOffset):
      (JSC::WriteBarrierBuffer::capacityOffset):
      (JSC::WriteBarrierBuffer::bufferOffset):
      * jit/JITOperations.cpp:
      * jit/JITOperations.h:
      * runtime/VM.h:
      
      Source/WTF: 
      
      * wtf/Platform.h: Added an #define for ENABLE(GGC) which will be used for landing things related to GenGC.
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@160796 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      4968e1a3
  4. 18 Nov, 2013 1 commit
    • fpizlo@apple.com's avatar
      FTL should have an explicit notion of bytecode liveness · 002405c0
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=124181
      
      Source/JavaScriptCore: 
      
      Reviewed by Sam Weinig.
              
      This makes FTL OSR exit use bytecode liveness analysis to determine which variables
      to include values for. The decision of how to get the values of variables is based on
      forward propagation of MovHints and SetLocals.
              
      This fixes a bunch of bugs (like https://bugs.webkit.org/show_bug.cgi?id=124138 but
      also others that I noticed when I started writing more targetted tests) and allows us
      to remove some sketchy code.
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/BytecodeBasicBlock.h:
      * bytecode/BytecodeLivenessAnalysis.cpp:
      (JSC::isValidRegisterForLiveness):
      (JSC::setForOperand):
      (JSC::computeUsesForBytecodeOffset):
      (JSC::computeDefsForBytecodeOffset):
      (JSC::stepOverInstruction):
      (JSC::computeLocalLivenessForBytecodeOffset):
      (JSC::BytecodeLivenessAnalysis::runLivenessFixpoint):
      (JSC::BytecodeLivenessAnalysis::operandIsLiveAtBytecodeOffset):
      (JSC::getLivenessInfo):
      (JSC::BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset):
      (JSC::BytecodeLivenessAnalysis::computeFullLiveness):
      * bytecode/BytecodeLivenessAnalysis.h:
      * bytecode/BytecodeLivenessAnalysisInlines.h: Added.
      (JSC::operandIsAlwaysLive):
      (JSC::operandThatIsNotAlwaysLiveIsLive):
      (JSC::operandIsLive):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::captureCount):
      (JSC::CodeBlock::captureStart):
      (JSC::CodeBlock::captureEnd):
      * bytecode/CodeOrigin.cpp:
      (JSC::InlineCallFrame::dumpInContext):
      * bytecode/FullBytecodeLiveness.h: Added.
      (JSC::FullBytecodeLiveness::FullBytecodeLiveness):
      (JSC::FullBytecodeLiveness::getOut):
      (JSC::FullBytecodeLiveness::operandIsLive):
      (JSC::FullBytecodeLiveness::getLiveness):
      * dfg/DFGAvailability.cpp: Added.
      (JSC::DFG::Availability::dump):
      (JSC::DFG::Availability::dumpInContext):
      * dfg/DFGAvailability.h: Added.
      (JSC::DFG::Availability::Availability):
      (JSC::DFG::Availability::unavailable):
      (JSC::DFG::Availability::withFlush):
      (JSC::DFG::Availability::withNode):
      (JSC::DFG::Availability::withUnavailableNode):
      (JSC::DFG::Availability::nodeIsUndecided):
      (JSC::DFG::Availability::nodeIsUnavailable):
      (JSC::DFG::Availability::hasNode):
      (JSC::DFG::Availability::node):
      (JSC::DFG::Availability::flushedAt):
      (JSC::DFG::Availability::operator!):
      (JSC::DFG::Availability::operator==):
      (JSC::DFG::Availability::merge):
      (JSC::DFG::Availability::mergeNodes):
      (JSC::DFG::Availability::unavailableMarker):
      * dfg/DFGBasicBlock.h:
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGDisassembler.cpp:
      (JSC::DFG::Disassembler::Disassembler):
      * dfg/DFGFlushFormat.cpp:
      (WTF::printInternal):
      * dfg/DFGFlushFormat.h:
      (JSC::DFG::resultFor):
      (JSC::DFG::useKindFor):
      (JSC::DFG::dataFormatFor):
      * dfg/DFGFlushedAt.cpp:
      (JSC::DFG::FlushedAt::dump):
      * dfg/DFGFlushedAt.h:
      (JSC::DFG::FlushedAt::FlushedAt):
      (JSC::DFG::FlushedAt::merge):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      (JSC::DFG::Graph::livenessFor):
      (JSC::DFG::Graph::isLiveInBytecode):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::baselineCodeBlockFor):
      * dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
      (JSC::DFG::OSRAvailabilityAnalysisPhase::run):
      * dfg/DFGOSRAvailabilityAnalysisPhase.h:
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      * dfg/DFGResurrectionForValidationPhase.cpp: Added.
      (JSC::DFG::ResurrectionForValidationPhase::ResurrectionForValidationPhase):
      (JSC::DFG::ResurrectionForValidationPhase::run):
      (JSC::DFG::performResurrectionForValidation):
      * dfg/DFGResurrectionForValidationPhase.h: Added.
      * dfg/DFGSSAConversionPhase.cpp:
      (JSC::DFG::SSAConversionPhase::run):
      * dfg/DFGValueSource.h:
      (JSC::DFG::ValueSource::forFlushFormat):
      * dfg/DFGVariableAccessData.h:
      * ftl/FTLExitValue.cpp:
      (JSC::FTL::ExitValue::dumpInContext):
      * ftl/FTLInlineCacheSize.cpp:
      (JSC::FTL::sizeOfGetById):
      * ftl/FTLLocation.cpp:
      (JSC::FTL::Location::gpr):
      (JSC::FTL::Location::fpr):
      (JSC::FTL::Location::directGPR):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::compileBlock):
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
      (JSC::FTL::LowerDFGToLLVM::compileZombieHint):
      (JSC::FTL::LowerDFGToLLVM::compilePutById):
      (JSC::FTL::LowerDFGToLLVM::compileInvalidationPoint):
      (JSC::FTL::LowerDFGToLLVM::initializeOSRExitStateForBlock):
      (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
      (JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
      (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
      (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
      (JSC::FTL::LowerDFGToLLVM::observeMovHint):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::alloca):
      * ftl/FTLValueSource.cpp: Removed.
      * ftl/FTLValueSource.h: Removed.
      * llvm/LLVMAPIFunctions.h:
      * runtime/DumpContext.cpp:
      (JSC::DumpContext::DumpContext):
      * runtime/DumpContext.h:
      * runtime/Options.h:
      * runtime/SymbolTable.h:
      (JSC::SharedSymbolTable::captureStart):
      (JSC::SharedSymbolTable::captureEnd):
      (JSC::SharedSymbolTable::captureCount):
      
      Tools: 
      
      Reviewed by Mark Hahnenberg.
      
      * Scripts/run-jsc-stress-tests:
      
      LayoutTests: 
      
      Reviewed by Mark Hahnenberg or Sam Weinig.
              
      I totally added this test after the rest of the patch was r+'d. Under the right tier-up
      modes this triggers one of the bugs that the rest of the patch is trying to avoid.
      
      * js/regress/script-tests/weird-inlining-const-prop.js: Added.
      (foo):
      (bar):
      (fuzz):
      (testImpl):
      (test):
      * js/regress/weird-inlining-const-prop-expected.txt: Added.
      * js/regress/weird-inlining-const-prop.html: Added.
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@159394 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      002405c0
  5. 06 Oct, 2013 1 commit
    • fpizlo@apple.com's avatar
      Compress DFG stack layout · a62d4829
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=122024
      
      Reviewed by Oliver Hunt.
              
      The DFG needs to be able to store things at a known offset from frame pointer so that
      the runtime can read those things. Prior to this patch, the DFG would use the exact
      offsets that the bytecode asked for, even in the case of inlining, where it would use
      the callsite stack offset to shift all of the inlined function's variables over just as
      they would have been if a bytecode interpreter had really made the call.
              
      But this won't work once WebKit-LLVM integration is complete. LLVM has no notion of
      storing things at a fixed offset from the frame pointer. We could try to hack LLVM to do
      that, but it would seriously complicate LLVM's stack layout. But what we might be able
      to do is have LLVM tell us (via an addressof intrinsic and a side-channel) where some
      alloca landed relative to the frame pointer. Hence if the DFG can put all of its flushed
      variables in a contiguous range that can be expressed to LLVM as a struct that we
      alloca, then all of this can still work just fine.
              
      Previously the flushed variables didn't fit in a contiguous range, but this patch makes
      them contiguous by allowing the stack layout to be compressed.
              
      What this really means is that there is now a distinction between where the DFG saw a
      variable stored in bytecode and where it will actually store it in the resulting machine
      code. Henceforth when the DFG says "local" or "virtual register" it means the variable
      according to bytecode (with the stack offsetting for inlined code as before), but when
      it says "machine local" or "machine virtual register" it means the actual place where it
      will store things in the resulting machine code. All of the OSR exit, inlined arguments,
      captured variables, and various stack unwinding machine now knows about all of this.
              
      Note that the DFG's abstract interpretation still uses bytecode variables rather than
      machine variables. Same for CSE and abstract heaps. This makes sense since it means that
      we don't have to decide on machine variable allocation just to do those optimizations.
              
      The decision of what a local's machine location becomes is deferred to very late in
      compilation. We only need to assign machine locations to variables that must be stored
      to the stack. It's now mandatory to run some kind of "stack layout phase" that makes the
      decision and updates all data structures.
              
      So far the way that this is being used is just to compress the DFG stack layout, which
      is something that we should have done anyway, a long time ago. And the compression isn't
      even that good - the current StackLayoutPhase just identifies local indices that are
      unused in machine code and slides all other variables towards zero. This doesn't achieve
      particularly good compression but it is better than nothing. Note that this phase makes
      it seem like the bytecode-machine mapping is based on bytecode local indices; for
      example if bytecode local 4 is mapped to machine local 3 then it always will be. That's
      true for the current StackLayoutPhase but it _will not_ be true for all possible stack
      layout phases and it would be incorrect to assume that it should be true. This is why
      the current data structures have each VariableAccessData hold its own copy of the
      machine virtual register, and also have each InlineCallFrame report their own machine
      virtual registers for the various things. The DFG backend is likely to always use the
      dumb StackLayoutPhase since it is very cheap to run, but the FTL backend is likely to
      eventually get a better one, where we do some kind of constraint-based coloring: we
      institute constraints where some VariableAccessData's must have the same indices as some
      other ones, and also must be right next to some other ones; then we process all
      VariableAccessData's and attempt to assign them machine locals while preserving those
      constraints. This could lead to two VariableAccessDatas for the same bytecode local
      ending up with different machine locals.
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::CodeBlock):
      (JSC::CodeBlock::isCaptured):
      (JSC::CodeBlock::framePointerOffsetToGetActivationRegisters):
      (JSC::CodeBlock::machineSlowArguments):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::hasSlowArguments):
      * bytecode/CodeOrigin.cpp:
      (JSC::CodeOrigin::dump):
      (JSC::InlineCallFrame::calleeForCallFrame):
      (JSC::InlineCallFrame::dumpInContext):
      * bytecode/CodeOrigin.h:
      (JSC::InlineCallFrame::InlineCallFrame):
      (JSC::InlineCallFrame::calleeConstant):
      * bytecode/Operands.h:
      (JSC::Operands::indexForOperand):
      * dfg/DFGBasicBlock.cpp:
      (JSC::DFG::BasicBlock::SSAData::SSAData):
      * dfg/DFGBasicBlock.h:
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::ByteCodeParser):
      (JSC::DFG::ByteCodeParser::get):
      (JSC::DFG::ByteCodeParser::getLocal):
      (JSC::DFG::ByteCodeParser::flushDirect):
      (JSC::DFG::ByteCodeParser::flush):
      (JSC::DFG::ByteCodeParser::handleInlining):
      (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
      (JSC::DFG::ByteCodeParser::parse):
      * dfg/DFGCommon.h:
      * dfg/DFGCommonData.h:
      (JSC::DFG::CommonData::CommonData):
      * dfg/DFGDesiredWriteBarriers.cpp:
      (JSC::DFG::DesiredWriteBarrier::trigger):
      * dfg/DFGDesiredWriteBarriers.h:
      * dfg/DFGFlushLivenessAnalysisPhase.cpp:
      (JSC::DFG::FlushLivenessAnalysisPhase::run):
      (JSC::DFG::FlushLivenessAnalysisPhase::process):
      (JSC::DFG::FlushLivenessAnalysisPhase::reportError):
      * dfg/DFGFlushedAt.cpp: Added.
      (JSC::DFG::FlushedAt::dump):
      (JSC::DFG::FlushedAt::dumpInContext):
      * dfg/DFGFlushedAt.h: Added.
      (JSC::DFG::FlushedAt::FlushedAt):
      (JSC::DFG::FlushedAt::operator!):
      (JSC::DFG::FlushedAt::format):
      (JSC::DFG::FlushedAt::virtualRegister):
      (JSC::DFG::FlushedAt::operator==):
      (JSC::DFG::FlushedAt::operator!=):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::Graph):
      (JSC::DFG::Graph::dump):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::bytecodeRegisterForArgument):
      (JSC::DFG::Graph::argumentsRegisterFor):
      (JSC::DFG::Graph::machineArgumentsRegisterFor):
      (JSC::DFG::Graph::uncheckedArgumentsRegisterFor):
      (JSC::DFG::Graph::activationRegister):
      (JSC::DFG::Graph::uncheckedActivationRegister):
      (JSC::DFG::Graph::machineActivationRegister):
      (JSC::DFG::Graph::uncheckedMachineActivationRegister):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::link):
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::JITCompiler::noticeOSREntry):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::convertToGetLocalUnlinked):
      (JSC::DFG::Node::convertToGetLocal):
      (JSC::DFG::Node::machineLocal):
      (JSC::DFG::Node::hasUnlinkedMachineLocal):
      (JSC::DFG::Node::setUnlinkedMachineLocal):
      (JSC::DFG::Node::unlinkedMachineLocal):
      (JSC::DFG::Node::hasInlineStartData):
      (JSC::DFG::Node::inlineStartData):
      * dfg/DFGNodeFlags.cpp:
      (JSC::DFG::dumpNodeFlags):
      * dfg/DFGOSREntry.cpp:
      (JSC::DFG::prepareOSREntry):
      * dfg/DFGOSREntry.h:
      (JSC::DFG::OSREntryReshuffling::OSREntryReshuffling):
      * dfg/DFGOSRExitCompiler64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * dfg/DFGOSRExitCompilerCommon.cpp:
      (JSC::DFG::reifyInlinedCallFrames):
      * dfg/DFGOperations.cpp:
      * dfg/DFGOperations.h:
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      * dfg/DFGScoreBoard.h:
      (JSC::DFG::ScoreBoard::ScoreBoard):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compileInlineStart):
      (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
      (JSC::DFG::SpeculativeJIT::createOSREntries):
      (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::calleeFrameOffset):
      (JSC::DFG::SpeculativeJIT::callFrameSlot):
      (JSC::DFG::SpeculativeJIT::argumentSlot):
      (JSC::DFG::SpeculativeJIT::callFrameTagSlot):
      (JSC::DFG::SpeculativeJIT::callFramePayloadSlot):
      (JSC::DFG::SpeculativeJIT::argumentTagSlot):
      (JSC::DFG::SpeculativeJIT::argumentPayloadSlot):
      (JSC::DFG::SpeculativeJIT::framePointerOffsetToGetActivationRegisters):
      (JSC::DFG::SpeculativeJIT::callOperation):
      (JSC::DFG::SpeculativeJIT::recordSetLocal):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::emitCall):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::emitCall):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGStackLayoutPhase.cpp: Added.
      (JSC::DFG::StackLayoutPhase::StackLayoutPhase):
      (JSC::DFG::StackLayoutPhase::run):
      (JSC::DFG::performStackLayout):
      * dfg/DFGStackLayoutPhase.h: Added.
      * dfg/DFGValidate.cpp:
      (JSC::DFG::Validate::validate):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::machineLocal):
      (JSC::DFG::VariableAccessData::flushedAt):
      * dfg/DFGVirtualRegisterAllocationPhase.cpp:
      (JSC::DFG::VirtualRegisterAllocationPhase::run):
      * ftl/FTLExitValue.h:
      (JSC::FTL::ExitValue::inJSStack):
      (JSC::FTL::ExitValue::inJSStackAsInt32):
      (JSC::FTL::ExitValue::inJSStackAsInt52):
      (JSC::FTL::ExitValue::inJSStackAsDouble):
      (JSC::FTL::ExitValue::virtualRegister):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileGetArgument):
      (JSC::FTL::LowerDFGToLLVM::compileGetLocal):
      (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
      (JSC::FTL::LowerDFGToLLVM::initializeOSRExitStateForBlock):
      (JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
      * ftl/FTLOSRExitCompiler.cpp:
      (JSC::FTL::compileStub):
      * ftl/FTLValueSource.cpp:
      (JSC::FTL::ValueSource::dump):
      * ftl/FTLValueSource.h:
      (JSC::FTL::ValueSource::ValueSource):
      (JSC::FTL::ValueSource::kind):
      (JSC::FTL::ValueSource::operator!):
      (JSC::FTL::ValueSource::node):
      (JSC::FTL::ValueSource::virtualRegister):
      * interpreter/Interpreter.cpp:
      (JSC::unwindCallFrame):
      * interpreter/StackVisitor.cpp:
      (JSC::StackVisitor::readInlinedFrame):
      (JSC::StackVisitor::Frame::createArguments):
      (JSC::StackVisitor::Frame::existingArguments):
      * interpreter/StackVisitor.h:
      * jit/AssemblyHelpers.h:
      (JSC::AssemblyHelpers::addressFor):
      (JSC::AssemblyHelpers::tagFor):
      (JSC::AssemblyHelpers::payloadFor):
      (JSC::AssemblyHelpers::offsetOfArgumentsIncludingThis):
      * runtime/Arguments.cpp:
      (JSC::Arguments::tearOff):
      * runtime/Arguments.h:
      (JSC::Arguments::allocateSlowArguments):
      (JSC::Arguments::tryDeleteArgument):
      (JSC::Arguments::isDeletedArgument):
      (JSC::Arguments::isArgument):
      (JSC::Arguments::argument):
      (JSC::Arguments::finishCreation):
      * runtime/JSActivation.h:
      (JSC::JSActivation::create):
      (JSC::JSActivation::JSActivation):
      * runtime/JSFunction.cpp:
      (JSC::RetrieveArgumentsFunctor::operator()):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@156984 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      a62d4829
  6. 26 Sep, 2013 3 commits
    • msaboff@apple.com's avatar
      VirtualRegister should be a class · 62aa8b77
      msaboff@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=121732
      
      Reviewed by Geoffrey Garen.
      
      This is a refactoring change.  Changed VirtualRegister from an enum to a class.
      Moved Operands::operandIsArgument(), operandToArgument(), argumentToOperand()
      and the similar functions for locals to VirtualRegister class.
      
      This is in preparation for changing the offset for the first local register from
      0 to -1.  This is needed since most native calling conventions have the architected
      frame pointer (e.g. %rbp for X86) point at the slot that stores the previous frame
      pointer.  Local values start below that address.
      
      * bytecode/CodeBlock.cpp:
      * bytecode/CodeBlock.h:
      * bytecode/Instruction.h:
      * bytecode/LazyOperandValueProfile.h:
      * bytecode/MethodOfGettingAValueProfile.cpp:
      * bytecode/Operands.h:
      * bytecode/UnlinkedCodeBlock.cpp:
      * bytecode/UnlinkedCodeBlock.h:
      * bytecode/ValueRecovery.h:
      * bytecode/VirtualRegister.h:
      * bytecompiler/BytecodeGenerator.cpp:
      * bytecompiler/BytecodeGenerator.h:
      * bytecompiler/RegisterID.h:
      * debugger/DebuggerCallFrame.cpp:
      * dfg/DFGAbstractHeap.h:
      * dfg/DFGAbstractInterpreterInlines.h:
      * dfg/DFGArgumentPosition.h:
      * dfg/DFGArgumentsSimplificationPhase.cpp:
      * dfg/DFGByteCodeParser.cpp:
      * dfg/DFGCFGSimplificationPhase.cpp:
      * dfg/DFGCPSRethreadingPhase.cpp:
      * dfg/DFGCapabilities.cpp:
      * dfg/DFGConstantFoldingPhase.cpp:
      * dfg/DFGFlushLivenessAnalysisPhase.cpp:
      * dfg/DFGGraph.cpp:
      * dfg/DFGGraph.h:
      * dfg/DFGJITCode.cpp:
      * dfg/DFGNode.h:
      * dfg/DFGOSREntry.cpp:
      * dfg/DFGOSREntrypointCreationPhase.cpp:
      * dfg/DFGOSRExit.h:
      * dfg/DFGOSRExitCompiler32_64.cpp:
      * dfg/DFGOSRExitCompiler64.cpp:
      * dfg/DFGRegisterBank.h:
      * dfg/DFGScoreBoard.h:
      * dfg/DFGSpeculativeJIT.cpp:
      * dfg/DFGSpeculativeJIT.h:
      * dfg/DFGSpeculativeJIT32_64.cpp:
      * dfg/DFGSpeculativeJIT64.cpp:
      * dfg/DFGValidate.cpp:
      * dfg/DFGValueRecoveryOverride.h:
      * dfg/DFGVariableAccessData.h:
      * dfg/DFGVariableEvent.h:
      * dfg/DFGVariableEventStream.cpp:
      * dfg/DFGVirtualRegisterAllocationPhase.cpp:
      * ftl/FTLExitArgumentForOperand.h:
      * ftl/FTLLink.cpp:
      * ftl/FTLLowerDFGToLLVM.cpp:
      * ftl/FTLOSREntry.cpp:
      * ftl/FTLOSRExit.cpp:
      * ftl/FTLOSRExit.h:
      * ftl/FTLOSRExitCompiler.cpp:
      * interpreter/CallFrame.h:
      * interpreter/Interpreter.cpp:
      * jit/AssemblyHelpers.h:
      * jit/JIT.h:
      * jit/JITCall.cpp:
      * jit/JITCall32_64.cpp:
      * jit/JITInlines.h:
      * jit/JITOpcodes.cpp:
      * jit/JITOpcodes32_64.cpp:
      * jit/JITPropertyAccess32_64.cpp:
      * jit/JITStubs.cpp:
      * llint/LLIntSlowPaths.cpp:
      * profiler/ProfilerBytecodeSequence.cpp:
      * runtime/CommonSlowPaths.cpp:
      * runtime/JSActivation.cpp:
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@156511 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      62aa8b77
    • commit-queue@webkit.org's avatar
      Unreviewed, rolling out r156474. · bf43ed96
      commit-queue@webkit.org authored
      http://trac.webkit.org/changeset/156474
      https://bugs.webkit.org/show_bug.cgi?id=121966
      
      Broke the builds. (Requested by xenon on #webkit).
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::registerName):
      (JSC::CodeBlock::dumpBytecode):
      (JSC::CodeBlock::CodeBlock):
      (JSC::CodeBlock::createActivation):
      (JSC::CodeBlock::nameForRegister):
      * bytecode/CodeBlock.h:
      (JSC::unmodifiedArgumentsRegister):
      (JSC::CodeBlock::isKnownNotImmediate):
      (JSC::CodeBlock::setThisRegister):
      (JSC::CodeBlock::thisRegister):
      (JSC::CodeBlock::setArgumentsRegister):
      (JSC::CodeBlock::argumentsRegister):
      (JSC::CodeBlock::uncheckedArgumentsRegister):
      (JSC::CodeBlock::setActivationRegister):
      (JSC::CodeBlock::activationRegister):
      (JSC::CodeBlock::uncheckedActivationRegister):
      (JSC::CodeBlock::usesArguments):
      (JSC::CodeBlock::isCaptured):
      * bytecode/Instruction.h:
      * bytecode/LazyOperandValueProfile.h:
      (JSC::LazyOperandValueProfileKey::LazyOperandValueProfileKey):
      (JSC::LazyOperandValueProfileKey::operator!):
      (JSC::LazyOperandValueProfileKey::hash):
      (JSC::LazyOperandValueProfileKey::operand):
      (JSC::LazyOperandValueProfileKey::isHashTableDeletedValue):
      (JSC::LazyOperandValueProfile::LazyOperandValueProfile):
      * bytecode/MethodOfGettingAValueProfile.cpp:
      (JSC::MethodOfGettingAValueProfile::fromLazyOperand):
      (JSC::MethodOfGettingAValueProfile::getSpecFailBucket):
      * bytecode/Operands.h:
      (JSC::localToOperand):
      (JSC::operandIsLocal):
      (JSC::operandToLocal):
      (JSC::operandIsArgument):
      (JSC::operandToArgument):
      (JSC::argumentToOperand):
      (JSC::Operands::operand):
      (JSC::Operands::hasOperand):
      (JSC::Operands::setOperand):
      (JSC::Operands::operandForIndex):
      (JSC::Operands::setOperandFirstTime):
      * bytecode/UnlinkedCodeBlock.cpp:
      (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
      * bytecode/UnlinkedCodeBlock.h:
      (JSC::UnlinkedCodeBlock::setThisRegister):
      (JSC::UnlinkedCodeBlock::setActivationRegister):
      (JSC::UnlinkedCodeBlock::setArgumentsRegister):
      (JSC::UnlinkedCodeBlock::usesArguments):
      (JSC::UnlinkedCodeBlock::argumentsRegister):
      (JSC::UnlinkedCodeBlock::usesGlobalObject):
      (JSC::UnlinkedCodeBlock::setGlobalObjectRegister):
      (JSC::UnlinkedCodeBlock::globalObjectRegister):
      (JSC::UnlinkedCodeBlock::thisRegister):
      (JSC::UnlinkedCodeBlock::activationRegister):
      * bytecode/ValueRecovery.h:
      (JSC::ValueRecovery::displacedInJSStack):
      (JSC::ValueRecovery::virtualRegister):
      (JSC::ValueRecovery::dumpInContext):
      * bytecode/VirtualRegister.h:
      (WTF::printInternal):
      * bytecompiler/BytecodeGenerator.cpp:
      (JSC::BytecodeGenerator::generate):
      (JSC::BytecodeGenerator::addVar):
      (JSC::BytecodeGenerator::BytecodeGenerator):
      (JSC::BytecodeGenerator::createLazyRegisterIfNecessary):
      (JSC::BytecodeGenerator::newRegister):
      (JSC::BytecodeGenerator::emitLoadGlobalObject):
      (JSC::BytecodeGenerator::emitGetArgumentsLength):
      (JSC::BytecodeGenerator::emitGetArgumentByVal):
      (JSC::BytecodeGenerator::createArgumentsIfNecessary):
      (JSC::BytecodeGenerator::emitReturn):
      * bytecompiler/BytecodeGenerator.h:
      (JSC::BytecodeGenerator::registerFor):
      * bytecompiler/RegisterID.h:
      (JSC::RegisterID::RegisterID):
      (JSC::RegisterID::setIndex):
      (JSC::RegisterID::index):
      * debugger/DebuggerCallFrame.cpp:
      (JSC::DebuggerCallFrame::thisObject):
      * dfg/DFGAbstractHeap.h:
      (JSC::DFG::AbstractHeap::Payload::Payload):
      * dfg/DFGAbstractInterpreterInlines.h:
      (JSC::DFG::::executeEffects):
      (JSC::DFG::::clobberCapturedVars):
      * dfg/DFGArgumentPosition.h:
      (JSC::DFG::ArgumentPosition::dump):
      * dfg/DFGArgumentsSimplificationPhase.cpp:
      (JSC::DFG::ArgumentsSimplificationPhase::run):
      (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse):
      (JSC::DFG::ArgumentsSimplificationPhase::isOKToOptimize):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::newVariableAccessData):
      (JSC::DFG::ByteCodeParser::getDirect):
      (JSC::DFG::ByteCodeParser::get):
      (JSC::DFG::ByteCodeParser::setDirect):
      (JSC::DFG::ByteCodeParser::set):
      (JSC::DFG::ByteCodeParser::getLocal):
      (JSC::DFG::ByteCodeParser::setLocal):
      (JSC::DFG::ByteCodeParser::getArgument):
      (JSC::DFG::ByteCodeParser::setArgument):
      (JSC::DFG::ByteCodeParser::findArgumentPositionForLocal):
      (JSC::DFG::ByteCodeParser::findArgumentPosition):
      (JSC::DFG::ByteCodeParser::flush):
      (JSC::DFG::ByteCodeParser::flushDirect):
      (JSC::DFG::ByteCodeParser::getToInt32):
      (JSC::DFG::ByteCodeParser::getThis):
      (JSC::DFG::ByteCodeParser::addCall):
      (JSC::DFG::ByteCodeParser::InlineStackEntry::remapOperand):
      (JSC::DFG::ByteCodeParser::handleCall):
      (JSC::DFG::ByteCodeParser::emitFunctionChecks):
      (JSC::DFG::ByteCodeParser::emitArgumentPhantoms):
      (JSC::DFG::ByteCodeParser::handleInlining):
      (JSC::DFG::ByteCodeParser::handleMinMax):
      (JSC::DFG::ByteCodeParser::handleIntrinsic):
      (JSC::DFG::ByteCodeParser::handleTypedArrayConstructor):
      (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
      (JSC::DFG::ByteCodeParser::handleGetByOffset):
      (JSC::DFG::ByteCodeParser::handleGetById):
      (JSC::DFG::ByteCodeParser::parseBlock):
      (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
      (JSC::DFG::ByteCodeParser::parse):
      * dfg/DFGCFGSimplificationPhase.cpp:
      * dfg/DFGCPSRethreadingPhase.cpp:
      (JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocal):
      (JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocal):
      (JSC::DFG::CPSRethreadingPhase::canonicalizeSetArgument):
      * dfg/DFGCapabilities.cpp:
      (JSC::DFG::capabilityLevel):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::isCapturedAtOrAfter):
      * dfg/DFGFlushLivenessAnalysisPhase.cpp:
      (JSC::DFG::FlushLivenessAnalysisPhase::setForNode):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::argumentsRegisterFor):
      (JSC::DFG::Graph::uncheckedArgumentsRegisterFor):
      (JSC::DFG::Graph::uncheckedActivationRegisterFor):
      (JSC::DFG::Graph::valueProfileFor):
      * dfg/DFGJITCode.cpp:
      (JSC::DFG::JITCode::reconstruct):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::Node):
      (JSC::DFG::Node::convertToGetLocalUnlinked):
      (JSC::DFG::Node::hasVirtualRegister):
      (JSC::DFG::Node::virtualRegister):
      (JSC::DFG::Node::setVirtualRegister):
      * dfg/DFGOSREntry.cpp:
      (JSC::DFG::prepareOSREntry):
      * dfg/DFGOSREntrypointCreationPhase.cpp:
      (JSC::DFG::OSREntrypointCreationPhase::run):
      * dfg/DFGOSRExit.h:
      * dfg/DFGOSRExitCompiler32_64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * dfg/DFGOSRExitCompiler64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * dfg/DFGRegisterBank.h:
      (JSC::DFG::RegisterBank::tryAllocate):
      (JSC::DFG::RegisterBank::allocateSpecific):
      (JSC::DFG::RegisterBank::retain):
      (JSC::DFG::RegisterBank::isInUse):
      (JSC::DFG::RegisterBank::dump):
      (JSC::DFG::RegisterBank::releaseAtIndex):
      (JSC::DFG::RegisterBank::allocateInternal):
      (JSC::DFG::RegisterBank::MapEntry::MapEntry):
      * dfg/DFGScoreBoard.h:
      (JSC::DFG::ScoreBoard::allocate):
      (JSC::DFG::ScoreBoard::use):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::SpeculativeJIT):
      (JSC::DFG::SpeculativeJIT::checkConsistency):
      (JSC::DFG::SpeculativeJIT::compileMovHint):
      (JSC::DFG::SpeculativeJIT::compileInlineStart):
      (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::allocate):
      (JSC::DFG::SpeculativeJIT::fprAllocate):
      (JSC::DFG::SpeculativeJIT::silentSpillAllRegistersImpl):
      (JSC::DFG::SpeculativeJIT::flushRegisters):
      (JSC::DFG::SpeculativeJIT::isFlushed):
      (JSC::DFG::SpeculativeJIT::argumentSlot):
      (JSC::DFG::SpeculativeJIT::argumentTagSlot):
      (JSC::DFG::SpeculativeJIT::argumentPayloadSlot):
      (JSC::DFG::SpeculativeJIT::valueSourceForOperand):
      (JSC::DFG::SpeculativeJIT::setNodeForOperand):
      (JSC::DFG::SpeculativeJIT::valueSourceReferenceForOperand):
      (JSC::DFG::SpeculativeJIT::recordSetLocal):
      (JSC::DFG::SpeculativeJIT::generationInfoFromVirtualRegister):
      (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGValidate.cpp:
      (JSC::DFG::Validate::validate):
      (JSC::DFG::Validate::validateCPS):
      (JSC::DFG::Validate::checkOperand):
      (JSC::DFG::Validate::reportValidationContext):
      * dfg/DFGValueRecoveryOverride.h:
      (JSC::DFG::ValueRecoveryOverride::ValueRecoveryOverride):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::operand):
      (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):
      (JSC::DFG::VariableAccessData::tallyVotesForShouldUseDoubleFormat):
      (JSC::DFG::VariableAccessData::flushFormat):
      * dfg/DFGVariableEvent.h:
      (JSC::DFG::VariableEvent::spill):
      (JSC::DFG::VariableEvent::setLocal):
      * dfg/DFGVariableEventStream.cpp:
      (JSC::DFG::VariableEventStream::reconstruct):
      * dfg/DFGVirtualRegisterAllocationPhase.cpp:
      (JSC::DFG::VirtualRegisterAllocationPhase::run):
      * ftl/FTLExitArgumentForOperand.h:
      (JSC::FTL::ExitArgumentForOperand::ExitArgumentForOperand):
      (JSC::FTL::ExitArgumentForOperand::operand):
      * ftl/FTLLink.cpp:
      (JSC::FTL::link):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::compileGetArgument):
      (JSC::FTL::LowerDFGToLLVM::compileExtractOSREntryLocal):
      (JSC::FTL::LowerDFGToLLVM::compileCallOrConstruct):
      (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
      (JSC::FTL::LowerDFGToLLVM::observeMovHint):
      (JSC::FTL::LowerDFGToLLVM::addressFor):
      (JSC::FTL::LowerDFGToLLVM::payloadFor):
      (JSC::FTL::LowerDFGToLLVM::tagFor):
      * ftl/FTLOSREntry.cpp:
      (JSC::FTL::prepareOSREntry):
      * ftl/FTLOSRExit.cpp:
      (JSC::FTL::OSRExit::convertToForward):
      * ftl/FTLOSRExit.h:
      * ftl/FTLOSRExitCompiler.cpp:
      (JSC::FTL::compileStub):
      * interpreter/CallFrame.h:
      * interpreter/Interpreter.cpp:
      (JSC::Interpreter::dumpRegisters):
      (JSC::unwindCallFrame):
      (JSC::Interpreter::unwind):
      * jit/AssemblyHelpers.h:
      (JSC::AssemblyHelpers::addressFor):
      (JSC::AssemblyHelpers::tagFor):
      (JSC::AssemblyHelpers::payloadFor):
      (JSC::AssemblyHelpers::argumentsRegisterFor):
      * jit/JIT.h:
      * jit/JITCall.cpp:
      (JSC::JIT::compileLoadVarargs):
      * jit/JITInlines.h:
      (JSC::JIT::emitGetVirtualRegister):
      * jit/JITOpcodes.cpp:
      (JSC::JIT::emit_op_tear_off_arguments):
      (JSC::JIT::emit_op_get_pnames):
      (JSC::JIT::emit_op_enter):
      (JSC::JIT::emit_op_create_arguments):
      (JSC::JIT::emitSlow_op_get_argument_by_val):
      * jit/JITOpcodes32_64.cpp:
      (JSC::JIT::emit_op_enter):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::LLINT_SLOW_PATH_DECL):
      * profiler/ProfilerBytecodeSequence.cpp:
      (JSC::Profiler::BytecodeSequence::BytecodeSequence):
      * runtime/CommonSlowPaths.cpp:
      (JSC::SLOW_PATH_DECL):
      * runtime/JSActivation.cpp:
      (JSC::JSActivation::argumentsGetter):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@156482 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      bf43ed96
    • msaboff@apple.com's avatar
      VirtualRegister should be a class · 1796ad0f
      msaboff@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=121732
      
      Reviewed by Geoffrey Garen.
      
      This is a refactoring change.  Changed VirtualRegister from an enum to a class.
      Moved Operands::operandIsArgument(), operandToArgument(), argumentToOperand()
      and the similar functions for locals to VirtualRegister class.
      
      This is in preparation for changing the offset for the first local register from
      0 to -1.  This is needed since most native calling conventions have the architected
      frame pointer (e.g. %rbp for X86) point at the slot that stores the previous frame
      pointer.  Local values start below that address.
      
      * bytecode/CodeBlock.cpp:
      * bytecode/CodeBlock.h:
      * bytecode/Instruction.h:
      * bytecode/LazyOperandValueProfile.h:
      * bytecode/MethodOfGettingAValueProfile.cpp:
      * bytecode/Operands.h:
      * bytecode/UnlinkedCodeBlock.cpp:
      * bytecode/UnlinkedCodeBlock.h:
      * bytecode/ValueRecovery.h:
      * bytecode/VirtualRegister.h:
      * bytecompiler/BytecodeGenerator.cpp:
      * bytecompiler/BytecodeGenerator.h:
      * bytecompiler/RegisterID.h:
      * debugger/DebuggerCallFrame.cpp:
      * dfg/DFGAbstractHeap.h:
      * dfg/DFGAbstractInterpreterInlines.h:
      * dfg/DFGArgumentPosition.h:
      * dfg/DFGArgumentsSimplificationPhase.cpp:
      * dfg/DFGByteCodeParser.cpp:
      * dfg/DFGCFGSimplificationPhase.cpp:
      * dfg/DFGCPSRethreadingPhase.cpp:
      * dfg/DFGCapabilities.cpp:
      * dfg/DFGConstantFoldingPhase.cpp:
      * dfg/DFGFlushLivenessAnalysisPhase.cpp:
      * dfg/DFGGraph.cpp:
      * dfg/DFGGraph.h:
      * dfg/DFGJITCode.cpp:
      * dfg/DFGNode.h:
      * dfg/DFGOSREntry.cpp:
      * dfg/DFGOSREntrypointCreationPhase.cpp:
      * dfg/DFGOSRExit.h:
      * dfg/DFGOSRExitCompiler32_64.cpp:
      * dfg/DFGOSRExitCompiler64.cpp:
      * dfg/DFGRegisterBank.h:
      * dfg/DFGScoreBoard.h:
      * dfg/DFGSpeculativeJIT.cpp:
      * dfg/DFGSpeculativeJIT.h:
      * dfg/DFGSpeculativeJIT64.cpp:
      * dfg/DFGValidate.cpp:
      * dfg/DFGValueRecoveryOverride.h:
      * dfg/DFGVariableAccessData.h:
      * dfg/DFGVariableEvent.h:
      * dfg/DFGVariableEventStream.cpp:
      * dfg/DFGVirtualRegisterAllocationPhase.cpp:
      * ftl/FTLExitArgumentForOperand.h:
      * ftl/FTLLink.cpp:
      * ftl/FTLLowerDFGToLLVM.cpp:
      * ftl/FTLOSREntry.cpp:
      * ftl/FTLOSRExit.cpp:
      * ftl/FTLOSRExit.h:
      * ftl/FTLOSRExitCompiler.cpp:
      * interpreter/CallFrame.h:
      * interpreter/Interpreter.cpp:
      * jit/AssemblyHelpers.h:
      * jit/JIT.h:
      * jit/JITCall.cpp:
      * jit/JITInlines.h:
      * jit/JITOpcodes.cpp:
      * jit/JITOpcodes32_64.cpp:
      * jit/JITStubs.cpp:
      * llint/LLIntSlowPaths.cpp:
      * profiler/ProfilerBytecodeSequence.cpp:
      * runtime/CommonSlowPaths.cpp:
      * runtime/JSActivation.cpp:
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@156474 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      1796ad0f
  7. 18 Sep, 2013 3 commits
    • fpizlo@apple.com's avatar
      DFG should support Int52 for local variables · 6921b29b
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=121064
      
      Source/JavaScriptCore: 
      
      Reviewed by Oliver Hunt.
              
      This adds Int52 support for local variables to the DFG and FTL. It's a speed-up on
      programs that have local int32 overflows but where a larger int representation can
      prevent us from having to convert all the way up to double.
              
      It's a small speed-up for now. But we're just supporting Int52 for a handful of
      operations (add, sub, mul, neg, compare, bitops, typed array access) and this lays
      the groundwork for adding Int52 to JSValue, which will probably be a bigger
      speed-up.
              
      The basic approach is:
              
      - We have a notion of Int52 in our typesystem. Int52 doesn't belong to BytecodeTop
        or HeapTop - i.e. it doesn't arise from JSValues.
              
      - DFG treats Int52 as being part of its FullTop and will treat it as being a
        subtype of double unless instructed otherwise.
              
      - Prediction propagator creates Int52s whenever we have a node going doubly but due
        to large values rather than fractional values, and that node is known to be able
        to produce Int52 natively in the DFG backend.
              
      - Fixup phase converts edges to MachineIntUses in nodes that are known to be able
        to deal with Int52, and where we have a subtype of Int32|Int52 as the predicted
        input.
              
      - The DFG backend and FTL LLVM IR lowering have two notions of Int52s - ones that
        are left-shifted by 16 (great for overflow checks) and ones that are
        sign-extended. Both backends know how to convert between Int52s and the other
        representations.
      
      * assembler/MacroAssemblerX86_64.h:
      (JSC::MacroAssemblerX86_64::rshift64):
      (JSC::MacroAssemblerX86_64::mul64):
      (JSC::MacroAssemblerX86_64::branchMul64):
      (JSC::MacroAssemblerX86_64::branchNeg64):
      (JSC::MacroAssemblerX86_64::convertInt64ToDouble):
      * assembler/X86Assembler.h:
      (JSC::X86Assembler::imulq_rr):
      (JSC::X86Assembler::cvtsi2sdq_rr):
      * bytecode/DataFormat.h:
      (JSC::dataFormatToString):
      * bytecode/ExitKind.cpp:
      (JSC::exitKindToString):
      * bytecode/ExitKind.h:
      * bytecode/OperandsInlines.h:
      (JSC::::dumpInContext):
      * bytecode/SpeculatedType.cpp:
      (JSC::dumpSpeculation):
      (JSC::speculationToAbbreviatedString):
      (JSC::speculationFromValue):
      * bytecode/SpeculatedType.h:
      (JSC::isInt32SpeculationForArithmetic):
      (JSC::isInt52Speculation):
      (JSC::isMachineIntSpeculationForArithmetic):
      (JSC::isInt52AsDoubleSpeculation):
      (JSC::isBytecodeRealNumberSpeculation):
      (JSC::isFullRealNumberSpeculation):
      (JSC::isBytecodeNumberSpeculation):
      (JSC::isFullNumberSpeculation):
      (JSC::isBytecodeNumberSpeculationExpectingDefined):
      (JSC::isFullNumberSpeculationExpectingDefined):
      * bytecode/ValueRecovery.h:
      (JSC::ValueRecovery::alreadyInJSStackAsUnboxedInt52):
      (JSC::ValueRecovery::inGPR):
      (JSC::ValueRecovery::displacedInJSStack):
      (JSC::ValueRecovery::isAlreadyInJSStack):
      (JSC::ValueRecovery::gpr):
      (JSC::ValueRecovery::virtualRegister):
      (JSC::ValueRecovery::dumpInContext):
      * dfg/DFGAbstractInterpreter.h:
      (JSC::DFG::AbstractInterpreter::needsTypeCheck):
      (JSC::DFG::AbstractInterpreter::filterByType):
      * dfg/DFGAbstractInterpreterInlines.h:
      (JSC::DFG::::executeEffects):
      * dfg/DFGAbstractValue.cpp:
      (JSC::DFG::AbstractValue::set):
      (JSC::DFG::AbstractValue::checkConsistency):
      * dfg/DFGAbstractValue.h:
      (JSC::DFG::AbstractValue::couldBeType):
      (JSC::DFG::AbstractValue::isType):
      (JSC::DFG::AbstractValue::checkConsistency):
      (JSC::DFG::AbstractValue::validateType):
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::ArrayMode::refine):
      * dfg/DFGAssemblyHelpers.h:
      (JSC::DFG::AssemblyHelpers::boxInt52):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::makeSafe):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::pureCSE):
      (JSC::DFG::CSEPhase::getByValLoadElimination):
      (JSC::DFG::CSEPhase::performNodeCSE):
      * dfg/DFGClobberize.h:
      (JSC::DFG::clobberize):
      * dfg/DFGCommon.h:
      (JSC::DFG::enableInt52):
      * dfg/DFGDCEPhase.cpp:
      (JSC::DFG::DCEPhase::fixupBlock):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::run):
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::fixupSetLocalsInBlock):
      (JSC::DFG::FixupPhase::fixupUntypedSetLocalsInBlock):
      (JSC::DFG::FixupPhase::observeUseKindOnNode):
      (JSC::DFG::FixupPhase::fixEdge):
      (JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
      (JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
      * dfg/DFGFlushFormat.cpp:
      (WTF::printInternal):
      * dfg/DFGFlushFormat.h:
      (JSC::DFG::resultFor):
      (JSC::DFG::useKindFor):
      * dfg/DFGGenerationInfo.h:
      (JSC::DFG::GenerationInfo::initInt52):
      (JSC::DFG::GenerationInfo::initStrictInt52):
      (JSC::DFG::GenerationInfo::isFormat):
      (JSC::DFG::GenerationInfo::isInt52):
      (JSC::DFG::GenerationInfo::isStrictInt52):
      (JSC::DFG::GenerationInfo::fillInt52):
      (JSC::DFG::GenerationInfo::fillStrictInt52):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::addShouldSpeculateMachineInt):
      (JSC::DFG::Graph::mulShouldSpeculateMachineInt):
      (JSC::DFG::Graph::negateShouldSpeculateMachineInt):
      * dfg/DFGInPlaceAbstractState.cpp:
      (JSC::DFG::InPlaceAbstractState::mergeStateAtTail):
      * dfg/DFGJITCode.cpp:
      (JSC::DFG::JITCode::reconstruct):
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::JITCompiler::noticeOSREntry):
      * dfg/DFGMinifiedNode.h:
      (JSC::DFG::belongsInMinifiedGraph):
      (JSC::DFG::MinifiedNode::hasChild):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::shouldSpeculateNumber):
      (JSC::DFG::Node::shouldSpeculateNumberExpectingDefined):
      (JSC::DFG::Node::canSpeculateInt52):
      * dfg/DFGNodeFlags.h:
      (JSC::DFG::nodeCanSpeculateInt52):
      * dfg/DFGNodeType.h:
      (JSC::DFG::permitsOSRBackwardRewiring):
      (JSC::DFG::forwardRewiringSelectionScore):
      * dfg/DFGOSREntry.cpp:
      (JSC::DFG::prepareOSREntry):
      * dfg/DFGOSREntry.h:
      * dfg/DFGOSRExitCompiler.cpp:
      * dfg/DFGOSRExitCompiler64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::speculatedDoubleTypeForPrediction):
      (JSC::DFG::PredictionPropagationPhase::propagate):
      (JSC::DFG::PredictionPropagationPhase::doDoubleVoting):
      * dfg/DFGSafeToExecute.h:
      (JSC::DFG::SafeToExecuteEdge::operator()):
      (JSC::DFG::safeToExecute):
      * dfg/DFGSilentRegisterSavePlan.h:
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
      (JSC::DFG::SpeculativeJIT::silentFill):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
      (JSC::DFG::SpeculativeJIT::compileInlineStart):
      (JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
      (JSC::DFG::SpeculativeJIT::compileValueToInt32):
      (JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
      (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
      (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
      (JSC::DFG::SpeculativeJIT::compileAdd):
      (JSC::DFG::SpeculativeJIT::compileArithSub):
      (JSC::DFG::SpeculativeJIT::compileArithNegate):
      (JSC::DFG::SpeculativeJIT::compileArithMul):
      (JSC::DFG::SpeculativeJIT::compare):
      (JSC::DFG::SpeculativeJIT::compileStrictEq):
      (JSC::DFG::SpeculativeJIT::speculateMachineInt):
      (JSC::DFG::SpeculativeJIT::speculateNumber):
      (JSC::DFG::SpeculativeJIT::speculateRealNumber):
      (JSC::DFG::SpeculativeJIT::speculate):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::canReuse):
      (JSC::DFG::SpeculativeJIT::isFilled):
      (JSC::DFG::SpeculativeJIT::isFilledDouble):
      (JSC::DFG::SpeculativeJIT::use):
      (JSC::DFG::SpeculativeJIT::isKnownInteger):
      (JSC::DFG::SpeculativeJIT::isKnownCell):
      (JSC::DFG::SpeculativeJIT::isKnownNotNumber):
      (JSC::DFG::SpeculativeJIT::int52Result):
      (JSC::DFG::SpeculativeJIT::strictInt52Result):
      (JSC::DFG::SpeculativeJIT::initConstantInfo):
      (JSC::DFG::SpeculativeJIT::isInteger):
      (JSC::DFG::SpeculativeJIT::betterUseStrictInt52):
      (JSC::DFG::SpeculativeJIT::generationInfo):
      (JSC::DFG::SpeculateInt52Operand::SpeculateInt52Operand):
      (JSC::DFG::SpeculateInt52Operand::~SpeculateInt52Operand):
      (JSC::DFG::SpeculateInt52Operand::edge):
      (JSC::DFG::SpeculateInt52Operand::node):
      (JSC::DFG::SpeculateInt52Operand::gpr):
      (JSC::DFG::SpeculateInt52Operand::use):
      (JSC::DFG::SpeculateStrictInt52Operand::SpeculateStrictInt52Operand):
      (JSC::DFG::SpeculateStrictInt52Operand::~SpeculateStrictInt52Operand):
      (JSC::DFG::SpeculateStrictInt52Operand::edge):
      (JSC::DFG::SpeculateStrictInt52Operand::node):
      (JSC::DFG::SpeculateStrictInt52Operand::gpr):
      (JSC::DFG::SpeculateStrictInt52Operand::use):
      (JSC::DFG::SpeculateWhicheverInt52Operand::SpeculateWhicheverInt52Operand):
      (JSC::DFG::SpeculateWhicheverInt52Operand::~SpeculateWhicheverInt52Operand):
      (JSC::DFG::SpeculateWhicheverInt52Operand::edge):
      (JSC::DFG::SpeculateWhicheverInt52Operand::node):
      (JSC::DFG::SpeculateWhicheverInt52Operand::gpr):
      (JSC::DFG::SpeculateWhicheverInt52Operand::use):
      (JSC::DFG::SpeculateWhicheverInt52Operand::format):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::boxInt52):
      (JSC::DFG::SpeculativeJIT::fillJSValue):
      (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
      (JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
      (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
      (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
      (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
      (JSC::DFG::SpeculativeJIT::compileInt52Compare):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleInt52Branch):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGUseKind.cpp:
      (WTF::printInternal):
      * dfg/DFGUseKind.h:
      (JSC::DFG::typeFilterFor):
      (JSC::DFG::isNumerical):
      * dfg/DFGValueSource.cpp:
      (JSC::DFG::ValueSource::dump):
      * dfg/DFGValueSource.h:
      (JSC::DFG::dataFormatToValueSourceKind):
      (JSC::DFG::valueSourceKindToDataFormat):
      (JSC::DFG::ValueSource::forFlushFormat):
      (JSC::DFG::ValueSource::valueRecovery):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):
      (JSC::DFG::VariableAccessData::flushFormat):
      * ftl/FTLCArgumentGetter.cpp:
      (JSC::FTL::CArgumentGetter::loadNextAndBox):
      * ftl/FTLCArgumentGetter.h:
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLExitValue.cpp:
      (JSC::FTL::ExitValue::dumpInContext):
      * ftl/FTLExitValue.h:
      (JSC::FTL::ExitValue::inJSStackAsInt52):
      * ftl/FTLIntrinsicRepository.h:
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::createPhiVariables):
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileUpsilon):
      (JSC::FTL::LowerDFGToLLVM::compilePhi):
      (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
      (JSC::FTL::LowerDFGToLLVM::compileAdd):
      (JSC::FTL::LowerDFGToLLVM::compileArithSub):
      (JSC::FTL::LowerDFGToLLVM::compileArithMul):
      (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
      (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
      (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareLess):
      (JSC::FTL::LowerDFGToLLVM::compileCompareLessEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareGreater):
      (JSC::FTL::LowerDFGToLLVM::compileCompareGreaterEq):
      (JSC::FTL::LowerDFGToLLVM::lowInt32):
      (JSC::FTL::LowerDFGToLLVM::lowInt52):
      (JSC::FTL::LowerDFGToLLVM::lowStrictInt52):
      (JSC::FTL::LowerDFGToLLVM::betterUseStrictInt52):
      (JSC::FTL::LowerDFGToLLVM::bestInt52Kind):
      (JSC::FTL::LowerDFGToLLVM::opposite):
      (JSC::FTL::LowerDFGToLLVM::lowWhicheverInt52):
      (JSC::FTL::LowerDFGToLLVM::lowCell):
      (JSC::FTL::LowerDFGToLLVM::lowBoolean):
      (JSC::FTL::LowerDFGToLLVM::lowDouble):
      (JSC::FTL::LowerDFGToLLVM::lowJSValue):
      (JSC::FTL::LowerDFGToLLVM::strictInt52ToInt32):
      (JSC::FTL::LowerDFGToLLVM::strictInt52ToDouble):
      (JSC::FTL::LowerDFGToLLVM::strictInt52ToJSValue):
      (JSC::FTL::LowerDFGToLLVM::setInt52WithStrictValue):
      (JSC::FTL::LowerDFGToLLVM::strictInt52ToInt52):
      (JSC::FTL::LowerDFGToLLVM::int52ToStrictInt52):
      (JSC::FTL::LowerDFGToLLVM::speculateRealNumber):
      (JSC::FTL::LowerDFGToLLVM::initializeOSRExitStateForBlock):
      (JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
      (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
      (JSC::FTL::LowerDFGToLLVM::setInt52):
      (JSC::FTL::LowerDFGToLLVM::setStrictInt52):
      * ftl/FTLOSRExitCompiler.cpp:
      (JSC::FTL::compileStub):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::addWithOverflow64):
      (JSC::FTL::Output::subWithOverflow64):
      (JSC::FTL::Output::mulWithOverflow64):
      * ftl/FTLValueFormat.cpp:
      (WTF::printInternal):
      * ftl/FTLValueFormat.h:
      * ftl/FTLValueSource.cpp:
      (JSC::FTL::ValueSource::dump):
      * ftl/FTLValueSource.h:
      * interpreter/Register.h:
      (JSC::Register::unboxedInt52):
      * runtime/Arguments.cpp:
      (JSC::Arguments::tearOffForInlineCallFrame):
      * runtime/IndexingType.cpp:
      (JSC::leastUpperBoundOfIndexingTypeAndType):
      * runtime/JSCJSValue.h:
      * runtime/JSCJSValueInlines.h:
      (JSC::JSValue::isMachineInt):
      (JSC::JSValue::asMachineInt):
      
      Source/WTF: 
      
      Reviewed by Oliver Hunt.
      
      * wtf/PrintStream.h:
      (WTF::ValueIgnoringContext::ValueIgnoringContext):
      (WTF::ValueIgnoringContext::dump):
      (WTF::ignoringContext):
      
      Tools: 
      
      Reviewed by Oliver Hunt.
      
      * Scripts/run-jsc-stress-tests:
      
      LayoutTests: 
      
      Reviewed by Oliver Hunt.
      
      * js/dfg-int-overflow-large-constants-in-a-line-expected.txt:
      * js/regress/large-int-captured-expected.txt: Added.
      * js/regress/large-int-captured.html: Added.
      * js/regress/large-int-expected.txt: Added.
      * js/regress/large-int-neg-expected.txt: Added.
      * js/regress/large-int-neg.html: Added.
      * js/regress/large-int.html: Added.
      * js/regress/marsaglia-larger-ints-expected.txt: Added.
      * js/regress/marsaglia-larger-ints.html: Added.
      * js/regress/script-tests/large-int-captured.js: Added.
      (.bar):
      (foo):
      * js/regress/script-tests/large-int-neg.js: Added.
      (foo):
      * js/regress/script-tests/large-int.js: Added.
      (foo):
      * js/regress/script-tests/marsaglia-larger-ints.js: Added.
      (uint):
      (marsaglia):
      * js/script-tests/dfg-int-overflow-large-constants-in-a-line.js:
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@156047 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      6921b29b
    • commit-queue@webkit.org's avatar
      Unreviewed, rolling out r156019 and r156020. · 92c67000
      commit-queue@webkit.org authored
      http://trac.webkit.org/changeset/156019
      http://trac.webkit.org/changeset/156020
      https://bugs.webkit.org/show_bug.cgi?id=121540
      
      Broke tests (Requested by ap on #webkit).
      
      Source/JavaScriptCore:
      
      * assembler/MacroAssemblerX86_64.h:
      * assembler/X86Assembler.h:
      * bytecode/DataFormat.h:
      (JSC::dataFormatToString):
      * bytecode/ExitKind.cpp:
      (JSC::exitKindToString):
      * bytecode/ExitKind.h:
      * bytecode/OperandsInlines.h:
      (JSC::::dumpInContext):
      * bytecode/SpeculatedType.cpp:
      (JSC::dumpSpeculation):
      (JSC::speculationToAbbreviatedString):
      (JSC::speculationFromValue):
      * bytecode/SpeculatedType.h:
      (JSC::isInt32SpeculationForArithmetic):
      (JSC::isInt48Speculation):
      (JSC::isMachineIntSpeculationForArithmetic):
      (JSC::isInt48AsDoubleSpeculation):
      (JSC::isRealNumberSpeculation):
      (JSC::isNumberSpeculation):
      (JSC::isNumberSpeculationExpectingDefined):
      * bytecode/ValueRecovery.h:
      (JSC::ValueRecovery::inGPR):
      (JSC::ValueRecovery::displacedInJSStack):
      (JSC::ValueRecovery::isAlreadyInJSStack):
      (JSC::ValueRecovery::gpr):
      (JSC::ValueRecovery::virtualRegister):
      (JSC::ValueRecovery::dumpInContext):
      * dfg/DFGAbstractInterpreter.h:
      (JSC::DFG::AbstractInterpreter::needsTypeCheck):
      (JSC::DFG::AbstractInterpreter::filterByType):
      * dfg/DFGAbstractInterpreterInlines.h:
      (JSC::DFG::::executeEffects):
      * dfg/DFGAbstractValue.cpp:
      (JSC::DFG::AbstractValue::set):
      (JSC::DFG::AbstractValue::checkConsistency):
      * dfg/DFGAbstractValue.h:
      (JSC::DFG::AbstractValue::validateType):
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::ArrayMode::refine):
      * dfg/DFGAssemblyHelpers.h:
      (JSC::DFG::AssemblyHelpers::unboxDouble):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::makeSafe):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::canonicalize):
      (JSC::DFG::CSEPhase::pureCSE):
      (JSC::DFG::CSEPhase::getByValLoadElimination):
      (JSC::DFG::CSEPhase::performNodeCSE):
      * dfg/DFGClobberize.h:
      (JSC::DFG::clobberize):
      * dfg/DFGCommon.h:
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::run):
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::fixupSetLocalsInBlock):
      (JSC::DFG::FixupPhase::observeUseKindOnNode):
      (JSC::DFG::FixupPhase::fixEdge):
      (JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
      (JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
      * dfg/DFGFlushFormat.cpp:
      (WTF::printInternal):
      * dfg/DFGFlushFormat.h:
      (JSC::DFG::resultFor):
      (JSC::DFG::useKindFor):
      * dfg/DFGGenerationInfo.h:
      (JSC::DFG::GenerationInfo::initInt32):
      (JSC::DFG::GenerationInfo::fillInt32):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::addShouldSpeculateMachineInt):
      (JSC::DFG::Graph::mulShouldSpeculateMachineInt):
      (JSC::DFG::Graph::negateShouldSpeculateMachineInt):
      * dfg/DFGInPlaceAbstractState.cpp:
      (JSC::DFG::InPlaceAbstractState::mergeStateAtTail):
      * dfg/DFGJITCode.cpp:
      (JSC::DFG::JITCode::reconstruct):
      * dfg/DFGMinifiedNode.h:
      (JSC::DFG::belongsInMinifiedGraph):
      (JSC::DFG::MinifiedNode::hasChild):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::shouldSpeculateNumber):
      (JSC::DFG::Node::shouldSpeculateNumberExpectingDefined):
      (JSC::DFG::Node::canSpeculateInt48):
      * dfg/DFGNodeFlags.h:
      (JSC::DFG::nodeCanSpeculateInt48):
      * dfg/DFGNodeType.h:
      (JSC::DFG::forwardRewiringSelectionScore):
      * dfg/DFGOSRExitCompiler.cpp:
      (JSC::DFG::shortOperandsDump):
      * dfg/DFGOSRExitCompiler64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::speculatedDoubleTypeForPrediction):
      (JSC::DFG::PredictionPropagationPhase::propagate):
      (JSC::DFG::PredictionPropagationPhase::doDoubleVoting):
      * dfg/DFGSafeToExecute.h:
      (JSC::DFG::SafeToExecuteEdge::operator()):
      (JSC::DFG::safeToExecute):
      * dfg/DFGSilentRegisterSavePlan.h:
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
      (JSC::DFG::SpeculativeJIT::silentFill):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
      (JSC::DFG::SpeculativeJIT::compileInlineStart):
      (JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
      (JSC::DFG::SpeculativeJIT::compileValueToInt32):
      (JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
      (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
      (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
      (JSC::DFG::SpeculativeJIT::compileAdd):
      (JSC::DFG::SpeculativeJIT::compileArithSub):
      (JSC::DFG::SpeculativeJIT::compileArithNegate):
      (JSC::DFG::SpeculativeJIT::compileArithMul):
      (JSC::DFG::SpeculativeJIT::compare):
      (JSC::DFG::SpeculativeJIT::compileStrictEq):
      (JSC::DFG::SpeculativeJIT::speculateNumber):
      (JSC::DFG::SpeculativeJIT::speculateRealNumber):
      (JSC::DFG::SpeculativeJIT::speculate):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::canReuse):
      (JSC::DFG::SpeculativeJIT::isFilled):
      (JSC::DFG::SpeculativeJIT::isFilledDouble):
      (JSC::DFG::SpeculativeJIT::use):
      (JSC::DFG::SpeculativeJIT::boxDouble):
      (JSC::DFG::SpeculativeJIT::isKnownInteger):
      (JSC::DFG::SpeculativeJIT::isKnownCell):
      (JSC::DFG::SpeculativeJIT::isKnownNotNumber):
      (JSC::DFG::SpeculativeJIT::int32Result):
      (JSC::DFG::SpeculativeJIT::initConstantInfo):
      (JSC::DFG::SpeculativeJIT::isInteger):
      (JSC::DFG::SpeculativeJIT::generationInfoFromVirtualRegister):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::fillJSValue):
      (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
      (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
      (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
      (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGUseKind.cpp:
      (WTF::printInternal):
      * dfg/DFGUseKind.h:
      (JSC::DFG::typeFilterFor):
      (JSC::DFG::isNumerical):
      * dfg/DFGValueSource.cpp:
      (JSC::DFG::ValueSource::dump):
      * dfg/DFGValueSource.h:
      (JSC::DFG::dataFormatToValueSourceKind):
      (JSC::DFG::valueSourceKindToDataFormat):
      (JSC::DFG::ValueSource::forFlushFormat):
      (JSC::DFG::ValueSource::valueRecovery):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):
      (JSC::DFG::VariableAccessData::flushFormat):
      * ftl/FTLCArgumentGetter.cpp:
      (JSC::FTL::CArgumentGetter::loadNextAndBox):
      * ftl/FTLCArgumentGetter.h:
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLExitValue.cpp:
      (JSC::FTL::ExitValue::dumpInContext):
      * ftl/FTLExitValue.h:
      * ftl/FTLIntrinsicRepository.h:
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::createPhiVariables):
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileUpsilon):
      (JSC::FTL::LowerDFGToLLVM::compilePhi):
      (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
      (JSC::FTL::LowerDFGToLLVM::compileAdd):
      (JSC::FTL::LowerDFGToLLVM::compileArithSub):
      (JSC::FTL::LowerDFGToLLVM::compileArithMul):
      (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
      (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
      (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareLess):
      (JSC::FTL::LowerDFGToLLVM::compileCompareLessEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareGreater):
      (JSC::FTL::LowerDFGToLLVM::compileCompareGreaterEq):
      (JSC::FTL::LowerDFGToLLVM::lowInt32):
      (JSC::FTL::LowerDFGToLLVM::lowCell):
      (JSC::FTL::LowerDFGToLLVM::lowBoolean):
      (JSC::FTL::LowerDFGToLLVM::lowDouble):
      (JSC::FTL::LowerDFGToLLVM::lowJSValue):
      (JSC::FTL::LowerDFGToLLVM::speculateRealNumber):
      (JSC::FTL::LowerDFGToLLVM::initializeOSRExitStateForBlock):
      (JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
      (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
      (JSC::FTL::LowerDFGToLLVM::setInt32):
      * ftl/FTLOSRExitCompiler.cpp:
      (JSC::FTL::compileStub):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::mulWithOverflow32):
      * ftl/FTLValueFormat.cpp:
      (WTF::printInternal):
      * ftl/FTLValueFormat.h:
      * ftl/FTLValueSource.cpp:
      (JSC::FTL::ValueSource::dump):
      * ftl/FTLValueSource.h:
      * interpreter/Register.h:
      * runtime/Arguments.cpp:
      (JSC::Arguments::tearOffForInlineCallFrame):
      * runtime/IndexingType.cpp:
      (JSC::leastUpperBoundOfIndexingTypeAndType):
      * runtime/JSCJSValue.h:
      * runtime/JSCJSValueInlines.h:
      
      Source/WTF:
      
      * wtf/PrintStream.h:
      
      Tools:
      
      * Scripts/run-jsc-stress-tests:
      
      LayoutTests:
      
      * js/regress/large-int-captured-expected.txt: Removed.
      * js/regress/large-int-captured.html: Removed.
      * js/regress/large-int-expected.txt: Removed.
      * js/regress/large-int-neg-expected.txt: Removed.
      * js/regress/large-int-neg.html: Removed.
      * js/regress/large-int.html: Removed.
      * js/regress/marsaglia-larger-ints-expected.txt: Removed.
      * js/regress/marsaglia-larger-ints.html: Removed.
      * js/regress/script-tests/large-int-captured.js: Removed.
      * js/regress/script-tests/large-int-neg.js: Removed.
      * js/regress/script-tests/large-int.js: Removed.
      * js/regress/script-tests/marsaglia-larger-ints.js: Removed.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@156029 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      92c67000
    • fpizlo@apple.com's avatar
      DFG should support Int52 for local variables · 4c466ec6
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=121064
      
      Source/JavaScriptCore: 
      
      Reviewed by Oliver Hunt.
              
      This adds Int52 support for local variables to the DFG and FTL. It's a speed-up on
      programs that have local int32 overflows but where a larger int representation can
      prevent us from having to convert all the way up to double.
              
      It's a small speed-up for now. But we're just supporting Int52 for a handful of
      operations (add, sub, mul, neg, compare, bitops, typed array access) and this lays
      the groundwork for adding Int52 to JSValue, which will probably be a bigger
      speed-up.
              
      The basic approach is:
              
      - We have a notion of Int52 in our typesystem. Int52 doesn't belong to BytecodeTop
        or HeapTop - i.e. it doesn't arise from JSValues.
              
      - DFG treats Int52 as being part of its FullTop and will treat it as being a
        subtype of double unless instructed otherwise.
              
      - Prediction propagator creates Int52s whenever we have a node going doubly but due
        to large values rather than fractional values, and that node is known to be able
        to produce Int52 natively in the DFG backend.
              
      - Fixup phase converts edges to MachineIntUses in nodes that are known to be able
        to deal with Int52, and where we have a subtype of Int32|Int52 as the predicted
        input.
              
      - The DFG backend and FTL LLVM IR lowering have two notions of Int52s - ones that
        are left-shifted by 16 (great for overflow checks) and ones that are
        sign-extended. Both backends know how to convert between Int52s and the other
        representations.
      
      * assembler/MacroAssemblerX86_64.h:
      (JSC::MacroAssemblerX86_64::rshift64):
      (JSC::MacroAssemblerX86_64::mul64):
      (JSC::MacroAssemblerX86_64::branchMul64):
      (JSC::MacroAssemblerX86_64::branchNeg64):
      (JSC::MacroAssemblerX86_64::convertInt64ToDouble):
      * assembler/X86Assembler.h:
      (JSC::X86Assembler::imulq_rr):
      (JSC::X86Assembler::cvtsi2sdq_rr):
      * bytecode/DataFormat.h:
      (JSC::dataFormatToString):
      * bytecode/OperandsInlines.h:
      (JSC::::dumpInContext):
      * bytecode/SpeculatedType.cpp:
      (JSC::dumpSpeculation):
      (JSC::speculationToAbbreviatedString):
      (JSC::speculationFromValue):
      * bytecode/SpeculatedType.h:
      (JSC::isInt32SpeculationForArithmetic):
      (JSC::isMachineIntSpeculationForArithmetic):
      (JSC::isBytecodeRealNumberSpeculation):
      (JSC::isFullRealNumberSpeculation):
      (JSC::isBytecodeNumberSpeculation):
      (JSC::isFullNumberSpeculation):
      (JSC::isBytecodeNumberSpeculationExpectingDefined):
      (JSC::isFullNumberSpeculationExpectingDefined):
      * bytecode/ValueRecovery.h:
      (JSC::ValueRecovery::alreadyInJSStackAsUnboxedInt52):
      (JSC::ValueRecovery::inGPR):
      (JSC::ValueRecovery::displacedInJSStack):
      (JSC::ValueRecovery::isAlreadyInJSStack):
      (JSC::ValueRecovery::gpr):
      (JSC::ValueRecovery::virtualRegister):
      (JSC::ValueRecovery::dumpInContext):
      * dfg/DFGAbstractInterpreter.h:
      (JSC::DFG::AbstractInterpreter::needsTypeCheck):
      (JSC::DFG::AbstractInterpreter::filterByType):
      * dfg/DFGAbstractInterpreterInlines.h:
      (JSC::DFG::::executeEffects):
      * dfg/DFGAbstractValue.cpp:
      (JSC::DFG::AbstractValue::set):
      (JSC::DFG::AbstractValue::checkConsistency):
      * dfg/DFGAbstractValue.h:
      (JSC::DFG::AbstractValue::couldBeType):
      (JSC::DFG::AbstractValue::isType):
      (JSC::DFG::AbstractValue::checkConsistency):
      (JSC::DFG::AbstractValue::validateType):
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::ArrayMode::refine):
      * dfg/DFGAssemblyHelpers.h:
      (JSC::DFG::AssemblyHelpers::boxInt52):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::pureCSE):
      (JSC::DFG::CSEPhase::getByValLoadElimination):
      (JSC::DFG::CSEPhase::performNodeCSE):
      * dfg/DFGClobberize.h:
      (JSC::DFG::clobberize):
      * dfg/DFGCommon.h:
      (JSC::DFG::enableInt52):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::run):
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::fixupSetLocalsInBlock):
      (JSC::DFG::FixupPhase::fixupUntypedSetLocalsInBlock):
      (JSC::DFG::FixupPhase::observeUseKindOnNode):
      (JSC::DFG::FixupPhase::fixEdge):
      (JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
      (JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
      * dfg/DFGFlushFormat.cpp:
      (WTF::printInternal):
      * dfg/DFGFlushFormat.h:
      (JSC::DFG::resultFor):
      (JSC::DFG::useKindFor):
      * dfg/DFGGenerationInfo.h:
      (JSC::DFG::GenerationInfo::initInt52):
      (JSC::DFG::GenerationInfo::initStrictInt52):
      (JSC::DFG::GenerationInfo::isFormat):
      (JSC::DFG::GenerationInfo::isInt52):
      (JSC::DFG::GenerationInfo::isStrictInt52):
      (JSC::DFG::GenerationInfo::fillInt52):
      (JSC::DFG::GenerationInfo::fillStrictInt52):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::addShouldSpeculateMachineInt):
      (JSC::DFG::Graph::mulShouldSpeculateMachineInt):
      (JSC::DFG::Graph::negateShouldSpeculateMachineInt):
      * dfg/DFGInPlaceAbstractState.cpp:
      (JSC::DFG::InPlaceAbstractState::mergeStateAtTail):
      * dfg/DFGJITCode.cpp:
      (JSC::DFG::JITCode::reconstruct):
      * dfg/DFGMinifiedNode.h:
      (JSC::DFG::belongsInMinifiedGraph):
      (JSC::DFG::MinifiedNode::hasChild):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::shouldSpeculateNumber):
      (JSC::DFG::Node::shouldSpeculateNumberExpectingDefined):
      * dfg/DFGNodeFlags.h:
      * dfg/DFGNodeType.h:
      (JSC::DFG::forwardRewiringSelectionScore):
      * dfg/DFGOSRExitCompiler.cpp:
      * dfg/DFGOSRExitCompiler64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::speculatedDoubleTypeForPrediction):
      (JSC::DFG::PredictionPropagationPhase::propagate):
      (JSC::DFG::PredictionPropagationPhase::doDoubleVoting):
      * dfg/DFGSafeToExecute.h:
      (JSC::DFG::SafeToExecuteEdge::operator()):
      (JSC::DFG::safeToExecute):
      * dfg/DFGSilentRegisterSavePlan.h:
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
      (JSC::DFG::SpeculativeJIT::silentFill):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
      (JSC::DFG::SpeculativeJIT::compileInlineStart):
      (JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
      (JSC::DFG::SpeculativeJIT::compileValueToInt32):
      (JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
      (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
      (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
      (JSC::DFG::SpeculativeJIT::compileAdd):
      (JSC::DFG::SpeculativeJIT::compileArithSub):
      (JSC::DFG::SpeculativeJIT::compileArithNegate):
      (JSC::DFG::SpeculativeJIT::compileArithMul):
      (JSC::DFG::SpeculativeJIT::compare):
      (JSC::DFG::SpeculativeJIT::compileStrictEq):
      (JSC::DFG::SpeculativeJIT::speculateMachineInt):
      (JSC::DFG::SpeculativeJIT::speculateNumber):
      (JSC::DFG::SpeculativeJIT::speculateRealNumber):
      (JSC::DFG::SpeculativeJIT::speculate):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::canReuse):
      (JSC::DFG::SpeculativeJIT::isFilled):
      (JSC::DFG::SpeculativeJIT::isFilledDouble):
      (JSC::DFG::SpeculativeJIT::use):
      (JSC::DFG::SpeculativeJIT::isKnownInteger):
      (JSC::DFG::SpeculativeJIT::isKnownCell):
      (JSC::DFG::SpeculativeJIT::isKnownNotNumber):
      (JSC::DFG::SpeculativeJIT::int52Result):
      (JSC::DFG::SpeculativeJIT::strictInt52Result):
      (JSC::DFG::SpeculativeJIT::initConstantInfo):
      (JSC::DFG::SpeculativeJIT::isInteger):
      (JSC::DFG::SpeculativeJIT::betterUseStrictInt52):
      (JSC::DFG::SpeculativeJIT::generationInfo):
      (JSC::DFG::SpeculateInt52Operand::SpeculateInt52Operand):
      (JSC::DFG::SpeculateInt52Operand::~SpeculateInt52Operand):
      (JSC::DFG::SpeculateInt52Operand::edge):
      (JSC::DFG::SpeculateInt52Operand::node):
      (JSC::DFG::SpeculateInt52Operand::gpr):
      (JSC::DFG::SpeculateInt52Operand::use):
      (JSC::DFG::SpeculateStrictInt52Operand::SpeculateStrictInt52Operand):
      (JSC::DFG::SpeculateStrictInt52Operand::~SpeculateStrictInt52Operand):
      (JSC::DFG::SpeculateStrictInt52Operand::edge):
      (JSC::DFG::SpeculateStrictInt52Operand::node):
      (JSC::DFG::SpeculateStrictInt52Operand::gpr):
      (JSC::DFG::SpeculateStrictInt52Operand::use):
      (JSC::DFG::SpeculateWhicheverInt52Operand::SpeculateWhicheverInt52Operand):
      (JSC::DFG::SpeculateWhicheverInt52Operand::~SpeculateWhicheverInt52Operand):
      (JSC::DFG::SpeculateWhicheverInt52Operand::edge):
      (JSC::DFG::SpeculateWhicheverInt52Operand::node):
      (JSC::DFG::SpeculateWhicheverInt52Operand::gpr):
      (JSC::DFG::SpeculateWhicheverInt52Operand::use):
      (JSC::DFG::SpeculateWhicheverInt52Operand::format):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::boxInt52):
      (JSC::DFG::SpeculativeJIT::fillJSValue):
      (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
      (JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
      (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
      (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
      (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
      (JSC::DFG::SpeculativeJIT::compileInt52Compare):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleInt52Branch):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGUseKind.cpp:
      (WTF::printInternal):
      * dfg/DFGUseKind.h:
      (JSC::DFG::typeFilterFor):
      (JSC::DFG::isNumerical):
      * dfg/DFGValueSource.cpp:
      (JSC::DFG::ValueSource::dump):
      * dfg/DFGValueSource.h:
      (JSC::DFG::dataFormatToValueSourceKind):
      (JSC::DFG::valueSourceKindToDataFormat):
      (JSC::DFG::ValueSource::forFlushFormat):
      (JSC::DFG::ValueSource::valueRecovery):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):
      (JSC::DFG::VariableAccessData::flushFormat):
      * ftl/FTLCArgumentGetter.cpp:
      (JSC::FTL::CArgumentGetter::loadNextAndBox):
      * ftl/FTLCArgumentGetter.h:
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLExitValue.cpp:
      (JSC::FTL::ExitValue::dumpInContext):
      * ftl/FTLExitValue.h:
      (JSC::FTL::ExitValue::inJSStackAsInt52):
      * ftl/FTLIntrinsicRepository.h:
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::createPhiVariables):
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileUpsilon):
      (JSC::FTL::LowerDFGToLLVM::compilePhi):
      (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
      (JSC::FTL::LowerDFGToLLVM::compileAdd):
      (JSC::FTL::LowerDFGToLLVM::compileArithSub):
      (JSC::FTL::LowerDFGToLLVM::compileArithMul):
      (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
      (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
      (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareLess):
      (JSC::FTL::LowerDFGToLLVM::compileCompareLessEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareGreater):
      (JSC::FTL::LowerDFGToLLVM::compileCompareGreaterEq):
      (JSC::FTL::LowerDFGToLLVM::lowInt32):
      (JSC::FTL::LowerDFGToLLVM::lowInt52):
      (JSC::FTL::LowerDFGToLLVM::lowStrictInt52):
      (JSC::FTL::LowerDFGToLLVM::betterUseStrictInt52):
      (JSC::FTL::LowerDFGToLLVM::bestInt52Kind):
      (JSC::FTL::LowerDFGToLLVM::opposite):
      (JSC::FTL::LowerDFGToLLVM::Int52s::operator[]):
      (JSC::FTL::LowerDFGToLLVM::lowWhicheverInt52):
      (JSC::FTL::LowerDFGToLLVM::lowWhicheverInt52s):
      (JSC::FTL::LowerDFGToLLVM::lowOpposingInt52s):
      (JSC::FTL::LowerDFGToLLVM::lowCell):
      (JSC::FTL::LowerDFGToLLVM::lowBoolean):
      (JSC::FTL::LowerDFGToLLVM::lowDouble):
      (JSC::FTL::LowerDFGToLLVM::lowJSValue):
      (JSC::FTL::LowerDFGToLLVM::strictInt52ToInt32):
      (JSC::FTL::LowerDFGToLLVM::strictInt52ToDouble):
      (JSC::FTL::LowerDFGToLLVM::strictInt52ToJSValue):
      (JSC::FTL::LowerDFGToLLVM::setInt52WithStrictValue):
      (JSC::FTL::LowerDFGToLLVM::strictInt52ToInt52):
      (JSC::FTL::LowerDFGToLLVM::int52ToStrictInt52):
      (JSC::FTL::LowerDFGToLLVM::speculateRealNumber):
      (JSC::FTL::LowerDFGToLLVM::initializeOSRExitStateForBlock):
      (JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
      (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
      (JSC::FTL::LowerDFGToLLVM::setInt52):
      (JSC::FTL::LowerDFGToLLVM::setStrictInt52):
      * ftl/FTLOSRExitCompiler.cpp:
      (JSC::FTL::compileStub):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::addWithOverflow64):
      (JSC::FTL::Output::subWithOverflow64):
      (JSC::FTL::Output::mulWithOverflow64):
      * ftl/FTLValueFormat.cpp:
      (WTF::printInternal):
      * ftl/FTLValueFormat.h:
      * ftl/FTLValueSource.cpp:
      (JSC::FTL::ValueSource::dump):
      * ftl/FTLValueSource.h:
      * interpreter/Register.h:
      (JSC::Register::unboxedInt52):
      * runtime/Arguments.cpp:
      (JSC::Arguments::tearOffForInlineCallFrame):
      * runtime/IndexingType.cpp:
      (JSC::leastUpperBoundOfIndexingTypeAndType):
      * runtime/JSCJSValue.h:
      * runtime/JSCJSValueInlines.h:
      (JSC::JSValue::isMachineInt):
      (JSC::JSValue::asMachineInt):
      
      Source/WTF: 
      
      Reviewed by Oliver Hunt.
      
      * wtf/PrintStream.h:
      (WTF::ValueIgnoringContext::ValueIgnoringContext):
      (WTF::ValueIgnoringContext::dump):
      (WTF::ignoringContext):
      
      Tools: 
      
      Reviewed by Oliver Hunt.
      
      * Scripts/run-jsc-stress-tests:
      
      LayoutTests: 
      
      Reviewed by Oliver Hunt.
      
      * js/regress/large-int-captured-expected.txt: Added.
      * js/regress/large-int-captured.html: Added.
      * js/regress/large-int-expected.txt: Added.
      * js/regress/large-int-neg-expected.txt: Added.
      * js/regress/large-int-neg.html: Added.
      * js/regress/large-int.html: Added.
      * js/regress/marsaglia-larger-ints-expected.txt: Added.
      * js/regress/marsaglia-larger-ints.html: Added.
      * js/regress/script-tests/large-int-captured.js: Added.
      (.bar):
      (foo):
      * js/regress/script-tests/large-int-neg.js: Added.
      (foo):
      * js/regress/script-tests/large-int.js: Added.
      (foo):
      * js/regress/script-tests/marsaglia-larger-ints.js: Added.
      (uint):
      (marsaglia):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@156019 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      4c466ec6
  8. 11 Sep, 2013 1 commit
    • fpizlo@apple.com's avatar
      Be explicit about backwards propagation properties that care about escaping to... · dc36e83f
      fpizlo@apple.com authored
      Be explicit about backwards propagation properties that care about escaping to bytecode, as opposed to just escaping within DFG code.
      
      Rubber stamped by Mark Hahnenberg.
              
      We need to care about escaping to bytecode if we're doing a lossy optimization,
      i.e. the optimization means we produce less information and so we can't rescue
      ourselves during OSR exit.
              
      We only need to care about escaping within the DFG code (and can ignore what
      might happen in bytecode) if we're doing an optimization that is lossless, i.e.
      we can always still reconstruct the values that bytecode wants.
              
      Example #1:
              
          Large int32 + int32 which overflows. We want to optimize away the overflow
          check and just do a 32-bit add.
                  
          This is lossy; the result should have one extra bit but we simply throw
          that bit away by doing a check-less 32-bit add. Hence we need to know that 
          even the bytecode wouldn't have cared about that bit. This is true in cases
          like (a + b) | 0.
              
      Example #2:
              
          Larbe int32 + int32 which overflows. We want to optimize away the overflow
          check by doing a 64-bit add.
                  
          This is lossless. We can always convert the resulting 64-bit int back to a
          double if that's what bytecode wants. Hence we only need to know that the
          DFG code won't want to do something to this value that would make 64-bit
          ints either unprofitable or unsound.
              
      The backwards propagator's notions of flags (NodeUsedAsValue, etc) are for lossy
      optimizations and so should be named in a way that reflects this. This patch
      calls then NodeBytecodeUsesAsValue, etc.
              
      * dfg/DFGAbstractInterpreterInlines.h:
      (JSC::DFG::::executeEffects):
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::ArrayMode::refine):
      * dfg/DFGBackwardsPropagationPhase.cpp:
      (JSC::DFG::BackwardsPropagationPhase::mergeDefaultFlags):
      (JSC::DFG::BackwardsPropagationPhase::propagate):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::addImmediateShouldSpeculateInt32):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::arithNodeFlags):
      * dfg/DFGNodeFlags.cpp:
      (JSC::DFG::dumpNodeFlags):
      * dfg/DFGNodeFlags.h:
      (JSC::DFG::bytecodeUsesAsNumber):
      (JSC::DFG::bytecodeCanTruncateInteger):
      (JSC::DFG::bytecodeCanIgnoreNegativeZero):
      (JSC::DFG::nodeMayNegZero):
      (JSC::DFG::nodeCanSpeculateInt32):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compileDoubleAsInt32):
      (JSC::DFG::SpeculativeJIT::compileAdd):
      (JSC::DFG::SpeculativeJIT::compileArithSub):
      (JSC::DFG::SpeculativeJIT::compileArithNegate):
      (JSC::DFG::SpeculativeJIT::compileArithMul):
      (JSC::DFG::SpeculativeJIT::compileArithDiv):
      (JSC::DFG::SpeculativeJIT::compileArithMod):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileAdd):
      (JSC::FTL::LowerDFGToLLVM::compileArithSub):
      (JSC::FTL::LowerDFGToLLVM::compileArithMul):
      (JSC::FTL::LowerDFGToLLVM::compileArithDiv):
      (JSC::FTL::LowerDFGToLLVM::compileArithMod):
      (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@155497 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      dc36e83f
  9. 25 Jul, 2013 2 commits
    • oliver@apple.com's avatar
      fourthTier: DFG should have an SSA form for use by FTL · 827d2cf7
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118338
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      Adds an SSA form to the DFG. We can convert ThreadedCPS form into SSA form
      after breaking critical edges. The conversion algorithm follows Aycock and
      Horspool, and the SSA form itself follows something I've done before, where
      instead of having Phi functions specify input nodes corresponding to block
      predecessors, we instead have Upsilon functions in the predecessors that
      specify which value in that block goes into which subsequent Phi. Upsilons
      don't have to dominate Phis (usually they don't) and they correspond to a
      non-SSA "mov" into the Phi's "variable". This gives all of the good
      properties of SSA, while ensuring that a bunch of CFG transformations don't
      have to be SSA-aware.
      
      So far the only DFG phases that are SSA-aware are DCE and CFA. CFG
      simplification is probably SSA-aware by default, though I haven't tried it.
      Constant folding probably needs a few tweaks, but is likely ready. Ditto
      for CSE, though it's not clear that we'd want to use block-local CSE when
      we could be doing GVN.
      
      Currently only the FTL can generate code from the SSA form, and there is no
      way to convert from SSA to ThreadedCPS or LoadStore. There probably will
      never be such a capability.
      
      In order to handle OSR exit state in the SSA, we place MovHints at Phi
      points. Other than that, you can reconstruct state-at-exit by forward
      propagating MovHints. Note that MovHint is the new SetLocal in SSA.
      SetLocal and GetLocal only survive into SSA if they are on captured
      variables, or in the case of flushes. A "live SetLocal" will be
      NodeMustGenerate and will always correspond to a flush. Computing the
      state-at-exit requires running SSA liveness analysis, OSR availability
      analysis, and flush liveness analysis. The FTL runs all of these prior to
      generating code. While OSR exit continues to be tricky, much of the logic
      is now factored into separate phases and the backend has to do less work
      to reason about what happened outside of the basic block that is being
      lowered.
      
      Conversion from DFG SSA to LLVM SSA is done by ensuring that we generate
      code in depth-first order, thus guaranteeing that a node will always be
      lowered (and hence have a LValue) before any of the blocks dominated by
      that node's block have code generated. For Upsilon/Phi, we just use
      alloca's. We could do something more clever there, but it's probably not
      worth it, at least not now.
      
      Finally, while the SSA form is currently only being converted to LLVM IR,
      there is nothing that prevents us from considering other backends in the
      future - with the caveat that this form is designed to be first lowered to
      a lower-level SSA before actual machine code generation commences. So we
      ought to either use LLVM (the intended path) or we will have to write our
      own SSA low-level backend.
      
      This runs all of the code that the FTL was known to run previously. No
      change in performance for now. But it does open some exciting
      possibilities!
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/Operands.h:
      (JSC::OperandValueTraits::dump):
      (JSC::Operands::fill):
      (Operands):
      (JSC::Operands::clear):
      (JSC::Operands::operator==):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::beginBasicBlock):
      (JSC::DFG::setLiveValues):
      (DFG):
      (JSC::DFG::AbstractState::initialize):
      (JSC::DFG::AbstractState::endBasicBlock):
      (JSC::DFG::AbstractState::executeEffects):
      (JSC::DFG::AbstractState::mergeStateAtTail):
      (JSC::DFG::AbstractState::merge):
      * dfg/DFGAbstractState.h:
      (AbstractState):
      * dfg/DFGAdjacencyList.h:
      (JSC::DFG::AdjacencyList::justOneChild):
      (AdjacencyList):
      * dfg/DFGBasicBlock.cpp: Added.
      (DFG):
      (JSC::DFG::BasicBlock::BasicBlock):
      (JSC::DFG::BasicBlock::~BasicBlock):
      (JSC::DFG::BasicBlock::ensureLocals):
      (JSC::DFG::BasicBlock::isInPhis):
      (JSC::DFG::BasicBlock::isInBlock):
      (JSC::DFG::BasicBlock::removePredecessor):
      (JSC::DFG::BasicBlock::replacePredecessor):
      (JSC::DFG::BasicBlock::dump):
      (JSC::DFG::BasicBlock::SSAData::SSAData):
      (JSC::DFG::BasicBlock::SSAData::~SSAData):
      * dfg/DFGBasicBlock.h:
      (BasicBlock):
      (JSC::DFG::BasicBlock::operator[]):
      (JSC::DFG::BasicBlock::successor):
      (JSC::DFG::BasicBlock::successorForCondition):
      (SSAData):
      * dfg/DFGBasicBlockInlines.h:
      (DFG):
      * dfg/DFGBlockInsertionSet.cpp: Added.
      (DFG):
      (JSC::DFG::BlockInsertionSet::BlockInsertionSet):
      (JSC::DFG::BlockInsertionSet::~BlockInsertionSet):
      (JSC::DFG::BlockInsertionSet::insert):
      (JSC::DFG::BlockInsertionSet::insertBefore):
      (JSC::DFG::BlockInsertionSet::execute):
      * dfg/DFGBlockInsertionSet.h: Added.
      (DFG):
      (BlockInsertionSet):
      * dfg/DFGCFAPhase.cpp:
      (JSC::DFG::CFAPhase::run):
      * dfg/DFGCFGSimplificationPhase.cpp:
      * dfg/DFGCPSRethreadingPhase.cpp:
      (JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock):
      * dfg/DFGCommon.cpp:
      (WTF::printInternal):
      * dfg/DFGCommon.h:
      (JSC::DFG::doesKill):
      (DFG):
      (JSC::DFG::killStatusForDoesKill):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      (JSC::DFG::ConstantFoldingPhase::isCapturedAtOrAfter):
      * dfg/DFGCriticalEdgeBreakingPhase.cpp: Added.
      (DFG):
      (CriticalEdgeBreakingPhase):
      (JSC::DFG::CriticalEdgeBreakingPhase::CriticalEdgeBreakingPhase):
      (JSC::DFG::CriticalEdgeBreakingPhase::run):
      (JSC::DFG::CriticalEdgeBreakingPhase::breakCriticalEdge):
      (JSC::DFG::performCriticalEdgeBreaking):
      * dfg/DFGCriticalEdgeBreakingPhase.h: Added.
      (DFG):
      * dfg/DFGDCEPhase.cpp:
      (JSC::DFG::DCEPhase::run):
      (JSC::DFG::DCEPhase::findTypeCheckRoot):
      (JSC::DFG::DCEPhase::countNode):
      (DCEPhase):
      (JSC::DFG::DCEPhase::countEdge):
      (JSC::DFG::DCEPhase::eliminateIrrelevantPhantomChildren):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * dfg/DFGEdge.cpp:
      (JSC::DFG::Edge::dump):
      * dfg/DFGEdge.h:
      (JSC::DFG::Edge::Edge):
      (JSC::DFG::Edge::setNode):
      (JSC::DFG::Edge::useKindUnchecked):
      (JSC::DFG::Edge::setUseKind):
      (JSC::DFG::Edge::setProofStatus):
      (JSC::DFG::Edge::willNotHaveCheck):
      (JSC::DFG::Edge::willHaveCheck):
      (Edge):
      (JSC::DFG::Edge::killStatusUnchecked):
      (JSC::DFG::Edge::killStatus):
      (JSC::DFG::Edge::setKillStatus):
      (JSC::DFG::Edge::doesKill):
      (JSC::DFG::Edge::doesNotKill):
      (JSC::DFG::Edge::shift):
      (JSC::DFG::Edge::makeWord):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGFlushFormat.cpp: Added.
      (WTF):
      (WTF::printInternal):
      * dfg/DFGFlushFormat.h: Added.
      (DFG):
      (JSC::DFG::resultFor):
      (JSC::DFG::useKindFor):
      (WTF):
      * dfg/DFGFlushLivenessAnalysisPhase.cpp: Added.
      (DFG):
      (FlushLivenessAnalysisPhase):
      (JSC::DFG::FlushLivenessAnalysisPhase::FlushLivenessAnalysisPhase):
      (JSC::DFG::FlushLivenessAnalysisPhase::run):
      (JSC::DFG::FlushLivenessAnalysisPhase::process):
      (JSC::DFG::FlushLivenessAnalysisPhase::setForNode):
      (JSC::DFG::FlushLivenessAnalysisPhase::flushFormat):
      (JSC::DFG::performFlushLivenessAnalysis):
      * dfg/DFGFlushLivenessAnalysisPhase.h: Added.
      (DFG):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      (JSC::DFG::Graph::dumpBlockHeader):
      (DFG):
      (JSC::DFG::Graph::addForDepthFirstSort):
      (JSC::DFG::Graph::getBlocksInDepthFirstOrder):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::convertToConstant):
      (JSC::DFG::Graph::valueProfileFor):
      (Graph):
      * dfg/DFGInsertionSet.h:
      (DFG):
      (JSC::DFG::InsertionSet::execute):
      * dfg/DFGLivenessAnalysisPhase.cpp: Added.
      (DFG):
      (LivenessAnalysisPhase):
      (JSC::DFG::LivenessAnalysisPhase::LivenessAnalysisPhase):
      (JSC::DFG::LivenessAnalysisPhase::run):
      (JSC::DFG::LivenessAnalysisPhase::process):
      (JSC::DFG::LivenessAnalysisPhase::addChildUse):
      (JSC::DFG::performLivenessAnalysis):
      * dfg/DFGLivenessAnalysisPhase.h: Added.
      (DFG):
      * dfg/DFGNode.cpp:
      (JSC::DFG::Node::hasVariableAccessData):
      (DFG):
      * dfg/DFGNode.h:
      (DFG):
      (Node):
      (JSC::DFG::Node::hasLocal):
      (JSC::DFG::Node::variableAccessData):
      (JSC::DFG::Node::hasPhi):
      (JSC::DFG::Node::phi):
      (JSC::DFG::Node::takenBlock):
      (JSC::DFG::Node::notTakenBlock):
      (JSC::DFG::Node::successor):
      (JSC::DFG::Node::successorForCondition):
      (JSC::DFG::nodeComparator):
      (JSC::DFG::nodeListDump):
      (JSC::DFG::nodeMapDump):
      * dfg/DFGNodeFlags.cpp:
      (JSC::DFG::dumpNodeFlags):
      * dfg/DFGNodeType.h:
      (DFG):
      * dfg/DFGOSRAvailabilityAnalysisPhase.cpp: Added.
      (DFG):
      (OSRAvailabilityAnalysisPhase):
      (JSC::DFG::OSRAvailabilityAnalysisPhase::OSRAvailabilityAnalysisPhase):
      (JSC::DFG::OSRAvailabilityAnalysisPhase::run):
      (JSC::DFG::performOSRAvailabilityAnalysis):
      * dfg/DFGOSRAvailabilityAnalysisPhase.h: Added.
      (DFG):
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      * dfg/DFGPredictionInjectionPhase.cpp:
      (JSC::DFG::PredictionInjectionPhase::run):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGSSAConversionPhase.cpp: Added.
      (DFG):
      (SSAConversionPhase):
      (JSC::DFG::SSAConversionPhase::SSAConversionPhase):
      (JSC::DFG::SSAConversionPhase::run):
      (JSC::DFG::SSAConversionPhase::forwardPhiChildren):
      (JSC::DFG::SSAConversionPhase::forwardPhi):
      (JSC::DFG::SSAConversionPhase::forwardPhiEdge):
      (JSC::DFG::SSAConversionPhase::deduplicateChildren):
      (JSC::DFG::SSAConversionPhase::addFlushedLocalOp):
      (JSC::DFG::SSAConversionPhase::addFlushedLocalEdge):
      (JSC::DFG::performSSAConversion):
      * dfg/DFGSSAConversionPhase.h: Added.
      (DFG):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGValidate.cpp:
      (JSC::DFG::Validate::validate):
      (Validate):
      (JSC::DFG::Validate::validateCPS):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::flushFormat):
      (VariableAccessData):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::lower):
      (JSC::FTL::LowerDFGToLLVM::createPhiVariables):
      (JSC::FTL::LowerDFGToLLVM::compileBlock):
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileUpsilon):
      (LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::compilePhi):
      (JSC::FTL::LowerDFGToLLVM::compileJSConstant):
      (JSC::FTL::LowerDFGToLLVM::compileWeakJSConstant):
      (JSC::FTL::LowerDFGToLLVM::compileGetArgument):
      (JSC::FTL::LowerDFGToLLVM::compileGetLocal):
      (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
      (JSC::FTL::LowerDFGToLLVM::compileAdd):
      (JSC::FTL::LowerDFGToLLVM::compileArithSub):
      (JSC::FTL::LowerDFGToLLVM::compileArithMul):
      (JSC::FTL::LowerDFGToLLVM::compileArithDiv):
      (JSC::FTL::LowerDFGToLLVM::compileArithMod):
      (JSC::FTL::LowerDFGToLLVM::compileArithMinOrMax):
      (JSC::FTL::LowerDFGToLLVM::compileArithAbs):
      (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
      (JSC::FTL::LowerDFGToLLVM::compileBitAnd):
      (JSC::FTL::LowerDFGToLLVM::compileBitOr):
      (JSC::FTL::LowerDFGToLLVM::compileBitXor):
      (JSC::FTL::LowerDFGToLLVM::compileBitRShift):
      (JSC::FTL::LowerDFGToLLVM::compileBitLShift):
      (JSC::FTL::LowerDFGToLLVM::compileBitURShift):
      (JSC::FTL::LowerDFGToLLVM::compileUInt32ToNumber):
      (JSC::FTL::LowerDFGToLLVM::compileInt32ToDouble):
      (JSC::FTL::LowerDFGToLLVM::compileGetButterfly):
      (JSC::FTL::LowerDFGToLLVM::compileGetArrayLength):
      (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
      (JSC::FTL::LowerDFGToLLVM::compileGetByOffset):
      (JSC::FTL::LowerDFGToLLVM::compileGetGlobalVar):
      (JSC::FTL::LowerDFGToLLVM::compileCompareEqConstant):
      (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEqConstant):
      (JSC::FTL::LowerDFGToLLVM::compileCompareLess):
      (JSC::FTL::LowerDFGToLLVM::compileCompareLessEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareGreater):
      (JSC::FTL::LowerDFGToLLVM::compileCompareGreaterEq):
      (JSC::FTL::LowerDFGToLLVM::compileLogicalNot):
      (JSC::FTL::LowerDFGToLLVM::speculateBackward):
      (JSC::FTL::LowerDFGToLLVM::lowInt32):
      (JSC::FTL::LowerDFGToLLVM::lowCell):
      (JSC::FTL::LowerDFGToLLVM::lowBoolean):
      (JSC::FTL::LowerDFGToLLVM::lowDouble):
      (JSC::FTL::LowerDFGToLLVM::lowJSValue):
      (JSC::FTL::LowerDFGToLLVM::lowStorage):
      (JSC::FTL::LowerDFGToLLVM::speculate):
      (JSC::FTL::LowerDFGToLLVM::speculateBoolean):
      (JSC::FTL::LowerDFGToLLVM::isLive):
      (JSC::FTL::LowerDFGToLLVM::use):
      (JSC::FTL::LowerDFGToLLVM::initializeOSRExitStateForBlock):
      (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
      (JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
      (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
      (JSC::FTL::LowerDFGToLLVM::linkOSRExitsAndCompleteInitializationBlocks):
      (JSC::FTL::LowerDFGToLLVM::setInt32):
      (JSC::FTL::LowerDFGToLLVM::setJSValue):
      (JSC::FTL::LowerDFGToLLVM::setBoolean):
      (JSC::FTL::LowerDFGToLLVM::setStorage):
      (JSC::FTL::LowerDFGToLLVM::setDouble):
      (JSC::FTL::LowerDFGToLLVM::isValid):
      * ftl/FTLLoweredNodeValue.h: Added.
      (FTL):
      (LoweredNodeValue):
      (JSC::FTL::LoweredNodeValue::LoweredNodeValue):
      (JSC::FTL::LoweredNodeValue::isSet):
      (JSC::FTL::LoweredNodeValue::operator!):
      (JSC::FTL::LoweredNodeValue::value):
      (JSC::FTL::LoweredNodeValue::block):
      * ftl/FTLValueFromBlock.h:
      (JSC::FTL::ValueFromBlock::ValueFromBlock):
      (ValueFromBlock):
      * ftl/FTLValueSource.cpp:
      (JSC::FTL::ValueSource::dump):
      * ftl/FTLValueSource.h:
      
      Source/WTF:
      
      Reviewed by Mark Hahnenberg.
      
      - Extend variadicity of PrintStream and dataLog.
      
      - Give HashSet the ability to add a span of things.
      
      - Give HashSet the ability to == another HashSet.
      
      - Note FIXME's in HashTable concerning copying performance, that affects
        the way that the DFG now uses HashSets and HashMaps.
      
      - Factor out the bulk-insertion logic of JSC::DFG::InsertionSet into
        WTF::Insertion, so that it can be used in more places.
      
      - Create a dumper for lists and maps.
      
      * WTF.xcodeproj/project.pbxproj:
      * wtf/DataLog.h:
      (WTF):
      (WTF::dataLog):
      * wtf/HashSet.h:
      (HashSet):
      (WTF):
      (WTF::::add):
      (WTF::=):
      * wtf/HashTable.h:
      (WTF::::HashTable):
      (WTF::=):
      * wtf/Insertion.h: Added.
      (WTF):
      (Insertion):
      (WTF::Insertion::Insertion):
      (WTF::Insertion::index):
      (WTF::Insertion::element):
      (WTF::Insertion::operator<):
      (WTF::executeInsertions):
      * wtf/ListDump.h: Added.
      (WTF):
      (ListDump):
      (WTF::ListDump::ListDump):
      (WTF::ListDump::dump):
      (MapDump):
      (WTF::MapDump::MapDump):
      (WTF::MapDump::dump):
      (WTF::listDump):
      (WTF::sortedListDump):
      (WTF::lessThan):
      (WTF::mapDump):
      (WTF::sortedMapDump):
      * wtf/PrintStream.h:
      (PrintStream):
      (WTF::PrintStream::print):
      
      Conflicts:
      	Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153274 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      827d2cf7
    • oliver@apple.com's avatar
      fourthTier: CheckArrays should be hoisted · c0a050be
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116353
      
      Source/JavaScriptCore:
      
      Performance neutral. This will be more important when we start depending on CheckArray for flat arrays.
      
      Reviewed by Filip Pizlo.
      
      * dfg/DFGAbstractState.cpp: Add ForwardCheckArray to wherever we had a CheckArray before.
      (JSC::DFG::AbstractState::executeEffects):
      * dfg/DFGArgumentsSimplificationPhase.cpp:
      (JSC::DFG::ArgumentsSimplificationPhase::run):
      * dfg/DFGArrayMode.h:
      (JSC::DFG::ArrayMode::isContravenedByStructure): Checks if the ArrayMode derived from a specific Structure
      would contradict the ArrayModes that would be filtered by the current ArrayMode. This is used to detect
      if any specific CheckStructures would contradict our CheckArray so that we can defer to the CheckStructure's
      judgment.
      * dfg/DFGByteCodeParser.cpp: Fill in checkArrayHoistingFailed where we previously exited due to a BadIndexingType.
      (JSC::DFG::ByteCodeParser::setLocal):
      (JSC::DFG::ByteCodeParser::setArgument):
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::checkArrayElimination):
      (JSC::DFG::CSEPhase::performNodeCSE):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::hasArrayMode):
      * dfg/DFGNodeType.h: New ForwardCheckArray node type.
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGTypeCheckHoistingPhase.cpp: Refactored most of TypeCheckHoistingPhase into separate functions, some
      of which are now generic to both CheckStructure and CheckArray hoisting while others are specific to one or the
      other. Both of the non-zero CheckBallot values must be 1 because we use them as an index into an array of
      length 2 inside the VariableAccessData.
      (CheckData): Moved structure outside of TypeCheckHoistingPhase so that ArrayTypeCheck and StructureTypeCheck
      can access it. Also added new fields for tracking ArrayModes. We need the m_arrayModeIsValid because there
      isn't a good sentinel value for "this ArrayMode is invalid and meaningless" like there is for m_structure.
      We need m_arrayModeHoistingOkay for when we want to permanently disable hoisting for that particular variable.
      (JSC::DFG::CheckData::CheckData):
      (JSC::DFG::CheckData::disableCheckArrayHoisting): Helper function for disabling CheckArray hoisting for a
      specific CheckData.
      (JSC::DFG::TypeCheckHoistingPhase::run): We now do both CheckStructure and CheckArray hoisting, although we prefer
      CheckStructure hoisting when given the possibility to do both.
      (TypeCheckHoistingPhase):
      (JSC::DFG::TypeCheckHoistingPhase::clearVariableVotes): Clears all of the VariableAccessData votes since they
      can only have two types of votes at any particular time.
      (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
      (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks): Very similar to identifyRedundantStructureChecks,
      but with a few different nodes that are important, namely CheckArray (instead of CheckStructure) and the Arrayify-like
      nodes always disable hoisting since they always change the IndexingType.
      (JSC::DFG::TypeCheckHoistingPhase::disableHoistingForVariablesWithInsufficientVotes):
      (JSC::DFG::TypeCheckHoistingPhase::disableHoistingAcrossOSREntries):
      (JSC::DFG::TypeCheckHoistingPhase::disableCheckArrayHoisting): Helper that looks up the CheckData for the
      specified variable and disables CheckArray hoisting on it.
      (JSC::DFG::TypeCheckHoistingPhase::shouldConsiderForHoisting):
      (JSC::DFG::TypeCheckHoistingPhase::noticeStructureCheck):
      (JSC::DFG::TypeCheckHoistingPhase::noticeCheckArray):
      (JSC::DFG::TypeCheckHoistingPhase::noticeStructureCheckAccountingForArrayMode): We want to take CheckStructure nodes
      into account when hoisting CheckArrays, so we make sure that if we contradict what a CheckStructure says then we
      give up on hoisting the CheckArray.
      (JSC::DFG::ArrayTypeCheck::isValidToHoist):
      (ArrayTypeCheck): Structure that houses some of the specifics on how to hoist CheckArrays. This structure
      is used a template argument to allow some of the very similar code to statically parameterized and reused
      for both CheckStructure and CheckArray hoisting.
      (JSC::DFG::ArrayTypeCheck::disableHoisting):
      (JSC::DFG::ArrayTypeCheck::isContravenedByValue):
      (JSC::DFG::ArrayTypeCheck::hasEnoughVotesToHoist):
      (JSC::DFG::ArrayTypeCheck::hoistingPreviouslyFailed):
      (JSC::DFG::StructureTypeCheck::isValidToHoist):
      (StructureTypeCheck): Same as ArrayTypeCheck, but specific to CheckStructure hoisting.
      (JSC::DFG::StructureTypeCheck::disableHoisting):
      (JSC::DFG::StructureTypeCheck::isContravenedByValue):
      (JSC::DFG::StructureTypeCheck::hasEnoughVotesToHoist):
      (JSC::DFG::StructureTypeCheck::hoistingPreviouslyFailed):
      * dfg/DFGUnificationPhase.cpp: Added merging of whether or not CheckArray hoisting failed.
      (JSC::DFG::UnificationPhase::run):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::VariableAccessData):
      (JSC::DFG::VariableAccessData::mergeCheckArrayHoistingFailed):
      (VariableAccessData):
      (JSC::DFG::VariableAccessData::checkArrayHoistingFailed):
      * runtime/Options.h:
      
      LayoutTests:
      
      Added a microbenchmark to JSRegress that specifically targets CheckArray hoisting.
      We get a 25% improvement on it.
      
      Reviewed by Filip Pizlo.
      
      * fast/js/regress/check-array-hoisting-expected.txt: Added.
      * fast/js/regress/check-array-hoisting.html: Added.
      * fast/js/regress/script-tests/check-array-hoisting.js: Added.
      (f):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153167 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      c0a050be
  10. 12 Mar, 2013 1 commit
    • fpizlo@apple.com's avatar
      DFG overflow check elimination is too smart for its own good · 96820433
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=111832
      
      Source/JavaScriptCore: 
      
      Reviewed by Oliver Hunt and Gavin Barraclough.
              
      Rolling this back in after fixing accidental misuse of JSValue. The code was doing value < someInt
      rather than value.asInt32() < someInt. This "worked" when isWithinPowerOfTwo wasn't templatized.
      It worked by always being false and always disabling the relvant optimization.
              
      This improves overflow check elimination in three ways:
              
      1) It reduces the amount of time the compiler will spend doing it.
              
      2) It fixes bugs where overflow check elimination was overzealous. Precisely, for a binary operation
         over @a and @b where both @a and @b will type check that their inputs (@a->children, @b->children)
         are int32's and then perform a possibly-overflowing operation, we must be careful not to assume
         that @a's non-int32 parts don't matter if at the point that @a runs we have as yet not proved that
         @b->children are int32's and that hence @b might produce a large enough result that doubles would
         start chopping low bits. The specific implication of this is that for a binary operation to not
         propagate that it cares about non-int32 parts (NodeUsedAsNumber), we must prove that at least one
         of the inputs is guaranteed to produce a result within 2^32 and that there won't be a tower of such
         operations large enough to ultimately produce a double greater than 2^52 (roughly). We achieve the
         latter by disabling this optimization for very large basic blocks. It's noteworthy that blocks that
         large won't even make it into the DFG currently.
              
      3) It makes the overflow check elimination more precise for cases where the inputs to an Add or Sub
         are the outputs of a bit-op. For example in (@a + (@b | 0)) | 0, we don't need to propagate
         NodeUsedAsNumber to either @a or @b.
              
      This is neutral on V8v7 and a slight speed-up on compile time benchmarks.
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::ArrayMode::refine):
      * dfg/DFGBackwardsPropagationPhase.cpp: Added.
      (DFG):
      (BackwardsPropagationPhase):
      (JSC::DFG::BackwardsPropagationPhase::BackwardsPropagationPhase):
      (JSC::DFG::BackwardsPropagationPhase::run):
      (JSC::DFG::BackwardsPropagationPhase::isNotNegZero):
      (JSC::DFG::BackwardsPropagationPhase::isNotZero):
      (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwoForConstant):
      (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwoNonRecursive):
      (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwo):
      (JSC::DFG::BackwardsPropagationPhase::mergeDefaultFlags):
      (JSC::DFG::BackwardsPropagationPhase::propagate):
      (JSC::DFG::performBackwardsPropagation):
      * dfg/DFGBackwardsPropagationPhase.h: Added.
      (DFG):
      * dfg/DFGCPSRethreadingPhase.cpp:
      (JSC::DFG::CPSRethreadingPhase::run):
      (JSC::DFG::CPSRethreadingPhase::clearIsLoadedFrom):
      (CPSRethreadingPhase):
      (JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
      (JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocalFor):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      * dfg/DFGNodeFlags.cpp:
      (JSC::DFG::dumpNodeFlags):
      (DFG):
      * dfg/DFGNodeFlags.h:
      (DFG):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (PredictionPropagationPhase):
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGUnificationPhase.cpp:
      (JSC::DFG::UnificationPhase::run):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::VariableAccessData):
      (JSC::DFG::VariableAccessData::mergeIsLoadedFrom):
      (VariableAccessData):
      (JSC::DFG::VariableAccessData::setIsLoadedFrom):
      (JSC::DFG::VariableAccessData::isLoadedFrom):
      
      LayoutTests: 
      
      Reviewed by Oliver Hunt and Gavin Barraclough.
      
      * fast/js/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int-expected.txt: Added.
      * fast/js/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int.html: Added.
      * fast/js/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers-expected.txt: Added.
      * fast/js/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers.html: Added.
      * fast/js/jsc-test-list:
      * fast/js/script-tests/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int.js: Added.
      (foo):
      (bar):
      * fast/js/script-tests/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers.js: Added.
      (foo):
      (bar):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@145489 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      96820433
  11. 09 Mar, 2013 2 commits
    • commit-queue@webkit.org's avatar
      Unreviewed, rolling out r145299. · e8aaf5a0
      commit-queue@webkit.org authored
      http://trac.webkit.org/changeset/145299
      https://bugs.webkit.org/show_bug.cgi?id=111928
      
      compilation failure with recent clang
      (DFGBackwardsPropagationPhase.cpp:132:35: error: comparison of
      constant 10 with expression of type 'bool' is always false)
      (Requested by thorton on #webkit).
      
      Patch by Sheriff Bot <webkit.review.bot@gmail.com> on 2013-03-09
      
      Source/JavaScriptCore:
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::ArrayMode::refine):
      * dfg/DFGBackwardsPropagationPhase.cpp: Removed.
      * dfg/DFGBackwardsPropagationPhase.h: Removed.
      * dfg/DFGCPSRethreadingPhase.cpp:
      (JSC::DFG::CPSRethreadingPhase::run):
      (CPSRethreadingPhase):
      (JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
      (JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocalFor):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      * dfg/DFGNodeFlags.cpp:
      (JSC::DFG::nodeFlagsAsString):
      (DFG):
      * dfg/DFGNodeFlags.h:
      (DFG):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::isNotNegZero):
      (PredictionPropagationPhase):
      (JSC::DFG::PredictionPropagationPhase::isNotZero):
      (JSC::DFG::PredictionPropagationPhase::isWithinPowerOfTwoForConstant):
      (JSC::DFG::PredictionPropagationPhase::isWithinPowerOfTwoNonRecursive):
      (JSC::DFG::PredictionPropagationPhase::isWithinPowerOfTwo):
      (JSC::DFG::PredictionPropagationPhase::propagate):
      (JSC::DFG::PredictionPropagationPhase::mergeDefaultFlags):
      * dfg/DFGUnificationPhase.cpp:
      (JSC::DFG::UnificationPhase::run):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::VariableAccessData):
      (VariableAccessData):
      
      LayoutTests:
      
      * fast/js/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int-expected.txt: Removed.
      * fast/js/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int.html: Removed.
      * fast/js/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers-expected.txt: Removed.
      * fast/js/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers.html: Removed.
      * fast/js/jsc-test-list:
      * fast/js/script-tests/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int.js: Removed.
      * fast/js/script-tests/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers.js: Removed.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@145323 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      e8aaf5a0
    • fpizlo@apple.com's avatar
      DFG overflow check elimination is too smart for its own good · 4695cd92
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=111832
      
      Source/JavaScriptCore: 
      
      Reviewed by Oliver Hunt and Gavin Barraclough.
              
      This improves overflow check elimination in three ways:
              
      1) It reduces the amount of time the compiler will spend doing it.
              
      2) It fixes bugs where overflow check elimination was overzealous. Precisely, for a binary operation
         over @a and @b where both @a and @b will type check that their inputs (@a->children, @b->children)
         are int32's and then perform a possibly-overflowing operation, we must be careful not to assume
         that @a's non-int32 parts don't matter if at the point that @a runs we have as yet not proved that
         @b->children are int32's and that hence @b might produce a large enough result that doubles would
         start chopping low bits. The specific implication of this is that for a binary operation to not
         propagate that it cares about non-int32 parts (NodeUsedAsNumber), we must prove that at least one
         of the inputs is guaranteed to produce a result within 2^32 and that there won't be a tower of such
         operations large enough to ultimately produce a double greater than 2^52 (roughly). We achieve the
         latter by disabling this optimization for very large basic blocks. It's noteworthy that blocks that
         large won't even make it into the DFG currently.
              
      3) It makes the overflow check elimination more precise for cases where the inputs to an Add or Sub
         are the outputs of a bit-op. For example in (@a + (@b | 0)) | 0, we don't need to propagate
         NodeUsedAsNumber to either @a or @b.
              
      This is neutral on V8v7 and a slight speed-up on compile time benchmarks.
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::ArrayMode::refine):
      * dfg/DFGBackwardsPropagationPhase.cpp: Added.
      (DFG):
      (BackwardsPropagationPhase):
      (JSC::DFG::BackwardsPropagationPhase::BackwardsPropagationPhase):
      (JSC::DFG::BackwardsPropagationPhase::run):
      (JSC::DFG::BackwardsPropagationPhase::isNotNegZero):
      (JSC::DFG::BackwardsPropagationPhase::isNotZero):
      (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwoForConstant):
      (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwoNonRecursive):
      (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwo):
      (JSC::DFG::BackwardsPropagationPhase::mergeDefaultFlags):
      (JSC::DFG::BackwardsPropagationPhase::propagate):
      (JSC::DFG::performBackwardsPropagation):
      * dfg/DFGBackwardsPropagationPhase.h: Added.
      (DFG):
      * dfg/DFGCPSRethreadingPhase.cpp:
      (JSC::DFG::CPSRethreadingPhase::run):
      (JSC::DFG::CPSRethreadingPhase::clearIsLoadedFrom):
      (CPSRethreadingPhase):
      (JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
      (JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocalFor):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      * dfg/DFGNodeFlags.cpp:
      (JSC::DFG::dumpNodeFlags):
      (DFG):
      * dfg/DFGNodeFlags.h:
      (DFG):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (PredictionPropagationPhase):
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGUnificationPhase.cpp:
      (JSC::DFG::UnificationPhase::run):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::VariableAccessData):
      (JSC::DFG::VariableAccessData::mergeIsLoadedFrom):
      (VariableAccessData):
      (JSC::DFG::VariableAccessData::setIsLoadedFrom):
      (JSC::DFG::VariableAccessData::isLoadedFrom):
      
      LayoutTests: 
      
      Reviewed by Oliver Hunt and Gavin Barraclough.
      
      * fast/js/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int-expected.txt: Added.
      * fast/js/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int.html: Added.
      * fast/js/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers-expected.txt: Added.
      * fast/js/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers.html: Added.
      * fast/js/jsc-test-list:
      * fast/js/script-tests/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int.js: Added.
      (foo):
      (bar):
      * fast/js/script-tests/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers.js: Added.
      (foo):
      (bar):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@145299 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      4695cd92
  12. 27 Feb, 2013 1 commit
    • fpizlo@apple.com's avatar
      The DFG backend's and OSR's decision to unbox a variable should be based on... · bbaf619c
      fpizlo@apple.com authored
      The DFG backend's and OSR's decision to unbox a variable should be based on whether it's used in a typed context
      https://bugs.webkit.org/show_bug.cgi?id=110433
      
      Reviewed by Oliver Hunt and Mark Hahnenberg.
              
      This introduces the equivalent of a liveness analysis, except for type checking.
      A variable is said to be "profitable for unboxing" (i.e. live at a type check)
      if there exists a type check on a GetLocal of that variable, and the type check
      is consistent with the variable's prediction. Variables that are not profitable
      for unboxing aren't unboxed. Previously they would have been.
              
      This is a slight speed-up on some things but mostly neutral.
      
      * dfg/DFGArgumentPosition.h:
      (JSC::DFG::ArgumentPosition::ArgumentPosition):
      (JSC::DFG::ArgumentPosition::mergeShouldNeverUnbox):
      (JSC::DFG::ArgumentPosition::mergeArgumentPredictionAwareness):
      (JSC::DFG::ArgumentPosition::mergeArgumentUnboxingAwareness):
      (ArgumentPosition):
      (JSC::DFG::ArgumentPosition::isProfitableToUnbox):
      (JSC::DFG::ArgumentPosition::shouldUseDoubleFormat):
      * dfg/DFGCommon.h:
      (JSC::DFG::checkAndSet):
      (DFG):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::run):
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::fixupSetLocalsInBlock):
      (FixupPhase):
      (JSC::DFG::FixupPhase::alwaysUnboxSimplePrimitives):
      (JSC::DFG::FixupPhase::setUseKindAndUnboxIfProfitable):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::checkArgumentTypes):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::VariableAccessData):
      (JSC::DFG::VariableAccessData::mergeIsCaptured):
      (JSC::DFG::VariableAccessData::mergeIsProfitableToUnbox):
      (VariableAccessData):
      (JSC::DFG::VariableAccessData::isProfitableToUnbox):
      (JSC::DFG::VariableAccessData::shouldUnboxIfPossible):
      (JSC::DFG::VariableAccessData::mergeStructureCheckHoistingFailed):
      (JSC::DFG::VariableAccessData::mergeIsArgumentsAlias):
      (JSC::DFG::VariableAccessData::shouldUseDoubleFormat):
      (JSC::DFG::VariableAccessData::mergeFlags):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@144131 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      bbaf619c
  13. 25 Feb, 2013 1 commit
    • fpizlo@apple.com's avatar
      The DFG special case checks for isCreatedThisArgument are fragile · 5470ec77
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=110535
      
      Reviewed by Oliver Hunt.
              
      There may be many situations in which we want to force a variable to never be
      unboxed. Capturing is one such case, and the created this argument is another.
      Previously all code that dealt with this issue had to query both scenarios.
              
      Now DFG::VariableAccessData knows these things. You just have to ask
      VariableAccessData for whether a variable should be unboxed. Anyone wishing to
      force a variable to never be unboxed just tells VariableAccessData.
      
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::initialize):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::parseBlock):
      (DFG):
      * dfg/DFGCFGSimplificationPhase.cpp:
      (CFGSimplificationPhase):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGGraph.h:
      (Graph):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGUnificationPhase.cpp:
      (JSC::DFG::UnificationPhase::run):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::VariableAccessData):
      (JSC::DFG::VariableAccessData::mergeIsCaptured):
      (JSC::DFG::VariableAccessData::mergeShouldNeverUnbox):
      (VariableAccessData):
      (JSC::DFG::VariableAccessData::shouldNeverUnbox):
      (JSC::DFG::VariableAccessData::shouldUnboxIfPossible):
      (JSC::DFG::VariableAccessData::shouldUseDoubleFormat):
      (JSC::DFG::VariableAccessData::tallyVotesForShouldUseDoubleFormat):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@143955 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      5470ec77
  14. 12 Feb, 2013 1 commit
    • fpizlo@apple.com's avatar
      Strange bug in DFG OSR in JSC · 393289db
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=109491
      
      Source/JavaScriptCore: 
      
      Reviewed by Mark Hahnenberg.
              
      Int32ToDouble was being injected after a side-effecting operation and before a SetLocal. Anytime we
      inject something just before a SetLocal we should be aware that the previous operation may have been
      a side-effect associated with the current code origin. Hence, we should use a forward exit.
      Int32ToDouble does not do forward exits by default.
              
      This patch adds a forward-exiting form of Int32ToDouble, for use in SetLocal Int32ToDouble injections.
      Changed the CSE and other things to treat these nodes identically, but for the exit strategy to be
      distinct (Int32ToDouble -> backward, ForwardInt32ToDouble -> forward). The use of the NodeType for
      signaling exit direction is not "great" but it's what we use in other places already (like
      ForwardCheckStructure).
      
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::execute):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::int32ToDoubleCSE):
      (CSEPhase):
      (JSC::DFG::CSEPhase::performNodeCSE):
      * dfg/DFGCommon.h:
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::fixDoubleEdge):
      (JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::willHaveCodeGenOrOSR):
      * dfg/DFGNodeType.h:
      (DFG):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
      (JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
      * dfg/DFGSpeculativeJIT.h:
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGVariableEventStream.cpp:
      (JSC::DFG::VariableEventStream::reconstruct):
      
      LayoutTests: 
      
      Reviewed by Mark Hahnenberg.
              
      Added one version of the test (dfg-int32-to-double-on-set-local-and-exit) that is based
      exactly on Gabor's original test, and another that ought to fail even if I fix other bugs
      in the future (see https://bugs.webkit.org/show_bug.cgi?id=109511).
      
      * fast/js/dfg-int32-to-double-on-set-local-and-exit-expected.txt: Added.
      * fast/js/dfg-int32-to-double-on-set-local-and-exit.html: Added.
      * fast/js/dfg-int32-to-double-on-set-local-and-sometimes-exit-expected.txt: Added.
      * fast/js/dfg-int32-to-double-on-set-local-and-sometimes-exit.html: Added.
      * fast/js/script-tests/dfg-int32-to-double-on-set-local-and-exit.js: Added.
      (checkpoint):
      (func1):
      (func2):
      (func3):
      (test):
      * fast/js/script-tests/dfg-int32-to-double-on-set-local-and-sometimes-exit.js: Added.
      (checkpoint):
      (func1):
      (func2):
      (func3):
      (test):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@142544 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      393289db
  15. 02 Aug, 2012 1 commit
    • fpizlo@apple.com's avatar
      DFG should hoist structure checks · caa68812
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=92696
      
      Source/JavaScriptCore: 
      
      Reviewed by Gavin Barraclough.
      
      This hoists structure checks in the same way that we would hoist array checks, but with added
      complexity to cope with the fact that the structure of an object may change. This is handled
      by performing a side effects analysis over the region in which the respective variable is
      live. If a structure clobbering side effect may happen then we either hoist the structure
      checks and fall back on structure transition watchpoints (if the watchpoint set is still
      valid), or we avoid hoisting altogether.
              
      Doing this required teaching the CFA that we may have an expectation that an object has a
      particular structure even after structure clobbering happens, in the sense that structure
      proofs that were cobbered can be revived using watchpoints. CFA must know about this so that
      OSR entry may know about it, since we cannot allow entry to happen if the variable has a
      clobbered structure proof, will have a watchpoint to revive the proof, and the variable in
      the baseline JIT has a completely unrelated structure.
              
      This is mostly performance neutral.
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * bytecode/ValueRecovery.h:
      (JSC::ValueRecovery::isSet):
      (JSC::ValueRecovery::operator!):
      (ValueRecovery):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::execute):
      (JSC::DFG::AbstractState::clobberWorld):
      (DFG):
      (JSC::DFG::AbstractState::clobberCapturedVars):
      * dfg/DFGAbstractState.h:
      (AbstractState):
      * dfg/DFGAbstractValue.h:
      (JSC::DFG::AbstractValue::clear):
      (JSC::DFG::AbstractValue::isClear):
      (JSC::DFG::AbstractValue::makeTop):
      (JSC::DFG::AbstractValue::isTop):
      (JSC::DFG::AbstractValue::set):
      (JSC::DFG::AbstractValue::operator==):
      (JSC::DFG::AbstractValue::merge):
      (JSC::DFG::AbstractValue::filter):
      (JSC::DFG::AbstractValue::validate):
      (JSC::DFG::AbstractValue::validateForEntry):
      (AbstractValue):
      (JSC::DFG::AbstractValue::checkConsistency):
      (JSC::DFG::AbstractValue::dump):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::setLocal):
      (JSC::DFG::ByteCodeParser::getArgument):
      (JSC::DFG::ByteCodeParser::setArgument):
      (JSC::DFG::ByteCodeParser::parseBlock):
      (JSC::DFG::ByteCodeParser::fixVariableAccessSpeculations):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::checkStructureLoadElimination):
      (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
      (JSC::DFG::CSEPhase::putStructureStoreElimination):
      (JSC::DFG::CSEPhase::getLocalLoadElimination):
      (JSC::DFG::CSEPhase::performNodeCSE):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::vote):
      (Graph):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::convertToStructureTransitionWatchpoint):
      (Node):
      (JSC::DFG::Node::hasStructureSet):
      * dfg/DFGNodeType.h:
      (DFG):
      * dfg/DFGOSREntry.cpp:
      (JSC::DFG::prepareOSREntry):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      (PredictionPropagationPhase):
      (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
      * dfg/DFGSpeculativeJIT.h:
      (SpeculativeJIT):
      (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck):
      (JSC::DFG::SpeculativeJIT::speculationCheckWithConditionalDirection):
      (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecutionWithConditionalDirection):
      (JSC::DFG::SpeculateCellOperand::SpeculateCellOperand):
      (JSC::DFG::SpeculateCellOperand::gpr):
      (SpeculateCellOperand):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGStructureCheckHoistingPhase.cpp: Added.
      (DFG):
      (StructureCheckHoistingPhase):
      (JSC::DFG::StructureCheckHoistingPhase::StructureCheckHoistingPhase):
      (JSC::DFG::StructureCheckHoistingPhase::run):
      (JSC::DFG::StructureCheckHoistingPhase::noticeStructureCheck):
      (JSC::DFG::StructureCheckHoistingPhase::noticeClobber):
      (JSC::DFG::StructureCheckHoistingPhase::clobber):
      (CheckData):
      (JSC::DFG::StructureCheckHoistingPhase::CheckData::CheckData):
      (JSC::DFG::performStructureCheckHoisting):
      * dfg/DFGStructureCheckHoistingPhase.h: Added.
      (DFG):
      * dfg/DFGVariableAccessData.h:
      (VariableAccessData):
      (JSC::DFG::VariableAccessData::VariableAccessData):
      (JSC::DFG::VariableAccessData::mergeStructureCheckHoistingFailed):
      (JSC::DFG::VariableAccessData::structureCheckHoistingFailed):
      (JSC::DFG::VariableAccessData::clearVotes):
      (JSC::DFG::VariableAccessData::vote):
      (JSC::DFG::VariableAccessData::voteRatio):
      (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):
      * runtime/Options.h:
      (JSC):
      
      LayoutTests: 
      
      Rubber stamped by Gavin Barraclough.
      
      Added a new test that covers the following scenarios:
              
      - OSR entry if a variable with a hoisted check has an unexpected structure, structures get clobbered, and
        we're protecting ourselves with structure transition watchpoints.
              
      - OSR exit on hoisted structure checks, if the object doesn't have the expected structure, and where the
        source of the assignment is side-effecting.
              
      I combined these into a single test because there is no way to test the latter without testing the former.
      
      * fast/js/dfg-osr-entry-hoisted-clobbered-structure-check-expected.txt: Added.
      * fast/js/dfg-osr-entry-hoisted-clobbered-structure-check.html: Added.
      * fast/js/jsc-test-list:
      * fast/js/script-tests/dfg-osr-entry-hoisted-clobbered-structure-check.js: Added.
      (foo):
      (bar):
      (baz):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@124404 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      caa68812
  16. 03 Jul, 2012 1 commit
    • commit-queue@webkit.org's avatar
      Add ability to symbolically set and dump JSC VM options. · fbda60c5
      commit-queue@webkit.org authored
      See comments in runtime/Options.h for details on how the options work.
      https://bugs.webkit.org/show_bug.cgi?id=90420
      
      Patch by Mark Lam <mark.lam@apple.com> on 2012-07-03
      Reviewed by Filip Pizlo.
      
      * assembler/LinkBuffer.cpp:
      (JSC::LinkBuffer::finalizeCodeWithDisassembly):
      * assembler/LinkBuffer.h:
      (JSC):
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::shouldOptimizeNow):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::likelyToTakeSlowCase):
      (JSC::CodeBlock::couldTakeSlowCase):
      (JSC::CodeBlock::likelyToTakeSpecialFastCase):
      (JSC::CodeBlock::likelyToTakeDeepestSlowCase):
      (JSC::CodeBlock::likelyToTakeAnySlowCase):
      (JSC::CodeBlock::jitAfterWarmUp):
      (JSC::CodeBlock::jitSoon):
      (JSC::CodeBlock::reoptimizationRetryCounter):
      (JSC::CodeBlock::countReoptimization):
      (JSC::CodeBlock::counterValueForOptimizeAfterWarmUp):
      (JSC::CodeBlock::counterValueForOptimizeAfterLongWarmUp):
      (JSC::CodeBlock::optimizeSoon):
      (JSC::CodeBlock::exitCountThresholdForReoptimization):
      (JSC::CodeBlock::exitCountThresholdForReoptimizationFromLoop):
      * bytecode/ExecutionCounter.h:
      (JSC::ExecutionCounter::clippedThreshold):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::handleInlining):
      * dfg/DFGCapabilities.h:
      (JSC::DFG::mightCompileEval):
      (JSC::DFG::mightCompileProgram):
      (JSC::DFG::mightCompileFunctionForCall):
      (JSC::DFG::mightCompileFunctionForConstruct):
      (JSC::DFG::mightInlineFunctionForCall):
      (JSC::DFG::mightInlineFunctionForConstruct):
      * dfg/DFGCommon.h:
      (JSC::DFG::shouldShowDisassembly):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * dfg/DFGOSRExit.cpp:
      (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):
      * heap/MarkStack.cpp:
      (JSC::MarkStackSegmentAllocator::allocate):
      (JSC::MarkStackSegmentAllocator::shrinkReserve):
      (JSC::MarkStackArray::MarkStackArray):
      (JSC::MarkStackThreadSharedData::MarkStackThreadSharedData):
      (JSC::SlotVisitor::donateKnownParallel):
      (JSC::SlotVisitor::drain):
      (JSC::SlotVisitor::drainFromShared):
      * heap/MarkStack.h:
      (JSC::MarkStack::mergeOpaqueRootsIfProfitable):
      (JSC::MarkStack::addOpaqueRoot):
      * heap/SlotVisitor.h:
      (JSC::SlotVisitor::donate):
      * jit/JIT.cpp:
      (JSC::JIT::emitOptimizationCheck):
      * jsc.cpp:
      (printUsageStatement):
      (parseArguments):
      * runtime/InitializeThreading.cpp:
      (JSC::initializeThreadingOnce):
      * runtime/JSGlobalData.cpp:
      (JSC::enableAssembler):
      * runtime/JSGlobalObject.cpp:
      (JSC::JSGlobalObject::JSGlobalObject):
      * runtime/Options.cpp:
      (JSC):
      (JSC::overrideOptionWithHeuristic):
      (JSC::Options::initialize):
      (JSC::Options::setOption):
      (JSC::Options::dumpAllOptions):
      (JSC::Options::dumpOption):
      * runtime/Options.h:
      (JSC):
      (Options):
      (EntryInfo):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@121798 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      fbda60c5
  17. 07 Jun, 2012 1 commit
    • fpizlo@apple.com's avatar
      PredictedType should be called SpeculatedType · 62336163
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=88477
      
      Rubber stamped by Gavin Barraclough.
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::shouldOptimizeNow):
      (JSC::CodeBlock::dumpValueProfiles):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::valueProfilePredictionForBytecodeOffset):
      * bytecode/LazyOperandValueProfile.cpp:
      (JSC::LazyOperandValueProfileParser::prediction):
      * bytecode/LazyOperandValueProfile.h:
      (LazyOperandValueProfileParser):
      * bytecode/PredictedType.cpp: Removed.
      * bytecode/PredictedType.h: Removed.
      * bytecode/SpeculatedType.cpp: Copied from Source/JavaScriptCore/bytecode/PredictedType.cpp.
      (JSC::speculationToString):
      (JSC::speculationToAbbreviatedString):
      (JSC::speculationFromClassInfo):
      (JSC::speculationFromStructure):
      (JSC::speculationFromCell):
      (JSC::speculationFromValue):
      * bytecode/SpeculatedType.h: Copied from Source/JavaScriptCore/bytecode/PredictedType.h.
      (JSC):
      (JSC::isAnySpeculation):
      (JSC::isCellSpeculation):
      (JSC::isObjectSpeculation):
      (JSC::isFinalObjectSpeculation):
      (JSC::isFinalObjectOrOtherSpeculation):
      (JSC::isFixedIndexedStorageObjectSpeculation):
      (JSC::isStringSpeculation):
      (JSC::isArraySpeculation):
      (JSC::isFunctionSpeculation):
      (JSC::isInt8ArraySpeculation):
      (JSC::isInt16ArraySpeculation):
      (JSC::isInt32ArraySpeculation):
      (JSC::isUint8ArraySpeculation):
      (JSC::isUint8ClampedArraySpeculation):
      (JSC::isUint16ArraySpeculation):
      (JSC::isUint32ArraySpeculation):
      (JSC::isFloat32ArraySpeculation):
      (JSC::isFloat64ArraySpeculation):
      (JSC::isArgumentsSpeculation):
      (JSC::isActionableIntMutableArraySpeculation):
      (JSC::isActionableFloatMutableArraySpeculation):
      (JSC::isActionableTypedMutableArraySpeculation):
      (JSC::isActionableMutableArraySpeculation):
      (JSC::isActionableArraySpeculation):
      (JSC::isArrayOrOtherSpeculation):
      (JSC::isMyArgumentsSpeculation):
      (JSC::isInt32Speculation):
      (JSC::isDoubleRealSpeculation):
      (JSC::isDoubleSpeculation):
      (JSC::isNumberSpeculation):
      (JSC::isBooleanSpeculation):
      (JSC::isOtherSpeculation):
      (JSC::isEmptySpeculation):
      (JSC::mergeSpeculations):
      (JSC::mergeSpeculation):
      * bytecode/StructureSet.h:
      (JSC::StructureSet::speculationFromStructures):
      * bytecode/ValueProfile.h:
      (JSC::ValueProfileBase::ValueProfileBase):
      (JSC::ValueProfileBase::dump):
      (JSC::ValueProfileBase::computeUpdatedPrediction):
      (ValueProfileBase):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::initialize):
      (JSC::DFG::AbstractState::execute):
      (JSC::DFG::AbstractState::mergeStateAtTail):
      * dfg/DFGAbstractState.h:
      (JSC::DFG::AbstractState::speculateInt32Unary):
      (JSC::DFG::AbstractState::speculateNumberUnary):
      (JSC::DFG::AbstractState::speculateBooleanUnary):
      (JSC::DFG::AbstractState::speculateInt32Binary):
      (JSC::DFG::AbstractState::speculateNumberBinary):
      * dfg/DFGAbstractValue.h:
      (JSC::DFG::StructureAbstractValue::filter):
      (JSC::DFG::StructureAbstractValue::speculationFromStructures):
      (JSC::DFG::AbstractValue::AbstractValue):
      (JSC::DFG::AbstractValue::clear):
      (JSC::DFG::AbstractValue::isClear):
      (JSC::DFG::AbstractValue::makeTop):
      (JSC::DFG::AbstractValue::clobberStructures):
      (JSC::DFG::AbstractValue::isTop):
      (JSC::DFG::AbstractValue::set):
      (JSC::DFG::AbstractValue::merge):
      (JSC::DFG::AbstractValue::filter):
      (JSC::DFG::AbstractValue::validateIgnoringValue):
      (JSC::DFG::AbstractValue::validate):
      (JSC::DFG::AbstractValue::checkConsistency):
      (JSC::DFG::AbstractValue::dump):
      (AbstractValue):
      * dfg/DFGArgumentPosition.h:
      (JSC::DFG::ArgumentPosition::ArgumentPosition):
      (JSC::DFG::ArgumentPosition::mergeArgumentAwareness):
      (JSC::DFG::ArgumentPosition::prediction):
      (ArgumentPosition):
      * dfg/DFGArgumentsSimplificationPhase.cpp:
      (JSC::DFG::ArgumentsSimplificationPhase::run):
      * dfg/DFGByteCodeParser.cpp:
      (ByteCodeParser):
      (JSC::DFG::ByteCodeParser::injectLazyOperandSpeculation):
      (JSC::DFG::ByteCodeParser::getLocal):
      (JSC::DFG::ByteCodeParser::getArgument):
      (JSC::DFG::ByteCodeParser::addCall):
      (JSC::DFG::ByteCodeParser::getSpeculationWithoutOSRExit):
      (JSC::DFG::ByteCodeParser::getSpeculation):
      (InlineStackEntry):
      (JSC::DFG::ByteCodeParser::handleCall):
      (JSC::DFG::ByteCodeParser::handleIntrinsic):
      (JSC::DFG::ByteCodeParser::handleGetById):
      (JSC::DFG::ByteCodeParser::parseBlock):
      (JSC::DFG::ByteCodeParser::fixVariableAccessSpeculations):
      (JSC::DFG::ByteCodeParser::parse):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination):
      (JSC::DFG::CSEPhase::performNodeCSE):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::run):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::fixDoubleEdge):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::nameOfVariableAccessData):
      (JSC::DFG::Graph::dump):
      (JSC::DFG::Graph::predictArgumentTypes):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::getJSConstantSpeculation):
      (JSC::DFG::Graph::isPredictedNumerical):
      (JSC::DFG::Graph::byValIsPure):
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::JITCompiler::getSpeculation):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::Node):
      (JSC::DFG::Node::getHeapPrediction):
      (JSC::DFG::Node::predictHeap):
      (JSC::DFG::Node::prediction):
      (JSC::DFG::Node::predict):
      (JSC::DFG::Node::shouldSpeculateInteger):
      (JSC::DFG::Node::shouldSpeculateDouble):
      (JSC::DFG::Node::shouldSpeculateNumber):
      (JSC::DFG::Node::shouldSpeculateBoolean):
      (JSC::DFG::Node::shouldSpeculateFinalObject):
      (JSC::DFG::Node::shouldSpeculateFinalObjectOrOther):
      (JSC::DFG::Node::shouldSpeculateArray):
      (JSC::DFG::Node::shouldSpeculateArguments):
      (JSC::DFG::Node::shouldSpeculateInt8Array):
      (JSC::DFG::Node::shouldSpeculateInt16Array):
      (JSC::DFG::Node::shouldSpeculateInt32Array):
      (JSC::DFG::Node::shouldSpeculateUint8Array):
      (JSC::DFG::Node::shouldSpeculateUint8ClampedArray):
      (JSC::DFG::Node::shouldSpeculateUint16Array):
      (JSC::DFG::Node::shouldSpeculateUint32Array):
      (JSC::DFG::Node::shouldSpeculateFloat32Array):
      (JSC::DFG::Node::shouldSpeculateFloat64Array):
      (JSC::DFG::Node::shouldSpeculateArrayOrOther):
      (JSC::DFG::Node::shouldSpeculateObject):
      (JSC::DFG::Node::shouldSpeculateCell):
      (Node):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::setPrediction):
      (JSC::DFG::PredictionPropagationPhase::mergePrediction):
      (JSC::DFG::PredictionPropagationPhase::propagate):
      (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::fillStorage):
      (JSC::DFG::SpeculativeJIT::writeBarrier):
      (JSC::DFG::GPRTemporary::GPRTemporary):
      (JSC::DFG::FPRTemporary::FPRTemporary):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleDoubleBranch):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
      (JSC::DFG::SpeculativeJIT::compile):
      (JSC::DFG::SpeculativeJIT::checkArgumentTypes):
      (JSC::DFG::SpeculativeJIT::compileGetCharCodeAt):
      (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
      (JSC::DFG::SpeculativeJIT::compileValueToInt32):
      (JSC::DFG::SpeculativeJIT::compileDoubleAsInt32):
      (JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
      (JSC::DFG::SpeculativeJIT::compileGetTypedArrayLength):
      (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
      (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
      (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
      (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray):
      (JSC::DFG::SpeculativeJIT::compileInstanceOf):
      (JSC::DFG::SpeculativeJIT::compileAdd):
      (JSC::DFG::SpeculativeJIT::compileArithSub):
      (JSC::DFG::SpeculativeJIT::compileArithNegate):
      (JSC::DFG::SpeculativeJIT::compileArithMul):
      (JSC::DFG::SpeculativeJIT::compileArithMod):
      (JSC::DFG::SpeculativeJIT::compare):
      (JSC::DFG::SpeculativeJIT::compileStrictEq):
      (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
      (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments):
      (JSC::DFG::SpeculativeJIT::compileGetArgumentsLength):
      (JSC::DFG::SpeculativeJIT::compileRegExpExec):
      * dfg/DFGSpeculativeJIT.h:
      (DFG):
      (JSC::DFG::ValueSource::forSpeculation):
      (SpeculativeJIT):
      (GPRTemporary):
      (FPRTemporary):
      (JSC::DFG::SpecDoubleOperand::SpecDoubleOperand):
      (JSC::DFG::SpecDoubleOperand::~SpecDoubleOperand):
      (JSC::DFG::SpecDoubleOperand::fpr):
      (JSC::DFG::SpecCellOperand::SpecCellOperand):
      (JSC::DFG::SpecCellOperand::~SpecCellOperand):
      (JSC::DFG::SpecCellOperand::gpr):
      (JSC::DFG::SpecBooleanOperand::SpecBooleanOperand):
      (JSC::DFG::SpecBooleanOperand::~SpecBooleanOperand):
      (JSC::DFG::SpecBooleanOperand::gpr):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
      (JSC::DFG::SpeculativeJIT::fillSpecDouble):
      (JSC::DFG::SpeculativeJIT::fillSpecCell):
      (JSC::DFG::SpeculativeJIT::fillSpecBoolean):
      (JSC::DFG::SpeculativeJIT::compileObjectEquality):
      (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compileDoubleCompare):
      (JSC::DFG::SpeculativeJIT::compileLogicalNot):
      (JSC::DFG::SpeculativeJIT::emitBranch):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
      (JSC::DFG::SpeculativeJIT::fillSpecDouble):
      (JSC::DFG::SpeculativeJIT::fillSpecCell):
      (JSC::DFG::SpeculativeJIT::fillSpecBoolean):
      (JSC::DFG::SpeculativeJIT::compileObjectEquality):
      (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compileDoubleCompare):
      (JSC::DFG::SpeculativeJIT::compileLogicalNot):
      (JSC::DFG::SpeculativeJIT::emitBranch):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::VariableAccessData):
      (JSC::DFG::VariableAccessData::predict):
      (JSC::DFG::VariableAccessData::nonUnifiedPrediction):
      (JSC::DFG::VariableAccessData::prediction):
      (JSC::DFG::VariableAccessData::argumentAwarePrediction):
      (JSC::DFG::VariableAccessData::mergeArgumentAwarePrediction):
      (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):
      (JSC::DFG::VariableAccessData::makePredictionForDoubleFormat):
      (VariableAccessData):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@119660 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      62336163
  18. 24 May, 2012 1 commit
    • fpizlo@apple.com's avatar
      DFG should optimize aliased uses of the Arguments object of the current call frame · 9a548f19
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=86552
      
      Source/JavaScriptCore: 
      
      Reviewed by Geoff Garen.
              
      Merged r117542 and r117543 from dfgopt.
              
      Performs must-alias and escape analysis on uses of CreateArguments, and if
      a variable is must-aliased to CreateArguments and does not escape, then we
      turn all uses of that variable into direct arguments accesses.
              
      36% speed-up on V8/earley leading to a 2.3% speed-up overall in V8.
      
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::uncheckedArgumentsRegister):
      * bytecode/ValueRecovery.h:
      (JSC::ValueRecovery::argumentsThatWereNotCreated):
      (ValueRecovery):
      (JSC::ValueRecovery::dump):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::execute):
      * dfg/DFGAdjacencyList.h:
      (AdjacencyList):
      (JSC::DFG::AdjacencyList::removeEdgeFromBag):
      * dfg/DFGArgumentsSimplificationPhase.cpp:
      (JSC::DFG::ArgumentsSimplificationPhase::run):
      (ArgumentsSimplificationPhase):
      (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse):
      (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUses):
      (JSC::DFG::ArgumentsSimplificationPhase::observeProperArgumentsUse):
      (JSC::DFG::ArgumentsSimplificationPhase::isOKToOptimize):
      (JSC::DFG::ArgumentsSimplificationPhase::removeArgumentsReferencingPhantomChild):
      * dfg/DFGAssemblyHelpers.h:
      (JSC::DFG::AssemblyHelpers::argumentsRegisterFor):
      (AssemblyHelpers):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGCFGSimplificationPhase.cpp:
      (JSC::DFG::CFGSimplificationPhase::removePotentiallyDeadPhiReference):
      * dfg/DFGGPRInfo.h:
      (GPRInfo):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::collectGarbage):
      (DFG):
      * dfg/DFGGraph.h:
      (Graph):
      (JSC::DFG::Graph::executableFor):
      (JSC::DFG::Graph::argumentsRegisterFor):
      (JSC::DFG::Graph::uncheckedArgumentsRegisterFor):
      (JSC::DFG::Graph::clobbersWorld):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::hasHeapPrediction):
      * dfg/DFGNodeType.h:
      (DFG):
      * dfg/DFGOSRExitCompiler.cpp:
      * dfg/DFGOSRExitCompiler.h:
      (JSC::DFG::OSRExitCompiler::OSRExitCompiler):
      (OSRExitCompiler):
      * dfg/DFGOSRExitCompiler32_64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * dfg/DFGOSRExitCompiler64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * dfg/DFGOperations.cpp:
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::ValueSource::dump):
      (JSC::DFG::SpeculativeJIT::compile):
      (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor):
      * dfg/DFGSpeculativeJIT.h:
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::VariableAccessData):
      (JSC::DFG::VariableAccessData::mergeIsArgumentsAlias):
      (VariableAccessData):
      (JSC::DFG::VariableAccessData::isArgumentsAlias):
      * jit/JITOpcodes.cpp:
      (JSC::JIT::emitSlow_op_get_argument_by_val):
      
      LayoutTests: 
      
      Rubber stamped by Geoff Garen.
              
      Merged r117542 from dfgopt.
              
      Added a bunch of tests that check that our optimizations for aliased uses of the
      'arguments' object are robust against various forms of JavaScript crazy.
              
      * fast/js/dfg-arguments-alias-escape-expected.txt: Added.
      * fast/js/dfg-arguments-alias-escape.html: Added.
      * fast/js/dfg-arguments-alias-expected.txt: Added.
      * fast/js/dfg-arguments-alias.html: Added.
      * fast/js/dfg-arguments-cross-code-origin-expected.txt: Added.
      * fast/js/dfg-arguments-cross-code-origin.html: Added.
      * fast/js/dfg-arguments-mixed-alias-expected.txt: Added.
      * fast/js/dfg-arguments-mixed-alias.html: Added.
      * fast/js/dfg-arguments-osr-exit-expected.txt: Added.
      * fast/js/dfg-arguments-osr-exit.html: Added.
      * fast/js/dfg-arguments-unexpected-escape-expected.txt: Added.
      * fast/js/dfg-arguments-unexpected-escape.html: Added.
      * fast/js/jsc-test-list:
      * fast/js/script-tests/dfg-arguments-alias-escape.js: Added.
      (foo):
      (bar):
      * fast/js/script-tests/dfg-arguments-alias.js: Added.
      (foo):
      (bar):
      * fast/js/script-tests/dfg-arguments-cross-code-origin.js: Added.
      (foo):
      (bar):
      (baz):
      * fast/js/script-tests/dfg-arguments-mixed-alias.js: Added.
      (foo):
      (bar):
      * fast/js/script-tests/dfg-arguments-osr-exit.js: Added.
      (baz):
      (foo):
      (bar):
      * fast/js/script-tests/dfg-arguments-unexpected-escape.js: Added.
      (baz):
      (foo):
      (bar):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@118323 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      9a548f19
  19. 23 May, 2012 1 commit
    • fpizlo@apple.com's avatar
      DFG variable capture analysis should work even if the variables arose through inlining · 1688cc18
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=85945
      
      Reviewed by Oliver Hunt.
              
      Merged r116555 from dfgopt.
              
      This just changes how the DFG queries whether a variable is captured. It does not
      change any user-visible behavior.
              
      As part of this change, I further solidified the policy that the CFA behaves in an
      undefined way for captured locals and queries about their values will not yield
      reliable results. This will likely be changed in the future, but for now it makes
      sense.
              
      One fun part about this change is that it recognizes that the same variable may
      be both captured and not, at the same time, because their live interval spans
      inlining boundaries. This only happens in the case of arguments to functions that
      capture their arguments, and this change treats them with just the right touch of
      conservatism: they will be treated as if captured by the caller as well as the 
      callee.
              
      Finally, this also adds captured variable reasoning to the InlineCallFrame, which
      I thought might be useful for later tooling.
              
      This is perf-neutral, since it does it does not make the DFG take advantage of this
      new functionality in any way. In particular, it is still the case that the DFG will
      not inline functions that use arguments reflectively or that create activations.
      
      * bytecode/CodeBlock.h:
      (CodeBlock):
      (JSC::CodeBlock::needsActivation):
      (JSC::CodeBlock::argumentIsCaptured):
      (JSC::CodeBlock::localIsCaptured):
      (JSC::CodeBlock::isCaptured):
      * bytecode/CodeOrigin.h:
      (InlineCallFrame):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::initialize):
      (JSC::DFG::AbstractState::endBasicBlock):
      (JSC::DFG::AbstractState::execute):
      (JSC::DFG::AbstractState::merge):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::newVariableAccessData):
      (JSC::DFG::ByteCodeParser::getLocal):
      (JSC::DFG::ByteCodeParser::setLocal):
      (JSC::DFG::ByteCodeParser::getArgument):
      (JSC::DFG::ByteCodeParser::setArgument):
      (JSC::DFG::ByteCodeParser::flushArgument):
      (JSC::DFG::ByteCodeParser::parseBlock):
      (JSC::DFG::ByteCodeParser::processPhiStack):
      (JSC::DFG::ByteCodeParser::fixVariableAccessPredictions):
      (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
      * dfg/DFGCFGSimplificationPhase.cpp:
      (CFGSimplificationPhase):
      (JSC::DFG::CFGSimplificationPhase::keepOperandAlive):
      (JSC::DFG::CFGSimplificationPhase::fixPossibleGetLocal):
      (JSC::DFG::CFGSimplificationPhase::fixTailOperand):
      * dfg/DFGCommon.h:
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::nameOfVariableAccessData):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::needsActivation):
      (JSC::DFG::Graph::usesArguments):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::VariableAccessData):
      (JSC::DFG::VariableAccessData::mergeIsCaptured):
      (VariableAccessData):
      (JSC::DFG::VariableAccessData::isCaptured):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@118136 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      1688cc18
  20. 11 Apr, 2012 1 commit
    • fpizlo@apple.com's avatar
      DFG should flush SetLocals to arguments · af8940bf
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=83554
      
      Source/JavaScriptCore: 
      
      Reviewed by Gavin Barraclough.
              
      This is necessary to match baseline JIT argument capture behavior.
              
      But to make this work right we need to have a story for arguments into
      which we store values of different formats. This patch introduces the
      notion of an ArgumentPosition - i.e. an argument in a particular inline
      call frame - and forces unification of all data pertinent to selecting
      the argument's data format.
              
      Also fixed an amusing bug in the handling of OSR on SetLocals if there
      was any insertion/deletion of nodes in the basic block. This is benign
      for now but won't be eventually since the DFG is getting smarter. So
      better fix it now.
              
      Also fixed an amusing bug in the handling of OSR on SetLocals if they
      are immediately followed by a Flush. I think this bug might have always
      been there but now it'll happen more commonly, and it's covered by the
      run-javascriptcore-tests.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::execute):
      * dfg/DFGArgumentPosition.h: Added.
      (DFG):
      (ArgumentPosition):
      (JSC::DFG::ArgumentPosition::ArgumentPosition):
      (JSC::DFG::ArgumentPosition::addVariable):
      (JSC::DFG::ArgumentPosition::mergeArgumentAwareness):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::setLocal):
      (JSC::DFG::ByteCodeParser::setArgument):
      (InlineStackEntry):
      (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
      * dfg/DFGDoubleFormatState.h: Added.
      (DFG):
      (JSC::DFG::mergeDoubleFormatStates):
      (JSC::DFG::mergeDoubleFormatState):
      (JSC::DFG::doubleFormatStateToString):
      * dfg/DFGGraph.h:
      (Graph):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::VariableAccessData):
      (JSC::DFG::VariableAccessData::predict):
      (JSC::DFG::VariableAccessData::argumentAwarePrediction):
      (VariableAccessData):
      (JSC::DFG::VariableAccessData::mergeArgumentAwarePrediction):
      (JSC::DFG::VariableAccessData::doubleFormatState):
      (JSC::DFG::VariableAccessData::shouldUseDoubleFormat):
      (JSC::DFG::VariableAccessData::tallyVotesForShouldUseDoubleFormat):
      (JSC::DFG::VariableAccessData::mergeDoubleFormatState):
      (JSC::DFG::VariableAccessData::makePredictionForDoubleFormat):
      
      Source/WTF: 
      
      Reviewed by Gavin Barraclough.
              
      Added an isRoot() method that is a faster shorthand for saying
      find() == this.
      
      * wtf/UnionFind.h:
      (WTF::UnionFind::isRoot):
      (UnionFind):
      
      LayoutTests: 
      
      Rubber stamped by Gavin Barraclough.
              
      Added a variety of tests for reassigning arguments prior to function.arguments
      retrieval.
      
      * fast/js/dfg-inline-arguments-become-double-expected.txt: Added.
      * fast/js/dfg-inline-arguments-become-double.html: Added.
      * fast/js/dfg-inline-arguments-become-int32-expected.txt: Added.
      * fast/js/dfg-inline-arguments-become-int32.html: Added.
      * fast/js/dfg-inline-arguments-reset-changetype-expected.txt: Added.
      * fast/js/dfg-inline-arguments-reset-changetype.html: Added.
      * fast/js/dfg-inline-arguments-reset-expected.txt: Added.
      * fast/js/dfg-inline-arguments-reset.html: Added.
      * fast/js/script-tests/dfg-inline-arguments-become-double.js: Added.
      (foo):
      (bar):
      (baz):
      (argsToStr):
      * fast/js/script-tests/dfg-inline-arguments-become-int32.js: Added.
      (foo):
      (bar):
      (baz):
      (argsToStr):
      * fast/js/script-tests/dfg-inline-arguments-reset-changetype.js: Added.
      (foo):
      (bar):
      (baz):
      (argsToStr):
      * fast/js/script-tests/dfg-inline-arguments-reset.js: Added.
      (foo):
      (bar):
      (baz):
      (argsToStr):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@113796 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      af8940bf
  21. 25 Mar, 2012 2 commits
    • fpizlo@apple.com's avatar
      DFGOperands should be moved out of the DFG and into bytecode · 9cf19819
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=82151
      
      Reviewed by Dan Bernstein.
      
      * GNUmakefile.list.am:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/Operands.h: Copied from Source/JavaScriptCore/dfg/DFGOperands.h.
      * dfg/DFGBasicBlock.h:
      * dfg/DFGNode.h:
      * dfg/DFGOSREntry.h:
      * dfg/DFGOSRExit.h:
      * dfg/DFGOperands.h: Removed.
      * dfg/DFGVariableAccessData.h:
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@112039 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      9cf19819
    • fpizlo@apple.com's avatar
      DFG double voting may be overzealous in the case of variables that end up · deecc64f
      fpizlo@apple.com authored
      being used as integers
      https://bugs.webkit.org/show_bug.cgi?id=82008
      
      Reviewed by Oliver Hunt.
              
      Cleaned up propagation, making the intent more explicit in most places.
      Back-propagate NodeUsedAsInt for cases where a node was used in a context
      that is known to strongly prefer integers.
      
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::handleCall):
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dumpCodeOrigin):
      (JSC::DFG::Graph::dump):
      * dfg/DFGGraph.h:
      (Graph):
      * dfg/DFGNodeFlags.cpp:
      (JSC::DFG::nodeFlagsAsString):
      * dfg/DFGNodeFlags.h:
      (DFG):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::run):
      (JSC::DFG::PredictionPropagationPhase::propagate):
      (PredictionPropagationPhase):
      (JSC::DFG::PredictionPropagationPhase::mergeDefaultFlags):
      (JSC::DFG::PredictionPropagationPhase::vote):
      (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
      (JSC::DFG::PredictionPropagationPhase::fixupNode):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@112015 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      deecc64f
  22. 13 Mar, 2012 1 commit
    • fpizlo@apple.com's avatar
      Arithmetic use inference should be procedure-global and should run in tandem · 6740bf84
      fpizlo@apple.com authored
      with type propagation
      https://bugs.webkit.org/show_bug.cgi?id=80819
      <rdar://problem/11034006>
      
      Reviewed by Gavin Barraclough.
              
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * dfg/DFGArithNodeFlagsInferencePhase.cpp: Removed.
      * dfg/DFGArithNodeFlagsInferencePhase.h: Removed.
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::isNotNegZero):
      (PredictionPropagationPhase):
      (JSC::DFG::PredictionPropagationPhase::isNotZero):
      (JSC::DFG::PredictionPropagationPhase::propagate):
      (JSC::DFG::PredictionPropagationPhase::mergeDefaultArithFlags):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::VariableAccessData):
      (JSC::DFG::VariableAccessData::flags):
      (VariableAccessData):
      (JSC::DFG::VariableAccessData::mergeFlags):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@110518 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      6740bf84
  23. 23 Feb, 2012 1 commit
    • fpizlo@apple.com's avatar
      DFG OSR exit value profiling should have graceful handling of local variables and arguments · 31659dee
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=79310
      
      Reviewed by Gavin Barraclough.
              
      Previously, if we OSR exited because a prediction in a local was wrong, we'd
      only realize what the true type of the local was if the regular value profiling
      kicked in and told us. Unless the local was block-locally copy propagated, in
      which case we'd know from an OSR exit profile.
              
      This patch adds OSR exit profiling to all locals and arguments. Now, if we OSR
      exit because of a mispredicted local or argument type, we'll know what the type of
      the local or argument should be immediately upon exiting.
              
      The way that local variable OSR exit profiling works is that we now have a lazily
      added set of OSR-exit-only value profiles for exit sites that are BadType and that
      cited a GetLocal as their value source. The value profiles are only added if the
      OSR exit is taken, and are keyed by CodeBlock, bytecode index of the GetLocal, and
      operand. The look-up is performed by querying the
      CompressedLazyOperandValueProfileHolder in the CodeBlock, using a key that contains
      the bytecode index and the operand. Because the value profiles are added at random
      times, they are not sorted; instead they are just stored in an arbitrarily-ordered
      SegmentedVector. Look-ups are made fast by "decompressing": the DFG::ByteCodeParser
      creates a LazyOperandValueProfileParser, which turns the
      CompressedLazyOperandValueProfileHolder's contents into a HashMap for the duration
      of DFG parsing.
              
      Previously, OSR exits had a pointer to the ValueProfile that had the specFailBucket
      into which values observed during OSR exit would be placed. Now it uses a lazy
      thunk for a ValueProfile. I call this the MethodOfGettingAValueProfile. It may
      either contain a ValueProfile inside it (which works for previous uses of OSR exit
      profiling) or it may just have knowledge of how to go about creating the
      LazyOperandValueProfile in the case that the OSR exit is actually taken. This
      ensures that we never have to create NumOperands*NumBytecodeIndices*NumCodeBlocks
      value profiling buckets unless we actually did OSR exit on every single operand,
      in every single instruction, in each code block (that's probably unlikely).
              
      This appears to be neutral on the major benchmarks, but is a double-digit speed-up
      on code deliberately written to have data flow that spans basic blocks and where
      the code exhibits post-optimization polymorphism in a local variable.
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::stronglyVisitStrongReferences):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      (JSC::CodeBlock::lazyOperandValueProfiles):
      * bytecode/LazyOperandValueProfile.cpp: Added.
      (JSC):
      (JSC::CompressedLazyOperandValueProfileHolder::CompressedLazyOperandValueProfileHolder):
      (JSC::CompressedLazyOperandValueProfileHolder::~CompressedLazyOperandValueProfileHolder):
      (JSC::CompressedLazyOperandValueProfileHolder::computeUpdatedPredictions):
      (JSC::CompressedLazyOperandValueProfileHolder::add):
      (JSC::LazyOperandValueProfileParser::LazyOperandValueProfileParser):
      (JSC::LazyOperandValueProfileParser::~LazyOperandValueProfileParser):
      (JSC::LazyOperandValueProfileParser::getIfPresent):
      (JSC::LazyOperandValueProfileParser::prediction):
      * bytecode/LazyOperandValueProfile.h: Added.
      (JSC):
      (LazyOperandValueProfileKey):
      (JSC::LazyOperandValueProfileKey::LazyOperandValueProfileKey):
      (JSC::LazyOperandValueProfileKey::operator!):
      (JSC::LazyOperandValueProfileKey::operator==):
      (JSC::LazyOperandValueProfileKey::hash):
      (JSC::LazyOperandValueProfileKey::bytecodeOffset):
      (JSC::LazyOperandValueProfileKey::operand):
      (JSC::LazyOperandValueProfileKey::isHashTableDeletedValue):
      (JSC::LazyOperandValueProfileKeyHash::hash):
      (JSC::LazyOperandValueProfileKeyHash::equal):
      (LazyOperandValueProfileKeyHash):
      (WTF):
      (JSC::LazyOperandValueProfile::LazyOperandValueProfile):
      (LazyOperandValueProfile):
      (JSC::LazyOperandValueProfile::key):
      (CompressedLazyOperandValueProfileHolder):
      (LazyOperandValueProfileParser):
      * bytecode/MethodOfGettingAValueProfile.cpp: Added.
      (JSC):
      (JSC::MethodOfGettingAValueProfile::fromLazyOperand):
      (JSC::MethodOfGettingAValueProfile::getSpecFailBucket):
      * bytecode/MethodOfGettingAValueProfile.h: Added.
      (JSC):
      (MethodOfGettingAValueProfile):
      (JSC::MethodOfGettingAValueProfile::MethodOfGettingAValueProfile):
      (JSC::MethodOfGettingAValueProfile::operator!):
      * bytecode/ValueProfile.cpp: Removed.
      * bytecode/ValueProfile.h:
      (JSC):
      (ValueProfileBase):
      (JSC::ValueProfileBase::ValueProfileBase):
      (JSC::ValueProfileBase::dump):
      (JSC::ValueProfileBase::computeUpdatedPrediction):
      (JSC::MinimalValueProfile::MinimalValueProfile):
      (ValueProfileWithLogNumberOfBuckets):
      (JSC::ValueProfileWithLogNumberOfBuckets::ValueProfileWithLogNumberOfBuckets):
      (JSC::ValueProfile::ValueProfile):
      (JSC::getValueProfileBytecodeOffset):
      (JSC::getRareCaseProfileBytecodeOffset):
      * dfg/DFGByteCodeParser.cpp:
      (ByteCodeParser):
      (JSC::DFG::ByteCodeParser::injectLazyOperandPrediction):
      (JSC::DFG::ByteCodeParser::getLocal):
      (JSC::DFG::ByteCodeParser::getArgument):
      (InlineStackEntry):
      (JSC::DFG::ByteCodeParser::fixVariableAccessPredictions):
      (DFG):
      (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
      (JSC::DFG::ByteCodeParser::parse):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::valueProfileFor):
      (JSC::DFG::Graph::methodOfGettingAValueProfileFor):
      (Graph):
      * dfg/DFGNode.h:
      (Node):
      * dfg/DFGOSRExit.cpp:
      (JSC::DFG::OSRExit::OSRExit):
      * dfg/DFGOSRExit.h:
      (OSRExit):
      * dfg/DFGOSRExitCompiler32_64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * dfg/DFGOSRExitCompiler64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * dfg/DFGPhase.cpp:
      (JSC::DFG::Phase::beginPhase):
      (JSC::DFG::Phase::endPhase):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::checkArgumentTypes):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::speculationCheck):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::nonUnifiedPrediction):
      (VariableAccessData):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@108677 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      31659dee
  24. 04 Jan, 2012 1 commit
    • fpizlo@apple.com's avatar
      DFG: The assertion that a double-voted variable cannot become double-unvoted is wrong · e793f71d
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=75516
      <rdar://problem/10640266>
      
      Source/JavaScriptCore: 
      
      Reviewed by Gavin Barraclough.
              
      Removed the offending assertion, since it was wrong.  Also hardened the code to make
      this case less likely by first having the propagator fixpoint converge, and then doing
      double voting combined with a second fixpoint.  This is neutral on benchmarks and
      fixes the assertion in a fairly low-risk way (i.e. we won't vote a variable double
      until we've converged to the conclusion that it really is double).
      
      * dfg/DFGPropagator.cpp:
      (JSC::DFG::Propagator::propagatePredictions):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::tallyVotesForShouldUseDoubleFormat):
      
      LayoutTests: 
      
      Reviewed by Andy Estes.
              
      Created a fuzzer that produces sufficiently awkward data flow that includes variables
      that become either double, or integer, or mix of double and integer only after multiple
      iterations of a fixpoint. This crashes the compiler prior to this patch, but works with
      this patch.
      
      * fast/js/dfg-double-vote-fuzz-expected.txt: Added.
      * fast/js/dfg-double-vote-fuzz.html: Added.
      * fast/js/script-tests/dfg-double-vote-fuzz.js: Added.
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@104016 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      e793f71d
  25. 15 Dec, 2011 1 commit
    • commit-queue@webkit.org's avatar
      Rename JSC::Heuristics to JSC::Options · a2e15981
      commit-queue@webkit.org authored
      https://bugs.webkit.org/show_bug.cgi?id=72889
      
      Patch by Andy Wingo <wingo@igalia.com> on 2011-12-15
      Reviewed by Filip Pizlo.
      
      * runtime/Options.cpp: Renamed from Source/JavaScriptCore/runtime/Heuristics.cpp.
      * runtime/Options.h: Renamed from Source/JavaScriptCore/runtime/Heuristics.h.
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::shouldOptimizeNow):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::likelyToTakeSlowCase):
      (JSC::CodeBlock::couldTakeSlowCase):
      (JSC::CodeBlock::likelyToTakeSpecialFastCase):
      (JSC::CodeBlock::likelyToTakeDeepestSlowCase):
      (JSC::CodeBlock::likelyToTakeAnySlowCase):
      (JSC::CodeBlock::reoptimizationRetryCounter):
      (JSC::CodeBlock::countReoptimization):
      (JSC::CodeBlock::counterValueForOptimizeAfterWarmUp):
      (JSC::CodeBlock::counterValueForOptimizeAfterLongWarmUp):
      (JSC::CodeBlock::optimizeNextInvocation):
      (JSC::CodeBlock::dontOptimizeAnytimeSoon):
      (JSC::CodeBlock::optimizeSoon):
      (JSC::CodeBlock::largeFailCountThreshold):
      (JSC::CodeBlock::largeFailCountThresholdForLoop):
      (JSC::CodeBlock::shouldReoptimizeNow):
      (JSC::CodeBlock::shouldReoptimizeFromLoopNow):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::handleInlining):
      * dfg/DFGCapabilities.h:
      (JSC::DFG::mightCompileEval):
      (JSC::DFG::mightCompileProgram):
      (JSC::DFG::mightCompileFunctionForCall):
      (JSC::DFG::mightCompileFunctionForConstruct):
      (JSC::DFG::mightInlineFunctionForCall):
      (JSC::DFG::mightInlineFunctionForConstruct):
      * dfg/DFGOSRExit.cpp:
      (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow):
      * dfg/DFGOSRExitCompiler32_64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * dfg/DFGOSRExitCompiler64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):
      * heap/MarkStack.cpp:
      (JSC::MarkStackSegmentAllocator::allocate):
      (JSC::MarkStackSegmentAllocator::shrinkReserve):
      (JSC::MarkStackArray::MarkStackArray):
      (JSC::MarkStackArray::donateSomeCellsTo):
      (JSC::MarkStackArray::stealSomeCellsFrom):
      (JSC::MarkStackThreadSharedData::MarkStackThreadSharedData):
      (JSC::SlotVisitor::donateSlow):
      (JSC::SlotVisitor::drain):
      (JSC::SlotVisitor::drainFromShared):
      * heap/MarkStack.h:
      (JSC::MarkStack::mergeOpaqueRootsIfProfitable):
      (JSC::MarkStack::addOpaqueRoot):
      (JSC::MarkStackArray::canDonateSomeCells):
      * heap/SlotVisitor.h:
      (JSC::SlotVisitor::donate):
      * jit/JIT.cpp:
      (JSC::JIT::emitOptimizationCheck):
      * runtime/InitializeThreading.cpp:
      (JSC::initializeThreadingOnce): Adapt callers and build systems.
      
      * testRegExp.cpp:
      (CommandLine::CommandLine):
      * jsc.cpp:
      (CommandLine::CommandLine):
      Rename from Options, to avoid name conflict.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@102917 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      a2e15981
  26. 14 Dec, 2011 1 commit
    • fpizlo@apple.com's avatar
      DFG should infer when local variables are doubles · 10f22fc0
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=74480
      
      Reviewed by Oliver Hunt.
              
      Introduced the notion that a local variable (though not an argument, yet!) can
      be stored as a double, and will be guaranteed to always contain a double. This
      requires more magic in the OSR (conversion in both entry and exit). The inference
      is quite unorthodox: all uses of a variable vote on whether they think it should
      be a double or a JSValue, based on how they use it. If they use it in an integer
      or boxed value context, they vote JSValue. If they use it in a double context,
      they vote double. This voting is interleaved in the propagator's fixpoint, so
      that variables voted double then have a double prediction propagated from them.
      This interleaving is needed because a variable that actually always contains an
      integer that always gets used in arithmetic that involves doubles may end up
      being voted double, which then means that all uses of the variable will see a
      double rather than an integer.
              
      This is worth 18% to SunSpider/3d-cube, 7% to Kraken/audio-beat-detection, 7%
      to Kraken/audio-fft, 6% to Kraken/imaging-darkroom, 20% to
      Kraken/imaging-gaussian-blur, and just over 1% to Kraken/json-parse-financial.
      It results in a 1% speed-up on SunSpider and a 4% speed-up in Kraken.  Similar
      results on JSVALUE32_64, though with a bigger win on Kraken (5%) and no overall
      win on SunSpider.
      
      * bytecode/ValueRecovery.h:
      (JSC::ValueRecovery::alreadyInRegisterFileAsUnboxedDouble):
      (JSC::ValueRecovery::dump):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::execute):
      * dfg/DFGAssemblyHelpers.h:
      (JSC::DFG::AssemblyHelpers::boxDouble):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::JITCompiler::noticeOSREntry):
      * dfg/DFGOSREntry.cpp:
      (JSC::DFG::prepareOSREntry):
      * dfg/DFGOSREntry.h:
      * dfg/DFGOSRExitCompiler64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * dfg/DFGPropagator.cpp:
      (JSC::DFG::Propagator::vote):
      (JSC::DFG::Propagator::doRoundOfDoubleVoting):
      (JSC::DFG::Propagator::propagatePredictions):
      (JSC::DFG::Propagator::fixupNode):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::ValueSource::dump):
      (JSC::DFG::SpeculativeJIT::compile):
      (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor):
      * dfg/DFGSpeculativeJIT.h:
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::VariableAccessData):
      (JSC::DFG::VariableAccessData::clearVotes):
      (JSC::DFG::VariableAccessData::vote):
      (JSC::DFG::VariableAccessData::doubleVoteRatio):
      (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):
      (JSC::DFG::VariableAccessData::shouldUseDoubleFormat):
      (JSC::DFG::VariableAccessData::tallyVotesForShouldUseDoubleFormat):
      * runtime/Arguments.cpp:
      (JSC::Arguments::tearOff):
      * runtime/Heuristics.cpp:
      (JSC::Heuristics::initializeHeuristics):
      * runtime/Heuristics.h:
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@102743 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      10f22fc0
  27. 06 Nov, 2011 1 commit
  28. 03 Nov, 2011 1 commit
    • fpizlo@apple.com's avatar
      ValueRecovery should be moved out of the DFG JIT · 96106050
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=71439
      
      Reviewed by Oliver Hunt.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/DataFormat.h: Added.
      (JSC::dataFormatToString):
      (JSC::needDataFormatConversion):
      (JSC::isJSFormat):
      (JSC::isJSInteger):
      (JSC::isJSDouble):
      (JSC::isJSCell):
      (JSC::isJSBoolean):
      * bytecode/ValueRecovery.h: Added.
      (JSC::ValueRecovery::ValueRecovery):
      (JSC::ValueRecovery::alreadyInRegisterFile):
      (JSC::ValueRecovery::alreadyInRegisterFileAsUnboxedInt32):
      (JSC::ValueRecovery::alreadyInRegisterFileAsUnboxedCell):
      (JSC::ValueRecovery::alreadyInRegisterFileAsUnboxedBoolean):
      (JSC::ValueRecovery::inGPR):
      (JSC::ValueRecovery::inPair):
      (JSC::ValueRecovery::inFPR):
      (JSC::ValueRecovery::displacedInRegisterFile):
      (JSC::ValueRecovery::constant):
      (JSC::ValueRecovery::technique):
      (JSC::ValueRecovery::isInRegisters):
      (JSC::ValueRecovery::gpr):
      (JSC::ValueRecovery::tagGPR):
      (JSC::ValueRecovery::payloadGPR):
      (JSC::ValueRecovery::fpr):
      (JSC::ValueRecovery::virtualRegister):
      (JSC::ValueRecovery::dump):
      * bytecode/VirtualRegister.h: Added.
      * dfg/DFGGenerationInfo.h:
      (JSC::DFG::GenerationInfo::isJSFormat):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::ValueSource::dump):
      * dfg/DFGSpeculativeJIT.h:
      * dfg/DFGVariableAccessData.h:
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@99144 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      96106050
  29. 12 Oct, 2011 1 commit
    • fpizlo@apple.com's avatar
      DFG does not have flow-sensitive intraprocedural control flow analysis · 4ffd3956
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=69690
      
      Reviewed by Gavin Barraclough.
      
      Implemented a control flow analysis (CFA). It currently propagates type
      proofs only. For example, if all predecessors to a basic block have
      checks that variable X is a JSFinalObject with structure 0xabcdef, then
      this basic block will now know this fact and will know that it does not
      have to emit either JSFinalObject checks or any structure checks since
      the structure is precisely known. The CFA takes heap side-effects into
      account (though somewhat conservatively), so that if the object pointed
      to by variable X could have possibly undergone a structure transition
      then this is reflected: the analysis may simply say that X's structure
      is unknown.
              
      This also propagates a wealth of other type information which is
      currently not being used. For example, we now know when a variable can
      only hold doubles. Even if a variable may hold other types at different
      points in its live range, we can still prove exactly when it will only
      be double.
              
      There's a bunch of stuff that the CFA could do that it still does not
      do, like precise handling of PutStructure (i.e. structure transitions),
      precise handling of CheckFunction and CheckMethod, etc. So this is
      very much intended to be a starting point rather than an end unto
      itself.
              
      This is a 1% win on V8 (mostly due to a 3% win on richards and deltablue)
      and a 1% win on Kraken (mostly due to a 6% win on imaging-desaturate).
      Neutral on SunSpider.
      
      * GNUmakefile.list.am:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/ActionablePrediction.h: Removed.
      * bytecode/PredictedType.cpp:
      (JSC::predictionToString):
      * bytecode/PredictedType.h:
      * dfg/DFGAbstractState.cpp: Added.
      (JSC::DFG::AbstractState::AbstractState):
      (JSC::DFG::AbstractState::~AbstractState):
      (JSC::DFG::AbstractState::beginBasicBlock):
      (JSC::DFG::AbstractState::initialize):
      (JSC::DFG::AbstractState::endBasicBlock):
      (JSC::DFG::AbstractState::reset):
      (JSC::DFG::AbstractState::execute):
      (JSC::DFG::AbstractState::clobberStructures):
      (JSC::DFG::AbstractState::mergeStateAtTail):
      (JSC::DFG::AbstractState::merge):
      (JSC::DFG::AbstractState::mergeToSuccessors):
      (JSC::DFG::AbstractState::mergeVariableBetweenBlocks):
      (JSC::DFG::AbstractState::dump):
      * dfg/DFGAbstractState.h: Added.
      (JSC::DFG::AbstractState::forNode):
      (JSC::DFG::AbstractState::isValid):
      * dfg/DFGAbstractValue.h: Added.
      (JSC::DFG::StructureAbstractValue::StructureAbstractValue):
      (JSC::DFG::StructureAbstractValue::clear):
      (JSC::DFG::StructureAbstractValue::makeTop):
      (JSC::DFG::StructureAbstractValue::top):
      (JSC::DFG::StructureAbstractValue::add):
      (JSC::DFG::StructureAbstractValue::addAll):
      (JSC::DFG::StructureAbstractValue::contains):
      (JSC::DFG::StructureAbstractValue::isSubsetOf):
      (JSC::DFG::StructureAbstractValue::doesNotContainAnyOtherThan):
      (JSC::DFG::StructureAbstractValue::isSupersetOf):
      (JSC::DFG::StructureAbstractValue::filter):
      (JSC::DFG::StructureAbstractValue::isClear):
      (JSC::DFG::StructureAbstractValue::isTop):
      (JSC::DFG::StructureAbstractValue::size):
      (JSC::DFG::StructureAbstractValue::at):
      (JSC::DFG::StructureAbstractValue::operator[]):
      (JSC::DFG::StructureAbstractValue::last):
      (JSC::DFG::StructureAbstractValue::predictionFromStructures):
      (JSC::DFG::StructureAbstractValue::operator==):
      (JSC::DFG::StructureAbstractValue::dump):
      (JSC::DFG::AbstractValue::AbstractValue):
      (JSC::DFG::AbstractValue::clear):
      (JSC::DFG::AbstractValue::isClear):
      (JSC::DFG::AbstractValue::makeTop):
      (JSC::DFG::AbstractValue::clobberStructures):
      (JSC::DFG::AbstractValue::isTop):
      (JSC::DFG::AbstractValue::top):
      (JSC::DFG::AbstractValue::set):
      (JSC::DFG::AbstractValue::operator==):
      (JSC::DFG::AbstractValue::merge):
      (JSC::DFG::AbstractValue::filter):
      (JSC::DFG::AbstractValue::validate):
      (JSC::DFG::AbstractValue::dump):
      * dfg/DFGBasicBlock.h: Added.
      (JSC::DFG::BasicBlock::BasicBlock):
      (JSC::DFG::BasicBlock::getBytecodeBegin):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::getLocal):
      (JSC::DFG::ByteCodeParser::setLocal):
      (JSC::DFG::ByteCodeParser::getArgument):
      (JSC::DFG::ByteCodeParser::setArgument):
      (JSC::DFG::ByteCodeParser::parseBlock):
      (JSC::DFG::ByteCodeParser::processPhiStack):
      (JSC::DFG::ByteCodeParser::setupPredecessors):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      * dfg/DFGGraph.h:
      * dfg/DFGJITCodeGenerator.h:
      (JSC::DFG::block):
      * dfg/DFGJITCodeGenerator32_64.cpp:
      (JSC::DFG::JITCodeGenerator::nonSpeculativePeepholeBranchNull):
      (JSC::DFG::JITCodeGenerator::nonSpeculativePeepholeBranch):
      (JSC::DFG::JITCodeGenerator::nonSpeculativePeepholeStrictEq):
      * dfg/DFGJITCodeGenerator64.cpp:
      (JSC::DFG::JITCodeGenerator::nonSpeculativePeepholeBranchNull):
      (JSC::DFG::JITCodeGenerator::nonSpeculativePeepholeBranch):
      (JSC::DFG::JITCodeGenerator::nonSpeculativePeepholeStrictEq):
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::JITCompiler::noticeOSREntry):
      * dfg/DFGNode.h:
      (JSC::DFG::NodeIndexTraits::defaultValue):
      (JSC::DFG::Node::variableAccessData):
      (JSC::DFG::Node::takenBytecodeOffsetDuringParsing):
      (JSC::DFG::Node::notTakenBytecodeOffsetDuringParsing):
      (JSC::DFG::Node::setTakenBlockIndex):
      (JSC::DFG::Node::setNotTakenBlockIndex):
      (JSC::DFG::Node::takenBlockIndex):
      (JSC::DFG::Node::notTakenBlockIndex):
      * dfg/DFGOSREntry.cpp:
      (JSC::DFG::prepareOSREntry):
      * dfg/DFGOSREntry.h:
      * dfg/DFGOperands.h: Added.
      (JSC::DFG::operandIsArgument):
      (JSC::DFG::OperandValueTraits::defaultValue):
      (JSC::DFG::Operands::Operands):
      (JSC::DFG::Operands::numberOfArguments):
      (JSC::DFG::Operands::numberOfLocals):
      (JSC::DFG::Operands::argument):
      (JSC::DFG::Operands::local):
      (JSC::DFG::Operands::setLocal):
      (JSC::DFG::Operands::setArgumentFirstTime):
      (JSC::DFG::Operands::setLocalFirstTime):
      (JSC::DFG::Operands::operand):
      (JSC::DFG::Operands::setOperand):
      (JSC::DFG::Operands::clear):
      (JSC::DFG::dumpOperands):
      * dfg/DFGPropagator.cpp:
      (JSC::DFG::Propagator::fixpoint):
      (JSC::DFG::Propagator::propagateArithNodeFlags):
      (JSC::DFG::Propagator::propagateNodePredictions):
      (JSC::DFG::Propagator::propagatePredictions):
      (JSC::DFG::Propagator::performBlockCFA):
      (JSC::DFG::Propagator::performForwardCFA):
      (JSC::DFG::Propagator::globalCFA):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compilePeepHoleDoubleBranch):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleIntegerBranch):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
      (JSC::DFG::SpeculativeJIT::compile):
      (JSC::DFG::SpeculativeJIT::compileGetCharCodeAt):
      (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::SpeculativeJIT):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compileObjectEquality):
      (JSC::DFG::SpeculativeJIT::compare):
      (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
      (JSC::DFG::SpeculativeJIT::compileLogicalNot):
      (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
      (JSC::DFG::SpeculativeJIT::emitBranch):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compileObjectEquality):
      (JSC::DFG::SpeculativeJIT::compare):
      (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
      (JSC::DFG::SpeculativeJIT::compileLogicalNot):
      (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
      (JSC::DFG::SpeculativeJIT::emitBranch):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGStructureSet.h:
      (JSC::DFG::StructureSet::clear):
      (JSC::DFG::StructureSet::predictionFromStructures):
      (JSC::DFG::StructureSet::operator==):
      (JSC::DFG::StructureSet::dump):
      * dfg/DFGVariableAccessData.h: Added.
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@97218 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      4ffd3956