1. 25 Jul, 2013 40 commits
    • oliver@apple.com's avatar
      fourthTier: DFG should separate link phase into things that must be done... · 90fce824
      oliver@apple.com authored
      fourthTier: DFG should separate link phase into things that must be done concurrently and things that must be done synchronously, and have a way of passing data from one to the other
      https://bugs.webkit.org/show_bug.cgi?id=116060
      
      Reviewed by Gavin Barraclough.
      
      This introduces the concept of a DFG::Plan, which corresponds to:
      
      - The data that the concurrent DFG or FTL need to start compiling a CodeBlock.
        This mostly includes basic things like CodeBlock*, but also a list of
        must-handle values for OSR entry.
      
      - The data that the synchronous linker need to link in code compiled by a
        concurrent compilation thread. This is further encapsulated by DFG::Finalizer,
        since the data, and the actions that need to be taken, are different in DFG
        versus FTL. This patch also institutes the policy that the concurrent
        compilation thread shall not use LinkBuffer::performFinalization(), since that
        code assumes that it's running on the same thread that will actually run the
        code.
      
      - The actions that need to be taken to compile code. In other words, most of the
        code that previously lived in DFGDriver.cpp now lives in
        DFG::Plan::compileInThread().
      
      - The actions that need to be taken when synchronously linking the code. This
        includes "really" adding watchpoints and identifiers, checking watchpoint and
        chain validity, and running the DFG::Finalizer.
      
      Currently, DFGDriver just creates a Plan and runs it synchronously. But in the
      future, we will be able to malloc some Plans and enqueue them, and have the
      concurrent thread dequeue them and call Plan::compileInThread().
      
      For now, this has no behavior or performance change.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * assembler/LinkBuffer.cpp:
      (JSC::LinkBuffer::performFinalization):
      * assembler/LinkBuffer.h:
      (LinkBuffer):
      (JSC::LinkBuffer::LinkBuffer):
      (JSC::LinkBuffer::~LinkBuffer):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::initialize):
      (JSC::DFG::AbstractState::executeEffects):
      * dfg/DFGAbstractValue.cpp:
      (JSC::DFG::AbstractValue::setFuturePossibleStructure):
      (JSC::DFG::AbstractValue::filterFuturePossibleStructure):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::addStructureTransitionCheck):
      (JSC::DFG::ByteCodeParser::handleGetById):
      (JSC::DFG::ByteCodeParser::parseResolveOperations):
      (JSC::DFG::ByteCodeParser::parseBlock):
      (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
      (JSC::DFG::ByteCodeParser::parseCodeBlock):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
      * dfg/DFGDriver.cpp:
      (DFG):
      (JSC::DFG::compile):
      * dfg/DFGFailedFinalizer.cpp: Added.
      (DFG):
      (JSC::DFG::FailedFinalizer::FailedFinalizer):
      (JSC::DFG::FailedFinalizer::~FailedFinalizer):
      (JSC::DFG::FailedFinalizer::finalize):
      (JSC::DFG::FailedFinalizer::finalizeFunction):
      * dfg/DFGFailedFinalizer.h: Added.
      (DFG):
      (FailedFinalizer):
      * dfg/DFGFinalizer.cpp: Added.
      (DFG):
      (JSC::DFG::Finalizer::Finalizer):
      (JSC::DFG::Finalizer::~Finalizer):
      * dfg/DFGFinalizer.h: Added.
      (DFG):
      (Finalizer):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::canOptimizeStringObjectAccess):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::Graph):
      (JSC::DFG::Graph::dump):
      (DFG):
      * dfg/DFGGraph.h:
      (Graph):
      (JSC::DFG::Graph::masqueradesAsUndefinedWatchpointIsStillValid):
      (JSC::DFG::Graph::compilation):
      (JSC::DFG::Graph::identifiers):
      (JSC::DFG::Graph::watchpoints):
      (JSC::DFG::Graph::chains):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::linkOSRExits):
      (JSC::DFG::JITCompiler::link):
      (JSC::DFG::JITCompiler::compile):
      (JSC::DFG::JITCompiler::compileFunction):
      (JSC::DFG::JITCompiler::linkFunction):
      (DFG):
      (JSC::DFG::JITCompiler::disassemble):
      * dfg/DFGJITCompiler.h:
      (JITCompiler):
      (JSC::DFG::JITCompiler::addLazily):
      * dfg/DFGJITFinalizer.cpp: Added.
      (DFG):
      (JSC::DFG::JITFinalizer::JITFinalizer):
      (JSC::DFG::JITFinalizer::~JITFinalizer):
      (JSC::DFG::JITFinalizer::finalize):
      (JSC::DFG::JITFinalizer::finalizeFunction):
      (JSC::DFG::JITFinalizer::finalizeCommon):
      * dfg/DFGJITFinalizer.h: Added.
      (DFG):
      (JITFinalizer):
      * dfg/DFGPlan.cpp: Added.
      (DFG):
      (JSC::DFG::dumpAndVerifyGraph):
      (JSC::DFG::Plan::Plan):
      (JSC::DFG::Plan::~Plan):
      (JSC::DFG::Plan::compileInThread):
      (JSC::DFG::Plan::isStillValid):
      (JSC::DFG::Plan::reallyAdd):
      (JSC::DFG::Plan::finalize):
      * dfg/DFGPlan.h: Added.
      (DFG):
      (Plan):
      (JSC::DFG::Plan::vm):
      * dfg/DFGPredictionInjectionPhase.cpp:
      (JSC::DFG::PredictionInjectionPhase::run):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::identifierUID):
      (JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure):
      * dfg/DFGTypeCheckHoistingPhase.cpp:
      (JSC::DFG::TypeCheckHoistingPhase::run):
      * ftl/FTLGeneratedFunction.h: Added.
      (FTL):
      * ftl/FTLJITFinalizer.cpp: Added.
      (FTL):
      (JSC::FTL::JITFinalizer::JITFinalizer):
      (JSC::FTL::JITFinalizer::~JITFinalizer):
      (JSC::FTL::JITFinalizer::finalize):
      (JSC::FTL::JITFinalizer::finalizeFunction):
      * ftl/FTLJITFinalizer.h: Added.
      (FTL):
      (JITFinalizer):
      (JSC::FTL::JITFinalizer::initializeExitThunksLinkBuffer):
      (JSC::FTL::JITFinalizer::initializeEntrypointLinkBuffer):
      (JSC::FTL::JITFinalizer::initializeCode):
      (JSC::FTL::JITFinalizer::initializeFunction):
      (JSC::FTL::JITFinalizer::initializeArityCheck):
      (JSC::FTL::JITFinalizer::initializeJITCode):
      * ftl/FTLLink.cpp:
      (JSC::FTL::link):
      * ftl/FTLLink.h:
      (FTL):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::linkOSRExitsAndCompleteInitializationBlocks):
      * ftl/FTLState.cpp:
      (JSC::FTL::State::State):
      * ftl/FTLState.h:
      (FTL):
      (State):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153161 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      90fce824
    • oliver@apple.com's avatar
      fourthTier: Refactor JITStubs.cpp to move CPU specific parts out into their own files. · cd1c2e74
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116135.
      
      Reviewed by Michael Saboff.
      
      This mod only moves the CPU specific parts out. There is no code change.
      Tested on debug builds of X86, X86_64, ARM and ARMv7. The SH4 and MIPS
      ports are untested. Windows port also not tested.
      
      * GNUmakefile.list.am:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * jit/JITStubs.cpp:
      (JSC::performPlatformSpecificJITAssertions):
      * jit/JITStubsARM.h: Added.
      (JSC::ctiTrampoline):
      (JSC::ctiTrampolineEnd):
      (JSC::ctiVMThrowTrampoline):
      (JSC::ctiOpThrowNotCaught):
      (JSC::performARMJITAssertions):
      * jit/JITStubsARMv7.h: Added.
      (JSC::ctiTrampoline):
      (JSC::ctiVMThrowTrampoline):
      (JSC::ctiOpThrowNotCaught):
      (JSC::performARMv7JITAssertions):
      * jit/JITStubsMIPS.h: Added.
      (JSC::performMIPSJITAssertions):
      * jit/JITStubsSH4.h: Added.
      * jit/JITStubsX86.h: Added.
      * jit/JITStubsX86_64.h: Added.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153160 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      cd1c2e74
    • oliver@apple.com's avatar
      fourthTier: Segfault in jsc with simple test program when running with profile dumping enabled · 118f1300
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116082
      
      It's crashing because CodeBlock::baselineVersion() doesn't know how to handle the case where 'this' is the
      baseline version but it hasn't been assigned to the m_blahCodeBlock field in BlahExecutable. The fix is to
      check if we're the baseline version in baselineVersion() and return this if so.
      
      Reviewed by Filip Pizlo.
      
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::baselineVersion):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153159 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      118f1300
    • oliver@apple.com's avatar
      fourthTier: Rename StructureCheckHoistingPhase to TypeCheckHoistingPhase · dcaa7482
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115938
      
      We're going to add some more types of check hoisting soon, so let's have
      the right name here.
      
      Rubber stamped by Filip Pizlo.
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * dfg/DFGStructureCheckHoistingPhase.cpp: Removed.
      * dfg/DFGStructureCheckHoistingPhase.h: Removed.
      * dfg/DFGTypeCheckHoistingPhase.cpp: Added.
      (DFG):
      (TypeCheckHoistingPhase):
      (JSC::DFG::TypeCheckHoistingPhase::TypeCheckHoistingPhase):
      (JSC::DFG::TypeCheckHoistingPhase::run):
      (JSC::DFG::TypeCheckHoistingPhase::shouldConsiderForHoisting):
      (JSC::DFG::TypeCheckHoistingPhase::noticeStructureCheck):
      (CheckData):
      (JSC::DFG::TypeCheckHoistingPhase::CheckData::CheckData):
      (JSC::DFG::performTypeCheckHoisting):
      * dfg/DFGTypeCheckHoistingPhase.h: Added.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153158 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      dcaa7482
    • oliver@apple.com's avatar
      fourthTier: SpeculativeJIT::checkArray should use the correct ExitKind · 628ff3fb
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115943
      
      Currently it uses Uncountable, which gives us no information if we end up exiting due to a
      mismatched ClassInfo pointer. It should instead use BadType and should pass the correct
      JSValueSource and Node instead of passing empty values.
      
      Reviewed by Filip Pizlo.
      
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::checkArray):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153157 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      628ff3fb
    • oliver@apple.com's avatar
      fourthTier: FTL should support Jump and ForceOSRExit · 0d018be1
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115942
      
      Reviewed by Oliver Hunt.
      
      Added two obvious nodes: Jump and ForceOSRExit. We already had everything we needed
      to support them.
      
      Adding these increases our coverage a fair bit, and revealed a bug: LLVM's full
      instruction selector currently appears to mishandle doubles in constant pools (or
      just constant pools in general) with the small code model in the MCJIT. But switching
      to FastISel "fixes" it. That's what this patch does, for now. This will probably
      actually be permanent; the FastISel does pretty much everything we would ever want,
      at least in the foreseeable future.
      
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      (FTL):
      * ftl/FTLCompile.cpp:
      (JSC::FTL::compile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileBlock):
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileJSConstant):
      (LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::compileJump):
      (JSC::FTL::LowerDFGToLLVM::compileReturn):
      (JSC::FTL::LowerDFGToLLVM::compileForceOSRExit):
      * runtime/Options.h:
      (JSC):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153156 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      0d018be1
    • oliver@apple.com's avatar
      fourthTier: FTL should support CompareStrictEqConstant · 9a58da10
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115941
      
      Reviewed by Mark Hahnenberg.
      
      Pretty simple, but factors out the craziness of comparing against null or undefined
      in a way that is reusable for both == and ===.
      
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileCompareEqConstant):
      (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEqConstant):
      (LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153155 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      9a58da10
    • oliver@apple.com's avatar
      fourthTier: FTL should support CompareEqConstant · aafa46d1
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115939
      
      Reviewed by Oliver Hunt and Mark Hahnenberg.
      
      The most interesting part of this patch is the way I make it easier to deal with
      the inputs to Phi functions. This adds the notion of ValueFromBlock, which you
      can get by doing m_out.anchor(value). You can build up a vector of these, and then
      pass them to m_out.phi(type, vector) in one go.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * ftl/FTLAbbreviatedTypes.h: Added.
      (FTL):
      * ftl/FTLAbbreviations.h:
      (FTL):
      (JSC::FTL::addIncoming):
      (JSC::FTL::buildPhi):
      * ftl/FTLAbstractHeapRepository.h:
      (FTL):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileCompareEqConstant):
      (LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::lowDouble):
      (JSC::FTL::LowerDFGToLLVM::masqueradesAsUndefinedWatchpointIfIsStillValid):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::phi):
      (Output):
      (JSC::FTL::Output::anchor):
      * ftl/FTLValueFromBlock.h: Added.
      (FTL):
      (ValueFromBlock):
      (JSC::FTL::ValueFromBlock::ValueFromBlock):
      (JSC::FTL::ValueFromBlock::value):
      (JSC::FTL::ValueFromBlock::block):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153154 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      aafa46d1
    • oliver@apple.com's avatar
      fourthTier: FTL should support CompareStrictEq · 023d1c71
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115927
      
      Reviewed by Mark Hahnenberg.
      
      Do the sensible thing, and make it so that for common cases, CompareEq is
      implemented in terms of CompareStrictEq in the FTL backend. All of the cases
      we currently support can be done this way.
      
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
      (LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153153 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      023d1c71
    • oliver@apple.com's avatar
      fourthTier: FTL should support Int32ToDouble · afce403e
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115926
      
      Reviewed by Mark Hahnenberg.
      
      This node exists mainly to help the DFG see that a node may have both an int
      and a double representation. But in the FTL, nodes already have multiple
      representations. So this is just a no-op for the FTL.
      
      I considered making it so that the node isn't even inserted if we're doing
      FTL compilation, but that would have required a bunch of conditionalizing in
      the DFG's optimization phases, which sort of expect this node to be present
      and necessary.
      
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileInt32ToDouble):
      (LowerDFGToLLVM):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153152 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      afce403e
    • oliver@apple.com's avatar
      fourthTier: FTL should support LogicalNot · 4965ebc2
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115924
      
      Reviewed by Mark Hahnenberg.
      
      * ftl/FTLAbbreviations.h:
      (JSC::FTL::buildNot):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileLogicalNot):
      (LowerDFGToLLVM):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::bitNot):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153151 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      4965ebc2
    • oliver@apple.com's avatar
      fourthTier: FTL should support CompareGreater, CompareLessEq, and CompareGreaterEq · 1f9b9b7d
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115923
      
      Reviewed by Mark Hahnenberg.
      
      Also fixed a bug where double CompareLess would assert.
      
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileCompareLess):
      (LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::compileCompareLessEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareGreater):
      (JSC::FTL::LowerDFGToLLVM::compileCompareGreaterEq):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153150 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      1f9b9b7d
    • oliver@apple.com's avatar
      fourthTier: FTL CompareEq ObjectUse should handle masquerading · 9eff4657
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115920
      
      Reviewed by Mark Hahnenberg.
      
      We don't yet support watchpoints, but this does all the wiring right up to the
      part where we would have emitted watchpoints. I've also written this in a way that
      makes it easy to use the case where you would have anyway speculated non-masquerading
      even if the watchpoint was invalidated.
      
      This is inherently racy, of course: but the only race here is that you might first
      set the watchpoint, and then the watchpoint is invalidated, and then you compile rest
      of the code in a way that doesn't need the watchpoint. That's fine, since the FTL
      will remember that it had set the watchpoint and then cancel the compilation.
      
      * ftl/FTLAbbreviations.h:
      (JSC::FTL::int8Type):
      * ftl/FTLAbstractHeapRepository.h:
      (FTL):
      * ftl/FTLCommonValues.cpp:
      (JSC::FTL::CommonValues::CommonValues):
      * ftl/FTLCommonValues.h:
      (CommonValues):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
      (JSC::FTL::LowerDFGToLLVM::lowNonNullObject):
      (LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::speculateNonNullObject):
      (JSC::FTL::LowerDFGToLLVM::masqueradesAsUndefinedWatchpointIsStillValid):
      (JSC::FTL::LowerDFGToLLVM::masqueradesAsUndefinedWatchpointIfIsStillValid):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::constInt8):
      (JSC::FTL::Output::load8):
      (JSC::FTL::Output::isZero8):
      (JSC::FTL::Output::notZero8):
      (JSC::FTL::Output::testIsZero8):
      (JSC::FTL::Output::testNonZero8):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153149 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      9eff4657
    • oliver@apple.com's avatar
      fourthTier: DFG shouldn't allocate in the GC heap · f322a221
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115598
      
      Reviewed by Geoffrey Garen.
      
      I believe that we've now fixed this, and this patch just adds the relevant assertion.
      
      * runtime/JSCellInlines.h:
      (JSC::JSCell::JSCell):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153148 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      f322a221
    • oliver@apple.com's avatar
      fourthTier: CodeBlock should be RefCounted · 410b541c
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115594
      
      Reviewed by Geoffrey Garen.
      
      This makes it possible to have the currently-being-compiled CodeBlock not be
      installed in Executable, while also allowing it to point to its intended
      alternative(). So long as we were using ownership and not reference counting, it
      would have been difficult to have both CodeBlock::m_alternative and
      Executable::m_codeBlockForBlah point to the previous CodeBlock.
      
      I also took the opportunity to clean up a bunch of code that appears to have
      rotted.
      
      * assembler/MacroAssemblerCodeRef.h:
      (MacroAssemblerCodePtr):
      (JSC::MacroAssemblerCodePtr::operator==):
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::CodeBlock):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::releaseAlternative):
      (JSC::CodeBlock::setAlternative):
      (CodeBlock):
      (JSC::GlobalCodeBlock::GlobalCodeBlock):
      (JSC::ProgramCodeBlock::ProgramCodeBlock):
      (JSC::EvalCodeBlock::EvalCodeBlock):
      (JSC::FunctionCodeBlock::FunctionCodeBlock):
      * heap/DFGCodeBlocks.cpp:
      (JSC::DFGCodeBlocks::~DFGCodeBlocks):
      (JSC::DFGCodeBlocks::jettison):
      (JSC::DFGCodeBlocks::deleteUnmarkedJettisonedCodeBlocks):
      * heap/DFGCodeBlocks.h:
      (DFGCodeBlocks):
      * heap/Heap.cpp:
      (JSC::Heap::jettisonDFGCodeBlock):
      * heap/Heap.h:
      * jit/JITDriver.h:
      (JSC::jitCompileIfAppropriate):
      (JSC::jitCompileFunctionIfAppropriate):
      * runtime/Executable.cpp:
      (JSC::jettisonCodeBlock):
      (JSC::EvalExecutable::jitCompile):
      (JSC::EvalExecutable::compileInternal):
      (JSC::ProgramExecutable::jitCompile):
      (JSC::ProgramExecutable::compileInternal):
      (JSC::FunctionExecutable::jitCompileForCall):
      (JSC::FunctionExecutable::jitCompileForConstruct):
      (JSC::FunctionExecutable::produceCodeBlockFor):
      (JSC::FunctionExecutable::compileForCallInternal):
      (JSC::FunctionExecutable::compileForConstructInternal):
      * runtime/Executable.h:
      (EvalExecutable):
      (FunctionExecutable):
      (JSC::FunctionExecutable::codeBlockFor):
      * runtime/ExecutionHarness.h:
      (JSC::prepareForExecution):
      (JSC::prepareFunctionForExecution):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153147 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      410b541c
    • oliver@apple.com's avatar
      fourthTier: DFG should have its own notion of StructureChain, and it should be... · 98fb6bf1
      oliver@apple.com authored
      fourthTier: DFG should have its own notion of StructureChain, and it should be possible to validate it after compilation finishes
      https://bugs.webkit.org/show_bug.cgi?id=115841
      
      Reviewed by Oliver Hunt.
      
      This adds IntendedStructureChain, which is like StructureChain, except that it holds a bit
      more information and can be validated independantly of its owning Structure and lexical
      GlobalObject, since it remembers both of those things. It's also malloc'd and RefCounted
      rather than GC'd, so it can be allocated in a concurrent compilation thread.
      
      Gave this class a bunch of methods to allow the following idiom:
      
      - Snapshot a structure chain concurrently. This structure chain may end up being
        wrong in case of races, but in that case we will find out when we try to validate
        it.
      
      - Perform validation on the structure chain itself, without recomputing the chain.
        Previously, many chain validation methods (prototypeChainMayInterceptStoreTo() for
        example) recomputed the chain, and hence, were inherently racy: you could build one
        chain and then validate against a different chain, and hence not realize that the
        chain you did build was actually broken for your purposes, because the chain you
        checked was a different one.
      
      - Validate that the chain is still the right one at any time, allowing the cancellation
        of compilation if there was a race.
      
      Also added DFG::DesiredStructureChains, which tracks those intended structure chains that
      the compiler had already chosen to use. If any of those are invalid at link time, throw
      out the compilation.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/GetByIdStatus.cpp:
      (JSC::GetByIdStatus::computeForChain):
      (JSC::GetByIdStatus::computeFor):
      * bytecode/GetByIdStatus.h:
      (JSC::GetByIdStatus::GetByIdStatus):
      (JSC::GetByIdStatus::chain):
      (GetByIdStatus):
      * bytecode/PutByIdStatus.cpp:
      (JSC::PutByIdStatus::computeFromLLInt):
      (JSC::PutByIdStatus::computeFor):
      * bytecode/PutByIdStatus.h:
      (JSC::PutByIdStatus::PutByIdStatus):
      (JSC::PutByIdStatus::structureChain):
      (PutByIdStatus):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::executeEffects):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::handleGetById):
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      * dfg/DFGDesiredStructureChains.cpp: Added.
      (DFG):
      (JSC::DFG::DesiredStructureChains::DesiredStructureChains):
      (JSC::DFG::DesiredStructureChains::~DesiredStructureChains):
      (JSC::DFG::DesiredStructureChains::areStillValid):
      * dfg/DFGDesiredStructureChains.h: Added.
      (DFG):
      (DesiredStructureChains):
      (JSC::DFG::DesiredStructureChains::addLazily):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::isStillValid):
      (DFG):
      * dfg/DFGGraph.h:
      (Graph):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::link):
      (JSC::DFG::JITCompiler::linkFunction):
      * ftl/FTLLink.cpp:
      (JSC::FTL::link):
      * runtime/IntendedStructureChain.cpp: Added.
      (JSC):
      (JSC::IntendedStructureChain::IntendedStructureChain):
      (JSC::IntendedStructureChain::~IntendedStructureChain):
      (JSC::IntendedStructureChain::isStillValid):
      (JSC::IntendedStructureChain::matches):
      (JSC::IntendedStructureChain::chain):
      (JSC::IntendedStructureChain::mayInterceptStoreTo):
      (JSC::IntendedStructureChain::isNormalized):
      (JSC::IntendedStructureChain::terminalPrototype):
      * runtime/IntendedStructureChain.h: Added.
      (JSC):
      (IntendedStructureChain):
      (JSC::IntendedStructureChain::head):
      (JSC::IntendedStructureChain::size):
      (JSC::IntendedStructureChain::at):
      (JSC::IntendedStructureChain::operator[]):
      (JSC::IntendedStructureChain::last):
      * runtime/Structure.cpp:
      (JSC::Structure::prototypeChainMayInterceptStoreTo):
      * runtime/Structure.h:
      (Structure):
      * runtime/StructureInlines.h:
      (JSC::Structure::storedPrototypeObject):
      (JSC):
      (JSC::Structure::storedPrototypeStructure):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153146 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      98fb6bf1
    • oliver@apple.com's avatar
      fourthTier: Rationalized 'this' conversion, includes subsequent FTL branch fixes · e2fe4ceb
      oliver@apple.com authored
      Reviewed by Oliver Hunt.
      
      Source/JavaScriptCore:
      
          Rationalized 'this' value conversion
          https://bugs.webkit.org/show_bug.cgi?id=115542
      
          This fixes a bunch of Sputnik tests, and some bad pointer access.
      
          The new model is that the callee always performs 'this' value conversion.
      
          My ultimate goal is to break up resolve_with_this into single-result
          opcodes. This step avoids having to add a special form of convert_this
          that distinguishes callers vs callees.
      
          Only the callee knows whether it uses 'this' and/or whether 'this'
          conversion should use StrictMode, so it's most natural to perform
          convert_this in the callee.
      
          * API/JSCallbackFunction.cpp:
          (JSC::JSCallbackFunction::call): Perform 'this' value conversion for
          our callee, since it may observe 'this'.
      
          * API/JSCallbackObjectFunctions.h:
          (JSC::::call): Ditto.
      
          * API/JSContextRef.cpp:
          (JSGlobalContextCreateInGroup): Use a proxy 'this' object in global scope
          even when we're not in the browser. This eliminates some odd cases where
          API clients used to be able to get a direct reference to an environment
          record. Now, any reference to an environment record unambiguously means
          that the VM resolved that record in the scope chain.
      
          (JSContextGetGlobalObject): Removed an incorrect comment. Now that JSC
          participates in the proxy 'this' object scheme, the behavior is not
          WebCore-only.
      
          * API/JSObjectRef.cpp:
          (JSObjectSetPrototype):
          (JSObjectCallAsFunction): Don't perform 'this' value conversion in the
          caller; the callee will do it if needed.
      
          * JavaScriptCore.order: Order!
      
          * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
          * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
          What are the chances that this will work?
      
          * bytecode/CodeBlock.cpp:
          (JSC::CodeBlock::dumpBytecode):
          (JSC::CodeBlock::CodeBlock): Renamed convert_this to to_this, to match our
          other conversion opcodes.
      
          * bytecode/CodeOrigin.h:
          (CodeOrigin):
          (InlineCallFrame):
          (JSC::CodeOrigin::codeOriginOwner): Use the more precise type for our
          executable, so compilation can discover where we're in strict mode.
      
          * bytecode/Opcode.h:
          (JSC::padOpcodeName): Updated for rename.
      
          * bytecompiler/BytecodeGenerator.cpp:
          (JSC::BytecodeGenerator::BytecodeGenerator): Always emit to_this when
          'this' is in use -- strict mode still needs to convert environment
          records to 'undefined'.
      
          * dfg/DFGAbstractState.cpp:
          (JSC::DFG::AbstractState::executeEffects):
          * dfg/DFGByteCodeParser.cpp:
          (JSC::DFG::ByteCodeParser::parseBlock):
          * dfg/DFGCapabilities.h:
          (JSC::DFG::canCompileOpcode): Updated for renames.
      
          * dfg/DFGFixupPhase.cpp:
          (JSC::DFG::FixupPhase::fixupNode): Tightened up this code to consider
          strict mode (a new requirement) and to consider the global object (which
          was always a requirement).
      
          * dfg/DFGGraph.h:
          (JSC::DFG::Graph::globalThisObjectFor):
          (JSC::DFG::Graph::executableFor):
          * dfg/DFGNodeType.h:
          * dfg/DFGOperations.cpp:
          * dfg/DFGOperations.h:
          * dfg/DFGPredictionPropagationPhase.cpp:
          (JSC::DFG::PredictionPropagationPhase::propagate):
          * dfg/DFGSpeculativeJIT32_64.cpp:
          (JSC::DFG::SpeculativeJIT::compile):
          * dfg/DFGSpeculativeJIT64.cpp:
          (JSC::DFG::SpeculativeJIT::compile): Ditto.
      
          * interpreter/Interpreter.cpp:
          (JSC::eval):
          (JSC::Interpreter::execute):
          (JSC::Interpreter::executeCall):
          * interpreter/Interpreter.h: Don't ASSERT about 'this' -- it's our job
          to fix it up if needed.
      
          * jit/JIT.cpp:
          (JSC::JIT::privateCompileMainPass):
          (JSC::JIT::privateCompileSlowCases):
          * jit/JIT.h:
          (JIT):
          * jit/JITOpcodes.cpp:
          (JSC::JIT::emit_op_to_this):
          (JSC::JIT::emitSlow_op_to_this):
          * jit/JITOpcodes32_64.cpp:
          (JSC::JIT::emit_op_to_this):
          (JSC::JIT::emitSlow_op_to_this):
          * jit/JITStubs.cpp:
          (JSC::DEFINE_STUB_FUNCTION):
          * jit/JITStubs.h: Removed special-case code for various kinds of
          conversions. The baseline fast path is now final objects only. It hurt
          my brain to think through how to keep the other fast paths working, and
          our benchmarks do not object.
      
          * llint/LLIntData.cpp:
          (JSC::LLInt::Data::performAssertions):
          * llint/LLIntSlowPaths.cpp:
          (JSC::LLInt::LLINT_SLOW_PATH_DECL):
          * llint/LLIntSlowPaths.h:
          (LLInt):
          * llint/LowLevelInterpreter.asm:
          * llint/LowLevelInterpreter32_64.asm:
          * llint/LowLevelInterpreter64.asm: Updated for renames. Removed some
          special case code, as in the JIT above.
      
          * profiler/ProfileGenerator.cpp:
          (JSC::ProfileGenerator::addParentForConsoleStart):
          * runtime/CallData.cpp:
          (JSC::call):
          * runtime/ClassInfo.h:
          (MethodTable):
          * runtime/Completion.cpp:
          (JSC::evaluate):
          * runtime/DatePrototype.cpp:
          (JSC::dateProtoFuncToJSON): The callee performs 'this' conversion, not
          the caller.
      
          * runtime/GetterSetter.cpp:
          (JSC::callGetter):
          (JSC::callSetter):
          * runtime/GetterSetter.h: Added helper functions for invoking getters
          and setters from C++ code, since this was duplicated in a bunch of
          places.
      
          * runtime/JSActivation.cpp:
          (JSC::JSActivation::toThis):
          * runtime/JSActivation.h:
          (JSActivation):
          * runtime/JSCJSValue.cpp:
          (JSC::JSValue::toThisSlowCase):
          (JSC::JSValue::putToPrimitive):
          * runtime/JSCJSValue.h:
          (JSValue):
          * runtime/JSCJSValueInlines.h:
          (JSC::JSValue::toThis):
          * runtime/JSCell.cpp:
          (JSC::JSCell::toThis):
          * runtime/JSCell.h:
          (JSCell):
          * runtime/JSGlobalObject.cpp:
          (JSC::JSGlobalObject::toThis):
          * runtime/JSGlobalObject.h:
          (JSGlobalObject): Filled out runtime support for converting 'this'
          values as needed, according to the appropriate strictness, using
          helper functions where getter/setter code was duplicated.
      
          * runtime/JSGlobalObjectFunctions.cpp:
          (JSC::globalFuncProtoGetter):
          (JSC::globalFuncProtoSetter): Perform 'this' value conversion, since we
          observe 'this'.
      
          * runtime/JSNameScope.cpp:
          (JSC::JSNameScope::toThis):
          * runtime/JSNameScope.h:
          (JSNameScope): Same as JSActivation.
      
          * runtime/JSObject.cpp:
          (JSC::JSObject::put):
          (JSC::JSObject::setPrototypeWithCycleCheck): Bug fix. Don't peform
          'this' value conversion in this helper function. The __proto__
          setter does this for us, since it's the function that logically observes
          'this' -- and we can ASSERT so. Also, the previous code used
          "globalExec()->thisValue()", which is a read past the beginning of a
          buffer! I don't think this ever worked on purpose.
      
          (JSC::JSObject::toThis):
          (JSC::JSObject::fillGetterPropertySlot):
          * runtime/JSObject.h:
          (JSC::JSObject::inlineGetOwnPropertySlot):
          * runtime/JSScope.cpp:
          (JSC::JSScope::resolveWithThis):
          * runtime/JSString.cpp:
          (JSC::JSString::toThis):
          * runtime/JSString.h:
          (JSString):
          * runtime/PropertySlot.cpp:
          (JSC::PropertySlot::functionGetter):
          * runtime/PropertySlot.h:
          (JSC):
          (JSC::PropertySlot::setGetterSlot):
          (JSC::PropertySlot::setCacheableGetterSlot):
          * runtime/SparseArrayValueMap.cpp:
          (JSC::SparseArrayEntry::get):
          (JSC::SparseArrayEntry::put):
          * runtime/StrictEvalActivation.cpp:
          (JSC::StrictEvalActivation::toThis):
          * runtime/StrictEvalActivation.h:
          (StrictEvalActivation): Ditto.
      
      Source/WebCore:
      
          Rationalized 'this' value conversion
          https://bugs.webkit.org/show_bug.cgi?id=115542
      
      Source/WebKit/mac:
      
          Rationalized 'this' value conversion
          https://bugs.webkit.org/show_bug.cgi?id=115542
      
      Source/WebKit2:
      
          Rationalized 'this' value conversion
          https://bugs.webkit.org/show_bug.cgi?id=115542
      
      LayoutTests:
      
          Rationalized 'this' value conversion
          https://bugs.webkit.org/show_bug.cgi?id=115542
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153145 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      e2fe4ceb
    • oliver@apple.com's avatar
      fourthTier: DFG::ByteCodeParser doesn't need ExecState* · e571c18d
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115582
      
      Reviewed by Geoffrey Garen.
      
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::ByteCodeParser):
      (ByteCodeParser):
      (JSC::DFG::parse):
      * dfg/DFGByteCodeParser.h:
      (DFG):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153144 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      e571c18d
    • oliver@apple.com's avatar
      fourthTier: Profiler should be thread-safe · 4bba8c0b
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115445
      
      Reviewed by Geoffrey Garen.
      
      Change the Profiler::Database API for Compilation creation so that we don't add
      it to the Database until it's completely constructed. This prevents the Database
      from seeing Compilations that are being concurrently constructed.
      
      Change the Profiler::Database itself to do locking for creation of Bytecodes and
      for modifying the map. This map may be consulted by both the main thread and the
      concurrent thread.
      
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::Graph):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::link):
      (JSC::DFG::JITCompiler::linkFunction):
      * jit/JIT.cpp:
      (JSC::JIT::privateCompile):
      * profiler/ProfilerBytecodes.h:
      * profiler/ProfilerDatabase.cpp:
      (JSC::Profiler::Database::ensureBytecodesFor):
      (JSC::Profiler::Database::notifyDestruction):
      (JSC::Profiler::Database::addCompilation):
      * profiler/ProfilerDatabase.h:
      (Database):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153143 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      4bba8c0b
    • oliver@apple.com's avatar
      fourthTier: DFG tries to ref/deref StringImpls in a ton of places · 02039469
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115300
      
      Source/JavaScriptCore:
      
      Reviewed by Geoffrey Garen.
      
      Change any code transitively called from DFG compilation to use StringImpl*
      directly instead of String, Identifier, or PropertyName. I use the convention
      of passing "StringImpl* uid" instead of an Identifier or PropertyName.
      
      Switch over any code transitively called from DFG compilation to use CStrings
      whenever possible for all of its debug dumping.
      
      This makes it possible to compile things without hitting the ref/deref
      assertion in StringImpl.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::inferredName):
      (JSC::CodeBlock::sourceCodeForTools):
      (JSC::CodeBlock::sourceCodeOnOneLine):
      (JSC::constantName):
      (JSC::idName):
      (JSC::CodeBlock::registerName):
      (JSC::regexpToSourceString):
      (JSC::regexpName):
      (JSC::pointerToSourceString):
      (JSC::CodeBlock::printUnaryOp):
      (JSC::CodeBlock::printBinaryOp):
      (JSC::CodeBlock::printConditionalJump):
      (JSC::CodeBlock::printGetByIdOp):
      (JSC::dumpStructure):
      (JSC::CodeBlock::printCallOp):
      (JSC::CodeBlock::printPutByIdOp):
      (JSC::CodeBlock::printStructure):
      (JSC::CodeBlock::printStructures):
      (JSC::CodeBlock::dumpBytecode):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      * bytecode/CodeBlockHash.cpp:
      (JSC::CodeBlockHash::CodeBlockHash):
      * bytecode/CodeOrigin.cpp:
      (JSC::InlineCallFrame::inferredName):
      * bytecode/CodeOrigin.h:
      (InlineCallFrame):
      * bytecode/GetByIdStatus.cpp:
      (JSC::GetByIdStatus::computeFromLLInt):
      (JSC::GetByIdStatus::computeForChain):
      (JSC::GetByIdStatus::computeFor):
      * bytecode/GetByIdStatus.h:
      (JSC):
      (GetByIdStatus):
      * bytecode/PutByIdStatus.cpp:
      (JSC::PutByIdStatus::computeFromLLInt):
      (JSC::PutByIdStatus::computeFor):
      * bytecode/PutByIdStatus.h:
      (JSC):
      (PutByIdStatus):
      * bytecode/ReduceWhitespace.cpp:
      (JSC::reduceWhitespace):
      * bytecode/ReduceWhitespace.h:
      (JSC):
      * bytecode/ResolveGlobalStatus.cpp:
      (JSC::computeForStructure):
      (JSC::ResolveGlobalStatus::computeFor):
      * bytecode/ResolveGlobalStatus.h:
      (JSC):
      (ResolveGlobalStatus):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::executeEffects):
      * dfg/DFGByteCodeParser.cpp:
      (ByteCodeParser):
      (JSC::DFG::ByteCodeParser::parseResolveOperations):
      (JSC::DFG::ByteCodeParser::parseBlock):
      (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      * dfg/DFGDesiredIdentifiers.cpp: Added.
      (DFG):
      (JSC::DFG::DesiredIdentifiers::DesiredIdentifiers):
      (JSC::DFG::DesiredIdentifiers::~DesiredIdentifiers):
      (JSC::DFG::DesiredIdentifiers::addLazily):
      (JSC::DFG::DesiredIdentifiers::reallyAdd):
      * dfg/DFGDesiredIdentifiers.h: Added.
      (DFG):
      (DesiredIdentifiers):
      (JSC::DFG::DesiredIdentifiers::numberOfIdentifiers):
      (JSC::DFG::DesiredIdentifiers::at):
      (JSC::DFG::DesiredIdentifiers::operator[]):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::isStringPrototypeMethodSane):
      (JSC::DFG::FixupPhase::canOptimizeStringObjectAccess):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::Graph):
      (JSC::DFG::Graph::dump):
      * dfg/DFGGraph.h:
      (Graph):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::link):
      * dfg/DFGOperations.cpp:
      * dfg/DFGOperations.h:
      * dfg/DFGRepatch.cpp:
      (JSC::DFG::tryBuildGetByIDList):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::identifierUID):
      (JSC::DFG::SpeculativeJIT::callOperation):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::cachedGetById):
      (JSC::DFG::SpeculativeJIT::cachedPutById):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::cachedGetById):
      (JSC::DFG::SpeculativeJIT::cachedPutById):
      (JSC::DFG::SpeculativeJIT::compile):
      * parser/SourceCode.cpp: Added.
      (JSC):
      (JSC::SourceCode::toUTF8):
      * parser/SourceCode.h:
      (SourceCode):
      * profiler/ProfilerBytecodes.cpp:
      (JSC::Profiler::Bytecodes::toJS):
      * profiler/ProfilerBytecodes.h:
      (JSC::Profiler::Bytecodes::inferredName):
      (JSC::Profiler::Bytecodes::sourceCode):
      (Bytecodes):
      * runtime/Identifier.h:
      (JSC::Identifier::utf8):
      (JSC):
      * runtime/Structure.cpp:
      (JSC::Structure::addPropertyTransitionToExistingStructureImpl):
      (JSC::Structure::addPropertyTransitionToExistingStructure):
      (JSC::Structure::addPropertyTransitionToExistingStructureConcurrently):
      (JSC::Structure::getConcurrently):
      (JSC::Structure::prototypeChainMayInterceptStoreTo):
      (JSC):
      * runtime/Structure.h:
      (Structure):
      * runtime/StructureInlines.h:
      (JSC::Structure::getConcurrently):
      
      Source/WTF:
      
      Reviewed by Geoffrey Garen.
      
      Make it possible to do more things directly to StringImpl*'s, including being
      able to directly do utf8 conversion on a substring without creating the
      substring first.
      
      Add assertions to StringImpl that it isn't being ref/deref'd from the
      compilation thread.
      
      * wtf/PrintStream.cpp:
      (WTF::printInternal):
      (WTF):
      * wtf/PrintStream.h:
      (WTF):
      (WTF::printInternal):
      * wtf/StringPrintStream.h:
      (WTF):
      (WTF::toCString):
      * wtf/text/StringImpl.cpp:
      (WTF::StringImpl::utf8ForRange):
      (WTF::StringImpl::utf8):
      (WTF):
      * wtf/text/StringImpl.h:
      (StringImpl):
      (WTF::StringImpl::hasAtLeastOneRef):
      (WTF::StringImpl::ref):
      (WTF::StringImpl::deref):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153142 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      02039469
    • oliver@apple.com's avatar
      fourthTier: Structure transition table keys don't have to ref their StringImpl's · 36e01a77
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115525
      
      Reviewed by Geoffrey Garen.
      
      The structure transition table basically maps string to structure. The string is
      always also stored, and ref'd, in the structure in Structure::m_nameInPrevious.
      m_nameInPrevious is never mutated, and never cleared. The string cannot die unless
      the structure dies. If the structure dies, then that entry in the transition map
      becomes a zombie anyway and we will detect this separately.
      
      So, we don't need to use RefPtr<StringImpl>. We can just use StringImpl*.
      
      This also fixes a goof where we were getting the StringImpl's hash rather than
      using a pointer hash. Not only is the latter faster, but it prevents my change
      from leading to crashes: with my change we can have zombie keys, not just zombie
      values. They will exist only until the next map mutation, which will clear them.
      Lookups will work fine because the lookup routine will reject zombies. But it
      does mean that the HashMap will have to deal with dangling StringImpl*'s; all it
      takes to make this work is to ensure that the HashMap itself never dereferences
      them. Using a pointer hash rather than StringImpl::existingHash() accomplishes
      this.
      
      This also ensures that we don't accidentally call ref() or deref() from the
      compilation thread, if the compilation thread inspects the transition table.
      
      And no, we wouldn't have been able to use the HashMap<RefPtr<...>, ...>
      specialization, because the transition table is actually
      HashMap<pair<RefPtr<StringImpl>, unsigned>, ...>: hence that specialization
      doesn't kick in. We could have written a new specialization or something, but
      that seemed like a lot of work given that we don't need the table to be ref'ing
      the strings anyways.
      
      * runtime/Structure.cpp:
      (JSC::StructureTransitionTable::add):
      * runtime/StructureTransitionTable.h:
      (StructureTransitionTable):
      (Hash):
      (JSC::StructureTransitionTable::Hash::hash):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153141 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      36e01a77
    • oliver@apple.com's avatar
      fourthTier: Structure::addPropertyTransitionToExistingStructure should be thread-safe · cece4b66
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115468
      
      Reviewed by Geoffrey Garen.
      
      This makes the main thread modify the transition table while holding a lock. Note
      that the GC might modify its weak pointers without locking, but the GC will lock out
      the compilation thread anyway. The map will then only reshape in response to add()
      and set(), which happen while holding a lock.
      
      This allows the compilation thread to now query transition tables safely, provided it
      holds a lock when doing so.
      
      Also changed LLVM asm printer initialization to just initialize the X86 one. It makes
      sense for us to just initialize the asm printer(s) that we actually use; you could
      imagine us being linked to a system LLVM that has cross-compilation support; there is
      no point in the WebKit or JSC process doing work to initialize all of those targets.
      That part was rubber stamped by Mark Hahnenberg.
      
      * bytecode/PutByIdStatus.cpp:
      (JSC::PutByIdStatus::computeFor):
      * runtime/InitializeThreading.cpp:
      (JSC::initializeThreadingOnce):
      * runtime/Structure.cpp:
      (JSC::Structure::addPropertyTransitionToExistingStructureImpl):
      (JSC::Structure::addPropertyTransitionToExistingStructure):
      (JSC):
      (JSC::Structure::addPropertyTransitionToExistingStructureConcurrently):
      (JSC::Structure::addPropertyTransition):
      (JSC::Structure::nonPropertyTransition):
      * runtime/Structure.h:
      (Structure):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153140 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      cece4b66
    • oliver@apple.com's avatar
      fourthTier: Structure::getConcurrently() may be called from for uncacheable... · ac8aba9a
      oliver@apple.com authored
      fourthTier: Structure::getConcurrently() may be called from for uncacheable dictionaries, and this is safe
      https://bugs.webkit.org/show_bug.cgi?id=115464
      
      Reviewed by Oliver Hunt and Geoffrey Garen.
      
      This can happen for example transitively from JSObject::put(). getCurrently() does
      work for uncacheable dictionaries; it just has the obvious race that right after it
      returns, the result it returned may no longer be right. This isn't an issue if it was
      called on the main thread, and may not be an issue in some other situations.
      
      So, we should just remove the assertion, since the only thing it buys us is crashes.
      
      * runtime/Structure.cpp:
      (JSC::Structure::getConcurrently):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153139 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      ac8aba9a
    • oliver@apple.com's avatar
      fourthTier: Use hw.availcpu instead of hw.ncpu, and configure LLVM with --enable-zlib=no · 3f7f506b
      oliver@apple.com authored
      Rubber stamped by Mark Rowe.
      
      * Scripts/copy-webkitlibraries-to-product-directory:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153138 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      3f7f506b
    • oliver@apple.com's avatar
      fourthTier: Don't link gtest into JavaScriptCore · 140c67fd
      oliver@apple.com authored
      Rubber stamped by Mark Rowe.
      
      * Configurations/JavaScriptCore.xcconfig:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153137 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      140c67fd
    • oliver@apple.com's avatar
      fourthTier: Updated LLVM drops to include MCJIT fixes and newly exposed API. · d6d7c660
      oliver@apple.com authored
      Rubber stamped by Mark Hahnenberg.
      
      * LLVMIncludesMountainLion.tar.bz2:
      * LLVMLibrariesMountainLion.tar.bz2:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153136 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      d6d7c660
    • oliver@apple.com's avatar
      fourthTier: String::utf8() should also be available as StringImpl::utf8() so... · 1d1a380b
      oliver@apple.com authored
      fourthTier: String::utf8() should also be available as StringImpl::utf8() so that you don't have to ref() a StringImpl just to get its utf8()
      https://bugs.webkit.org/show_bug.cgi?id=115393
      
      Reviewed by Geoffrey Garen.
      
      Source/JavaScriptCore:
      
      * runtime/JSGlobalObjectFunctions.cpp:
      (JSC::encode):
      
      Source/WebCore:
      
      No new tests because no new behavior.
      
      * Modules/websockets/WebSocket.cpp:
      (WebCore::WebSocket::close):
      * Modules/websockets/WebSocketChannel.cpp:
      (WebCore::WebSocketChannel::send):
      * html/MediaFragmentURIParser.cpp:
      (WebCore::MediaFragmentURIParser::parseFragments):
      
      Source/WTF:
      
      * WTF.xcodeproj/project.pbxproj:
      * wtf/text/ConversionMode.h: Added.
      (WTF):
      * wtf/text/StringImpl.cpp:
      (WTF):
      (WTF::putUTF8Triple):
      (WTF::StringImpl::utf8):
      * wtf/text/StringImpl.h:
      (StringImpl):
      * wtf/text/WTFString.cpp:
      (WTF):
      (WTF::String::utf8):
      * wtf/text/WTFString.h:
      (String):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153135 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      1d1a380b
    • oliver@apple.com's avatar
      fourthTier: ASSERT that commonly used not-thread-safe methods in the runtime... · 634a76a2
      oliver@apple.com authored
      fourthTier: ASSERT that commonly used not-thread-safe methods in the runtime are not being called during compilation
      https://bugs.webkit.org/show_bug.cgi?id=115297
      
      Source/JavaScriptCore:
      
      Reviewed by Geoffrey Garen.
      
      Put in assertions that we're not doing bad things in compilation threads. Also
      factored compilation into compile+link so that even though we don't yet have
      concurrent compilation, we can be explicit about which parts of DFG work are
      meant to be concurrent, and which aren't.
      
      Also fix a handful of bugs found by these assertions.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/ResolveGlobalStatus.cpp:
      (JSC::computeForStructure):
      * bytecode/Watchpoint.cpp:
      (JSC::WatchpointSet::add):
      (JSC::InlineWatchpointSet::inflateSlow):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::~JITCompiler):
      (DFG):
      (JSC::DFG::JITCompiler::compileBody):
      (JSC::DFG::JITCompiler::compile):
      (JSC::DFG::JITCompiler::link):
      (JSC::DFG::JITCompiler::compileFunction):
      (JSC::DFG::JITCompiler::linkFunction):
      * dfg/DFGJITCompiler.h:
      (JITCompiler):
      * ftl/FTLCompile.cpp:
      (JSC::FTL::compile):
      * ftl/FTLCompile.h:
      (FTL):
      * ftl/FTLLink.cpp: Added.
      (FTL):
      (JSC::FTL::compileEntry):
      (JSC::FTL::link):
      * ftl/FTLLink.h: Added.
      (FTL):
      * ftl/FTLState.cpp:
      (JSC::FTL::State::State):
      * ftl/FTLState.h:
      (FTL):
      (State):
      * runtime/Structure.cpp:
      (JSC::Structure::get):
      (JSC::Structure::prototypeChainMayInterceptStoreTo):
      * runtime/Structure.h:
      (JSC::Structure::materializePropertyMapIfNecessary):
      * runtime/StructureInlines.h:
      (JSC::Structure::get):
      
      Source/WTF:
      
      Reviewed by Geoffrey Garen.
      
      Taught WTF the notion of compilation threads. This allows all parts of our stack
      to assert that we're not being called from a JSC compilation thread. This is in
      WTF because it will probably end up being used in StringImpl and WTFString.
      
      * WTF.xcodeproj/project.pbxproj:
      * wtf/CompilationThread.cpp: Added.
      (WTF):
      (WTF::initializeCompilationThreadsOnce):
      (WTF::initializeCompilationThreads):
      (WTF::isCompilationThread):
      (WTF::exchangeIsCompilationThread):
      * wtf/CompilationThread.h: Added.
      (WTF):
      (CompilationScope):
      (WTF::CompilationScope::CompilationScope):
      (WTF::CompilationScope::~CompilationScope):
      (WTF::CompilationScope::leaveEarly):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153134 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      634a76a2
    • oliver@apple.com's avatar
      fourthTier: FTL should support double variables · 32295c1a
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=113624
      
      Reviewed by Geoffrey Garen.
      
      Made all of the operations that the FTL already supports, also support doubles.
      OSR exit already basically had everything it needed, so no changes there. This
      mostly just glues together bits of DFG IR to LLVM IR, in a straight-forward way.
      
      * ftl/FTLAbbreviations.h:
      (FTL):
      (JSC::FTL::doubleType):
      (JSC::FTL::constReal):
      (JSC::FTL::buildPhi):
      (JSC::FTL::addIncoming):
      (JSC::FTL::buildFAdd):
      (JSC::FTL::buildFSub):
      (JSC::FTL::buildFMul):
      (JSC::FTL::buildFNeg):
      (JSC::FTL::buildSIToFP):
      (JSC::FTL::buildUIToFP):
      (JSC::FTL::buildBitCast):
      (JSC::FTL::buildFCmp):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLCommonValues.cpp:
      (JSC::FTL::CommonValues::CommonValues):
      * ftl/FTLCommonValues.h:
      (CommonValues):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::lower):
      (JSC::FTL::LowerDFGToLLVM::compileGetLocal):
      (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
      (JSC::FTL::LowerDFGToLLVM::compileAdd):
      (JSC::FTL::LowerDFGToLLVM::compileArithSub):
      (JSC::FTL::LowerDFGToLLVM::compileArithMul):
      (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
      (JSC::FTL::LowerDFGToLLVM::compileUInt32ToNumber):
      (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
      (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareLess):
      (JSC::FTL::LowerDFGToLLVM::lowDouble):
      (LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::lowJSValue):
      (JSC::FTL::LowerDFGToLLVM::isCellOrMisc):
      (JSC::FTL::LowerDFGToLLVM::unboxDouble):
      (JSC::FTL::LowerDFGToLLVM::boxDouble):
      (JSC::FTL::LowerDFGToLLVM::speculate):
      (JSC::FTL::LowerDFGToLLVM::speculateNumber):
      (JSC::FTL::LowerDFGToLLVM::speculateRealNumber):
      (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
      (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::constDouble):
      (Output):
      (JSC::FTL::Output::phi):
      (JSC::FTL::Output::doubleAdd):
      (JSC::FTL::Output::doubleSub):
      (JSC::FTL::Output::doubleMul):
      (JSC::FTL::Output::doubleNeg):
      (JSC::FTL::Output::intToFP):
      (JSC::FTL::Output::intToDouble):
      (JSC::FTL::Output::unsignedToFP):
      (JSC::FTL::Output::unsignedToDouble):
      (JSC::FTL::Output::bitCast):
      (JSC::FTL::Output::loadDouble):
      (JSC::FTL::Output::storeDouble):
      (JSC::FTL::Output::doubleEqual):
      (JSC::FTL::Output::doubleNotEqualOrUnordered):
      (JSC::FTL::Output::doubleLessThan):
      (JSC::FTL::Output::doubleLessThanOrEqual):
      (JSC::FTL::Output::doubleGreaterThan):
      (JSC::FTL::Output::doubleGreaterThanOrEqual):
      (JSC::FTL::Output::doubleEqualOrUnordered):
      (JSC::FTL::Output::doubleNotEqual):
      (JSC::FTL::Output::doubleLessThanOrUnordered):
      (JSC::FTL::Output::doubleLessThanOrEqualOrUnordered):
      (JSC::FTL::Output::doubleGreaterThanOrUnordered):
      (JSC::FTL::Output::doubleGreaterThanOrEqualOrUnordered):
      (JSC::FTL::Output::testIsZero64):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153133 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      32295c1a
    • oliver@apple.com's avatar
      fourthTier: SymbolTable should be thread-safe · f72e22e2
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115301
      
      Reviewed by Geoffrey Garen.
      
      Makes SymbolTable thread-safe. Relies on SymbolTableEntry already being immutable,
      other than the WatchpointSet; but the WatchpointSet already has a righteous
      concurrency protocol. So, this patch just protects the SymbolTable's HashMap.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::nameForRegister):
      * bytecompiler/BytecodeGenerator.cpp:
      (JSC::BytecodeGenerator::addVar):
      * runtime/Executable.cpp:
      (JSC::ProgramExecutable::addGlobalVar):
      * runtime/JSActivation.cpp:
      (JSC::JSActivation::getOwnNonIndexPropertyNames):
      (JSC::JSActivation::symbolTablePutWithAttributes):
      * runtime/JSSymbolTableObject.cpp:
      (JSC::JSSymbolTableObject::getOwnNonIndexPropertyNames):
      * runtime/JSSymbolTableObject.h:
      (JSC::symbolTableGet):
      (JSC::symbolTablePut):
      (JSC::symbolTablePutWithAttributes):
      * runtime/SymbolTable.cpp:
      (JSC::SymbolTable::SymbolTable):
      (JSC::SymbolTable::~SymbolTable):
      * runtime/SymbolTable.h:
      (JSC::SymbolTable::find):
      (JSC::SymbolTable::get):
      (JSC::SymbolTable::inlineGet):
      (JSC::SymbolTable::begin):
      (JSC::SymbolTable::end):
      (JSC::SymbolTable::size):
      (JSC::SymbolTable::add):
      (JSC::SymbolTable::set):
      (JSC::SymbolTable::contains):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153132 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      f72e22e2
    • oliver@apple.com's avatar
      fourthTier: WatchpointSet should make racy uses easier to reason about · 9055d143
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115299
      
      Reviewed by Anders Carlsson.
      
      The compiler often does things like:
      
      1c) Observe something that would imply that a WatchpointSet ought to be invalid
      
      2c) Check that it is invalid
      
      The main thread often does things like:
      
      1m) Fire the watchpoint set
      
      2m) Do some other thing that would cause the compiler to assume that the WatchpointSet
      ought to be invalid
      
      An example is structure transitions, where (1c) is the compiler noticing that a
      put_by_id inline cache is in a transition state, with the source structure being S;
      (2c) is the compiler asserting that S's watchpoint set is invalid; (1m) is the main
      thread firing S's watchpoint set before it does the first transition away from S; and
      (2m) is the main thread caching the put_by_id transition away from S.
      
      This is totally fine, except that (1c) and (2c), and (1m) and (2m) could be reordered.
      Probably, in most cases, this ought to do enough things that the main thread probably
      already has some fencing. But the compiler thread definitely doesn't have fencing. In
      any case, we should play it safe and just have additional fencing in all of the
      relevant places.
      
      We already have some idioms to put load-load and store-store fences in the right
      places. But this change just makes WatchpointSet take care of this for us, thus
      reducing the chances of us getting this wrong.
      
      * bytecode/Watchpoint.cpp:
      (JSC::WatchpointSet::notifyWriteSlow):
      * bytecode/Watchpoint.h:
      (WatchpointSet):
      (JSC::WatchpointSet::isStillValid):
      (JSC::WatchpointSet::hasBeenInvalidated):
      (JSC::InlineWatchpointSet::hasBeenInvalidated):
      (JSC::InlineWatchpointSet::notifyWrite):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGDesiredWatchpoints.h:
      (JSC::DFG::GenericDesiredWatchpoints::shouldAssumeMixedState):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153131 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      9055d143
    • oliver@apple.com's avatar
      fourthTier: CFA should defend against results seeming inconsistent due to a... · 67e0f33a
      oliver@apple.com authored
      fourthTier: CFA should defend against results seeming inconsistent due to a watchpoint firing during compilation
      https://bugs.webkit.org/show_bug.cgi?id=115083
      
      Reviewed by Geoffrey Garen.
      
      This ruggedizes our racyness with respect to watchpoints. We want to be able to assert,
      in some places, that a watchpoint-based optimization has only occurred if the
      watchpoint set was still valid. But currently we *can* soundly do watchpoint-based
      optimizations even for invalid watchpoints, so long as we recorded in the IR that we
      had done so; this will then lead to the code being insta-jettisoned after compilation
      completes. Obviously, we don't want this to happen often - but we do want to allow it
      precisely in the case of watchpoint races.
      
      This adds the ability to assert that we hadn't over-watchpointed ourselves, with and
      exemption for races.
      
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::executeEffects):
      * dfg/DFGAbstractValue.cpp:
      (JSC::DFG::AbstractValue::setFuturePossibleStructure):
      (JSC::DFG::AbstractValue::filterFuturePossibleStructure):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::addStructureTransitionCheck):
      (JSC::DFG::ByteCodeParser::parseResolveOperations):
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
      * dfg/DFGDesiredWatchpoints.h:
      (GenericDesiredWatchpoints):
      (JSC::DFG::GenericDesiredWatchpoints::isStillValid):
      (JSC::DFG::GenericDesiredWatchpoints::shouldAssumeMixedState):
      (JSC::DFG::GenericDesiredWatchpoints::isValidOrMixed):
      (JSC::DFG::DesiredWatchpoints::isStillValid):
      (JSC::DFG::DesiredWatchpoints::shouldAssumeMixedState):
      (JSC::DFG::DesiredWatchpoints::isValidOrMixed):
      (DesiredWatchpoints):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::canOptimizeStringObjectAccess):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::masqueradesAsUndefinedWatchpointIsStillValid):
      (Graph):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::link):
      (JSC::DFG::JITCompiler::compile):
      (JSC::DFG::JITCompiler::compileFunction):
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::JITCompiler::addLazily):
      (JITCompiler):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
      * dfg/DFGSpeculativeJIT.h:
      (SpeculativeJIT):
      (JSC::DFG::SpeculativeJIT::masqueradesAsUndefinedWatchpointIsStillValid):
      (JSC::DFG::SpeculativeJIT::speculationWatchpointForMasqueradesAsUndefined):
      (JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
      (JSC::DFG::SpeculativeJIT::compileObjectEquality):
      (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
      (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
      (JSC::DFG::SpeculativeJIT::compileObjectEquality):
      (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
      (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
      (JSC::DFG::SpeculativeJIT::compile):
      * ftl/FTLCompile.cpp:
      (JSC::FTL::compile):
      * ftl/FTLState.h:
      (State):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153130 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      67e0f33a
    • oliver@apple.com's avatar
      fourthTier: AbstractValue methods that deal with watchpoints should have... · fe0cc19e
      oliver@apple.com authored
      fourthTier: AbstractValue methods that deal with watchpoints should have access to Graph, so that in debug mode, Graph can track the history of watchpoint states and detect races
      https://bugs.webkit.org/show_bug.cgi?id=115084
      
      Reviewed by Geoffrey Garen.
      
      The idea is that as part of https://bugs.webkit.org/show_bug.cgi?id=115083, I'll have
      Graph record the initial state of a watchpoint at the time that we decide to take
      advantage of it; then I will use this to disable any watchpoint-related assertions
      in debug mode. Note that this "watchpoint cache" will only be maintained in debug
      mode, so there will be no release performance implications. But to do this, I need to
      ensure that all of the places that reason about watchpoints have access to Graph.
      For example, I'll want AbstractValue::setFuturePossibleStructure to record the state
      of the watchpoint in Graph so that subsequent assertions can check if the watchpoint's
      state had changed since that decision was made.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::initialize):
      (JSC::DFG::AbstractState::executeEffects):
      (JSC::DFG::AbstractState::mergeStateAtTail):
      * dfg/DFGAbstractState.h:
      (JSC::DFG::AbstractState::trySetConstant):
      * dfg/DFGAbstractValue.cpp: Added.
      (DFG):
      (JSC::DFG::AbstractValue::setMostSpecific):
      (JSC::DFG::AbstractValue::set):
      (JSC::DFG::AbstractValue::filter):
      (JSC::DFG::AbstractValue::setFuturePossibleStructure):
      (JSC::DFG::AbstractValue::filterFuturePossibleStructure):
      (JSC::DFG::AbstractValue::dump):
      * dfg/DFGAbstractValue.h:
      (DFG):
      (AbstractValue):
      (JSC::DFG::AbstractValue::setType):
      (JSC::DFG::AbstractValue::filterByValue):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153129 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      fe0cc19e
    • oliver@apple.com's avatar
      fourthTier: Create an equivalent of Structure::get() that can work from a compilation thread · 22fdb104
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=114987
      
      Reviewed by Geoffrey Garen.
      
      This completes the work started by r148570. That patch made it possible to do
      Structure::get() without modifying Structure. This patch takes this further, and
      makes this thread-safe (for non-uncacheable-dictionaries) via
      Structure::getConcurrently(). This method not only doesn't modify Structure, but
      also ensures that any concurrent attempts to add to, remove from, or steal the
      table from that structure doesn't mess up the result of the call. The call may
      return invalidOffset even if a property is *just* about to be added, but it will
      never do the reverse: if it returns a property then you can be sure that the
      structure really does have that property and always will have it.
      
      * bytecode/GetByIdStatus.cpp:
      (JSC::GetByIdStatus::computeFromLLInt):
      (JSC::GetByIdStatus::computeForChain):
      (JSC::GetByIdStatus::computeFor):
      * bytecode/PutByIdStatus.cpp:
      (JSC::PutByIdStatus::computeFromLLInt):
      (JSC::PutByIdStatus::computeFor):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::isStringPrototypeMethodSane):
      * runtime/PropertyMapHashTable.h:
      (PropertyTable):
      (JSC::PropertyTable::findConcurrently):
      (JSC):
      (JSC::PropertyTable::add):
      (JSC::PropertyTable::remove):
      (JSC::PropertyTable::reinsert):
      (JSC::PropertyTable::rehash):
      * runtime/PropertyTable.cpp:
      (JSC::PropertyTable::PropertyTable):
      * runtime/Structure.cpp:
      (JSC::Structure::findStructuresAndMapForMaterialization):
      (JSC::Structure::getConcurrently):
      * runtime/Structure.h:
      (Structure):
      * runtime/StructureInlines.h:
      (JSC::Structure::getConcurrently):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153128 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      22fdb104
    • oliver@apple.com's avatar
      fourthTier: tandem WebKit and LLVM builds should ./configure LLVM if needed · a6b761cc
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=114933
      
      Reviewed by Andy Estes.
      
      This makes it easy to get set up for tandem LLVM builds.
      
      * Scripts/copy-webkitlibraries-to-product-directory:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153127 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      a6b761cc
    • oliver@apple.com's avatar
      fourthTier: WebKit's build system should relink JavaScriptCore if LLVM's... · f0c513fa
      oliver@apple.com authored
      fourthTier: WebKit's build system should relink JavaScriptCore if LLVM's libraries changed but its headers didn't
      https://bugs.webkit.org/show_bug.cgi?id=114926
      
      Source/JavaScriptCore:
      
      Reviewed by Geoffrey Garen.
      
      Use a phony file that includes a phony header to force JavaScriptCore to be relinked
      if necessary. The external LLVM-importing scripts will touch the header if the libraries
      are known to have changed.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * ftl/WebKitLLVMLibraryAnchor.cpp: Added.
      
      Tools:
      
      Reviewed by Geoffrey Garen.
      
      If the LLVM libraries change, then touch a phony header, which will force relink
      of JavaScriptCore.
      
      * Scripts/copy-webkitlibraries-to-product-directory:
      (unpackIfNecessary):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153126 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      f0c513fa
    • oliver@apple.com's avatar
      fourthTier: developing LLVM in tandem with WebKit should be fun and easy · f9e858a3
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=114925
      
      Reviewed by Geoffrey Garen.
      
      This enables building LLVM along with WebKit, so that build-jsc and build-webkit
      will also optionally build LLVM and quickly symlink LLVM's built products into
      the right places.
      
      Most WebKit and JSC hackers will want to rely on the checked-in already-built
      versions of LLVM in WebKitLibraries. But developing both systems in tandem is an
      increasingly common use-case for me, and it may become a common use case for a
      handful of others. Currently, this is really painful: you first have to build
      LLVM, then you have to export-llvm-build (which takes a while), and then you
      have to make sure that your LLVM_LIBRARY_PACKAGE and LLVM_INCLUDE_PACKAGE
      variables are set to point to the thing you exported. The whole process loses
      track of dependencies very quickly: making a tiny change in LLVM requires
      packaging, and then unpackaging, a large number of potentially large headers and
      static libraries. Not only is this slow but it then causes the WebKit build
      system to rebuild anything that transitively includes any LLVM header, which is
      now quite a few files. While this sort of use pattern is still worthwhile if
      you're trying to package a binary drop and test it, it's not great if you're
      just trying to do experimental development that involves making small changes
      in both trees.
      
      This change fixes this use case while keeping the old use cases intact. You can
      do tandem development using one of two modes:
      
      Your own LLVM directory: just set LLVM_SOURCE_PATH to the *absolute* path of
      the LLVM directory you're using. Once this is done, any invocation of a WebKit
      build via build-jsc or build-webkit will also build LLVM, and then quickly
      symlink things into place without perturbing dependency tracking.
      
      Internal LLVM directory: if you check out llvm into a directory called 'llvm'
      right off of the WebKit source tree, then the build system will automatically
      use this.
      
      Here's how this takes care of dependencies:
      
      Headers: the include/llvm and include/llvm-c directories are symlinked into
      $productsDir/usr/local/include. And then everything just works.
      
      Libraries: the build system detects, by reading LLVM's Makefile.config, which
      mode LLVM is built in (like Release+Asserts or Debug+Asserts) and symlinks
      the .a files into $productsDir/<thingy>. It will ranlib those libraries only
      if they have changed, by checking both the modification time and also whether
      the last time we had a symlink, that symlink was from the same directory.
      This helps if you switch to an *older* LLVM build (using LLVM_SOURCE_PATH)
      but that build wasn't yet ranlib'd.
      
      One problem that this does not yet solve is that xcodebuild will not relink
      JavaScriptCore if the only thing that changed was the libraries. I will work
      on this problem separately: https://bugs.webkit.org/show_bug.cgi?id=114926.
      
      * Scripts/copy-webkitlibraries-to-product-directory:
      (unpackIfNecessary):
      (fileContains):
      (fileContentsEquals):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153125 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      f9e858a3
    • oliver@apple.com's avatar
      fourthTier: It should be possible to query WatchpointSets, and add... · 9397e00c
      oliver@apple.com authored
      fourthTier: It should be possible to query WatchpointSets, and add Watchpoints, even if the compiler is running in another thread
      https://bugs.webkit.org/show_bug.cgi?id=114909
      
      Source/JavaScriptCore:
      
      Reviewed by Oliver Hunt.
      
      The idea here is that a concurrent compiler will use watchpoint sets as follows:
      
      During concurrent compilation: It will create Watchpoints, and query WatchpointSets only
      for the purpose of profiling. That is, it will use decide whether it is profitable to
      compile the code "as if" the watchpoint sets are valid.
      
      During synchronous linking: By "linking" I don't necessarily mean the LinkBuffer stuff,
      but just the very bitter end of compilation where we make the JIT code callable. This
      can happen after LinkBuffer stuff. Anyway, this will have to happen synchronously, and
      at that point we can (a) check that all WatchpointSets that we assumed were valid are
      still valid and (b) if they are then we add the watchpoints to those sets. If any of the
      sets are invalid, we give up on this compilation and try again later.
      
      The querying of WatchpointSets is engineered to say that the set is still valid if it
      is so *right now*, but this is done in a racy way and so it may say so spuriously: we
      may, with hopefully low probability, have a set that says it is valid even though it was
      just invalidated. The goal is only to ensure that (i) a set never claims to be invalid
      if it is actually valid, (ii) a set doesn't claim to be valid if it was invalidated
      before compilation even began, and (iii) querying the validity of a set doesn't cause us
      to crash.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/Watchpoint.cpp:
      (JSC::InlineWatchpointSet::inflateSlow):
      * bytecode/Watchpoint.h:
      (WatchpointSet):
      (InlineWatchpointSet):
      (JSC::InlineWatchpointSet::hasBeenInvalidated):
      (JSC::InlineWatchpointSet::isThin):
      (JSC::InlineWatchpointSet::isFat):
      (JSC::InlineWatchpointSet::fat):
      * dfg/DFGDesiredWatchpoints.cpp: Added.
      (DFG):
      (JSC::DFG::DesiredWatchpoints::DesiredWatchpoints):
      (JSC::DFG::DesiredWatchpoints::~DesiredWatchpoints):
      (JSC::DFG::DesiredWatchpoints::addLazily):
      (JSC::DFG::DesiredWatchpoints::reallyAdd):
      (JSC::DFG::DesiredWatchpoints::areStillValid):
      * dfg/DFGDesiredWatchpoints.h: Added.
      (DFG):
      (JSC::DFG::WatchpointForGenericWatchpointSet::WatchpointForGenericWatchpointSet):
      (WatchpointForGenericWatchpointSet):
      (GenericDesiredWatchpoints):
      (JSC::DFG::GenericDesiredWatchpoints::GenericDesiredWatchpoints):
      (JSC::DFG::GenericDesiredWatchpoints::addLazily):
      (JSC::DFG::GenericDesiredWatchpoints::reallyAdd):
      (JSC::DFG::GenericDesiredWatchpoints::areStillValid):
      (DesiredWatchpoints):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::link):
      (JSC::DFG::JITCompiler::compile):
      (JSC::DFG::JITCompiler::compileFunction):
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::JITCompiler::addLazily):
      (JITCompiler):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
      (JSC::DFG::SpeculativeJIT::compileObjectEquality):
      (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
      (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
      (JSC::DFG::SpeculativeJIT::compileObjectEquality):
      (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
      (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
      (JSC::DFG::SpeculativeJIT::compile):
      * ftl/FTLCompile.cpp:
      (JSC::FTL::compile):
      * ftl/FTLCompile.h:
      (FTL):
      * ftl/FTLState.h:
      (State):
      * runtime/JSFunction.h:
      (JSFunction):
      (JSC::JSFunction::allocationProfileWatchpointSet):
      * runtime/Structure.h:
      (Structure):
      (JSC::Structure::transitionWatchpointSet):
      
      Source/WTF:
      
      Reviewed by Oliver Hunt.
      
      Harden our notions of memory fences, now that we're doing racy algorithms.
      
      * wtf/Atomics.h:
      (WTF):
      (WTF::compilerFence):
      (WTF::armV7_dmb):
      (WTF::armV7_dmb_st):
      (WTF::loadLoadFence):
      (WTF::loadStoreFence):
      (WTF::storeLoadFence):
      (WTF::storeStoreFence):
      (WTF::memoryBarrierAfterLock):
      (WTF::memoryBarrierBeforeUnlock):
      (WTF::x86_mfence):
      
      
      Conflicts:
      	Source/WTF/wtf/Atomics.h
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153124 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      9397e00c
    • oliver@apple.com's avatar
      fourthTier: value profiles and array profiles should be thread-safe enough to... · c14eb7d0
      oliver@apple.com authored
      fourthTier: value profiles and array profiles should be thread-safe enough to be accessible in a concurrent compilation thread
      https://bugs.webkit.org/show_bug.cgi?id=114906
      
      Source/JavaScriptCore:
      
      Reviewed by Oliver Hunt.
      
      This introduces thread safety to value profiles, array profiles, and
      array allocation profiles.
      
      We already have three separate operations that happen on profiles:
      (1) writing, which the JIT, LLInt, and OSR exit do; (2) updating,
      which happens during GC, from OSR entry slow-paths, and in the DFG;
      and (3) reading, which happens in the DFG. For example, the JIT/LLInt
      and OSR exit write to ValueProfile::m_buckets, which gets synthesized
      into ValueProfile::m_prediction (and other fields) during update, and
      the latter gets read by the DFG. Note that (2) must also happen in
      the DFG since only the DFG knows which code blocks it will inline,
      and those blocks' profiles may not have otherwise been updated via
      any other mechanism.
      
      I refer to these three operations as writing, updating, and reading.
      
      Consequently, both profile updating and profile reading may happen
      asynchronously, if the JIT is asynchronous.
      
      The locking protocol for profiles works as follows:
      
      - Writing does not require locking, but is only allowed on the main
        thread. We require that these fields can be stored atomically by
        the profiling code, even without locks. For value profiles, this
        only works on 64-bit platforms, currently. For array profiles,
        which consist of multiple separate fields, this means that an
        asynchronous update of the profile may see slight inconsistencies
        (like a structure that doesn't quite match the array modes bits),
        but these should be harmless: at worst, the DFG will specialize
        too much and we'll have OSR exits.
      
      - Updating a value profile requires holding a lock, but must assume
        that the fields written by the profiling code in JIT/LLInt may
        be written to without locking.
      
      - Reading a value profile requires holding a lock.
      
      The one major exception to these rules is the ArrayAllocationProfile,
      which requires no locking. We do this because it's used so often and
      in places where we don't necessarily have access to the owning
      CodeBlock, so if we did want it to be locked it would have to have
      its own lock. Also, I believe that it is sound to just make this
      profile racy and not worry about locking at all. All that was needed
      were some changes to ensure that we explicitly read some raced-over
      fields only once.
      
      Two additional interesting things in this change:
      
      - To make it easy to see which profile methods require locking, they
        take a const CodeBlockLocker& as an argument. I saw this idiom for
        identifying which methods require which locks to be held being used
        in LLVM, and I quite like it.
      
      - Lazy operand value profiles, which are created lazily and at any
        time, require the CodeBlockLock to be held when they are being
        created. Writes to them are lockless and main-thread-only, but as
        with other profiles, updates and reads require locking.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/ArrayAllocationProfile.cpp:
      (JSC::ArrayAllocationProfile::updateIndexingType):
      * bytecode/ArrayAllocationProfile.h:
      (JSC::ArrayAllocationProfile::selectIndexingType):
      * bytecode/ArrayProfile.cpp:
      (JSC::ArrayProfile::computeUpdatedPrediction):
      (JSC::ArrayProfile::briefDescription):
      * bytecode/ArrayProfile.h:
      (ArrayProfile):
      (JSC::ArrayProfile::expectedStructure):
      (JSC::ArrayProfile::structureIsPolymorphic):
      (JSC::ArrayProfile::hasDefiniteStructure):
      (JSC::ArrayProfile::observedArrayModes):
      (JSC::ArrayProfile::mayInterceptIndexedAccesses):
      (JSC::ArrayProfile::mayStoreToHole):
      (JSC::ArrayProfile::outOfBounds):
      (JSC::ArrayProfile::usesOriginalArrayStructures):
      * bytecode/CallLinkStatus.cpp:
      (JSC::CallLinkStatus::computeFor):
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::dumpValueProfiling):
      (JSC::CodeBlock::dumpArrayProfiling):
      (JSC::CodeBlock::updateAllPredictionsAndCountLiveness):
      (JSC::CodeBlock::updateAllArrayPredictions):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::valueProfilePredictionForBytecodeOffset):
      (JSC::CodeBlock::updateAllPredictionsAndCheckIfShouldOptimizeNow):
      (CodeBlock):
      * bytecode/CodeBlockLock.h: Added.
      (JSC):
      * bytecode/GetByIdStatus.cpp:
      (JSC::GetByIdStatus::computeFor):
      * bytecode/LazyOperandValueProfile.cpp:
      (JSC::CompressedLazyOperandValueProfileHolder::computeUpdatedPredictions):
      (JSC::CompressedLazyOperandValueProfileHolder::add):
      (JSC::LazyOperandValueProfileParser::LazyOperandValueProfileParser):
      (JSC::LazyOperandValueProfileParser::~LazyOperandValueProfileParser):
      (JSC):
      (JSC::LazyOperandValueProfileParser::initialize):
      (JSC::LazyOperandValueProfileParser::prediction):
      * bytecode/LazyOperandValueProfile.h:
      (CompressedLazyOperandValueProfileHolder):
      (LazyOperandValueProfileParser):
      * bytecode/MethodOfGettingAValueProfile.cpp:
      (JSC::MethodOfGettingAValueProfile::getSpecFailBucket):
      * bytecode/PutByIdStatus.cpp:
      (JSC::PutByIdStatus::computeFor):
      * bytecode/ResolveGlobalStatus.cpp:
      (JSC::ResolveGlobalStatus::computeFor):
      * bytecode/ValueProfile.h:
      (JSC::ValueProfileBase::briefDescription):
      (ValueProfileBase):
      (JSC::ValueProfileBase::computeUpdatedPrediction):
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::ArrayMode::fromObserved):
      * dfg/DFGArrayMode.h:
      (ArrayMode):
      (JSC::DFG::ArrayMode::withProfile):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::injectLazyOperandSpeculation):
      (JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit):
      (JSC::DFG::ByteCodeParser::getArrayMode):
      (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks):
      (JSC::DFG::ByteCodeParser::parseResolveOperations):
      (JSC::DFG::ByteCodeParser::parseBlock):
      (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGOSRExitPreparation.cpp:
      (JSC::DFG::prepareCodeOriginForOSRExit):
      * dfg/DFGPredictionInjectionPhase.cpp:
      (JSC::DFG::PredictionInjectionPhase::run):
      * jit/JITInlines.h:
      (JSC::JIT::chooseArrayMode):
      * jit/JITStubs.cpp:
      (JSC::tryCachePutByID):
      (JSC::tryCacheGetByID):
      (JSC::DEFINE_STUB_FUNCTION):
      (JSC::lazyLinkFor):
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::LLINT_SLOW_PATH_DECL):
      (JSC::LLInt::setUpCall):
      * profiler/ProfilerBytecodeSequence.cpp:
      (JSC::Profiler::BytecodeSequence::BytecodeSequence):
      * runtime/JSScope.cpp:
      (JSC::JSScope::resolveContainingScopeInternal):
      (JSC::JSScope::resolvePut):
      
      Source/WTF:
      
      Reviewed by Oliver Hunt.
      
      Add ability to abstract whether or not the CodeBlock requires locking at all,
      since some platforms may not support the byte spin-locking and/or may not want
      to, if they turn off concurrent JIT.
      
      * WTF.xcodeproj/project.pbxproj:
      * wtf/ByteSpinLock.h:
      * wtf/NoLock.h: Added.
      (WTF):
      (NoLock):
      (WTF::NoLock::lock):
      (WTF::NoLock::unlock):
      (WTF::NoLock::isHeld):
      * wtf/Platform.h:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153123 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      c14eb7d0
    • oliver@apple.com's avatar
      fourthTier: all inline caches should thread-safe enough to allow a concurrent... · 0c1b13e9
      oliver@apple.com authored
      fourthTier: all inline caches should thread-safe enough to allow a concurrent compilation thread to read them safely
      https://bugs.webkit.org/show_bug.cgi?id=114762
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      For most inline caches this is easy: the inline cache has a clean temporal
      separation between doing the requested action (which may take an unbounded
      amount of time, may recurse, and may do arbitrary things) and recording the
      relevant information in the cache. So, we just put locks around the
      recording bit. That part is always O(1) and does not recurse. The lock we
      use is per-CodeBlock to achieve a good balance between locking granularity
      and low space overhead. So a concurrent compilation thread will only block
      if an inline cache ping-pongs in the code block being compiled (or inlined)
      and never when other inline caches do things.
      
      For resolve operations, it's a bit tricky. The global resolve bit works
      like any other IC in that it has the clean temporal separation. But the
      operations vector itself doesn't have this separation, since we will be
      filling it in tandem with actions that may take a long time. This patch
      gets around this by having a m_ready bit in the ResolveOperations and
      PutToBaseOperation. This is set while holding the CodeBlock's lock. If the
      DFG observes the m_ready bit not set (while holding the lock) then it
      conservatively assumes that the resolve hasn't happened yet and just
      plants a ForceOSRExit.
      
      * bytecode/CallLinkStatus.cpp:
      (JSC::CallLinkStatus::computeFor):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      * bytecode/GetByIdStatus.cpp:
      (JSC::GetByIdStatus::computeFor):
      * bytecode/PutByIdStatus.cpp:
      (JSC::PutByIdStatus::computeFor):
      * bytecode/ResolveGlobalStatus.cpp:
      (JSC::ResolveGlobalStatus::computeFor):
      * bytecode/ResolveOperation.h:
      (JSC::ResolveOperations::ResolveOperations):
      (ResolveOperations):
      (JSC::PutToBaseOperation::PutToBaseOperation):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::parseResolveOperations):
      (JSC::DFG::ByteCodeParser::parseBlock):
      * jit/JITStubs.cpp:
      (JSC::tryCachePutByID):
      (JSC::tryCacheGetByID):
      (JSC::DEFINE_STUB_FUNCTION):
      (JSC::lazyLinkFor):
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::LLINT_SLOW_PATH_DECL):
      (JSC::LLInt::setUpCall):
      * runtime/JSScope.cpp:
      (JSC::JSScope::resolveContainingScopeInternal):
      (JSC::JSScope::resolveContainingScope):
      (JSC::JSScope::resolvePut):
      
      Source/WTF:
      
      Reviewed by Mark Hahnenberg.
      
      Implemented a new spinlock that is optimized for compactness, by using just a byte.
      This will be useful as we start using fine-grained locking on a bunch of places.
      
      At some point I'll make these byte-sized spinlocks into adaptive mutexes, but for
      now I think it's fine to do the evil thing and use spinning particularly since we
      only use them for short critical sections.
      
      * WTF.xcodeproj/project.pbxproj:
      * wtf/Atomics.h:
      (WTF):
      (WTF::weakCompareAndSwap):
      * wtf/ByteSpinLock.h: Added.
      (WTF):
      (ByteSpinLock):
      (WTF::ByteSpinLock::ByteSpinLock):
      (WTF::ByteSpinLock::lock):
      (WTF::ByteSpinLock::unlock):
      (WTF::ByteSpinLock::isHeld):
      * wtf/ThreadingPrimitives.h:
      (WTF::pauseBriefly):
      (WTF):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153122 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      0c1b13e9