1. 12 Nov, 2013 1 commit
    • mhahnenberg@apple.com's avatar
      CodeBlocks should be able to determine bytecode liveness · 3811e215
      mhahnenberg@apple.com authored
      Reviewed by Filip Pizlo.
      This will simplify some things in the DFG related to OSR exits and determining 
      which bytecode variables are live at which points during execution. It will
      also be useful for making our conservative GC scan more precise. Currently it 
      doesn't properly account for liveness while the DFG is running, so it will be 
      off by default behing a runtime Options flag.
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/BytecodeBasicBlock.cpp: Added.
      (JSC::isBranch): Used to determine the end of basic blocks.
      (JSC::isUnconditionalBranch): Used to determine when a branch at the end of a 
      basic block can't possibly fall through to the next basic block in program order.
      (JSC::isTerminal): Also used to detect the end of a block.
      (JSC::isJumpTarget): Used to correctly separate basic blocks. Any jump destination 
      must be the head of its own basic block.
      (JSC::linkBlocks): Links two blocks together in a bi-direcitonal fashion.
      (JSC::computeBytecodeBasicBlocks): Creates a set of basic blocks given a particular 
      CodeBlock and links them together.
      * bytecode/BytecodeBasicBlock.h: Added.
      (JSC::BytecodeBasicBlock::isEntryBlock): Entry blocks are a special basic blocks 
      that indicate the beginning of the function.
      (JSC::BytecodeBasicBlock::isExitBlock): Exit blocks are a special basic block that 
      all blocks that exit the function have as a successor. Entry and exit blocks allows 
      the various code paths to be more regular.
      (JSC::BytecodeBasicBlock::leaderBytecodeOffset): The leader bytecode offset is the 
      bytecode offset of the first instruction in the block.
      (JSC::BytecodeBasicBlock::totalBytecodeLength): The total length of all the bytecodes 
      in this block.
      (JSC::BytecodeBasicBlock::bytecodeOffsets): The bytecode offsets in this particular 
      basic block. This Vector allows us to iterate over the bytecodes in reverse order 
      which wouldn't be possible normally since they are of variable size.
      (JSC::BytecodeBasicBlock::addPredecessor): Links a block to a specified predecessor. 
      Only creates one direction of the link.
      (JSC::BytecodeBasicBlock::addSuccessor): Same as addPredecessor, but for successors.
      (JSC::BytecodeBasicBlock::predecessors): Getter for predecessors.
      (JSC::BytecodeBasicBlock::successors): Getter for successors.
      (JSC::BytecodeBasicBlock::in): Getter for the liveness info at the head of the block.
      (JSC::BytecodeBasicBlock::out): Getter for the liveness info at  the tail of the block.
      (JSC::BytecodeBasicBlock::addBytecodeLength): When creating basic blocks we call 
      this function when we want to add the next bytecode in program order to this block.
      * bytecode/BytecodeLivenessAnalysis.cpp: Added.
      (JSC::numberOfCapturedVariables): Convenience wrapper. Returns the
      number of captured variables for a particular CodeBlock, or 0 if 
      the CodeBlock has no SymbolTable.
      (JSC::captureStart): Ditto, but for captureStart().
      (JSC::captureEnd): Ditto, but for captureEnd().
      (JSC::isValidRegisterForLiveness): Returns true if the liveness analysis should 
      track the liveness of a particular operand. We ignore constants, arguments, and 
      captured variables. We ignore arguments because they're live for the duration of 
      a function call. We ignore captured variables because we also treat them as live 
      for the duration of the function. This could probably be improved to be more precise, 
      but it didn't seem worth it for now.
      (JSC::setForOperand): Convenience wrapper that sets the bit in the provided bit 
      vector for the provided operand. It handles skipping over captured variables.
      (JSC::computeUsesForBytecodeOffset): Computes which operands are used by a particular bytecode.
      (JSC::computeDefsForBytecodeOffset): Computes which operands are defined by a particular 
      bytecode. Typically this is just the left-most operand.
      (JSC::findBasicBlockForBytecodeOffset): Scans over basic blocks to find the block 
      which contains a particular bytecode offset.
      (JSC::computeLocalLivenessForBytecodeOffset): Computes block-local liveness from the 
      bottom of the block until a specified bytecode offset is reached. 
      (JSC::computeLocalLivenessForBlock): Computes liveness for the entire block and 
      stores the resulting liveness at the head.
      (JSC::BytecodeLivenessAnalysis::runLivenessFixpoint): Runs backward flow liveness 
      analysis to fixpoint.
      Slow path to get liveness info for non-captured, non-argument variable.
      (JSC::BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset): Returns the liveness 
      info for both captured and non-captured vars at a particular bytecode offset.
      (JSC::BytecodeLivenessAnalysis::dumpResults): Dumps the output of the liveness analysis. 
      Controlled by new flag in Options.h/.cpp.
      (JSC::BytecodeLivenessAnalysis::compute): Creates bytecode basic blocks and runs 
      full liveness analysis.
      * bytecode/BytecodeLivenessAnalysis.h: Added.
      * bytecode/CodeBlock.cpp:
      * bytecode/CodeBlock.h:
      * bytecode/PreciseJumpTargets.cpp: Refactored to be able to get the jump targets for 
      a particular bytecode offset for use during bytecode basic block construction.
      * bytecode/PreciseJumpTargets.h:
      * runtime/Options.cpp:
      * runtime/Options.h:
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@159136 268f45cc-cd09-0410-ab3c-d52691b4dbfc