1. 24 Jul, 2013 40 commits
    • oliver@apple.com's avatar
      fourthTier: Introducing the StackIterator class. · 2b2e1324
      oliver@apple.com authored
      This was a non trivial merge as trunk has changed computation of line and column information
      
      Introducing the StackIterator class.
      https://bugs.webkit.org/show_bug.cgi?id=117390.
      
      Reviewed by Geoffrey Garen.
      
      Source/JavaScriptCore:
      
      The StackIterator class is meant to unify the way we iterate the JS
      stack. It also makes it so that we don't have to copy the frame data
      into the intermediate StackFrame struct before processing it.
      Unfortunately we still can't get rid of StackFrame because it is used
      to record frame information for the Exception stack that is expected
      to persist beyond when the frames have been popped off the JS stack.
      
      The StackIterator will iterate over all "logical" frames (i.e. including
      inlined frames). As it iterates the JS stack, if it encounters a DFG
      frame that has inlined frames, the iterator will canonicalize the
      inlined frames before returning. Once canonicalized, the frame can be
      read like any other frame.
      
      The StackIterator implements a Frame class that inherits from CallFrame.
      The StackIterator::Frame serves as reader of the CallFrame that makes
      it easier to access information about the frame. The StackIterator::Frame
      only adds functions, and no additional data fields.
      
      * API/JSContextRef.cpp:
      (JSContextCreateBacktrace):
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * interpreter/CallFrame.cpp:
      (JSC::CallFrame::begin):
      (JSC::CallFrame::beginAt):
      * interpreter/CallFrame.h:
      (JSC::ExecState::setInlineCallFrame):
      (ExecState):
      (JSC::ExecState::end):
      * interpreter/Interpreter.cpp:
      (JSC::Interpreter::dumpRegisters):
      (JSC::Interpreter::unwindCallFrame):
      (JSC::Interpreter::getStackTrace):
      (JSC::Interpreter::throwException):
      (JSC::Interpreter::debug):
      * interpreter/Interpreter.h:
      (Interpreter):
      * interpreter/StackIterator.cpp: Added.
      (JSC::StackIterator::StackIterator):
      (JSC::StackIterator::beginAt):
      (JSC::StackIterator::gotoNextFrame):
      - Based on the deleted Interpreter::findFunctionCallFrameFromVMCode().
      (JSC::StackIterator::findFrameForFunction):
      - Based on the deleted Interpreter::retrieveCallerFromVMCode().
      (JSC::StackIterator::Frame::codeType):
      - Based on the deleted getStackFrameCodeType().
      (JSC::StackIterator::Frame::functionName):
      - Based on StackFrame::friendlyFunctionName().
      (JSC::StackIterator::Frame::sourceURL):
      - Based on StackFrame::friendlySourceURL().
      (JSC::StackIterator::Frame::toString):
      - Based on StackFrame::toString().
      (JSC::StackIterator::Frame::bytecodeOffset):
      (JSC::StackIterator::Frame::line):
      - Based on StackFrame::line().
      (JSC::StackIterator::Frame::column):
      - Based on StackFrame::column().
      (JSC::StackIterator::Frame::arguments):
      - Based on the deleted Interpreter::retrieveArgumentsFromVMCode().
      (JSC::StackIterator::Frame::retrieveExpressionInfo):
      - Based on StackFrame::expressionInfo().
      (JSC::StackIterator::Frame::logicalFrame):
      - Based on the now deleted CallFrame::trueCallFrame().
      (JSC::StackIterator::Frame::logicalCallerFrame):
      - Based on the now deleted CallFrame::trueCallerFrame().
      (JSC::jitTypeName):
      (JSC::printIndents):
      (JSC::printif):
      (JSC::StackIterator::Frame::print):
      (debugPrintCallFrame):
      - Prints the contents of the frame for debugging purposes.
        There are 2 versions that can be used as follows:
      
        1. When you have a valid StackIterator, you can print
           the current frame's content using the print instance
           method:
               iter->print(indentLevel);
      
        2. When you have a CallFrame* that you want to dump from a debugger
           console, you can print its content as follows:
               (gdb) call debugPrintCallFrame(callFrame)
      
        A sample of the output looks like this:
      
            frame 0x1510c70b0 {
               name 'shouldBe'
               sourceURL 'testapi.js'
               hostFlag 0
               isInlinedFrame 0
               callee 0x15154efb0
               returnPC 0x10ed0786d
               callerFrame 0x1510c7058
               logicalCallerFrame 0x1510c7058
               rawLocationBits 27 0x1b
               codeBlock 0x7fe79b037200
                  bytecodeOffset 27 0x1b / 210
                  line 46
                  column 20
                  jitType 3 <BaselineJIT> isOptimizingJIT 0
                  hasCodeOrigins 0
            }
      
      * interpreter/StackIterator.h: Added.
      (StackIterator::Frame):
      (JSC::StackIterator::Frame::create):
      (JSC::StackIterator::Frame::isJSFrame):
      (JSC::StackIterator::Frame::callFrame):
      * interpreter/StackIteratorPrivate.h: Added.
      (StackIterator):
      (JSC::StackIterator::operator*):
      (JSC::StackIterator::operator->):
      (JSC::StackIterator::operator==):
      (JSC::StackIterator::operator!=):
      (JSC::StackIterator::operator++):
      (JSC::StackIterator::end):
      (JSC::StackIterator::empty):
      * jsc.cpp:
      (functionJSCStack):
      * profiler/ProfileGenerator.cpp:
      (JSC::ProfileGenerator::addParentForConsoleStart):
      * profiler/ProfileNode.h:
      (ProfileNode):
      * runtime/JSFunction.cpp:
      (JSC::retrieveArguments):
      (JSC::JSFunction::argumentsGetter):
      (JSC::skipOverBoundFunctions):
      (JSC::retrieveCallerFunction):
      (JSC::JSFunction::callerGetter):
      (JSC::JSFunction::getOwnPropertyDescriptor):
      (JSC::JSFunction::defineOwnProperty):
      * runtime/JSGlobalObjectFunctions.cpp:
      (JSC::globalFuncProtoGetter):
      (JSC::globalFuncProtoSetter):
      * runtime/ObjectConstructor.cpp:
      (JSC::objectConstructorGetPrototypeOf):
      * runtime/Operations.h:
      
      Source/WebCore:
      
      No new tests.
      
      * ForwardingHeaders/interpreter/StackIterator.h: Added.
      * bindings/js/JSXMLHttpRequestCustom.cpp:
      (WebCore::JSXMLHttpRequest::send):
      * bindings/js/ScriptCallStackFactory.cpp:
      (WebCore::createScriptCallStack):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153218 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      2b2e1324
    • oliver@apple.com's avatar
      fourthTier: DFG GetById patching shouldn't distinguish between self lists and proto lists · 73823ba8
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117377
      
      Source/JavaScriptCore:
      
      Reviewed by Geoffrey Garen.
      
      Previously if you did self accesses and then wanted to do a prototype access, you'd
      have a bad time: the prototype accesses would be forced to take slow path because
      the self list wouldn't allow prototype accesses. Likewise if you did prototype (or
      chain) accesses and then wanted to do a self access, similar stupidity would ensue.
      
      This fixes the stupidity.
      
      I believe that this was introduced way back in the days of the old interpreter,
      where distinguishing between self lists, proto lists, and chain lists was meaningful
      for interpreter performance: it meant fewer branches to evaluate those lists. Then
      it got mostly carried over to the old JIT since the old JIT was just initially an
      optimized version of the old interpreter, and then later it got carried over to the
      DFG because I didn't know any better at the time. Now I do know better and I'm
      fixing it.
      
      * bytecode/PolymorphicAccessStructureList.h:
      (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::set):
      * bytecode/StructureStubInfo.h:
      (JSC::StructureStubInfo::initGetByIdSelfList):
      * dfg/DFGOperations.cpp:
      * dfg/DFGOperations.h:
      * dfg/DFGRepatch.cpp:
      (JSC::DFG::tryCacheGetByID):
      (JSC::DFG::getPolymorphicStructureList):
      (DFG):
      (JSC::DFG::patchJumpToGetByIdStub):
      (JSC::DFG::tryBuildGetByIDList):
      (JSC::DFG::dfgBuildGetByIDList):
      
      LayoutTests:
      
      Reviewed by Geoffrey Garen.
      
      Add tests that show why this is important. These tests speed up by more than 3x.
      
      * fast/js/regress/get-by-id-proto-or-self-expected.txt: Added.
      * fast/js/regress/get-by-id-proto-or-self.html: Added.
      * fast/js/regress/get-by-id-self-or-proto-expected.txt: Added.
      * fast/js/regress/get-by-id-self-or-proto.html: Added.
      * fast/js/regress/script-tests/get-by-id-proto-or-self.js: Added.
      (foo):
      (bar):
      (Foo):
      * fast/js/regress/script-tests/get-by-id-self-or-proto.js: Added.
      (foo):
      (bar):
      (Foo):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153217 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      73823ba8
    • oliver@apple.com's avatar
      fourthTier: Recursive deadlock in DFG::ByteCodeParser · 0919f4f3
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117376
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      Leave the lock early to prevent a deadlock beneath get().
      
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::parseBlock):
      
      Source/WTF:
      
      Reviewed by Mark Hahnenberg.
      
      I've often wanted to leave a lock early. Now I have that power!
      
      * wtf/Locker.h:
      (WTF::Locker::Locker):
      (WTF::Locker::~Locker):
      (Locker):
      (WTF::Locker::unlockEarly):
      (WTF::Locker::lock):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153216 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      0919f4f3
    • oliver@apple.com's avatar
      fourthTier: don't insert ForceOSRExits except for inadequate coverage · 37bd9382
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117363
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      Previously (in http://trac.webkit.org/changeset/151303) I made it so that we
      inserted ForceOSRExits more eagerly.  I now think it's better to have
      contradictions execute normally and exit with full OSR exit profiling.  It's
      better at catching the few cases where the DFG will end up with different
      types than the baseline engines.
      
      This simplifies a bunch of code. For example it gets rid of
      ConstantFoldingPhase::paintUnreachableCode().
      
      You can think of this as a partial roll-out of r151303, except that it uses
      the facilities introduced by that patch to give us run-time assertions that
      check the CFA's correctness: if the CFA thought that something was a
      contradiction but the code didn't exit, we'll now trap.
      
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::AbstractState):
      (JSC::DFG::AbstractState::startExecuting):
      (JSC::DFG::AbstractState::executeEffects):
      (JSC::DFG::AbstractState::execute):
      (JSC::DFG::AbstractState::filter):
      (JSC::DFG::AbstractState::filterArrayModes):
      (JSC::DFG::AbstractState::filterByValue):
      (DFG):
      * dfg/DFGAbstractState.h:
      (AbstractState):
      (JSC::DFG::AbstractState::filter):
      (JSC::DFG::AbstractState::filterArrayModes):
      (JSC::DFG::AbstractState::filterByValue):
      * dfg/DFGCFAPhase.cpp:
      (JSC::DFG::CFAPhase::performBlockCFA):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::run):
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      (ConstantFoldingPhase):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      
      LayoutTests:
      
      Reviewed by Mark Hahnenberg.
      
      Convert this test, since this was the test originally added for
      ConstantFoldingPhase::paintUnreachableCode(). I wanted to make sure that I had good coverage
      for this since I am removing that method.
      
      * fast/js/dfg-force-exit-then-sparse-conditional-constant-prop-in-loop-expected.txt:
      * fast/js/script-tests/dfg-force-exit-then-sparse-conditional-constant-prop-in-loop.js:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153215 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      37bd9382
    • 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: DFG CFA should know when it hits a contradiction · 3391387e
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117272
      
      Reviewed by Oliver Hunt.
      
      This makes the DFG CFA immediately detect when it hit a contradiction. Previously
      we might not know this: for example if we did an int32 type check on a known string;
      the code would definitely always exit but the CFA would think that we wouldn't have
      even though it would have computed a BOTTOM (i.e. contradictory) value for that
      variable.
      
      This requires two other changes:
      
      - CFA must report contradictions as if they are frequent exit sites, since
        contradictory speculations will subsequently get replaced with ForceOSRExit.
        ForceOSRExit cannot itself report profiling data back to the DFG::ExitProfile. So,
        we do this on behalf of the speculation, eagerly, within the CFA. This also has
        the effect of speeding convergence somewhat. We may want to revisit this later;
        for example we might want to instead have the notion of a ForceOSRExit that knows
        the set of speculations that got folded into it.
      
      - This revealed a bug where the CFA was modeling CheckStructure on a node that had
        a known singleton m_futurePossibleStructure set somewhat differently than the
        constant folder. If the CheckStructure was checking a structure set with two or
        more structures in it, it would not filter the abstract value. But the constant
        folder would turn this into a watchpoint on the singleton structure, thereby
        filtering the value. This discrepancy meant that we wouldn't realize the
        contradiction until the backend, and the AbstractState::bail() method asserts that
        we always realize contradictions in the constant folder.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::addFrequentExitSite):
      (JSC::CodeBlock::hasExitSite):
      (CodeBlock):
      * bytecode/DFGExitProfile.cpp:
      (JSC::DFG::ExitProfile::add):
      (JSC::DFG::ExitProfile::hasExitSite):
      (JSC::DFG::QueryableExitProfile::QueryableExitProfile):
      (JSC::DFG::QueryableExitProfile::~QueryableExitProfile):
      (DFG):
      (JSC::DFG::QueryableExitProfile::initialize):
      * bytecode/DFGExitProfile.h:
      (JSC::DFG::FrequentExitSite::FrequentExitSite):
      (ExitProfile):
      (JSC::DFG::ExitProfile::hasExitSite):
      (QueryableExitProfile):
      * bytecode/ExitKind.cpp:
      (JSC::exitKindToString):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::AbstractState):
      (JSC::DFG::AbstractState::beginBasicBlock):
      (JSC::DFG::AbstractState::reset):
      (JSC::DFG::AbstractState::startExecuting):
      (JSC::DFG::AbstractState::executeEffects):
      (JSC::DFG::AbstractState::execute):
      (JSC::DFG::AbstractState::filter):
      (DFG):
      (JSC::DFG::AbstractState::filterArrayModes):
      (JSC::DFG::AbstractState::filterByValue):
      (JSC::DFG::AbstractState::bail):
      * dfg/DFGAbstractState.h:
      (AbstractState):
      (JSC::DFG::AbstractState::filter):
      (JSC::DFG::AbstractState::filterArrayModes):
      (JSC::DFG::AbstractState::filterByValue):
      (JSC::DFG::AbstractState::filterByType):
      * dfg/DFGAbstractValue.cpp:
      (JSC::DFG::AbstractValue::filter):
      (JSC::DFG::AbstractValue::filterArrayModes):
      (DFG):
      (JSC::DFG::AbstractValue::filterByValue):
      (JSC::DFG::AbstractValue::normalizeClarity):
      * dfg/DFGAbstractValue.h:
      (AbstractValue):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
      * dfg/DFGCFAPhase.cpp:
      (JSC::DFG::CFAPhase::performBlockCFA):
      * dfg/DFGCapabilities.cpp:
      (JSC::DFG::debugFail):
      (JSC::DFG::capabilityLevel):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      (ConstantFoldingPhase):
      (JSC::DFG::ConstantFoldingPhase::paintUnreachableCode):
      * dfg/DFGFiltrationResult.h: Added.
      (DFG):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGNodeType.h:
      (DFG):
      * dfg/DFGOSRExitBase.cpp:
      (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSiteSlow):
      * dfg/DFGOSRExitBase.h:
      (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSite):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::backwardTypeCheck):
      (JSC::DFG::SpeculativeJIT::bail):
      (DFG):
      (JSC::DFG::SpeculativeJIT::compile):
      (JSC::DFG::SpeculativeJIT::compileToStringOnCell):
      (JSC::DFG::SpeculativeJIT::speculateStringObject):
      (JSC::DFG::SpeculativeJIT::speculateStringOrStringObject):
      * dfg/DFGSpeculativeJIT.h:
      (SpeculativeJIT):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
      (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
      (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
      (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
      (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
      (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
      (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
      (JSC::DFG::SpeculativeJIT::compile):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::appendTypeCheck):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153213 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      3391387e
    • oliver@apple.com's avatar
      fourthTier: 32-bit CallFrame::Location should use Instruction* for... · c4c9b8a1
      oliver@apple.com authored
      fourthTier: 32-bit CallFrame::Location should use Instruction* for BytecodeLocation, not bytecodeOffset.
      https://bugs.webkit.org/show_bug.cgi?id=117327.
      
      Reviewed by Michael Saboff.
      
      - Renamed CallFrame::Location's Type to TypeTag.
      - Made the CallFrame::Location::TypeTag private, and provided type
        specific encoder functions. This reduces verbosity in client code.
      - Fixed the DFG's reifyInlinedCallFrames() on 32-bit ports to store a
        bytecode Instruction* in the CallFrame location instead of a bytecode
        offset.
      - Fixed places in JIT and FTL code which populate the CallFrame location
        (i.e. ArgumentCount tag) to use a Location encoder instead of storing
        the bytecodeOffset directly. This doesn't make any semantic difference,
        but it does assert that the stored value does not have bits where we
        would expect Location TypeTags to be.
      
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::JITCompiler::beginCall):
      * dfg/DFGOSRExitCompilerCommon.cpp:
      (JSC::DFG::reifyInlinedCallFrames):
      * ftl/FTLLink.cpp:
      (JSC::FTL::link):
      * interpreter/CallFrame.cpp:
      (JSC::CallFrame::setLocationAsBytecodeOffset):
      * interpreter/CallFrame.h:
      (Location):
      * interpreter/CallFrameInlines.h:
      (JSC::CallFrame::Location::encodeAsBytecodeOffset):
      (JSC::CallFrame::Location::encodeAsBytecodeInstruction):
      (JSC::CallFrame::Location::encodeAsCodeOriginIndex):
      (JSC::CallFrame::Location::encodeAsInlinedCode):
      (JSC::CallFrame::Location::isBytecodeLocation):
      (JSC::CallFrame::setIsInlinedFrame):
      (JSC::CallFrame::hasLocationAsBytecodeOffset):
      (JSC::CallFrame::setLocationAsBytecodeOffset):
      * jit/JITCall.cpp:
      (JSC::JIT::compileOpCall):
      * jit/JITCall32_64.cpp:
      (JSC::JIT::compileOpCall):
      * jit/JITInlines.h:
      (JSC::JIT::updateTopCallFrame):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153212 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      c4c9b8a1
    • oliver@apple.com's avatar
      fourthTier: CallFrame::trueCallFrame() should populate the bytecodeOffset field · 1e7b6b5d
      oliver@apple.com authored
      when reifying inlined frames..
      https://bugs.webkit.org/show_bug.cgi?id=117209.
      
      Reviewed by Geoffrey Garen.
      
      When reifying an inlined frame, we fill in its CodeBlock, and
      bytecodeOffset. We also set the InlinedFrame bit in the location field.
      This is needed in order to iterate the stack correctly. Here's why:
      
          Let's say we have the following stack trace:
            X calls A inlines B inlines C calls D
      
          Based on the above scenario,
          1. D's callerFrame points to A (not C).
          2. A has a codeOriginIndex that points to C.
      
      When iterating the stack (from D back towards X), we will encounter A
      twice:
      
          t1. when trying to find C as D's caller.
              This is the time when we reify B and C using the
              codeOriginIndex in A, and return C as the caller frame of D.
      
          t2. when getting's the reified B's caller.
              This time, we don't run the reification process, and
              just take A as the caller frame of B.
      
      To discern which treatment of the DFG frame (i.e. A) we need to apply,
      we check if the callee is an inlined frame:
      
          If callee is NOT an inlined frame (e.g. frame D), apply treatment t1.
          If callee is an inlined frame (e.g. frame B), apply treatment t2.
      
      Why not just reify A by replacing its codeOriginIndex with A's
      bytecodeOffset?
      
      We can't do this because D's callerFrame pointer still points to A, and
      needs to remain that way because we did not deopt A. It remains a DFG
      frame which inlined B and C.
      
      If we replace the codeOriginIndex in A with A's bytecodeOffset, we will
      only get to iterate the stack correctly once. If we try to iterate the
      stack a second time, we will not have the information from the
      codeOriginIndex to tell us that D's caller is actually the inlined C,
      and not A.
      
      To recap, when reifying frames for stack iteration purposes, the DFG
      frame needs to hold on to its codeOriginIndex. This in turn means the
      DFG frame will need to be treated in 2 possible ways, and we need to
      know if a callee frame is an inlined frame in order to choose the
      correct treatment for the DFG frame.
      
      Other changes:
      - Simplified Interpreter::getCallerInfo().
      - Removed CodeBlock::codeOriginForReturn() and supporting code
        which is now unneeded.
      - Moved CallFrame location bit encoding from the CodeOrigin to the
        new CallFrame::Location class.
      - Explicitly tagged inlined frames. This is necessary in order to
        iterate the stack correctly as explained above.
      
      * bytecode/CodeBlock.cpp:
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::codeOrigins):
      (CodeBlock):
      (JSC::CodeBlock::codeOrigin):
      (RareData):
      * bytecode/CodeOrigin.h:
      (CodeOrigin):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::link):
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::JITCompiler::beginCall):
      * interpreter/CallFrame.cpp:
      (JSC::CallFrame::trueCallFrame):
      (JSC::CallFrame::trueCallerFrame):
      (JSC::CallFrame::bytecodeOffsetFromCodeOriginIndex):
      * interpreter/CallFrame.h:
      (Location):
      (ExecState):
      (JSC::ExecState::trueCallerFrame):
      (JSC::ExecState::callerFrameNoFlags):
      * interpreter/CallFrameInlines.h:
      (JSC::CallFrame::Location::encode):
      (JSC::CallFrame::Location::decode):
      (JSC::CallFrame::Location::isBytecodeOffset):
      (JSC::CallFrame::Location::isCodeOriginIndex):
      (JSC::CallFrame::Location::isInlinedFrame):
      (JSC::CallFrame::isInlinedFrame):
      (JSC::CallFrame::setIsInlinedFrame):
      (JSC::CallFrame::hasLocationAsBytecodeOffset):
      (JSC::CallFrame::hasLocationAsCodeOriginIndex):
      (JSC::CallFrame::locationAsBytecodeOffset):
      (JSC::CallFrame::setLocationAsBytecodeOffset):
      (JSC::CallFrame::locationAsCodeOriginIndex):
      * interpreter/Interpreter.cpp:
      (JSC::getCallerInfo):
      (JSC::Interpreter::getStackTrace):
      (JSC::Interpreter::findFunctionCallFrameFromVMCode):
      * runtime/Arguments.cpp:
      (JSC::Arguments::tearOff):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153211 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      1e7b6b5d
    • oliver@apple.com's avatar
      fourthTier: DFG CFA shouldn't filter ArrayModes with ALL_NON_ARRAY_ARRAY_MODES... · afa7e3aa
      oliver@apple.com authored
      fourthTier: DFG CFA shouldn't filter ArrayModes with ALL_NON_ARRAY_ARRAY_MODES if the speculated type is not SpecArray
      https://bugs.webkit.org/show_bug.cgi?id=117279
      
      Reviewed by Mark Hahnenberg.
      
      The normalization of abstract value clarity introduced in r151229 revealed a
      long-standing bug where we filtered ArrayModes incorrectly and sometimes ended
      up with BOTTOM incorrectly.
      
      This patch fixes that bug, and cleans up a bunch of debugging infrastructure
      that I needed to resurrect to track this down.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::resetStubInternal):
      (JSC::CodeBlock::noticeIncomingCall):
      * dfg/DFGAbstractValue.cpp:
      (JSC::DFG::AbstractValue::filterArrayModesByType):
      * dfg/DFGCFAPhase.cpp:
      (CFAPhase):
      (JSC::DFG::CFAPhase::run):
      (JSC::DFG::CFAPhase::performBlockCFA):
      (JSC::DFG::CFAPhase::performForwardCFA):
      * runtime/Options.h:
      (JSC):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153210 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      afa7e3aa
    • oliver@apple.com's avatar
      fourthTier: Disambiguate between CallFrame bytecodeOffset and codeOriginIndex. · c4497327
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117262.
      
      Reviewed by Geoffrey Garen.
      
      When writing to the ArgumentCount tag in CallFrame, we will set the high
      bit if the written value is a codeOriginIndex.
      
      * GNUmakefile.list.am:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/CodeOrigin.h:
      (CodeOrigin):
      (JSC::CodeOrigin::isHandle):
      (JSC::CodeOrigin::encodeHandle):
      (JSC::CodeOrigin::decodeHandle):
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::JITCompiler::beginCall):
      * dfg/DFGRepatch.cpp:
      (JSC::DFG::tryBuildGetByIDList):
      * interpreter/CallFrame.cpp:
      (JSC::CallFrame::locationAsBytecodeOffset):
      (JSC::CallFrame::setLocationAsBytecodeOffset):
      (JSC::CallFrame::currentVPC):
      (JSC::CallFrame::setCurrentVPC):
      (JSC::CallFrame::trueCallFrame):
      * interpreter/CallFrame.h:
      (ExecState):
      (JSC::ExecState::inlineCallFrame):
      * interpreter/CallFrameInlines.h: Added.
      (JSC::CallFrame::hasLocationAsBytecodeOffset):
      (JSC::CallFrame::hasLocationAsCodeOriginIndex):
      (JSC::CallFrame::locationAsRawBits):
      (JSC::CallFrame::setLocationAsRawBits):
      (JSC::CallFrame::locationAsBytecodeOffset):
      (JSC::CallFrame::setLocationAsBytecodeOffset):
      (JSC::CallFrame::locationAsCodeOriginIndex):
      * interpreter/Interpreter.cpp:
      (JSC::getBytecodeOffsetForCallFrame):
      (JSC::getCallerInfo):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153209 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      c4497327
    • oliver@apple.com's avatar
      fourthTier: Clean up AbstractValue · db4f90d9
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117217
      
      Reviewed by Oliver Hunt.
      
      This started as an attempt to make it so that when AbstractValue becomes empty,
      its m_type always becomes SpecNone. I wanted this to happen naturally. That turns
      out to be basically impossible, since AbstractValue is a set that is dynamically
      computed from the intersection of several internal sets: so the value becomes
      empty when any of the sets go empty. It's OK if we're imprecise here because it's
      always safe for the AbstractValue to seem to overapproximate the set of values
      that we see. So I mostly gave up on cleaning up that aspect of AbstractValue. But
      while trying to make this happen, I encountered two bugs:
      
      - filterValueByType() ignores the case when m_type contravenes m_value. Namely,
        we might filter the AbstractValue against a SpeculatedType leading to m_value
        becoming inconsistent with the new m_type. This change fixes that case. This
        wasn't a symptomatic bug but it was a silly oversight.
      
      - filterFuturePossibleStructure() was never right. The one call to this method,
        in filter(Graph&, const StructureSet&), assumed that the previous notions of
        what structures the value could have in the future were still relevant. This
        could lead to a bug where we:
      
        1) CheckStructure(@foo, S1)
      
           Where S1 has a valid watchpoint. Now @foo's abstract value will have current
           and future structure = S1.
      
        2) Clobber the world.
      
           Now @foo's abstract value will have current structure = TOP, and future
           possible structure = S1.
      
        3) CheckStructure(@foo, S2)
      
           Now @foo's abstract value will have current structure = S2 and future
           possible structure = S1 intersect S2 = BOTTOM.
      
        Now we will think that any subsequent watchpoint on @foo is valid because the
        value is effectively BOTTOM. That would only be correct if we had actually set
        a watchpoint on S1. If we had done so, then (3) would only pass (i.e. @foo
        would only have structure S2) if S1's watchpoint fired, in which case (3)
        wouldn't have been reachable. But we didn't actually set a watchpoint on S1:
        we just observed that we *could* have set the watchpoint. Hence future possible
        structure should only be set to either the known structure at compile-time, or
        it should be the structure we just checked; in both cases it should only be set
        if the structure is watchable.
      
      Then, in addition to all of this, I changed AbstractValue's filtering methods to
      call clear() if the AbstractValue is effectively clear. This is just meant to
      simplify the recognition of truly empty AbstractValues, but doesn't actually have
      any other implications.
      
      * bytecode/StructureSet.h:
      (JSC::StructureSet::dump):
      * dfg/DFGAbstractValue.cpp:
      (JSC::DFG::AbstractValue::filter):
      (DFG):
      (JSC::DFG::AbstractValue::filterArrayModes):
      (JSC::DFG::AbstractValue::filterValueByType):
      (JSC::DFG::AbstractValue::filterArrayModesByType):
      (JSC::DFG::AbstractValue::shouldBeClear):
      (JSC::DFG::AbstractValue::normalizeClarity):
      (JSC::DFG::AbstractValue::checkConsistency):
      * dfg/DFGAbstractValue.h:
      (JSC::DFG::AbstractValue::isClear):
      (AbstractValue):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153208 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      db4f90d9
    • oliver@apple.com's avatar
      fourthTier: The DFG JIT should populate frame bytecodeOffsets on OSR exit. · 7ddfce85
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117103.
      
      Reviewed by Geoffrey Garen.
      
      * dfg/DFGOSRExitCompilerCommon.cpp:
      (JSC::DFG::reifyInlinedCallFrames):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153207 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      7ddfce85
    • oliver@apple.com's avatar
      fourthTier: all cached put_by_id transitions, even ones that weren't inlined... · a152471c
      oliver@apple.com authored
      fourthTier: all cached put_by_id transitions, even ones that weren't inlined by the DFG, should be propagated by the GC
      https://bugs.webkit.org/show_bug.cgi?id=117170
      
      Reviewed by Mark Hahnenberg.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::visitAggregate):
      (JSC::CodeBlock::propagateTransitions):
      (JSC):
      (JSC::CodeBlock::determineLiveness):
      (JSC::CodeBlock::visitWeakReferences):
      (JSC::CodeBlock::finalizeUnconditionally):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      * bytecode/PolymorphicPutByIdList.h:
      (JSC):
      (PutByIdAccess):
      (PolymorphicPutByIdList):
      * bytecode/StructureStubInfo.h:
      (StructureStubInfo):
      * jit/JITCode.h:
      (JSC::JITCode::couldBeInterpreted):
      (JITCode):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153206 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      a152471c
    • oliver@apple.com's avatar
      fourthTier: Get rid of StructureStubInfo::bytecodeIndex · 6a8125ee
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117127
      
      Reviewed by Mark Hahnenberg.
      
      StructureStubInfo already has a CodeOrigin field, which also has a bytecodeIndex.
      It makes sense to just always use the CodeOrigin.
      
      * bytecode/StructureStubInfo.h:
      (StructureStubInfo):
      (JSC::getStructureStubInfoBytecodeIndex):
      * jit/JIT.cpp:
      (JSC::PropertyStubCompilationInfo::copyToStubInfo):
      * jit/JIT.h:
      (JSC::JIT::compileGetByIdProto):
      (JSC::JIT::compileGetByIdSelfList):
      (JSC::JIT::compileGetByIdProtoList):
      (JSC::JIT::compileGetByIdChainList):
      (JSC::JIT::compileGetByIdChain):
      (JSC::JIT::compilePutByIdTransition):
      * jit/JITPropertyAccess.cpp:
      (JSC::JIT::privateCompilePutByIdTransition):
      * jit/JITPropertyAccess32_64.cpp:
      (JSC::JIT::privateCompilePutByIdTransition):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153205 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      6a8125ee
    • oliver@apple.com's avatar
      fourthTier: Fix some minor issues in the DFG's profiling of heap accesses · 1622cae4
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=113010
      
      Reviewed by Goeffrey Garen.
      
      Carefully merge r146669 from trunk. This required some fiddling since it
      wasn't a clean apply.
      
      Original changelog:
      
          1) If a CodeBlock gets jettisoned by GC, we should count the exit sites.
      
          2) If a CodeBlock clears a structure stub during GC, it should record this, and
          the DFG should prefer to not inline that access (i.e. treat it as if it had an
          exit site).
      
          3) If a PutById was seen by the baseline JIT, and the JIT attempted to cache it,
          but it chose not to, then assume that it will take slow path.
      
          4) If we frequently exited because of a structure check on a weak constant,
          don't try to inline that access in the future.
      
          5) Treat all exits that were counted as being frequent.
      
          81% speed-up on Octane/gbemu. Small speed-ups elsewhere, and no regressions.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::finalizeUnconditionally):
      (JSC):
      (JSC::CodeBlock::resetStubDuringGCInternal):
      (JSC::CodeBlock::reoptimize):
      (JSC::CodeBlock::jettison):
      (JSC::ProgramCodeBlock::jettisonImpl):
      (JSC::EvalCodeBlock::jettisonImpl):
      (JSC::FunctionCodeBlock::jettisonImpl):
      (JSC::CodeBlock::tallyFrequentExitSites):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      (JSC::CodeBlock::tallyFrequentExitSites):
      (ProgramCodeBlock):
      (EvalCodeBlock):
      (FunctionCodeBlock):
      * bytecode/GetByIdStatus.cpp:
      (JSC::GetByIdStatus::computeFor):
      * bytecode/PutByIdStatus.cpp:
      (JSC::PutByIdStatus::computeFor):
      * bytecode/StructureStubInfo.h:
      (JSC::StructureStubInfo::StructureStubInfo):
      (StructureStubInfo):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::handleGetById):
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGOSRExitBase.cpp:
      (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSiteSlow):
      * dfg/DFGOSRExitBase.h:
      (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSite):
      (OSRExitBase):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * runtime/Options.h:
      (JSC):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153204 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      1622cae4
    • oliver@apple.com's avatar
      fourthTier: convert more fast/js/dfg-* tests to wait for the concurrent JIT · 382f5620
      oliver@apple.com authored
      Rubber stamped by Mark Hahnenberg.
      
      * fast/js/dfg-arguments-alias-one-block-overwrite-expected.txt:
      * fast/js/dfg-arguments-out-of-bounds-expected.txt:
      * fast/js/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int-expected.txt:
      * fast/js/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers-expected.txt:
      * fast/js/dfg-array-length-dead-expected.txt:
      * fast/js/dfg-array-pop-side-effects-expected.txt:
      * fast/js/resources/js-test-pre.js:
      (testFailed):
      (dfgIncrement):
      (isSuccessfullyParsed):
      * fast/js/script-tests/dfg-arguments-alias-one-block-overwrite.js:
      * fast/js/script-tests/dfg-arguments-out-of-bounds.js:
      * fast/js/script-tests/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int.js:
      * fast/js/script-tests/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers.js:
      * fast/js/script-tests/dfg-array-length-dead.js:
      * fast/js/script-tests/dfg-array-pop-side-effects.js:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153203 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      382f5620
    • oliver@apple.com's avatar
      fourthTier: Remove CodeOrigin::valueProfileOffset since it was only needed for op_call_put_result. · bc2930b5
      oliver@apple.com authored
      Rubber stamped by Mark Hahnenberg.
      
      * bytecode/CodeOrigin.h:
      (CodeOrigin):
      (JSC::CodeOrigin::CodeOrigin):
      (JSC::CodeOrigin::isSet):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::currentCodeOrigin):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::valueProfileFor):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153202 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      bc2930b5
    • oliver@apple.com's avatar
      fourthTier: Remove finalDestinationOrIgnored since it isn't called anymore. · e64543a0
      oliver@apple.com authored
      Rubber stamped by Mark Hahnenberg.
      
      * bytecompiler/BytecodeGenerator.h:
      (BytecodeGenerator):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153201 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      e64543a0
    • oliver@apple.com's avatar
      fourthTier: get rid of op_call_put_result · cf0e6c40
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117047
      
      Reviewed by Gavin Barraclough.
      
      Work in progress. This still makes like 20 tests crash.
      
      op_call_put_result is an oddball. Its semantics are that it takes the return
      value of a call instruction, which is set aside in regT0/regT1, and places them
      into some stack slot. This is weird since there is an implicit contract with the
      preceding bytecode instruction, and it's even weirder since it means that it
      doesn't make sense to jump to it; for example OSR exit from the preceding call
      instruction must make sure to jump over the op_call_put_result.
      
      So this patch gets rid of op_call_put_result:
      
      - In bytecode, all calls return a value and we always allocate a temporary for
        that value even if it isn't used.
      
      - The LLInt does the return value saving as part of dispatchAfterCall().
      
      - The JIT and DFG do the return value saving as part of normal code generation.
        The DFG already did the right thing.
      
      - DFG->JIT OSR exit in the case of inlining will make the return PC's point at
        the CallLinkInfo::callReturnLocation, rather than the machine PC associated
        with the op_call_put_result instruction.
      
      - Tons of code gets removed. The DFG had to track whether or not a call had a
        return value in a bunch of places. It had to track the fact that we would
        exit to after the op_call_put_result. It was a mess. That mess is now gone.
      
      * bytecode/CallLinkStatus.cpp:
      (JSC::CallLinkStatus::computeFromLLInt):
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::printCallOp):
      (JSC::CodeBlock::dumpArrayProfiling):
      (JSC::CodeBlock::dumpBytecode):
      (JSC::CodeBlock::CodeBlock):
      * bytecode/CodeBlock.h:
      * bytecode/Opcode.h:
      (JSC):
      (JSC::padOpcodeName):
      * bytecompiler/BytecodeGenerator.cpp:
      (JSC::BytecodeGenerator::emitCall):
      (JSC::BytecodeGenerator::emitCallVarargs):
      (JSC::BytecodeGenerator::emitConstruct):
      * bytecompiler/NodesCodegen.cpp:
      (JSC::NewExprNode::emitBytecode):
      (JSC::FunctionCallValueNode::emitBytecode):
      (JSC::FunctionCallResolveNode::emitBytecode):
      (JSC::FunctionCallBracketNode::emitBytecode):
      (JSC::FunctionCallDotNode::emitBytecode):
      (JSC::CallFunctionCallDotNode::emitBytecode):
      (JSC::ApplyFunctionCallDotNode::emitBytecode):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::ByteCodeParser):
      (ByteCodeParser):
      (JSC::DFG::ByteCodeParser::currentCodeOrigin):
      (JSC::DFG::ByteCodeParser::addCall):
      (JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit):
      (JSC::DFG::ByteCodeParser::getPrediction):
      (JSC::DFG::ByteCodeParser::handleCall):
      (JSC::DFG::ByteCodeParser::handleInlining):
      (JSC::DFG::ByteCodeParser::handleMinMax):
      (JSC::DFG::ByteCodeParser::handleIntrinsic):
      (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGCapabilities.cpp:
      (JSC::DFG::capabilityLevel):
      * dfg/DFGOSRExitCompiler.cpp:
      * dfg/DFGOSRExitCompilerCommon.cpp:
      (JSC::DFG::reifyInlinedCallFrames):
      * jit/JIT.cpp:
      (JSC::JIT::privateCompileMainPass):
      * jit/JIT.h:
      (JIT):
      * jit/JITCall.cpp:
      (JSC::JIT::emitPutCallResult):
      (JSC::JIT::compileLoadVarargs):
      (JSC::JIT::compileCallEval):
      (JSC::JIT::compileCallEvalSlowCase):
      (JSC::JIT::compileOpCall):
      (JSC::JIT::compileOpCallSlowCase):
      (JSC::JIT::emit_op_call):
      (JSC):
      (JSC::JIT::emit_op_call_eval):
      (JSC::JIT::emit_op_call_varargs):
      (JSC::JIT::emit_op_construct):
      (JSC::JIT::emitSlow_op_call):
      (JSC::JIT::emitSlow_op_call_eval):
      (JSC::JIT::emitSlow_op_call_varargs):
      (JSC::JIT::emitSlow_op_construct):
      * jit/JITCall32_64.cpp:
      (JSC::JIT::emitPutCallResult):
      (JSC::JIT::compileLoadVarargs):
      (JSC::JIT::compileCallEval):
      (JSC::JIT::compileCallEvalSlowCase):
      (JSC::JIT::compileOpCall):
      (JSC::JIT::compileOpCallSlowCase):
      * jit/JITOpcodes.cpp:
      (JSC):
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::genericCall):
      (JSC::LLInt::LLINT_SLOW_PATH_DECL):
      * llint/LowLevelInterpreter.cpp:
      (JSC::CLoop::execute):
      * llint/LowLevelInterpreter32_64.asm:
      * llint/LowLevelInterpreter64.asm:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153200 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      cf0e6c40
    • oliver@apple.com's avatar
      fourthTier: LLInt shouldn't store an offset call PC during op_call-like calls · dc48dc36
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117048
      
      Reviewed by Mark Hahnenberg.
      
      This just makes everything consistent in the LLInt: anytime any op calls out,
      it stores its PC and never the next op's PC.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::dumpBytecode):
      (JSC::CodeBlock::linkIncomingCall):
      (JSC::CodeBlock::bytecodeOffset):
      * bytecode/CodeBlock.h:
      * bytecode/Opcode.h:
      (JSC::padOpcodeName):
      * bytecompiler/BytecodeGenerator.cpp:
      (JSC::BytecodeGenerator::emitCallVarargs):
      * llint/LLIntExceptions.cpp:
      (JSC::LLInt::interpreterThrowInCaller):
      (JSC::LLInt::returnToThrow):
      (JSC::LLInt::callToThrow):
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::LLINT_SLOW_PATH_DECL):
      * llint/LowLevelInterpreter.asm:
      * llint/LowLevelInterpreter.cpp:
      (JSC::CLoop::execute):
      * llint/LowLevelInterpreter32_64.asm:
      * llint/LowLevelInterpreter64.asm:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153199 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      dc48dc36
    • oliver@apple.com's avatar
      fourthTier: FTL should support ArithAbs · 0452e56c
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116890
      
      Reviewed by Oliver Hunt.
      
      Implements ArithAbs in the FTL, and cleans up the DFG implementation. The
      DFG implementation was previously doing zero extensions manually when it
      is probably better to just use StrictInt32Operand instead.
      
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLIntrinsicRepository.h:
      (FTL):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileArithAbs):
      (LowerDFGToLLVM):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::doubleAbs):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153198 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      0452e56c
    • oliver@apple.com's avatar
      fourthTier: Misc JIT probe enhacements. · c3a5b8c5
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116586.
      
      Reviewed by Michael Saboff.
      
      1. Added JIT probe support for ARMv7 and traditional ARM.
         Built and tested on ARMv7. ARM version not tested nor built.
      2. Fix the following bugs in the X86 and X86_64 probes:
         a. Cannot assume that the stack pointer is already aligned when
            we push args for the probe. Instead, we ensure the stack
            alignment at runtime when we set up the probe call.
            This is now done in the ctiMasmProbeTrampoline.
         b. On return, the user probe function may have altered the stack
            pointer value to be restored. Previously, if the sp restore value
            points to some of the other register restore values in the
            ProbeContext record, we will fail to return from the probe having
            those user specified value as we're expected to do.
            This is now fixed.
      3. Rearranged the X86/X86_64 registers order to organize them like gdb
         expects on X86_64.
      4. We also now preserve the condition code registers.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * assembler/ARMAssembler.h:
      * assembler/ARMv7Assembler.h:
      (ARMRegisters):
      * assembler/MacroAssemblerARM.cpp:
      (JSC::isVFPPresent):
      (JSC::MacroAssemblerARM::ProbeContext::dumpCPURegisters):
      (JSC::MacroAssemblerARM::ProbeContext::dump):
      (JSC::MacroAssemblerARM::probe):
      * assembler/MacroAssemblerARM.h:
      (MacroAssemblerARM):
      (CPUState):
      (ProbeContext):
      (JSC::MacroAssemblerARM::trustedImm32FromPtr):
      * assembler/MacroAssemblerARMv7.h:
      (MacroAssemblerARMv7):
      (CPUState):
      (ProbeContext):
      (JSC::MacroAssemblerARMv7::trustedImm32FromPtr):
      * assembler/MacroAssemblerX86.h:
      (MacroAssemblerX86):
      (JSC::MacroAssemblerX86::probe):
      * assembler/MacroAssemblerX86Common.cpp:
      (JSC::MacroAssemblerX86Common::ProbeContext::dumpCPURegisters):
      * assembler/MacroAssemblerX86_64.h:
      (JSC::MacroAssemblerX86_64::probe):
      * assembler/X86Assembler.h:
      * config.h:
      * jit/JITStubsARM.h:
      * jit/JITStubsARMv7.h:
      * jit/JITStubsX86.h:
      * jit/JITStubsX86Common.h:
      * jit/JITStubsX86_64.h:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153197 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      c3a5b8c5
    • oliver@apple.com's avatar
      fourthTier: FTL should call masqueradesAsUndefinedWatchpointIfIsStillValid()... · 34c16e27
      oliver@apple.com authored
      fourthTier: FTL should call masqueradesAsUndefinedWatchpointIfIsStillValid() in all of the places where it currently calls masqueradesAsUndefinedWatchpointIsStillValid()
      https://bugs.webkit.org/show_bug.cgi?id=116892
      
      Reviewed by Oliver Hunt.
      
      All of those places mean to plant the watchpoint if it's still valid.
      
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
      (JSC::FTL::LowerDFGToLLVM::speculateNonNullObject):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153196 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      34c16e27
    • oliver@apple.com's avatar
      fourthTier: convert more fast/js/dfg-* tests to wait for the concurrent JIT · 920c78dc
      oliver@apple.com authored
      Rubber stamped by Oliver Hunt.
      
      * fast/js/dfg-arguments-alias-activation-expected.txt:
      * fast/js/dfg-arguments-alias-activation.html:
      * fast/js/dfg-arguments-alias-expected.txt:
      * fast/js/script-tests/dfg-arguments-alias.js:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153195 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      920c78dc
    • oliver@apple.com's avatar
      fourthTier: FTL should support ArithMin/ArithMax · 61cccb84
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116885
      
      Reviewed by Oliver Hunt.
      
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::compileArithMinOrMax):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153194 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      61cccb84
    • oliver@apple.com's avatar
      fourthTier: convert more fast/js/dfg-* tests to wait for the concurrent JIT · bd4b0fce
      oliver@apple.com authored
      Rubber stamped by Oliver Hunt.
      
      * fast/js/dfg-abs-backwards-propagation-expected.txt:
      * fast/js/dfg-add-not-number-expected.txt:
      * fast/js/dfg-arguments-alias-escape-expected.txt:
      * fast/js/resources/js-test-pre.js:
      (dfgCompiled):
      (dfgIncrement):
      * fast/js/script-tests/dfg-abs-backwards-propagation.js:
      * fast/js/script-tests/dfg-add-not-number.js:
      * fast/js/script-tests/dfg-arguments-alias-escape.js:
      * fast/js/script-tests/dfg-arguments-alias-one-block-osr-exit.js:
      * fast/js/script-tests/dfg-arguments-alias-one-block-overwrite-arguments.js:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153193 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      bd4b0fce
    • oliver@apple.com's avatar
      fourthTier: fast/js should have a way of running tests long enough to wait for... · 52619b34
      oliver@apple.com authored
      fourthTier: fast/js should have a way of running tests long enough to wait for the concurrent JIT to tier up
      https://bugs.webkit.org/show_bug.cgi?id=116878
      
      Reviewed by Oliver Hunt.
      
      This adds three things to js-test-pre and uses them in one representative test:
      
      silentTestPass: If you set this to true, then testPassed() won't print anything, and will instead just have
          isSuccessfullyParsed() print a message saying that some tests passed silently. This allows tests to call
          shouldBe() and friends in a loop whose running time is dependent on concurrent JIT behavior, and still
          be sure that the resulting test will be deterministic.
      
      noInline(): If testRunner is present, disable inlining of the relevant function.
      
      dfgIncrement({f:function, i:index, n:limit}): Returns index either if index < limit, or if the function is
          DFG compiled. Otherwise, if index >= limit and the function isn't DFG compiled, return 0. This means
          that the 'i++' in the fast/js/dfg-* warm-up loops can be replaced with:
      
          i = dfgIncrement({f:<function you're interested in>, i:i + 1, n:<some number smaller than the loop condition>)
      
          This has the effect of having the loop repeat the first 'n' iterations until the function is DFG
          compiled. See the modified test, where we do n:100 and the loop condition is i < 200. So the loop will
          repeat the first 100 iterations until the function is DFG compiled and will only do the last 100
          iterations once DFG compilation kicks in.
      
      * fast/js/dfg-arguments-osr-exit-multiple-blocks-expected.txt:
      * fast/js/resources/js-test-pre.js:
      (testPassed):
      (dfgIncrement):
      (noInline):
      (isSuccessfullyParsed):
      * fast/js/script-tests/dfg-arguments-osr-exit-multiple-blocks.js:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153192 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      52619b34
    • oliver@apple.com's avatar
      fourthTier: testRunner should have a way of disabling inlining of functions · 4e67ae52
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116875
      
      Reviewed by Mark Hahnenberg.
      
      Source/JavaScriptCore:
      
      * API/JSCTestRunnerUtils.cpp:
      (JSC::getExecutable):
      (JSC):
      (JSC::numberOfDFGCompiles):
      (JSC::setNeverInline):
      * API/JSCTestRunnerUtils.h:
      (JSC):
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::dumpAssumingJITType):
      * dfg/DFGCapabilities.cpp:
      (JSC::DFG::mightInlineFunctionForCall):
      (JSC::DFG::mightInlineFunctionForClosureCall):
      (JSC::DFG::mightInlineFunctionForConstruct):
      * runtime/Executable.h:
      (JSC::ScriptExecutable::ScriptExecutable):
      (ScriptExecutable):
      (JSC::ScriptExecutable::setNeverInline):
      (JSC::ScriptExecutable::neverInline):
      (JSC::ScriptExecutable::isInliningCandidate):
      
      Tools:
      
      * DumpRenderTree/TestRunner.cpp:
      (neverInlineFunction):
      (TestRunner::staticFunctions):
      
      LayoutTests:
      
      * fast/js/script-tests/dfg-min-max.js:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153191 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      4e67ae52
    • oliver@apple.com's avatar
      fourthTier: FTL should support ArithMod · d533b183
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116792
      
      Reviewed by Oliver Hunt.
      
      * ftl/FTLAbbreviations.h:
      (JSC::FTL::buildFRem):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileArithMod):
      (LowerDFGToLLVM):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::doubleRem):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153190 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      d533b183
    • oliver@apple.com's avatar
      fourthTier: It should be possible to record heap operations (both FastMalloc and JSC GC) · a03796ac
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116848
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      Record GC heap operations if ENABLE(ALLOCATION_LOGGING).
      
      * API/JSManagedValue.mm:
      * dfg/DFGOperations.cpp:
      * heap/Heap.cpp:
      (JSC::Heap::collect):
      * heap/Heap.h:
      (Heap):
      (JSC::Heap::allocateWithNormalDestructor):
      (JSC::Heap::allocateWithImmortalStructureDestructor):
      (JSC::Heap::allocateWithoutDestructor):
      (JSC::Heap::tryAllocateStorage):
      (JSC::Heap::tryReallocateStorage):
      (JSC):
      (JSC::Heap::ascribeOwner):
      * heap/SlotVisitor.cpp:
      (JSC::SlotVisitor::append):
      (JSC::SlotVisitor::internalAppend):
      * heap/SlotVisitor.h:
      (SlotVisitor):
      * heap/SlotVisitorInlines.h:
      (JSC::SlotVisitor::append):
      (JSC::SlotVisitor::appendUnbarrieredPointer):
      (JSC::SlotVisitor::appendUnbarrieredValue):
      (JSC::SlotVisitor::appendUnbarrieredWeak):
      (JSC::SlotVisitor::internalAppend):
      (JSC):
      (JSC::SlotVisitor::appendValues):
      * jit/JITWriteBarrier.h:
      (JSC::SlotVisitor::append):
      * llint/LLIntCommon.h:
      * runtime/Butterfly.h:
      (Butterfly):
      * runtime/ButterflyInlines.h:
      (JSC::Butterfly::createUninitialized):
      (JSC::Butterfly::create):
      (JSC::Butterfly::growPropertyStorage):
      (JSC::Butterfly::createOrGrowArrayRight):
      (JSC):
      (JSC::Butterfly::growArrayRight):
      (JSC::Butterfly::resizeArray):
      * runtime/JSArray.cpp:
      (JSC::createArrayButterflyInDictionaryIndexingMode):
      (JSC::JSArray::unshiftCountSlowCase):
      * runtime/JSArray.h:
      (JSC::createContiguousArrayButterfly):
      (JSC::createArrayButterfly):
      (JSC):
      (JSC::JSArray::create):
      (JSC::JSArray::tryCreateUninitialized):
      * runtime/JSObject.cpp:
      (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists):
      (JSC::JSObject::createInitialIndexedStorage):
      (JSC::JSObject::createArrayStorage):
      (JSC::JSObject::constructConvertedArrayStorageWithoutCopyingElements):
      (JSC::JSObject::increaseVectorLength):
      (JSC::JSObject::ensureLengthSlow):
      (JSC::JSObject::growOutOfLineStorage):
      * runtime/JSObject.h:
      (JSC::JSObject::JSObject):
      * runtime/Operations.h:
      * runtime/RegExpMatchesArray.cpp:
      (JSC::RegExpMatchesArray::create):
      * runtime/StructureInlines.h:
      (JSC):
      * runtime/WriteBarrier.h:
      (JSC):
      
      Source/WTF:
      
      Reviewed by Mark Hahnenberg.
      
      * WTF.xcodeproj/project.pbxproj:
      * wtf/DataLog.cpp:
      (WTF):
      (WTF::initializeLogFileOnce):
      * wtf/FastMalloc.cpp:
      (WTF::TCMalloc_ThreadCache::CreateCacheIfNecessary):
      * wtf/Platform.h:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153189 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      a03796ac
    • oliver@apple.com's avatar
      fourthTier: testRunner should be able to tell you if a function is DFG compiled · 37172f80
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116847
      
      Reviewed by Mark Hahnenberg.
      
      Source/JavaScriptCore:
      
      * API/JSCTestRunnerUtils.cpp: Added.
      (JSC):
      (JSC::numberOfDFGCompiles):
      * API/JSCTestRunnerUtils.h: Added.
      (JSC):
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::numberOfDFGCompiles):
      (JSC):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      * dfg/DFGWorklist.cpp:
      (JSC::DFG::Worklist::runThread):
      * runtime/Executable.h:
      (JSC):
      * runtime/JSFunctionInlines.h: Added.
      (JSC):
      (JSC::JSFunction::JSFunction):
      (JSC::JSFunction::jsExecutable):
      (JSC::JSFunction::isHostFunction):
      (JSC::JSFunction::nativeFunction):
      (JSC::JSFunction::nativeConstructor):
      * runtime/Operations.h:
      
      Source/WebCore:
      
      Bail early if we're in the compilation thread. This is only relevant for
      debug dumps.
      
      No new tests becase no new behavior.
      
      * loader/cache/CachedScript.cpp:
      (WebCore::CachedScript::script):
      
      Tools:
      
      * DumpRenderTree/TestRunner.cpp:
      (numberOfDFGCompiles):
      (TestRunner::staticFunctions):
      
      LayoutTests:
      
      * fast/js/script-tests/dfg-min-max.js:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153188 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      37172f80
    • oliver@apple.com's avatar
      fourthTier: DFG ArithMod should have the !nodeUsedAsNumber optimizations that ArithDiv has · 34a59ca9
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116841
      
      Reviewed by Mark Hahnenberg.
      
      Source/JavaScriptCore:
      
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compileArithMod):
      
      LayoutTests:
      
      * fast/js/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc-expected.txt: Added.
      * fast/js/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc.html: Added.
      * fast/js/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc-expected.txt: Added.
      * fast/js/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc.html: Added.
      * fast/js/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc-expected.txt: Added.
      * fast/js/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc.html: Added.
      * fast/js/jsc-test-list:
      * fast/js/script-tests/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc.js: Added.
      (foo):
      * fast/js/script-tests/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc.js: Added.
      (foo):
      * fast/js/script-tests/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc.js: Added.
      (foo):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153187 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      34a59ca9
    • oliver@apple.com's avatar
      fourthTier: clean up ArithDiv/ArithMod in the DFG · f4443a7b
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116793
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      This makes ArithDiv and ArithMod behave similarly, and moves both of their
      implementations entirely into DFGSpeculativeJIT.cpp into methods named like
      the ones for ArithSub/ArithMul.
      
      Specifically, ArithMod now uses the wrap-in-conversion-nodes idiom that
      ArithDiv used for platforms that don't support integer division. Previously
      ArithMod had its own int-to-double and double-to-int conversions for this
      purpose.
      
      As well, this gets rid of confusing methods like compileSoftModulo() (which
      did no such thing, there wasn't anything "soft" about it) and
      compileIntegerArithDivForX86() (which is accurately named but we don't use
      the platform-specific method convention anywhere else).
      
      Finally, this takes the optimized power-of-two modulo operation that was
      previously only for ARMv7s, and makes it available for all platforms. Well,
      sort of: I actually rewrote it to do what latest LLVM appears to do, which
      is a crazy straight-line power-of-2 modulo based on a combination of shifts,
      ands, additions, and subtractions. I can kind of understand it well enough
      to see that it complies with both C and JS power-of-2 modulo semantics. I've
      also confirmed that it does by testing (hence the corresponding improvements
      to one of the division tests). But, I don't claim to know exactly how this
      code works other than to observe that it is super leet.
      
      Overall, this patch has the effect of killing some code (no more hackish
      int-to-double conversions in ArithMod), making some optimization work on
      more platforms, and making the compiler less confusing by doing more things
      with the same idiom.
      
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::executeEffects):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGSpeculativeJIT.cpp:
      (DFG):
      (JSC::DFG::SpeculativeJIT::compileArithDiv):
      (JSC::DFG::SpeculativeJIT::compileArithMod):
      * dfg/DFGSpeculativeJIT.h:
      (SpeculativeJIT):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      
      LayoutTests:
      
      Reviewed by Mark Hahnenberg.
      
      * fast/js/script-tests/integer-division-neg2tothe32-by-neg1.js:
      (myModBy2):
      (myModBy1073741824):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153186 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      f4443a7b
    • oliver@apple.com's avatar
      fourthTier: cti_optimize shouldn't allow GCs to get in the way of it seeing... · 7033017e
      oliver@apple.com authored
      fourthTier: cti_optimize shouldn't allow GCs to get in the way of it seeing the state of its CodeBlock
      https://bugs.webkit.org/show_bug.cgi?id=116748
      
      Reviewed by Geoffrey Garen.
      
      This fixes the following race: an optimized version of our code block could be installed
      by the GC just as we return from completeAllReadyPlansForVM(), leading us to believe
      that the code block isn't ready yet even though it is. Currently this triggers a
      RELEASE_ASSERT. We could remove that assertion, but then this case would lead to the
      code in question entering into optimizeAfterWarmUp mode. That seems pretty wasteful.
      
      Fix the bug, and hopefully close the door on these bugs for a while, by wrapping
      cti_optimize in a DeferGC. There is little downside to doing so since the only
      "allocations" in cti_optimize are the ones where we inform the GC about extra memory
      usage.
      
      I had a more comprehensive solution (see the bug, "work in progress" patch) but that
      one involved adding *more* raciness to cti_optimize. I decided that was a less good
      approach once I came to appreciate the simplicity of just using DeferGC.
      
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153185 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      7033017e
    • oliver@apple.com's avatar
      fourthTier: FTL should support ArithDiv · dd372b7a
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116771
      
      Reviewed by Oliver Hunt.
      
      * ftl/FTLAbbreviations.h:
      (JSC::FTL::buildDiv):
      (JSC::FTL::buildRem):
      (JSC::FTL::buildFDiv):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLCommonValues.cpp:
      (JSC::FTL::CommonValues::CommonValues):
      * ftl/FTLCommonValues.h:
      (CommonValues):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileArithMul):
      (JSC::FTL::LowerDFGToLLVM::compileArithDiv):
      (LowerDFGToLLVM):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::div):
      (JSC::FTL::Output::rem):
      (JSC::FTL::Output::doubleDiv):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153184 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      dd372b7a
    • oliver@apple.com's avatar
      fourthTier: Remove Interpreter::retrieveLastCaller(). · e0b15eec
      oliver@apple.com authored
      This merge is complicated by the trunk js stack reporting logic.
      
      Remove Interpreter::retrieveLastCaller().
      https://bugs.webkit.org/show_bug.cgi?id=116753.
      
      Reviewed by Geoffrey Garen.
      
      This is part of the refactoring effort to get rid of functions walking
      the JS stack in their own way.
      
      ../JavaScriptCore:
      
      * API/JSContextRef.cpp:
      (JSContextCreateBacktrace):
      * interpreter/CallFrame.cpp:
      * interpreter/Interpreter.cpp:
      (JSC::Interpreter::Interpreter):
      (JSC::Interpreter::getStackTrace):
      (JSC::Interpreter::addStackTraceIfNecessary):
      * interpreter/Interpreter.h:
      (StackFrame):
      (JSC::StackFrame::StackFrame):
      (Interpreter):
      * jsc.cpp:
      (functionJSCStack):
      * profiler/ProfileGenerator.cpp:
      (JSC::ProfileGenerator::addParentForConsoleStart):
      
      ../WebCore:
      
      No new tests.
      
      * bindings/js/JSXMLHttpRequestCustom.cpp:
      (WebCore::JSXMLHttpRequest::send):
      * bindings/js/ScriptCallStackFactory.cpp:
      (WebCore::createScriptCallStack):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153183 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      e0b15eec
    • oliver@apple.com's avatar
      fourthTier: FTL boolify should support ObjectOrOtherUse · fdbb0868
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116741
      
      Reviewed by Geoffrey Garen.
      
      Just reusing what was already there in equalNullOrUndefined(). Note that we will
      sometimes generate some redundant IR - like having some spurious bitNot's in
      places - but it's safe to assume that LLVM will simplify those, and that it won't
      be the longest pole in the tent for compile times.
      
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileCompareEqConstant):
      (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEqConstant):
      (JSC::FTL::LowerDFGToLLVM::boolify):
      (JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153182 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      fdbb0868
    • oliver@apple.com's avatar
      fourthTier: FTL should support LogicalNot and Branch on Int32 and Number · ec61ab2d
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116739
      
      Reviewed by Gavin Barraclough.
      
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileLogicalNot):
      (JSC::FTL::LowerDFGToLLVM::compileBranch):
      (JSC::FTL::LowerDFGToLLVM::boolify):
      (LowerDFGToLLVM):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::isZero32):
      (JSC::FTL::Output::notZero32):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153181 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      ec61ab2d
    • 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: rationalize DFG::CapabilityLevel and DFGCapabilities.[h|cpp] · 07f66d4a
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116696
      
      Reviewed by Sam Weinig.
      
      Make it so that all capability calculation is funneled through one function, which tells
      you everything you wanted to know: can it be inlined, and can it be compiled.
      
      This work will help with https://bugs.webkit.org/show_bug.cgi?id=116557, since now the
      JIT has a fairly authoritative answer to the "can it be inlined" question.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::CodeBlock):
      (JSC::ProgramCodeBlock::capabilityLevelInternal):
      (JSC::EvalCodeBlock::capabilityLevelInternal):
      (JSC::FunctionCodeBlock::capabilityLevelInternal):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      (JSC::CodeBlock::capabilityLevel):
      (JSC::CodeBlock::capabilityLevelState):
      (ProgramCodeBlock):
      (EvalCodeBlock):
      (FunctionCodeBlock):
      * dfg/DFGCapabilities.cpp:
      (JSC::DFG::debugFail):
      (DFG):
      (JSC::DFG::canInlineResolveOperations):
      (JSC::DFG::capabilityLevel):
      * dfg/DFGCapabilities.h:
      (DFG):
      (JSC::DFG::capabilityLevel):
      (JSC::DFG::evalCapabilityLevel):
      (JSC::DFG::programCapabilityLevel):
      (JSC::DFG::functionForCallCapabilityLevel):
      (JSC::DFG::functionForConstructCapabilityLevel):
      (JSC::DFG::canInlineFunctionForCall):
      (JSC::DFG::canInlineFunctionForClosureCall):
      (JSC::DFG::canInlineFunctionForConstruct):
      * dfg/DFGCommon.h:
      (JSC::DFG::canCompile):
      (DFG):
      (JSC::DFG::canInline):
      (JSC::DFG::leastUpperBound):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * jit/JIT.cpp:
      (JSC::JIT::privateCompile):
      * jit/JITPropertyAccess.cpp:
      (JSC::JIT::privateCompilePutByIdTransition):
      * jit/JITPropertyAccess32_64.cpp:
      (JSC::JIT::privateCompilePutByIdTransition):
      * tools/CodeProfile.cpp:
      (JSC::CodeProfile::sample):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153179 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      07f66d4a