void BytecodeLivenessAnalysis::runLivenessFixpoint() { UnlinkedCodeBlock* unlinkedCodeBlock = m_codeBlock->unlinkedCodeBlock(); unsigned numberOfVariables = unlinkedCodeBlock->m_numCalleeLocals; for (unsigned i = 0; i < m_basicBlocks.size(); i++) { BytecodeBasicBlock* block = m_basicBlocks[i].get(); block->in().resize(numberOfVariables); block->out().resize(numberOfVariables); } bool changed; m_basicBlocks.last()->in().clearAll(); m_basicBlocks.last()->out().clearAll(); FastBitVector newOut; newOut.resize(m_basicBlocks.last()->out().numBits()); do { changed = false; for (unsigned i = m_basicBlocks.size() - 1; i--;) { BytecodeBasicBlock* block = m_basicBlocks[i].get(); newOut.clearAll(); for (unsigned j = 0; j < block->successors().size(); j++) newOut.merge(block->successors()[j]->in()); bool outDidChange = block->out().setAndCheck(newOut); computeLocalLivenessForBlock(m_codeBlock, block, m_basicBlocks); changed |= outDidChange; } } while (changed); }
static void computeLocalLivenessForBytecodeOffset(CodeBlock* codeBlock, BytecodeBasicBlock* block, Vector<RefPtr<BytecodeBasicBlock> >& basicBlocks, unsigned targetOffset, FastBitVector& result) { ASSERT(!block->isExitBlock()); ASSERT(!block->isEntryBlock()); FastBitVector out = block->out(); HandlerInfo* handler = 0; FastBitVector uses; FastBitVector defs; uses.resize(out.numBits()); defs.resize(out.numBits()); for (int i = block->bytecodeOffsets().size() - 1; i >= 0; i--) { unsigned bytecodeOffset = block->bytecodeOffsets()[i]; if (targetOffset > bytecodeOffset) break; uses.clearAll(); defs.clearAll(); computeUsesForBytecodeOffset(codeBlock, bytecodeOffset, uses); computeDefsForBytecodeOffset(codeBlock, bytecodeOffset, defs); out.exclude(defs); out.merge(uses); // If we have an exception handler, we want the live-in variables of the // exception handler block to be included in the live-in of this particular bytecode. if ((handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset))) { BytecodeBasicBlock* handlerBlock = findBasicBlockWithLeaderOffset(basicBlocks, handler->target); ASSERT(handlerBlock); out.merge(handlerBlock->in()); } } result.set(out); }