1. 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
  2. 10 Dec, 2013 1 commit
    • fpizlo@apple.com's avatar
      Reveal array bounds checks in DFG IR · 8624c4b8
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=125253
      
      Reviewed by Oliver Hunt and Mark Hahnenberg.
              
      In SSA mode, this reveals array bounds checks and the load of array length in DFG IR,
      making this a candidate for LICM.
      
      This also fixes a long-standing performance bug where the JSObject slow paths would
      always create contiguous storage, rather than type-specialized storage, when doing a
      "storage creating" storage, like:
              
          var o = {};
          o[0] = 42;
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/ExitKind.cpp:
      (JSC::exitKindToString):
      (JSC::exitKindIsCountable):
      * bytecode/ExitKind.h:
      * dfg/DFGAbstractInterpreterInlines.h:
      (JSC::DFG::::executeEffects):
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::permitsBoundsCheckLowering):
      (JSC::DFG::ArrayMode::permitsBoundsCheckLowering):
      * dfg/DFGArrayMode.h:
      (JSC::DFG::ArrayMode::lengthNeedsStorage):
      * dfg/DFGClobberize.h:
      (JSC::DFG::clobberize):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGNodeType.h:
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGSSALoweringPhase.cpp: Added.
      (JSC::DFG::SSALoweringPhase::SSALoweringPhase):
      (JSC::DFG::SSALoweringPhase::run):
      (JSC::DFG::SSALoweringPhase::handleNode):
      (JSC::DFG::SSALoweringPhase::lowerBoundsCheck):
      (JSC::DFG::performSSALowering):
      * dfg/DFGSSALoweringPhase.h: Added.
      * dfg/DFGSafeToExecute.h:
      (JSC::DFG::safeToExecute):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compileContiguousPutByVal):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileCheckInBounds):
      (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
      (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
      (JSC::FTL::LowerDFGToLLVM::contiguousPutByValOutOfBounds):
      * runtime/JSObject.cpp:
      (JSC::JSObject::convertUndecidedForValue):
      (JSC::JSObject::createInitialForValueAndSet):
      (JSC::JSObject::putByIndexBeyondVectorLength):
      (JSC::JSObject::putDirectIndexBeyondVectorLength):
      * runtime/JSObject.h:
      * tests/stress/float32array-out-of-bounds.js: Added.
      (make):
      (foo):
      (test):
      * tests/stress/int32-object-out-of-bounds.js: Added.
      (make):
      (foo):
      (test):
      * tests/stress/int32-out-of-bounds.js: Added.
      (foo):
      (test):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@160347 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      8624c4b8
  3. 09 Dec, 2013 1 commit
  4. 08 Dec, 2013 1 commit
    • fpizlo@apple.com's avatar
      Fold typedArray.length if typedArray is constant · ce995b22
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=125252
      
      Source/JavaScriptCore: 
      
      Reviewed by Sam Weinig.
              
      This was meant to be easy. The problem is that there was no good place for putting
      the folding of typedArray.length to a constant. You can't quite do it in the
      bytecode parser because at that point you don't yet know if typedArray is really
      a typed array. You can't do it as part of constant folding because the folder
      assumes that it can opportunistically forward-flow a constant value without changing
      the IR; this doesn't work since we need to first change the IR to register a
      desired watchpoint and only after that can we introduce that constant. We could have
      done it in Fixup but that would have been awkward since Fixup's code for turning a
      GetById of "length" into GetArrayLength is already somewhat complex. We could have
      done it in CSE but CSE is already fairly gnarly and will probably get rewritten.
              
      So I introduced a new phase, called StrengthReduction. This phase should have any
      transformations that don't requite CFA or CSE and that it would be weird to put into
      those other phases.
              
      I also took the opportunity to refactor some of the other folding code.
              
      This also adds a test, but the test couldn't quite be a LayoutTests/js/regress so I
      introduced the notion of JavaScriptCore/tests/stress.
              
      The goal of this patch isn't really to improve performance or anything like that.
      It adds an optimization for completeness, and in doing so it unlocks a bunch of new
      possibilities. The one that I'm most excited about is revealing array length checks
      in DFG IR, which will allow for array bounds check hoisting and elimination.
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * dfg/DFGAbstractInterpreterInlines.h:
      (JSC::DFG::::executeEffects):
      * dfg/DFGClobberize.h:
      (JSC::DFG::clobberize):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::tryGetFoldableView):
      (JSC::DFG::Graph::tryGetFoldableViewForChild1):
      * dfg/DFGGraph.h:
      * dfg/DFGNode.h:
      (JSC::DFG::Node::hasTypedArray):
      (JSC::DFG::Node::typedArray):
      * dfg/DFGNodeType.h:
      * 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::jumpForTypedArrayOutOfBounds):
      (JSC::DFG::SpeculativeJIT::compileConstantIndexedPropertyStorage):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGStrengthReductionPhase.cpp: Added.
      (JSC::DFG::StrengthReductionPhase::StrengthReductionPhase):
      (JSC::DFG::StrengthReductionPhase::run):
      (JSC::DFG::StrengthReductionPhase::handleNode):
      (JSC::DFG::StrengthReductionPhase::foldTypedArrayPropertyToConstant):
      (JSC::DFG::performStrengthReduction):
      * dfg/DFGStrengthReductionPhase.h: Added.
      * dfg/DFGWatchpointCollectionPhase.cpp:
      (JSC::DFG::WatchpointCollectionPhase::handle):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileGetIndexedPropertyStorage):
      (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
      (JSC::FTL::LowerDFGToLLVM::typedArrayLength):
      * jsc.cpp:
      (GlobalObject::finishCreation):
      (functionTransferArrayBuffer):
      * runtime/ArrayBufferView.h:
      * tests/stress: Added.
      * tests/stress/fold-typed-array-properties.js: Added.
      (foo):
      
      Tools: 
      
      Reviewed by Sam Weinig.
              
      Add Source/JavaScriptCore/tests/stress to the set of JS tests. This is where you
      should put tests that run just like JSRegress but don't run as part of LayoutTests.
      Currently I'm using it for tests that require some surgical support from jsc.cpp.
      
      * Scripts/run-javascriptcore-tests:
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@160292 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      ce995b22
  5. 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
  6. 30 Oct, 2013 1 commit
    • fpizlo@apple.com's avatar
      Add InvalidationPoints to the DFG and use them for all watchpoints · d84425d1
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=123472
      
      Reviewed by Mark Hahnenberg.
              
      This makes a fundamental change to how watchpoints work in the DFG.
              
      Previously, a watchpoint was an instruction whose execution semantics were something
      like:
              
          if (watchpoint->invalidated)
              exit
              
      We would implement this without any branch by using jump replacement.
              
      This is a very good optimization. But it's a bit awkward once you get a lot of
      watchpoints: semantically we will have lots of these branches in the code, which the
      compiler needs to reason about even though they don't actually result in any emitted
      code.
              
      Separately, we also had a mechanism for jettisoning a CodeBlock. This mechanism would
      be invoked if a CodeBlock exited a lot. It would ensure that a CodeBlock wouldn't be
      called into again, but it would do nothing for CodeBlocks that were already on the
      stack.
              
      This change flips jettisoning and watchpoint invalidation on their heads. Now, the jump
      replacement has nothing to do with watchpoints; instead it's something that happens if
      you ever jettison a CodeBlock. Jump replacement is now an all-or-nothing operation over
      all of the potential call-return safe-exit-points in a CodeBlock. We call these
      "InvalidationPoint"s. A watchpoint instruction is now "lowered" by having the DFG
      collect all of the watchpoint sets that the CodeBlock cares about, and then registering
      a CodeBlockJettisoningWatchpoint with all of them. That is, if the watchpoint fires, it
      jettisons the CodeBlock, which in turn ensures that the CodeBlock can't be called into
      (because the entrypoint now points to baseline code) and can't be returned into
      (because returning exits to baseline before the next bytecode instruction).
              
      This will allow for a sensible lowering of watchpoints to LLVM IR. It will also allow
      for jettison() to be used effectively for things like breakpointing and single-stepping
      in the debugger.
              
      Well, basically, this mechanism just takes us into the HotSpot-style world where anyone
      can, at any time and for any reason, request that an optimized CodeBlock is rendered
      immediately invalid. You can use this for many cool things, I'm sure.
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * assembler/AbstractMacroAssembler.h:
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::jettison):
      * bytecode/CodeBlock.h:
      * bytecode/CodeBlockJettisoningWatchpoint.cpp: Added.
      (JSC::CodeBlockJettisoningWatchpoint::fireInternal):
      * bytecode/CodeBlockJettisoningWatchpoint.h: Added.
      (JSC::CodeBlockJettisoningWatchpoint::CodeBlockJettisoningWatchpoint):
      * bytecode/ExitKind.cpp:
      (JSC::exitKindToString):
      * bytecode/ExitKind.h:
      * bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp: Added.
      (JSC::ProfiledCodeBlockJettisoningWatchpoint::fireInternal):
      * bytecode/ProfiledCodeBlockJettisoningWatchpoint.h: Added.
      (JSC::ProfiledCodeBlockJettisoningWatchpoint::ProfiledCodeBlockJettisoningWatchpoint):
      * dfg/DFGAbstractHeap.h:
      * dfg/DFGAbstractInterpreterInlines.h:
      (JSC::DFG::::executeEffects):
      * dfg/DFGClobberize.cpp:
      (JSC::DFG::writesOverlap):
      * dfg/DFGClobberize.h:
      (JSC::DFG::clobberize):
      (JSC::DFG::AbstractHeapOverlaps::AbstractHeapOverlaps):
      (JSC::DFG::AbstractHeapOverlaps::operator()):
      (JSC::DFG::AbstractHeapOverlaps::result):
      * dfg/DFGCommonData.cpp:
      (JSC::DFG::CommonData::invalidate):
      * dfg/DFGCommonData.h:
      (JSC::DFG::CommonData::CommonData):
      * dfg/DFGDesiredWatchpoints.cpp:
      (JSC::DFG::DesiredWatchpoints::addLazily):
      (JSC::DFG::DesiredWatchpoints::reallyAdd):
      * dfg/DFGDesiredWatchpoints.h:
      (JSC::DFG::WatchpointForGenericWatchpointSet::WatchpointForGenericWatchpointSet):
      (JSC::DFG::GenericDesiredWatchpoints::addLazily):
      (JSC::DFG::GenericDesiredWatchpoints::reallyAdd):
      (JSC::DFG::GenericDesiredWatchpoints::areStillValid):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGInvalidationPointInjectionPhase.cpp: Added.
      (JSC::DFG::InvalidationPointInjectionPhase::InvalidationPointInjectionPhase):
      (JSC::DFG::InvalidationPointInjectionPhase::run):
      (JSC::DFG::InvalidationPointInjectionPhase::handle):
      (JSC::DFG::InvalidationPointInjectionPhase::insertInvalidationCheck):
      (JSC::DFG::performInvalidationPointInjection):
      * dfg/DFGInvalidationPointInjectionPhase.h: Added.
      * dfg/DFGJITCode.h:
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::linkOSRExits):
      (JSC::DFG::JITCompiler::link):
      * dfg/DFGJITCompiler.h:
      * dfg/DFGJumpReplacement.cpp: Added.
      (JSC::DFG::JumpReplacement::fire):
      * dfg/DFGJumpReplacement.h: Added.
      (JSC::DFG::JumpReplacement::JumpReplacement):
      * dfg/DFGNodeType.h:
      * dfg/DFGOSRExitCompilationInfo.h:
      * dfg/DFGOperations.cpp:
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      (JSC::DFG::Plan::reallyAdd):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGSafeToExecute.h:
      (JSC::DFG::safeToExecute):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::emitInvalidationPoint):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
      (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::masqueradesAsUndefinedWatchpointIsStillValid):
      (JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
      (JSC::DFG::SpeculativeJIT::compileObjectEquality):
      (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
      (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
      (JSC::DFG::SpeculativeJIT::compileObjectEquality):
      (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
      (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGWatchpointCollectionPhase.cpp: Added.
      (JSC::DFG::WatchpointCollectionPhase::WatchpointCollectionPhase):
      (JSC::DFG::WatchpointCollectionPhase::run):
      (JSC::DFG::WatchpointCollectionPhase::handle):
      (JSC::DFG::WatchpointCollectionPhase::handleEdge):
      (JSC::DFG::WatchpointCollectionPhase::handleMasqueradesAsUndefined):
      (JSC::DFG::WatchpointCollectionPhase::handleStringGetByVal):
      (JSC::DFG::WatchpointCollectionPhase::addLazily):
      (JSC::DFG::WatchpointCollectionPhase::globalObject):
      (JSC::DFG::performWatchpointCollection):
      * dfg/DFGWatchpointCollectionPhase.h: Added.
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileStructureTransitionWatchpoint):
      (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
      (JSC::FTL::LowerDFGToLLVM::compileGlobalVarWatchpoint):
      (JSC::FTL::LowerDFGToLLVM::compileCompareEqConstant):
      (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEqConstant):
      (JSC::FTL::LowerDFGToLLVM::compileInvalidationPoint):
      (JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
      (JSC::FTL::LowerDFGToLLVM::speculateNonNullObject):
      * jit/JITOperations.cpp:
      * jit/JumpReplacementWatchpoint.cpp: Removed.
      * jit/JumpReplacementWatchpoint.h: Removed.
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@158304 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      d84425d1
  7. 10 Oct, 2013 2 commits
    • fpizlo@apple.com's avatar
      FTL: Soft-link LLVM as a workaround for LLVM's static initializers and exit-time destructors · ef8dbf84
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=122566
      
      Source/JavaScriptCore: 
      
      Reviewed by Mark Rowe.
              
      The JSC project now builds a libllvmForJSC.dylib. If FTL is enabled, this
      gets copied into JavaScriptCore.framework/Versions/A/Libraries. JSC will
      load the dylib by finding it using NSBundle APIs and then doing dlopen().
      That will only happen lazily, when something happens that requires LLVM.
              
      This mostly takes care of LLVM static initialization overhead by deferring
      it until it's really needed.
              
      This takes care of LLVM's exit-time destructors because inside
      libllvmForJSC.dylib, we override __cxa_atexit.
              
      * Configurations/JavaScriptCore.xcconfig:
      * Configurations/LLVMForJSC.xcconfig: Added.
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      * disassembler/LLVMDisassembler.cpp:
      (JSC::tryToDisassembleWithLLVM):
      * ftl/FTLAbbreviatedTypes.h:
      * ftl/FTLAbbreviations.h:
      (JSC::FTL::voidType):
      (JSC::FTL::int1Type):
      (JSC::FTL::int8Type):
      (JSC::FTL::int16Type):
      (JSC::FTL::int32Type):
      (JSC::FTL::int64Type):
      (JSC::FTL::intPtrType):
      (JSC::FTL::floatType):
      (JSC::FTL::doubleType):
      (JSC::FTL::pointerType):
      (JSC::FTL::structType):
      (JSC::FTL::functionType):
      (JSC::FTL::typeOf):
      (JSC::FTL::mdKindID):
      (JSC::FTL::mdString):
      (JSC::FTL::mdNode):
      (JSC::FTL::setMetadata):
      (JSC::FTL::addFunction):
      (JSC::FTL::setLinkage):
      (JSC::FTL::setFunctionCallingConv):
      (JSC::FTL::getParam):
      (JSC::FTL::constInt):
      (JSC::FTL::constReal):
      (JSC::FTL::constIntToPtr):
      (JSC::FTL::constBitCast):
      (JSC::FTL::appendBasicBlock):
      (JSC::FTL::insertBasicBlock):
      (JSC::FTL::buildPhi):
      (JSC::FTL::addIncoming):
      (JSC::FTL::buildAlloca):
      (JSC::FTL::buildAdd):
      (JSC::FTL::buildSub):
      (JSC::FTL::buildMul):
      (JSC::FTL::buildDiv):
      (JSC::FTL::buildRem):
      (JSC::FTL::buildNeg):
      (JSC::FTL::buildFAdd):
      (JSC::FTL::buildFSub):
      (JSC::FTL::buildFMul):
      (JSC::FTL::buildFDiv):
      (JSC::FTL::buildFRem):
      (JSC::FTL::buildFNeg):
      (JSC::FTL::buildAnd):
      (JSC::FTL::buildOr):
      (JSC::FTL::buildXor):
      (JSC::FTL::buildShl):
      (JSC::FTL::buildAShr):
      (JSC::FTL::buildLShr):
      (JSC::FTL::buildNot):
      (JSC::FTL::buildLoad):
      (JSC::FTL::buildStore):
      (JSC::FTL::buildSExt):
      (JSC::FTL::buildZExt):
      (JSC::FTL::buildFPToSI):
      (JSC::FTL::buildFPToUI):
      (JSC::FTL::buildSIToFP):
      (JSC::FTL::buildUIToFP):
      (JSC::FTL::buildIntCast):
      (JSC::FTL::buildFPCast):
      (JSC::FTL::buildIntToPtr):
      (JSC::FTL::buildPtrToInt):
      (JSC::FTL::buildBitCast):
      (JSC::FTL::buildICmp):
      (JSC::FTL::buildFCmp):
      (JSC::FTL::buildCall):
      (JSC::FTL::setTailCall):
      (JSC::FTL::buildExtractValue):
      (JSC::FTL::buildSelect):
      (JSC::FTL::buildBr):
      (JSC::FTL::buildCondBr):
      (JSC::FTL::buildSwitch):
      (JSC::FTL::addCase):
      (JSC::FTL::buildRet):
      (JSC::FTL::buildUnreachable):
      (JSC::FTL::dumpModule):
      (JSC::FTL::verifyModule):
      * ftl/FTLCompile.cpp:
      (JSC::FTL::compile):
      * ftl/FTLFail.cpp:
      (JSC::FTL::fail):
      * ftl/FTLJITCode.h:
      * ftl/FTLJITFinalizer.h:
      * ftl/FTLLink.cpp:
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::lower):
      * ftl/FTLOutput.cpp:
      (JSC::FTL::Output::Output):
      (JSC::FTL::Output::~Output):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::appendTo):
      * ftl/FTLState.cpp:
      (JSC::FTL::State::State):
      (JSC::FTL::State::~State):
      * ftl/WebKitLLVMLibraryAnchor.cpp: Removed.
      * jsc.cpp:
      (jscmain):
      * llvm: Added.
      * llvm/InitializeLLVM.cpp: Added.
      (JSC::initializeLLVM):
      * llvm/InitializeLLVM.h: Added.
      * llvm/InitializeLLVMMac.mm: Added.
      (JSC::initializeLLVMImpl):
      * llvm/InitializeLLVMPOSIX.cpp: Added.
      (JSC::initializeLLVMPOSIX):
      * llvm/InitializeLLVMPOSIX.h: Added.
      * llvm/LLVMAPI.cpp: Added.
      * llvm/LLVMAPI.h: Added.
      * llvm/LLVMAPIFunctions.h: Added.
      * llvm/LLVMHeaders.h: Added.
      * llvm/library: Added.
      * llvm/library/LLVMAnchor.cpp: Added.
      * llvm/library/LLVMExports.cpp: Added.
      (initializeAndGetJSCLLVMAPI):
      * llvm/library/LLVMOverrides.cpp: Added.
      (__cxa_atexit):
      * llvm/library/config_llvm.h: Added.
      * runtime/InitializeThreading.cpp:
      (JSC::initializeThreadingOnce):
      * runtime/Options.h:
      
      Source/WTF: 
      
      Reviewed by Mark Rowe.
              
      Remove all LLVM stuff from WTF since to get LLVM you need to soft-link and it's
      entirely the responsibility of JSC to do that.
              
      Also fixed an export goof that I found after fixing the weak thingy script in JSC.
      
      * WTF.xcodeproj/project.pbxproj:
      * wtf/LLVMHeaders.h: Removed.
      * wtf/text/CString.h:
      (WTF::CStringHash::hash):
      
      Tools: 
      
      Reviewed by Mark Rowe.
      
      * Scripts/configure-llvm:
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@157260 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      ef8dbf84
    • fpizlo@apple.com's avatar
      FTL should be able to do simple OSR exits using llvm.webkit.stackmap · ea92c209
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=122538
      
      Reviewed by Oliver Hunt.
              
      This gives the FTL the ability to OSR exit using the llvm.webkit.stackmap intrinsic.
              
      - The FTL compiles all OSR exit calls as calls to llvm.webkit.stackmap with a unique
        ID, passing a requested size that is big enough for own jump replacement.
              
      - After LLVM compilation, we parse the new LLVM stackmap section.
              
      - For all llvm.webkit.stackmaps that we used for OSR exits, we do a jumpReplacement,
        which targets exit thunks that we generate.
              
      - If an exit thunk fires, it causes JSC to compile an exit off-ramp that uses a
        combination of the JSC-internal OSR exit accounting (FTL::ExitValue and friends) and
        LLVM stackmap's accounting of where data actually ended up (register, indirect,
        constant) to reconstruct bytecode state.
              
      This still has shortcomings; for example it cannot handle XMM or YMM registers. Handling
      YMM registers will require adding some basic YMM support to our assemblers - really we
      just need the ability to move a YMM's value into a GPR.
              
      This patch preserves all of the old, intrinsic-less, FTL OSR exit support. Hence it
      manages to pass all existing FTL tests even despite its incompleteness. I think that's
      the right way to go since this is already a big patch, and anyway it would be great to
      keep the intrinsic-less FTL OSR exit support so long as the LLVM side of this hasn't
      landed.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * assembler/AbstractMacroAssembler.h:
      (JSC::AbstractMacroAssembler::firstRegister):
      (JSC::AbstractMacroAssembler::lastRegister):
      * assembler/MacroAssembler.h:
      (JSC::MacroAssembler::isStackRelated):
      (JSC::MacroAssembler::firstRealRegister):
      (JSC::MacroAssembler::nextRegister):
      (JSC::MacroAssembler::secondRealRegister):
      * assembler/MacroAssemblerX86Common.h:
      * assembler/X86Assembler.h:
      (JSC::X86Assembler::firstRegister):
      (JSC::X86Assembler::lastRegister):
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      * ftl/FTLCArgumentGetter.cpp:
      (JSC::FTL::CArgumentGetter::loadNextAndBox):
      * ftl/FTLCArgumentGetter.h:
      (JSC::FTL::CArgumentGetter::loadNextDoubleIntoGPR):
      * ftl/FTLCompile.cpp:
      (JSC::FTL::mmAllocateCodeSection):
      (JSC::FTL::mmAllocateDataSection):
      (JSC::FTL::dumpDataSection):
      (JSC::FTL::fixFunctionBasedOnStackMaps):
      (JSC::FTL::compile):
      * ftl/FTLExitThunkGenerator.cpp:
      (JSC::FTL::ExitThunkGenerator::emitThunk):
      (JSC::FTL::ExitThunkGenerator::emitThunks):
      * ftl/FTLExitThunkGenerator.h:
      * ftl/FTLExitValue.h:
      (JSC::FTL::ExitValue::isInJSStackSomehow):
      (JSC::FTL::ExitValue::valueFormat):
      * ftl/FTLFail.cpp:
      (JSC::FTL::fail):
      * ftl/FTLIntrinsicRepository.h:
      * ftl/FTLJITCode.h:
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::generateExitThunks):
      (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
      (JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
      (JSC::FTL::LowerDFGToLLVM::linkOSRExitsAndCompleteInitializationBlocks):
      * ftl/FTLOSRExit.h:
      * ftl/FTLOSRExitCompilationInfo.h:
      (JSC::FTL::OSRExitCompilationInfo::OSRExitCompilationInfo):
      * ftl/FTLOSRExitCompiler.cpp:
      (JSC::FTL::compileStubWithOSRExitStackmap):
      (JSC::FTL::compileStubWithoutOSRExitStackmap):
      (JSC::FTL::compileFTLOSRExit):
      * ftl/FTLSaveRestore.cpp: Added.
      (JSC::FTL::bytesForGPRs):
      (JSC::FTL::requiredScratchMemorySizeInBytes):
      (JSC::FTL::offsetOfGPR):
      (JSC::FTL::saveAllRegisters):
      (JSC::FTL::restoreAllRegisters):
      * ftl/FTLSaveRestore.h: Added.
      * ftl/FTLStackMaps.cpp: Added.
      (JSC::FTL::readObject):
      (JSC::FTL::StackMaps::Constant::parse):
      (JSC::FTL::StackMaps::Constant::dump):
      (JSC::FTL::StackMaps::Location::parse):
      (JSC::FTL::StackMaps::Location::dump):
      (JSC::FTL::StackMaps::Location::involvesGPR):
      (JSC::FTL::StackMaps::Location::isGPR):
      (JSC::FTL::StackMaps::Location::gpr):
      (JSC::FTL::StackMaps::Location::restoreInto):
      (JSC::FTL::StackMaps::Record::parse):
      (JSC::FTL::StackMaps::Record::dump):
      (JSC::FTL::StackMaps::parse):
      (JSC::FTL::StackMaps::dump):
      (JSC::FTL::StackMaps::dumpMultiline):
      (JSC::FTL::StackMaps::getRecordMap):
      (WTF::printInternal):
      * ftl/FTLStackMaps.h: Added.
      * ftl/FTLState.h:
      * ftl/FTLThunks.cpp:
      (JSC::FTL::osrExitGenerationThunkGenerator):
      * ftl/FTLValueFormat.cpp:
      (JSC::FTL::reboxAccordingToFormat):
      * ftl/FTLValueFormat.h:
      * runtime/DataView.cpp:
      (JSC::DataView::create):
      * runtime/DataView.h:
      (JSC::DataView::read):
      * runtime/Options.h:
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@157209 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      ea92c209
  8. 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
  9. 04 Sep, 2013 1 commit
    • fpizlo@apple.com's avatar
      The DFG should be able to tier-up and OSR enter into the FTL · 532f1e51
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=112838
      
      Source/JavaScriptCore: 
      
      Reviewed by Mark Hahnenberg.
              
      This adds the ability for the DFG to tier-up into the FTL. This works in both
      of the expected tier-up modes:
              
      Replacement: frequently called functions eventually have their entrypoint
      replaced with one that goes into FTL-compiled code. Note, this will be a
      slow-down for now since we don't yet have LLVM calling convention integration.
              
      OSR entry: code stuck in hot loops gets OSR'd into the FTL from the DFG.
              
      This means that if the DFG detects that a function is an FTL candidate, it
      inserts execution counting code similar to the kind that the baseline JIT
      would use. If you trip on a loop count in a loop header that is an OSR
      candidate (it's not an inlined loop), we do OSR; otherwise we do replacement.
      OSR almost always also implies future replacement.
              
      OSR entry into the FTL is really cool. It uses a specialized FTL compile of
      the code, where early in the DFG pipeline we replace the original root block
      with an OSR entrypoint block that jumps to the pre-header of the hot loop.
      The OSR entrypoint loads all live state at the loop pre-header using loads
      from a scratch buffer, which gets populated by the runtime's OSR entry
      preparation code (FTL::prepareOSREntry()). This approach appears to work well
      with all of our subsequent optimizations, including prediction propagation,
      CFA, and LICM. LLVM seems happy with it, too. Best of all, it works naturally
      with concurrent compilation: when we hit the tier-up trigger we spawn a
      compilation plan at the bytecode index from which we triggered; once the
      compilation finishes the next trigger will try to enter, at that bytecode
      index. If it can't - for example because the code has moved on to another
      loop - then we just try again. Loops that get hot enough for OSR entry (about
      25,000 iterations) will probably still be running when a concurrent compile
      finishes, so this doesn't appear to be a big problem.
              
      This immediately gives us a 70% speed-up on imaging-gaussian-blur. We could
      get a bigger speed-up by adding some more intelligence and tweaking LLVM to
      compile code faster. Those things will happen eventually but this is a good
      start. Probably this code will see more tuning as we get more coverage in the
      FTL JIT, but I'll worry about that in future patches.
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::CodeBlock):
      (JSC::CodeBlock::hasOptimizedReplacement):
      (JSC::CodeBlock::setOptimizationThresholdBasedOnCompilationResult):
      * bytecode/CodeBlock.h:
      * dfg/DFGAbstractInterpreterInlines.h:
      (JSC::DFG::::executeEffects):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::parseBlock):
      (JSC::DFG::ByteCodeParser::parse):
      * dfg/DFGCFGSimplificationPhase.cpp:
      (JSC::DFG::CFGSimplificationPhase::run):
      * dfg/DFGClobberize.h:
      (JSC::DFG::clobberize):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compileImpl):
      (JSC::DFG::compile):
      * dfg/DFGDriver.h:
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      (JSC::DFG::Graph::killBlockAndItsContents):
      (JSC::DFG::Graph::killUnreachableBlocks):
      * dfg/DFGGraph.h:
      * dfg/DFGInPlaceAbstractState.cpp:
      (JSC::DFG::InPlaceAbstractState::initialize):
      * dfg/DFGJITCode.cpp:
      (JSC::DFG::JITCode::reconstruct):
      (JSC::DFG::JITCode::checkIfOptimizationThresholdReached):
      (JSC::DFG::JITCode::optimizeNextInvocation):
      (JSC::DFG::JITCode::dontOptimizeAnytimeSoon):
      (JSC::DFG::JITCode::optimizeAfterWarmUp):
      (JSC::DFG::JITCode::optimizeSoon):
      (JSC::DFG::JITCode::forceOptimizationSlowPathConcurrently):
      (JSC::DFG::JITCode::setOptimizationThresholdBasedOnCompilationResult):
      * dfg/DFGJITCode.h:
      * dfg/DFGJITFinalizer.cpp:
      (JSC::DFG::JITFinalizer::finalize):
      (JSC::DFG::JITFinalizer::finalizeFunction):
      (JSC::DFG::JITFinalizer::finalizeCommon):
      * dfg/DFGLoopPreHeaderCreationPhase.cpp:
      (JSC::DFG::createPreHeader):
      (JSC::DFG::LoopPreHeaderCreationPhase::run):
      * dfg/DFGLoopPreHeaderCreationPhase.h:
      * dfg/DFGNode.h:
      (JSC::DFG::Node::hasUnlinkedLocal):
      (JSC::DFG::Node::unlinkedLocal):
      * dfg/DFGNodeType.h:
      * dfg/DFGOSREntry.cpp:
      (JSC::DFG::prepareOSREntry):
      * dfg/DFGOSREntrypointCreationPhase.cpp: Added.
      (JSC::DFG::OSREntrypointCreationPhase::OSREntrypointCreationPhase):
      (JSC::DFG::OSREntrypointCreationPhase::run):
      (JSC::DFG::performOSREntrypointCreation):
      * dfg/DFGOSREntrypointCreationPhase.h: Added.
      * dfg/DFGOperations.cpp:
      * dfg/DFGOperations.h:
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::Plan):
      (JSC::DFG::Plan::compileInThread):
      (JSC::DFG::Plan::compileInThreadImpl):
      * dfg/DFGPlan.h:
      * dfg/DFGPredictionInjectionPhase.cpp:
      (JSC::DFG::PredictionInjectionPhase::run):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGSafeToExecute.h:
      (JSC::DFG::safeToExecute):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGTierUpCheckInjectionPhase.cpp: Added.
      (JSC::DFG::TierUpCheckInjectionPhase::TierUpCheckInjectionPhase):
      (JSC::DFG::TierUpCheckInjectionPhase::run):
      (JSC::DFG::performTierUpCheckInjection):
      * dfg/DFGTierUpCheckInjectionPhase.h: Added.
      * dfg/DFGToFTLDeferredCompilationCallback.cpp: Added.
      (JSC::DFG::ToFTLDeferredCompilationCallback::ToFTLDeferredCompilationCallback):
      (JSC::DFG::ToFTLDeferredCompilationCallback::~ToFTLDeferredCompilationCallback):
      (JSC::DFG::ToFTLDeferredCompilationCallback::create):
      (JSC::DFG::ToFTLDeferredCompilationCallback::compilationDidBecomeReadyAsynchronously):
      (JSC::DFG::ToFTLDeferredCompilationCallback::compilationDidComplete):
      * dfg/DFGToFTLDeferredCompilationCallback.h: Added.
      * dfg/DFGToFTLForOSREntryDeferredCompilationCallback.cpp: Added.
      (JSC::DFG::ToFTLForOSREntryDeferredCompilationCallback::ToFTLForOSREntryDeferredCompilationCallback):
      (JSC::DFG::ToFTLForOSREntryDeferredCompilationCallback::~ToFTLForOSREntryDeferredCompilationCallback):
      (JSC::DFG::ToFTLForOSREntryDeferredCompilationCallback::create):
      (JSC::DFG::ToFTLForOSREntryDeferredCompilationCallback::compilationDidBecomeReadyAsynchronously):
      (JSC::DFG::ToFTLForOSREntryDeferredCompilationCallback::compilationDidComplete):
      * dfg/DFGToFTLForOSREntryDeferredCompilationCallback.h: Added.
      * dfg/DFGWorklist.cpp:
      (JSC::DFG::globalWorklist):
      * dfg/DFGWorklist.h:
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLCapabilities.h:
      * ftl/FTLForOSREntryJITCode.cpp: Added.
      (JSC::FTL::ForOSREntryJITCode::ForOSREntryJITCode):
      (JSC::FTL::ForOSREntryJITCode::~ForOSREntryJITCode):
      (JSC::FTL::ForOSREntryJITCode::ftlForOSREntry):
      (JSC::FTL::ForOSREntryJITCode::initializeEntryBuffer):
      * ftl/FTLForOSREntryJITCode.h: Added.
      (JSC::FTL::ForOSREntryJITCode::entryBuffer):
      (JSC::FTL::ForOSREntryJITCode::setBytecodeIndex):
      (JSC::FTL::ForOSREntryJITCode::bytecodeIndex):
      (JSC::FTL::ForOSREntryJITCode::countEntryFailure):
      (JSC::FTL::ForOSREntryJITCode::entryFailureCount):
      * ftl/FTLJITFinalizer.cpp:
      (JSC::FTL::JITFinalizer::finalizeFunction):
      * ftl/FTLLink.cpp:
      (JSC::FTL::link):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileBlock):
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileExtractOSREntryLocal):
      (JSC::FTL::LowerDFGToLLVM::compileGetLocal):
      (JSC::FTL::LowerDFGToLLVM::addWeakReference):
      * ftl/FTLOSREntry.cpp: Added.
      (JSC::FTL::prepareOSREntry):
      * ftl/FTLOSREntry.h: Added.
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::crashNonTerminal):
      (JSC::FTL::Output::crash):
      * ftl/FTLState.cpp:
      (JSC::FTL::State::State):
      * interpreter/Register.h:
      (JSC::Register::unboxedDouble):
      * jit/JIT.cpp:
      (JSC::JIT::emitEnterOptimizationCheck):
      * jit/JITCode.cpp:
      (JSC::JITCode::ftlForOSREntry):
      * jit/JITCode.h:
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * runtime/Executable.cpp:
      (JSC::ScriptExecutable::newReplacementCodeBlockFor):
      * runtime/Options.h:
      * runtime/VM.cpp:
      (JSC::VM::ensureWorklist):
      * runtime/VM.h:
      
      LayoutTests: 
      
      Reviewed by Mark Hahnenberg.
              
      Fix marsaglia to check the result instead of printing, and add a second
      version that relies on OSR entry.
      
      * fast/js/regress/marsaglia-osr-entry-expected.txt: Added.
      * fast/js/regress/marsaglia-osr-entry.html: Added.
      * fast/js/regress/script-tests/marsaglia-osr-entry.js: Added.
      (marsaglia):
      * fast/js/regress/script-tests/marsaglia.js:
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@155023 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      532f1e51
  10. 29 Aug, 2013 4 commits
    • fpizlo@apple.com's avatar
      Teach DFG::Worklist and its clients that it may be reused for different kinds of compilations · 6931c476
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=120489
      
      Reviewed by Geoffrey Garen.
              
      If the baseline JIT hits an OSR entry trigger into the DFG and we already have a
      DFG compilation but we've also started one or more FTL compilations, then we
      shouldn't get confused. Previously we would have gotten confused because we would
      see an in-process deferred compile (the FTL compile) and also an optimized
      replacement (the DFG code).
              
      If the baseline JIT hits an OSR entry trigger into the DFG and we previously
      did two things in this order: triggered a tier-up compilation from the DFG into
      the FTL, and then jettisoned the DFG code because it exited a bunch, then we
      shouldn't be confused by the presence of an in-process deferred compile (the FTL
      compile). Previously we would have waited for that compile to finish; but the more
      sensible thing to do is to let it complete and then invalidate it, while at the
      same time enqueueing a DFG compile to create a new, more valid, DFG code block.
              
      If the DFG JIT hits a loop OSR entry trigger (into the FTL) and it has already
      triggered an FTL compile for replacement, then it should fire off a second compile
      instead of thinking that it can wait for that one to finish. Or vice-versa. We
      need to allow for two FTL compiles to be enqueued at the same time (one for
      replacement and one for OSR entry in a loop).
              
      Then there's also the problem that DFG::compile() is almost certainly going to be
      the hook for triggering both DFG compiles and the two kinds of FTL compiles, but
      right now there is no way to tell it which one you want.
              
      This fixes these problems and removes a bunch of potential confusion by making the
      key for a compile in the DFG::Worklist be a CompilationMode (one of DFGMode,
      FTLMode, or FTLForOSREntryMode). That mode is also passed to DFG::compile().
              
      Awkwardly, this still leaves us in a no DFG->FTL tier-up situation - so
      DFG::compile() is always passed DFGMode and then it might do an FTL compile if
      possible. Fixing that is a bigger issue for a later changeset.
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::checkIfOptimizationThresholdReached):
      * dfg/DFGCompilationKey.cpp: Added.
      (JSC::DFG::CompilationKey::dump):
      * dfg/DFGCompilationKey.h: Added.
      (JSC::DFG::CompilationKey::CompilationKey):
      (JSC::DFG::CompilationKey::operator!):
      (JSC::DFG::CompilationKey::isHashTableDeletedValue):
      (JSC::DFG::CompilationKey::profiledBlock):
      (JSC::DFG::CompilationKey::mode):
      (JSC::DFG::CompilationKey::operator==):
      (JSC::DFG::CompilationKey::hash):
      (JSC::DFG::CompilationKeyHash::hash):
      (JSC::DFG::CompilationKeyHash::equal):
      * dfg/DFGCompilationMode.cpp: Added.
      (WTF::printInternal):
      * dfg/DFGCompilationMode.h: Added.
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compileImpl):
      (JSC::DFG::compile):
      * dfg/DFGDriver.h:
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::Plan):
      (JSC::DFG::Plan::key):
      * dfg/DFGPlan.h:
      * dfg/DFGWorklist.cpp:
      (JSC::DFG::Worklist::enqueue):
      (JSC::DFG::Worklist::compilationState):
      (JSC::DFG::Worklist::completeAllReadyPlansForVM):
      (JSC::DFG::Worklist::runThread):
      * dfg/DFGWorklist.h:
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@154854 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      6931c476
    • fpizlo@apple.com's avatar
      CodeBlock compilation and installation should be simplified and rationalized · 62b6af85
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=120326
      
      Reviewed by Oliver Hunt.
              
      Rolling r154804 back in after fixing no-LLInt build.
              
      Previously Executable owned the code for generating JIT code; you always had
      to go through Executable. But often you also had to go through CodeBlock,
      because ScriptExecutable couldn't have virtual methods, but CodeBlock could.
      So you'd ask CodeBlock to do something, which would dispatch through a
      virtual method that would select the appropriate Executable subtype's method.
      This all meant that the same code would often be duplicated, because most of
      the work needed to compile something was identical regardless of code type.
      But then we tried to fix this, by having templatized helpers in
      ExecutionHarness.h and JITDriver.h. The result was that if you wanted to find
      out what happened when you asked for something to be compiled, you'd go on a
      wild ride that started with CodeBlock, touched upon Executable, and then
      ricocheted into either ExecutionHarness or JITDriver (likely both).
              
      Another awkwardness was that for concurrent compiles, the DFG::Worklist had
      super-special inside knowledge of what JITStubs.cpp's cti_optimize would have
      done once the compilation finished.
              
      Also, most of the DFG JIT drivers assumed that they couldn't install the
      JITCode into the CodeBlock directly - instead they would return it via a
      reference, which happened to be a reference to the JITCode pointer in
      Executable. This was super weird.
              
      Finally, there was no notion of compiling code into a special CodeBlock that
      wasn't used for handling calls into an Executable. I'd like this for FTL OSR
      entry.
              
      This patch solves these problems by reducing all of that complexity into just
      three primitives:
              
      - Executable::newCodeBlock(). This gives you a new code block, either for call
        or for construct, and either to serve as the baseline code or the optimized
        code. The new code block is then owned by the caller; Executable doesn't
        register it anywhere. The new code block has no JITCode and isn't callable,
        but it has all of the bytecode.
              
      - CodeBlock::prepareForExecution(). This takes the CodeBlock's bytecode and
        produces a JITCode, and then installs the JITCode into the CodeBlock. This
        method takes a JITType, and always compiles with that JIT. If you ask for
        JITCode::InterpreterThunk then you'll get JITCode that just points to the
        LLInt entrypoints. Once this returns, it is possible to call into the
        CodeBlock if you do so manually - but the Executable still won't know about
        it so JS calls to that Executable will still be routed to whatever CodeBlock
        is associated with the Executable.
              
      - Executable::installCode(). This takes a CodeBlock and makes it the code-for-
        entry for that Executable. This involves unlinking the Executable's last
        CodeBlock, if there was one. This also tells the GC about any effect on
        memory usage and does a bunch of weird data structure rewiring, since
        Executable caches some of CodeBlock's fields for the benefit of virtual call
        fast paths.
              
      This functionality is then wrapped around three convenience methods:
              
      - Executable::prepareForExecution(). If there is no code block for that
        Executable, then one is created (newCodeBlock()), compiled
        (CodeBlock::prepareForExecution()) and installed (installCode()).
              
      - CodeBlock::newReplacement(). Asks the Executable for a new CodeBlock that
        can serve as an optimized replacement of the current one.
              
      - CodeBlock::install(). Asks the Executable to install this code block.
              
      This patch allows me to kill *a lot* of code and to remove a lot of
      specializations for functions vs. not-functions, and a lot of places where we
      pass around JITCode references and such. ExecutionHarness and JITDriver are
      both gone. Overall this patch has more red than green.
              
      It also allows me to work on FTL OSR entry and tier-up:
              
      - FTL tier-up: this will involve DFGOperations.cpp asking the DFG::Worklist
        to do some compilation, but it will require the DFG::Worklist to do
        something different than what JITStubs.cpp would want, once the compilation
        finishes. This patch introduces a callback mechanism for that purpose.
              
      - FTL OSR entry: this will involve creating a special auto-jettisoned
        CodeBlock that is used only for FTL OSR entry. The new set of primitives
        allows for this: Executable can vend you a fresh new CodeBlock, and you can
        ask that CodeBlock to compile itself with any JIT of your choosing. Or you
        can take that CodeBlock and compile it yourself. Previously the act of
        producing a CodeBlock-for-optimization and the act of compiling code for it
        were tightly coupled; now you can separate them and you can create such
        auto-jettisoned CodeBlocks that are used for a one-shot OSR entry.
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::unlinkIncomingCalls):
      (JSC::CodeBlock::prepareForExecutionImpl):
      (JSC::CodeBlock::prepareForExecution):
      (JSC::CodeBlock::prepareForExecutionAsynchronously):
      (JSC::CodeBlock::install):
      (JSC::CodeBlock::newReplacement):
      (JSC::FunctionCodeBlock::jettisonImpl):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::hasBaselineJITProfiling):
      * bytecode/DeferredCompilationCallback.cpp: Added.
      (JSC::DeferredCompilationCallback::DeferredCompilationCallback):
      (JSC::DeferredCompilationCallback::~DeferredCompilationCallback):
      * bytecode/DeferredCompilationCallback.h: Added.
      * dfg/DFGDriver.cpp:
      (JSC::DFG::tryCompile):
      * dfg/DFGDriver.h:
      (JSC::DFG::tryCompile):
      * dfg/DFGFailedFinalizer.cpp:
      (JSC::DFG::FailedFinalizer::finalize):
      (JSC::DFG::FailedFinalizer::finalizeFunction):
      * dfg/DFGFailedFinalizer.h:
      * dfg/DFGFinalizer.h:
      * dfg/DFGJITFinalizer.cpp:
      (JSC::DFG::JITFinalizer::finalize):
      (JSC::DFG::JITFinalizer::finalizeFunction):
      * dfg/DFGJITFinalizer.h:
      * dfg/DFGOSRExitPreparation.cpp:
      (JSC::DFG::prepareCodeOriginForOSRExit):
      * dfg/DFGOperations.cpp:
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::Plan):
      (JSC::DFG::Plan::compileInThreadImpl):
      (JSC::DFG::Plan::notifyReady):
      (JSC::DFG::Plan::finalizeWithoutNotifyingCallback):
      (JSC::DFG::Plan::finalizeAndNotifyCallback):
      * dfg/DFGPlan.h:
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGWorklist.cpp:
      (JSC::DFG::Worklist::completeAllReadyPlansForVM):
      (JSC::DFG::Worklist::runThread):
      * ftl/FTLJITFinalizer.cpp:
      (JSC::FTL::JITFinalizer::finalize):
      (JSC::FTL::JITFinalizer::finalizeFunction):
      * ftl/FTLJITFinalizer.h:
      * heap/Heap.h:
      (JSC::Heap::isDeferred):
      * interpreter/Interpreter.cpp:
      (JSC::Interpreter::execute):
      (JSC::Interpreter::executeCall):
      (JSC::Interpreter::executeConstruct):
      (JSC::Interpreter::prepareForRepeatCall):
      * jit/JITDriver.h: Removed.
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      (JSC::jitCompileFor):
      (JSC::lazyLinkFor):
      * jit/JITToDFGDeferredCompilationCallback.cpp: Added.
      (JSC::JITToDFGDeferredCompilationCallback::JITToDFGDeferredCompilationCallback):
      (JSC::JITToDFGDeferredCompilationCallback::~JITToDFGDeferredCompilationCallback):
      (JSC::JITToDFGDeferredCompilationCallback::create):
      (JSC::JITToDFGDeferredCompilationCallback::compilationDidBecomeReadyAsynchronously):
      (JSC::JITToDFGDeferredCompilationCallback::compilationDidComplete):
      * jit/JITToDFGDeferredCompilationCallback.h: Added.
      * llint/LLIntEntrypoints.cpp:
      (JSC::LLInt::setFunctionEntrypoint):
      (JSC::LLInt::setEvalEntrypoint):
      (JSC::LLInt::setProgramEntrypoint):
      * llint/LLIntEntrypoints.h:
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::jitCompileAndSetHeuristics):
      (JSC::LLInt::setUpCall):
      * runtime/ArrayPrototype.cpp:
      (JSC::isNumericCompareFunction):
      * runtime/CommonSlowPaths.cpp:
      * runtime/CompilationResult.cpp:
      (WTF::printInternal):
      * runtime/CompilationResult.h:
      * runtime/Executable.cpp:
      (JSC::ScriptExecutable::installCode):
      (JSC::ScriptExecutable::newCodeBlockFor):
      (JSC::ScriptExecutable::newReplacementCodeBlockFor):
      (JSC::ScriptExecutable::prepareForExecutionImpl):
      * runtime/Executable.h:
      (JSC::ExecutableBase::offsetOfJITCodeWithArityCheckFor):
      (JSC::ExecutableBase::offsetOfNumParametersFor):
      (JSC::ScriptExecutable::prepareForExecution):
      (JSC::FunctionExecutable::jettisonOptimizedCodeFor):
      * runtime/ExecutionHarness.h: Removed.
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@154824 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      62b6af85
    • commit-queue@webkit.org's avatar
      Unreviewed, rolling out r154804. · ea1f9022
      commit-queue@webkit.org authored
      http://trac.webkit.org/changeset/154804
      https://bugs.webkit.org/show_bug.cgi?id=120477
      
      Broke Windows build (assumes LLInt features not enabled on
      this build) (Requested by bfulgham on #webkit).
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::linkIncomingCall):
      (JSC::CodeBlock::unlinkIncomingCalls):
      (JSC::CodeBlock::reoptimize):
      (JSC::ProgramCodeBlock::replacement):
      (JSC::EvalCodeBlock::replacement):
      (JSC::FunctionCodeBlock::replacement):
      (JSC::ProgramCodeBlock::compileOptimized):
      (JSC::ProgramCodeBlock::replaceWithDeferredOptimizedCode):
      (JSC::EvalCodeBlock::compileOptimized):
      (JSC::EvalCodeBlock::replaceWithDeferredOptimizedCode):
      (JSC::FunctionCodeBlock::compileOptimized):
      (JSC::FunctionCodeBlock::replaceWithDeferredOptimizedCode):
      (JSC::ProgramCodeBlock::jitCompileImpl):
      (JSC::EvalCodeBlock::jitCompileImpl):
      (JSC::FunctionCodeBlock::jitCompileImpl):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::jitType):
      (JSC::CodeBlock::jitCompile):
      * bytecode/DeferredCompilationCallback.cpp: Removed.
      * bytecode/DeferredCompilationCallback.h: Removed.
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      (JSC::DFG::tryCompile):
      (JSC::DFG::tryCompileFunction):
      (JSC::DFG::tryFinalizePlan):
      * dfg/DFGDriver.h:
      (JSC::DFG::tryCompile):
      (JSC::DFG::tryCompileFunction):
      (JSC::DFG::tryFinalizePlan):
      * dfg/DFGFailedFinalizer.cpp:
      (JSC::DFG::FailedFinalizer::finalize):
      (JSC::DFG::FailedFinalizer::finalizeFunction):
      * dfg/DFGFailedFinalizer.h:
      * dfg/DFGFinalizer.h:
      * dfg/DFGJITFinalizer.cpp:
      (JSC::DFG::JITFinalizer::finalize):
      (JSC::DFG::JITFinalizer::finalizeFunction):
      * dfg/DFGJITFinalizer.h:
      * dfg/DFGOSRExitPreparation.cpp:
      (JSC::DFG::prepareCodeOriginForOSRExit):
      * dfg/DFGOperations.cpp:
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::Plan):
      (JSC::DFG::Plan::compileInThreadImpl):
      (JSC::DFG::Plan::finalize):
      * dfg/DFGPlan.h:
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGWorklist.cpp:
      (JSC::DFG::Worklist::completeAllReadyPlansForVM):
      (JSC::DFG::Worklist::runThread):
      * ftl/FTLJITFinalizer.cpp:
      (JSC::FTL::JITFinalizer::finalize):
      (JSC::FTL::JITFinalizer::finalizeFunction):
      * ftl/FTLJITFinalizer.h:
      * heap/Heap.h:
      * interpreter/Interpreter.cpp:
      (JSC::Interpreter::execute):
      (JSC::Interpreter::executeCall):
      (JSC::Interpreter::executeConstruct):
      (JSC::Interpreter::prepareForRepeatCall):
      * jit/JITDriver.h: Added.
      (JSC::jitCompileIfAppropriateImpl):
      (JSC::jitCompileFunctionIfAppropriateImpl):
      (JSC::jitCompileIfAppropriate):
      (JSC::jitCompileFunctionIfAppropriate):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      (JSC::jitCompileFor):
      (JSC::lazyLinkFor):
      * jit/JITToDFGDeferredCompilationCallback.cpp: Removed.
      * jit/JITToDFGDeferredCompilationCallback.h: Removed.
      * llint/LLIntEntrypoints.cpp:
      (JSC::LLInt::getFunctionEntrypoint):
      (JSC::LLInt::getEvalEntrypoint):
      (JSC::LLInt::getProgramEntrypoint):
      * llint/LLIntEntrypoints.h:
      (JSC::LLInt::getEntrypoint):
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::jitCompileAndSetHeuristics):
      (JSC::LLInt::setUpCall):
      * runtime/ArrayPrototype.cpp:
      (JSC::isNumericCompareFunction):
      * runtime/CommonSlowPaths.cpp:
      * runtime/CompilationResult.cpp:
      (WTF::printInternal):
      * runtime/CompilationResult.h:
      * runtime/Executable.cpp:
      (JSC::EvalExecutable::compileOptimized):
      (JSC::EvalExecutable::jitCompile):
      (JSC::EvalExecutable::compileInternal):
      (JSC::EvalExecutable::replaceWithDeferredOptimizedCode):
      (JSC::ProgramExecutable::compileOptimized):
      (JSC::ProgramExecutable::jitCompile):
      (JSC::ProgramExecutable::compileInternal):
      (JSC::ProgramExecutable::replaceWithDeferredOptimizedCode):
      (JSC::FunctionExecutable::compileOptimizedForCall):
      (JSC::FunctionExecutable::compileOptimizedForConstruct):
      (JSC::FunctionExecutable::jitCompileForCall):
      (JSC::FunctionExecutable::jitCompileForConstruct):
      (JSC::FunctionExecutable::produceCodeBlockFor):
      (JSC::FunctionExecutable::compileForCallInternal):
      (JSC::FunctionExecutable::replaceWithDeferredOptimizedCodeForCall):
      (JSC::FunctionExecutable::compileForConstructInternal):
      (JSC::FunctionExecutable::replaceWithDeferredOptimizedCodeForConstruct):
      * runtime/Executable.h:
      (JSC::ExecutableBase::offsetOfJITCodeWithArityCheckFor):
      (JSC::ExecutableBase::offsetOfNumParametersFor):
      (JSC::ExecutableBase::catchRoutineFor):
      (JSC::EvalExecutable::compile):
      (JSC::ProgramExecutable::compile):
      (JSC::FunctionExecutable::compileForCall):
      (JSC::FunctionExecutable::compileForConstruct):
      (JSC::FunctionExecutable::compileFor):
      (JSC::FunctionExecutable::compileOptimizedFor):
      (JSC::FunctionExecutable::replaceWithDeferredOptimizedCodeFor):
      (JSC::FunctionExecutable::jitCompileFor):
      * runtime/ExecutionHarness.h: Added.
      (JSC::prepareForExecutionImpl):
      (JSC::prepareFunctionForExecutionImpl):
      (JSC::installOptimizedCode):
      (JSC::prepareForExecution):
      (JSC::prepareFunctionForExecution):
      (JSC::replaceWithDeferredOptimizedCode):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@154814 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      ea1f9022
    • fpizlo@apple.com's avatar
      CodeBlock compilation and installation should be simplified and rationalized · 4ea262e2
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=120326
      
      Reviewed by Oliver Hunt.
              
      Previously Executable owned the code for generating JIT code; you always had
      to go through Executable. But often you also had to go through CodeBlock,
      because ScriptExecutable couldn't have virtual methods, but CodeBlock could.
      So you'd ask CodeBlock to do something, which would dispatch through a
      virtual method that would select the appropriate Executable subtype's method.
      This all meant that the same code would often be duplicated, because most of
      the work needed to compile something was identical regardless of code type.
      But then we tried to fix this, by having templatized helpers in
      ExecutionHarness.h and JITDriver.h. The result was that if you wanted to find
      out what happened when you asked for something to be compiled, you'd go on a
      wild ride that started with CodeBlock, touched upon Executable, and then
      ricocheted into either ExecutionHarness or JITDriver (likely both).
              
      Another awkwardness was that for concurrent compiles, the DFG::Worklist had
      super-special inside knowledge of what JITStubs.cpp's cti_optimize would have
      done once the compilation finished.
              
      Also, most of the DFG JIT drivers assumed that they couldn't install the
      JITCode into the CodeBlock directly - instead they would return it via a
      reference, which happened to be a reference to the JITCode pointer in
      Executable. This was super weird.
              
      Finally, there was no notion of compiling code into a special CodeBlock that
      wasn't used for handling calls into an Executable. I'd like this for FTL OSR
      entry.
              
      This patch solves these problems by reducing all of that complexity into just
      three primitives:
              
      - Executable::newCodeBlock(). This gives you a new code block, either for call
        or for construct, and either to serve as the baseline code or the optimized
        code. The new code block is then owned by the caller; Executable doesn't
        register it anywhere. The new code block has no JITCode and isn't callable,
        but it has all of the bytecode.
              
      - CodeBlock::prepareForExecution(). This takes the CodeBlock's bytecode and
        produces a JITCode, and then installs the JITCode into the CodeBlock. This
        method takes a JITType, and always compiles with that JIT. If you ask for
        JITCode::InterpreterThunk then you'll get JITCode that just points to the
        LLInt entrypoints. Once this returns, it is possible to call into the
        CodeBlock if you do so manually - but the Executable still won't know about
        it so JS calls to that Executable will still be routed to whatever CodeBlock
        is associated with the Executable.
              
      - Executable::installCode(). This takes a CodeBlock and makes it the code-for-
        entry for that Executable. This involves unlinking the Executable's last
        CodeBlock, if there was one. This also tells the GC about any effect on
        memory usage and does a bunch of weird data structure rewiring, since
        Executable caches some of CodeBlock's fields for the benefit of virtual call
        fast paths.
              
      This functionality is then wrapped around three convenience methods:
              
      - Executable::prepareForExecution(). If there is no code block for that
        Executable, then one is created (newCodeBlock()), compiled
        (CodeBlock::prepareForExecution()) and installed (installCode()).
              
      - CodeBlock::newReplacement(). Asks the Executable for a new CodeBlock that
        can serve as an optimized replacement of the current one.
              
      - CodeBlock::install(). Asks the Executable to install this code block.
              
      This patch allows me to kill *a lot* of code and to remove a lot of
      specializations for functions vs. not-functions, and a lot of places where we
      pass around JITCode references and such. ExecutionHarness and JITDriver are
      both gone. Overall this patch has more red than green.
              
      It also allows me to work on FTL OSR entry and tier-up:
              
      - FTL tier-up: this will involve DFGOperations.cpp asking the DFG::Worklist
        to do some compilation, but it will require the DFG::Worklist to do
        something different than what JITStubs.cpp would want, once the compilation
        finishes. This patch introduces a callback mechanism for that purpose.
              
      - FTL OSR entry: this will involve creating a special auto-jettisoned
        CodeBlock that is used only for FTL OSR entry. The new set of primitives
        allows for this: Executable can vend you a fresh new CodeBlock, and you can
        ask that CodeBlock to compile itself with any JIT of your choosing. Or you
        can take that CodeBlock and compile it yourself. Previously the act of
        producing a CodeBlock-for-optimization and the act of compiling code for it
        were tightly coupled; now you can separate them and you can create such
        auto-jettisoned CodeBlocks that are used for a one-shot OSR entry.
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::prepareForExecution):
      (JSC::CodeBlock::install):
      (JSC::CodeBlock::newReplacement):
      (JSC::FunctionCodeBlock::jettisonImpl):
      (JSC::CodeBlock::setOptimizationThresholdBasedOnCompilationResult):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::hasBaselineJITProfiling):
      * bytecode/DeferredCompilationCallback.cpp: Added.
      (JSC::DeferredCompilationCallback::DeferredCompilationCallback):
      (JSC::DeferredCompilationCallback::~DeferredCompilationCallback):
      * bytecode/DeferredCompilationCallback.h: Added.
      * dfg/DFGDriver.cpp:
      (JSC::DFG::tryCompile):
      * dfg/DFGDriver.h:
      (JSC::DFG::tryCompile):
      * dfg/DFGFailedFinalizer.cpp:
      (JSC::DFG::FailedFinalizer::finalize):
      (JSC::DFG::FailedFinalizer::finalizeFunction):
      * dfg/DFGFailedFinalizer.h:
      * dfg/DFGFinalizer.h:
      * dfg/DFGJITFinalizer.cpp:
      (JSC::DFG::JITFinalizer::finalize):
      (JSC::DFG::JITFinalizer::finalizeFunction):
      * dfg/DFGJITFinalizer.h:
      * dfg/DFGOSRExitPreparation.cpp:
      (JSC::DFG::prepareCodeOriginForOSRExit):
      * dfg/DFGOperations.cpp:
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::Plan):
      (JSC::DFG::Plan::compileInThreadImpl):
      (JSC::DFG::Plan::finalizeWithoutNotifyingCallback):
      (JSC::DFG::Plan::finalizeAndNotifyCallback):
      * dfg/DFGPlan.h:
      * dfg/DFGWorklist.cpp:
      (JSC::DFG::Worklist::completeAllReadyPlansForVM):
      * ftl/FTLJITFinalizer.cpp:
      (JSC::FTL::JITFinalizer::finalize):
      (JSC::FTL::JITFinalizer::finalizeFunction):
      * ftl/FTLJITFinalizer.h:
      * heap/Heap.h:
      (JSC::Heap::isDeferred):
      * interpreter/Interpreter.cpp:
      (JSC::Interpreter::execute):
      (JSC::Interpreter::executeCall):
      (JSC::Interpreter::executeConstruct):
      (JSC::Interpreter::prepareForRepeatCall):
      * jit/JITDriver.h: Removed.
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      (JSC::jitCompileFor):
      (JSC::lazyLinkFor):
      * jit/JITToDFGDeferredCompilationCallback.cpp: Added.
      (JSC::JITToDFGDeferredCompilationCallback::JITToDFGDeferredCompilationCallback):
      (JSC::JITToDFGDeferredCompilationCallback::~JITToDFGDeferredCompilationCallback):
      (JSC::JITToDFGDeferredCompilationCallback::create):
      (JSC::JITToDFGDeferredCompilationCallback::compilationDidComplete):
      * jit/JITToDFGDeferredCompilationCallback.h: Added.
      * llint/LLIntEntrypoints.cpp:
      (JSC::LLInt::setFunctionEntrypoint):
      (JSC::LLInt::setEvalEntrypoint):
      (JSC::LLInt::setProgramEntrypoint):
      * llint/LLIntEntrypoints.h:
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::jitCompileAndSetHeuristics):
      (JSC::LLInt::setUpCall):
      * runtime/ArrayPrototype.cpp:
      (JSC::isNumericCompareFunction):
      * runtime/CommonSlowPaths.cpp:
      * runtime/CompilationResult.cpp:
      (WTF::printInternal):
      * runtime/CompilationResult.h:
      * runtime/Executable.cpp:
      (JSC::ScriptExecutable::installCode):
      (JSC::ScriptExecutable::newCodeBlockFor):
      (JSC::ScriptExecutable::newReplacementCodeBlockFor):
      (JSC::ScriptExecutable::prepareForExecutionImpl):
      * runtime/Executable.h:
      (JSC::ScriptExecutable::prepareForExecution):
      (JSC::FunctionExecutable::jettisonOptimizedCodeFor):
      * runtime/ExecutionHarness.h: Removed.
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@154804 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      4ea262e2
  11. 23 Aug, 2013 1 commit
  12. 16 Aug, 2013 1 commit
    • mhahnenberg@apple.com's avatar
      <https://webkit.org/b/119833> Concurrent compilation thread should not trigger WriteBarriers · 941ab380
      mhahnenberg@apple.com authored
      Reviewed by Oliver Hunt.
      
      The concurrent compilation thread should interact minimally with the Heap, including not
      triggering WriteBarriers. This is a prerequisite for generational GC.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::addOrFindConstant):
      (JSC::CodeBlock::findConstant):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::addConstantLazily):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::getJSConstantForValue):
      (JSC::DFG::ByteCodeParser::constantUndefined):
      (JSC::DFG::ByteCodeParser::constantNull):
      (JSC::DFG::ByteCodeParser::one):
      (JSC::DFG::ByteCodeParser::constantNaN):
      (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
      * dfg/DFGCommonData.cpp:
      (JSC::DFG::CommonData::notifyCompilingStructureTransition):
      * dfg/DFGCommonData.h:
      * dfg/DFGDesiredTransitions.cpp: Added.
      (JSC::DFG::DesiredTransition::DesiredTransition):
      (JSC::DFG::DesiredTransition::reallyAdd):
      (JSC::DFG::DesiredTransitions::DesiredTransitions):
      (JSC::DFG::DesiredTransitions::~DesiredTransitions):
      (JSC::DFG::DesiredTransitions::addLazily):
      (JSC::DFG::DesiredTransitions::reallyAdd):
      * dfg/DFGDesiredTransitions.h: Added.
      * dfg/DFGDesiredWeakReferences.cpp: Added.
      (JSC::DFG::DesiredWeakReferences::DesiredWeakReferences):
      (JSC::DFG::DesiredWeakReferences::~DesiredWeakReferences):
      (JSC::DFG::DesiredWeakReferences::addLazily):
      (JSC::DFG::DesiredWeakReferences::reallyAdd):
      * dfg/DFGDesiredWeakReferences.h: Added.
      * dfg/DFGDesiredWriteBarriers.cpp: Added.
      (JSC::DFG::DesiredWriteBarrier::DesiredWriteBarrier):
      (JSC::DFG::DesiredWriteBarrier::trigger):
      (JSC::DFG::DesiredWriteBarriers::DesiredWriteBarriers):
      (JSC::DFG::DesiredWriteBarriers::~DesiredWriteBarriers):
      (JSC::DFG::DesiredWriteBarriers::addImpl):
      (JSC::DFG::DesiredWriteBarriers::trigger):
      * dfg/DFGDesiredWriteBarriers.h: Added.
      (JSC::DFG::DesiredWriteBarriers::add):
      (JSC::DFG::initializeLazyWriteBarrier):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::truncateConstantToInt32):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::convertToConstant):
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::JITCompiler::addWeakReference):
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::Plan):
      (JSC::DFG::Plan::reallyAdd):
      * dfg/DFGPlan.h:
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * runtime/WriteBarrier.h:
      (JSC::WriteBarrierBase::set):
      (JSC::WriteBarrier::WriteBarrier):
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@154162 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      941ab380
  13. 13 Aug, 2013 1 commit
  14. 30 Jul, 2013 1 commit
    • carlosgc@webkit.org's avatar
      Unreviewed. Fix make distcheck. · 13f6daf2
      carlosgc@webkit.org authored
      Source/JavaScriptCore:
      
      * GNUmakefile.list.am: Add missing files to compilation.
      * bytecode/CodeBlock.cpp: Add a ENABLE(FTL_JIT) #if block to
      include FTL header files not included in the compilation.
      * dfg/DFGDriver.cpp: Ditto.
      * dfg/DFGPlan.cpp: Ditto.
      
      Source/ThirdParty/ANGLE:
      
      * GNUmakefile.am: Add missing header files to compilation.
      
      Source/WebCore:
      
      * GNUmakefile.list.am: Add missing header file to compilation.
      
      Source/WebKit2:
      
      * GNUmakefile.list.am: Add missing header file to compilation.
      
      Source/WTF:
      
      * GNUmakefile.list.am: Add missing files to compilation.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153460 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      13f6daf2
  15. 25 Jul, 2013 20 commits
    • ossy@webkit.org's avatar
      Buildfix after this error: · 313fe958
      ossy@webkit.org authored
      error: 'pathName' may be used uninitialized in this function [-Werror=uninitialized]
      
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThread):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153310 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      313fe958
    • oliver@apple.com's avatar
      fourthTier: DFG should do a high-level LICM before going to FTL · e17632e6
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118749
      
      Reviewed by Oliver Hunt.
      
      Implements LICM hoisting for nodes that never write anything and never read
      things that are clobbered by the loop. There are some other preconditions for
      hoisting, see DFGLICMPhase.cpp.
      
      Also did a few fixes:
      
      - ClobberSet::add was failing to switch Super entries to Direct entries in
        some cases.
      
      - DFGClobberize.cpp needed to #include "Operations.h".
      
      - DCEPhase needs to process the graph in reverse DFS order, when we're in SSA.
      
      - AbstractInterpreter can now execute a Node without knowing its indexInBlock.
        Knowing the indexInBlock is an optional optimization that all other clients
        of AI still opt into, but LICM doesn't.
      
      This makes the FTL a 2.19x speed-up on imaging-gaussian-blur.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * dfg/DFGAbstractInterpreter.h:
      (AbstractInterpreter):
      * dfg/DFGAbstractInterpreterInlines.h:
      (JSC::DFG::::executeEffects):
      (JSC::DFG::::execute):
      (DFG):
      (JSC::DFG::::clobberWorld):
      (JSC::DFG::::clobberStructures):
      * dfg/DFGAtTailAbstractState.cpp: Added.
      (DFG):
      (JSC::DFG::AtTailAbstractState::AtTailAbstractState):
      (JSC::DFG::AtTailAbstractState::~AtTailAbstractState):
      (JSC::DFG::AtTailAbstractState::createValueForNode):
      (JSC::DFG::AtTailAbstractState::forNode):
      * dfg/DFGAtTailAbstractState.h: Added.
      (DFG):
      (AtTailAbstractState):
      (JSC::DFG::AtTailAbstractState::initializeTo):
      (JSC::DFG::AtTailAbstractState::forNode):
      (JSC::DFG::AtTailAbstractState::variables):
      (JSC::DFG::AtTailAbstractState::block):
      (JSC::DFG::AtTailAbstractState::isValid):
      (JSC::DFG::AtTailAbstractState::setDidClobber):
      (JSC::DFG::AtTailAbstractState::setIsValid):
      (JSC::DFG::AtTailAbstractState::setBranchDirection):
      (JSC::DFG::AtTailAbstractState::setFoundConstants):
      (JSC::DFG::AtTailAbstractState::haveStructures):
      (JSC::DFG::AtTailAbstractState::setHaveStructures):
      * dfg/DFGBasicBlock.h:
      (JSC::DFG::BasicBlock::insertBeforeLast):
      * dfg/DFGBasicBlockInlines.h:
      (DFG):
      * dfg/DFGClobberSet.cpp:
      (JSC::DFG::ClobberSet::add):
      (JSC::DFG::ClobberSet::addAll):
      * dfg/DFGClobberize.cpp:
      (JSC::DFG::doesWrites):
      * dfg/DFGClobberize.h:
      (DFG):
      * dfg/DFGDCEPhase.cpp:
      (JSC::DFG::DCEPhase::DCEPhase):
      (JSC::DFG::DCEPhase::run):
      (JSC::DFG::DCEPhase::fixupBlock):
      (DCEPhase):
      * dfg/DFGEdgeDominates.h: Added.
      (DFG):
      (EdgeDominates):
      (JSC::DFG::EdgeDominates::EdgeDominates):
      (JSC::DFG::EdgeDominates::operator()):
      (JSC::DFG::EdgeDominates::result):
      (JSC::DFG::edgesDominate):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::checkArray):
      * dfg/DFGLICMPhase.cpp: Added.
      (LICMPhase):
      (JSC::DFG::LICMPhase::LICMPhase):
      (JSC::DFG::LICMPhase::run):
      (JSC::DFG::LICMPhase::attemptHoist):
      (DFG):
      (JSC::DFG::performLICM):
      * dfg/DFGLICMPhase.h: Added.
      (DFG):
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153295 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      e17632e6
    • oliver@apple.com's avatar
      fourthTier: FTL should be able to generate LLVM IR that uses an intrinsic for OSR exit · 6d1bb643
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118948
      
      Source/JavaScriptCore:
      
      Reviewed by Sam Weinig.
      
      - Add the ability to generate LLVM IR but then not use it, via --llvmAlwaysFails=true.
        This allows doing "what if" experiments with IR generation, even if the generated IR
        can't yet execute.
      
      - Add an OSR exit path that just calls an intrinsic that combines the branch and the
        off-ramp.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      * ftl/FTLFail.cpp: Added.
      (FTL):
      (JSC::FTL::fail):
      * ftl/FTLFail.h: Added.
      (FTL):
      * ftl/FTLIntrinsicRepository.h:
      (FTL):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
      (JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
      * runtime/Options.h:
      (JSC):
      
      Tools:
      
      Reviewed by Sam Weinig.
      
      - Make ReducedFTL capable of dealing with code that uses the fake OSR exit intrinsic,
        by exporting it as a function.
      
      - Make combineModules.rb idempotent. Sometimes it's convenient to run a file through
        it even if you know that you've already done so. See processIRDump.sh.
      
      - Add a script, processIRDump.sh, that takes the output of --dumpLLVMIR=true and
        runs it through ReducedFTL automatically. You typically want to say something like:
      
        jsc --dumpLLVMIR=true <program(s)> > jsc-output.txt
        ./processIRDump.sh --timing < jsc-output.txt
      
      * ReducedFTL/ReducedFTL.c:
      (webkit_osr_exit):
      * ReducedFTL/combineModules.rb:
      * ReducedFTL/processIRDump.sh: Added.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153289 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      6d1bb643
    • oliver@apple.com's avatar
      fourthTier: Add a phase to create loop pre-headers · 5663e31c
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118778
      
      Reviewed by Oliver Hunt.
      
      Add a loop pre-header creation phase. Any loop that doesn't already have
      just one predecessor that isn't part of the loop has a pre-header
      prepended. All non-loop predecessors then jump to that pre-header.
      
      Also fix a handful of bugs:
      
      - DFG::Analysis should set m_valid before running the analysis, since that
        makes it easier to use ASSERT(m_valid) in the analysis' methods, which
        may be called by the analysis before the analysis completes. NaturalLoops
        does this with loopsOf().
      
      - NaturalLoops::headerOf() was missing a check for innerMostLoopOf()
        returning 0, since that'll happen if the block isn't in any loop.
      
      - Change BlockInsertionSet to dethread the graph, since anyone using it
        will want to do so.
      
      - Change dethreading to ignore SSA form graphs.
      
      This also adds NaturalLoops::belongsTo(), which I always used in the
      pre-header creation phase. I didn't end up using it but I'll probably use
      it in the near future.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * dfg/DFGAnalysis.h:
      (JSC::DFG::Analysis::computeIfNecessary):
      * dfg/DFGBlockInsertionSet.cpp:
      (JSC::DFG::BlockInsertionSet::execute):
      * dfg/DFGCriticalEdgeBreakingPhase.cpp:
      (JSC::DFG::CriticalEdgeBreakingPhase::breakCriticalEdge):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dethread):
      * dfg/DFGLoopPreHeaderCreationPhase.cpp: Added.
      (DFG):
      (LoopPreHeaderCreationPhase):
      (JSC::DFG::LoopPreHeaderCreationPhase::LoopPreHeaderCreationPhase):
      (JSC::DFG::LoopPreHeaderCreationPhase::run):
      (JSC::DFG::performLoopPreHeaderCreation):
      * dfg/DFGLoopPreHeaderCreationPhase.h: Added.
      (DFG):
      * dfg/DFGNaturalLoops.h:
      (NaturalLoop):
      (JSC::DFG::NaturalLoops::headerOf):
      (JSC::DFG::NaturalLoops::innerMostLoopOf):
      (JSC::DFG::NaturalLoops::innerMostOuterLoop):
      (JSC::DFG::NaturalLoops::belongsTo):
      (NaturalLoops):
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      
      Conflicts:
      	Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153279 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      5663e31c
    • oliver@apple.com's avatar
      fourthTier: NaturalLoops should be able to quickly answer questions like "what... · 4fe26dec
      oliver@apple.com authored
      fourthTier: NaturalLoops should be able to quickly answer questions like "what loops own this basic block"
      https://bugs.webkit.org/show_bug.cgi?id=118750
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      * dfg/DFGBasicBlock.h:
      (BasicBlock):
      * dfg/DFGNaturalLoops.cpp:
      (JSC::DFG::NaturalLoops::compute):
      (JSC::DFG::NaturalLoops::loopsOf):
      * dfg/DFGNaturalLoops.h:
      (DFG):
      (JSC::DFG::NaturalLoop::NaturalLoop):
      (NaturalLoop):
      (JSC::DFG::NaturalLoop::index):
      (JSC::DFG::NaturalLoop::isOuterMostLoop):
      (JSC::DFG::NaturalLoop::addBlock):
      (JSC::DFG::NaturalLoops::headerOf):
      (JSC::DFG::NaturalLoops::innerMostLoopOf):
      (NaturalLoops):
      (JSC::DFG::NaturalLoops::innerMostOuterLoop):
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      
      Source/WTF:
      
      Reviewed by Mark Hahnenberg.
      
      Add a utility function for inserting an element into a vector that has bounded size,
      and where the insertion causes things to drop off the end.
      
      * wtf/StdLibExtras.h:
      (WTF):
      (WTF::insertIntoBoundedVector):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153277 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      4fe26dec
    • 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: FTL should better report its compile-times and it should be able... · 62242ce4
      oliver@apple.com authored
      fourthTier: FTL should better report its compile-times and it should be able to run in a mode where it doesn't spend time generating OSR exits
      https://bugs.webkit.org/show_bug.cgi?id=118401
      
      Reviewed by Sam Weinig.
      
      Add two new OSR exit modes, which are useful only for playing with compile times:
      
      - All OSR exits are llvm.trap().
      
      - OSR exits don't take arguments and have no exit value marshaling.
      
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThread):
      (JSC::DFG::Plan::compileInThreadImpl):
      * dfg/DFGPlan.h:
      (Plan):
      * ftl/FTLIntrinsicRepository.h:
      (FTL):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
      (LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::trap):
      * runtime/Options.h:
      (JSC):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153268 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      62242ce4
    • oliver@apple.com's avatar
      fourthTier: Unreviewed, add a helpful comment for why DCE is needed in the FTL. · 5a554043
      oliver@apple.com authored
      I believe I've now twice down the experiment of disabling DCE in the FTL,
      only to realize that this can't work, and that DCE is needed. I'd kind of
      like to not make that mistake again.
      
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153266 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      5a554043
    • oliver@apple.com's avatar
      fourthTier: Reenable the DFG optimization fixpoint now that it's profitable to... · 8b3558be
      oliver@apple.com authored
      fourthTier: Reenable the DFG optimization fixpoint now that it's profitable to do so with concurrent compilation
      https://bugs.webkit.org/show_bug.cgi?id=117331
      
      Rubber stamped by Sam Weinig.
      
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153214 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      8b3558be
    • oliver@apple.com's avatar
      fourthTier: add heuristics to reduce the likelihood of a trivially inlineable... · d2cdd316
      oliver@apple.com authored
      fourthTier: add heuristics to reduce the likelihood of a trivially inlineable function being independently compiled by the concurrent JIT
      https://bugs.webkit.org/show_bug.cgi?id=116557
      
      Reviewed by Geoffrey Garen.
      
      This introduces a fairly comprehensive mechanism for preventing trivially inlineable
      functions from being compiled independently of all of the things into which they end
      up being inlined.
      
      The trick is CodeBlock::m_shouldAlwaysBeInlined, or SABI for short (that's what the
      debug logging calls it). A SABI function is one that we currently believe should
      never be DFG optimized because it should always be inlined into the functions that
      call it. SABI follows "innocent until proven guilty": all functions start out SABI
      and have SABI set to false if we see proof that that function may be called in some
      possibly non-inlineable way. So long as a function is SABI, it will not tier up to
      the DFG: cti_optimize will perpetually postpone its optimization. Because SABI has
      such a severe effect, we make the burden of proof of guilt quite low. SABI gets
      cleared if any of the following happen:
      
      - You get called from native code (either through CallData or CachedCall).
      
      - You get called from an eval, since eval code takes a long time to get DFG
        optimized.
      
      - You get called from global code, since often global code doesn't tier-up since
        it's run-once.
      
      - You get called recursively, where recursion is detected by a stack walk of depth
        Options::maximumInliningDepth().
      
      - You get called through an unlinked virtual call.
      
      - You get called from DFG code, since if the caller was already DFG optimized and
        didn't inline you then obviously, you might not get inlined.
      
      - You've tiered up to the baseline JIT and you get called from the interpreter.
        The idea here is that this kind of ensures that you stay SABI only if you're
        called no more frequently than any of your callers.
      
      - You get called from a code block that isn't a DFG candidate.
      
      - You aren't an inlining candidate.
      
      Most of the heuristics for SABI are in CodeBlock::noticeIncomingCall().
      
      This is neutral on SunSpider and V8Spider, and appears to be a slight speed-up on
      V8v7, which was previously adversely affected by concurrent compilation. I also
      confirmed that for example on V8/richards, it dramatically reduces the number of
      code blocks that get DFG compiled. It is a speed-up on those V8v7 benchmarks that
      saw regressions from concurrent compilation.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::dumpAssumingJITType):
      (JSC::CodeBlock::CodeBlock):
      (JSC::CodeBlock::linkIncomingCall):
      (JSC):
      (JSC::CodeBlock::noticeIncomingCall):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      * dfg/DFGCapabilities.h:
      (JSC::DFG::mightInlineFunction):
      (DFG):
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThread):
      * dfg/DFGRepatch.cpp:
      (JSC::DFG::dfgLinkFor):
      * interpreter/Interpreter.cpp:
      (JSC::Interpreter::executeCall):
      (JSC::Interpreter::executeConstruct):
      (JSC::Interpreter::prepareForRepeatCall):
      * jit/JIT.cpp:
      (JSC::JIT::privateCompile):
      (JSC::JIT::linkFor):
      * jit/JIT.h:
      (JIT):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      (JSC::lazyLinkFor):
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::setUpCall):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153180 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      d2cdd316
    • oliver@apple.com's avatar
      fourthTier: FTL shouldn't use the LLVM global context, and should instead... · f023bee1
      oliver@apple.com authored
      fourthTier: FTL shouldn't use the LLVM global context, and should instead create its own context for each compilation
      https://bugs.webkit.org/show_bug.cgi?id=116631
      
      Reviewed by Mark Hahnenberg.
      
      In the future we might want to share contexts for multiple compilations, but for
      now using one context per compilation is a progression over just constantly using
      the global context.
      
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThread):
      (DFG):
      (JSC::DFG::Plan::compileInThreadImpl):
      * dfg/DFGPlan.h:
      * ftl/FTLAbbreviatedTypes.h:
      (FTL):
      * ftl/FTLAbbreviations.h:
      (JSC::FTL::voidType):
      (JSC::FTL::int1Type):
      (JSC::FTL::int8Type):
      (JSC::FTL::int32Type):
      (JSC::FTL::int64Type):
      (JSC::FTL::intPtrType):
      (JSC::FTL::doubleType):
      (JSC::FTL::structType):
      (JSC::FTL::mdKindID):
      (JSC::FTL::mdString):
      (JSC::FTL::mdNode):
      (JSC::FTL::appendBasicBlock):
      (JSC::FTL::insertBasicBlock):
      * ftl/FTLAbstractHeap.cpp:
      (JSC::FTL::AbstractHeap::tbaaMetadataSlow):
      (JSC::FTL::IndexedAbstractHeap::IndexedAbstractHeap):
      (JSC::FTL::NumberedAbstractHeap::NumberedAbstractHeap):
      (JSC::FTL::AbsoluteAbstractHeap::AbsoluteAbstractHeap):
      * ftl/FTLAbstractHeap.h:
      (IndexedAbstractHeap):
      (NumberedAbstractHeap):
      (AbsoluteAbstractHeap):
      * ftl/FTLAbstractHeapRepository.cpp:
      (JSC::FTL::AbstractHeapRepository::AbstractHeapRepository):
      * ftl/FTLAbstractHeapRepository.h:
      (AbstractHeapRepository):
      * ftl/FTLCommonValues.cpp:
      (JSC::FTL::CommonValues::CommonValues):
      * ftl/FTLCommonValues.h:
      (CommonValues):
      * ftl/FTLCompile.cpp:
      (JSC::FTL::mmAllocateCodeSection):
      * ftl/FTLIntrinsicRepository.cpp:
      (JSC::FTL::IntrinsicRepository::IntrinsicRepository):
      * ftl/FTLIntrinsicRepository.h:
      (FTL):
      (IntrinsicRepository):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::lower):
      * ftl/FTLOutput.cpp:
      (JSC::FTL::Output::Output):
      * ftl/FTLOutput.h:
      (Output):
      (JSC::FTL::Output::newBlock):
      * ftl/FTLState.cpp:
      (JSC::FTL::State::State):
      (JSC::FTL::State::~State):
      (FTL):
      * ftl/FTLState.h:
      (State):
      * runtime/Options.h:
      (JSC):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153174 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      f023bee1
    • oliver@apple.com's avatar
      fourthTier: DFG should be able to run on a separate thread · 284cc3d6
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=112839
      
      Source/JavaScriptCore:
      
      Reviewed by Geoffrey Garen.
      
      This is the final bit of concurrent JITing. The idea is that there is a
      single global worklist, and a single global thread, that does all
      optimizing compilation. This is the DFG::Worklist. It contains a queue of
      DFG::Plans, and a map from CodeBlock* (the baseline code block we're
      trying to optimize) to DFG::Plan. If the DFGDriver tries to concurrently
      compile something, it puts the Plan on the Worklist. The Worklist's
      thread will compile that Plan eventually, and when it's done, it will
      signal its completion by (1) notifying anyone waiting for the Worklist to
      be done, and (2) forcing the CodeBlock::m_jitExecuteCounter to take slow
      path. The next Baseline JIT cti_optimize call will then install all ready
      (i.e. compiled) Plans for that VM. Note that (1) is only for the GC and
      VM shutdown, which will want to ensure that there aren't any outstanding
      async compilations before proceeding. They do so by simply waiting for
      all of the plans for the current VM to complete. (2) is the actual way
      that code typically gets installed.
      
      This is all very racy by design. For example, just as we try to force the
      execute counter to take slow path, the main thread may be setting the
      execute counter to some other value. The main thread must set it to
      another value because (a) JIT code is constantly incrementing the counter
      in a racy way, (b) the cti_optimize slow path will set it to some
      large-ish negative value to ensure that cti_optimize isn't called
      repeatedly, and (c) OSR exits from previously jettisoned code blocks may
      still want to reset the counter values. This "race" is made benign, by
      ensuring that while there is an asynchronous compilation, we at worse set
      the counter to optimizeAfterWarmUp and never to deferIndefinitely. Hence
      if the race happens then the worst case is that we wait another ~1000
      counts before installing the optimized code. Another defense is that if
      any CodeBlock calls into cti_optimize, then it will check for all ready
      plans for the VM - so even if a code block has to wait another ~1000
      executions before it calls cti_optimize to do the installation, it may
      actually end up being installed sooner because a different code block had
      called cti_optimize, potentially for an unrelated reason.
      
      Special care is taken to ensure that installing plans informs the GC
      about the increased memory usage, but also ensures that we don't recurse
      infinitely - since at start of GC we try to install outstanding plans.
      This is done by introducing a new GC deferral mechanism (the DeferGC
      block-scoped thingy), which will ensure that GCs don't happen in the
      scope but are allowed to happen after. This still leaves the strange
      corner case that cti_optimize may install outstanding plans, then GC, and
      that GC may jettison the code block that was installed. This, and the
      fact that the plan that we took slow path to install could have been a
      failed or invalid compile, mean that we have to take special precautions
      in cti_optimize.
      
      This patch also fixes a number of small concurrency bugs that I found
      when things started running. There are probably more of those bugs still
      left to fix. This patch just fixes the ones I know about.
      
      Concurrent compilation is right now only enabled on X86_64 Mac. We need
      platforms that are sufficiently CAStastic so that we can do the various
      memory fence and CAS tricks that make this safe. We also need a platform
      that uses JSVALUE64. And we need pthread_once. So, that pretty much means
      just X64_64 for now. Enabling Linux-64_64 should be a breeze, but I'll
      leave that up to the Qt and GTK+ ports to do at their discretion.
      
      This is a solid speed-up on SunSpider (8-9%) and V8Spider (16%), our two
      main compile-time benchmarks. Most peculiarly, this also appears to
      reduce measurement noise, rather than increasing it as you would have
      expected. I don't understand that result but I like it anyway. On the
      other hand, this is a slight (1%) slow-down on V8v7. I will continue to
      investigate this but I think that the results are already good enough
      that we should land this as-is. So far, it appears that the slow-down is
      due to this breaking the don't-compile-inlineables heuristics. See
      investigation in https://bugs.webkit.org/show_bug.cgi?id=116556 and the
      bug https://bugs.webkit.org/show_bug.cgi?id=116557.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/CodeBlock.cpp:
      (JSC):
      (JSC::CodeBlock::finalizeUnconditionally):
      (JSC::CodeBlock::resetStubInternal):
      (JSC::CodeBlock::baselineVersion):
      (JSC::CodeBlock::hasOptimizedReplacement):
      (JSC::CodeBlock::optimizationThresholdScalingFactor):
      (JSC::CodeBlock::checkIfOptimizationThresholdReached):
      (JSC::CodeBlock::optimizeNextInvocation):
      (JSC::CodeBlock::dontOptimizeAnytimeSoon):
      (JSC::CodeBlock::optimizeAfterWarmUp):
      (JSC::CodeBlock::optimizeAfterLongWarmUp):
      (JSC::CodeBlock::optimizeSoon):
      (JSC::CodeBlock::forceOptimizationSlowPathConcurrently):
      (JSC::CodeBlock::setOptimizationThresholdBasedOnCompilationResult):
      (JSC::CodeBlock::updateAllPredictionsAndCountLiveness):
      (JSC::CodeBlock::updateAllArrayPredictions):
      (JSC::CodeBlock::shouldOptimizeNow):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      (JSC::CodeBlock::jitCompile):
      * bytecode/CodeBlockLock.h:
      (JSC):
      * bytecode/ExecutionCounter.cpp:
      (JSC::ExecutionCounter::forceSlowPathConcurrently):
      (JSC):
      (JSC::ExecutionCounter::setThreshold):
      * bytecode/ExecutionCounter.h:
      (ExecutionCounter):
      * debugger/Debugger.cpp:
      (JSC::Debugger::recompileAllJSFunctions):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::injectLazyOperandSpeculation):
      (JSC::DFG::ByteCodeParser::getArrayMode):
      (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks):
      * dfg/DFGCommon.h:
      (JSC::DFG::enableConcurrentJIT):
      (DFG):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::Graph):
      * dfg/DFGGraph.h:
      (Graph):
      * dfg/DFGOSREntry.cpp:
      (JSC::DFG::prepareOSREntry):
      * dfg/DFGOperations.cpp:
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::Plan):
      (JSC::DFG::Plan::compileInThread):
      (JSC::DFG::Plan::key):
      (DFG):
      * dfg/DFGPlan.h:
      (DFG):
      (Plan):
      * dfg/DFGWorklist.cpp: Added.
      (DFG):
      (JSC::DFG::Worklist::Worklist):
      (JSC::DFG::Worklist::~Worklist):
      (JSC::DFG::Worklist::finishCreation):
      (JSC::DFG::Worklist::create):
      (JSC::DFG::Worklist::enqueue):
      (JSC::DFG::Worklist::compilationState):
      (JSC::DFG::Worklist::waitUntilAllPlansForVMAreReady):
      (JSC::DFG::Worklist::removeAllReadyPlansForVM):
      (JSC::DFG::Worklist::completeAllReadyPlansForVM):
      (JSC::DFG::Worklist::completeAllPlansForVM):
      (JSC::DFG::Worklist::queueLength):
      (JSC::DFG::Worklist::dump):
      (JSC::DFG::Worklist::runThread):
      (JSC::DFG::Worklist::threadFunction):
      (JSC::DFG::initializeGlobalWorklistOnce):
      (JSC::DFG::globalWorklist):
      * dfg/DFGWorklist.h: Added.
      (DFG):
      (Worklist):
      * heap/CopiedSpaceInlines.h:
      (JSC::CopiedSpace::allocateBlock):
      * heap/DeferGC.h: Added.
      (JSC):
      (DeferGC):
      (JSC::DeferGC::DeferGC):
      (JSC::DeferGC::~DeferGC):
      * heap/Heap.cpp:
      (JSC::Heap::Heap):
      (JSC::Heap::reportExtraMemoryCostSlowCase):
      (JSC::Heap::collectAllGarbage):
      (JSC::Heap::collect):
      (JSC::Heap::collectIfNecessaryOrDefer):
      (JSC):
      (JSC::Heap::incrementDeferralDepth):
      (JSC::Heap::decrementDeferralDepthAndGCIfNeeded):
      * heap/Heap.h:
      (Heap):
      (JSC::Heap::isCollecting):
      (JSC):
      * heap/MarkedAllocator.cpp:
      (JSC::MarkedAllocator::allocateSlowCase):
      * jit/JIT.cpp:
      (JSC::JIT::privateCompile):
      * jit/JIT.h:
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::jitCompileAndSetHeuristics):
      (JSC::LLInt::entryOSR):
      (JSC::LLInt::LLINT_SLOW_PATH_DECL):
      * profiler/ProfilerBytecodes.h:
      * runtime/ConcurrentJITLock.h: Added.
      (JSC):
      * runtime/ExecutionHarness.h:
      (JSC::replaceWithDeferredOptimizedCode):
      * runtime/JSSegmentedVariableObject.cpp:
      (JSC::JSSegmentedVariableObject::findRegisterIndex):
      (JSC::JSSegmentedVariableObject::addRegisters):
      * runtime/JSSegmentedVariableObject.h:
      (JSSegmentedVariableObject):
      * runtime/Options.h:
      (JSC):
      * runtime/Structure.h:
      (Structure):
      * runtime/StructureInlines.h:
      (JSC::Structure::propertyTable):
      * runtime/SymbolTable.h:
      (SymbolTable):
      * runtime/VM.cpp:
      (JSC::VM::VM):
      (JSC::VM::~VM):
      (JSC::VM::prepareToDiscardCode):
      (JSC):
      (JSC::VM::discardAllCode):
      (JSC::VM::releaseExecutableMemory):
      * runtime/VM.h:
      (DFG):
      (VM):
      
      Source/WTF:
      
      Reviewed by Geoffrey Garen.
      
      * wtf/ByteSpinLock.h:
      Make it non-copyable. We previously had bugs where we used ByteSpinLock as a locker.
      Clearly that's bad.
      
      * wtf/MetaAllocatorHandle.h:
      Make it thread-safe ref-counted, since we may now be passing them between the
      concurrent JIT thread and the main thread.
      
      * wtf/Vector.h:
      (WTF::Vector::takeLast):
      I've wanted this method for ages, and now I finally added.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153169 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      284cc3d6
    • oliver@apple.com's avatar
      fourthTier: Executable and CodeBlock should be aware of DFG::Plans that complete asynchronously · 75afc4f8
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116350
      
      Reviewed by Oliver Hunt.
      
      This refactors compilation so that:
      
      - JITStubs knows exactly what the result of compilation was. For example, if
        compilation was deferred, it will now know this.
      
      - The set of things that has to happen to install compiled code is now factored
        out into JSC::installOptimizedCode().
      
      - A bunch of the code in Executable.cpp is now made more common to reduce code
        duplication. For example, the heap heuristics stuff is now in one place.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/CodeBlock.cpp:
      (JSC::ProgramCodeBlock::compileOptimized):
      (JSC::ProgramCodeBlock::replaceWithDeferredOptimizedCode):
      (JSC):
      (JSC::EvalCodeBlock::compileOptimized):
      (JSC::EvalCodeBlock::replaceWithDeferredOptimizedCode):
      (JSC::FunctionCodeBlock::compileOptimized):
      (JSC::FunctionCodeBlock::replaceWithDeferredOptimizedCode):
      (JSC::ProgramCodeBlock::jitCompileImpl):
      (JSC::EvalCodeBlock::jitCompileImpl):
      (JSC::FunctionCodeBlock::jitCompileImpl):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      (JSC::CodeBlock::jitCompile):
      (ProgramCodeBlock):
      (EvalCodeBlock):
      (FunctionCodeBlock):
      * dfg/DFGDesiredIdentifiers.cpp:
      (JSC::DFG::DesiredIdentifiers::numberOfIdentifiers):
      (DFG):
      (JSC::DFG::DesiredIdentifiers::at):
      * dfg/DFGDesiredIdentifiers.h:
      (JSC):
      (DesiredIdentifiers):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      (JSC::DFG::tryCompile):
      (JSC::DFG::tryCompileFunction):
      (JSC::DFG::tryFinalizePlan):
      (DFG):
      * dfg/DFGDriver.h:
      (DFG):
      (JSC::DFG::tryCompile):
      (JSC::DFG::tryCompileFunction):
      (JSC::DFG::tryFinalizePlan):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::Graph):
      * dfg/DFGJITFinalizer.cpp:
      (JSC::DFG::JITFinalizer::finalizeCommon):
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::Plan):
      (JSC::DFG::Plan::compileInThread):
      (JSC::DFG::Plan::reallyAdd):
      * dfg/DFGPlan.h:
      (JSC):
      (Plan):
      (DFG):
      * ftl/FTLJITFinalizer.cpp:
      (JSC::FTL::JITFinalizer::finalizeFunction):
      * jit/JITDriver.h:
      (JSC::jitCompileIfAppropriateImpl):
      (JSC::jitCompileFunctionIfAppropriateImpl):
      (JSC):
      (JSC::jitCompileIfAppropriate):
      (JSC::jitCompileFunctionIfAppropriate):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::jitCompileAndSetHeuristics):
      * runtime/CompilationResult.cpp: Added.
      (WTF):
      (WTF::printInternal):
      * runtime/CompilationResult.h: Added.
      (JSC):
      (WTF):
      * runtime/Executable.cpp:
      (JSC::EvalExecutable::compileOptimized):
      (JSC::EvalExecutable::jitCompile):
      (JSC::EvalExecutable::compileInternal):
      (JSC::EvalExecutable::replaceWithDeferredOptimizedCode):
      (JSC):
      (JSC::ProgramExecutable::compileOptimized):
      (JSC::ProgramExecutable::jitCompile):
      (JSC::ProgramExecutable::compileInternal):
      (JSC::ProgramExecutable::replaceWithDeferredOptimizedCode):
      (JSC::FunctionExecutable::compileOptimizedForCall):
      (JSC::FunctionExecutable::compileOptimizedForConstruct):
      (JSC::FunctionExecutable::jitCompileForCall):
      (JSC::FunctionExecutable::jitCompileForConstruct):
      (JSC::FunctionExecutable::compileForCallInternal):
      (JSC::FunctionExecutable::replaceWithDeferredOptimizedCodeForCall):
      (JSC::FunctionExecutable::compileForConstructInternal):
      (JSC::FunctionExecutable::replaceWithDeferredOptimizedCodeForConstruct):
      * runtime/Executable.h:
      (ScriptExecutable):
      (EvalExecutable):
      (ProgramExecutable):
      (FunctionExecutable):
      (JSC::FunctionExecutable::compileOptimizedFor):
      (JSC::FunctionExecutable::replaceWithDeferredOptimizedCodeFor):
      (JSC::FunctionExecutable::jitCompileFor):
      * runtime/ExecutionHarness.h:
      (JSC::prepareForExecutionImpl):
      (JSC::prepareFunctionForExecutionImpl):
      (JSC):
      (JSC::installOptimizedCode):
      (JSC::prepareForExecution):
      (JSC::prepareFunctionForExecution):
      (JSC::replaceWithDeferredOptimizedCode):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153165 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      75afc4f8
    • oliver@apple.com's avatar
      fourthTier: DFG should separate link phase into things that must be done... · 90fce824
      oliver@apple.com authored
      fourthTier: DFG should separate link phase into things that must be done concurrently and things that must be done synchronously, and have a way of passing data from one to the other
      https://bugs.webkit.org/show_bug.cgi?id=116060
      
      Reviewed by Gavin Barraclough.
      
      This introduces the concept of a DFG::Plan, which corresponds to:
      
      - The data that the concurrent DFG or FTL need to start compiling a CodeBlock.
        This mostly includes basic things like CodeBlock*, but also a list of
        must-handle values for OSR entry.
      
      - The data that the synchronous linker need to link in code compiled by a
        concurrent compilation thread. This is further encapsulated by DFG::Finalizer,
        since the data, and the actions that need to be taken, are different in DFG
        versus FTL. This patch also institutes the policy that the concurrent
        compilation thread shall not use LinkBuffer::performFinalization(), since that
        code assumes that it's running on the same thread that will actually run the
        code.
      
      - The actions that need to be taken to compile code. In other words, most of the
        code that previously lived in DFGDriver.cpp now lives in
        DFG::Plan::compileInThread().
      
      - The actions that need to be taken when synchronously linking the code. This
        includes "really" adding watchpoints and identifiers, checking watchpoint and
        chain validity, and running the DFG::Finalizer.
      
      Currently, DFGDriver just creates a Plan and runs it synchronously. But in the
      future, we will be able to malloc some Plans and enqueue them, and have the
      concurrent thread dequeue them and call Plan::compileInThread().
      
      For now, this has no behavior or performance change.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * assembler/LinkBuffer.cpp:
      (JSC::LinkBuffer::performFinalization):
      * assembler/LinkBuffer.h:
      (LinkBuffer):
      (JSC::LinkBuffer::LinkBuffer):
      (JSC::LinkBuffer::~LinkBuffer):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::initialize):
      (JSC::DFG::AbstractState::executeEffects):
      * dfg/DFGAbstractValue.cpp:
      (JSC::DFG::AbstractValue::setFuturePossibleStructure):
      (JSC::DFG::AbstractValue::filterFuturePossibleStructure):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::addStructureTransitionCheck):
      (JSC::DFG::ByteCodeParser::handleGetById):
      (JSC::DFG::ByteCodeParser::parseResolveOperations):
      (JSC::DFG::ByteCodeParser::parseBlock):
      (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
      (JSC::DFG::ByteCodeParser::parseCodeBlock):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
      * dfg/DFGDriver.cpp:
      (DFG):
      (JSC::DFG::compile):
      * dfg/DFGFailedFinalizer.cpp: Added.
      (DFG):
      (JSC::DFG::FailedFinalizer::FailedFinalizer):
      (JSC::DFG::FailedFinalizer::~FailedFinalizer):
      (JSC::DFG::FailedFinalizer::finalize):
      (JSC::DFG::FailedFinalizer::finalizeFunction):
      * dfg/DFGFailedFinalizer.h: Added.
      (DFG):
      (FailedFinalizer):
      * dfg/DFGFinalizer.cpp: Added.
      (DFG):
      (JSC::DFG::Finalizer::Finalizer):
      (JSC::DFG::Finalizer::~Finalizer):
      * dfg/DFGFinalizer.h: Added.
      (DFG):
      (Finalizer):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::canOptimizeStringObjectAccess):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::Graph):
      (JSC::DFG::Graph::dump):
      (DFG):
      * dfg/DFGGraph.h:
      (Graph):
      (JSC::DFG::Graph::masqueradesAsUndefinedWatchpointIsStillValid):
      (JSC::DFG::Graph::compilation):
      (JSC::DFG::Graph::identifiers):
      (JSC::DFG::Graph::watchpoints):
      (JSC::DFG::Graph::chains):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::linkOSRExits):
      (JSC::DFG::JITCompiler::link):
      (JSC::DFG::JITCompiler::compile):
      (JSC::DFG::JITCompiler::compileFunction):
      (JSC::DFG::JITCompiler::linkFunction):
      (DFG):
      (JSC::DFG::JITCompiler::disassemble):
      * dfg/DFGJITCompiler.h:
      (JITCompiler):
      (JSC::DFG::JITCompiler::addLazily):
      * dfg/DFGJITFinalizer.cpp: Added.
      (DFG):
      (JSC::DFG::JITFinalizer::JITFinalizer):
      (JSC::DFG::JITFinalizer::~JITFinalizer):
      (JSC::DFG::JITFinalizer::finalize):
      (JSC::DFG::JITFinalizer::finalizeFunction):
      (JSC::DFG::JITFinalizer::finalizeCommon):
      * dfg/DFGJITFinalizer.h: Added.
      (DFG):
      (JITFinalizer):
      * dfg/DFGPlan.cpp: Added.
      (DFG):
      (JSC::DFG::dumpAndVerifyGraph):
      (JSC::DFG::Plan::Plan):
      (JSC::DFG::Plan::~Plan):
      (JSC::DFG::Plan::compileInThread):
      (JSC::DFG::Plan::isStillValid):
      (JSC::DFG::Plan::reallyAdd):
      (JSC::DFG::Plan::finalize):
      * dfg/DFGPlan.h: Added.
      (DFG):
      (Plan):
      (JSC::DFG::Plan::vm):
      * dfg/DFGPredictionInjectionPhase.cpp:
      (JSC::DFG::PredictionInjectionPhase::run):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::identifierUID):
      (JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure):
      * dfg/DFGTypeCheckHoistingPhase.cpp:
      (JSC::DFG::TypeCheckHoistingPhase::run):
      * ftl/FTLGeneratedFunction.h: Added.
      (FTL):
      * ftl/FTLJITFinalizer.cpp: Added.
      (FTL):
      (JSC::FTL::JITFinalizer::JITFinalizer):
      (JSC::FTL::JITFinalizer::~JITFinalizer):
      (JSC::FTL::JITFinalizer::finalize):
      (JSC::FTL::JITFinalizer::finalizeFunction):
      * ftl/FTLJITFinalizer.h: Added.
      (FTL):
      (JITFinalizer):
      (JSC::FTL::JITFinalizer::initializeExitThunksLinkBuffer):
      (JSC::FTL::JITFinalizer::initializeEntrypointLinkBuffer):
      (JSC::FTL::JITFinalizer::initializeCode):
      (JSC::FTL::JITFinalizer::initializeFunction):
      (JSC::FTL::JITFinalizer::initializeArityCheck):
      (JSC::FTL::JITFinalizer::initializeJITCode):
      * ftl/FTLLink.cpp:
      (JSC::FTL::link):
      * ftl/FTLLink.h:
      (FTL):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::linkOSRExitsAndCompleteInitializationBlocks):
      * ftl/FTLState.cpp:
      (JSC::FTL::State::State):
      * ftl/FTLState.h:
      (FTL):
      (State):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153161 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      90fce824
    • oliver@apple.com's avatar
      fourthTier: DFG::ByteCodeParser doesn't need ExecState* · e571c18d
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115582
      
      Reviewed by Geoffrey Garen.
      
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::ByteCodeParser):
      (ByteCodeParser):
      (JSC::DFG::parse):
      * dfg/DFGByteCodeParser.h:
      (DFG):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153144 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      e571c18d
    • oliver@apple.com's avatar
      fourthTier: ASSERT that commonly used not-thread-safe methods in the runtime... · 634a76a2
      oliver@apple.com authored
      fourthTier: ASSERT that commonly used not-thread-safe methods in the runtime are not being called during compilation
      https://bugs.webkit.org/show_bug.cgi?id=115297
      
      Source/JavaScriptCore:
      
      Reviewed by Geoffrey Garen.
      
      Put in assertions that we're not doing bad things in compilation threads. Also
      factored compilation into compile+link so that even though we don't yet have
      concurrent compilation, we can be explicit about which parts of DFG work are
      meant to be concurrent, and which aren't.
      
      Also fix a handful of bugs found by these assertions.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/ResolveGlobalStatus.cpp:
      (JSC::computeForStructure):
      * bytecode/Watchpoint.cpp:
      (JSC::WatchpointSet::add):
      (JSC::InlineWatchpointSet::inflateSlow):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::~JITCompiler):
      (DFG):
      (JSC::DFG::JITCompiler::compileBody):
      (JSC::DFG::JITCompiler::compile):
      (JSC::DFG::JITCompiler::link):
      (JSC::DFG::JITCompiler::compileFunction):
      (JSC::DFG::JITCompiler::linkFunction):
      * dfg/DFGJITCompiler.h:
      (JITCompiler):
      * ftl/FTLCompile.cpp:
      (JSC::FTL::compile):
      * ftl/FTLCompile.h:
      (FTL):
      * ftl/FTLLink.cpp: Added.
      (FTL):
      (JSC::FTL::compileEntry):
      (JSC::FTL::link):
      * ftl/FTLLink.h: Added.
      (FTL):
      * ftl/FTLState.cpp:
      (JSC::FTL::State::State):
      * ftl/FTLState.h:
      (FTL):
      (State):
      * runtime/Structure.cpp:
      (JSC::Structure::get):
      (JSC::Structure::prototypeChainMayInterceptStoreTo):
      * runtime/Structure.h:
      (JSC::Structure::materializePropertyMapIfNecessary):
      * runtime/StructureInlines.h:
      (JSC::Structure::get):
      
      Source/WTF:
      
      Reviewed by Geoffrey Garen.
      
      Taught WTF the notion of compilation threads. This allows all parts of our stack
      to assert that we're not being called from a JSC compilation thread. This is in
      WTF because it will probably end up being used in StringImpl and WTFString.
      
      * WTF.xcodeproj/project.pbxproj:
      * wtf/CompilationThread.cpp: Added.
      (WTF):
      (WTF::initializeCompilationThreadsOnce):
      (WTF::initializeCompilationThreads):
      (WTF::isCompilationThread):
      (WTF::exchangeIsCompilationThread):
      * wtf/CompilationThread.h: Added.
      (WTF):
      (CompilationScope):
      (WTF::CompilationScope::CompilationScope):
      (WTF::CompilationScope::~CompilationScope):
      (WTF::CompilationScope::leaveEarly):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153134 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      634a76a2
    • oliver@apple.com's avatar
      fourthTier: It should be possible to query WatchpointSets, and add... · 9397e00c
      oliver@apple.com authored
      fourthTier: It should be possible to query WatchpointSets, and add Watchpoints, even if the compiler is running in another thread
      https://bugs.webkit.org/show_bug.cgi?id=114909
      
      Source/JavaScriptCore:
      
      Reviewed by Oliver Hunt.
      
      The idea here is that a concurrent compiler will use watchpoint sets as follows:
      
      During concurrent compilation: It will create Watchpoints, and query WatchpointSets only
      for the purpose of profiling. That is, it will use decide whether it is profitable to
      compile the code "as if" the watchpoint sets are valid.
      
      During synchronous linking: By "linking" I don't necessarily mean the LinkBuffer stuff,
      but just the very bitter end of compilation where we make the JIT code callable. This
      can happen after LinkBuffer stuff. Anyway, this will have to happen synchronously, and
      at that point we can (a) check that all WatchpointSets that we assumed were valid are
      still valid and (b) if they are then we add the watchpoints to those sets. If any of the
      sets are invalid, we give up on this compilation and try again later.
      
      The querying of WatchpointSets is engineered to say that the set is still valid if it
      is so *right now*, but this is done in a racy way and so it may say so spuriously: we
      may, with hopefully low probability, have a set that says it is valid even though it was
      just invalidated. The goal is only to ensure that (i) a set never claims to be invalid
      if it is actually valid, (ii) a set doesn't claim to be valid if it was invalidated
      before compilation even began, and (iii) querying the validity of a set doesn't cause us
      to crash.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/Watchpoint.cpp:
      (JSC::InlineWatchpointSet::inflateSlow):
      * bytecode/Watchpoint.h:
      (WatchpointSet):
      (InlineWatchpointSet):
      (JSC::InlineWatchpointSet::hasBeenInvalidated):
      (JSC::InlineWatchpointSet::isThin):
      (JSC::InlineWatchpointSet::isFat):
      (JSC::InlineWatchpointSet::fat):
      * dfg/DFGDesiredWatchpoints.cpp: Added.
      (DFG):
      (JSC::DFG::DesiredWatchpoints::DesiredWatchpoints):
      (JSC::DFG::DesiredWatchpoints::~DesiredWatchpoints):
      (JSC::DFG::DesiredWatchpoints::addLazily):
      (JSC::DFG::DesiredWatchpoints::reallyAdd):
      (JSC::DFG::DesiredWatchpoints::areStillValid):
      * dfg/DFGDesiredWatchpoints.h: Added.
      (DFG):
      (JSC::DFG::WatchpointForGenericWatchpointSet::WatchpointForGenericWatchpointSet):
      (WatchpointForGenericWatchpointSet):
      (GenericDesiredWatchpoints):
      (JSC::DFG::GenericDesiredWatchpoints::GenericDesiredWatchpoints):
      (JSC::DFG::GenericDesiredWatchpoints::addLazily):
      (JSC::DFG::GenericDesiredWatchpoints::reallyAdd):
      (JSC::DFG::GenericDesiredWatchpoints::areStillValid):
      (DesiredWatchpoints):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::link):
      (JSC::DFG::JITCompiler::compile):
      (JSC::DFG::JITCompiler::compileFunction):
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::JITCompiler::addLazily):
      (JITCompiler):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
      (JSC::DFG::SpeculativeJIT::compileObjectEquality):
      (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
      (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
      (JSC::DFG::SpeculativeJIT::compileObjectEquality):
      (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
      (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
      (JSC::DFG::SpeculativeJIT::compile):
      * ftl/FTLCompile.cpp:
      (JSC::FTL::compile):
      * ftl/FTLCompile.h:
      (FTL):
      * ftl/FTLState.h:
      (State):
      * runtime/JSFunction.h:
      (JSFunction):
      (JSC::JSFunction::allocationProfileWatchpointSet):
      * runtime/Structure.h:
      (Structure):
      (JSC::Structure::transitionWatchpointSet):
      
      Source/WTF:
      
      Reviewed by Oliver Hunt.
      
      Harden our notions of memory fences, now that we're doing racy algorithms.
      
      * wtf/Atomics.h:
      (WTF):
      (WTF::compilerFence):
      (WTF::armV7_dmb):
      (WTF::armV7_dmb_st):
      (WTF::loadLoadFence):
      (WTF::loadStoreFence):
      (WTF::storeLoadFence):
      (WTF::storeStoreFence):
      (WTF::memoryBarrierAfterLock):
      (WTF::memoryBarrierBeforeUnlock):
      (WTF::x86_mfence):
      
      
      Conflicts:
      	Source/WTF/wtf/Atomics.h
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153124 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      9397e00c
    • oliver@apple.com's avatar
      fourthTier: Landing the initial FTL logic in a single commit to avoid spurious · ea77149c
      oliver@apple.com authored
      broken builds.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153121 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      ea77149c
    • oliver@apple.com's avatar
      fourthTier: put DFG data into a DFG::JITCode, and put common DFG and FTL data... · 02b179b1
      oliver@apple.com authored
      fourthTier: put DFG data into a DFG::JITCode, and put common DFG and FTL data into something accessible from both DFG::JITCode and FTL::JITCode
      https://bugs.webkit.org/show_bug.cgi?id=113905
      
      Reviewed by Geoffrey Garen.
      
      This removes one pointer from CodeBlock.
      
      It also gives us a framework for having JITType-specific data in CodeBlock, by
      putting it into the appropriate JITCode class (either DFG::JITCode or
      FTL::JITCode). And it allows us to have DFG and FTL share some common data,
      via DFG::CommonData, which is stored in both DFG::JITCode and FTL::JITCode and
      always accessible via JITCode::dfgCommon().
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * bytecode/CodeBlock.cpp:
      (JSC):
      (JSC::CodeBlock::dumpBytecode):
      (JSC::CodeBlock::visitAggregate):
      (JSC::CodeBlock::performTracingFixpointIteration):
      (JSC::CodeBlock::finalizeUnconditionally):
      (JSC::CodeBlock::stronglyVisitWeakReferences):
      (JSC::CodeBlock::shrinkToFit):
      (JSC::CodeBlock::tallyFrequentExitSites):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      (JSC::CodeBlock::setJITCode):
      (JSC::CodeBlock::shouldImmediatelyAssumeLivenessDuringScan):
      (JSC::DFGCodeBlocks::mark):
      * dfg/DFGAssemblyHelpers.h:
      * dfg/DFGCommonData.cpp: Added.
      (DFG):
      (JSC::DFG::CommonData::notifyCompilingStructureTransition):
      (JSC::DFG::CommonData::shrinkToFit):
      * dfg/DFGCommonData.h: Added.
      (JSC):
      (DFG):
      (JSC::DFG::WeakReferenceTransition::WeakReferenceTransition):
      (WeakReferenceTransition):
      (CommonData):
      (JSC::DFG::CommonData::CommonData):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      (JSC::DFG::tryCompile):
      (JSC::DFG::tryCompileFunction):
      * dfg/DFGDriver.h:
      (DFG):
      (JSC::DFG::tryCompile):
      (JSC::DFG::tryCompileFunction):
      * dfg/DFGGraph.h:
      (Graph):
      * dfg/DFGJITCode.cpp: Added.
      (DFG):
      (JSC::DFG::JITCode::JITCode):
      (JSC::DFG::JITCode::~JITCode):
      (JSC::DFG::JITCode::dfgCommon):
      (JSC::DFG::JITCode::dfg):
      (JSC::DFG::JITCode::shrinkToFit):
      * dfg/DFGJITCode.h: Added.
      (DFG):
      (JITCode):
      (JSC::DFG::JITCode::appendOSREntryData):
      (JSC::DFG::JITCode::osrEntryDataForBytecodeIndex):
      (JSC::DFG::JITCode::appendOSRExit):
      (JSC::DFG::JITCode::lastOSRExit):
      (JSC::DFG::JITCode::appendSpeculationRecovery):
      (JSC::DFG::JITCode::appendWatchpoint):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::JITCompiler):
      (JSC::DFG::JITCompiler::linkOSRExits):
      (JSC::DFG::JITCompiler::link):
      (JSC::DFG::JITCompiler::compile):
      (JSC::DFG::JITCompiler::compileFunction):
      * dfg/DFGJITCompiler.h:
      (JITCompiler):
      (JSC::DFG::JITCompiler::addWeakReference):
      (JSC::DFG::JITCompiler::noticeOSREntry):
      (JSC::DFG::JITCompiler::jitCode):
      * dfg/DFGOSREntry.cpp:
      (JSC::DFG::prepareOSREntry):
      * dfg/DFGOSRExit.h:
      (OSRExit):
      * dfg/DFGOSRExitCompiler.cpp:
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::SpeculativeJIT):
      (JSC::DFG::SpeculativeJIT::backwardSpeculationCheck):
      (JSC::DFG::SpeculativeJIT::speculationWatchpoint):
      (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGVariableEventStream.cpp:
      * ftl/FTLCompile.cpp:
      (JSC::FTL::compile):
      * ftl/FTLJITCode.cpp:
      (JSC::FTL::JITCode::JITCode):
      (JSC::FTL::JITCode::~JITCode):
      (FTL):
      (JSC::FTL::JITCode::initializeCode):
      (JSC::FTL::JITCode::addressForCall):
      (JSC::FTL::JITCode::executableAddressAtOffset):
      (JSC::FTL::JITCode::dataAddressAtOffset):
      (JSC::FTL::JITCode::offsetOf):
      (JSC::FTL::JITCode::size):
      (JSC::FTL::JITCode::contains):
      (JSC::FTL::JITCode::ftl):
      (JSC::FTL::JITCode::dfgCommon):
      * ftl/FTLJITCode.h:
      (JITCode):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileStructureTransitionWatchpoint):
      (JSC::FTL::LowerDFGToLLVM::compilePutStructure):
      (JSC::FTL::LowerDFGToLLVM::compilePhantomPutStructure):
      (JSC::FTL::LowerDFGToLLVM::addWeakReference):
      (LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::weakPointer):
      * ftl/FTLState.cpp:
      (FTL):
      (JSC::FTL::State::State):
      (JSC::FTL::State::dumpState):
      * ftl/FTLState.h:
      (State):
      * heap/DFGCodeBlocks.cpp:
      (JSC::DFGCodeBlocks::~DFGCodeBlocks):
      (JSC::DFGCodeBlocks::jettison):
      (JSC::DFGCodeBlocks::clearMarks):
      (JSC::DFGCodeBlocks::deleteUnmarkedJettisonedCodeBlocks):
      (JSC::DFGCodeBlocks::traceMarkedCodeBlocks):
      * jit/JITCode.cpp:
      (JSC::JITCode::dfgCommon):
      (JSC):
      (JSC::JITCode::dfg):
      (JSC::JITCode::ftl):
      (JSC::DirectJITCode::DirectJITCode):
      (JSC::DirectJITCode::initializeCodeRef):
      (JSC::DirectJITCode::addressForCall):
      (JSC::DirectJITCode::executableAddressAtOffset):
      (JSC::DirectJITCode::dataAddressAtOffset):
      (JSC::DirectJITCode::offsetOf):
      (JSC::DirectJITCode::size):
      (JSC::DirectJITCode::contains):
      * jit/JITCode.h:
      (DFG):
      (FTL):
      (JSC):
      (JITCode):
      (DirectJITCode):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153116 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      02b179b1
    • oliver@apple.com's avatar
      fourthTier: JITCode should abstract exactly how the JIT code is structured and... · 9a1ae938
      oliver@apple.com authored
      fourthTier: JITCode should abstract exactly how the JIT code is structured and where it was allocated
      https://bugs.webkit.org/show_bug.cgi?id=113437
      
      Reviewed by Mark Hahnenberg.
      
      JITCode is now a virtual base class, which will allow different JITs to have radically
      different memory allocation and management conventions in the future. It will also
      make it easier to store JIT-specific meta-data in CodeBlock just by putting it into
      an appropriate JITCode subclass.
      
      For now there is one subclass, DirectJITCode, which just behaves like JITCode used to
      behave.
      
      * assembler/RepatchBuffer.h:
      (JSC::RepatchBuffer::RepatchBuffer):
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::resetStubInternal):
      (JSC::CodeBlock::bytecodeOffset):
      (JSC::CodeBlock::codeOriginForReturn):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::setJITCode):
      (JSC::CodeBlock::getJITCode):
      (JSC::CodeBlock::getJITType):
      (CodeBlock):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      (JSC::DFG::tryCompile):
      (JSC::DFG::tryCompileFunction):
      * dfg/DFGDriver.h:
      (DFG):
      (JSC::DFG::tryCompile):
      (JSC::DFG::tryCompileFunction):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::compile):
      (JSC::DFG::JITCompiler::compileFunction):
      * dfg/DFGJITCompiler.h:
      (JITCompiler):
      * dfg/DFGOSREntry.cpp:
      (JSC::DFG::prepareOSREntry):
      * dfg/DFGOSRExit.cpp:
      (JSC::DFG::OSRExit::codeLocationForRepatch):
      * dfg/DFGOSRExitCompiler32_64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * dfg/DFGOSRExitCompiler64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * dfg/DFGOperations.cpp:
      * interpreter/Interpreter.cpp:
      (JSC::Interpreter::execute):
      (JSC::Interpreter::executeCall):
      (JSC::Interpreter::executeConstruct):
      * jit/JIT.cpp:
      (JSC::JIT::privateCompile):
      * jit/JIT.h:
      (JSC::JIT::compile):
      (JIT):
      * jit/JITCode.cpp:
      (JSC):
      (JSC::JITCode::JITCode):
      (JSC::JITCode::~JITCode):
      (JSC::JITCode::execute):
      (JSC::JITCode::hostFunction):
      (JSC::DirectJITCode::DirectJITCode):
      (JSC::DirectJITCode::~DirectJITCode):
      (JSC::DirectJITCode::addressForCall):
      (JSC::DirectJITCode::executableAddressAtOffset):
      (JSC::DirectJITCode::dataAddressAtOffset):
      (JSC::DirectJITCode::offsetOf):
      (JSC::DirectJITCode::size):
      (JSC::DirectJITCode::contains):
      * jit/JITCode.h:
      (JSC):
      (JITCode):
      (JSC::JITCode::bottomTierJIT):
      (JSC::JITCode::topTierJIT):
      (JSC::JITCode::nextTierJIT):
      (JSC::JITCode::isOptimizingJIT):
      (JSC::JITCode::isBaselineCode):
      (JSC::JITCode::jitType):
      (JSC::JITCode::jitTypeFor):
      (JSC::JITCode::executableAddress):
      (JSC::JITCode::start):
      (JSC::JITCode::end):
      (DirectJITCode):
      * jit/JITDriver.h:
      (JSC::jitCompileIfAppropriate):
      (JSC::jitCompileFunctionIfAppropriate):
      * jit/JITStubs.cpp:
      (JSC::lazyLinkFor):
      (JSC::DEFINE_STUB_FUNCTION):
      * jit/ThunkGenerators.cpp:
      (JSC::virtualForGenerator):
      * llint/LLIntEntrypoints.cpp:
      (JSC::LLInt::getFunctionEntrypoint):
      (JSC::LLInt::getEvalEntrypoint):
      (JSC::LLInt::getProgramEntrypoint):
      * llint/LLIntEntrypoints.h:
      (JSC):
      (LLInt):
      (JSC::LLInt::getEntrypoint):
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::jitCompileAndSetHeuristics):
      (JSC::LLInt::entryOSR):
      (JSC::LLInt::LLINT_SLOW_PATH_DECL):
      * runtime/Executable.cpp:
      (JSC::EvalExecutable::compileInternal):
      (JSC::ProgramExecutable::compileInternal):
      (JSC::FunctionExecutable::compileForCallInternal):
      (JSC::FunctionExecutable::compileForConstructInternal):
      * runtime/Executable.h:
      (JSC::ExecutableBase::generatedJITCodeForCall):
      (JSC::ExecutableBase::generatedJITCodeForConstruct):
      (JSC::ExecutableBase::generatedJITCodeFor):
      (ExecutableBase):
      (JSC::ExecutableBase::hostCodeEntryFor):
      (JSC::ExecutableBase::jsCodeEntryFor):
      (JSC::ExecutableBase::jsCodeWithArityCheckEntryFor):
      (JSC::NativeExecutable::create):
      (JSC::NativeExecutable::finishCreation):
      (JSC::EvalExecutable::generatedJITCode):
      (JSC::ProgramExecutable::generatedJITCode):
      * runtime/ExecutionHarness.h:
      (JSC::prepareForExecution):
      (JSC::prepareFunctionForExecution):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153113 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      9a1ae938
  16. 10 May, 2013 1 commit
    • mhahnenberg@apple.com's avatar
      Rename StructureCheckHoistingPhase to TypeCheckHoistingPhase · f94b583f
      mhahnenberg@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115938
      
      We're going to add some more types of check hoisting soon, so let's have the right name here.
      
      Rubber stamped by Filip Pizlo.
              
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * dfg/DFGStructureCheckHoistingPhase.cpp: Removed.
      * dfg/DFGStructureCheckHoistingPhase.h: Removed.
      * dfg/DFGTypeCheckHoistingPhase.cpp: Copied from Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp.
      (JSC::DFG::TypeCheckHoistingPhase::TypeCheckHoistingPhase):
      (JSC::DFG::performTypeCheckHoisting):
      * dfg/DFGTypeCheckHoistingPhase.h: Copied from Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.h.
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@149911 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      f94b583f
  17. 04 May, 2013 1 commit
    • msaboff@apple.com's avatar
      There should be a runtime option to constrain what functions get DFG compiled · 7b4d2076
      msaboff@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115576
      
      Reviewed by Mark Hahnenberg.
      
      Added OptionRange to Options to allow checking that something is within an option
      or not.  The new OptionClass supports range strings in the form of [!]<low>[:<high>].
      If only one value is given, then it will be used for both low and high.  A leading
      '!' inverts the check.  If no range is given, then checking for a value within a range
      will always return true.  Added the option "bytecodeRangeToDFGCompile" that takes an
      OptionRange string to select the bytecode range of code blocks to DFG compile.
      
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile): Added new check for bytecode count within bytecodeRangeToDFGCompile
      range.
      * runtime/Options.cpp:
      (JSC::parse): Added overloaded parse() for OptionRange.
      (JSC::OptionRange::init): Parse range string and then initialize the range.
      (JSC::OptionRange::isInRange): Function used by consumer to check if a value is within
      the specified range.
      (JSC::Options::dumpOption): Added code to dump OptionRange options.
      * runtime/Options.h:
      (OptionRange): New class.
      (JSC::OptionRange::operator= ): This is really used as a default ctor for use within
      the Option static array initialization.
      (JSC::OptionRange::rangeString): This is used for debug.  It assumes that the char*
      passed into OptionRange::init is valid when this function is called.
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@149552 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      7b4d2076