fourthTier: DFG should refer to BasicBlocks by BasicBlock* and not BlockIndex
https://bugs.webkit.org/show_bug.cgi?id=118339

Reviewed by Michael Saboff.

This accomplishes two goals:

1) Simplifies a bunch of code. You can now much more directly get to a successor
   or predecessor, since you just get the pointer directly. The backend(s) always
   hold onto a pointer to the block they're on, so you don't have to do work to
   get the block from the index.

2) It allows for the possibility of inserting blocks into the program.
   Previously, if you did that, you'd have to edit all references to blocks since
   those references would have outdated indexing after an insertion. Now, if you
   change the indexing, you just have to invalidate some analyses and make sure
   that you change each block's BasicBlock::index accordingly.

* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::initialize):
(JSC::DFG::AbstractState::endBasicBlock):
(JSC::DFG::AbstractState::mergeToSuccessors):
* dfg/DFGAbstractState.h:
(AbstractState):
* dfg/DFGArgumentsSimplificationPhase.cpp:
(JSC::DFG::ArgumentsSimplificationPhase::run):
* dfg/DFGBackwardsPropagationPhase.cpp:
(JSC::DFG::BackwardsPropagationPhase::run):
* dfg/DFGBasicBlock.h:
(DFG):
(JSC::DFG::BasicBlock::BasicBlock):
(JSC::DFG::BasicBlock::size):
(JSC::DFG::BasicBlock::isEmpty):
(JSC::DFG::BasicBlock::at):
(JSC::DFG::BasicBlock::operator[]):
(JSC::DFG::BasicBlock::last):
(JSC::DFG::BasicBlock::resize):
(JSC::DFG::BasicBlock::grow):
(BasicBlock):
(JSC::DFG::BasicBlock::append):
(JSC::DFG::BasicBlock::numSuccessors):
(JSC::DFG::BasicBlock::successor):
(JSC::DFG::BasicBlock::successorForCondition):
(JSC::DFG::BasicBlock::dump):
(UnlinkedBlock):
(JSC::DFG::UnlinkedBlock::UnlinkedBlock):
(JSC::DFG::getBytecodeBeginForBlock):
(JSC::DFG::blockForBytecodeOffset):
* dfg/DFGByteCodeParser.cpp:
(ByteCodeParser):
(InlineStackEntry):
(JSC::DFG::ByteCodeParser::handleInlining):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::linkBlock):
(JSC::DFG::ByteCodeParser::linkBlocks):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
(JSC::DFG::ByteCodeParser::parseCodeBlock):
(JSC::DFG::ByteCodeParser::parse):
* dfg/DFGCFAPhase.cpp:
(JSC::DFG::CFAPhase::performBlockCFA):
(JSC::DFG::CFAPhase::performForwardCFA):
* dfg/DFGCFGSimplificationPhase.cpp:
(JSC::DFG::CFGSimplificationPhase::run):
(JSC::DFG::CFGSimplificationPhase::convertToJump):
* dfg/DFGCPSRethreadingPhase.cpp:
(JSC::DFG::CPSRethreadingPhase::freeUnnecessaryNodes):
(JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlocks):
(JSC::DFG::CPSRethreadingPhase::propagatePhis):
(CPSRethreadingPhase):
* dfg/DFGCSEPhase.cpp:
(JSC::DFG::CSEPhase::run):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::run):
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* dfg/DFGDCEPhase.cpp:
(JSC::DFG::DCEPhase::run):
* dfg/DFGDisassembler.cpp:
(JSC::DFG::Disassembler::Disassembler):
(JSC::DFG::Disassembler::createDumpList):
* dfg/DFGDisassembler.h:
(JSC::DFG::Disassembler::setForBlockIndex):
* dfg/DFGDominators.cpp:
(JSC::DFG::Dominators::compute):
(JSC::DFG::Dominators::iterateForBlock):
* dfg/DFGDominators.h:
(JSC::DFG::Dominators::dominates):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::run):
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
(JSC::DFG::Graph::dumpBlockHeader):
(JSC::DFG::Graph::handleSuccessor):
(JSC::DFG::Graph::determineReachability):
(JSC::DFG::Graph::resetReachability):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::numBlocks):
(JSC::DFG::Graph::block):
(JSC::DFG::Graph::lastBlock):
(Graph):
(JSC::DFG::Graph::appendBlock):
(JSC::DFG::Graph::killBlock):
(DFG):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::JITCompiler):
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
(JSC::DFG::JITCompiler::setForBlockIndex):
* dfg/DFGNaturalLoops.cpp:
(JSC::DFG::NaturalLoop::dump):
(JSC::DFG::NaturalLoops::compute):
(JSC::DFG::NaturalLoops::loopsOf):
* dfg/DFGNaturalLoops.h:
(JSC::DFG::NaturalLoop::NaturalLoop):
(JSC::DFG::NaturalLoop::addBlock):
(JSC::DFG::NaturalLoop::header):
(JSC::DFG::NaturalLoop::at):
(JSC::DFG::NaturalLoop::operator[]):
(JSC::DFG::NaturalLoop::contains):
(NaturalLoop):
(JSC::DFG::NaturalLoops::headerOf):
(NaturalLoops):
* dfg/DFGNode.h:
(DFG):
(JSC::DFG::SwitchCase::SwitchCase):
(JSC::DFG::SwitchCase::withBytecodeIndex):
(SwitchCase):
(JSC::DFG::SwitchCase::targetBytecodeIndex):
(JSC::DFG::SwitchData::SwitchData):
(JSC::DFG::SwitchData::setFallThroughBytecodeIndex):
(JSC::DFG::SwitchData::fallThroughBytecodeIndex):
(SwitchData):
(JSC::DFG::Node::setTakenBlock):
(JSC::DFG::Node::setNotTakenBlock):
(JSC::DFG::Node::takenBlock):
(JSC::DFG::Node::notTakenBlock):
(JSC::DFG::Node::successor):
(JSC::DFG::Node::successorForCondition):
* dfg/DFGPredictionInjectionPhase.cpp:
(JSC::DFG::PredictionInjectionPhase::run):
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagateForward):
(JSC::DFG::PredictionPropagationPhase::propagateBackward):
(JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
(JSC::DFG::SpeculativeJIT::nonSpeculativeCompare):
(JSC::DFG::SpeculativeJIT::nonSpeculativeStrictEq):
(JSC::DFG::SpeculativeJIT::compilePeepHoleDoubleBranch):
(JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
(JSC::DFG::SpeculativeJIT::compilePeepHoleIntegerBranch):
(JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
(JSC::DFG::SpeculativeJIT::compileCurrentBlock):
(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::createOSREntries):
(JSC::DFG::SpeculativeJIT::linkOSREntries):
(JSC::DFG::SpeculativeJIT::compileStrictEqForConstant):
(JSC::DFG::SpeculativeJIT::compileStrictEq):
(JSC::DFG::SpeculativeJIT::compileRegExpExec):
(JSC::DFG::SpeculativeJIT::addBranch):
(JSC::DFG::SpeculativeJIT::linkBranches):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::nextBlock):
(SpeculativeJIT):
(JSC::DFG::SpeculativeJIT::detectPeepHoleBranch):
(JSC::DFG::SpeculativeJIT::branchDouble):
(JSC::DFG::SpeculativeJIT::branchDoubleNonZero):
(JSC::DFG::SpeculativeJIT::branch32):
(JSC::DFG::SpeculativeJIT::branchTest32):
(JSC::DFG::SpeculativeJIT::branch64):
(JSC::DFG::SpeculativeJIT::branch8):
(JSC::DFG::SpeculativeJIT::branchPtr):
(JSC::DFG::SpeculativeJIT::branchTestPtr):
(JSC::DFG::SpeculativeJIT::branchTest8):
(JSC::DFG::SpeculativeJIT::jump):
(JSC::DFG::SpeculativeJIT::addBranch):
(JSC::DFG::SpeculativeJIT::StringSwitchCase::StringSwitchCase):
(StringSwitchCase):
(JSC::DFG::SpeculativeJIT::BranchRecord::BranchRecord):
(BranchRecord):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
(JSC::DFG::SpeculativeJIT::nonSpeculativeCompareNull):
(JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
(JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
(JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
(JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
(JSC::DFG::SpeculativeJIT::emitBranch):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
(JSC::DFG::SpeculativeJIT::nonSpeculativeCompareNull):
(JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
(JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
(JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
(JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
(JSC::DFG::SpeculativeJIT::emitBranch):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGTypeCheckHoistingPhase.cpp:
(JSC::DFG::TypeCheckHoistingPhase::run):
(JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
(JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
(JSC::DFG::TypeCheckHoistingPhase::disableHoistingAcrossOSREntries):
* dfg/DFGUnificationPhase.cpp:
(JSC::DFG::UnificationPhase::run):
* dfg/DFGValidate.cpp:
(JSC::DFG::Validate::validate):
(JSC::DFG::Validate::checkOperand):
(JSC::DFG::Validate::reportValidationContext):
* dfg/DFGVirtualRegisterAllocationPhase.cpp:
(JSC::DFG::VirtualRegisterAllocationPhase::run):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
(JSC::FTL::LowerDFGToLLVM::lower):
(JSC::FTL::LowerDFGToLLVM::compileBlock):
(JSC::FTL::LowerDFGToLLVM::compileJump):
(JSC::FTL::LowerDFGToLLVM::compileBranch):
(JSC::FTL::LowerDFGToLLVM::lowBlock):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 1385350..f362e3e 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,5 +1,228 @@
 2013-07-04  Filip Pizlo  <fpizlo@apple.com>
 
+        fourthTier: DFG should refer to BasicBlocks by BasicBlock* and not BlockIndex
+        https://bugs.webkit.org/show_bug.cgi?id=118339
+
+        Reviewed by Michael Saboff.
+        
+        This accomplishes two goals:
+
+        1) Simplifies a bunch of code. You can now much more directly get to a successor
+           or predecessor, since you just get the pointer directly. The backend(s) always
+           hold onto a pointer to the block they're on, so you don't have to do work to
+           get the block from the index.
+        
+        2) It allows for the possibility of inserting blocks into the program.
+           Previously, if you did that, you'd have to edit all references to blocks since
+           those references would have outdated indexing after an insertion. Now, if you
+           change the indexing, you just have to invalidate some analyses and make sure
+           that you change each block's BasicBlock::index accordingly.
+
+        * dfg/DFGAbstractState.cpp:
+        (JSC::DFG::AbstractState::initialize):
+        (JSC::DFG::AbstractState::endBasicBlock):
+        (JSC::DFG::AbstractState::mergeToSuccessors):
+        * dfg/DFGAbstractState.h:
+        (AbstractState):
+        * dfg/DFGArgumentsSimplificationPhase.cpp:
+        (JSC::DFG::ArgumentsSimplificationPhase::run):
+        * dfg/DFGBackwardsPropagationPhase.cpp:
+        (JSC::DFG::BackwardsPropagationPhase::run):
+        * dfg/DFGBasicBlock.h:
+        (DFG):
+        (JSC::DFG::BasicBlock::BasicBlock):
+        (JSC::DFG::BasicBlock::size):
+        (JSC::DFG::BasicBlock::isEmpty):
+        (JSC::DFG::BasicBlock::at):
+        (JSC::DFG::BasicBlock::operator[]):
+        (JSC::DFG::BasicBlock::last):
+        (JSC::DFG::BasicBlock::resize):
+        (JSC::DFG::BasicBlock::grow):
+        (BasicBlock):
+        (JSC::DFG::BasicBlock::append):
+        (JSC::DFG::BasicBlock::numSuccessors):
+        (JSC::DFG::BasicBlock::successor):
+        (JSC::DFG::BasicBlock::successorForCondition):
+        (JSC::DFG::BasicBlock::dump):
+        (UnlinkedBlock):
+        (JSC::DFG::UnlinkedBlock::UnlinkedBlock):
+        (JSC::DFG::getBytecodeBeginForBlock):
+        (JSC::DFG::blockForBytecodeOffset):
+        * dfg/DFGByteCodeParser.cpp:
+        (ByteCodeParser):
+        (InlineStackEntry):
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        (JSC::DFG::ByteCodeParser::linkBlock):
+        (JSC::DFG::ByteCodeParser::linkBlocks):
+        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+        (JSC::DFG::ByteCodeParser::parseCodeBlock):
+        (JSC::DFG::ByteCodeParser::parse):
+        * dfg/DFGCFAPhase.cpp:
+        (JSC::DFG::CFAPhase::performBlockCFA):
+        (JSC::DFG::CFAPhase::performForwardCFA):
+        * dfg/DFGCFGSimplificationPhase.cpp:
+        (JSC::DFG::CFGSimplificationPhase::run):
+        (JSC::DFG::CFGSimplificationPhase::convertToJump):
+        * dfg/DFGCPSRethreadingPhase.cpp:
+        (JSC::DFG::CPSRethreadingPhase::freeUnnecessaryNodes):
+        (JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlocks):
+        (JSC::DFG::CPSRethreadingPhase::propagatePhis):
+        (CPSRethreadingPhase):
+        * dfg/DFGCSEPhase.cpp:
+        (JSC::DFG::CSEPhase::run):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::run):
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGDCEPhase.cpp:
+        (JSC::DFG::DCEPhase::run):
+        * dfg/DFGDisassembler.cpp:
+        (JSC::DFG::Disassembler::Disassembler):
+        (JSC::DFG::Disassembler::createDumpList):
+        * dfg/DFGDisassembler.h:
+        (JSC::DFG::Disassembler::setForBlockIndex):
+        * dfg/DFGDominators.cpp:
+        (JSC::DFG::Dominators::compute):
+        (JSC::DFG::Dominators::iterateForBlock):
+        * dfg/DFGDominators.h:
+        (JSC::DFG::Dominators::dominates):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::run):
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        (JSC::DFG::Graph::dumpBlockHeader):
+        (JSC::DFG::Graph::handleSuccessor):
+        (JSC::DFG::Graph::determineReachability):
+        (JSC::DFG::Graph::resetReachability):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::numBlocks):
+        (JSC::DFG::Graph::block):
+        (JSC::DFG::Graph::lastBlock):
+        (Graph):
+        (JSC::DFG::Graph::appendBlock):
+        (JSC::DFG::Graph::killBlock):
+        (DFG):
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::JITCompiler):
+        (JSC::DFG::JITCompiler::link):
+        * dfg/DFGJITCompiler.h:
+        (JSC::DFG::JITCompiler::setForBlockIndex):
+        * dfg/DFGNaturalLoops.cpp:
+        (JSC::DFG::NaturalLoop::dump):
+        (JSC::DFG::NaturalLoops::compute):
+        (JSC::DFG::NaturalLoops::loopsOf):
+        * dfg/DFGNaturalLoops.h:
+        (JSC::DFG::NaturalLoop::NaturalLoop):
+        (JSC::DFG::NaturalLoop::addBlock):
+        (JSC::DFG::NaturalLoop::header):
+        (JSC::DFG::NaturalLoop::at):
+        (JSC::DFG::NaturalLoop::operator[]):
+        (JSC::DFG::NaturalLoop::contains):
+        (NaturalLoop):
+        (JSC::DFG::NaturalLoops::headerOf):
+        (NaturalLoops):
+        * dfg/DFGNode.h:
+        (DFG):
+        (JSC::DFG::SwitchCase::SwitchCase):
+        (JSC::DFG::SwitchCase::withBytecodeIndex):
+        (SwitchCase):
+        (JSC::DFG::SwitchCase::targetBytecodeIndex):
+        (JSC::DFG::SwitchData::SwitchData):
+        (JSC::DFG::SwitchData::setFallThroughBytecodeIndex):
+        (JSC::DFG::SwitchData::fallThroughBytecodeIndex):
+        (SwitchData):
+        (JSC::DFG::Node::setTakenBlock):
+        (JSC::DFG::Node::setNotTakenBlock):
+        (JSC::DFG::Node::takenBlock):
+        (JSC::DFG::Node::notTakenBlock):
+        (JSC::DFG::Node::successor):
+        (JSC::DFG::Node::successorForCondition):
+        * dfg/DFGPredictionInjectionPhase.cpp:
+        (JSC::DFG::PredictionInjectionPhase::run):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagateForward):
+        (JSC::DFG::PredictionPropagationPhase::propagateBackward):
+        (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativeCompare):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativeStrictEq):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleDoubleBranch):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleIntegerBranch):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
+        (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
+        (JSC::DFG::SpeculativeJIT::compile):
+        (JSC::DFG::SpeculativeJIT::createOSREntries):
+        (JSC::DFG::SpeculativeJIT::linkOSREntries):
+        (JSC::DFG::SpeculativeJIT::compileStrictEqForConstant):
+        (JSC::DFG::SpeculativeJIT::compileStrictEq):
+        (JSC::DFG::SpeculativeJIT::compileRegExpExec):
+        (JSC::DFG::SpeculativeJIT::addBranch):
+        (JSC::DFG::SpeculativeJIT::linkBranches):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::nextBlock):
+        (SpeculativeJIT):
+        (JSC::DFG::SpeculativeJIT::detectPeepHoleBranch):
+        (JSC::DFG::SpeculativeJIT::branchDouble):
+        (JSC::DFG::SpeculativeJIT::branchDoubleNonZero):
+        (JSC::DFG::SpeculativeJIT::branch32):
+        (JSC::DFG::SpeculativeJIT::branchTest32):
+        (JSC::DFG::SpeculativeJIT::branch64):
+        (JSC::DFG::SpeculativeJIT::branch8):
+        (JSC::DFG::SpeculativeJIT::branchPtr):
+        (JSC::DFG::SpeculativeJIT::branchTestPtr):
+        (JSC::DFG::SpeculativeJIT::branchTest8):
+        (JSC::DFG::SpeculativeJIT::jump):
+        (JSC::DFG::SpeculativeJIT::addBranch):
+        (JSC::DFG::SpeculativeJIT::StringSwitchCase::StringSwitchCase):
+        (StringSwitchCase):
+        (JSC::DFG::SpeculativeJIT::BranchRecord::BranchRecord):
+        (BranchRecord):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativeCompareNull):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+        (JSC::DFG::SpeculativeJIT::emitBranch):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativeCompareNull):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
+        (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
+        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+        (JSC::DFG::SpeculativeJIT::emitBranch):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGTypeCheckHoistingPhase.cpp:
+        (JSC::DFG::TypeCheckHoistingPhase::run):
+        (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
+        (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
+        (JSC::DFG::TypeCheckHoistingPhase::disableHoistingAcrossOSREntries):
+        * dfg/DFGUnificationPhase.cpp:
+        (JSC::DFG::UnificationPhase::run):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        (JSC::DFG::Validate::checkOperand):
+        (JSC::DFG::Validate::reportValidationContext):
+        * dfg/DFGVirtualRegisterAllocationPhase.cpp:
+        (JSC::DFG::VirtualRegisterAllocationPhase::run):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
+        (JSC::FTL::LowerDFGToLLVM::lower):
+        (JSC::FTL::LowerDFGToLLVM::compileBlock):
+        (JSC::FTL::LowerDFGToLLVM::compileJump):
+        (JSC::FTL::LowerDFGToLLVM::compileBranch):
+        (JSC::FTL::LowerDFGToLLVM::lowBlock):
+
+2013-07-04  Filip Pizlo  <fpizlo@apple.com>
+
         Unreviewed, add a helpful comment for why DCE is needed in the FTL.
 
         I believe I've now twice down the experiment of disabling DCE in the FTL,
diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index 6e8d5af..9111baf 100644
--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -2123,9 +2123,9 @@
 		034768DFFF38A50411DB9C8B /* Products */ = {
 			isa = PBXGroup;
 			children = (
+				932F5BE10822A1C700736975 /* jsc */,
 				0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */,
 				932F5BD90822A1C700736975 /* JavaScriptCore.framework */,
-				932F5BE10822A1C700736975 /* jsc */,
 				141211200A48793C00480255 /* minidom */,
 				14BD59BF0A3E8F9000BAF59C /* testapi */,
 				6511230514046A4C002B101D /* testRegExp */,
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
index 58a065a..b54c097 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
@@ -85,7 +85,7 @@
 
 void AbstractState::initialize(Graph& graph)
 {
-    BasicBlock* root = graph.m_blocks[0].get();
+    BasicBlock* root = graph.block(0);
     root->cfaShouldRevisit = true;
     root->cfaHasVisited = false;
     root->cfaFoundConstants = false;
@@ -118,8 +118,8 @@
             root->valuesAtHead.local(i).clear();
         root->valuesAtTail.local(i).clear();
     }
-    for (BlockIndex blockIndex = 1 ; blockIndex < graph.m_blocks.size(); ++blockIndex) {
-        BasicBlock* block = graph.m_blocks[blockIndex].get();
+    for (BlockIndex blockIndex = 1 ; blockIndex < graph.numBlocks(); ++blockIndex) {
+        BasicBlock* block = graph.block(blockIndex);
         if (!block)
             continue;
         if (!block->isReachable)
@@ -200,7 +200,7 @@
     if (mergeMode != MergeToSuccessors)
         return changed;
     
-    return mergeToSuccessors(m_graph, block);
+    return mergeToSuccessors(block);
 }
 
 void AbstractState::reset()
@@ -1816,7 +1816,7 @@
     return changed;
 }
 
-inline bool AbstractState::mergeToSuccessors(Graph& graph, BasicBlock* basicBlock)
+inline bool AbstractState::mergeToSuccessors(BasicBlock* basicBlock)
 {
     Node* terminal = basicBlock->last();
     
@@ -1826,24 +1826,24 @@
     case Jump: {
         ASSERT(basicBlock->cfaBranchDirection == InvalidBranchDirection);
 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
-        dataLogF("        Merging to block #%u.\n", terminal->takenBlockIndex());
+        dataLog("        Merging to block ", *terminal->takenBlock(), ".\n");
 #endif
-        return merge(basicBlock, graph.m_blocks[terminal->takenBlockIndex()].get());
+        return merge(basicBlock, terminal->takenBlock());
     }
         
     case Branch: {
         ASSERT(basicBlock->cfaBranchDirection != InvalidBranchDirection);
         bool changed = false;
 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
-        dataLogF("        Merging to block #%u.\n", terminal->takenBlockIndex());
+        dataLog("        Merging to block ", *terminal->takenBlock(), ".\n");
 #endif
         if (basicBlock->cfaBranchDirection != TakeFalse)
-            changed |= merge(basicBlock, graph.m_blocks[terminal->takenBlockIndex()].get());
+            changed |= merge(basicBlock, terminal->takenBlock());
 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
-        dataLogF("        Merging to block #%u.\n", terminal->notTakenBlockIndex());
+        dataLog("        Merging to block ", *terminal->notTakenBlock(), ".\n");
 #endif
         if (basicBlock->cfaBranchDirection != TakeTrue)
-            changed |= merge(basicBlock, graph.m_blocks[terminal->notTakenBlockIndex()].get());
+            changed |= merge(basicBlock, terminal->notTakenBlock());
         return changed;
     }
         
@@ -1852,9 +1852,9 @@
         // we're not. However I somehow doubt that this will ever be a big deal.
         ASSERT(basicBlock->cfaBranchDirection == InvalidBranchDirection);
         SwitchData* data = terminal->switchData();
-        bool changed = merge(basicBlock, graph.m_blocks[data->fallThrough].get());
+        bool changed = merge(basicBlock, data->fallThrough);
         for (unsigned i = data->cases.size(); i--;)
-            changed |= merge(basicBlock, graph.m_blocks[data->cases[i].target].get());
+            changed |= merge(basicBlock, data->cases[i].target);
         return changed;
     }
         
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.h b/Source/JavaScriptCore/dfg/DFGAbstractState.h
index 9db0545..4dec4c9 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.h
@@ -227,7 +227,7 @@
     // successors. Returns true if any of the successors' states changed. Note
     // that this is automatically called in endBasicBlock() if MergeMode is
     // MergeToSuccessors.
-    bool mergeToSuccessors(Graph&, BasicBlock*);
+    bool mergeToSuccessors(BasicBlock*);
     
     void dump(PrintStream& out);
     
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp b/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp
index 0c29b29..c70a94f 100644
--- a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp
@@ -142,8 +142,8 @@
         
         // Figure out which variables are live, using a conservative approximation of
         // liveness.
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
@@ -164,8 +164,8 @@
         // used only for GetByVal and GetArrayLength accesses. At the same time,
         // identify uses of CreateArguments that are not consistent with the arguments
         // being aliased only to variables that satisfy these constraints.
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
@@ -352,8 +352,8 @@
         // the arguments as requiring creation. This is a property of SetLocals to
         // variables that are neither the correct arguments register nor are marked as
         // being arguments-aliased.
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
@@ -428,8 +428,8 @@
         
         InsertionSet insertionSet(m_graph);
         
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             for (unsigned indexInBlock = 0; indexInBlock < block->size(); indexInBlock++) {
@@ -661,8 +661,8 @@
             insertionSet.execute(block);
         }
         
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
diff --git a/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp
index dc527935..2d4894e 100644
--- a/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp
@@ -44,8 +44,8 @@
     
     bool run()
     {
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             
diff --git a/Source/JavaScriptCore/dfg/DFGBasicBlock.h b/Source/JavaScriptCore/dfg/DFGBasicBlock.h
index bae9d52..da52354 100644
--- a/Source/JavaScriptCore/dfg/DFGBasicBlock.h
+++ b/Source/JavaScriptCore/dfg/DFGBasicBlock.h
@@ -39,12 +39,14 @@
 namespace JSC { namespace DFG {
 
 class Graph;
+class InsertionSet;
 
-typedef Vector <BlockIndex, 2> PredecessorList;
+typedef Vector<BasicBlock*, 2> PredecessorList;
 
-struct BasicBlock : Vector<Node*, 8> {
+struct BasicBlock : RefCounted<BasicBlock> {
     BasicBlock(unsigned bytecodeBegin, unsigned numArguments, unsigned numLocals)
         : bytecodeBegin(bytecodeBegin)
+        , index(NoBlock)
         , isOSRTarget(false)
         , cfaHasVisited(false)
         , cfaShouldRevisit(false)
@@ -74,6 +76,17 @@
         valuesAtTail.ensureLocals(newNumLocals);
     }
     
+    size_t size() const { return m_nodes.size(); }
+    bool isEmpty() const { return !size(); }
+    Node*& at(size_t i) { return m_nodes[i]; }
+    Node* at(size_t i) const { return m_nodes[i]; }
+    Node* operator[](size_t i) const { return at(i); }
+    Node* last() const { return at(size() - 1); }
+    void resize(size_t size) { m_nodes.resize(size); }
+    void grow(size_t size) { m_nodes.grow(size); }
+    
+    void append(Node* node) { m_nodes.append(node); }
+    
     size_t numNodes() const { return phis.size() + size(); }
     Node* node(size_t i) const
     {
@@ -101,15 +114,33 @@
         return false;
     }
     
+    unsigned numSuccessors() { return last()->numSuccessors(); }
+    
+    BasicBlock* successor(unsigned index)
+    {
+        return last()->successor(index);
+    }
+    BasicBlock* successorForCondition(bool condition)
+    {
+        return last()->successorForCondition(condition);
+    }
+
 #define DFG_DEFINE_APPEND_NODE(templatePre, templatePost, typeParams, valueParamsComma, valueParams, valueArgs) \
     templatePre typeParams templatePost Node* appendNode(Graph&, SpeculatedType valueParamsComma valueParams);
     DFG_VARIADIC_TEMPLATE_FUNCTION(DFG_DEFINE_APPEND_NODE)
 #undef DFG_DEFINE_APPEND_NODE
     
+    void dump(PrintStream& out) const
+    {
+        out.print("#", index);
+    }
+    
     // This value is used internally for block linking and OSR entry. It is mostly meaningless
     // for other purposes due to inlining.
     unsigned bytecodeBegin;
     
+    BlockIndex index;
+    
     bool isOSRTarget;
     bool cfaHasVisited;
     bool cfaShouldRevisit;
@@ -122,30 +153,44 @@
     bool isReachable;
     
     Vector<Node*> phis;
-    PredecessorList m_predecessors;
+    PredecessorList predecessors;
     
     Operands<Node*, NodePointerTraits> variablesAtHead;
     Operands<Node*, NodePointerTraits> variablesAtTail;
     
     Operands<AbstractValue> valuesAtHead;
     Operands<AbstractValue> valuesAtTail;
+
+private:
+    friend class InsertionSet;
+    Vector<Node*, 8> m_nodes;
 };
 
 struct UnlinkedBlock {
-    BlockIndex m_blockIndex;
+    BasicBlock* m_block;
     bool m_needsNormalLinking;
     bool m_needsEarlyReturnLinking;
     
     UnlinkedBlock() { }
     
-    explicit UnlinkedBlock(BlockIndex blockIndex)
-        : m_blockIndex(blockIndex)
+    explicit UnlinkedBlock(BasicBlock* block)
+        : m_block(block)
         , m_needsNormalLinking(true)
         , m_needsEarlyReturnLinking(false)
     {
     }
 };
     
+static inline unsigned getBytecodeBeginForBlock(BasicBlock** basicBlock)
+{
+    return (*basicBlock)->bytecodeBegin;
+}
+
+static inline BasicBlock* blockForBytecodeOffset(Vector<BasicBlock*>& linkingTargets, unsigned bytecodeBegin)
+{
+    return *binarySearch<BasicBlock*, unsigned>(linkingTargets, linkingTargets.size(), bytecodeBegin, getBytecodeBeginForBlock);
+}
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
index 86f3e46..c1d1d89 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
@@ -185,8 +185,8 @@
     // Parse a single basic block of bytecode instructions.
     bool parseBlock(unsigned limit);
     // Link block successors.
-    void linkBlock(BasicBlock*, Vector<BlockIndex>& possibleTargets);
-    void linkBlocks(Vector<UnlinkedBlock>& unlinkedBlocks, Vector<BlockIndex>& possibleTargets);
+    void linkBlock(BasicBlock*, Vector<BasicBlock*>& possibleTargets);
+    void linkBlocks(Vector<UnlinkedBlock>& unlinkedBlocks, Vector<BasicBlock*>& possibleTargets);
     
     VariableAccessData* newVariableAccessData(int operand, bool isCaptured)
     {
@@ -1021,13 +1021,13 @@
         // Potential block linking targets. Must be sorted by bytecodeBegin, and
         // cannot have two blocks that have the same bytecodeBegin. For this very
         // reason, this is not equivalent to 
-        Vector<BlockIndex> m_blockLinkingTargets;
+        Vector<BasicBlock*> m_blockLinkingTargets;
         
         // If the callsite's basic block was split into two, then this will be
         // the head of the callsite block. It needs its successors linked to the
         // m_unlinkedBlocks, but not the other way around: there's no way for
         // any blocks in m_unlinkedBlocks to jump back into this block.
-        BlockIndex m_callsiteBlockHead;
+        BasicBlock* m_callsiteBlockHead;
         
         // Does the callsite block head need linking? This is typically true
         // but will be false for the machine code block's inline stack entry
@@ -1058,7 +1058,7 @@
             ByteCodeParser*,
             CodeBlock*,
             CodeBlock* profiledBlock,
-            BlockIndex callsiteBlockHead,
+            BasicBlock* callsiteBlockHead,
             JSFunction* callee, // Null if this is a closure call.
             VirtualRegister returnValueVR,
             VirtualRegister inlineCallFrameStart,
@@ -1277,14 +1277,14 @@
     unsigned newNumLocals = inlineCallFrameStart + JSStack::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters;
     if (newNumLocals > m_numLocals) {
         m_numLocals = newNumLocals;
-        for (size_t i = 0; i < m_graph.m_blocks.size(); ++i)
-            m_graph.m_blocks[i]->ensureLocals(newNumLocals);
+        for (size_t i = 0; i < m_graph.numBlocks(); ++i)
+            m_graph.block(i)->ensureLocals(newNumLocals);
     }
     
     size_t argumentPositionStart = m_graph.m_argumentPositions.size();
 
     InlineStackEntry inlineStackEntry(
-        this, codeBlock, codeBlock, m_graph.m_blocks.size() - 1, callLinkStatus.function(),
+        this, codeBlock, codeBlock, m_graph.lastBlock(), callLinkStatus.function(),
         (VirtualRegister)m_inlineStackTop->remapOperand(resultOperand),
         (VirtualRegister)inlineCallFrameStart, argumentCountIncludingThis, kind);
     
@@ -1303,19 +1303,19 @@
     m_currentIndex = oldIndex;
     
     // If the inlined code created some new basic blocks, then we have linking to do.
-    if (inlineStackEntry.m_callsiteBlockHead != m_graph.m_blocks.size() - 1) {
+    if (inlineStackEntry.m_callsiteBlockHead != m_graph.lastBlock()) {
         
         ASSERT(!inlineStackEntry.m_unlinkedBlocks.isEmpty());
         if (inlineStackEntry.m_callsiteBlockHeadNeedsLinking)
-            linkBlock(m_graph.m_blocks[inlineStackEntry.m_callsiteBlockHead].get(), inlineStackEntry.m_blockLinkingTargets);
+            linkBlock(inlineStackEntry.m_callsiteBlockHead, inlineStackEntry.m_blockLinkingTargets);
         else
-            ASSERT(m_graph.m_blocks[inlineStackEntry.m_callsiteBlockHead]->isLinked);
+            ASSERT(inlineStackEntry.m_callsiteBlockHead->isLinked);
         
         // It's possible that the callsite block head is not owned by the caller.
         if (!inlineStackEntry.m_caller->m_unlinkedBlocks.isEmpty()) {
             // It's definitely owned by the caller, because the caller created new blocks.
             // Assert that this all adds up.
-            ASSERT(inlineStackEntry.m_caller->m_unlinkedBlocks.last().m_blockIndex == inlineStackEntry.m_callsiteBlockHead);
+            ASSERT(inlineStackEntry.m_caller->m_unlinkedBlocks.last().m_block == inlineStackEntry.m_callsiteBlockHead);
             ASSERT(inlineStackEntry.m_caller->m_unlinkedBlocks.last().m_needsNormalLinking);
             inlineStackEntry.m_caller->m_unlinkedBlocks.last().m_needsNormalLinking = false;
         } else {
@@ -1330,7 +1330,7 @@
     } else
         ASSERT(inlineStackEntry.m_unlinkedBlocks.isEmpty());
     
-    BasicBlock* lastBlock = m_graph.m_blocks.last().get();
+    BasicBlock* lastBlock = m_graph.lastBlock();
     // If there was a return, but no early returns, then we're done. We allow parsing of
     // the caller to continue in whatever basic block we're in right now.
     if (!inlineStackEntry.m_didEarlyReturn && inlineStackEntry.m_didReturn) {
@@ -1346,11 +1346,11 @@
             // for release builds because this block will never serve as a potential target
             // in the linker's binary search.
             lastBlock->bytecodeBegin = m_currentIndex;
-            m_inlineStackTop->m_caller->m_unlinkedBlocks.append(UnlinkedBlock(m_graph.m_blocks.size() - 1));
+            m_inlineStackTop->m_caller->m_unlinkedBlocks.append(UnlinkedBlock(m_graph.lastBlock()));
         }
         
-        m_currentBlock = m_graph.m_blocks.last().get();
-
+        m_currentBlock = m_graph.lastBlock();
+        
 #if DFG_ENABLE(DEBUG_VERBOSE)
         dataLogF("Done inlining executable %p, continuing code generation at epilogue.\n", executable);
 #endif
@@ -1360,32 +1360,35 @@
     // If we get to this point then all blocks must end in some sort of terminals.
     ASSERT(lastBlock->last()->isTerminal());
     
+
+    // Need to create a new basic block for the continuation at the caller.
+    RefPtr<BasicBlock> block = adoptRef(new BasicBlock(nextOffset, m_numArguments, m_numLocals));
+
+#if DFG_ENABLE(DEBUG_VERBOSE)
+    dataLogF("Creating inline epilogue basic block %p, #%zu for %p bc#%u at inline depth %u.\n", block.get(), m_graph.numBlocks(), m_inlineStackTop->executable(), m_currentIndex, CodeOrigin::inlineDepthForCallFrame(inlineCallFrame()));
+#endif
+
     // Link the early returns to the basic block we're about to create.
     for (size_t i = 0; i < inlineStackEntry.m_unlinkedBlocks.size(); ++i) {
         if (!inlineStackEntry.m_unlinkedBlocks[i].m_needsEarlyReturnLinking)
             continue;
-        BasicBlock* block = m_graph.m_blocks[inlineStackEntry.m_unlinkedBlocks[i].m_blockIndex].get();
-        ASSERT(!block->isLinked);
-        Node* node = block->last();
+        BasicBlock* blockToLink = inlineStackEntry.m_unlinkedBlocks[i].m_block;
+        ASSERT(!blockToLink->isLinked);
+        Node* node = blockToLink->last();
         ASSERT(node->op() == Jump);
-        ASSERT(node->takenBlockIndex() == NoBlock);
-        node->setTakenBlockIndex(m_graph.m_blocks.size());
+        ASSERT(node->takenBlock() == 0);
+        node->setTakenBlock(block.get());
         inlineStackEntry.m_unlinkedBlocks[i].m_needsEarlyReturnLinking = false;
 #if !ASSERT_DISABLED
-        block->isLinked = true;
+        blockToLink->isLinked = true;
 #endif
     }
     
-    // Need to create a new basic block for the continuation at the caller.
-    OwnPtr<BasicBlock> block = adoptPtr(new BasicBlock(nextOffset, m_numArguments, m_numLocals));
-#if DFG_ENABLE(DEBUG_VERBOSE)
-    dataLogF("Creating inline epilogue basic block %p, #%zu for %p bc#%u at inline depth %u.\n", block.get(), m_graph.m_blocks.size(), m_inlineStackTop->executable(), m_currentIndex, CodeOrigin::inlineDepthForCallFrame(inlineCallFrame()));
-#endif
     m_currentBlock = block.get();
-    ASSERT(m_inlineStackTop->m_caller->m_blockLinkingTargets.isEmpty() || m_graph.m_blocks[m_inlineStackTop->m_caller->m_blockLinkingTargets.last()]->bytecodeBegin < nextOffset);
-    m_inlineStackTop->m_caller->m_unlinkedBlocks.append(UnlinkedBlock(m_graph.m_blocks.size()));
-    m_inlineStackTop->m_caller->m_blockLinkingTargets.append(m_graph.m_blocks.size());
-    m_graph.m_blocks.append(block.release());
+    ASSERT(m_inlineStackTop->m_caller->m_blockLinkingTargets.isEmpty() || m_inlineStackTop->m_caller->m_blockLinkingTargets.last()->bytecodeBegin < nextOffset);
+    m_inlineStackTop->m_caller->m_unlinkedBlocks.append(UnlinkedBlock(block.get()));
+    m_inlineStackTop->m_caller->m_blockLinkingTargets.append(block.get());
+    m_graph.appendBlock(block);
     prepareToParseBlock();
     
     // At this point we return and continue to generate code for the caller, but
@@ -1757,7 +1760,7 @@
     // If we are the first basic block, introduce markers for arguments. This allows
     // us to track if a use of an argument may use the actual argument passed, as
     // opposed to using a value we set explicitly.
-    if (m_currentBlock == m_graph.m_blocks[0].get() && !inlineCallFrame()) {
+    if (m_currentBlock == m_graph.block(0) && !inlineCallFrame()) {
         m_graph.m_arguments.resize(m_numArguments);
         for (unsigned argument = 0; argument < m_numArguments; ++argument) {
             VariableAccessData* variable = newVariableAccessData(
@@ -2762,15 +2765,15 @@
             SwitchData data;
             data.kind = SwitchImm;
             data.switchTableIndex = m_inlineStackTop->m_switchRemap[currentInstruction[1].u.operand];
-            data.fallThrough = m_currentIndex + currentInstruction[2].u.operand;
+            data.setFallThroughBytecodeIndex(m_currentIndex + currentInstruction[2].u.operand);
             SimpleJumpTable& table = m_codeBlock->switchJumpTable(data.switchTableIndex);
             for (unsigned i = 0; i < table.branchOffsets.size(); ++i) {
                 if (!table.branchOffsets[i])
                     continue;
                 unsigned target = m_currentIndex + table.branchOffsets[i];
-                if (target == data.fallThrough)
+                if (target == data.fallThroughBytecodeIndex())
                     continue;
-                data.cases.append(SwitchCase(jsNumber(table.min + i), target));
+                data.cases.append(SwitchCase::withBytecodeIndex(jsNumber(table.min + i), target));
             }
             m_graph.m_switchData.append(data);
             addToGraph(Switch, OpInfo(&m_graph.m_switchData.last()), get(currentInstruction[3].u.operand));
@@ -2781,16 +2784,16 @@
             SwitchData data;
             data.kind = SwitchChar;
             data.switchTableIndex = m_inlineStackTop->m_switchRemap[currentInstruction[1].u.operand];
-            data.fallThrough = m_currentIndex + currentInstruction[2].u.operand;
+            data.setFallThroughBytecodeIndex(m_currentIndex + currentInstruction[2].u.operand);
             SimpleJumpTable& table = m_codeBlock->switchJumpTable(data.switchTableIndex);
             for (unsigned i = 0; i < table.branchOffsets.size(); ++i) {
                 if (!table.branchOffsets[i])
                     continue;
                 unsigned target = m_currentIndex + table.branchOffsets[i];
-                if (target == data.fallThrough)
+                if (target == data.fallThroughBytecodeIndex())
                     continue;
                 data.cases.append(
-                    SwitchCase(LazyJSValue::singleCharacterString(table.min + i), target));
+                    SwitchCase::withBytecodeIndex(LazyJSValue::singleCharacterString(table.min + i), target));
             }
             m_graph.m_switchData.append(data);
             addToGraph(Switch, OpInfo(&m_graph.m_switchData.last()), get(currentInstruction[3].u.operand));
@@ -2801,16 +2804,16 @@
             SwitchData data;
             data.kind = SwitchString;
             data.switchTableIndex = currentInstruction[1].u.operand;
-            data.fallThrough = m_currentIndex + currentInstruction[2].u.operand;
+            data.setFallThroughBytecodeIndex(m_currentIndex + currentInstruction[2].u.operand);
             StringJumpTable& table = m_codeBlock->stringSwitchJumpTable(data.switchTableIndex);
             StringJumpTable::StringOffsetTable::iterator iter;
             StringJumpTable::StringOffsetTable::iterator end = table.offsetTable.end();
             for (iter = table.offsetTable.begin(); iter != end; ++iter) {
                 unsigned target = m_currentIndex + iter->value.branchOffset;
-                if (target == data.fallThrough)
+                if (target == data.fallThroughBytecodeIndex())
                     continue;
                 data.cases.append(
-                    SwitchCase(LazyJSValue::knownStringImpl(iter->key.get()), target));
+                    SwitchCase::withBytecodeIndex(LazyJSValue::knownStringImpl(iter->key.get()), target));
             }
             m_graph.m_switchData.append(data);
             addToGraph(Switch, OpInfo(&m_graph.m_switchData.last()), get(currentInstruction[3].u.operand));
@@ -2825,18 +2828,18 @@
                 m_inlineStackTop->m_didReturn = true;
                 if (m_inlineStackTop->m_unlinkedBlocks.isEmpty()) {
                     // If we're returning from the first block, then we're done parsing.
-                    ASSERT(m_inlineStackTop->m_callsiteBlockHead == m_graph.m_blocks.size() - 1);
+                    ASSERT(m_inlineStackTop->m_callsiteBlockHead == m_graph.lastBlock());
                     shouldContinueParsing = false;
                     LAST_OPCODE(op_ret);
                 } else {
                     // If inlining created blocks, and we're doing a return, then we need some
                     // special linking.
-                    ASSERT(m_inlineStackTop->m_unlinkedBlocks.last().m_blockIndex == m_graph.m_blocks.size() - 1);
+                    ASSERT(m_inlineStackTop->m_unlinkedBlocks.last().m_block == m_graph.lastBlock());
                     m_inlineStackTop->m_unlinkedBlocks.last().m_needsNormalLinking = false;
                 }
                 if (m_currentIndex + OPCODE_LENGTH(op_ret) != m_inlineStackTop->m_codeBlock->instructions().size() || m_inlineStackTop->m_didEarlyReturn) {
                     ASSERT(m_currentIndex + OPCODE_LENGTH(op_ret) <= m_inlineStackTop->m_codeBlock->instructions().size());
-                    addToGraph(Jump, OpInfo(NoBlock));
+                    addToGraph(Jump, OpInfo(0));
                     m_inlineStackTop->m_unlinkedBlocks.last().m_needsEarlyReturnLinking = true;
                     m_inlineStackTop->m_didEarlyReturn = true;
                 }
@@ -3159,7 +3162,7 @@
     }
 }
 
-void ByteCodeParser::linkBlock(BasicBlock* block, Vector<BlockIndex>& possibleTargets)
+void ByteCodeParser::linkBlock(BasicBlock* block, Vector<BasicBlock*>& possibleTargets)
 {
     ASSERT(!block->isLinked);
     ASSERT(!block->isEmpty());
@@ -3168,24 +3171,24 @@
     
     switch (node->op()) {
     case Jump:
-        node->setTakenBlockIndex(m_graph.blockIndexForBytecodeOffset(possibleTargets, node->takenBytecodeOffsetDuringParsing()));
+        node->setTakenBlock(blockForBytecodeOffset(possibleTargets, node->takenBytecodeOffsetDuringParsing()));
 #if DFG_ENABLE(DEBUG_VERBOSE)
-        dataLogF("Linked basic block %p to %p, #%u.\n", block, m_graph.m_blocks[node->takenBlockIndex()].get(), node->takenBlockIndex());
+        dataLogF("Linked basic block %p to %p, #%u.\n", block, node->takenBlock(), node->takenBlock()->index);
 #endif
         break;
         
     case Branch:
-        node->setTakenBlockIndex(m_graph.blockIndexForBytecodeOffset(possibleTargets, node->takenBytecodeOffsetDuringParsing()));
-        node->setNotTakenBlockIndex(m_graph.blockIndexForBytecodeOffset(possibleTargets, node->notTakenBytecodeOffsetDuringParsing()));
+        node->setTakenBlock(blockForBytecodeOffset(possibleTargets, node->takenBytecodeOffsetDuringParsing()));
+        node->setNotTakenBlock(blockForBytecodeOffset(possibleTargets, node->notTakenBytecodeOffsetDuringParsing()));
 #if DFG_ENABLE(DEBUG_VERBOSE)
-        dataLogF("Linked basic block %p to %p, #%u and %p, #%u.\n", block, m_graph.m_blocks[node->takenBlockIndex()].get(), node->takenBlockIndex(), m_graph.m_blocks[node->notTakenBlockIndex()].get(), node->notTakenBlockIndex());
+        dataLogF("Linked basic block %p to %p, #%u and %p, #%u.\n", block, node->takenBlock(), node->takenBlock()->index, node->notTakenBlock(), node->notTakenBlock()->index);
 #endif
         break;
         
     case Switch:
         for (unsigned i = node->switchData()->cases.size(); i--;)
-            node->switchData()->cases[i].target = m_graph.blockIndexForBytecodeOffset(possibleTargets, node->switchData()->cases[i].target);
-        node->switchData()->fallThrough = m_graph.blockIndexForBytecodeOffset(possibleTargets, node->switchData()->fallThrough);
+            node->switchData()->cases[i].target = blockForBytecodeOffset(possibleTargets, node->switchData()->cases[i].targetBytecodeIndex());
+        node->switchData()->fallThrough = blockForBytecodeOffset(possibleTargets, node->switchData()->fallThroughBytecodeIndex());
         break;
         
     default:
@@ -3200,11 +3203,11 @@
 #endif
 }
 
-void ByteCodeParser::linkBlocks(Vector<UnlinkedBlock>& unlinkedBlocks, Vector<BlockIndex>& possibleTargets)
+void ByteCodeParser::linkBlocks(Vector<UnlinkedBlock>& unlinkedBlocks, Vector<BasicBlock*>& possibleTargets)
 {
     for (size_t i = 0; i < unlinkedBlocks.size(); ++i) {
         if (unlinkedBlocks[i].m_needsNormalLinking) {
-            linkBlock(m_graph.m_blocks[unlinkedBlocks[i].m_blockIndex].get(), possibleTargets);
+            linkBlock(unlinkedBlocks[i].m_block, possibleTargets);
             unlinkedBlocks[i].m_needsNormalLinking = false;
         }
     }
@@ -3232,7 +3235,7 @@
     ByteCodeParser* byteCodeParser,
     CodeBlock* codeBlock,
     CodeBlock* profiledBlock,
-    BlockIndex callsiteBlockHead,
+    BasicBlock* callsiteBlockHead,
     JSFunction* callee, // Null if this is a closure call.
     VirtualRegister returnValueVR,
     VirtualRegister inlineCallFrameStart,
@@ -3270,7 +3273,7 @@
         // Inline case.
         ASSERT(codeBlock != byteCodeParser->m_codeBlock);
         ASSERT(inlineCallFrameStart != InvalidVirtualRegister);
-        ASSERT(callsiteBlockHead != NoBlock);
+        ASSERT(callsiteBlockHead);
         
         InlineCallFrame inlineCallFrame;
         inlineCallFrame.executable.set(*byteCodeParser->m_vm, byteCodeParser->m_codeBlock->ownerExecutable(), codeBlock->ownerExecutable());
@@ -3365,7 +3368,7 @@
         ASSERT(!callee);
         ASSERT(returnValueVR == InvalidVirtualRegister);
         ASSERT(inlineCallFrameStart == InvalidVirtualRegister);
-        ASSERT(callsiteBlockHead == NoBlock);
+        ASSERT(!callsiteBlockHead);
 
         m_inlineCallFrame = 0;
 
@@ -3443,27 +3446,27 @@
         do {
             if (!m_currentBlock) {
                 // Check if we can use the last block.
-                if (!m_graph.m_blocks.isEmpty() && m_graph.m_blocks.last()->isEmpty()) {
+                if (m_graph.numBlocks() && m_graph.lastBlock()->isEmpty()) {
                     // This must be a block belonging to us.
-                    ASSERT(m_inlineStackTop->m_unlinkedBlocks.last().m_blockIndex == m_graph.m_blocks.size() - 1);
+                    ASSERT(m_inlineStackTop->m_unlinkedBlocks.last().m_block == m_graph.lastBlock());
                     // Either the block is linkable or it isn't. If it's linkable then it's the last
                     // block in the blockLinkingTargets list. If it's not then the last block will
                     // have a lower bytecode index that the one we're about to give to this block.
-                    if (m_inlineStackTop->m_blockLinkingTargets.isEmpty() || m_graph.m_blocks[m_inlineStackTop->m_blockLinkingTargets.last()]->bytecodeBegin != m_currentIndex) {
+                    if (m_inlineStackTop->m_blockLinkingTargets.isEmpty() || m_inlineStackTop->m_blockLinkingTargets.last()->bytecodeBegin != m_currentIndex) {
                         // Make the block linkable.
-                        ASSERT(m_inlineStackTop->m_blockLinkingTargets.isEmpty() || m_graph.m_blocks[m_inlineStackTop->m_blockLinkingTargets.last()]->bytecodeBegin < m_currentIndex);
-                        m_inlineStackTop->m_blockLinkingTargets.append(m_graph.m_blocks.size() - 1);
+                        ASSERT(m_inlineStackTop->m_blockLinkingTargets.isEmpty() || m_inlineStackTop->m_blockLinkingTargets.last()->bytecodeBegin < m_currentIndex);
+                        m_inlineStackTop->m_blockLinkingTargets.append(m_graph.lastBlock());
                     }
                     // Change its bytecode begin and continue.
-                    m_currentBlock = m_graph.m_blocks.last().get();
+                    m_currentBlock = m_graph.lastBlock();
 #if DFG_ENABLE(DEBUG_VERBOSE)
                     dataLogF("Reascribing bytecode index of block %p from bc#%u to bc#%u (peephole case).\n", m_currentBlock, m_currentBlock->bytecodeBegin, m_currentIndex);
 #endif
                     m_currentBlock->bytecodeBegin = m_currentIndex;
                 } else {
-                    OwnPtr<BasicBlock> block = adoptPtr(new BasicBlock(m_currentIndex, m_numArguments, m_numLocals));
+                    RefPtr<BasicBlock> block = adoptRef(new BasicBlock(m_currentIndex, m_numArguments, m_numLocals));
 #if DFG_ENABLE(DEBUG_VERBOSE)
-                    dataLogF("Creating basic block %p, #%zu for %p bc#%u at inline depth %u.\n", block.get(), m_graph.m_blocks.size(), m_inlineStackTop->executable(), m_currentIndex, CodeOrigin::inlineDepthForCallFrame(inlineCallFrame()));
+                    dataLogF("Creating basic block %p, #%zu for %p bc#%u at inline depth %u.\n", block.get(), m_graph.numBlocks(), m_inlineStackTop->executable(), m_currentIndex, CodeOrigin::inlineDepthForCallFrame(inlineCallFrame()));
 #endif
                     m_currentBlock = block.get();
                     // This assertion checks two things:
@@ -3472,13 +3475,13 @@
                     // 2) If the bytecodeBegin is equal to the currentIndex, then we failed to do
                     //    a peephole coalescing of this block in the if statement above. So, we're
                     //    generating suboptimal code and leaving more work for the CFG simplifier.
-                    ASSERT(m_inlineStackTop->m_unlinkedBlocks.isEmpty() || m_graph.m_blocks[m_inlineStackTop->m_unlinkedBlocks.last().m_blockIndex]->bytecodeBegin < m_currentIndex);
-                    m_inlineStackTop->m_unlinkedBlocks.append(UnlinkedBlock(m_graph.m_blocks.size()));
-                    m_inlineStackTop->m_blockLinkingTargets.append(m_graph.m_blocks.size());
+                    ASSERT(m_inlineStackTop->m_unlinkedBlocks.isEmpty() || m_inlineStackTop->m_unlinkedBlocks.last().m_block->bytecodeBegin < m_currentIndex);
+                    m_inlineStackTop->m_unlinkedBlocks.append(UnlinkedBlock(block.get()));
+                    m_inlineStackTop->m_blockLinkingTargets.append(block.get());
                     // The first block is definitely an OSR target.
-                    if (!m_graph.m_blocks.size())
+                    if (!m_graph.numBlocks())
                         block->isOSRTarget = true;
-                    m_graph.m_blocks.append(block.release());
+                    m_graph.appendBlock(block);
                     prepareToParseBlock();
                 }
             }
@@ -3517,7 +3520,7 @@
 #endif
     
     InlineStackEntry inlineStackEntry(
-        this, m_codeBlock, m_profiledBlock, NoBlock, 0, InvalidVirtualRegister, InvalidVirtualRegister,
+        this, m_codeBlock, m_profiledBlock, 0, 0, InvalidVirtualRegister, InvalidVirtualRegister,
         m_codeBlock->numParameters(), CodeForCall);
     
     parseCodeBlock();
@@ -3534,11 +3537,11 @@
         }
     }
     
-    for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-        BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+    for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+        BasicBlock* block = m_graph.block(blockIndex);
         ASSERT(block);
         if (!block->isReachable) {
-            m_graph.m_blocks[blockIndex].clear();
+            m_graph.killBlock(block);
             continue;
         }
         
diff --git a/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp b/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp
index be40afe..095c0d0 100644
--- a/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp
@@ -79,15 +79,14 @@
     }
     
 private:
-    void performBlockCFA(BlockIndex blockIndex)
+    void performBlockCFA(BasicBlock* block)
     {
-        BasicBlock* block = m_graph.m_blocks[blockIndex].get();
         if (!block)
             return;
         if (!block->cfaShouldRevisit)
             return;
         if (verbose)
-            dataLogF("   Block #%u (bc#%u):\n", blockIndex, block->bytecodeBegin);
+            dataLog("   Block ", *block, ":\n");
         m_state.beginBasicBlock(block);
         if (verbose) {
             dataLogF("      head vars: ");
@@ -127,8 +126,8 @@
         if (verbose)
             dataLogF("CFA [%u]\n", ++m_count);
         
-        for (BlockIndex block = 0; block < m_graph.m_blocks.size(); ++block)
-            performBlockCFA(block);
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
+            performBlockCFA(m_graph.block(blockIndex));
     }
 
 private:
diff --git a/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp b/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
index add8328..6473f1c 100644
--- a/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
@@ -54,8 +54,8 @@
         
         do {
             innerChanged = false;
-            for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-                BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+            for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+                BasicBlock* block = m_graph.block(blockIndex);
                 if (!block)
                     continue;
                 ASSERT(block->isReachable);
@@ -63,27 +63,24 @@
                 switch (block->last()->op()) {
                 case Jump: {
                     // Successor with one predecessor -> merge.
-                    if (m_graph.m_blocks[m_graph.successor(block, 0)]->m_predecessors.size() == 1) {
-                        ASSERT(m_graph.m_blocks[m_graph.successor(block, 0)]->m_predecessors[0]
-                               == blockIndex);
+                    if (block->successor(0)->predecessors.size() == 1) {
+                        ASSERT(block->successor(0)->predecessors[0] == block);
 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
-                        dataLogF("CFGSimplify: Jump merge on Block #%u to Block #%u.\n",
-                                blockIndex, m_graph.successor(block, 0));
+                        dataLog("CFGSimplify: Jump merge on Block ", *block, " to Block ", *block->successor(0), ".\n");
 #endif
                         if (extremeLogging)
                             m_graph.dump();
                         m_graph.dethread();
-                        mergeBlocks(blockIndex, m_graph.successor(block, 0), noBlocks());
+                        mergeBlocks(block, block->successor(0), noBlocks());
                         innerChanged = outerChanged = true;
                         break;
                     } else {
 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
-                        dataLogF("Not jump merging on Block #%u to Block #%u because predecessors = ",
-                                blockIndex, m_graph.successor(block, 0));
-                        for (unsigned i = 0; i < m_graph.m_blocks[m_graph.successor(block, 0)]->m_predecessors.size(); ++i) {
+                        dataLog("CFGSimplify: Not jump merging on Block ", *block, " to Block ", *block->successor(0), " because predecessors = ",);
+                        for (unsigned i = 0; i < block->successor(0)->predecessors.size(); ++i) {
                             if (i)
                                 dataLogF(", ");
-                            dataLogF("#%u", m_graph.m_blocks[m_graph.successor(block, 0)]->m_predecessors[i]);
+                            dataLog(*block->successor(0)->predecessors[i]);
                         }
                         dataLogF(".\n");
 #endif
@@ -103,52 +100,47 @@
                     // Branch on constant -> jettison the not-taken block and merge.
                     if (isKnownDirection(block->cfaBranchDirection)) {
                         bool condition = branchCondition(block->cfaBranchDirection);
-                        BasicBlock* targetBlock = m_graph.m_blocks[
-                            m_graph.successorForCondition(block, condition)].get();
-                        if (targetBlock->m_predecessors.size() == 1) {
+                        BasicBlock* targetBlock = block->successorForCondition(condition);
+                        BasicBlock* jettisonedBlock = block->successorForCondition(!condition);
+                        if (targetBlock->predecessors.size() == 1) {
 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
-                            dataLogF("CFGSimplify: Known condition (%s) branch merge on Block #%u to Block #%u, jettisoning Block #%u.\n",
-                                    condition ? "true" : "false",
-                                    blockIndex, m_graph.successorForCondition(block, condition),
-                                    m_graph.successorForCondition(block, !condition));
+                            dataLog(
+                                "CFGSimplify: Known condition (", condition, ") branch merge ",
+                                "on Block ", *block, " to Block ", *targetBlock,
+                                ", jettisoning Block ", *jettisonedBlock, ".\n");
 #endif
                             if (extremeLogging)
                                 m_graph.dump();
                             m_graph.dethread();
-                            mergeBlocks(
-                                blockIndex,
-                                m_graph.successorForCondition(block, condition),
-                                oneBlock(m_graph.successorForCondition(block, !condition)));
+                            mergeBlocks(block, targetBlock, oneBlock(jettisonedBlock));
                         } else {
 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
-                            dataLogF("CFGSimplify: Known condition (%s) branch->jump conversion on Block #%u to Block #%u, jettisoning Block #%u.\n",
-                                    condition ? "true" : "false",
-                                    blockIndex, m_graph.successorForCondition(block, condition),
-                                    m_graph.successorForCondition(block, !condition));
+                            dataLog(
+                                "CFGSimplify: Known condition (", condition, ") ",
+                                "branch->jump conversion on Block ", *block, " to Block ",
+                                targetBlock, ", jettisoning Block ", jettisonedBlock, ".\n");
 #endif
                             if (extremeLogging)
                                 m_graph.dump();
                             m_graph.dethread();
-                            BlockIndex takenBlockIndex = m_graph.successorForCondition(block, condition);
-                            BlockIndex notTakenBlockIndex = m_graph.successorForCondition(block, !condition);
                         
                             ASSERT(block->last()->isTerminal());
                             CodeOrigin boundaryCodeOrigin = block->last()->codeOrigin;
                             block->last()->convertToPhantom();
                             ASSERT(block->last()->refCount() == 1);
                         
-                            jettisonBlock(blockIndex, notTakenBlockIndex, boundaryCodeOrigin);
+                            jettisonBlock(block, jettisonedBlock, boundaryCodeOrigin);
                         
                             block->appendNode(
                                 m_graph, SpecNone, Jump, boundaryCodeOrigin,
-                                OpInfo(takenBlockIndex));
+                                OpInfo(targetBlock));
                         }
                         innerChanged = outerChanged = true;
                         break;
                     }
                     
-                    if (m_graph.successor(block, 0) == m_graph.successor(block, 1)) {
-                        convertToJump(blockIndex, m_graph.successor(block, 0));
+                    if (block->successor(0) == block->successor(1)) {
+                        convertToJump(block, block->successor(0));
                         innerChanged = outerChanged = true;
                         break;
                     }
@@ -177,7 +169,7 @@
                     // If there are no cases other than default then this turns
                     // into a jump.
                     if (data->cases.isEmpty()) {
-                        convertToJump(blockIndex, data->fallThrough);
+                        convertToJump(block, data->fallThrough);
                         innerChanged = outerChanged = true;
                         break;
                     }
@@ -186,47 +178,44 @@
                     if (block->last()->child1()->hasConstant()) {
                         JSValue value = m_graph.valueOfJSConstant(block->last()->child1().node());
                         TriState found = FalseTriState;
-                        BlockIndex targetBlockIndex = NoBlock;
+                        BasicBlock* targetBlock = 0;
                         for (unsigned i = data->cases.size(); found == FalseTriState && i--;) {
                             found = data->cases[i].value.strictEqual(value);
                             if (found == TrueTriState)
-                                targetBlockIndex = data->cases[i].target;
+                                targetBlock = data->cases[i].target;
                         }
                         
                         if (found == MixedTriState)
                             break;
                         if (found == FalseTriState)
-                            targetBlockIndex = data->fallThrough;
-                        ASSERT(targetBlockIndex != NoBlock);
+                            targetBlock = data->fallThrough;
+                        ASSERT(targetBlock);
                         
-                        Vector<BlockIndex, 1> jettisonedBlocks;
-                        for (unsigned i = m_graph.numSuccessors(block); i--;) {
-                            BlockIndex jettisonedBlockIndex = m_graph.successor(block, i);
-                            if (jettisonedBlockIndex != targetBlockIndex)
-                                jettisonedBlocks.append(jettisonedBlockIndex);
+                        Vector<BasicBlock*, 1> jettisonedBlocks;
+                        for (unsigned i = block->numSuccessors(); i--;) {
+                            BasicBlock* jettisonedBlock = block->successor(i);
+                            if (jettisonedBlock != targetBlock)
+                                jettisonedBlocks.append(jettisonedBlock);
                         }
                         
-                        BasicBlock* targetBlock = m_graph.m_blocks[targetBlockIndex].get();
-                        
-                        if (targetBlock->m_predecessors.size() == 1) {
+                        if (targetBlock->predecessors.size() == 1) {
 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
                             dataLog(
                                 "CFGSimplify: Known constant (", value, ") switch merge on ",
-                                "Block #", blockIndex, " to Block #", targetBlockIndex,
-                                ".\n");
+                                "Block ", *block, " to Block ", *targetBlock, ".\n");
 #endif
                             
                             if (extremeLogging)
                                 m_graph.dump();
                             m_graph.dethread();
                             
-                            mergeBlocks(blockIndex, targetBlockIndex, jettisonedBlocks);
+                            mergeBlocks(block, targetBlock, jettisonedBlocks);
                         } else {
 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
                             dataLog(
                                 "CFGSimplify: Known constant (", value, ") switch->jump "
-                                "conversion on Block #", blockIndex, " to Block #",
-                                targetBlockIndex, ".\n");
+                                "conversion on Block ", *block, " to Block #",
+                                *targetBlock, ".\n");
 #endif
                             if (extremeLogging)
                                 m_graph.dump();
@@ -235,9 +224,9 @@
                             CodeOrigin boundaryCodeOrigin = block->last()->codeOrigin;
                             block->last()->convertToPhantom();
                             for (unsigned i = jettisonedBlocks.size(); i--;)
-                                jettisonBlock(blockIndex, jettisonedBlocks[i], boundaryCodeOrigin);
+                                jettisonBlock(block, jettisonedBlocks[i], boundaryCodeOrigin);
                             block->appendNode(
-                                m_graph, SpecNone, Jump, boundaryCodeOrigin, OpInfo(targetBlockIndex));
+                                m_graph, SpecNone, Jump, boundaryCodeOrigin, OpInfo(targetBlock));
                         }
                         innerChanged = outerChanged = true;
                         break;
@@ -283,14 +272,14 @@
                 m_graph.invalidateCFG();
                 m_graph.resetReachability();
 
-                for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-                    BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+                for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+                    BasicBlock* block = m_graph.block(blockIndex);
                     if (!block)
                         continue;
                     if (block->isReachable)
                         continue;
                     
-                    killUnreachable(blockIndex);
+                    killUnreachable(block);
                 }
             }
             
@@ -302,25 +291,23 @@
     }
 
 private:
-    void convertToJump(BlockIndex blockIndex, BlockIndex targetBlockIndex)
+    void convertToJump(BasicBlock* block, BasicBlock* targetBlock)
     {
-        BasicBlock* block = m_graph.m_blocks[blockIndex].get();
-        BasicBlock* targetBlock = m_graph.m_blocks[targetBlockIndex].get();
         ASSERT(targetBlock);
         ASSERT(targetBlock->isReachable);
-        if (targetBlock->m_predecessors.size() == 1) {
+        if (targetBlock->predecessors.size() == 1) {
 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
-            dataLogF(
-                "CFGSimplify: Branch/Switch to same successor merge on Block #%u to Block #%u.\n",
-                blockIndex, targetBlockIndex);
+            dataLog(
+                "CFGSimplify: Branch/Switch to same successor merge on Block ", *block,
+                " to Block ", *targetBlock, ".\n");
 #endif
             m_graph.dethread();
-            mergeBlocks(blockIndex, targetBlockIndex, noBlocks());
+            mergeBlocks(block, targetBlock, noBlocks());
         } else {
 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
-            dataLogF(
-                "CFGSimplify: Branch->jump conversion to same successor on Block #%u to Block #%u.\n",
-                blockIndex, targetBlockIndex);
+            dataLog(
+                "CFGSimplify: Branch->jump conversion to same successor on Block ",
+                *block, " to Block ", *targetBlock, ".\n",
 #endif
             Node* branch = block->last();
             ASSERT(branch->isTerminal());
@@ -330,14 +317,12 @@
             
             block->appendNode(
                 m_graph, SpecNone, Jump, branch->codeOrigin,
-                OpInfo(targetBlockIndex));
+                OpInfo(targetBlock));
         }
     }
 
-    void killUnreachable(BlockIndex blockIndex)
+    void killUnreachable(BasicBlock* block)
     {
-        BasicBlock* block = m_graph.m_blocks[blockIndex].get();
-        
         ASSERT(block);
         ASSERT(!block->isReachable);
         
@@ -346,7 +331,7 @@
         for (unsigned nodeIndex = block->size(); nodeIndex--;)
             m_graph.m_allocator.free(block->at(nodeIndex));
         
-        m_graph.m_blocks[blockIndex].clear();
+        m_graph.killBlock(block);
     }
     
     void keepOperandAlive(BasicBlock* block, BasicBlock* jettisonedBlock, CodeOrigin codeOrigin, int operand)
@@ -361,49 +346,47 @@
             OpInfo(livenessNode->variableAccessData()));
     }
     
-    void jettisonBlock(BlockIndex blockIndex, BlockIndex jettisonedBlockIndex, CodeOrigin boundaryCodeOrigin)
+    void jettisonBlock(BasicBlock* block, BasicBlock* jettisonedBlock, CodeOrigin boundaryCodeOrigin)
     {
-        BasicBlock* block = m_graph.m_blocks[blockIndex].get();
-        BasicBlock* jettisonedBlock = m_graph.m_blocks[jettisonedBlockIndex].get();
-        
         for (size_t i = 0; i < jettisonedBlock->variablesAtHead.numberOfArguments(); ++i)
             keepOperandAlive(block, jettisonedBlock, boundaryCodeOrigin, argumentToOperand(i));
         for (size_t i = 0; i < jettisonedBlock->variablesAtHead.numberOfLocals(); ++i)
             keepOperandAlive(block, jettisonedBlock, boundaryCodeOrigin, i);
         
-        fixJettisonedPredecessors(blockIndex, jettisonedBlockIndex);
+        fixJettisonedPredecessors(block, jettisonedBlock);
     }
     
-    void fixJettisonedPredecessors(BlockIndex blockIndex, BlockIndex jettisonedBlockIndex)
+    void fixJettisonedPredecessors(BasicBlock* block, BasicBlock* jettisonedBlock)
     {
 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
-        dataLogF("Fixing predecessors and phis due to jettison of Block #%u from Block #%u.\n",
-                jettisonedBlockIndex, blockIndex);
+        dataLog(
+            "Fixing predecessors and phis due to jettison of Block ", *jettisonedBlock,
+            " from Block ", *block, ".\n",
 #endif
-        BasicBlock* jettisonedBlock = m_graph.m_blocks[jettisonedBlockIndex].get();
-        for (unsigned i = 0; i < jettisonedBlock->m_predecessors.size(); ++i) {
-            if (jettisonedBlock->m_predecessors[i] != blockIndex)
+        for (unsigned i = 0; i < jettisonedBlock->predecessors.size(); ++i) {
+            if (jettisonedBlock->predecessors[i] != block)
                 continue;
-            jettisonedBlock->m_predecessors[i] = jettisonedBlock->m_predecessors.last();
-            jettisonedBlock->m_predecessors.removeLast();
+            jettisonedBlock->predecessors[i] = jettisonedBlock->predecessors.last();
+            jettisonedBlock->predecessors.removeLast();
             break;
         }
     }
 
-    Vector<BlockIndex, 1> noBlocks()
+    Vector<BasicBlock*, 1> noBlocks()
     {
-        return Vector<BlockIndex, 1>();
+        return Vector<BasicBlock*, 1>();
     }
     
-    Vector<BlockIndex, 1> oneBlock(BlockIndex blockIndex)
+    Vector<BasicBlock*, 1> oneBlock(BasicBlock* block)
     {
-        Vector<BlockIndex, 1> result;
-        result.append(blockIndex);
+        Vector<BasicBlock*, 1> result;
+        result.append(block);
         return result;
     }
     
     void mergeBlocks(
-        BlockIndex firstBlockIndex, BlockIndex secondBlockIndex, Vector<BlockIndex, 1> jettisonedBlockIndices)
+        BasicBlock* firstBlock, BasicBlock* secondBlock,
+        Vector<BasicBlock*, 1> jettisonedBlocks)
     {
         // This will add all of the nodes in secondBlock to firstBlock, but in so doing
         // it will also ensure that any GetLocals from the second block that refer to
@@ -411,9 +394,6 @@
         // then Phantoms are inserted for anything that the jettisonedBlock would have
         // kept alive.
         
-        BasicBlock* firstBlock = m_graph.m_blocks[firstBlockIndex].get();
-        BasicBlock* secondBlock = m_graph.m_blocks[secondBlockIndex].get();
-        
         // Remove the terminal of firstBlock since we don't need it anymore. Well, we don't
         // really remove it; we actually turn it into a Phantom.
         ASSERT(firstBlock->last()->isTerminal());
@@ -421,8 +401,8 @@
         firstBlock->last()->convertToPhantom();
         ASSERT(firstBlock->last()->refCount() == 1);
         
-        for (unsigned i = jettisonedBlockIndices.size(); i--;) {
-            BasicBlock* jettisonedBlock = m_graph.m_blocks[jettisonedBlockIndices[i]].get();
+        for (unsigned i = jettisonedBlocks.size(); i--;) {
+            BasicBlock* jettisonedBlock = jettisonedBlocks[i];
             
             // Time to insert ghosties for things that need to be kept alive in case we OSR
             // exit prior to hitting the firstBlock's terminal, and end up going down a
@@ -447,23 +427,23 @@
         // predecessors eagerly to ensure that we know what they are in case the next block we
         // consider in this phase wishes to query the predecessors of one of the blocks we
         // affected.
-        for (unsigned i = m_graph.numSuccessors(firstBlock); i--;) {
-            BasicBlock* successor = m_graph.m_blocks[m_graph.successor(firstBlock, i)].get();
-            for (unsigned j = 0; j < successor->m_predecessors.size(); ++j) {
-                if (successor->m_predecessors[j] == secondBlockIndex)
-                    successor->m_predecessors[j] = firstBlockIndex;
+        for (unsigned i = firstBlock->numSuccessors(); i--;) {
+            BasicBlock* successor = firstBlock->successor(i);
+            for (unsigned j = 0; j < successor->predecessors.size(); ++j) {
+                if (successor->predecessors[j] == secondBlock)
+                    successor->predecessors[j] = firstBlock;
             }
         }
         
         // Fix the predecessors of my former successors. Again, we'd rather not do this, but it's
         // an unfortunate necessity. See above comment.
-        for (unsigned i = jettisonedBlockIndices.size(); i--;)
-            fixJettisonedPredecessors(firstBlockIndex, jettisonedBlockIndices[i]);
+        for (unsigned i = jettisonedBlocks.size(); i--;)
+            fixJettisonedPredecessors(firstBlock, jettisonedBlocks[i]);
         
         firstBlock->valuesAtTail = secondBlock->valuesAtTail;
         firstBlock->cfaBranchDirection = secondBlock->cfaBranchDirection;
         
-        m_graph.m_blocks[secondBlockIndex].clear();
+        m_graph.killBlock(secondBlock);
     }
 };
 
diff --git a/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp b/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp
index a10fbe8..cef4982 100644
--- a/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp
@@ -69,8 +69,8 @@
     {
         SamplingRegion samplingRegion("DFG CPS Rethreading: freeUnnecessaryNodes");
         
-        for (BlockIndex blockIndex = m_graph.m_blocks.size(); blockIndex--;) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             ASSERT(block->isReachable);
@@ -387,8 +387,8 @@
     {
         SamplingRegion samplingRegion("DFG CPS Rethreading: canonicalizeLocalsInBlocks");
         
-        for (m_blockIndex = m_graph.m_blocks.size(); m_blockIndex--;) {
-            m_block = m_graph.m_blocks[m_blockIndex].get();
+        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+            m_block = m_graph.block(blockIndex);
             canonicalizeLocalsInBlock();
         }
     }
@@ -402,20 +402,19 @@
         
         // Ensure that attempts to use this fail instantly.
         m_block = 0;
-        m_blockIndex = NoBlock;
         
         while (!phiStack.isEmpty()) {
             PhiStackEntry entry = phiStack.last();
             phiStack.removeLast();
             
             BasicBlock* block = entry.m_block;
-            PredecessorList& predecessors = block->m_predecessors;
+            PredecessorList& predecessors = block->predecessors;
             Node* currentPhi = entry.m_phi;
             VariableAccessData* variable = currentPhi->variableAccessData();
             size_t index = entry.m_index;
             
             for (size_t i = predecessors.size(); i--;) {
-                BasicBlock* predecessorBlock = m_graph.m_blocks[predecessors[i]].get();
+                BasicBlock* predecessorBlock = predecessors[i];
                 
                 Node* variableInPrevious = predecessorBlock->variablesAtTail.atFor<operandKind>(index);
                 if (!variableInPrevious) {
@@ -481,7 +480,6 @@
         return m_localPhiStack;
     }
     
-    BlockIndex m_blockIndex;
     BasicBlock* m_block;
     Vector<PhiStackEntry, 128> m_argumentPhiStack;
     Vector<PhiStackEntry, 128> m_localPhiStack;
diff --git a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
index 9a9d9b7..efd07fb 100644
--- a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
@@ -52,8 +52,8 @@
         
         m_changed = false;
         
-        for (unsigned block = 0; block < m_graph.m_blocks.size(); ++block)
-            performBlockCSE(m_graph.m_blocks[block].get());
+        for (unsigned blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
+            performBlockCSE(m_graph.block(blockIndex));
         
         return m_changed;
     }
diff --git a/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp b/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
index 3b85bd3..229b588 100644
--- a/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
@@ -52,24 +52,23 @@
     {
         bool changed = false;
         
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             if (block->cfaFoundConstants)
-                changed |= foldConstants(blockIndex);
+                changed |= foldConstants(block);
         }
         
         return changed;
     }
 
 private:
-    bool foldConstants(BlockIndex blockIndex)
+    bool foldConstants(BasicBlock* block)
     {
 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
-        dataLogF("Constant folding considering Block #%u.\n", blockIndex);
+        dataLog("Constant folding considering Block ", *block, ".\n");
 #endif
-        BasicBlock* block = m_graph.m_blocks[blockIndex].get();
         bool changed = false;
         m_state.beginBasicBlock(block);
         for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
diff --git a/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp b/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp
index 5cda110..4527980 100644
--- a/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp
@@ -46,8 +46,8 @@
     bool run()
     {
         // First reset the counts to 0 for all nodes.
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             for (unsigned indexInBlock = block->size(); indexInBlock--;)
@@ -60,8 +60,8 @@
         // - Nodes that are must-generate.
         // - Nodes that are reachable from type checks.
         // Set their ref counts to 1 and put them on the worklist.
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             for (unsigned indexInBlock = block->size(); indexInBlock--;) {
@@ -81,8 +81,8 @@
             DFG_NODE_DO_TO_CHILDREN(m_graph, node, countEdge);
         }
         
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
 
diff --git a/Source/JavaScriptCore/dfg/DFGDisassembler.cpp b/Source/JavaScriptCore/dfg/DFGDisassembler.cpp
index abaf4ba..5bc842b 100644
--- a/Source/JavaScriptCore/dfg/DFGDisassembler.cpp
+++ b/Source/JavaScriptCore/dfg/DFGDisassembler.cpp
@@ -36,7 +36,7 @@
 Disassembler::Disassembler(Graph& graph)
     : m_graph(graph)
 {
-    m_labelForBlockIndex.resize(graph.m_blocks.size());
+    m_labelForBlockIndex.resize(graph.numBlocks());
 }
 
 void Disassembler::dump(PrintStream& out, LinkBuffer& linkBuffer)
@@ -97,13 +97,13 @@
     
     Node* lastNode = 0;
     MacroAssembler::Label previousLabel = m_startOfCode;
-    for (size_t blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-        BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+    for (size_t blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+        BasicBlock* block = m_graph.block(blockIndex);
         if (!block)
             continue;
         dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, m_labelForBlockIndex[blockIndex], lastNode);
         append(result, out, previousOrigin);
-        m_graph.dumpBlockHeader(out, prefix, blockIndex, Graph::DumpLivePhisOnly);
+        m_graph.dumpBlockHeader(out, prefix, block, Graph::DumpLivePhisOnly);
         append(result, out, previousOrigin);
         Node* lastNodeForDisassembly = block->at(0);
         for (size_t i = 0; i < block->size(); ++i) {
@@ -118,7 +118,7 @@
                 // as the end point. This case is hit either during peephole compare
                 // optimizations (the Branch won't have its own label) or if we have a
                 // forced OSR exit.
-                if (blockIndex + 1 < m_graph.m_blocks.size())
+                if (blockIndex + 1 < m_graph.numBlocks())
                     currentLabel = m_labelForBlockIndex[blockIndex + 1];
                 else
                     currentLabel = m_endOfMainPath;
diff --git a/Source/JavaScriptCore/dfg/DFGDisassembler.h b/Source/JavaScriptCore/dfg/DFGDisassembler.h
index 9f6c5b0..c0cf130 100644
--- a/Source/JavaScriptCore/dfg/DFGDisassembler.h
+++ b/Source/JavaScriptCore/dfg/DFGDisassembler.h
@@ -47,7 +47,7 @@
     Disassembler(Graph&);
     
     void setStartOfCode(MacroAssembler::Label label) { m_startOfCode = label; }
-    void setForBlock(BlockIndex blockIndex, MacroAssembler::Label label)
+    void setForBlockIndex(BlockIndex blockIndex, MacroAssembler::Label label)
     {
         m_labelForBlockIndex[blockIndex] = label;
     }
diff --git a/Source/JavaScriptCore/dfg/DFGDominators.cpp b/Source/JavaScriptCore/dfg/DFGDominators.cpp
index 6f9037e..0997362 100644
--- a/Source/JavaScriptCore/dfg/DFGDominators.cpp
+++ b/Source/JavaScriptCore/dfg/DFGDominators.cpp
@@ -44,9 +44,9 @@
 {
     // This implements a naive dominator solver.
     
-    ASSERT(graph.m_blocks[0]->m_predecessors.isEmpty());
+    ASSERT(graph.block(0)->predecessors.isEmpty());
     
-    unsigned numBlocks = graph.m_blocks.size();
+    unsigned numBlocks = graph.numBlocks();
     
     if (numBlocks > m_results.size()) {
         m_results.grow(numBlocks);
@@ -60,13 +60,13 @@
     
     m_scratch.clearAll();
     for (unsigned i = numBlocks; i--;) {
-        if (!graph.m_blocks[i])
+        if (!graph.block(i))
             continue;
         m_scratch.set(i);
     }
     
     for (unsigned i = numBlocks; i-- > 1;) {
-        if (!graph.m_blocks[i] || graph.m_blocks[i]->m_predecessors.isEmpty())
+        if (!graph.block(i) || graph.block(i)->predecessors.isEmpty())
             m_results[i].clearAll();
         else
             m_results[i].set(m_scratch);
@@ -88,14 +88,14 @@
 
 bool Dominators::iterateForBlock(Graph& graph, BlockIndex i)
 {
-    BasicBlock* block = graph.m_blocks[i].get();
+    BasicBlock* block = graph.block(i);
     if (!block)
         return false;
-    if (block->m_predecessors.isEmpty())
+    if (block->predecessors.isEmpty())
         return false;
-    m_scratch.set(m_results[block->m_predecessors[0]]);
-    for (unsigned j = block->m_predecessors.size(); j-- > 1;)
-        m_scratch.filter(m_results[block->m_predecessors[j]]);
+    m_scratch.set(m_results[block->predecessors[0]->index]);
+    for (unsigned j = block->predecessors.size(); j-- > 1;)
+        m_scratch.filter(m_results[block->predecessors[j]->index]);
     m_scratch.set(i);
     return m_results[i].setAndCheck(m_scratch);
 }
diff --git a/Source/JavaScriptCore/dfg/DFGDominators.h b/Source/JavaScriptCore/dfg/DFGDominators.h
index dd6eeda..5392770 100644
--- a/Source/JavaScriptCore/dfg/DFGDominators.h
+++ b/Source/JavaScriptCore/dfg/DFGDominators.h
@@ -31,6 +31,7 @@
 #if ENABLE(DFG_JIT)
 
 #include "DFGAnalysis.h"
+#include "DFGBasicBlock.h"
 #include "DFGCommon.h"
 #include <wtf/FastBitVector.h>
 
@@ -48,7 +49,12 @@
     bool dominates(BlockIndex from, BlockIndex to) const
     {
         ASSERT(isValid());
-        return m_results[to].get(from);
+        return m_results[from].get(to);
+    }
+    
+    bool dominates(BasicBlock* from, BasicBlock* to) const
+    {
+        return dominates(from->index, to->index);
     }
     
 private:
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index 8d3e33d..f9be4c9 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -51,8 +51,8 @@
         ASSERT(m_graph.m_form == ThreadedCPS);
         
         m_profitabilityChanged = false;
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex)
-            fixupBlock(m_graph.m_blocks[blockIndex].get());
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
+            fixupBlock(m_graph.block(blockIndex));
         
         while (m_profitabilityChanged) {
             m_profitabilityChanged = false;
@@ -60,8 +60,8 @@
             for (unsigned i = m_graph.m_argumentPositions.size(); i--;)
                 m_graph.m_argumentPositions[i].mergeArgumentUnboxingAwareness();
             
-            for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex)
-                fixupSetLocalsInBlock(m_graph.m_blocks[blockIndex].get());
+            for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
+                fixupSetLocalsInBlock(m_graph.block(blockIndex));
         }
         
         return true;
@@ -589,10 +589,10 @@
                     if (newChildEdge->hasBooleanResult()) {
                         node->children.setChild1(newChildEdge);
                         
-                        BlockIndex toBeTaken = node->notTakenBlockIndex();
-                        BlockIndex toBeNotTaken = node->takenBlockIndex();
-                        node->setTakenBlockIndex(toBeTaken);
-                        node->setNotTakenBlockIndex(toBeNotTaken);
+                        BasicBlock* toBeTaken = node->notTakenBlock();
+                        BasicBlock* toBeNotTaken = node->takenBlock();
+                        node->setTakenBlock(toBeTaken);
+                        node->setNotTakenBlock(toBeNotTaken);
                     }
                 }
             }
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.cpp b/Source/JavaScriptCore/dfg/DFGGraph.cpp
index 93f8c55..36da8f5 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.cpp
+++ b/Source/JavaScriptCore/dfg/DFGGraph.cpp
@@ -253,15 +253,15 @@
     if (op == WeakJSConstant)
         out.print(comma, RawPointer(node->weakConstant()), " (structure: ", *node->weakConstant()->structure(), ")");
     if (node->isBranch() || node->isJump())
-        out.print(comma, "T:#", node->takenBlockIndex());
+        out.print(comma, "T:", *node->takenBlock());
     if (node->isBranch())
-        out.print(comma, "F:#", node->notTakenBlockIndex());
+        out.print(comma, "F:", *node->notTakenBlock());
     if (node->isSwitch()) {
         SwitchData* data = node->switchData();
         out.print(comma, data->kind);
         for (unsigned i = 0; i < data->cases.size(); ++i)
-            out.print(comma, data->cases[i].value, ":#", data->cases[i].target);
-        out.print(comma, "default:#", data->fallThrough);
+            out.print(comma, data->cases[i].value, ":", *data->cases[i].target);
+        out.print(comma, "default:", *data->fallThrough);
     }
     out.print(comma, "bc#", node->codeOrigin.bytecodeIndex);
     
@@ -277,37 +277,35 @@
     out.print("\n");
 }
 
-void Graph::dumpBlockHeader(PrintStream& out, const char* prefix, BlockIndex blockIndex, PhiNodeDumpMode phiNodeDumpMode)
+void Graph::dumpBlockHeader(PrintStream& out, const char* prefix, BasicBlock* block, PhiNodeDumpMode phiNodeDumpMode)
 {
-    BasicBlock* block = m_blocks[blockIndex].get();
-
-    out.print(prefix, "Block #", blockIndex, " (", block->at(0)->codeOrigin, "): ", block->isReachable ? "" : "(skipped)", block->isOSRTarget ? " (OSR target)" : "", "\n");
+    out.print(prefix, "Block ", *block, " (", block->at(0)->codeOrigin, "): ", block->isReachable ? "" : "(skipped)", block->isOSRTarget ? " (OSR target)" : "", "\n");
     out.print(prefix, "  Predecessors:");
-    for (size_t i = 0; i < block->m_predecessors.size(); ++i)
-        out.print(" #", block->m_predecessors[i]);
+    for (size_t i = 0; i < block->predecessors.size(); ++i)
+        out.print(" ", *block->predecessors[i]);
     out.print("\n");
     if (m_dominators.isValid()) {
         out.print(prefix, "  Dominated by:");
         for (size_t i = 0; i < m_blocks.size(); ++i) {
-            if (!m_dominators.dominates(i, blockIndex))
+            if (!m_dominators.dominates(i, block->index))
                 continue;
             out.print(" #", i);
         }
         out.print("\n");
         out.print(prefix, "  Dominates:");
         for (size_t i = 0; i < m_blocks.size(); ++i) {
-            if (!m_dominators.dominates(blockIndex, i))
+            if (!m_dominators.dominates(block->index, i))
                 continue;
             out.print(" #", i);
         }
         out.print("\n");
     }
     if (m_naturalLoops.isValid()) {
-        if (const NaturalLoop* loop = m_naturalLoops.headerOf(blockIndex)) {
+        if (const NaturalLoop* loop = m_naturalLoops.headerOf(block)) {
             out.print(prefix, "  Loop header, contains:");
             Vector<BlockIndex> sortedBlockList;
             for (unsigned i = 0; i < loop->size(); ++i)
-                sortedBlockList.append(loop->at(i));
+                sortedBlockList.append(loop->at(i)->index);
             std::sort(sortedBlockList.begin(), sortedBlockList.end());
             for (unsigned i = 0; i < sortedBlockList.size(); ++i)
                 out.print(" #", sortedBlockList[i]);
@@ -315,11 +313,11 @@
         }
         
         Vector<const NaturalLoop*> containingLoops =
-            m_naturalLoops.loopsOf(blockIndex);
+            m_naturalLoops.loopsOf(block);
         if (!containingLoops.isEmpty()) {
             out.print(prefix, "  Containing loop headers:");
             for (unsigned i = 0; i < containingLoops.size(); ++i)
-                out.print(" #", containingLoops[i]->header());
+                out.print(" ", *containingLoops[i]->header());
             out.print("\n");
         }
     }
@@ -359,7 +357,7 @@
         BasicBlock* block = m_blocks[b].get();
         if (!block)
             continue;
-        dumpBlockHeader(out, "", b, DumpAllPhis);
+        dumpBlockHeader(out, "", block, DumpAllPhis);
         out.print("  vars before: ");
         if (block->cfaHasVisited)
             dumpOperands(block->valuesAtHead, out);
@@ -409,29 +407,25 @@
     m_form = LoadStore;
 }
 
-void Graph::handleSuccessor(Vector<BlockIndex, 16>& worklist, BlockIndex blockIndex, BlockIndex successorIndex)
+void Graph::handleSuccessor(Vector<BasicBlock*, 16>& worklist, BasicBlock* block, BasicBlock* successor)
 {
-    BasicBlock* successor = m_blocks[successorIndex].get();
     if (!successor->isReachable) {
         successor->isReachable = true;
-        worklist.append(successorIndex);
+        worklist.append(successor);
     }
     
-    successor->m_predecessors.append(blockIndex);
+    successor->predecessors.append(block);
 }
 
 void Graph::determineReachability()
 {
-    Vector<BlockIndex, 16> worklist;
-    worklist.append(0);
-    m_blocks[0]->isReachable = true;
+    Vector<BasicBlock*, 16> worklist;
+    worklist.append(block(0));
+    block(0)->isReachable = true;
     while (!worklist.isEmpty()) {
-        BlockIndex index = worklist.last();
-        worklist.removeLast();
-        
-        BasicBlock* block = m_blocks[index].get();
-        for (unsigned i = numSuccessors(block); i--;)
-            handleSuccessor(worklist, index, successor(block, i));
+        BasicBlock* block = worklist.takeLast();
+        for (unsigned i = block->numSuccessors(); i--;)
+            handleSuccessor(worklist, block, block->successor(i));
     }
 }
 
@@ -442,7 +436,7 @@
         if (!block)
             continue;
         block->isReachable = false;
-        block->m_predecessors.clear();
+        block->predecessors.clear();
     }
     
     determineReachability();
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h
index 5aceaf7..1dce30e 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.h
+++ b/Source/JavaScriptCore/dfg/DFGGraph.h
@@ -169,7 +169,7 @@
     // CodeBlock is optional, but may allow additional information to be dumped (e.g. Identifier names).
     void dump(PrintStream& = WTF::dataFile());
     enum PhiNodeDumpMode { DumpLivePhisOnly, DumpAllPhis };
-    void dumpBlockHeader(PrintStream&, const char* prefix, BlockIndex, PhiNodeDumpMode);
+    void dumpBlockHeader(PrintStream&, const char* prefix, BasicBlock*, PhiNodeDumpMode);
     void dump(PrintStream&, Edge);
     void dump(PrintStream&, const char* prefix, Node*);
     static int amountOfNodeWhiteSpace(Node*);
@@ -179,8 +179,6 @@
     // preceding node. Returns true if anything was printed.
     bool dumpCodeOrigin(PrintStream&, const char* prefix, Node* previousNode, Node* currentNode);
 
-    BlockIndex blockIndexForBytecodeOffset(Vector<BlockIndex>& blocks, unsigned bytecodeBegin);
-
     SpeculatedType getJSConstantSpeculation(Node* node)
     {
         return speculationFromValue(node->valueOfJSConstant(m_codeBlock));
@@ -460,17 +458,24 @@
         return m_codeBlock->usesArguments();
     }
     
-    unsigned numSuccessors(BasicBlock* block)
+    BlockIndex numBlocks() const { return m_blocks.size(); }
+    BasicBlock* block(BlockIndex blockIndex) const { return m_blocks[blockIndex].get(); }
+    BasicBlock* lastBlock() const { return block(numBlocks() - 1); }
+
+    void appendBlock(PassRefPtr<BasicBlock> basicBlock)
     {
-        return block->last()->numSuccessors();
+        basicBlock->index = m_blocks.size();
+        m_blocks.append(basicBlock);
     }
-    BlockIndex successor(BasicBlock* block, unsigned index)
+    
+    void killBlock(BlockIndex blockIndex)
     {
-        return block->last()->successor(index);
+        m_blocks[blockIndex].clear();
     }
-    BlockIndex successorForCondition(BasicBlock* block, bool condition)
+    
+    void killBlock(BasicBlock* basicBlock)
     {
-        return block->last()->successorForCondition(condition);
+        killBlock(basicBlock->index);
     }
     
     bool isPredictedNumerical(Node* node)
@@ -664,7 +669,7 @@
     
     NodeAllocator& m_allocator;
 
-    Vector< OwnPtr<BasicBlock> , 8> m_blocks;
+    Vector< RefPtr<BasicBlock> , 8> m_blocks;
     Vector<Edge, 16> m_varArgChildren;
     Vector<StorageAccessData> m_storageAccessData;
     Vector<Node*, 8> m_arguments;
@@ -688,7 +693,7 @@
     RefCountState m_refCountState;
 private:
     
-    void handleSuccessor(Vector<BlockIndex, 16>& worklist, BlockIndex blockIndex, BlockIndex successorIndex);
+    void handleSuccessor(Vector<BasicBlock*, 16>& worklist, BasicBlock*, BasicBlock* successor);
     
     AddSpeculationMode addImmediateShouldSpeculateInteger(Node* add, bool variableShouldSpeculateInteger, Node* immediate)
     {
@@ -737,27 +742,6 @@
     }
 };
 
-class GetBytecodeBeginForBlock {
-public:
-    GetBytecodeBeginForBlock(Graph& graph)
-        : m_graph(graph)
-    {
-    }
-    
-    unsigned operator()(BlockIndex* blockIndex) const
-    {
-        return m_graph.m_blocks[*blockIndex]->bytecodeBegin;
-    }
-
-private:
-    Graph& m_graph;
-};
-
-inline BlockIndex Graph::blockIndexForBytecodeOffset(Vector<BlockIndex>& linkingTargets, unsigned bytecodeBegin)
-{
-    return *binarySearch<BlockIndex, unsigned>(linkingTargets, linkingTargets.size(), bytecodeBegin, GetBytecodeBeginForBlock(*this));
-}
-
 #define DFG_NODE_DO_TO_CHILDREN(graph, node, thingToDo) do {            \
         Node* _node = (node);                                           \
         if (_node->flags() & NodeHasVarArgs) {                          \
diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
index 842361d..347ebcb 100644
--- a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
+++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
@@ -48,7 +48,7 @@
     : CCallHelpers(&dfg.m_vm, dfg.m_codeBlock)
     , m_graph(dfg)
     , m_jitCode(adoptRef(new JITCode()))
-    , m_blockHeads(dfg.m_blocks.size())
+    , m_blockHeads(dfg.numBlocks())
     , m_currentCodeOriginIndex(0)
 {
     if (shouldShowDisassembly() || m_graph.m_vm.m_perBytecodeProfiler)
@@ -170,13 +170,13 @@
         
         usedJumpTables.set(data.switchTableIndex);
         SimpleJumpTable& table = m_codeBlock->switchJumpTable(data.switchTableIndex);
-        table.ctiDefault = linkBuffer.locationOf(m_blockHeads[data.fallThrough]);
+        table.ctiDefault = linkBuffer.locationOf(m_blockHeads[data.fallThrough->index]);
         for (unsigned j = table.ctiOffsets.size(); j--;)
             table.ctiOffsets[j] = table.ctiDefault;
         for (unsigned j = data.cases.size(); j--;) {
             SwitchCase& myCase = data.cases[j];
             table.ctiOffsets[myCase.value.switchLookupValue() - table.min] =
-                linkBuffer.locationOf(m_blockHeads[myCase.target]);
+                linkBuffer.locationOf(m_blockHeads[myCase.target->index]);
         }
     }
     
@@ -199,7 +199,7 @@
             continue;
         
         StringJumpTable& table = m_codeBlock->stringSwitchJumpTable(data.switchTableIndex);
-        table.ctiDefault = linkBuffer.locationOf(m_blockHeads[data.fallThrough]);
+        table.ctiDefault = linkBuffer.locationOf(m_blockHeads[data.fallThrough->index]);
         StringJumpTable::StringOffsetTable::iterator iter;
         StringJumpTable::StringOffsetTable::iterator end = table.offsetTable.end();
         for (iter = table.offsetTable.begin(); iter != end; ++iter)
@@ -208,7 +208,7 @@
             SwitchCase& myCase = data.cases[j];
             iter = table.offsetTable.find(myCase.value.stringImpl());
             RELEASE_ASSERT(iter != end);
-            iter->value.ctiOffset = linkBuffer.locationOf(m_blockHeads[myCase.target]);
+            iter->value.ctiOffset = linkBuffer.locationOf(m_blockHeads[myCase.target->index]);
         }
     }
 
diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.h b/Source/JavaScriptCore/dfg/DFGJITCompiler.h
index cad1611..fee29bc 100644
--- a/Source/JavaScriptCore/dfg/DFGJITCompiler.h
+++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.h
@@ -296,11 +296,11 @@
         m_disassembler->setStartOfCode(labelIgnoringWatchpoints());
     }
     
-    void setForBlock(BlockIndex blockIndex)
+    void setForBlockIndex(BlockIndex blockIndex)
     {
         if (LIKELY(!m_disassembler))
             return;
-        m_disassembler->setForBlock(blockIndex, labelIgnoringWatchpoints());
+        m_disassembler->setForBlockIndex(blockIndex, labelIgnoringWatchpoints());
     }
     
     void setForNode(Node* node)
diff --git a/Source/JavaScriptCore/dfg/DFGNaturalLoops.cpp b/Source/JavaScriptCore/dfg/DFGNaturalLoops.cpp
index 92b74b6..34f8281 100644
--- a/Source/JavaScriptCore/dfg/DFGNaturalLoops.cpp
+++ b/Source/JavaScriptCore/dfg/DFGNaturalLoops.cpp
@@ -35,9 +35,9 @@
 
 void NaturalLoop::dump(PrintStream& out) const
 {
-    out.print("[Header: #", header(), ", Body:");
+    out.print("[Header: ", *header(), ", Body:");
     for (unsigned i = 0; i < m_body.size(); ++i)
-        out.print(" #", m_body[i]);
+        out.print(" ", *m_body[i]);
     out.print("]");
 }
 
@@ -60,26 +60,26 @@
     
     m_loops.resize(0);
     
-    for (BlockIndex blockIndex = graph.m_blocks.size(); blockIndex--;) {
-        BasicBlock* block = graph.m_blocks[blockIndex].get();
+    for (BlockIndex blockIndex = graph.numBlocks(); blockIndex--;) {
+        BasicBlock* block = graph.block(blockIndex);
         if (!block)
             continue;
         
-        for (unsigned i = graph.numSuccessors(block); i--;) {
-            BlockIndex successorIndex = graph.successor(block, i);
-            if (!graph.m_dominators.dominates(successorIndex, blockIndex))
+        for (unsigned i = block->numSuccessors(); i--;) {
+            BasicBlock* successor = block->successor(i);
+            if (!graph.m_dominators.dominates(successor, block))
                 continue;
             bool found = false;
             for (unsigned j = m_loops.size(); j--;) {
-                if (m_loops[i].header() == successorIndex) {
-                    m_loops[i].addBlock(blockIndex);
+                if (m_loops[i].header() == successor) {
+                    m_loops[i].addBlock(block);
                     found = true;
                 }
             }
             if (found)
                 continue;
-            NaturalLoop loop(successorIndex);
-            loop.addBlock(blockIndex);
+            NaturalLoop loop(successor);
+            loop.addBlock(block);
             m_loops.append(loop);
         }
     }
@@ -88,8 +88,8 @@
         dataLog("After bootstrap: ", *this, "\n");
     
     FastBitVector seenBlocks;
-    Vector<BlockIndex, 4> blockWorklist;
-    seenBlocks.resize(graph.m_blocks.size());
+    Vector<BasicBlock*, 4> blockWorklist;
+    seenBlocks.resize(graph.numBlocks());
     
     for (unsigned i = m_loops.size(); i--;) {
         NaturalLoop& loop = m_loops[i];
@@ -101,30 +101,27 @@
             dataLog("Dealing with loop ", loop, "\n");
         
         for (unsigned j = loop.size(); j--;) {
-            seenBlocks.set(loop[j]);
+            seenBlocks.set(loop[j]->index);
             blockWorklist.append(loop[j]);
         }
         
         while (!blockWorklist.isEmpty()) {
-            BlockIndex blockIndex = blockWorklist.takeLast();
+            BasicBlock* block = blockWorklist.takeLast();
             
             if (verbose)
-                dataLog("    Dealing with #", blockIndex, "\n");
+                dataLog("    Dealing with ", *block, "\n");
             
-            if (blockIndex == loop.header())
+            if (block == loop.header())
                 continue;
             
-            BasicBlock* block = graph.m_blocks[blockIndex].get();
-            ASSERT(block);
-            
-            for (unsigned j = block->m_predecessors.size(); j--;) {
-                BlockIndex predecessorIndex = block->m_predecessors[j];
-                if (seenBlocks.get(predecessorIndex))
+            for (unsigned j = block->predecessors.size(); j--;) {
+                BasicBlock* predecessor = block->predecessors[j];
+                if (seenBlocks.get(predecessor->index))
                     continue;
                 
-                loop.addBlock(predecessorIndex);
-                blockWorklist.append(predecessorIndex);
-                seenBlocks.set(predecessorIndex);
+                loop.addBlock(predecessor);
+                blockWorklist.append(predecessor);
+                seenBlocks.set(predecessor->index);
             }
         }
     }
@@ -133,12 +130,12 @@
         dataLog("Results: ", *this, "\n");
 }
 
-Vector<const NaturalLoop*> NaturalLoops::loopsOf(BlockIndex blockIndex) const
+Vector<const NaturalLoop*> NaturalLoops::loopsOf(BasicBlock* block) const
 {
     Vector<const NaturalLoop*> result;
     
     for (unsigned i = m_loops.size(); i--;) {
-        if (m_loops[i].contains(blockIndex))
+        if (m_loops[i].contains(block))
             result.append(&m_loops[i]);
     }
     
diff --git a/Source/JavaScriptCore/dfg/DFGNaturalLoops.h b/Source/JavaScriptCore/dfg/DFGNaturalLoops.h
index 43df4b5..4db0647 100644
--- a/Source/JavaScriptCore/dfg/DFGNaturalLoops.h
+++ b/Source/JavaScriptCore/dfg/DFGNaturalLoops.h
@@ -31,6 +31,7 @@
 #if ENABLE(DFG_JIT)
 
 #include "DFGAnalysis.h"
+#include "DFGBasicBlock.h"
 #include "DFGCommon.h"
 
 namespace JSC { namespace DFG {
@@ -38,24 +39,24 @@
 class NaturalLoop {
 public:
     NaturalLoop()
-        : m_header(NoBlock)
+        : m_header(0)
     {
     }
     
-    NaturalLoop(BlockIndex header)
+    NaturalLoop(BasicBlock* header)
         : m_header(header)
     {
     }
     
-    void addBlock(BlockIndex block) { m_body.append(block); }
+    void addBlock(BasicBlock* block) { m_body.append(block); }
     
-    BlockIndex header() const { return m_header; }
+    BasicBlock* header() const { return m_header; }
     
     unsigned size() const { return m_body.size(); }
-    BlockIndex at(unsigned i) const { return m_body[i]; }
-    BlockIndex operator[](unsigned i) const { return at(i); }
+    BasicBlock* at(unsigned i) const { return m_body[i]; }
+    BasicBlock* operator[](unsigned i) const { return at(i); }
     
-    bool contains(BlockIndex block) const
+    bool contains(BasicBlock* block) const
     {
         for (unsigned i = m_body.size(); i--;) {
             if (m_body[i] == block)
@@ -67,8 +68,8 @@
     
     void dump(PrintStream&) const;
 private:
-    BlockIndex m_header;
-    Vector<BlockIndex, 4> m_body;
+    BasicBlock* m_header;
+    Vector<BasicBlock*, 4> m_body;
 };
 
 class NaturalLoops : public Analysis<NaturalLoops> {
@@ -91,17 +92,17 @@
     
     // Return either null if the block isn't a loop header, or the
     // loop it belongs to.
-    const NaturalLoop* headerOf(BlockIndex blockIndex) const
+    const NaturalLoop* headerOf(BasicBlock* block) const
     {
         for (unsigned i = m_loops.size(); i--;) {
-            if (m_loops[i].header() == blockIndex)
+            if (m_loops[i].header() == block)
                 return &m_loops[i];
         }
         return 0;
     }
     
     // Return the indices of all loops this belongs to.
-    Vector<const NaturalLoop*> loopsOf(BlockIndex blockIndex) const;
+    Vector<const NaturalLoop*> loopsOf(BasicBlock*) const;
 
     void dump(PrintStream&) const;
 private:
diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h
index 086b3ae..12b7d76 100644
--- a/Source/JavaScriptCore/dfg/DFGNode.h
+++ b/Source/JavaScriptCore/dfg/DFGNode.h
@@ -48,6 +48,8 @@
 
 namespace JSC { namespace DFG {
 
+struct BasicBlock;
+
 struct StructureTransitionData {
     Structure* previousStructure;
     Structure* newStructure;
@@ -80,18 +82,28 @@
 // values.
 struct SwitchCase {
     SwitchCase()
-        : target(NoBlock)
+        : target(0)
     {
     }
     
-    SwitchCase(LazyJSValue value, BlockIndex target)
+    SwitchCase(LazyJSValue value, BasicBlock* target)
         : value(value)
         , target(target)
     {
     }
     
+    static SwitchCase withBytecodeIndex(LazyJSValue value, unsigned bytecodeIndex)
+    {
+        SwitchCase result;
+        result.value = value;
+        result.target = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(bytecodeIndex));
+        return result;
+    }
+    
+    unsigned targetBytecodeIndex() const { return bitwise_cast<uintptr_t>(target); }
+    
     LazyJSValue value;
-    BlockIndex target;
+    BasicBlock* target;
 };
 
 enum SwitchKind {
@@ -105,15 +117,21 @@
     // constructing this should make sure to initialize everything they
     // care about manually.
     SwitchData()
-        : fallThrough(NoBlock)
+        : fallThrough(0)
         , kind(static_cast<SwitchKind>(-1))
         , switchTableIndex(UINT_MAX)
         , didUseJumpTable(false)
     {
     }
     
+    void setFallThroughBytecodeIndex(unsigned bytecodeIndex)
+    {
+        fallThrough = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(bytecodeIndex));
+    }
+    unsigned fallThroughBytecodeIndex() const { return bitwise_cast<uintptr_t>(fallThrough); }
+    
     Vector<SwitchCase> cases;
-    BlockIndex fallThrough;
+    BasicBlock* fallThrough;
     SwitchKind kind;
     unsigned switchTableIndex;
     bool didUseJumpTable;
@@ -745,28 +763,28 @@
         return m_opInfo2;
     }
     
-    void setTakenBlockIndex(BlockIndex blockIndex)
+    void setTakenBlock(BasicBlock* block)
     {
         ASSERT(isBranch() || isJump());
-        m_opInfo = blockIndex;
+        m_opInfo = bitwise_cast<uintptr_t>(block);
     }
     
-    void setNotTakenBlockIndex(BlockIndex blockIndex)
+    void setNotTakenBlock(BasicBlock* block)
     {
         ASSERT(isBranch());
-        m_opInfo2 = blockIndex;
+        m_opInfo2 = bitwise_cast<uintptr_t>(block);
     }
     
-    BlockIndex takenBlockIndex()
+    BasicBlock* takenBlock()
     {
         ASSERT(isBranch() || isJump());
-        return m_opInfo;
+        return bitwise_cast<BasicBlock*>(m_opInfo);
     }
     
-    BlockIndex notTakenBlockIndex()
+    BasicBlock* notTakenBlock()
     {
         ASSERT(isBranch());
-        return m_opInfo2;
+        return bitwise_cast<BasicBlock*>(m_opInfo2);
     }
     
     SwitchData* switchData()
@@ -789,7 +807,7 @@
         }
     }
     
-    BlockIndex successor(unsigned index)
+    BasicBlock* successor(unsigned index)
     {
         if (isSwitch()) {
             if (index < switchData()->cases.size())
@@ -799,19 +817,19 @@
         }
         switch (index) {
         case 0:
-            return takenBlockIndex();
+            return takenBlock();
         case 1:
-            return notTakenBlockIndex();
+            return notTakenBlock();
         default:
             RELEASE_ASSERT_NOT_REACHED();
-            return NoBlock;
+            return 0;
         }
     }
     
-    BlockIndex successorForCondition(bool condition)
+    BasicBlock* successorForCondition(bool condition)
     {
         ASSERT(isBranch());
-        return condition ? takenBlockIndex() : notTakenBlockIndex();
+        return condition ? takenBlock() : notTakenBlock();
     }
     
     bool hasHeapPrediction()
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionInjectionPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionInjectionPhase.cpp
index 75db08b..91d2193 100644
--- a/Source/JavaScriptCore/dfg/DFGPredictionInjectionPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPredictionInjectionPhase.cpp
@@ -68,8 +68,8 @@
             }
         }
         
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             if (!block->isOSRTarget)
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
index dda403b..dcea307 100644
--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
@@ -572,8 +572,8 @@
 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
         dataLogF("Propagating predictions forward [%u]\n", ++m_count);
 #endif
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             ASSERT(block->isReachable);
@@ -589,8 +589,8 @@
 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
         dataLogF("Propagating predictions backward [%u]\n", ++m_count);
 #endif
-        for (BlockIndex blockIndex = m_graph.m_blocks.size(); blockIndex--;) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             ASSERT(block->isReachable);
@@ -714,8 +714,8 @@
 #endif
         for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i)
             m_graph.m_variableAccessData[i].find()->clearVotes();
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             ASSERT(block->isReachable);
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index 915201f..bdbd93a 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -224,7 +224,7 @@
 void SpeculativeJIT::convertLastOSRExitToForward(const ValueRecovery& valueRecovery)
 {
     m_jit.jitCode()->lastOSRExit().convertToForward(
-        m_jit.graph().m_blocks[m_block].get(), m_currentNode, m_indexInBlock, valueRecovery);
+        m_block, m_currentNode, m_indexInBlock, valueRecovery);
 }
 
 void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, MacroAssembler::Jump jumpToFail, const ValueRecovery& valueRecovery)
@@ -993,7 +993,7 @@
 {
     unsigned branchIndexInBlock = detectPeepHoleBranch();
     if (branchIndexInBlock != UINT_MAX) {
-        Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+        Node* branchNode = m_block->at(branchIndexInBlock);
 
         ASSERT(node->adjustedRefCount() == 1);
         
@@ -1014,7 +1014,7 @@
 {
     unsigned branchIndexInBlock = detectPeepHoleBranch();
     if (branchIndexInBlock != UINT_MAX) {
-        Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+        Node* branchNode = m_block->at(branchIndexInBlock);
 
         ASSERT(node->adjustedRefCount() == 1);
         
@@ -1379,8 +1379,8 @@
 
 void SpeculativeJIT::compilePeepHoleDoubleBranch(Node* node, Node* branchNode, JITCompiler::DoubleCondition condition)
 {
-    BlockIndex taken = branchNode->takenBlockIndex();
-    BlockIndex notTaken = branchNode->notTakenBlockIndex();
+    BasicBlock* taken = branchNode->takenBlock();
+    BasicBlock* notTaken = branchNode->notTakenBlock();
     
     SpeculateDoubleOperand op1(this, node->child1());
     SpeculateDoubleOperand op2(this, node->child2());
@@ -1391,14 +1391,14 @@
 
 void SpeculativeJIT::compilePeepHoleObjectEquality(Node* node, Node* branchNode)
 {
-    BlockIndex taken = branchNode->takenBlockIndex();
-    BlockIndex notTaken = branchNode->notTakenBlockIndex();
+    BasicBlock* taken = branchNode->takenBlock();
+    BasicBlock* notTaken = branchNode->notTakenBlock();
 
     MacroAssembler::RelationalCondition condition = MacroAssembler::Equal;
     
     if (taken == nextBlock()) {
         condition = MacroAssembler::NotEqual;
-        BlockIndex tmp = taken;
+        BasicBlock* tmp = taken;
         taken = notTaken;
         notTaken = tmp;
     }
@@ -1469,14 +1469,14 @@
 
 void SpeculativeJIT::compilePeepHoleBooleanBranch(Node* node, Node* branchNode, JITCompiler::RelationalCondition condition)
 {
-    BlockIndex taken = branchNode->takenBlockIndex();
-    BlockIndex notTaken = branchNode->notTakenBlockIndex();
+    BasicBlock* taken = branchNode->takenBlock();
+    BasicBlock* notTaken = branchNode->notTakenBlock();
 
     // The branch instruction will branch to the taken block.
     // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
     if (taken == nextBlock()) {
         condition = JITCompiler::invert(condition);
-        BlockIndex tmp = taken;
+        BasicBlock* tmp = taken;
         taken = notTaken;
         notTaken = tmp;
     }
@@ -1500,14 +1500,14 @@
 
 void SpeculativeJIT::compilePeepHoleIntegerBranch(Node* node, Node* branchNode, JITCompiler::RelationalCondition condition)
 {
-    BlockIndex taken = branchNode->takenBlockIndex();
-    BlockIndex notTaken = branchNode->notTakenBlockIndex();
+    BasicBlock* taken = branchNode->takenBlock();
+    BasicBlock* notTaken = branchNode->notTakenBlock();
 
     // The branch instruction will branch to the taken block.
     // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
     if (taken == nextBlock()) {
         condition = JITCompiler::invert(condition);
-        BlockIndex tmp = taken;
+        BasicBlock* tmp = taken;
         taken = notTaken;
         notTaken = tmp;
     }
@@ -1535,7 +1535,7 @@
     // Fused compare & branch.
     unsigned branchIndexInBlock = detectPeepHoleBranch();
     if (branchIndexInBlock != UINT_MAX) {
-        Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+        Node* branchNode = m_block->at(branchIndexInBlock);
 
         // detectPeepHoleBranch currently only permits the branch to be the very next node,
         // so can be no intervening nodes to also reference the compare. 
@@ -1657,14 +1657,16 @@
     clearGenerationInfo();
 }
 
-void SpeculativeJIT::compile(BasicBlock& block)
+void SpeculativeJIT::compileCurrentBlock()
 {
     ASSERT(m_compileOkay);
     
-    if (!block.isReachable)
+    if (!m_block)
         return;
     
-    if (!block.cfaHasVisited) {
+    ASSERT(m_block->isReachable);
+    
+    if (!m_block->cfaHasVisited) {
         // Don't generate code for basic blocks that are unreachable according to CFA.
         // But to be sure that nobody has generated a jump to this block, drop in a
         // breakpoint here.
@@ -1672,20 +1674,20 @@
         return;
     }
 
-    m_jit.blockHeads()[m_block] = m_jit.label();
+    m_jit.blockHeads()[m_block->index] = m_jit.label();
 #if DFG_ENABLE(JIT_BREAK_ON_EVERY_BLOCK)
     m_jit.breakpoint();
 #endif
     
 #if DFG_ENABLE(DEBUG_VERBOSE)
-    dataLogF("Setting up state for block #%u: ", m_block);
+    dataLog("Setting up state for block ", *m_block, ": ");
 #endif
     
     m_stream->appendAndLog(VariableEvent::reset());
     
     m_jit.jitAssertHasValidCallFrame();
 
-    ASSERT(m_arguments.size() == block.variablesAtHead.numberOfArguments());
+    ASSERT(m_arguments.size() == m_block->variablesAtHead.numberOfArguments());
     for (size_t i = 0; i < m_arguments.size(); ++i) {
         ValueSource valueSource = ValueSource(ValueInJSStack);
         m_arguments[i] = valueSource;
@@ -1693,11 +1695,11 @@
     }
     
     m_state.reset();
-    m_state.beginBasicBlock(&block);
+    m_state.beginBasicBlock(m_block);
     
-    ASSERT(m_variables.size() == block.variablesAtHead.numberOfLocals());
+    ASSERT(m_variables.size() == m_block->variablesAtHead.numberOfLocals());
     for (size_t i = 0; i < m_variables.size(); ++i) {
-        Node* node = block.variablesAtHead.local(i);
+        Node* node = m_block->variablesAtHead.local(i);
         ValueSource valueSource;
         if (!node)
             valueSource = ValueSource(SourceIsDead);
@@ -1723,8 +1725,8 @@
     dataLogF("\n");
 #endif
 
-    for (m_indexInBlock = 0; m_indexInBlock < block.size(); ++m_indexInBlock) {
-        m_currentNode = block[m_indexInBlock];
+    for (m_indexInBlock = 0; m_indexInBlock < m_block->size(); ++m_indexInBlock) {
+        m_currentNode = m_block->at(m_indexInBlock);
         
         // We may have his a contradiction that the CFA was aware of but that the JIT
         // didn't cause directly.
@@ -1904,11 +1906,10 @@
     checkArgumentTypes();
 
     ASSERT(!m_currentNode);
-    for (m_block = 0; m_block < m_jit.graph().m_blocks.size(); ++m_block) {
-        m_jit.setForBlock(m_block);
-        BasicBlock* block = m_jit.graph().m_blocks[m_block].get();
-        if (block)
-            compile(*block);
+    for (BlockIndex blockIndex = 0; blockIndex < m_jit.graph().numBlocks(); ++blockIndex) {
+        m_jit.setForBlockIndex(blockIndex);
+        m_block = m_jit.graph().block(blockIndex);
+        compileCurrentBlock();
     }
     linkBranches();
     return true;
@@ -1916,8 +1917,8 @@
 
 void SpeculativeJIT::createOSREntries()
 {
-    for (BlockIndex blockIndex = 0; blockIndex < m_jit.graph().m_blocks.size(); ++blockIndex) {
-        BasicBlock* block = m_jit.graph().m_blocks[blockIndex].get();
+    for (BlockIndex blockIndex = 0; blockIndex < m_jit.graph().numBlocks(); ++blockIndex) {
+        BasicBlock* block = m_jit.graph().block(blockIndex);
         if (!block)
             continue;
         if (!block->isOSRTarget)
@@ -1932,8 +1933,8 @@
 void SpeculativeJIT::linkOSREntries(LinkBuffer& linkBuffer)
 {
     unsigned osrEntryIndex = 0;
-    for (BlockIndex blockIndex = 0; blockIndex < m_jit.graph().m_blocks.size(); ++blockIndex) {
-        BasicBlock* block = m_jit.graph().m_blocks[blockIndex].get();
+    for (BlockIndex blockIndex = 0; blockIndex < m_jit.graph().numBlocks(); ++blockIndex) {
+        BasicBlock* block = m_jit.graph().block(blockIndex);
         if (!block)
             continue;
         if (!block->isOSRTarget)
@@ -3721,16 +3722,16 @@
     
     unsigned branchIndexInBlock = detectPeepHoleBranch();
     if (branchIndexInBlock != UINT_MAX) {
-        Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
-        BlockIndex taken = branchNode->takenBlockIndex();
-        BlockIndex notTaken = branchNode->notTakenBlockIndex();
+        Node* branchNode = m_block->at(branchIndexInBlock);
+        BasicBlock* taken = branchNode->takenBlock();
+        BasicBlock* notTaken = branchNode->notTakenBlock();
         MacroAssembler::RelationalCondition condition = MacroAssembler::Equal;
         
         // The branch instruction will branch to the taken block.
         // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
         if (taken == nextBlock()) {
             condition = MacroAssembler::NotEqual;
-            BlockIndex tmp = taken;
+            BasicBlock* tmp = taken;
             taken = notTaken;
             notTaken = tmp;
         }
@@ -3793,7 +3794,7 @@
     case BooleanUse: {
         unsigned branchIndexInBlock = detectPeepHoleBranch();
         if (branchIndexInBlock != UINT_MAX) {
-            Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+            Node* branchNode = m_block->at(branchIndexInBlock);
             compilePeepHoleBooleanBranch(node, branchNode, MacroAssembler::Equal);
             use(node->child1());
             use(node->child2());
@@ -3808,7 +3809,7 @@
     case Int32Use: {
         unsigned branchIndexInBlock = detectPeepHoleBranch();
         if (branchIndexInBlock != UINT_MAX) {
-            Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+            Node* branchNode = m_block->at(branchIndexInBlock);
             compilePeepHoleIntegerBranch(node, branchNode, MacroAssembler::Equal);
             use(node->child1());
             use(node->child2());
@@ -3823,7 +3824,7 @@
     case NumberUse: {
         unsigned branchIndexInBlock = detectPeepHoleBranch();
         if (branchIndexInBlock != UINT_MAX) {
-            Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+            Node* branchNode = m_block->at(branchIndexInBlock);
             compilePeepHoleDoubleBranch(node, branchNode, MacroAssembler::DoubleEqual);
             use(node->child1());
             use(node->child2());
@@ -3848,7 +3849,7 @@
     case ObjectUse: {
         unsigned branchIndexInBlock = detectPeepHoleBranch();
         if (branchIndexInBlock != UINT_MAX) {
-            Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+            Node* branchNode = m_block->at(branchIndexInBlock);
             compilePeepHoleObjectEquality(node, branchNode);
             use(node->child1());
             use(node->child2());
@@ -4220,16 +4221,16 @@
     unsigned branchIndexInBlock = detectPeepHoleBranch();
     if (branchIndexInBlock == UINT_MAX)
         return false;
-    Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+    Node* branchNode = m_block->at(branchIndexInBlock);
     ASSERT(node->adjustedRefCount() == 1);
 
-    BlockIndex taken = branchNode->takenBlockIndex();
-    BlockIndex notTaken = branchNode->notTakenBlockIndex();
+    BasicBlock* taken = branchNode->takenBlock();
+    BasicBlock* notTaken = branchNode->notTakenBlock();
     
     bool invert = false;
     if (taken == nextBlock()) {
         invert = true;
-        BlockIndex tmp = taken;
+        BasicBlock* tmp = taken;
         taken = notTaken;
         notTaken = tmp;
     }
@@ -5264,7 +5265,7 @@
     RELEASE_ASSERT_NOT_REACHED();
 }
 
-void SpeculativeJIT::addBranch(const MacroAssembler::JumpList& jump, BlockIndex destination)
+void SpeculativeJIT::addBranch(const MacroAssembler::JumpList& jump, BasicBlock* destination)
 {
     for (unsigned i = jump.jumps().size(); i--;)
         addBranch(jump.jumps()[i], destination);
@@ -5274,7 +5275,7 @@
 {
     for (size_t i = 0; i < m_branches.size(); ++i) {
         BranchRecord& branch = m_branches[i];
-        branch.jump.linkTo(m_jit.blockHeads()[branch.destination], &m_jit);
+        branch.jump.linkTo(m_jit.blockHeads()[branch.destination->index], &m_jit);
     }
 }
 
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
index ee510826..383f701 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
@@ -119,12 +119,12 @@
     void createOSREntries();
     void linkOSREntries(LinkBuffer&);
 
-    BlockIndex nextBlock()
+    BasicBlock* nextBlock()
     {
-        for (BlockIndex result = m_block + 1; ; result++) {
-            if (result >= m_jit.graph().m_blocks.size())
-                return NoBlock;
-            if (m_jit.graph().m_blocks[result])
+        for (BlockIndex resultIndex = m_block->index + 1; ; resultIndex++) {
+            if (resultIndex >= m_jit.graph().numBlocks())
+                return 0;
+            if (BasicBlock* result = m_jit.graph().block(resultIndex))
                 return result;
         }
     }
@@ -344,7 +344,7 @@
     void compile(Node*);
     void noticeOSRBirth(Node*);
     void bail();
-    void compile(BasicBlock&);
+    void compileCurrentBlock();
 
     void checkArgumentTypes();
 
@@ -704,18 +704,16 @@
     // Returns the index of the branch node if peephole is okay, UINT_MAX otherwise.
     unsigned detectPeepHoleBranch()
     {
-        BasicBlock* block = m_jit.graph().m_blocks[m_block].get();
-
         // Check that no intervening nodes will be generated.
-        for (unsigned index = m_indexInBlock + 1; index < block->size() - 1; ++index) {
-            Node* node = block->at(index);
+        for (unsigned index = m_indexInBlock + 1; index < m_block->size() - 1; ++index) {
+            Node* node = m_block->at(index);
             if (node->shouldGenerate())
                 return UINT_MAX;
         }
 
         // Check if the lastNode is a branch on this node.
-        Node* lastNode = block->last();
-        return lastNode->op() == Branch && lastNode->child1() == m_currentNode ? block->size() - 1 : UINT_MAX;
+        Node* lastNode = m_block->last();
+        return lastNode->op() == Branch && lastNode->child1() == m_currentNode ? m_block->size() - 1 : UINT_MAX;
     }
     
     void compileMovHint(Node*);
@@ -1754,74 +1752,74 @@
     }
 #endif
     
-    void branchDouble(JITCompiler::DoubleCondition cond, FPRReg left, FPRReg right, BlockIndex destination)
+    void branchDouble(JITCompiler::DoubleCondition cond, FPRReg left, FPRReg right, BasicBlock* destination)
     {
         return addBranch(m_jit.branchDouble(cond, left, right), destination);
     }
     
-    void branchDoubleNonZero(FPRReg value, FPRReg scratch, BlockIndex destination)
+    void branchDoubleNonZero(FPRReg value, FPRReg scratch, BasicBlock* destination)
     {
         return addBranch(m_jit.branchDoubleNonZero(value, scratch), destination);
     }
     
     template<typename T, typename U>
-    void branch32(JITCompiler::RelationalCondition cond, T left, U right, BlockIndex destination)
+    void branch32(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
     {
         return addBranch(m_jit.branch32(cond, left, right), destination);
     }
     
     template<typename T, typename U>
-    void branchTest32(JITCompiler::ResultCondition cond, T value, U mask, BlockIndex destination)
+    void branchTest32(JITCompiler::ResultCondition cond, T value, U mask, BasicBlock* destination)
     {
         return addBranch(m_jit.branchTest32(cond, value, mask), destination);
     }
     
     template<typename T>
-    void branchTest32(JITCompiler::ResultCondition cond, T value, BlockIndex destination)
+    void branchTest32(JITCompiler::ResultCondition cond, T value, BasicBlock* destination)
     {
         return addBranch(m_jit.branchTest32(cond, value), destination);
     }
     
 #if USE(JSVALUE64)
     template<typename T, typename U>
-    void branch64(JITCompiler::RelationalCondition cond, T left, U right, BlockIndex destination)
+    void branch64(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
     {
         return addBranch(m_jit.branch64(cond, left, right), destination);
     }
 #endif
     
     template<typename T, typename U>
-    void branch8(JITCompiler::RelationalCondition cond, T left, U right, BlockIndex destination)
+    void branch8(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
     {
         return addBranch(m_jit.branch8(cond, left, right), destination);
     }
     
     template<typename T, typename U>
-    void branchPtr(JITCompiler::RelationalCondition cond, T left, U right, BlockIndex destination)
+    void branchPtr(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
     {
         return addBranch(m_jit.branchPtr(cond, left, right), destination);
     }
     
     template<typename T, typename U>
-    void branchTestPtr(JITCompiler::ResultCondition cond, T value, U mask, BlockIndex destination)
+    void branchTestPtr(JITCompiler::ResultCondition cond, T value, U mask, BasicBlock* destination)
     {
         return addBranch(m_jit.branchTestPtr(cond, value, mask), destination);
     }
     
     template<typename T>
-    void branchTestPtr(JITCompiler::ResultCondition cond, T value, BlockIndex destination)
+    void branchTestPtr(JITCompiler::ResultCondition cond, T value, BasicBlock* destination)
     {
         return addBranch(m_jit.branchTestPtr(cond, value), destination);
     }
     
     template<typename T, typename U>
-    void branchTest8(JITCompiler::ResultCondition cond, T value, U mask, BlockIndex destination)
+    void branchTest8(JITCompiler::ResultCondition cond, T value, U mask, BasicBlock* destination)
     {
         return addBranch(m_jit.branchTest8(cond, value, mask), destination);
     }
     
     template<typename T>
-    void branchTest8(JITCompiler::ResultCondition cond, T value, BlockIndex destination)
+    void branchTest8(JITCompiler::ResultCondition cond, T value, BasicBlock* destination)
     {
         return addBranch(m_jit.branchTest8(cond, value), destination);
     }
@@ -1830,7 +1828,7 @@
         AtFallThroughPoint,
         ForceJump
     };
-    void jump(BlockIndex destination, FallThroughMode fallThroughMode = AtFallThroughPoint)
+    void jump(BasicBlock* destination, FallThroughMode fallThroughMode = AtFallThroughPoint)
     {
         if (destination == nextBlock()
             && fallThroughMode == AtFallThroughPoint)
@@ -1838,19 +1836,14 @@
         addBranch(m_jit.jump(), destination);
     }
     
-    void addBranch(const MacroAssembler::Jump& jump, BlockIndex destination)
+    void addBranch(const MacroAssembler::Jump& jump, BasicBlock* destination)
     {
         m_branches.append(BranchRecord(jump, destination));
     }
-    void addBranch(const MacroAssembler::JumpList& jump, BlockIndex destination);
+    void addBranch(const MacroAssembler::JumpList& jump, BasicBlock* destination);
 
     void linkBranches();
 
-    BasicBlock* block()
-    {
-        return m_jit.graph().m_blocks[m_block].get();
-    }
-
 #ifndef NDEBUG
     void dump(const char* label = 0);
 #endif
@@ -1889,13 +1882,13 @@
     void compileLogicalNot(Node*);
     void compileStringEquality(Node*);
     void compileStringIdentEquality(Node*);
-    void emitObjectOrOtherBranch(Edge value, BlockIndex taken, BlockIndex notTaken);
+    void emitObjectOrOtherBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken);
     void emitBranch(Node*);
     
     struct StringSwitchCase {
         StringSwitchCase() { }
         
-        StringSwitchCase(StringImpl* string, BlockIndex target)
+        StringSwitchCase(StringImpl* string, BasicBlock* target)
             : string(string)
             , target(target)
         {
@@ -1904,7 +1897,7 @@
         bool operator<(const StringSwitchCase& other) const;
         
         StringImpl* string;
-        BlockIndex target;
+        BasicBlock* target;
     };
     
     void emitSwitchIntJump(SwitchData*, GPRReg value, GPRReg scratch);
@@ -2172,7 +2165,7 @@
     JITCompiler& m_jit;
 
     // The current node being generated.
-    BlockIndex m_block;
+    BasicBlock* m_block;
     Node* m_currentNode;
     SpeculationDirection m_speculationDirection;
     bool m_canExit;
@@ -2185,14 +2178,14 @@
     Vector<MacroAssembler::Label> m_osrEntryHeads;
     
     struct BranchRecord {
-        BranchRecord(MacroAssembler::Jump jump, BlockIndex destination)
+        BranchRecord(MacroAssembler::Jump jump, BasicBlock* destination)
             : jump(jump)
             , destination(destination)
         {
         }
 
         MacroAssembler::Jump jump;
-        BlockIndex destination;
+        BasicBlock* destination;
     };
     Vector<BranchRecord, 8> m_branches;
 
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
index aa778bc..e1b7e0a 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
@@ -435,12 +435,12 @@
 
 void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, Node* branchNode, bool invert)
 {
-    BlockIndex taken = branchNode->takenBlockIndex();
-    BlockIndex notTaken = branchNode->notTakenBlockIndex();
+    BasicBlock* taken = branchNode->takenBlock();
+    BasicBlock* notTaken = branchNode->notTakenBlock();
     
     if (taken == nextBlock()) {
         invert = !invert;
-        BlockIndex tmp = taken;
+        BasicBlock* tmp = taken;
         taken = notTaken;
         notTaken = tmp;
     }
@@ -495,7 +495,7 @@
 {
     unsigned branchIndexInBlock = detectPeepHoleBranch();
     if (branchIndexInBlock != UINT_MAX) {
-        Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+        Node* branchNode = m_block->at(branchIndexInBlock);
 
         ASSERT(node->adjustedRefCount() == 1);
         
@@ -516,8 +516,8 @@
 
 void SpeculativeJIT::nonSpeculativePeepholeBranch(Node* node, Node* branchNode, MacroAssembler::RelationalCondition cond, S_DFGOperation_EJJ helperFunction)
 {
-    BlockIndex taken = branchNode->takenBlockIndex();
-    BlockIndex notTaken = branchNode->notTakenBlockIndex();
+    BasicBlock* taken = branchNode->takenBlock();
+    BasicBlock* notTaken = branchNode->notTakenBlock();
 
     JITCompiler::ResultCondition callResultCondition = JITCompiler::NonZero;
 
@@ -526,7 +526,7 @@
     if (taken == nextBlock()) {
         cond = JITCompiler::invert(cond);
         callResultCondition = JITCompiler::Zero;
-        BlockIndex tmp = taken;
+        BasicBlock* tmp = taken;
         taken = notTaken;
         notTaken = tmp;
     }
@@ -580,7 +580,7 @@
 
     jump(notTaken);
     
-    m_indexInBlock = m_jit.graph().m_blocks[m_block]->size() - 1;
+    m_indexInBlock = m_block->size() - 1;
     m_currentNode = branchNode;
 }
 
@@ -669,14 +669,14 @@
 
 void SpeculativeJIT::nonSpeculativePeepholeStrictEq(Node* node, Node* branchNode, bool invert)
 {
-    BlockIndex taken = branchNode->takenBlockIndex();
-    BlockIndex notTaken = branchNode->notTakenBlockIndex();
+    BasicBlock* taken = branchNode->takenBlock();
+    BasicBlock* notTaken = branchNode->notTakenBlock();
 
     // The branch instruction will branch to the taken block.
     // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
     if (taken == nextBlock()) {
         invert = !invert;
-        BlockIndex tmp = taken;
+        BasicBlock* tmp = taken;
         taken = notTaken;
         notTaken = tmp;
     }
@@ -1445,8 +1445,8 @@
 
 void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, Node* branchNode)
 {
-    BlockIndex taken = branchNode->takenBlockIndex();
-    BlockIndex notTaken = branchNode->notTakenBlockIndex();
+    BasicBlock* taken = branchNode->takenBlock();
+    BasicBlock* notTaken = branchNode->notTakenBlock();
     
     SpeculateCellOperand op1(this, leftChild);
     JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
@@ -1737,7 +1737,7 @@
     }
 }
 
-void SpeculativeJIT::emitObjectOrOtherBranch(Edge nodeUse, BlockIndex taken, BlockIndex notTaken)
+void SpeculativeJIT::emitObjectOrOtherBranch(Edge nodeUse, BasicBlock* taken, BasicBlock* notTaken)
 {
     JSValueOperand value(this, nodeUse, ManualOperandSpeculation);
     GPRTemporary scratch(this);
@@ -1794,8 +1794,8 @@
 
 void SpeculativeJIT::emitBranch(Node* node)
 {
-    BlockIndex taken = node->takenBlockIndex();
-    BlockIndex notTaken = node->notTakenBlockIndex();
+    BasicBlock* taken = node->takenBlock();
+    BasicBlock* notTaken = node->notTakenBlock();
 
     switch (node->child1().useKind()) {
     case BooleanUse: {
@@ -1804,7 +1804,7 @@
 
         if (taken == nextBlock()) {
             condition = MacroAssembler::Zero;
-            BlockIndex tmp = taken;
+            BasicBlock* tmp = taken;
             taken = notTaken;
             notTaken = tmp;
         }
@@ -1828,7 +1828,7 @@
             
             if (taken == nextBlock()) {
                 invert = true;
-                BlockIndex tmp = taken;
+                BasicBlock* tmp = taken;
                 taken = notTaken;
                 notTaken = tmp;
             }
@@ -3225,8 +3225,7 @@
     }
 
     case DFG::Jump: {
-        BlockIndex taken = node->takenBlockIndex();
-        jump(taken);
+        jump(node->takenBlock());
         noResult(node);
         break;
     }
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
index 7c9d4dc..ca2184f 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
@@ -384,12 +384,12 @@
 
 void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, Node* branchNode, bool invert)
 {
-    BlockIndex taken = branchNode->takenBlockIndex();
-    BlockIndex notTaken = branchNode->notTakenBlockIndex();
+    BasicBlock* taken = branchNode->takenBlock();
+    BasicBlock* notTaken = branchNode->notTakenBlock();
     
     if (taken == nextBlock()) {
         invert = !invert;
-        BlockIndex tmp = taken;
+        BasicBlock* tmp = taken;
         taken = notTaken;
         notTaken = tmp;
     }
@@ -443,7 +443,7 @@
 {
     unsigned branchIndexInBlock = detectPeepHoleBranch();
     if (branchIndexInBlock != UINT_MAX) {
-        Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+        Node* branchNode = m_block->at(branchIndexInBlock);
 
         RELEASE_ASSERT(node->adjustedRefCount() == 1);
         
@@ -464,8 +464,8 @@
 
 void SpeculativeJIT::nonSpeculativePeepholeBranch(Node* node, Node* branchNode, MacroAssembler::RelationalCondition cond, S_DFGOperation_EJJ helperFunction)
 {
-    BlockIndex taken = branchNode->takenBlockIndex();
-    BlockIndex notTaken = branchNode->notTakenBlockIndex();
+    BasicBlock* taken = branchNode->takenBlock();
+    BasicBlock* notTaken = branchNode->notTakenBlock();
 
     JITCompiler::ResultCondition callResultCondition = JITCompiler::NonZero;
 
@@ -474,7 +474,7 @@
     if (taken == nextBlock()) {
         cond = JITCompiler::invert(cond);
         callResultCondition = JITCompiler::Zero;
-        BlockIndex tmp = taken;
+        BasicBlock* tmp = taken;
         taken = notTaken;
         notTaken = tmp;
     }
@@ -526,7 +526,7 @@
 
     jump(notTaken);
 
-    m_indexInBlock = m_jit.graph().m_blocks[m_block]->size() - 1;
+    m_indexInBlock = m_block->size() - 1;
     m_currentNode = branchNode;
 }
 
@@ -607,14 +607,14 @@
 
 void SpeculativeJIT::nonSpeculativePeepholeStrictEq(Node* node, Node* branchNode, bool invert)
 {
-    BlockIndex taken = branchNode->takenBlockIndex();
-    BlockIndex notTaken = branchNode->notTakenBlockIndex();
+    BasicBlock* taken = branchNode->takenBlock();
+    BasicBlock* notTaken = branchNode->notTakenBlock();
 
     // The branch instruction will branch to the taken block.
     // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
     if (taken == nextBlock()) {
         invert = !invert;
-        BlockIndex tmp = taken;
+        BasicBlock* tmp = taken;
         taken = notTaken;
         notTaken = tmp;
     }
@@ -1466,8 +1466,8 @@
 
 void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, Node* branchNode)
 {
-    BlockIndex taken = branchNode->takenBlockIndex();
-    BlockIndex notTaken = branchNode->notTakenBlockIndex();
+    BasicBlock* taken = branchNode->takenBlock();
+    BasicBlock* notTaken = branchNode->notTakenBlock();
     
     SpeculateCellOperand op1(this, leftChild);
     JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
@@ -1764,7 +1764,7 @@
     }
 }
 
-void SpeculativeJIT::emitObjectOrOtherBranch(Edge nodeUse, BlockIndex taken, BlockIndex notTaken)
+void SpeculativeJIT::emitObjectOrOtherBranch(Edge nodeUse, BasicBlock* taken, BasicBlock* notTaken)
 {
     JSValueOperand value(this, nodeUse, ManualOperandSpeculation);
     GPRTemporary scratch(this);
@@ -1817,8 +1817,8 @@
 
 void SpeculativeJIT::emitBranch(Node* node)
 {
-    BlockIndex taken = node->takenBlockIndex();
-    BlockIndex notTaken = node->notTakenBlockIndex();
+    BasicBlock* taken = node->takenBlock();
+    BasicBlock* notTaken = node->notTakenBlock();
     
     switch (node->child1().useKind()) {
     case ObjectOrOtherUse: {
@@ -1833,7 +1833,7 @@
             
             if (taken == nextBlock()) {
                 invert = true;
-                BlockIndex tmp = taken;
+                BasicBlock* tmp = taken;
                 taken = notTaken;
                 notTaken = tmp;
             }
@@ -1863,7 +1863,7 @@
                 
                 if (taken == nextBlock()) {
                     condition = MacroAssembler::Zero;
-                    BlockIndex tmp = taken;
+                    BasicBlock* tmp = taken;
                     taken = notTaken;
                     notTaken = tmp;
                 }
@@ -3169,8 +3169,7 @@
     }
 
     case DFG::Jump: {
-        BlockIndex taken = node->takenBlockIndex();
-        jump(taken);
+        jump(node->takenBlock());
         noResult(node);
         break;
     }
diff --git a/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp b/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp
index 9508833..4baa73c 100644
--- a/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -104,8 +104,8 @@
 
         // Place CheckStructure's at SetLocal sites.
         InsertionSet insertionSet(m_graph);
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
@@ -217,8 +217,8 @@
     // checks. For now, only consider monomorphic structure checks (one structure).
     void identifyRedundantStructureChecks()
     {    
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
@@ -321,8 +321,8 @@
         
     void identifyRedundantArrayChecks()
     {
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
@@ -451,8 +451,8 @@
     template <typename TypeCheck>
     void disableHoistingAcrossOSREntries()
     {
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             ASSERT(block->isReachable);
diff --git a/Source/JavaScriptCore/dfg/DFGUnificationPhase.cpp b/Source/JavaScriptCore/dfg/DFGUnificationPhase.cpp
index 14963e1..8f2929d 100644
--- a/Source/JavaScriptCore/dfg/DFGUnificationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGUnificationPhase.cpp
@@ -48,8 +48,8 @@
         ASSERT(m_graph.m_unificationState == LocallyUnified);
         
         // Ensure that all Phi functions are unified.
-        for (BlockIndex blockIndex = m_graph.m_blocks.size(); blockIndex--;) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             ASSERT(block->isReachable);
diff --git a/Source/JavaScriptCore/dfg/DFGValidate.cpp b/Source/JavaScriptCore/dfg/DFGValidate.cpp
index 6720451..e4cf6ed 100644
--- a/Source/JavaScriptCore/dfg/DFGValidate.cpp
+++ b/Source/JavaScriptCore/dfg/DFGValidate.cpp
@@ -76,22 +76,22 @@
         // in release builds.
         
         // Validate that all local variables at the head of the root block are dead.
-        BasicBlock* root = m_graph.m_blocks[0].get();
+        BasicBlock* root = m_graph.block(0);
         for (unsigned i = 0; i < root->variablesAtHead.numberOfLocals(); ++i)
             V_EQUAL((static_cast<VirtualRegister>(i), 0), static_cast<Node*>(0), root->variablesAtHead.local(i));
         
         // Validate ref counts and uses.
         HashMap<Node*, unsigned> myRefCounts;
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block || !block->isReachable)
                 continue;
             for (size_t i = 0; i < block->numNodes(); ++i)
                 myRefCounts.add(block->node(i), 0);
         }
         HashSet<Node*> acceptableNodes;
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block || !block->isReachable)
                 continue;
             for (size_t i = 0; i < block->numNodes(); ++i) {
@@ -157,8 +157,8 @@
                 }
             }
         }
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block || !block->isReachable)
                 continue;
             
@@ -225,14 +225,14 @@
                     // There must exist a predecessor block that has this node index in
                     // its tail variables.
                     bool found = false;
-                    for (unsigned k = 0; k < block->m_predecessors.size(); ++k) {
-                        BasicBlock* prevBlock = m_graph.m_blocks[block->m_predecessors[k]].get();
-                        VALIDATE((Block, block->m_predecessors[k]), prevBlock);
-                        VALIDATE((Block, block->m_predecessors[k]), prevBlock->isReachable);
+                    for (unsigned k = 0; k < block->predecessors.size(); ++k) {
+                        BasicBlock* prevBlock = block->predecessors[k];
+                        VALIDATE((block->predecessors[k]), prevBlock);
+                        VALIDATE((block->predecessors[k]), prevBlock->isReachable);
                         Node* prevNode = prevBlock->variablesAtTail.operand(local);
                         // If we have a Phi that is not referring to *this* block then all predecessors
                         // must have that local available.
-                        VALIDATE((local, blockIndex, Block, block->m_predecessors[k]), prevNode);
+                        VALIDATE((local, block, block->predecessors[k]), prevNode);
                         switch (prevNode->op()) {
                         case GetLocal:
                         case Flush:
@@ -243,11 +243,11 @@
                             break;
                         }
                         if (node->shouldGenerate()) {
-                            VALIDATE((local, block->m_predecessors[k], prevNode),
+                            VALIDATE((local, block->predecessors[k], prevNode),
                                      prevNode->shouldGenerate());
                         }
                         VALIDATE(
-                            (local, block->m_predecessors[k], prevNode),
+                            (local, block->predecessors[k], prevNode),
                             prevNode->op() == SetLocal
                             || prevNode->op() == MovHint
                             || prevNode->op() == MovHintAndCheck
@@ -259,7 +259,7 @@
                             break;
                         }
                         // At this point it cannot refer into this block.
-                        VALIDATE((local, block->m_predecessors[k], prevNode), !prevBlock->isInBlock(edge.node()));
+                        VALIDATE((local, block->predecessors[k], prevNode), !prevBlock->isInBlock(edge.node()));
                     }
                     
                     VALIDATE((node, edge), found);
@@ -274,17 +274,17 @@
                 block->variablesAtHead.numberOfLocals());
             
             for (size_t i = 0; i < block->variablesAtHead.numberOfArguments(); ++i) {
-                VALIDATE((static_cast<VirtualRegister>(argumentToOperand(i)), blockIndex), !block->variablesAtHead.argument(i) || block->variablesAtHead.argument(i)->hasVariableAccessData());
+                VALIDATE((static_cast<VirtualRegister>(argumentToOperand(i)), block), !block->variablesAtHead.argument(i) || block->variablesAtHead.argument(i)->hasVariableAccessData());
                 if (m_graph.m_form == ThreadedCPS)
-                    VALIDATE((static_cast<VirtualRegister>(argumentToOperand(i)), blockIndex), !block->variablesAtTail.argument(i) || block->variablesAtTail.argument(i)->hasVariableAccessData());
+                    VALIDATE((static_cast<VirtualRegister>(argumentToOperand(i)), block), !block->variablesAtTail.argument(i) || block->variablesAtTail.argument(i)->hasVariableAccessData());
                 
                 getLocalPositions.argument(i) = notSet;
                 setLocalPositions.argument(i) = notSet;
             }
             for (size_t i = 0; i < block->variablesAtHead.numberOfLocals(); ++i) {
-                VALIDATE((static_cast<VirtualRegister>(i), blockIndex), !block->variablesAtHead.local(i) || block->variablesAtHead.local(i)->hasVariableAccessData());
+                VALIDATE((static_cast<VirtualRegister>(i), block), !block->variablesAtHead.local(i) || block->variablesAtHead.local(i)->hasVariableAccessData());
                 if (m_graph.m_form == ThreadedCPS)
-                    VALIDATE((static_cast<VirtualRegister>(i), blockIndex), !block->variablesAtTail.local(i) || block->variablesAtTail.local(i)->hasVariableAccessData());
+                    VALIDATE((static_cast<VirtualRegister>(i), block), !block->variablesAtTail.local(i) || block->variablesAtTail.local(i)->hasVariableAccessData());
 
                 getLocalPositions.local(i) = notSet;
                 setLocalPositions.local(i) = notSet;
@@ -324,7 +324,7 @@
                     if (!myRefCounts.get(node))
                         break;
                     if (m_graph.m_form == ThreadedCPS)
-                        VALIDATE((node, blockIndex), getLocalPositions.operand(node->local()) == notSet);
+                        VALIDATE((node, block), getLocalPositions.operand(node->local()) == notSet);
                     getLocalPositions.operand(node->local()) = i;
                     break;
                 case SetLocal:
@@ -346,11 +346,11 @@
             
             for (size_t i = 0; i < block->variablesAtHead.numberOfArguments(); ++i) {
                 checkOperand(
-                    blockIndex, getLocalPositions, setLocalPositions, argumentToOperand(i));
+                    block, getLocalPositions, setLocalPositions, argumentToOperand(i));
             }
             for (size_t i = 0; i < block->variablesAtHead.numberOfLocals(); ++i) {
                 checkOperand(
-                    blockIndex, getLocalPositions, setLocalPositions, i);
+                    block, getLocalPositions, setLocalPositions, i);
             }
         }
     }
@@ -360,7 +360,7 @@
     GraphDumpMode m_graphDumpMode;
     
     void checkOperand(
-        BlockIndex blockIndex, Operands<size_t>& getLocalPositions,
+        BasicBlock* block, Operands<size_t>& getLocalPositions,
         Operands<size_t>& setLocalPositions, int operand)
     {
         if (getLocalPositions.operand(operand) == notSet)
@@ -368,12 +368,10 @@
         if (setLocalPositions.operand(operand) == notSet)
             return;
         
-        BasicBlock* block = m_graph.m_blocks[blockIndex].get();
-        
         VALIDATE(
             (block->at(getLocalPositions.operand(operand)),
              block->at(setLocalPositions.operand(operand)),
-             blockIndex),
+             block),
             getLocalPositions.operand(operand) < setLocalPositions.operand(operand));
     }
     
@@ -382,10 +380,9 @@
         dataLogF("@%u", node->index());
     }
     
-    enum BlockTag { Block };
-    void reportValidationContext(BlockTag, BlockIndex blockIndex)
+    void reportValidationContext(BasicBlock* block)
     {
-        dataLogF("Block #%u", blockIndex);
+        dataLog("Block ", *block);
     }
     
     void reportValidationContext(Node* node, Edge edge)
@@ -393,39 +390,37 @@
         dataLog(node, " -> ", edge);
     }
     
-    void reportValidationContext(VirtualRegister local, BlockIndex blockIndex)
+    void reportValidationContext(VirtualRegister local, BasicBlock* block)
     {
-        dataLogF("r%d in Block #%u", local, blockIndex);
+        dataLog("r", static_cast<int>(local), " in Block ", *block);
     }
     
     void reportValidationContext(
-        VirtualRegister local, BlockIndex sourceBlockIndex, BlockTag, BlockIndex destinationBlockIndex)
+        VirtualRegister local, BasicBlock* sourceBlock, BasicBlock* destinationBlock)
     {
-        dataLogF("r%d in Block #%u -> #%u", local, sourceBlockIndex, destinationBlockIndex);
+        dataLog("r", static_cast<int>(local), " in Block ", *sourceBlock, " -> ", *destinationBlock);
     }
     
     void reportValidationContext(
-        VirtualRegister local, BlockIndex sourceBlockIndex, Node* prevNode)
+        VirtualRegister local, BasicBlock* sourceBlock, Node* prevNode)
     {
-        dataLogF("@%u for r%d in Block #%u", prevNode->index(), local, sourceBlockIndex);
+        dataLog(prevNode, " for r", static_cast<int>(local), " in Block ", *sourceBlock);
+    }
+    
+    void reportValidationContext(Node* node, BasicBlock* block)
+    {
+        dataLog(node, " in Block ", *block);
+    }
+    
+    void reportValidationContext(Node* node, Node* node2, BasicBlock* block)
+    {
+        dataLog(node, " and ", node2, " in Block ", *block);
     }
     
     void reportValidationContext(
-        Node* node, BlockIndex blockIndex)
+        Node* node, BasicBlock* block, Node* expectedNode, Edge incomingEdge)
     {
-        dataLogF("@%u in Block #%u", node->index(), blockIndex);
-    }
-    
-    void reportValidationContext(
-        Node* node, Node* node2, BlockIndex blockIndex)
-    {
-        dataLogF("@%u and @%u in Block #%u", node->index(), node2->index(), blockIndex);
-    }
-    
-    void reportValidationContext(
-        Node* node, BlockIndex blockIndex, Node* expectedNode, Edge incomingEdge)
-    {
-        dataLog(node, " in Block #", blockIndex, ", searching for ", expectedNode, " from ", incomingEdge);
+        dataLog(node, " in Block ", *block, ", searching for ", expectedNode, " from ", incomingEdge);
     }
     
     void dumpGraphIfAppropriate()
diff --git a/Source/JavaScriptCore/dfg/DFGVirtualRegisterAllocationPhase.cpp b/Source/JavaScriptCore/dfg/DFGVirtualRegisterAllocationPhase.cpp
index e390300..e91fbdb 100644
--- a/Source/JavaScriptCore/dfg/DFGVirtualRegisterAllocationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGVirtualRegisterAllocationPhase.cpp
@@ -53,8 +53,8 @@
 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
         bool needsNewLine = false;
 #endif
-        for (size_t blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+        for (size_t blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             if (!block->isReachable)
diff --git a/Source/JavaScriptCore/dfg/DFGWorklist.cpp b/Source/JavaScriptCore/dfg/DFGWorklist.cpp
index 0c95fd1..4436c0d 100644
--- a/Source/JavaScriptCore/dfg/DFGWorklist.cpp
+++ b/Source/JavaScriptCore/dfg/DFGWorklist.cpp
@@ -135,7 +135,8 @@
         if (!plan->isCompiled)
             continue;
         myReadyPlans.append(plan);
-        m_readyPlans[i--] = m_readyPlans.takeLast();
+        m_readyPlans[i--] = m_readyPlans.last();
+        m_readyPlans.removeLast();
         m_plans.remove(plan->key());
     }
 }
diff --git a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp b/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
index 89e50f5..2fa80c0 100644
--- a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
+++ b/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
@@ -174,8 +174,8 @@
 
 bool canCompile(Graph& graph)
 {
-    for (BlockIndex blockIndex = graph.m_blocks.size(); blockIndex--;) {
-        BasicBlock* block = graph.m_blocks[blockIndex].get();
+    for (BlockIndex blockIndex = graph.numBlocks(); blockIndex--;) {
+        BasicBlock* block = graph.block(blockIndex);
         if (!block)
             continue;
         
diff --git a/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp b/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
index 981b7fa..1bb53f4 100644
--- a/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
+++ b/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
@@ -61,11 +61,11 @@
         , m_ftlState(state)
         , m_heaps(state.context)
         , m_out(state.context)
-        , m_localsBoolean(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
-        , m_locals32(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
-        , m_locals64(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
-        , m_localsDouble(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
-        , m_valueSources(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
+        , m_localsBoolean(OperandsLike, state.graph.block(0)->variablesAtHead)
+        , m_locals32(OperandsLike, state.graph.block(0)->variablesAtHead)
+        , m_locals64(OperandsLike, state.graph.block(0)->variablesAtHead)
+        , m_localsDouble(OperandsLike, state.graph.block(0)->variablesAtHead)
+        , m_valueSources(OperandsLike, state.graph.block(0)->variablesAtHead)
         , m_lastSetOperand(std::numeric_limits<int>::max())
         , m_exitThunkGenerator(state)
         , m_state(state.graph)
@@ -99,23 +99,23 @@
         m_tagTypeNumber = m_out.constInt64(TagTypeNumber);
         m_tagMask = m_out.constInt64(TagMask);
         
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
-            m_highBlock = m_graph.m_blocks[blockIndex].get();
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            m_highBlock = m_graph.block(blockIndex);
             if (!m_highBlock)
                 continue;
-            m_blocks.add(m_highBlock, FTL_NEW_BLOCK(m_out, ("Block #", blockIndex)));
+            m_blocks.add(m_highBlock, FTL_NEW_BLOCK(m_out, ("Block ", *m_highBlock)));
             addFlushedLocalOpRoots();
         }
         
         closeOverFlushedLocalOps();
         
-        m_out.appendTo(m_argumentChecks, lowBlock(0));
+        m_out.appendTo(m_argumentChecks, lowBlock(m_graph.block(0)));
 
         transferAndCheckArguments();
         
-        m_out.jump(lowBlock(0));
+        m_out.jump(lowBlock(m_graph.block(0)));
         
-        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex)
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
             compileBlock(blockIndex);
         
         // And now complete the initialization block.
@@ -214,15 +214,15 @@
     
     void compileBlock(BlockIndex blockIndex)
     {
-        m_highBlock = m_graph.m_blocks[blockIndex].get();
+        m_highBlock = m_graph.block(blockIndex);
         if (!m_highBlock)
             return;
         
         LBasicBlock lowBlock = m_blocks.get(m_highBlock);
         
         m_nextHighBlock = 0;
-        for (BlockIndex nextBlockIndex = blockIndex + 1; nextBlockIndex < m_graph.m_blocks.size(); ++nextBlockIndex) {
-            m_nextHighBlock = m_graph.m_blocks[nextBlockIndex].get();
+        for (BlockIndex nextBlockIndex = blockIndex + 1; nextBlockIndex < m_graph.numBlocks(); ++nextBlockIndex) {
+            m_nextHighBlock = m_graph.block(nextBlockIndex);
             if (m_nextHighBlock)
                 break;
         }
@@ -1582,15 +1582,15 @@
     
     void compileJump()
     {
-        m_out.jump(lowBlock(m_node->takenBlockIndex()));
+        m_out.jump(lowBlock(m_node->takenBlock()));
     }
     
     void compileBranch()
     {
         m_out.branch(
             boolify(m_node->child1()),
-            lowBlock(m_node->takenBlockIndex()),
-            lowBlock(m_node->notTakenBlockIndex()));
+            lowBlock(m_node->takenBlock()),
+            lowBlock(m_node->notTakenBlock()));
     }
     
     void compileSwitch()
@@ -2454,9 +2454,9 @@
         use(edge);
     }
     
-    LBasicBlock lowBlock(BlockIndex blockIndex)
+    LBasicBlock lowBlock(BasicBlock* block)
     {
-        return m_blocks.get(m_graph.m_blocks[blockIndex].get());
+        return m_blocks.get(block);
     }
     
     void initializeOSRExitStateForBlock()