1. 25 Jul, 2013 1 commit
    • 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
  2. 09 Dec, 2012 1 commit
    • fpizlo@apple.com's avatar
      JSC should scale the optimization threshold for a code block according to the cost of compiling it · 7f7ba49f
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=104406
      
      Reviewed by Oliver Hunt.
      
      We've long known that we want to scale the execution count threshold needed for the DFG
      to kick in to scale according to some estimate of the cost of compiling that code block.
      This institutes a relationship like this:
              
      threshold = thresholdSetting * (a * sqrt(instructionCount + b) + abs(c * instructionCount) + d
              
      Where a, b, c, d are coefficients derived from fitting the above expression to various
      data points, which I chose based on looking at one benchmark (3d-cube) and from my
      own intuitions.
              
      Making this work well also required changing the thresholdForOptimizeAfterLongWarmUp
      from 5000 to 1000.
              
      This is a >1% speed-up on SunSpider, a >3% speed-up on V8Spider, ~1% speed-up on V8v7,
      neutral on Octane, and neutral on Kraken.
              
      I also out-of-lined a bunch of methods related to these heuristics, because I couldn't
      stand having them defined in the header anymore. I also made improvements to debugging
      code because I needed it for tuning this change.
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::sourceCodeForTools):
      (JSC::CodeBlock::sourceCodeOnOneLine):
      (JSC::CodeBlock::dumpBytecode):
      (JSC::CodeBlock::CodeBlock):
      (JSC::CodeBlock::reoptimizationRetryCounter):
      (JSC::CodeBlock::countReoptimization):
      (JSC::CodeBlock::optimizationThresholdScalingFactor):
      (JSC::clipThreshold):
      (JSC::CodeBlock::counterValueForOptimizeAfterWarmUp):
      (JSC::CodeBlock::counterValueForOptimizeAfterLongWarmUp):
      (JSC::CodeBlock::counterValueForOptimizeSoon):
      (JSC::CodeBlock::checkIfOptimizationThresholdReached):
      (JSC::CodeBlock::optimizeNextInvocation):
      (JSC::CodeBlock::dontOptimizeAnytimeSoon):
      (JSC::CodeBlock::optimizeAfterWarmUp):
      (JSC::CodeBlock::optimizeAfterLongWarmUp):
      (JSC::CodeBlock::optimizeSoon):
      (JSC::CodeBlock::adjustedExitCountThreshold):
      (JSC::CodeBlock::exitCountThresholdForReoptimization):
      (JSC::CodeBlock::exitCountThresholdForReoptimizationFromLoop):
      (JSC::CodeBlock::shouldReoptimizeNow):
      (JSC::CodeBlock::shouldReoptimizeFromLoopNow):
      * bytecode/CodeBlock.h:
      * bytecode/ExecutionCounter.cpp:
      (JSC::ExecutionCounter::hasCrossedThreshold):
      * bytecode/ReduceWhitespace.cpp: Added.
      (JSC::reduceWhitespace):
      * bytecode/ReduceWhitespace.h: Added.
      * dfg/DFGCapabilities.cpp:
      (JSC::DFG::mightCompileEval):
      (JSC::DFG::mightCompileProgram):
      (JSC::DFG::mightCompileFunctionForCall):
      (JSC::DFG::mightCompileFunctionForConstruct):
      (JSC::DFG::mightInlineFunctionForCall):
      (JSC::DFG::mightInlineFunctionForConstruct):
      * dfg/DFGCapabilities.h:
      * dfg/DFGDisassembler.cpp:
      (JSC::DFG::Disassembler::dumpHeader):
      * dfg/DFGOSREntry.cpp:
      (JSC::DFG::prepareOSREntry):
      * jit/JITDisassembler.cpp:
      (JSC::JITDisassembler::dumpHeader):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::entryOSR):
      (JSC::LLInt::LLINT_SLOW_PATH_DECL):
      * profiler/ProfilerDatabase.cpp:
      (JSC::Profiler::Database::ensureBytecodesFor):
      * runtime/Options.h:
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@137094 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      7f7ba49f
  3. 30 Nov, 2012 1 commit
    • fpizlo@apple.com's avatar
      It should be easy to find code blocks in debug dumps · 0bfcc38a
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=103623
      
      Source/JavaScriptCore: 
      
      Reviewed by Goeffrey Garen.
      
      This gives CodeBlock a relatively strong, but also relatively compact, hash. We compute
      it lazily so that it only impacts run-time when debug support is enabled. We stringify
      it smartly so that it's short and easy to type. We base it on the source code so that
      the optimization level is irrelevant. And, we use SHA1 since it's already in our code
      base. Now, when a piece of code wants to print some debugging to say that it's operating
      on some code block, it can use this CodeBlockHash instead of memory addresses.
      
      This also takes CodeBlock debugging into the new world of print() and dataLog(). In
      particular, CodeBlock::dump() corresponds to the thing you want printed if you do:
      
      dataLog("I heart ", *myCodeBlock);
      
      Probably, you want to just print some identifying information at this point rather than
      the full bytecode dump. So, the existing CodeBlock::dump() has been renamed to
      CodeBlock::dumpBytecode(), and CodeBlock::dump() now prints the CodeBlockHash plus just
      a few little tidbits.
              
      Here's an example of CodeBlock::dump() output:
              
      EkILzr:[0x103883a00, BaselineFunctionCall]
              
      EkILzr is the CodeBlockHash. 0x103883a00 is the CodeBlock's address in memory. The other
      part is self-explanatory.
      
      Finally, this new notion of CodeBlockHash is available for other purposes like bisecting
      breakage. As such CodeBlockHash has all of the comparison operator overloads. When
      bisecting in DFGDriver.cpp, you can now say things like:
              
      if (codeBlock->hash() < CodeBlockHash("CAAAAA"))
          return false;
              
      And yes, CAAAAA is near the median hash, and the largest one is smaller than E99999. Such
      is life when you use base 62 to encode a 32-bit number.
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * bytecode/CallLinkInfo.h:
      (CallLinkInfo):
      (JSC::CallLinkInfo::specializationKind):
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::hash):
      (JSC):
      (JSC::CodeBlock::dumpAssumingJITType):
      (JSC::CodeBlock::dump):
      (JSC::CodeBlock::dumpBytecode):
      (JSC::CodeBlock::CodeBlock):
      (JSC::CodeBlock::finalizeUnconditionally):
      (JSC::CodeBlock::resetStubInternal):
      (JSC::CodeBlock::reoptimize):
      (JSC::ProgramCodeBlock::jettison):
      (JSC::EvalCodeBlock::jettison):
      (JSC::FunctionCodeBlock::jettison):
      (JSC::CodeBlock::shouldOptimizeNow):
      (JSC::CodeBlock::tallyFrequentExitSites):
      (JSC::CodeBlock::dumpValueProfiles):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::specializationKind):
      (CodeBlock):
      (JSC::CodeBlock::getJITType):
      * bytecode/CodeBlockHash.cpp: Added.
      (JSC):
      (JSC::CodeBlockHash::CodeBlockHash):
      (JSC::CodeBlockHash::dump):
      * bytecode/CodeBlockHash.h: Added.
      (JSC):
      (CodeBlockHash):
      (JSC::CodeBlockHash::CodeBlockHash):
      (JSC::CodeBlockHash::hash):
      (JSC::CodeBlockHash::operator==):
      (JSC::CodeBlockHash::operator!=):
      (JSC::CodeBlockHash::operator<):
      (JSC::CodeBlockHash::operator>):
      (JSC::CodeBlockHash::operator<=):
      (JSC::CodeBlockHash::operator>=):
      * bytecode/CodeBlockWithJITType.h: Added.
      (JSC):
      (CodeBlockWithJITType):
      (JSC::CodeBlockWithJITType::CodeBlockWithJITType):
      (JSC::CodeBlockWithJITType::dump):
      * bytecode/CodeOrigin.cpp: Added.
      (JSC):
      (JSC::CodeOrigin::inlineDepthForCallFrame):
      (JSC::CodeOrigin::inlineDepth):
      (JSC::CodeOrigin::inlineStack):
      (JSC::InlineCallFrame::hash):
      * bytecode/CodeOrigin.h:
      (InlineCallFrame):
      (JSC::InlineCallFrame::specializationKind):
      (JSC):
      * bytecode/CodeType.cpp: Added.
      (WTF):
      (WTF::printInternal):
      * bytecode/CodeType.h:
      (WTF):
      * bytecode/ExecutionCounter.cpp:
      (JSC::ExecutionCounter::dump):
      * bytecode/ExecutionCounter.h:
      (ExecutionCounter):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::parseCodeBlock):
      * dfg/DFGDisassembler.cpp:
      (JSC::DFG::Disassembler::dump):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dumpCodeOrigin):
      * dfg/DFGOSRExitCompiler.cpp:
      * dfg/DFGOperations.cpp:
      * dfg/DFGRepatch.cpp:
      (JSC::DFG::generateProtoChainAccessStub):
      (JSC::DFG::tryCacheGetByID):
      (JSC::DFG::tryBuildGetByIDList):
      (JSC::DFG::emitPutReplaceStub):
      (JSC::DFG::emitPutTransitionStub):
      (JSC::DFG::dfgLinkClosureCall):
      * interpreter/Interpreter.cpp:
      (JSC::Interpreter::dumpCallFrame):
      * jit/JITCode.cpp: Added.
      (WTF):
      (WTF::printInternal):
      * jit/JITCode.h:
      (JSC::JITCode::jitType):
      (WTF):
      * jit/JITDisassembler.cpp:
      (JSC::JITDisassembler::dump):
      (JSC::JITDisassembler::dumpForInstructions):
      * jit/JITPropertyAccess.cpp:
      (JSC::JIT::privateCompilePutByIdTransition):
      (JSC::JIT::privateCompilePatchGetArrayLength):
      (JSC::JIT::privateCompileGetByIdProto):
      (JSC::JIT::privateCompileGetByIdSelfList):
      (JSC::JIT::privateCompileGetByIdProtoList):
      (JSC::JIT::privateCompileGetByIdChainList):
      (JSC::JIT::privateCompileGetByIdChain):
      (JSC::JIT::privateCompileGetByVal):
      (JSC::JIT::privateCompilePutByVal):
      * jit/JITPropertyAccess32_64.cpp:
      (JSC::JIT::privateCompilePutByIdTransition):
      (JSC::JIT::privateCompilePatchGetArrayLength):
      (JSC::JIT::privateCompileGetByIdProto):
      (JSC::JIT::privateCompileGetByIdSelfList):
      (JSC::JIT::privateCompileGetByIdProtoList):
      (JSC::JIT::privateCompileGetByIdChainList):
      (JSC::JIT::privateCompileGetByIdChain):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * runtime/CodeSpecializationKind.cpp: Added.
      (WTF):
      (WTF::printInternal):
      * runtime/CodeSpecializationKind.h:
      (JSC::specializationFromIsCall):
      (JSC):
      (JSC::specializationFromIsConstruct):
      (WTF):
      * runtime/Executable.cpp:
      (JSC::ExecutableBase::hashFor):
      (JSC):
      (JSC::NativeExecutable::hashFor):
      (JSC::ScriptExecutable::hashFor):
      * runtime/Executable.h:
      (ExecutableBase):
      (NativeExecutable):
      (ScriptExecutable):
      (JSC::ScriptExecutable::source):
      
      Source/WTF: 
      
      Reviewed by Geoffrey Garen.
      
      Changed RawPointer to accept both const void* and void*, and use the former internally.
              
      Cleaned up SHA1 so that the functionality already used internally for self-testing is
      available via the API. This includes addBytes(CString) and computing hex digests.
      
      * wtf/RawPointer.h:
      (WTF::RawPointer::RawPointer):
      (RawPointer):
      (WTF::RawPointer::value):
      * wtf/SHA1.cpp:
      (WTF::expectSHA1):
      (WTF::SHA1::hexDigest):
      (WTF::SHA1::computeHexDigest):
      * wtf/SHA1.h:
      (WTF::SHA1::addBytes):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@136199 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      0bfcc38a
  4. 10 Jul, 2012 2 commits
    • fpizlo@apple.com's avatar
      DFG recompilation heuristics should be based on count, not rate · 39c94a4c
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=90146
      
      Reviewed by Oliver Hunt.
              
      Rolling r121511 back in after fixing the DFG's interpretation of op_div
      profiling, with Gavin's rubber stamp.
      
      This removes a bunch of code that was previously trying to prevent spurious
      reoptimizations if a large enough majority of executions of a code block did
      not result in OSR exit. It turns out that this code was purely harmful. This
      patch removes all of that logic and replaces it with a dead-simple
      heuristic: if you exit more than N times (where N is an exponential function
      of the number of times the code block has already been recompiled) then we
      will recompile.
              
      This appears to be a broad ~1% win on many benchmarks large and small.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::CodeBlock):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::couldTakeSpecialFastCase):
      (CodeBlock):
      (JSC::CodeBlock::osrExitCounter):
      (JSC::CodeBlock::countOSRExit):
      (JSC::CodeBlock::addressOfOSRExitCounter):
      (JSC::CodeBlock::offsetOfOSRExitCounter):
      (JSC::CodeBlock::adjustedExitCountThreshold):
      (JSC::CodeBlock::exitCountThresholdForReoptimization):
      (JSC::CodeBlock::exitCountThresholdForReoptimizationFromLoop):
      (JSC::CodeBlock::shouldReoptimizeNow):
      (JSC::CodeBlock::shouldReoptimizeFromLoopNow):
      * bytecode/ExecutionCounter.cpp:
      (JSC::ExecutionCounter::setThreshold):
      * bytecode/ExecutionCounter.h:
      (ExecutionCounter):
      (JSC::ExecutionCounter::clippedThreshold):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::makeDivSafe):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::compileBody):
      * dfg/DFGOSRExit.cpp:
      (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow):
      * dfg/DFGOSRExitCompiler.cpp:
      (JSC::DFG::OSRExitCompiler::handleExitCounts):
      * dfg/DFGOperations.cpp:
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * runtime/Options.h:
      (JSC):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@122206 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      39c94a4c
    • fpizlo@apple.com's avatar
      Unreviewed, roll out http://trac.webkit.org/changeset/121511 · 629c1cd7
      fpizlo@apple.com authored
      It made in-browser V8v7 10% slower.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::CodeBlock):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      (JSC::CodeBlock::countSpeculationSuccess):
      (JSC::CodeBlock::countSpeculationFailure):
      (JSC::CodeBlock::speculativeSuccessCounter):
      (JSC::CodeBlock::speculativeFailCounter):
      (JSC::CodeBlock::forcedOSRExitCounter):
      (JSC::CodeBlock::addressOfSpeculativeSuccessCounter):
      (JSC::CodeBlock::addressOfSpeculativeFailCounter):
      (JSC::CodeBlock::addressOfForcedOSRExitCounter):
      (JSC::CodeBlock::offsetOfSpeculativeSuccessCounter):
      (JSC::CodeBlock::offsetOfSpeculativeFailCounter):
      (JSC::CodeBlock::offsetOfForcedOSRExitCounter):
      (JSC::CodeBlock::largeFailCountThreshold):
      (JSC::CodeBlock::largeFailCountThresholdForLoop):
      (JSC::CodeBlock::shouldReoptimizeNow):
      (JSC::CodeBlock::shouldReoptimizeFromLoopNow):
      * bytecode/ExecutionCounter.cpp:
      (JSC::ExecutionCounter::setThreshold):
      * bytecode/ExecutionCounter.h:
      (ExecutionCounter):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::compileBody):
      * dfg/DFGOSRExit.cpp:
      (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow):
      * dfg/DFGOSRExitCompiler.cpp:
      (JSC::DFG::OSRExitCompiler::handleExitCounts):
      * dfg/DFGOperations.cpp:
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * runtime/Options.h:
      (JSC):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@122182 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      629c1cd7
  5. 29 Jun, 2012 1 commit
    • fpizlo@apple.com's avatar
      DFG recompilation heuristics should be based on count, not rate · 48a964b5
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=90146
      
      Reviewed by Oliver Hunt.
              
      This removes a bunch of code that was previously trying to prevent spurious
      reoptimizations if a large enough majority of executions of a code block did
      not result in OSR exit. It turns out that this code was purely harmful. This
      patch removes all of that logic and replaces it with a dead-simple
      heuristic: if you exit more than N times (where N is an exponential function
      of the number of times the code block has already been recompiled) then we
      will recompile.
              
      This appears to be a broad ~1% win on many benchmarks large and small.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::CodeBlock):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::osrExitCounter):
      (JSC::CodeBlock::countOSRExit):
      (CodeBlock):
      (JSC::CodeBlock::addressOfOSRExitCounter):
      (JSC::CodeBlock::offsetOfOSRExitCounter):
      (JSC::CodeBlock::adjustedExitCountThreshold):
      (JSC::CodeBlock::exitCountThresholdForReoptimization):
      (JSC::CodeBlock::exitCountThresholdForReoptimizationFromLoop):
      (JSC::CodeBlock::shouldReoptimizeNow):
      (JSC::CodeBlock::shouldReoptimizeFromLoopNow):
      * bytecode/ExecutionCounter.cpp:
      (JSC::ExecutionCounter::setThreshold):
      * bytecode/ExecutionCounter.h:
      (ExecutionCounter):
      (JSC::ExecutionCounter::clippedThreshold):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::compileBody):
      * dfg/DFGOSRExit.cpp:
      (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow):
      * dfg/DFGOSRExitCompiler.cpp:
      (JSC::DFG::OSRExitCompiler::handleExitCounts):
      * dfg/DFGOperations.cpp:
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * runtime/Options.cpp:
      (Options):
      (JSC::Options::initializeOptions):
      * runtime/Options.h:
      (Options):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@121511 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      48a964b5
  6. 26 Jun, 2012 2 commits
    • fpizlo@apple.com's avatar
      JSC should try to make profiling deterministic because otherwise reproducing failures is · 41a1f0ea
      fpizlo@apple.com authored
      nearly impossible
      https://bugs.webkit.org/show_bug.cgi?id=89940
      
      Rubber stamped by Gavin Barraclough.
              
      This rolls out the part of http://trac.webkit.org/changeset/121215 that introduced randomness
      into the system. Now, instead of randomizing the tier-up threshold, we always set it to an
      artificially low (and statically predetermined!) value. This gives most of the benefit of
      threshold randomization without actually making the system behave completely differently on
      each invocation.
      
      * bytecode/ExecutionCounter.cpp:
      (JSC::ExecutionCounter::setThreshold):
      * runtime/Options.cpp:
      (Options):
      (JSC::Options::initializeOptions):
      * runtime/Options.h:
      (Options):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@121218 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      41a1f0ea
    • fpizlo@apple.com's avatar
      Value profiling should use tier-up threshold randomization to get more coverage · 3745dbcf
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=89802
      
      Source/JavaScriptCore: 
      
      Reviewed by Gavin Barraclough.
              
      This patch causes both LLInt and Baseline JIT code to take the OSR slow path several
      times before actually doing OSR. If we take the OSR slow path before the execution
      count threshold is reached, then we just call CodeBlock::updateAllPredictions() to
      compute the current latest least-upper-bound SpecType of all values seen in each
      ValueProfile.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::stronglyVisitStrongReferences):
      (JSC::CodeBlock::updateAllPredictionsAndCountLiveness):
      (JSC):
      (JSC::CodeBlock::updateAllPredictions):
      (JSC::CodeBlock::shouldOptimizeNow):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::llintExecuteCounter):
      (JSC::CodeBlock::jitExecuteCounter):
      (CodeBlock):
      (JSC::CodeBlock::updateAllPredictions):
      * bytecode/ExecutionCounter.cpp:
      (JSC::ExecutionCounter::setThreshold):
      (JSC::ExecutionCounter::status):
      (JSC):
      * bytecode/ExecutionCounter.h:
      (JSC::ExecutionCounter::count):
      (ExecutionCounter):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::execute):
      * dfg/DFGOperations.cpp:
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::jitCompileAndSetHeuristics):
      (JSC::LLInt::entryOSR):
      (JSC::LLInt::LLINT_SLOW_PATH_DECL):
      * runtime/JSGlobalObject.cpp:
      (JSC::JSGlobalObject::JSGlobalObject):
      (JSC):
      * runtime/JSGlobalObject.h:
      (JSGlobalObject):
      (JSC::JSGlobalObject::weakRandomInteger):
      * runtime/Options.cpp:
      (Options):
      (JSC::Options::initializeOptions):
      * runtime/Options.h:
      (Options):
      * runtime/WeakRandom.h:
      (WeakRandom):
      (JSC::WeakRandom::seedUnsafe):
      
      LayoutTests: 
      
      Reviewed by Gavin Barraclough.
              
      * fast/js/dfg-store-unexpected-value-into-argument-and-osr-exit-expected.txt: Added.
      * fast/js/dfg-store-unexpected-value-into-argument-and-osr-exit.html: Added.
      * fast/js/script-tests/dfg-store-unexpected-value-into-argument-and-osr-exit.js: Added.
      (foo):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@121215 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      3745dbcf
  7. 12 Mar, 2012 1 commit
  8. 05 Mar, 2012 3 commits
    • fpizlo@apple.com's avatar
      Unreviewed, attempted build fix for !ENABLE(JIT) after r109705. · 905517d7
      fpizlo@apple.com authored
      * bytecode/ExecutionCounter.cpp:
      (JSC::ExecutionCounter::applyMemoryUsageHeuristics):
      * bytecode/ExecutionCounter.h:
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@109802 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      905517d7
    • paroga@webkit.org's avatar
      Unreviewed. Build fix for !ENABLE(JIT) after r109705. · 2f3ebf9b
      paroga@webkit.org authored
      * bytecode/ExecutionCounter.cpp:
      * bytecode/ExecutionCounter.h:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@109784 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      2f3ebf9b
    • fpizlo@apple.com's avatar
      JIT heuristics should be hyperbolic · 254d43bc
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=80055
      <rdar://problem/10922260>
      
      Source/JavaScriptCore: 
      
      Reviewed by Oliver Hunt.
              
      Added tracking of the amount of executable memory typically used for a bytecode
      instruction. Modified the execution counter scheme to use this, and the amount
      of free memory, to determine how long to wait before invoking the JIT.
              
      The result is that even if we bomb the VM with more code than can fit in our
      executable memory pool, we still keep running and almost never run out of
      executable memory - which ensures that if we have to JIT something critical, then
      we'll likely have enough memory to do so. This also does not regress performance
      on the three main benchmarks.
              
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::predictedMachineCodeSize):
      (JSC):
      (JSC::CodeBlock::usesOpcode):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      (JSC::CodeBlock::checkIfJITThresholdReached):
      (JSC::CodeBlock::dontJITAnytimeSoon):
      (JSC::CodeBlock::jitAfterWarmUp):
      (JSC::CodeBlock::jitSoon):
      (JSC::CodeBlock::llintExecuteCounter):
      (JSC::CodeBlock::counterValueForOptimizeAfterWarmUp):
      (JSC::CodeBlock::counterValueForOptimizeAfterLongWarmUp):
      (JSC::CodeBlock::addressOfJITExecuteCounter):
      (JSC::CodeBlock::offsetOfJITExecuteCounter):
      (JSC::CodeBlock::offsetOfJITExecutionActiveThreshold):
      (JSC::CodeBlock::offsetOfJITExecutionTotalCount):
      (JSC::CodeBlock::jitExecuteCounter):
      (JSC::CodeBlock::checkIfOptimizationThresholdReached):
      (JSC::CodeBlock::optimizeNextInvocation):
      (JSC::CodeBlock::dontOptimizeAnytimeSoon):
      (JSC::CodeBlock::optimizeAfterWarmUp):
      (JSC::CodeBlock::optimizeAfterLongWarmUp):
      (JSC::CodeBlock::optimizeSoon):
      * bytecode/ExecutionCounter.cpp: Added.
      (JSC):
      (JSC::ExecutionCounter::ExecutionCounter):
      (JSC::ExecutionCounter::checkIfThresholdCrossedAndSet):
      (JSC::ExecutionCounter::setNewThreshold):
      (JSC::ExecutionCounter::deferIndefinitely):
      (JSC::ExecutionCounter::applyMemoryUsageHeuristics):
      (JSC::ExecutionCounter::applyMemoryUsageHeuristicsAndConvertToInt):
      (JSC::ExecutionCounter::hasCrossedThreshold):
      (JSC::ExecutionCounter::setThreshold):
      (JSC::ExecutionCounter::reset):
      * bytecode/ExecutionCounter.h: Added.
      (JSC):
      (ExecutionCounter):
      (JSC::ExecutionCounter::formattedTotalCount):
      * dfg/DFGOSRExitCompiler32_64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * dfg/DFGOSRExitCompiler64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * jit/ExecutableAllocator.cpp:
      (JSC::DemandExecutableAllocator::allocateNewSpace):
      (JSC::ExecutableAllocator::underMemoryPressure):
      (JSC):
      (JSC::ExecutableAllocator::memoryPressureMultiplier):
      * jit/ExecutableAllocator.h:
      * jit/ExecutableAllocatorFixedVMPool.cpp:
      (JSC::ExecutableAllocator::memoryPressureMultiplier):
      (JSC):
      * jit/JIT.cpp:
      (JSC::JIT::privateCompile):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::jitCompileAndSetHeuristics):
      * llint/LowLevelInterpreter32_64.asm:
      * runtime/JSGlobalData.h:
      (JSGlobalData):
      * runtime/Options.cpp:
      (Options):
      (JSC::Options::initializeOptions):
      * runtime/Options.h:
      (Options):
      * wtf/SimpleStats.h: Added.
      (WTF):
      (SimpleStats):
      (WTF::SimpleStats::SimpleStats):
      (WTF::SimpleStats::add):
      (WTF::SimpleStats::operator!):
      (WTF::SimpleStats::count):
      (WTF::SimpleStats::sum):
      (WTF::SimpleStats::sumOfSquares):
      (WTF::SimpleStats::mean):
      (WTF::SimpleStats::variance):
      (WTF::SimpleStats::standardDeviation):
      
      Source/WebCore: 
      
      Reviewed by Oliver Hunt.
      
      No new tests, since there's no new functionality.
      
      * ForwardingHeaders/wtf/SimpleStats.h: Added.
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@109705 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      254d43bc