1. 24 Jul, 2013 40 commits
    • oliver@apple.com's avatar
      fourthTier: DFG shouldn't exit just because a String GetByVal went out-of-bounds · 211b3bec
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117906
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      This does the obvious thing, but also makes sure that out-of-bounds accesses
      don't fall off into a C call, but try to do the fast thing if the prototype
      chain is sane. We ought to probably do this for other array accesses in the
      future, as well, since it's so darn easy.
      
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::executeEffects):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGOperations.cpp:
      * dfg/DFGOperations.h:
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::callOperation):
      * runtime/JSGlobalObject.cpp:
      (JSC::JSGlobalObject::objectPrototypeIsSane):
      (JSC):
      (JSC::JSGlobalObject::arrayPrototypeChainIsSane):
      (JSC::JSGlobalObject::stringPrototypeChainIsSane):
      * runtime/JSGlobalObject.h:
      (JSGlobalObject):
      
      LayoutTests:
      
      Reviewed by Mark Hahnenberg.
      
      The out-of-bounds benchmark that isn't insane speeds up by 22x in this
      patch.
      
      * fast/js/regress/script-tests/string-get-by-val-out-of-bounds-insane.js: Added.
      (foo):
      * fast/js/regress/script-tests/string-get-by-val-out-of-bounds.js: Added.
      (foo):
      * fast/js/regress/string-get-by-val-out-of-bounds-expected.txt: Added.
      * fast/js/regress/string-get-by-val-out-of-bounds-insane-expected.txt: Added.
      * fast/js/regress/string-get-by-val-out-of-bounds-insane.html: Added.
      * fast/js/regress/string-get-by-val-out-of-bounds.html: Added.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153244 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      211b3bec
    • oliver@apple.com's avatar
      fourthTier: GC's put_by_id transition fixpoint should converge more quickly · c0a31d7e
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117912
      
      Reviewed by Mark Hahnenberg.
      
      This was a rookie mistake. The GC does a classic forward data flow fixpoint. These work well so long as you
      iterate the program in program order, or at least something close to program order. Because I enjoy reverse
      loops ("while (n--) blah"), I ended up iterating in *reverse* of program order which ensured worst-case
      pathologies every single time. And unsurprisingly, this slowed down a program, namely pdfjs.
      
      Flipping the loops to iterate forward fixes a 90% regression in Octane/pdfjs and is otherwise neutral.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::propagateTransitions):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153243 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      c0a31d7e
    • oliver@apple.com's avatar
      fourthTier: DFG should CSE MakeRope · c2eda9aa
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117905
      
      Source/JavaScriptCore:
      
      Reviewed by Geoffrey Garen.
      
      Adds MakeRope to the CSE phase and removes the comment that says that
      we could do it but aren't doing it.
      
      Also fixed SpeculatedType dumping so that if you have a Cell type then
      it just prints "Cell" and if you just have Object then it just prints
      "Object", instead of printing the long list of types.
      
      * bytecode/SpeculatedType.cpp:
      (JSC::dumpSpeculation):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::performNodeCSE):
      
      LayoutTests:
      
      Reviewed by Geoffrey Garen.
      
      This benchmark speeds up by 50%.
      
      * fast/js/regress/make-rope-cse-expected.txt: Added.
      * fast/js/regress/make-rope-cse.html: Added.
      * fast/js/regress/script-tests/make-rope-cse.js: Added.
      (foo):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153242 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      c2eda9aa
    • oliver@apple.com's avatar
      fourthTier: DFG should't exit just because it GetByVal'd a big character · 63af2d44
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117899
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      Add a slow path. Also clarify handling of GetByVal in PutStructure elimination.
      Previously it would fail due to canExit() but now we can also fail because
      GetByVal(String) can allocate. Just make it so GetByVal is totally poisoned, in
      a very explicit way.
      
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::putStructureStoreElimination):
      * dfg/DFGOperations.cpp:
      * dfg/DFGOperations.h:
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::callOperation):
      (SpeculativeJIT):
      
      LayoutTests:
      
      Reviewed by Mark Hahnenberg.
      
      This benchmark speeds up by 3x.
      
      * fast/js/regress/script-tests/string-get-by-val-big-char.js: Added.
      (foo):
      * fast/js/regress/string-get-by-val-big-char-expected.txt: Added.
      * fast/js/regress/string-get-by-val-big-char.html: Added.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153241 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      63af2d44
    • oliver@apple.com's avatar
      fourthTier: Small strings shouldn't get GC'd · 7e5973d7
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117897
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      Kill off the code needed to allocate them lazily and finalize them.
      
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
      * heap/Heap.cpp:
      (JSC::Heap::collect):
      * runtime/JSString.h:
      (JSC::jsSingleCharacterString):
      (JSC::jsSingleCharacterSubstring):
      (JSC::jsString):
      (JSC::jsSubstring8):
      (JSC::jsSubstring):
      (JSC::jsOwnedString):
      * runtime/NumberPrototype.cpp:
      (JSC::integerValueToString):
      * runtime/SmallStrings.cpp:
      (JSC):
      (JSC::SmallStrings::initializeCommonStrings):
      (JSC::SmallStrings::visitStrongReferences):
      * runtime/SmallStrings.h:
      (JSC::SmallStrings::singleCharacterString):
      (SmallStrings):
      
      LayoutTests:
      
      Reviewed by Mark Hahnenberg.
      
      This test speeds up by 5%.
      
      * fast/js/regress/script-tests/string-get-by-val.js: Added.
      (foo):
      * fast/js/regress/string-get-by-val-expected.txt: Added.
      * fast/js/regress/string-get-by-val.html: Added.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153240 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      7e5973d7
    • oliver@apple.com's avatar
      42e5917e
    • oliver@apple.com's avatar
      fourthTier: Structure should have a dump() · 880e6c35
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117859
      
      Reviewed by Geoffrey Garen.
      
      This is pretty cool. Anywhere we previously printed Structure pointers in dumps,
      we now print a bunch of other info as well. For example, for an object literal
      like "{f:42, g:64, h:24}", when we print the structure we'll now get:
      
          0x107a0af80:[Object, {f:0, g:1, h:2}, NonArray, Proto:0x107a8fff0]
      
      This also changes a bunch of places to use the dump method.
      
      * bytecode/StructureSet.h:
      (JSC::StructureSet::dump):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      * dfg/DFGStructureAbstractValue.h:
      (JSC::DFG::StructureAbstractValue::dump):
      * runtime/JSCJSValue.cpp:
      (JSC::JSValue::dump):
      * runtime/Structure.cpp:
      (JSC::Structure::dump):
      (JSC):
      * runtime/Structure.h:
      (Structure):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153238 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      880e6c35
    • oliver@apple.com's avatar
      fourthTier: There should only be one table of SimpleJumpTables · a14cea5d
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117856
      
      Reviewed by Geoffrey Garen.
      
      Having multiple tables of SimpleJumpTables just means we have to duplicate a
      ton of code. This patch deduplicates all of it.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::dumpBytecode):
      (JSC):
      (JSC::CodeBlock::CodeBlock):
      (JSC::CodeBlock::shrinkToFit):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::numberOfSwitchJumpTables):
      (JSC::CodeBlock::addSwitchJumpTable):
      (JSC::CodeBlock::switchJumpTable):
      (JSC::CodeBlock::clearSwitchJumpTables):
      (RareData):
      * bytecode/PreciseJumpTargets.cpp:
      (JSC):
      (JSC::computePreciseJumpTargets):
      * bytecode/UnlinkedCodeBlock.h:
      (JSC::UnlinkedCodeBlock::shrinkToFit):
      (JSC::UnlinkedCodeBlock::numberOfSwitchJumpTables):
      (JSC::UnlinkedCodeBlock::addSwitchJumpTable):
      (JSC::UnlinkedCodeBlock::switchJumpTable):
      (RareData):
      * bytecompiler/BytecodeGenerator.cpp:
      (JSC):
      (JSC::prepareJumpTableForSwitch):
      (JSC::BytecodeGenerator::endSwitch):
      * dfg/DFGByteCodeParser.cpp:
      (InlineStackEntry):
      (JSC::DFG::ByteCodeParser::parseBlock):
      (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::link):
      * dfg/DFGJITCompiler.h:
      (JITCompiler):
      * dfg/DFGOperations.cpp:
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::emitSwitchIntJump):
      (DFG):
      (JSC::DFG::SpeculativeJIT::emitSwitchImm):
      (JSC::DFG::SpeculativeJIT::emitSwitchCharStringJump):
      * dfg/DFGSpeculativeJIT.h:
      (SpeculativeJIT):
      * ftl/FTLLink.cpp:
      (JSC::FTL::link):
      * jit/JITOpcodes.cpp:
      (JSC::JIT::emit_op_switch_imm):
      (JSC::JIT::emit_op_switch_char):
      * jit/JITOpcodes32_64.cpp:
      (JSC::JIT::emit_op_switch_imm):
      (JSC::JIT::emit_op_switch_char):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::LLINT_SLOW_PATH_DECL):
      * llint/LowLevelInterpreter32_64.asm:
      * llint/LowLevelInterpreter64.asm:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153237 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      a14cea5d
    • oliver@apple.com's avatar
      fourthTier: FTL should clear character switch jump tables · 5eed80f7
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117852
      
      Reviewed by Sam Weinig.
      
      The FTL just uses LLVM's switch, which results in LLVM allocating its own switch
      jump tables as needed.
      
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::clearCharacterSwitchJumpTables):
      * ftl/FTLLink.cpp:
      (JSC::FTL::link):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153236 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      5eed80f7
    • oliver@apple.com's avatar
      fourthTier: FTL should support SwitchChar · 39478946
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117849
      
      Reviewed by Geoffrey Garen.
      
      This adds Switch(SwitchChar) to the FTL and also implicitly does some other things.
      SwitchChar requires calling a slow path to resolve ropes. Previously the FTL had no
      support for calling slow paths, and we avoided adding coverage that would require
      that. Well, this patch adds the ability to call slow paths and just uses that for
      resolving ropes for SwitchChar. Also SwitchChar required adding awareness of strings,
      so I did that, too.
      
      * bytecode/CodeBlock.h:
      (CodeBlock):
      (JSC::CodeBlock::addCodeOrigin):
      * dfg/DFGBackwardsPropagationPhase.cpp:
      (JSC::DFG::BackwardsPropagationPhase::propagate):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      * dfg/DFGNode.cpp:
      (WTF):
      (WTF::printInternal):
      * dfg/DFGNode.h:
      (WTF):
      * dfg/DFGOperations.h:
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::callOperation):
      * ftl/FTLAbbreviations.h:
      (JSC::FTL::int16Type):
      (JSC::FTL::constInt):
      * ftl/FTLAbstractHeapRepository.h:
      (FTL):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLCommonValues.cpp:
      (JSC::FTL::CommonValues::CommonValues):
      * ftl/FTLCommonValues.h:
      (CommonValues):
      * ftl/FTLIntrinsicRepository.cpp:
      (JSC::FTL::IntrinsicRepository::IntrinsicRepository):
      (FTL):
      * ftl/FTLIntrinsicRepository.h:
      (FTL):
      (IntrinsicRepository):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::lower):
      (JSC::FTL::LowerDFGToLLVM::transferAndCheckArguments):
      (JSC::FTL::LowerDFGToLLVM::compileJump):
      (JSC::FTL::LowerDFGToLLVM::compileBranch):
      (JSC::FTL::LowerDFGToLLVM::compileSwitch):
      (JSC::FTL::LowerDFGToLLVM::buildSwitch):
      (LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::lowString):
      (JSC::FTL::LowerDFGToLLVM::speculate):
      (JSC::FTL::LowerDFGToLLVM::isObject):
      (JSC::FTL::LowerDFGToLLVM::isNotString):
      (JSC::FTL::LowerDFGToLLVM::isString):
      (JSC::FTL::LowerDFGToLLVM::isNotObject):
      (JSC::FTL::LowerDFGToLLVM::speculateObject):
      (JSC::FTL::LowerDFGToLLVM::speculateString):
      (JSC::FTL::LowerDFGToLLVM::speculateNonNullObject):
      (JSC::FTL::LowerDFGToLLVM::vmCall):
      (JSC::FTL::LowerDFGToLLVM::callPreflight):
      (JSC::FTL::LowerDFGToLLVM::callCheck):
      (JSC::FTL::LowerDFGToLLVM::lowBlock):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::constBool):
      (JSC::FTL::Output::constInt8):
      (JSC::FTL::Output::constInt32):
      (JSC::FTL::Output::constIntPtr):
      (JSC::FTL::Output::constInt64):
      (JSC::FTL::Output::load16):
      (JSC::FTL::Output::isNull):
      (JSC::FTL::Output::notNull):
      (JSC::FTL::Output::testIsZero32):
      (JSC::FTL::Output::testNonZero32):
      (Output):
      (JSC::FTL::Output::operation):
      (JSC::FTL::Output::crash):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153235 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      39478946
    • oliver@apple.com's avatar
      fourthTier: DFG should have switch_char · 9e1c8098
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117710
      
      Source/JavaScriptCore:
      
      Reviewed by Michael Saboff.
      
      Add op_switch_char. Most of this is fairly simple, except for the whole
      LazyJSValue thing.
      
      It's long been the case that anytime you wanted the DFG to speak of a string
      that didn't appear in the constant pool, you would have a hard time since
      the DFG isn't allowed to allocate in the GC heap. For example, if you know
      that you want to speak of a single character string, you might find that
      the one you wanted to speak of had been GC'd. Another example is if you
      wanted to add constant folding for string concatenation - something we don't
      have yet but will want eventually.
      
      I solve this by finally adding the notion of LazyJSValue. In the future I
      anticipate using this for a variety of string-related things. The idea here
      is that the DFG can either say that it already knows what the value is, or
      it can describe the value. For example, in this patch I needed to be able to
      describe single-character strings.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::dumpBytecode):
      (JSC::CodeBlock::CodeBlock):
      * bytecode/JumpTable.h:
      * dfg/DFGBackwardsPropagationPhase.cpp:
      (JSC::DFG::BackwardsPropagationPhase::propagate):
      * dfg/DFGByteCodeParser.cpp:
      (InlineStackEntry):
      (JSC::DFG::ByteCodeParser::parseBlock):
      (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
      * dfg/DFGCFGSimplificationPhase.cpp:
      (JSC::DFG::CFGSimplificationPhase::run):
      * dfg/DFGCapabilities.cpp:
      (JSC::DFG::capabilityLevel):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGGPRInfo.h:
      (JSC::DFG::JSValueRegs::payloadGPR):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::jumpTable):
      (DFG):
      (JSC::DFG::JITCompiler::numberOfJumpTables):
      (JSC::DFG::JITCompiler::linkSwitches):
      (JSC::DFG::JITCompiler::link):
      * dfg/DFGJITCompiler.h:
      (JITCompiler):
      * dfg/DFGLazyJSValue.cpp: Added.
      (DFG):
      (JSC::DFG::LazyJSValue::getValue):
      (JSC::DFG::equalToSingleCharacter):
      (JSC::DFG::LazyJSValue::strictEqual):
      (JSC::DFG::LazyJSValue::dump):
      * dfg/DFGLazyJSValue.h: Added.
      (DFG):
      (LazyJSValue):
      (JSC::DFG::LazyJSValue::LazyJSValue):
      (JSC::DFG::LazyJSValue::singleCharacterString):
      (JSC::DFG::LazyJSValue::tryGetValue):
      (JSC::DFG::LazyJSValue::value):
      (JSC::DFG::LazyJSValue::character):
      (JSC::DFG::LazyJSValue::switchLookupValue):
      * dfg/DFGNode.h:
      (JSC::DFG::SwitchCase::SwitchCase):
      (SwitchCase):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::emitSwitchIntJump):
      (JSC::DFG::SpeculativeJIT::emitSwitchImmIntJump):
      (DFG):
      (JSC::DFG::SpeculativeJIT::emitSwitchImm):
      (JSC::DFG::SpeculativeJIT::emitSwitchCharStringJump):
      (JSC::DFG::SpeculativeJIT::emitSwitchChar):
      (JSC::DFG::SpeculativeJIT::emitSwitch):
      * dfg/DFGSpeculativeJIT.h:
      (SpeculativeJIT):
      
      Source/WTF:
      
      Reviewed by Michael Saboff.
      
      I wanted to be able to say stringImpl->at(index), and now I can!
      
      Also made it possible to convert a UChar to a utf8 CString without
      allocating a StringImpl.
      
      * wtf/text/StringImpl.cpp:
      (WTF::StringImpl::utf8Impl):
      (WTF):
      (WTF::StringImpl::utf8ForCharacters):
      (WTF::StringImpl::utf8ForRange):
      * wtf/text/StringImpl.h:
      (StringImpl):
      (WTF::StringImpl::at):
      (WTF::StringImpl::operator[]):
      
      LayoutTests:
      
      Rubber stamped by Mark Hahnenberg.
      
      * fast/js/regress/script-tests/switch-char-constant.js: Added.
      (foo):
      (bar):
      * fast/js/regress/script-tests/switch-char.js: Added.
      (foo):
      (bar):
      * fast/js/regress/switch-char-constant-expected.txt: Added.
      * fast/js/regress/switch-char-constant.html: Added.
      * fast/js/regress/switch-char-expected.txt: Added.
      * fast/js/regress/switch-char.html: Added.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153234 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      9e1c8098
    • oliver@apple.com's avatar
      fourthTier: Refactor ObjCCallbackFunction to inherit directly from InternalFunction · 5109edb6
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117595
      
      Reviewed by Geoffrey Garen.
      
      * API/APICallbackFunction.h: Added. New struct that allows JSCallbackFunction and
      ObjCCallbackFunction to share their host call() implementation through the magic of
      templates.
      (JSC::APICallbackFunction::call):
      * API/JSCallbackFunction.cpp:
      (JSC::JSCallbackFunction::getCallData): Changed to get the template-ized version of
      the host function.
      * API/JSCallbackFunction.h:
      * API/ObjCCallbackFunction.h: Now inherits directly from InternalFunction.
      * API/ObjCCallbackFunction.mm:
      (JSC::ObjCCallbackFunction::ObjCCallbackFunction):
      (JSC::ObjCCallbackFunction::getCallData): Ditto.
      * GNUmakefile.list.am: Build files!
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153233 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      5109edb6
    • oliver@apple.com's avatar
      fourthTier: Arity fixup should be done while on same stack · 3fd94fff
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117102
      
      Reviewed by Oliver Hunt.
      
      Removed the fixup part of op_call_arityCheck() and op_construct_arityCheck() and moved it to
      a thunk for the JITs and as assembly for the llint.  This patch provides the plumbing needed to
      move to the C stack for JS execution.  The fixup thunk and llint code would need to be change to
      work with a stack that grows down when we do move to the C stack.
      
      Due to an issue with the offline assembler, I moved the const at the top of LowLevelInterpreter64.asm
      and LowLevelInterpreter32_64.asm to LowLevelInterpreter.asm.  The problem is that a const defined in
      one file that are used in a macro doesn't resolve the const if the macro is used in another file.  This
      seemed like the quickest path.
      
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::compileFunction):
      (JSC::DFG::JITCompiler::linkFunction):
      * dfg/DFGJITCompiler.h:
      (JITCompiler):
      * ftl/FTLLink.cpp:
      (JSC::FTL::link):
      * jit/JIT.cpp:
      (JSC::JIT::privateCompile):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * jit/JITStubs.h:
      * jit/ThunkGenerators.cpp:
      (JSC::arityFixup):
      * jit/ThunkGenerators.h:
      * llint/LowLevelInterpreter.asm:
      * llint/LowLevelInterpreter32_64.asm:
      * llint/LowLevelInterpreter64.asm:
      * runtime/CommonSlowPaths.cpp:
      (JSC::SLOW_PATH_DECL):
      * runtime/CommonSlowPaths.h:
      (JSC::CommonSlowPaths::arityCheckFor):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153232 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      3fd94fff
    • oliver@apple.com's avatar
      fourthTier: Add another temp register regT4 to JSInterfaceJIT · a17ff5ba
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117719
      
      Reviewed by Geoffrey Garen.
      
      Made the dedicated bucketCounterRegister to be regT4 and then used regT4 wherever
      bucketCounterRegister had been used.  Since it is masked whenever it is used and
      we are looking for some randomness in the register anyway, we can use it without
      any issues.
      
      * jit/JIT.cpp:
      (JSC::JIT::privateCompile):
      * jit/JIT.h:
      (JSC::JIT::emitValueProfilingSite):
      * jit/JITCall.cpp:
      (JSC::JIT::emitPutCallResult):
      * jit/JITCall32_64.cpp:
      (JSC::JIT::emitPutCallResult):
      * jit/JITInlines.h:
      (JSC::JIT::emitValueProfilingSite):
      * jit/JITOpcodes.cpp:
      (JSC::JIT::emit_op_to_this):
      (JSC::JIT::emit_op_get_callee):
      (JSC::JIT::emit_op_get_argument_by_val):
      * jit/JITOpcodes32_64.cpp:
      (JSC::JIT::emit_op_get_callee):
      (JSC::JIT::emit_op_to_this):
      (JSC::JIT::emit_op_get_argument_by_val):
      * jit/JITPropertyAccess.cpp:
      (JSC::JIT::emit_op_get_by_val):
      (JSC::JIT::emitSlow_op_get_by_val):
      (JSC::JIT::emit_op_get_by_id):
      (JSC::JIT::emitSlow_op_get_by_id):
      (JSC::JIT::emit_op_get_from_scope):
      (JSC::JIT::emitSlow_op_get_from_scope):
      * jit/JITPropertyAccess32_64.cpp:
      (JSC::JIT::emit_op_get_by_val):
      (JSC::JIT::emitSlow_op_get_by_val):
      (JSC::JIT::emit_op_get_by_id):
      (JSC::JIT::emitSlow_op_get_by_id):
      (JSC::JIT::emit_op_get_from_scope):
      (JSC::JIT::emitSlow_op_get_from_scope):
      * jit/JITStubCall.h:
      (JSC::JITStubCall::callWithValueProfiling):
      * jit/JSInterfaceJIT.h:
      (JSInterfaceJIT):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153231 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      a17ff5ba
    • oliver@apple.com's avatar
      fourthTier: FTL should support Switch · 9f4a672d
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117704
      
      Reviewed by Oliver Hunt.
      
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::clearImmediateSwitchJumpTables):
      * ftl/FTLAbbreviations.h:
      (JSC::FTL::buildFPToSI):
      (JSC::FTL::buildSwitch):
      (JSC::FTL::addCase):
      (FTL):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLink.cpp:
      (JSC::FTL::link):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileSwitch):
      (LowerDFGToLLVM):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::fpToInt):
      (JSC::FTL::Output::fpToInt32):
      (Output):
      (JSC::FTL::Output::switchInstruction):
      * ftl/FTLSwitchCase.h: Added.
      (FTL):
      (SwitchCase):
      (JSC::FTL::SwitchCase::SwitchCase):
      (JSC::FTL::SwitchCase::value):
      (JSC::FTL::SwitchCase::target):
      
      Conflicts:
      	Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153230 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      9f4a672d
    • oliver@apple.com's avatar
      fourthTier: Add CFG simplification for Switch · 6ce44688
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117677
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      This is for completeness. It only speeds up a microbenchmark at this point.
      Broadly, we want all control constructs to be known to the CFG simplifier.
      
      * dfg/DFGCFGSimplificationPhase.cpp:
      (JSC::DFG::CFGSimplificationPhase::run):
      (JSC::DFG::CFGSimplificationPhase::convertToJump):
      (CFGSimplificationPhase):
      (JSC::DFG::CFGSimplificationPhase::noBlocks):
      (JSC::DFG::CFGSimplificationPhase::oneBlock):
      (JSC::DFG::CFGSimplificationPhase::mergeBlocks):
      * runtime/JSCJSValue.h:
      (JSValue):
      * runtime/JSCJSValueInlines.h:
      (JSC::JSValue::pureStrictEqual):
      (JSC):
      
      Source/WTF:
      
      Reviewed by Mark Hahnenberg.
      
      * wtf/TriState.h:
      * wtf/text/StringImpl.h:
      
      LayoutTests:
      
      Reviewed by Mark Hahnenberg.
      
      * fast/js/regress/script-tests/switch-constant.js: Added.
      (foo):
      (bar):
      * fast/js/regress/script-tests/switch.js: Added.
      (foo):
      (bar):
      * fast/js/regress/switch-constant-expected.txt: Added.
      * fast/js/regress/switch-constant.html: Added.
      * fast/js/regress/switch-expected.txt: Added.
      * fast/js/regress/switch.html: Added.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153229 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      6ce44688
    • oliver@apple.com's avatar
      fourthTier: DFG should support op_switch_imm · 9b7647ba
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117559
      
      Reviewed by Oliver Hunt.
      
      Implement integer (i.e. immediate) switches in the DFG. Reduce the minimum
      threshold for using op_switch.
      
      Also get rid of edge code support, since we haven't used it in the year since
      I introduced it. It was supposed to allow us to break critical edges late in
      the backend, thus enabling global register allocation from an SSA-form graph.
      But we aren't doing that so I figure we should just kill the code for now. It
      would have made implementing switch harder.
      
      * assembler/AbstractMacroAssembler.h:
      (JSC::AbstractMacroAssembler::timesPtr):
      * assembler/MacroAssemblerCodeRef.h:
      (JSC::MacroAssemblerCodePtr::dumpWithName):
      (MacroAssemblerCodePtr):
      (JSC::MacroAssemblerCodePtr::dump):
      (MacroAssemblerCodeRef):
      (JSC::MacroAssemblerCodeRef::dump):
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::shrinkToFit):
      * bytecode/JumpTable.h:
      (SimpleJumpTable):
      (JSC::SimpleJumpTable::clear):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::executeEffects):
      (JSC::DFG::AbstractState::mergeToSuccessors):
      * dfg/DFGBackwardsPropagationPhase.cpp:
      (JSC::DFG::BackwardsPropagationPhase::propagate):
      * dfg/DFGByteCodeParser.cpp:
      (InlineStackEntry):
      (JSC::DFG::ByteCodeParser::parseBlock):
      (JSC::DFG::ByteCodeParser::linkBlock):
      (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
      * dfg/DFGCapabilities.cpp:
      (JSC::DFG::capabilityLevel):
      * dfg/DFGCommon.h:
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      (JSC::DFG::Graph::determineReachability):
      * dfg/DFGGraph.h:
      (Graph):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::JITCompiler):
      (JSC::DFG::JITCompiler::link):
      * dfg/DFGJITCompiler.h:
      (JITCompiler):
      (JSC::DFG::JITCompiler::blockHeads):
      * dfg/DFGNode.h:
      (DFG):
      (JSC::DFG::SwitchCase::SwitchCase):
      (SwitchCase):
      (SwitchData):
      (JSC::DFG::SwitchData::SwitchData):
      (Node):
      (JSC::DFG::Node::isSwitch):
      (JSC::DFG::Node::isTerminal):
      (JSC::DFG::Node::switchData):
      (JSC::DFG::Node::numSuccessors):
      (JSC::DFG::Node::successor):
      * dfg/DFGNodeType.h:
      (DFG):
      * dfg/DFGOperations.cpp:
      * dfg/DFGOperations.h:
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::SpeculativeJIT):
      (JSC::DFG::SpeculativeJIT::compile):
      (JSC::DFG::SpeculativeJIT::createOSREntries):
      (JSC::DFG::SpeculativeJIT::emitSwitchImmIntJump):
      (DFG):
      (JSC::DFG::SpeculativeJIT::emitSwitchImm):
      (JSC::DFG::SpeculativeJIT::emitSwitch):
      (JSC::DFG::SpeculativeJIT::linkBranches):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::callOperation):
      (SpeculativeJIT):
      (JSC::DFG::SpeculativeJIT::branchDouble):
      (JSC::DFG::SpeculativeJIT::branchDoubleNonZero):
      (JSC::DFG::SpeculativeJIT::branch32):
      (JSC::DFG::SpeculativeJIT::branchTest32):
      (JSC::DFG::SpeculativeJIT::branch64):
      (JSC::DFG::SpeculativeJIT::branchPtr):
      (JSC::DFG::SpeculativeJIT::branchTestPtr):
      (JSC::DFG::SpeculativeJIT::branchTest8):
      (JSC::DFG::SpeculativeJIT::jump):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * parser/Nodes.h:
      (CaseBlockNode):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153228 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      9b7647ba
    • oliver@apple.com's avatar
      fourthTier: Concurrent JIT shouldn't try to recompute the CodeBlockHash as... · acdde49f
      oliver@apple.com authored
      fourthTier: Concurrent JIT shouldn't try to recompute the CodeBlockHash as part of debug dumps, since doing so may fail if dealing with a CachedScript that doesn't have its script string handy
      https://bugs.webkit.org/show_bug.cgi?id=117676
      
      Reviewed by Sam Weinig.
      
      Source/JavaScriptCore:
      
      CodeBlock now caches m_hash, and the DFG Driver will force its computation if we're doing debug dumps of any kind.
      
      Also made sure that CodeBlock::CodeBlock initializes all of its fields; it was previously missing the
      initialization of m_capabilityLevelState.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::hash):
      (JSC::CodeBlock::CodeBlock):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      * bytecode/CodeBlockHash.cpp:
      (JSC::CodeBlockHash::CodeBlockHash):
      * bytecode/CodeBlockHash.h:
      (CodeBlockHash):
      (JSC::CodeBlockHash::isSet):
      (JSC::CodeBlockHash::operator!):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      
      Source/WebCore:
      
      Remove the broken hack for the concurrent JIT, since now the concurrent JIT won't use this code anymore.
      
      No new tests because no new behavior.
      
      * loader/cache/CachedScript.cpp:
      (WebCore::CachedScript::script):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153227 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      acdde49f
    • oliver@apple.com's avatar
      fourthTier: Printing a StringImpl* should really guard against NULL · 64779127
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117675
      
      Reviewed by Mark Hahnenberg.
      
      * wtf/PrintStream.cpp:
      (WTF::printInternal):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153226 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      64779127
    • oliver@apple.com's avatar
      fourthTier: DFG should support op_in and it should use patching to make it fast · b3e5acbf
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117385
      
      Source/JavaScriptCore:
      
      Reviewed by Geoffrey Garen.
      
      Implement op_in in the DFG and give it patching. The code we generate is just
      a jump on the hot path, and the slow paths generate stubs and link the jump to
      them. I didn't want to bother with patching structures and load offsets and
      the like, although I probably could have.
      
      This is a ginormous speed-up on microbenchmarks for "in", obviously.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::dumpAssumingJITType):
      (JSC::CodeBlock::resetStubInternal):
      (JSC::structureStubInfoLessThan):
      (JSC):
      (JSC::CodeBlock::sortStructureStubInfos):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      * bytecode/StructureStubInfo.cpp:
      (JSC::StructureStubInfo::deref):
      (JSC::StructureStubInfo::visitWeakReferences):
      * bytecode/StructureStubInfo.h:
      (JSC::isInAccess):
      (JSC):
      (StructureStubInfo):
      (JSC::StructureStubInfo::initInList):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::executeEffects):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGCCallHelpers.h:
      (JSC::DFG::CCallHelpers::setupResults):
      * dfg/DFGCapabilities.cpp:
      (JSC::DFG::capabilityLevel):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGGPRInfo.h:
      (JSC::DFG::JSValueRegs::payloadOnly):
      (JSValueRegs):
      (JSC::DFG::JSValueRegs::JSValueRegs):
      (JSC::DFG::JSValueRegs::operator!):
      (JSC::DFG::JSValueSource::operator!):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::link):
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::InRecord::InRecord):
      (InRecord):
      (DFG):
      (JITCompiler):
      (JSC::DFG::JITCompiler::addIn):
      * dfg/DFGNodeType.h:
      (DFG):
      * dfg/DFGOperations.cpp:
      * dfg/DFGOperations.h:
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGRepatch.cpp:
      (JSC::DFG::tryRepatchIn):
      (DFG):
      (JSC::DFG::dfgRepatchIn):
      (JSC::DFG::dfgResetIn):
      * dfg/DFGRepatch.h:
      (DFG):
      (JSC::DFG::dfgResetIn):
      * dfg/DFGSlowPathGenerator.h:
      (JSC::DFG::CallSlowPathGenerator::CallSlowPathGenerator):
      (JSC::DFG::CallSlowPathGenerator::tearDown):
      (JSC::DFG::CallResultAndNoArgumentsSlowPathGenerator::generateInternal):
      (JSC::DFG::CallResultAndOneArgumentSlowPathGenerator::generateInternal):
      (JSC::DFG::CallResultAndTwoArgumentsSlowPathGenerator::generateInternal):
      (JSC::DFG::CallResultAndThreeArgumentsSlowPathGenerator::generateInternal):
      (JSC::DFG::CallResultAndFourArgumentsSlowPathGenerator::generateInternal):
      (JSC::DFG::CallResultAndFiveArgumentsSlowPathGenerator::generateInternal):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compileIn):
      (DFG):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::extractResult):
      (DFG):
      (SpeculativeJIT):
      (JSC::DFG::SpeculativeJIT::callOperation):
      (JSC::DFG::SpeculativeJIT::appendCallWithExceptionCheckSetResult):
      (JSC::DFG::SpeculativeJIT::appendCallSetResult):
      (JSC::DFG::JSValueOperand::tagGPR):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * runtime/JSCJSValue.cpp:
      (JSC::JSValue::dump):
      * runtime/JSString.h:
      (JSString):
      (JSC::JSString::tryGetValueImpl):
      (JSC):
      * runtime/Operations.h:
      (JSC::normalizePrototypeChainForChainAccess):
      
      Source/WTF:
      
      Reviewed by Geoffrey Garen.
      
      Now if you pass a null StringImpl* then something will still get printed instead
      of crashing. I figure that this is broadly useful for debug code, and I make use
      of it in the JSC portion of this patch.
      
      * wtf/PrintStream.cpp:
      (WTF::printInternal):
      
      LayoutTests:
      
      Reviewed by Geoffrey Garen.
      
      Test coverage for op_in performance.
      
      * fast/js/regress/in-four-cases-expected.txt: Added.
      * fast/js/regress/in-four-cases.html: Added.
      * fast/js/regress/in-one-case-false-expected.txt: Added.
      * fast/js/regress/in-one-case-false.html: Added.
      * fast/js/regress/in-one-case-true-expected.txt: Added.
      * fast/js/regress/in-one-case-true.html: Added.
      * fast/js/regress/in-two-cases-expected.txt: Added.
      * fast/js/regress/in-two-cases.html: Added.
      * fast/js/regress/script-tests/in-four-cases.js: Added.
      (foo):
      (bar):
      * fast/js/regress/script-tests/in-one-case-false.js: Added.
      (foo):
      (bar):
      * fast/js/regress/script-tests/in-one-case-true.js: Added.
      (foo):
      (bar):
      * fast/js/regress/script-tests/in-two-cases.js: Added.
      (foo):
      (bar):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153225 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      b3e5acbf
    • oliver@apple.com's avatar
      fourthTier: A few fixups to standalone-pre.js · 336e13ce
      oliver@apple.com authored
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153224 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      336e13ce
    • oliver@apple.com's avatar
      fourthTier: The Math object should not be polymorphic · 524161ed
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117576
      
      Reviewed by Oliver Hunt.
      
      Fill in the Math object eagerly, to avoid its structure changing during
      execution. There are lots of ways to skin this cat; this one seemed
      easiest, and justified given the relative hotness of math operations.
      
      20% speedup on DSP-filtrr tests, small speedups on a few Kraken tests.
      
      * DerivedSources.make:
      * JavaScriptCore.order:
      * create_hash_table:
      * interpreter/CallFrame.h:
      (JSC::ExecState::jsonTable): Removed the Math object's static table.
      
      * runtime/JSObject.cpp:
      (JSC::JSObject::putDirectNativeFunctionWithoutTransition):
      * runtime/JSObject.h:
      * runtime/MathObject.cpp:
      (JSC::MathObject::finishCreation):
      * runtime/MathObject.h:
      (JSC::MathObject::create): Set up the Math object at construction time.
      
      * runtime/VM.cpp:
      (JSC::VM::VM):
      (JSC::VM::~VM):
      * runtime/VM.h: Removed the Math object's static table.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153223 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      524161ed
    • oliver@apple.com's avatar
      fourthTier: The baseline jit and LLint should use common slow paths · 7ca71435
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116889
      
      Reviewed by Filip Pizlo.
      
      Moved the llint_slow_paths that return JSValue along with several others to CommonSlowPaths.cpp.
      Eliminated the related JIT stubs.  Changes the baseline JIT to call these new common stubs.
      Added a simple slow path call class that uses argument registers or the stack instead of
      JITStackFrame.  Changes the exception mechanism for to check for an exception after making
      a slowpath call instead of returning to the handler directly form the slowpath function.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * jit/JIT.cpp:
      (JSC::JIT::privateCompileMainPass):
      * jit/JIT.h:
      (JIT):
      * jit/JITArithmetic.cpp:
      (JSC::JIT::emitSlow_op_negate):
      (JSC::JIT::emitSlow_op_lshift):
      (JSC::JIT::emitSlow_op_rshift):
      (JSC::JIT::emitSlow_op_urshift):
      (JSC::JIT::emitSlow_op_bitand):
      (JSC::JIT::emitSlow_op_inc):
      (JSC::JIT::emitSlow_op_dec):
      (JSC::JIT::emitSlow_op_mod):
      (JSC::JIT::emit_op_mod):
      (JSC::JIT::compileBinaryArithOpSlowCase):
      (JSC::JIT::emit_op_add):
      (JSC::JIT::emitSlow_op_add):
      (JSC::JIT::emitSlow_op_mul):
      (JSC::JIT::emitSlow_op_div):
      (JSC::JIT::emitSlow_op_sub):
      * jit/JITArithmetic32_64.cpp:
      (JSC::JIT::emitSlow_op_negate):
      (JSC::JIT::emitSlow_op_lshift):
      (JSC::JIT::emitRightShiftSlowCase):
      (JSC::JIT::emitSlow_op_bitand):
      (JSC::JIT::emitSlow_op_bitor):
      (JSC::JIT::emitSlow_op_bitxor):
      (JSC::JIT::emitSlow_op_inc):
      (JSC::JIT::emitSlow_op_dec):
      (JSC::JIT::emit_op_add):
      (JSC::JIT::emitSlow_op_add):
      (JSC::JIT::emitSlow_op_sub):
      (JSC::JIT::emitSlow_op_mul):
      (JSC::JIT::emitSlow_op_div):
      (JSC::JIT::emit_op_mod):
      (JSC::JIT::emitSlow_op_mod):
      * jit/JITExceptions.cpp:
      (JSC::getExceptionLocation):
      (JSC::genericThrow):
      (JSC::jitThrowNew):
      * jit/JITExceptions.h:
      (ExceptionHandler):
      * jit/JITOpcodes.cpp:
      (JSC::JIT::emit_op_strcat):
      (JSC::JIT::emitSlow_op_create_this):
      (JSC::JIT::emitSlow_op_to_this):
      (JSC::JIT::emitSlow_op_to_primitive):
      (JSC::JIT::emitSlow_op_not):
      (JSC::JIT::emitSlow_op_bitxor):
      (JSC::JIT::emitSlow_op_bitor):
      (JSC::JIT::emitSlow_op_stricteq):
      (JSC::JIT::emitSlow_op_nstricteq):
      (JSC::JIT::emitSlow_op_to_number):
      * jit/JITOpcodes32_64.cpp:
      (JSC::JIT::privateCompileCTINativeCall):
      (JSC::JIT::emitSlow_op_to_primitive):
      (JSC::JIT::emit_op_strcat):
      (JSC::JIT::emitSlow_op_not):
      (JSC::JIT::emitSlow_op_stricteq):
      (JSC::JIT::emitSlow_op_nstricteq):
      (JSC::JIT::emitSlow_op_to_number):
      (JSC::JIT::emit_op_create_arguments):
      (JSC::JIT::emitSlow_op_create_this):
      (JSC::JIT::emitSlow_op_to_this):
      (JSC::JIT::emitSlow_op_get_argument_by_val):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      (JSC::cti_vm_throw_slowpath):
      * jit/JITStubs.h:
      * jit/JITStubsARM.h:
      * jit/JITStubsARMv7.h:
      * jit/JITStubsMIPS.h:
      * jit/JITStubsSH4.h:
      * jit/JITStubsX86.h:
      * jit/JITStubsX86_64.h:
      * jit/JSInterfaceJIT.h:
      (JSInterfaceJIT):
      * jit/SlowPathCall.h: Added.
      (JITSlowPathCall):
      (JSC::JITSlowPathCall::JITSlowPathCall):
      (JSC::JITSlowPathCall::call):
      * jit/ThunkGenerators.cpp:
      (JSC::nativeForGenerator):
      * llint/LLIntSlowPaths.cpp:
      (LLInt):
      * llint/LLIntSlowPaths.h:
      (LLInt):
      * llint/LowLevelInterpreter.asm:
      * llint/LowLevelInterpreter.cpp:
      * llint/LowLevelInterpreter32_64.asm:
      * llint/LowLevelInterpreter64.asm:
      * runtime/CommonSlowPaths.cpp: Added.
      (JSC::SLOW_PATH_DECL):
      * runtime/CommonSlowPaths.h:
      (SlowPathReturnType):
      (JSC::encodeResult):
      (JSC::decodeResult):
      * runtime/JSCJSValue.h:
      (JSValue):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153222 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      7ca71435
    • oliver@apple.com's avatar
      fourthTier: Re-worked non-local variable resolution · 58c86752
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117375
      
      Reviewed by Filip Pizlo.
      
      Source/JavaScriptCore:
      
      This patch has two goals:
      
      (1) Simplicity.
      
          * Net removes 15 opcodes.
          * Net removes 2,000 lines of code.
          * Removes setPair() from the DFG: All DFG nodes have 1 result register now.
      
      (2) Performance.
      
          * 2%-3% speedup on SunSpider (20% in LLInt and Baseline JIT)
          * 2% speedup on v8-spider
          * 10% speedup on js-regress-hashmap*
          * Amusing 2X speedup on js-regress-poly-stricteq
      
      The bytecode now separates the scope chain resolution opcode from the
      scope access opcode.
      
          OLD:
              get_scoped_var  r0, 1, 0
              inc             r0
              put_scoped_var  1, 0, r0
      
          NEW:
              resolve_scope   r0, x(@id0)
              get_from_scope  r1, r0, x(@id0)
              inc             r1
              put_to_scope    r0, x(@id0), r1
      
      Also, we link non-local variable resolution opcodes at CodeBlock link
      time instead of time of first opcode execution.
      
      This means that we can represent all possible non-local variable
      resolutions using just three opcodes, and any optimizations in these
      opcodes naturally apply across-the-board.
      
      * API/JSCTestRunnerUtils.cpp:
      (JSC::numberOfDFGCompiles):
      * GNUmakefile.list.am:
      * JavaScriptCore.gypi:
      * JavaScriptCore.order:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri: Build!
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::dumpBytecode): Updated for removed things.
      
      (JSC::CodeBlock::CodeBlock): Always provide the full scope chain when
      creating a CodeBlock, so we can perform non-local variable resolution.
      
      Added code to perform linking for these opcodes. This is where we figure
      out which non-local variable resolutions are optimizable, and how.
      
      (JSC::CodeBlock::finalizeUnconditionally):
      (JSC::CodeBlock::noticeIncomingCall):
      (JSC::CodeBlock::optimizeAfterWarmUp):
      (JSC::CodeBlock::optimizeAfterLongWarmUp):
      (JSC::CodeBlock::optimizeSoon): Updated for removed things.
      
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::needsActivation):
      (JSC::GlobalCodeBlock::GlobalCodeBlock):
      (JSC::ProgramCodeBlock::ProgramCodeBlock):
      (JSC::EvalCodeBlock::EvalCodeBlock):
      (JSC::FunctionCodeBlock::FunctionCodeBlock):
      * bytecode/EvalCodeCache.h:
      (JSC::EvalCodeCache::getSlow): Updated for interface changes.
      
      * bytecode/GetByIdStatus.cpp:
      (JSC::GetByIdStatus::computeFor): Treat global object access as
      optimizable even though the global object has a custom property access
      callback. This is what we've always done since, otherwise, we can't
      optimize globals. (In future, we probably want to figure out a more
      targeted policy than "any property access callback means no
      optimization".)
      
      * bytecode/GlobalResolveInfo.h: Removed.
      * bytecode/Instruction.h:
      * bytecode/Opcode.h:
      (JSC::padOpcodeName):
      
      * bytecode/PutByIdStatus.cpp:
      (JSC::PutByIdStatus::computeFor): Like GetByIdStatus.
      
      * bytecode/ResolveGlobalStatus.cpp: Removed.
      * bytecode/ResolveGlobalStatus.h: Removed.
      * bytecode/ResolveOperation.h: Removed.
      
      * bytecode/UnlinkedCodeBlock.cpp:
      (JSC::generateFunctionCodeBlock):
      (JSC::UnlinkedFunctionExecutable::codeBlockFor):
      (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
      * bytecode/UnlinkedCodeBlock.h: Don't provide a scope chain to unlinked
      code blocks. Giving a scope to an unscoped compilation unit invites
      programming errors.
      
      * bytecode/Watchpoint.h:
      (JSC::WatchpointSet::addressOfIsInvalidated):
      * bytecompiler/BytecodeGenerator.cpp:
      (JSC::BytecodeGenerator::BytecodeGenerator):
      (JSC::BytecodeGenerator::resolveCallee):
      (JSC::BytecodeGenerator::local):
      (JSC::BytecodeGenerator::constLocal):
      (JSC::BytecodeGenerator::resolveType):
      (JSC::BytecodeGenerator::emitResolveScope):
      (JSC::BytecodeGenerator::emitGetFromScope):
      (JSC::BytecodeGenerator::emitPutToScope):
      (JSC::BytecodeGenerator::emitInstanceOf):
      (JSC::BytecodeGenerator::emitPushWithScope):
      (JSC::BytecodeGenerator::emitPopScope):
      (JSC::BytecodeGenerator::pushFinallyContext):
      (JSC::BytecodeGenerator::emitComplexPopScopes):
      (JSC::BytecodeGenerator::popTryAndEmitCatch):
      (JSC::BytecodeGenerator::emitPushNameScope):
      (JSC::BytecodeGenerator::isArgumentNumber):
      * bytecompiler/BytecodeGenerator.h:
      (JSC::Local::Local):
      (JSC::Local::operator bool):
      (JSC::Local::get):
      (JSC::Local::isReadOnly):
      (JSC::BytecodeGenerator::scopeDepth):
      (JSC::BytecodeGenerator::shouldOptimizeLocals):
      (JSC::BytecodeGenerator::canOptimizeNonLocals): Refactored the bytecode
      generator to resolve all variables within local scope, as if there
      were no non-local scope. This helps provide a separation of concerns:
      unlinked bytecode is always scope-free, and the linking stage links
      in the provided scope.
      
      * bytecompiler/NodesCodegen.cpp:
      (JSC::ResolveNode::isPure):
      (JSC::ResolveNode::emitBytecode):
      (JSC::EvalFunctionCallNode::emitBytecode):
      (JSC::FunctionCallResolveNode::emitBytecode):
      (JSC::PostfixNode::emitResolve):
      (JSC::DeleteResolveNode::emitBytecode):
      (JSC::TypeOfResolveNode::emitBytecode):
      (JSC::PrefixNode::emitResolve):
      (JSC::ReadModifyResolveNode::emitBytecode):
      (JSC::AssignResolveNode::emitBytecode):
      (JSC::ConstDeclNode::emitCodeSingle):
      (JSC::ForInNode::emitBytecode): A bunch of this codegen is no longer
      necessary, since it's redundant with the linking stage.
      
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::executeEffects):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::ByteCodeParser):
      (JSC::DFG::ByteCodeParser::cellConstantWithStructureCheck):
      (JSC::DFG::ByteCodeParser::handlePutByOffset):
      (JSC::DFG::ByteCodeParser::handleGetById):
      (JSC::DFG::ByteCodeParser::parseBlock): Updated for interface changes.
      Notably, we can reuse existing DFG nodes -- but the mapping between
      bytecode and DFG nodes has changed, and some nodes and corner cases have
      been removed.
      
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::scopedVarLoadElimination):
      (JSC::DFG::CSEPhase::varInjectionWatchpointElimination):
      (JSC::DFG::CSEPhase::globalVarStoreElimination):
      (JSC::DFG::CSEPhase::scopedVarStoreElimination):
      (JSC::DFG::CSEPhase::getLocalLoadElimination):
      (JSC::DFG::CSEPhase::setLocalStoreElimination):
      (JSC::DFG::CSEPhase::performNodeCSE): Added CSE for var injection
      watchpoints. Even though watchpoints are "free", they're quite common
      inside code that's subject to var injection, so I figured we'd save a
      little memory.
      
      * dfg/DFGCapabilities.cpp:
      (JSC::DFG::capabilityLevel):
      * dfg/DFGCapabilities.h: Removed detection for old forms.
      
      * dfg/DFGDriver.h:
      (JSC::DFG::tryCompile):
      (JSC::DFG::tryCompileFunction):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGGraph.h:
      * dfg/DFGJITCode.cpp:
      * dfg/DFGNode.h:
      (JSC::DFG::Node::convertToStructureTransitionWatchpoint):
      (JSC::DFG::Node::hasVarNumber):
      (JSC::DFG::Node::hasIdentifierNumberForCheck):
      (JSC::DFG::Node::hasRegisterPointer):
      (JSC::DFG::Node::hasHeapPrediction):
      * dfg/DFGNodeType.h:
      * dfg/DFGOperations.cpp:
      * dfg/DFGOperations.h:
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGRepatch.h:
      (JSC::DFG::dfgResetGetByID):
      (JSC::DFG::dfgResetPutByID):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::callOperation): Removed some unneeded things,
      and updated for renames.
      
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile): The two primary changes here are:
      
      (1) Use a watchpoint for var injection instead of looping over the scope
      chain and checking. This is more efficient and much easier to model in
      code generation.
      
      (2) I've eliminated the notion of an optimized global assignment that
      needs to check for whether it should fire a watchpiont. Instead, we
      fire pre-emptively at the point of optimization. This removes a bunch
      of edge cases, and it seems like a more honest representation of
      the fact that our new optimization contradicts our old one.
      
      * dfg/DFGTypeCheckHoistingPhase.cpp:
      (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
      (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
      * heap/DFGCodeBlocks.cpp:
      (JSC::DFGCodeBlocks::jettison):
      * interpreter/CallFrame.h:
      (JSC::ExecState::trueCallFrame): Removed stuff that's unused now, and
      fixed the build.
      
      * interpreter/Interpreter.cpp:
      (JSC::eval):
      (JSC::getBytecodeOffsetForCallFrame):
      (JSC::getCallerInfo):
      (JSC::Interpreter::throwException): Updated exception scope tracking
      to match the rest of our linking strategy: The unlinked bytecode compiles
      exception scope as if non-local scope did not exist, and we add in
      non-local scope at link time. This means that we can restore the right
      scope depth based on a simple number, without checking the contents of
      the scope chain.
      
      (JSC::Interpreter::execute): Make sure to establish the full scope chain
      before linking eval code. We now require the full scope chain at link
      time, in order to link non-local variable resolution opcodes.
      
      * jit/JIT.cpp:
      (JSC::JIT::JIT):
      (JSC::JIT::privateCompileMainPass):
      (JSC::JIT::privateCompileSlowCases):
      * jit/JIT.h:
      * jit/JITArithmetic.cpp:
      (JSC::JIT::emit_op_add):
      * jit/JITCode.cpp:
      * jit/JITOpcodes.cpp:
      (JSC::JIT::emitSlow_op_bitxor):
      (JSC::JIT::emitSlow_op_bitor):
      * jit/JITOpcodes32_64.cpp:
      (JSC::JIT::emitSlow_op_to_primitive):
      (JSC::JIT::emit_op_strcat):
      (JSC::JIT::emitSlow_op_create_this):
      (JSC::JIT::emitSlow_op_to_this):
      * jit/JITPropertyAccess.cpp:
      (JSC::JIT::emitVarInjectionCheck):
      (JSC::JIT::emitResolveClosure):
      (JSC::JIT::emit_op_resolve_scope):
      (JSC::JIT::emitSlow_op_resolve_scope):
      (JSC::JIT::emitLoadWithStructureCheck):
      (JSC::JIT::emitGetGlobalProperty):
      (JSC::JIT::emitGetGlobalVar):
      (JSC::JIT::emitGetClosureVar):
      (JSC::JIT::emit_op_get_from_scope):
      (JSC::JIT::emitSlow_op_get_from_scope):
      (JSC::JIT::emitPutGlobalProperty):
      (JSC::JIT::emitPutGlobalVar):
      (JSC::JIT::emitPutClosureVar):
      (JSC::JIT::emit_op_put_to_scope):
      (JSC::JIT::emitSlow_op_put_to_scope):
      (JSC::JIT::emit_op_init_global_const):
      * jit/JITPropertyAccess32_64.cpp:
      (JSC::JIT::emitVarInjectionCheck):
      (JSC::JIT::emitResolveClosure):
      (JSC::JIT::emit_op_resolve_scope):
      (JSC::JIT::emitSlow_op_resolve_scope):
      (JSC::JIT::emitLoadWithStructureCheck):
      (JSC::JIT::emitGetGlobalProperty):
      (JSC::JIT::emitGetGlobalVar):
      (JSC::JIT::emitGetClosureVar):
      (JSC::JIT::emit_op_get_from_scope):
      (JSC::JIT::emitSlow_op_get_from_scope):
      (JSC::JIT::emitPutGlobalProperty):
      (JSC::JIT::emitPutGlobalVar):
      (JSC::JIT::emitPutClosureVar):
      (JSC::JIT::emit_op_put_to_scope):
      (JSC::JIT::emitSlow_op_put_to_scope):
      (JSC::JIT::emit_op_init_global_const):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * jit/JITStubs.h: Re-wrote baseline JIT codegen for our new variable
      resolution model.
      
      * llint/LLIntData.cpp:
      (JSC::LLInt::Data::performAssertions):
      * llint/LLIntSlowPaths.cpp:
      * llint/LLIntSlowPaths.h:
      * llint/LowLevelInterpreter.asm:
      * llint/LowLevelInterpreter.cpp:
      (JSC::CLoop::execute):
      * llint/LowLevelInterpreter32_64.asm:
      * llint/LowLevelInterpreter64.asm: Ditto for LLInt.
      
      * offlineasm/x86.rb: Fixed a pre-existing encoding bug for a syntactic
      form that we never used before.
      
      * runtime/ArrayPrototype.cpp:
      (JSC::arrayProtoFuncToString):
      (JSC::arrayProtoFuncToLocaleString):
      (JSC::arrayProtoFuncJoin):
      (JSC::arrayProtoFuncConcat):
      (JSC::arrayProtoFuncPop):
      (JSC::arrayProtoFuncPush):
      (JSC::arrayProtoFuncReverse):
      (JSC::arrayProtoFuncShift):
      (JSC::arrayProtoFuncSlice):
      (JSC::arrayProtoFuncSort):
      (JSC::arrayProtoFuncSplice):
      (JSC::arrayProtoFuncUnShift):
      (JSC::arrayProtoFuncFilter):
      (JSC::arrayProtoFuncMap):
      (JSC::arrayProtoFuncEvery):
      (JSC::arrayProtoFuncForEach):
      (JSC::arrayProtoFuncSome):
      (JSC::arrayProtoFuncReduce):
      (JSC::arrayProtoFuncReduceRight):
      (JSC::arrayProtoFuncIndexOf):
      (JSC::arrayProtoFuncLastIndexOf): Fixed some pre-existing bugs in
      'this' value conversion, which I made much more common by removing
      special cases in bytecode generation.
      
      These functions need to invoke toThis() because they observe the 'this'
      value. Also, toLocaleString() is specified to accept non-array 'this'
      values.
      
      (Most other host functions don't need this fix because they perform
      strict 'this' checking, which never coerces unexpected types.)
      
      * runtime/CodeCache.cpp:
      (JSC::CodeCache::getCodeBlock):
      (JSC::CodeCache::getProgramCodeBlock):
      (JSC::CodeCache::getEvalCodeBlock):
      * runtime/CodeCache.h: Don't supply a scope to the unlinked code cache.
      Unlinked code is supposed to be scope-free, so let's have the compiler
      help verify that.
      
      * runtime/CommonSlowPaths.cpp:
      (JSC::SLOW_PATH_DECL):
      * runtime/CommonSlowPaths.h:
      * runtime/Executable.cpp:
      (JSC::EvalExecutable::create):
      (JSC::EvalExecutable::compileInternal):
      (JSC::ProgramExecutable::compileInternal):
      (JSC::FunctionExecutable::produceCodeBlockFor):
      (JSC::FunctionExecutable::compileForCallInternal):
      (JSC::FunctionExecutable::compileForConstructInternal):
      * runtime/Executable.h:
      (JSC::EvalExecutable::numVariables):
      (JSC::EvalExecutable::numberOfFunctionDecls):
      * runtime/ExecutionHarness.h:
      (JSC::prepareForExecutionImpl):
      (JSC::prepareFunctionForExecutionImpl):
      (JSC::installOptimizedCode): Fiddled with executable initialization so
      that we can always generate a full scope chain before we go to link a
      code block. We need this because code block linking now depends on the
      scope chain to link non-local variable resolution opcodes.
      
      * runtime/JSActivation.h:
      * runtime/JSGlobalObject.cpp:
      (JSC::JSGlobalObject::JSGlobalObject):
      (JSC::JSGlobalObject::createEvalCodeBlock):
      * runtime/JSGlobalObject.h:
      (JSC::JSGlobalObject::varInjectionWatchpoint):
      * runtime/JSGlobalObjectFunctions.cpp:
      (JSC::globalFuncEval):
      * runtime/JSNameScope.h:
      * runtime/JSScope.cpp:
      (JSC::abstractAccess):
      (JSC::JSScope::objectAtScope):
      (JSC::JSScope::depth):
      (JSC::JSScope::resolve):
      (JSC::JSScope::abstractResolve): Updated to match changes explained above.
      
      * runtime/JSScope.h:
      (JSC::makeType):
      (JSC::needsVarInjectionChecks):
      (JSC::ResolveOp::ResolveOp):
      (JSC::ResolveModeAndType::ResolveModeAndType):
      (JSC::ResolveModeAndType::mode):
      (JSC::ResolveModeAndType::type):
      (JSC::ResolveModeAndType::operand): Removed the old variable resolution
      state machine, since it's unused now. Added logic for performing abstract
      variable resolution at link time. This is used by codeblock linking.
      
      * runtime/ObjectPrototype.cpp:
      (JSC::objectProtoFuncValueOf):
      (JSC::objectProtoFuncHasOwnProperty):
      (JSC::objectProtoFuncIsPrototypeOf):
      (JSC::objectProtoFuncDefineGetter):
      (JSC::objectProtoFuncDefineSetter):
      (JSC::objectProtoFuncLookupGetter):
      (JSC::objectProtoFuncLookupSetter):
      (JSC::objectProtoFuncPropertyIsEnumerable):
      (JSC::objectProtoFuncToLocaleString):
      (JSC::objectProtoFuncToString): Fixed some pre-existing bugs in
      'this' value conversion, which I made much more common by removing
      special cases in bytecode generation.
      
      These functions need to invoke toThis() because they observe the 'this'
      value.
      
      * runtime/StringPrototype.cpp:
      (JSC::checkObjectCoercible):
      (JSC::stringProtoFuncReplace):
      (JSC::stringProtoFuncCharAt):
      (JSC::stringProtoFuncCharCodeAt):
      (JSC::stringProtoFuncConcat):
      (JSC::stringProtoFuncIndexOf):
      (JSC::stringProtoFuncLastIndexOf):
      (JSC::stringProtoFuncMatch):
      (JSC::stringProtoFuncSearch):
      (JSC::stringProtoFuncSlice):
      (JSC::stringProtoFuncSplit):
      (JSC::stringProtoFuncSubstr):
      (JSC::stringProtoFuncSubstring):
      (JSC::stringProtoFuncToLowerCase):
      (JSC::stringProtoFuncToUpperCase):
      (JSC::stringProtoFuncLocaleCompare):
      (JSC::stringProtoFuncBig):
      (JSC::stringProtoFuncSmall):
      (JSC::stringProtoFuncBlink):
      (JSC::stringProtoFuncBold):
      (JSC::stringProtoFuncFixed):
      (JSC::stringProtoFuncItalics):
      (JSC::stringProtoFuncStrike):
      (JSC::stringProtoFuncSub):
      (JSC::stringProtoFuncSup):
      (JSC::stringProtoFuncFontcolor):
      (JSC::stringProtoFuncFontsize):
      (JSC::stringProtoFuncAnchor):
      (JSC::stringProtoFuncLink):
      (JSC::trimString): Fixed some pre-existing bugs in
      'this' value conversion, which I made much more common by removing
      special cases in bytecode generation.
      
      These functions need to invoke toThis() because they observe the 'this'
      value.
      
      * runtime/StructureRareData.cpp:
      * runtime/VM.cpp:
      (JSC::VM::~VM):
      
      * runtime/WriteBarrier.h:
      (JSC::WriteBarrierBase::slot): Modified to reduce casting in client code.
      
      LayoutTests:
      
      This patch removed special-case 'this' resolution from bytecode, making
      some pre-existing edge cases in 'this' value treatment much more common.
      
      I updated the test results below, and added some tests, to match bug
      fixes for these cases.
      
      * fast/js/script-tests/array-functions-non-arrays.js:
      * fast/js/array-functions-non-arrays-expected.txt: As specified, it's
      not an error to pass a non-array to toLocaleString. Our new result
      matches Firefox and Chrome.
      
      * fast/js/array-prototype-properties-expected.txt: Updated for slightly
      clearer error message.
      
      * fast/js/basic-strict-mode-expected.txt: Updated for slightly more
      standard error message.
      
      * fast/js/object-prototype-toString-expected.txt: Added.
      * fast/js/object-prototype-toString.html: Added. This test demonstrates
      why we now fail a Sputnik test below, while Firefox and Chrome pass it.
      (The test doesn't test what it thinks it tests, and this test verifies
      that we get right what it does think it tests.)
      
      * fast/js/string-prototype-function-this-expected.txt: Added.
      * fast/js/string-prototype-function-this.html: Added. This test shows
      that we CheckObjectCoercible in string prototype functions. (We used
      to get this wrong, but Sputnik tests made it seem like we got it right
      because they didn't test the dynamic scope case.)
      
      * sputnik/Conformance/11_Expressions/11.1_Primary_Expressions/11.1.1_The_this_Keyword/S11.1.1_A2-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.4_Array/15.4.4/15.4.4.3_Array_prototype_toLocaleString/S15.4.4.3_A2_T1-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.10_String.prototype.match/S15.5.4.10_A1_T3-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.11_String.prototype.replace/S15.5.4.11_A1_T3-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.12_String.prototype.search/S15.5.4.12_A1_T3-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.13_String.prototype.slice/S15.5.4.13_A1_T3-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.14_String.prototype.split/S15.5.4.14_A1_T3-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.15_String.prototype.substring/S15.5.4.15_A1_T3-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.6_String.prototype.concat/S15.5.4.6_A1_T3-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.7_String.prototype.indexOf/S15.5.4.7_A1_T3-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.8_String.prototype.lastIndexOf/S15.5.4.8_A1_T3-expected.txt:
      
      Updated to show failing results. Firefox and Chrome also fail these
      tests, and the ES5 spec seems to mandate failure. Because these tests
      resolve a String.prototype function at global scope, the 'this' value
      for the call is an environment record. Logically, an environment record
      converts to 'undefined' at the call site, and should then fail the
      CheckObjectCoercible test.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153221 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      58c86752
    • oliver@apple.com's avatar
      fourthTier: isContravenedByStructure is backwards · d05719a4
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117366
      
      We should be checking if arrayModeForStructure(structure) is a
      subset of arrayModesThatPassFiltering(), not the other way around.
      Also renamed isContravenedByStructure to better reflect what the
      function is trying to determine.
      
      Rubber stamped by Filip Pizlo.
      
      * dfg/DFGArrayMode.h:
      (JSC::DFG::ArrayMode::structureWouldPassArrayModeFiltering):
      * dfg/DFGTypeCheckHoistingPhase.cpp:
      (JSC::DFG::TypeCheckHoistingPhase::noticeStructureCheckAccountingForArrayMode):
      (JSC::DFG::ArrayTypeCheck::isContravenedByValue):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153220 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      d05719a4
    • oliver@apple.com's avatar
      fourthTier: Type check hoisting phase has a dead if statement · 75d8e086
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117510
      
      Reviewed by Geoffrey Garen.
      
      * dfg/DFGTypeCheckHoistingPhase.cpp:
      (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153219 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      75d8e086
    • 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