Heap variables shouldn't end up in the stack frame
https://bugs.webkit.org/show_bug.cgi?id=141174

Reviewed by Geoffrey Garen.
Source/JavaScriptCore:

        
This is a major change to how JavaScriptCore handles declared variables (i.e. "var"). It removes
any ambiguity about whether a variable should be in the heap or on the stack. A variable will no
longer move between heap and stack during its lifetime. This enables a bunch of optimizations and
simplifications:
        
- Accesses to variables no longer need checks or indirections to determine where the variable is
  at that moment in time. For example, loading a closure variable now takes just one load instead
  of two. Loading an argument by index now takes a bounds check and a load in the fastest case
  (when no arguments object allocation is required) while previously that same operation required
  a "did I allocate arguments yet" check, a bounds check, and then the load.
        
- Reasoning about the allocation of an activation or arguments object now follows the same simple
  logic as the allocation of any other kind of object. Previously, those objects were lazily
  allocated - so an allocation instruction wasn't the actual allocation site, since it might not
  allocate anything at all. This made the implementation of traditional escape analyses really
  awkward, and ultimately it meant that we missed important cases. Now, we can reason about the
  arguments object using the usual SSA tricks which allows for more comprehensive removal.
        
- The allocations of arguments objects, functions, and activations are now much faster. While
  this patch generally expands our ability to eliminate arguments object allocations, an earlier
  version of the patch - which lacked that functionality - was a progression on some arguments-
  and closure-happy benchmarks because although no allocations were eliminated, all allocations
  were faster.
        
- There is no tear-off. The runtime no loner needs to know about where on the stack a frame keeps
  its arguments objects or activations. The runtime doesn't have to do things to the arguments
  objects and activations that a frame allocated, when the frame is unwound. We always had horrid
  bugs in that code, so it's good to see it go. This removes *a ton* of machinery from the DFG,
  FTL, CodeBlock, and other places. All of the things having to do with "captured variables" is
  now gone. This also enables implementing block-scoping. Without this change, block-scope
  support would require telling CodeBlock and all of the rest of the runtime about all of the
  variables that store currently-live scopes. That would have been so disastrously hard that it
  might as well be impossible. With this change, it's fair game for the bytecode generator to
  simply allocate whatever activations it wants, wherever it wants, and to keep them live for
  however long it wants. This all works, because after bytecode generation, an activation is just
  an object and variables that refer to it are just normal variables.
        
- SymbolTable can now tell you explicitly where a variable lives. The answer is in the form of a
  VarOffset object, which has methods like isStack(), isScope(), etc. VirtualRegister is never
  used for offsets of non-stack variables anymore. We now have shiny new objects for other kinds
  of offsets - ScopeOffset for offsets into scopes, and DirectArgumentsOffset for offsets into
  an arguments object.
        
- Functions that create activations can now tier-up into the FTL. Previously they couldn't. Also,
  using activations used to prevent inlining; now functions that use activations can be inlined
  just fine.
        
This is a >1% speed-up on Octane. This is a >2% speed-up on CompressionBench. This is a tiny
speed-up on AsmBench (~0.4% or something). This looks like it might be a speed-up on SunSpider.
It's only a slow-down on very short-running microbenchmarks we had previously written for our old
style of tear-off-based arguments optimization. Those benchmarks are not part of any major suite.
        
The easiest way of understanding this change is to start by looking at the changes in runtime/,
and then the changes in bytecompiler/, and then sort of work your way up the compiler tiers.

* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* assembler/AbortReason.h:
* assembler/AbstractMacroAssembler.h:
(JSC::AbstractMacroAssembler::BaseIndex::withOffset):
* bytecode/ByValInfo.h:
(JSC::hasOptimizableIndexingForJSType):
(JSC::hasOptimizableIndexing):
(JSC::jitArrayModeForJSType):
(JSC::jitArrayModePermitsPut):
(JSC::jitArrayModeForStructure):
* bytecode/BytecodeKills.h: Added.
(JSC::BytecodeKills::BytecodeKills):
(JSC::BytecodeKills::operandIsKilled):
(JSC::BytecodeKills::forEachOperandKilledAt):
(JSC::BytecodeKills::KillSet::KillSet):
(JSC::BytecodeKills::KillSet::add):
(JSC::BytecodeKills::KillSet::forEachLocal):
(JSC::BytecodeKills::KillSet::contains):
* bytecode/BytecodeList.json:
* bytecode/BytecodeLivenessAnalysis.cpp:
(JSC::isValidRegisterForLiveness):
(JSC::stepOverInstruction):
(JSC::BytecodeLivenessAnalysis::runLivenessFixpoint):
(JSC::BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset):
(JSC::BytecodeLivenessAnalysis::operandIsLiveAtBytecodeOffset):
(JSC::BytecodeLivenessAnalysis::computeFullLiveness):
(JSC::BytecodeLivenessAnalysis::computeKills):
(JSC::indexForOperand): Deleted.
(JSC::BytecodeLivenessAnalysis::getLivenessInfoForNonCapturedVarsAtBytecodeOffset): Deleted.
(JSC::getLivenessInfo): Deleted.
* bytecode/BytecodeLivenessAnalysis.h:
* bytecode/BytecodeLivenessAnalysisInlines.h:
(JSC::operandIsAlwaysLive):
(JSC::operandThatIsNotAlwaysLiveIsLive):
(JSC::operandIsLive):
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::nameForRegister):
(JSC::CodeBlock::validate):
(JSC::CodeBlock::isCaptured): Deleted.
(JSC::CodeBlock::framePointerOffsetToGetActivationRegisters): Deleted.
(JSC::CodeBlock::machineSlowArguments): Deleted.
* bytecode/CodeBlock.h:
(JSC::unmodifiedArgumentsRegister): Deleted.
(JSC::CodeBlock::setArgumentsRegister): Deleted.
(JSC::CodeBlock::argumentsRegister): Deleted.
(JSC::CodeBlock::uncheckedArgumentsRegister): Deleted.
(JSC::CodeBlock::usesArguments): Deleted.
(JSC::CodeBlock::captureCount): Deleted.
(JSC::CodeBlock::captureStart): Deleted.
(JSC::CodeBlock::captureEnd): Deleted.
(JSC::CodeBlock::argumentIndexAfterCapture): Deleted.
(JSC::CodeBlock::hasSlowArguments): Deleted.
(JSC::ExecState::argumentAfterCapture): Deleted.
* bytecode/CodeOrigin.h:
* bytecode/DataFormat.h:
(JSC::dataFormatToString):
* bytecode/FullBytecodeLiveness.h:
(JSC::FullBytecodeLiveness::getLiveness):
(JSC::FullBytecodeLiveness::operandIsLive):
(JSC::FullBytecodeLiveness::FullBytecodeLiveness): Deleted.
(JSC::FullBytecodeLiveness::getOut): Deleted.
* bytecode/Instruction.h:
(JSC::Instruction::Instruction):
* bytecode/Operands.h:
(JSC::Operands::virtualRegisterForIndex):
* bytecode/SpeculatedType.cpp:
(JSC::dumpSpeculation):
(JSC::speculationToAbbreviatedString):
(JSC::speculationFromClassInfo):
* bytecode/SpeculatedType.h:
(JSC::isDirectArgumentsSpeculation):
(JSC::isScopedArgumentsSpeculation):
(JSC::isActionableMutableArraySpeculation):
(JSC::isActionableArraySpeculation):
(JSC::isArgumentsSpeculation): Deleted.
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedCodeBlock::setArgumentsRegister): Deleted.
(JSC::UnlinkedCodeBlock::usesArguments): Deleted.
(JSC::UnlinkedCodeBlock::argumentsRegister): Deleted.
* bytecode/ValueRecovery.cpp:
(JSC::ValueRecovery::dumpInContext):
* bytecode/ValueRecovery.h:
(JSC::ValueRecovery::directArgumentsThatWereNotCreated):
(JSC::ValueRecovery::outOfBandArgumentsThatWereNotCreated):
(JSC::ValueRecovery::nodeID):
(JSC::ValueRecovery::argumentsThatWereNotCreated): Deleted.
* bytecode/VirtualRegister.h:
(JSC::VirtualRegister::operator==):
(JSC::VirtualRegister::operator!=):
(JSC::VirtualRegister::operator<):
(JSC::VirtualRegister::operator>):
(JSC::VirtualRegister::operator<=):
(JSC::VirtualRegister::operator>=):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::generate):
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::initializeNextParameter):
(JSC::BytecodeGenerator::visibleNameForParameter):
(JSC::BytecodeGenerator::emitMove):
(JSC::BytecodeGenerator::variable):
(JSC::BytecodeGenerator::createVariable):
(JSC::BytecodeGenerator::emitResolveScope):
(JSC::BytecodeGenerator::emitGetFromScope):
(JSC::BytecodeGenerator::emitPutToScope):
(JSC::BytecodeGenerator::initializeVariable):
(JSC::BytecodeGenerator::emitInstanceOf):
(JSC::BytecodeGenerator::emitNewFunction):
(JSC::BytecodeGenerator::emitNewFunctionInternal):
(JSC::BytecodeGenerator::emitCall):
(JSC::BytecodeGenerator::emitReturn):
(JSC::BytecodeGenerator::emitConstruct):
(JSC::BytecodeGenerator::isArgumentNumber):
(JSC::BytecodeGenerator::emitEnumeration):
(JSC::BytecodeGenerator::addVar): Deleted.
(JSC::BytecodeGenerator::emitInitLazyRegister): Deleted.
(JSC::BytecodeGenerator::initializeCapturedVariable): Deleted.
(JSC::BytecodeGenerator::resolveCallee): Deleted.
(JSC::BytecodeGenerator::addCallee): Deleted.
(JSC::BytecodeGenerator::addParameter): Deleted.
(JSC::BytecodeGenerator::willResolveToArgumentsRegister): Deleted.
(JSC::BytecodeGenerator::uncheckedLocalArgumentsRegister): Deleted.
(JSC::BytecodeGenerator::createLazyRegisterIfNecessary): Deleted.
(JSC::BytecodeGenerator::isCaptured): Deleted.
(JSC::BytecodeGenerator::local): Deleted.
(JSC::BytecodeGenerator::constLocal): Deleted.
(JSC::BytecodeGenerator::emitResolveConstantLocal): Deleted.
(JSC::BytecodeGenerator::emitGetArgumentsLength): Deleted.
(JSC::BytecodeGenerator::emitGetArgumentByVal): Deleted.
(JSC::BytecodeGenerator::emitLazyNewFunction): Deleted.
(JSC::BytecodeGenerator::createArgumentsIfNecessary): Deleted.
* bytecompiler/BytecodeGenerator.h:
(JSC::Variable::Variable):
(JSC::Variable::isResolved):
(JSC::Variable::ident):
(JSC::Variable::offset):
(JSC::Variable::isLocal):
(JSC::Variable::local):
(JSC::Variable::isSpecial):
(JSC::BytecodeGenerator::argumentsRegister):
(JSC::BytecodeGenerator::emitNode):
(JSC::BytecodeGenerator::registerFor):
(JSC::Local::Local): Deleted.
(JSC::Local::operator bool): Deleted.
(JSC::Local::get): Deleted.
(JSC::Local::isSpecial): Deleted.
(JSC::ResolveScopeInfo::ResolveScopeInfo): Deleted.
(JSC::ResolveScopeInfo::isLocal): Deleted.
(JSC::ResolveScopeInfo::localIndex): Deleted.
(JSC::BytecodeGenerator::hasSafeLocalArgumentsRegister): Deleted.
(JSC::BytecodeGenerator::captureMode): Deleted.
(JSC::BytecodeGenerator::shouldTearOffArgumentsEagerly): Deleted.
(JSC::BytecodeGenerator::shouldCreateArgumentsEagerly): Deleted.
(JSC::BytecodeGenerator::hasWatchableVariable): Deleted.
(JSC::BytecodeGenerator::watchableVariableIdentifier): Deleted.
* bytecompiler/NodesCodegen.cpp:
(JSC::ResolveNode::isPure):
(JSC::ResolveNode::emitBytecode):
(JSC::BracketAccessorNode::emitBytecode):
(JSC::DotAccessorNode::emitBytecode):
(JSC::EvalFunctionCallNode::emitBytecode):
(JSC::FunctionCallResolveNode::emitBytecode):
(JSC::CallFunctionCallDotNode::emitBytecode):
(JSC::ApplyFunctionCallDotNode::emitBytecode):
(JSC::PostfixNode::emitResolve):
(JSC::DeleteResolveNode::emitBytecode):
(JSC::TypeOfResolveNode::emitBytecode):
(JSC::PrefixNode::emitResolve):
(JSC::ReadModifyResolveNode::emitBytecode):
(JSC::AssignResolveNode::emitBytecode):
(JSC::ConstDeclNode::emitCodeSingle):
(JSC::EmptyVarExpression::emitBytecode):
(JSC::ForInNode::tryGetBoundLocal):
(JSC::ForInNode::emitLoopHeader):
(JSC::ForOfNode::emitBytecode):
(JSC::ArrayPatternNode::emitDirectBinding):
(JSC::BindingNode::bindValue):
(JSC::getArgumentByVal): Deleted.
* dfg/DFGAbstractHeap.h:
* dfg/DFGAbstractInterpreter.h:
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
(JSC::DFG::AbstractInterpreter<AbstractStateType>::clobberWorld):
(JSC::DFG::AbstractInterpreter<AbstractStateType>::clobberCapturedVars): Deleted.
* dfg/DFGAbstractValue.h:
* dfg/DFGArgumentPosition.h:
(JSC::DFG::ArgumentPosition::addVariable):
* dfg/DFGArgumentsEliminationPhase.cpp: Added.
(JSC::DFG::performArgumentsElimination):
* dfg/DFGArgumentsEliminationPhase.h: Added.
* dfg/DFGArgumentsSimplificationPhase.cpp: Removed.
* dfg/DFGArgumentsSimplificationPhase.h: Removed.
* dfg/DFGArgumentsUtilities.cpp: Added.
(JSC::DFG::argumentsInvolveStackSlot):
(JSC::DFG::emitCodeToGetArgumentsArrayLength):
* dfg/DFGArgumentsUtilities.h: Added.
* dfg/DFGArrayMode.cpp:
(JSC::DFG::ArrayMode::refine):
(JSC::DFG::ArrayMode::alreadyChecked):
(JSC::DFG::arrayTypeToString):
* dfg/DFGArrayMode.h:
(JSC::DFG::ArrayMode::canCSEStorage):
(JSC::DFG::ArrayMode::modeForPut):
* dfg/DFGAvailabilityMap.cpp:
(JSC::DFG::AvailabilityMap::prune):
* dfg/DFGAvailabilityMap.h:
(JSC::DFG::AvailabilityMap::closeOverNodes):
(JSC::DFG::AvailabilityMap::closeStartingWithLocal):
* dfg/DFGBackwardsPropagationPhase.cpp:
(JSC::DFG::BackwardsPropagationPhase::propagate):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::newVariableAccessData):
(JSC::DFG::ByteCodeParser::getLocal):
(JSC::DFG::ByteCodeParser::setLocal):
(JSC::DFG::ByteCodeParser::getArgument):
(JSC::DFG::ByteCodeParser::setArgument):
(JSC::DFG::ByteCodeParser::flushDirect):
(JSC::DFG::ByteCodeParser::flush):
(JSC::DFG::ByteCodeParser::noticeArgumentsUse):
(JSC::DFG::ByteCodeParser::handleVarargsCall):
(JSC::DFG::ByteCodeParser::attemptToInlineCall):
(JSC::DFG::ByteCodeParser::handleInlining):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
(JSC::DFG::ByteCodeParser::parseCodeBlock):
* dfg/DFGCPSRethreadingPhase.cpp:
(JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
(JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock):
* dfg/DFGCSEPhase.cpp:
* dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h: Added.
(JSC::DFG::CallCreateDirectArgumentsSlowPathGenerator::CallCreateDirectArgumentsSlowPathGenerator):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::isSupportedForInlining):
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGCommon.h:
* dfg/DFGCommonData.h:
(JSC::DFG::CommonData::CommonData):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* dfg/DFGDCEPhase.cpp:
(JSC::DFG::DCEPhase::cleanVariables):
* dfg/DFGDisassembler.h:
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGFlushFormat.cpp:
(WTF::printInternal):
* dfg/DFGFlushFormat.h:
(JSC::DFG::resultFor):
(JSC::DFG::useKindFor):
(JSC::DFG::dataFormatFor):
* dfg/DFGForAllKills.h: Added.
(JSC::DFG::forAllLiveNodesAtTail):
(JSC::DFG::forAllDirectlyKilledOperands):
(JSC::DFG::forAllKilledOperands):
(JSC::DFG::forAllKilledNodesAtNodeIndex):
(JSC::DFG::forAllKillsInBlock):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::Graph):
(JSC::DFG::Graph::dump):
(JSC::DFG::Graph::substituteGetLocal):
(JSC::DFG::Graph::livenessFor):
(JSC::DFG::Graph::killsFor):
(JSC::DFG::Graph::tryGetConstantClosureVar):
(JSC::DFG::Graph::tryGetRegisters): Deleted.
* dfg/DFGGraph.h:
(JSC::DFG::Graph::symbolTableFor):
(JSC::DFG::Graph::uses):
(JSC::DFG::Graph::bytecodeRegisterForArgument): Deleted.
(JSC::DFG::Graph::capturedVarsFor): Deleted.
(JSC::DFG::Graph::usesArguments): Deleted.
(JSC::DFG::Graph::argumentsRegisterFor): Deleted.
(JSC::DFG::Graph::machineArgumentsRegisterFor): Deleted.
(JSC::DFG::Graph::uncheckedArgumentsRegisterFor): Deleted.
* dfg/DFGHeapLocation.cpp:
(WTF::printInternal):
* dfg/DFGHeapLocation.h:
* dfg/DFGInPlaceAbstractState.cpp:
(JSC::DFG::InPlaceAbstractState::initialize):
(JSC::DFG::InPlaceAbstractState::mergeStateAtTail):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
* dfg/DFGMayExit.cpp:
(JSC::DFG::mayExit):
* dfg/DFGMinifiedID.h:
* dfg/DFGMinifiedNode.cpp:
(JSC::DFG::MinifiedNode::fromNode):
* dfg/DFGMinifiedNode.h:
(JSC::DFG::belongsInMinifiedGraph):
(JSC::DFG::MinifiedNode::hasInlineCallFrame):
(JSC::DFG::MinifiedNode::inlineCallFrame):
* dfg/DFGNode.cpp:
(JSC::DFG::Node::convertToIdentityOn):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasConstant):
(JSC::DFG::Node::constant):
(JSC::DFG::Node::hasScopeOffset):
(JSC::DFG::Node::scopeOffset):
(JSC::DFG::Node::hasDirectArgumentsOffset):
(JSC::DFG::Node::capturedArgumentsOffset):
(JSC::DFG::Node::variablePointer):
(JSC::DFG::Node::hasCallVarargsData):
(JSC::DFG::Node::hasLoadVarargsData):
(JSC::DFG::Node::hasHeapPrediction):
(JSC::DFG::Node::hasCellOperand):
(JSC::DFG::Node::objectMaterializationData):
(JSC::DFG::Node::isPhantomAllocation):
(JSC::DFG::Node::willHaveCodeGenOrOSR):
(JSC::DFG::Node::shouldSpeculateDirectArguments):
(JSC::DFG::Node::shouldSpeculateScopedArguments):
(JSC::DFG::Node::isPhantomArguments): Deleted.
(JSC::DFG::Node::hasVarNumber): Deleted.
(JSC::DFG::Node::varNumber): Deleted.
(JSC::DFG::Node::registerPointer): Deleted.
(JSC::DFG::Node::shouldSpeculateArguments): Deleted.
* dfg/DFGNodeType.h:
* dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
(JSC::DFG::OSRAvailabilityAnalysisPhase::run):
(JSC::DFG::LocalOSRAvailabilityCalculator::executeNode):
* dfg/DFGOSRExitCompiler.cpp:
(JSC::DFG::OSRExitCompiler::emitRestoreArguments):
* dfg/DFGOSRExitCompiler.h:
(JSC::DFG::OSRExitCompiler::badIndex): Deleted.
(JSC::DFG::OSRExitCompiler::initializePoisoned): Deleted.
(JSC::DFG::OSRExitCompiler::poisonIndex): Deleted.
* dfg/DFGOSRExitCompiler32_64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGOSRExitCompiler64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGOSRExitCompilerCommon.cpp:
(JSC::DFG::reifyInlinedCallFrames):
(JSC::DFG::ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator): Deleted.
(JSC::DFG::ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator): Deleted.
(JSC::DFG::ArgumentsRecoveryGenerator::generateFor): Deleted.
* dfg/DFGOSRExitCompilerCommon.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):
* dfg/DFGPreciseLocalClobberize.h:
(JSC::DFG::PreciseLocalClobberizeAdaptor::read):
(JSC::DFG::PreciseLocalClobberizeAdaptor::write):
(JSC::DFG::PreciseLocalClobberizeAdaptor::def):
(JSC::DFG::PreciseLocalClobberizeAdaptor::readTop):
(JSC::DFG::preciseLocalClobberize):
(JSC::DFG::PreciseLocalClobberizeAdaptor::writeTop): Deleted.
(JSC::DFG::forEachLocalReadByUnwind): Deleted.
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::run):
(JSC::DFG::PredictionPropagationPhase::propagate):
(JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
(JSC::DFG::PredictionPropagationPhase::propagateThroughArgumentPositions):
* dfg/DFGPromoteHeapAccess.h:
(JSC::DFG::promoteHeapAccess):
* dfg/DFGPromotedHeapLocation.cpp:
(WTF::printInternal):
* dfg/DFGPromotedHeapLocation.h:
* dfg/DFGSSAConversionPhase.cpp:
(JSC::DFG::SSAConversionPhase::run):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::emitAllocateJSArray):
(JSC::DFG::SpeculativeJIT::emitGetLength):
(JSC::DFG::SpeculativeJIT::emitGetCallee):
(JSC::DFG::SpeculativeJIT::emitGetArgumentStart):
(JSC::DFG::SpeculativeJIT::checkArray):
(JSC::DFG::SpeculativeJIT::compileGetByValOnDirectArguments):
(JSC::DFG::SpeculativeJIT::compileGetByValOnScopedArguments):
(JSC::DFG::SpeculativeJIT::compileGetArrayLength):
(JSC::DFG::SpeculativeJIT::compileNewFunction):
(JSC::DFG::SpeculativeJIT::compileForwardVarargs):
(JSC::DFG::SpeculativeJIT::compileCreateActivation):
(JSC::DFG::SpeculativeJIT::compileCreateDirectArguments):
(JSC::DFG::SpeculativeJIT::compileGetFromArguments):
(JSC::DFG::SpeculativeJIT::compilePutToArguments):
(JSC::DFG::SpeculativeJIT::compileCreateScopedArguments):
(JSC::DFG::SpeculativeJIT::compileCreateClonedArguments):
(JSC::DFG::SpeculativeJIT::emitAllocateArguments): Deleted.
(JSC::DFG::SpeculativeJIT::compileGetByValOnArguments): Deleted.
(JSC::DFG::SpeculativeJIT::compileGetArgumentsLength): Deleted.
(JSC::DFG::SpeculativeJIT::compileNewFunctionNoCheck): Deleted.
(JSC::DFG::SpeculativeJIT::compileNewFunctionExpression): Deleted.
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
(JSC::DFG::SpeculativeJIT::emitAllocateJSObjectWithKnownSize):
(JSC::DFG::SpeculativeJIT::emitAllocateJSObject):
(JSC::DFG::SpeculativeJIT::framePointerOffsetToGetActivationRegisters): Deleted.
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::emitCall):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::emitCall):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStackLayoutPhase.cpp:
(JSC::DFG::StackLayoutPhase::run):
* dfg/DFGStrengthReductionPhase.cpp:
(JSC::DFG::StrengthReductionPhase::handleNode):
* dfg/DFGStructureRegistrationPhase.cpp:
(JSC::DFG::StructureRegistrationPhase::run):
* dfg/DFGUnificationPhase.cpp:
(JSC::DFG::UnificationPhase::run):
* dfg/DFGValidate.cpp:
(JSC::DFG::Validate::validateCPS):
* dfg/DFGValueSource.cpp:
(JSC::DFG::ValueSource::dump):
* dfg/DFGValueSource.h:
(JSC::DFG::dataFormatToValueSourceKind):
(JSC::DFG::valueSourceKindToDataFormat):
(JSC::DFG::ValueSource::ValueSource):
(JSC::DFG::ValueSource::forFlushFormat):
(JSC::DFG::ValueSource::valueRecovery):
* dfg/DFGVarargsForwardingPhase.cpp: Added.
(JSC::DFG::performVarargsForwarding):
* dfg/DFGVarargsForwardingPhase.h: Added.
* dfg/DFGVariableAccessData.cpp:
(JSC::DFG::VariableAccessData::VariableAccessData):
(JSC::DFG::VariableAccessData::flushFormat):
(JSC::DFG::VariableAccessData::mergeIsCaptured): Deleted.
* dfg/DFGVariableAccessData.h:
(JSC::DFG::VariableAccessData::shouldNeverUnbox):
(JSC::DFG::VariableAccessData::shouldUseDoubleFormat):
(JSC::DFG::VariableAccessData::isCaptured): Deleted.
(JSC::DFG::VariableAccessData::mergeIsArgumentsAlias): Deleted.
(JSC::DFG::VariableAccessData::isArgumentsAlias): Deleted.
* dfg/DFGVariableAccessDataDump.cpp:
(JSC::DFG::VariableAccessDataDump::dump):
* dfg/DFGVariableAccessDataDump.h:
* dfg/DFGVariableEventStream.cpp:
(JSC::DFG::VariableEventStream::tryToSetConstantRecovery):
* dfg/DFGVariableEventStream.h:
* ftl/FTLAbstractHeap.cpp:
(JSC::FTL::AbstractHeap::dump):
(JSC::FTL::AbstractField::dump):
(JSC::FTL::IndexedAbstractHeap::dump):
(JSC::FTL::NumberedAbstractHeap::dump):
(JSC::FTL::AbsoluteAbstractHeap::dump):
* ftl/FTLAbstractHeap.h:
* ftl/FTLAbstractHeapRepository.cpp:
* ftl/FTLAbstractHeapRepository.h:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLCompile.cpp:
(JSC::FTL::mmAllocateDataSection):
* ftl/FTLExitArgument.cpp:
(JSC::FTL::ExitArgument::dump):
* ftl/FTLExitPropertyValue.cpp:
(JSC::FTL::ExitPropertyValue::withLocalsOffset):
* ftl/FTLExitPropertyValue.h:
* ftl/FTLExitTimeObjectMaterialization.cpp:
(JSC::FTL::ExitTimeObjectMaterialization::ExitTimeObjectMaterialization):
(JSC::FTL::ExitTimeObjectMaterialization::accountForLocalsOffset):
* ftl/FTLExitTimeObjectMaterialization.h:
(JSC::FTL::ExitTimeObjectMaterialization::origin):
* ftl/FTLExitValue.cpp:
(JSC::FTL::ExitValue::withLocalsOffset):
(JSC::FTL::ExitValue::valueFormat):
(JSC::FTL::ExitValue::dumpInContext):
* ftl/FTLExitValue.h:
(JSC::FTL::ExitValue::isArgument):
(JSC::FTL::ExitValue::argumentsObjectThatWasNotCreated): Deleted.
(JSC::FTL::ExitValue::isArgumentsObjectThatWasNotCreated): Deleted.
(JSC::FTL::ExitValue::valueFormat): Deleted.
* ftl/FTLInlineCacheSize.cpp:
(JSC::FTL::sizeOfCallForwardVarargs):
(JSC::FTL::sizeOfConstructForwardVarargs):
(JSC::FTL::sizeOfICFor):
* ftl/FTLInlineCacheSize.h:
* ftl/FTLIntrinsicRepository.h:
* ftl/FTLJSCallVarargs.cpp:
(JSC::FTL::JSCallVarargs::JSCallVarargs):
(JSC::FTL::JSCallVarargs::emit):
* ftl/FTLJSCallVarargs.h:
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::lower):
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compilePutStack):
(JSC::FTL::LowerDFGToLLVM::compileGetArrayLength):
(JSC::FTL::LowerDFGToLLVM::compileGetByVal):
(JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
(JSC::FTL::LowerDFGToLLVM::compilePutByVal):
(JSC::FTL::LowerDFGToLLVM::compileArrayPush):
(JSC::FTL::LowerDFGToLLVM::compileArrayPop):
(JSC::FTL::LowerDFGToLLVM::compileCreateActivation):
(JSC::FTL::LowerDFGToLLVM::compileNewFunction):
(JSC::FTL::LowerDFGToLLVM::compileCreateDirectArguments):
(JSC::FTL::LowerDFGToLLVM::compileCreateScopedArguments):
(JSC::FTL::LowerDFGToLLVM::compileCreateClonedArguments):
(JSC::FTL::LowerDFGToLLVM::compileStringCharAt):
(JSC::FTL::LowerDFGToLLVM::compileStringCharCodeAt):
(JSC::FTL::LowerDFGToLLVM::compileGetGlobalVar):
(JSC::FTL::LowerDFGToLLVM::compilePutGlobalVar):
(JSC::FTL::LowerDFGToLLVM::compileGetArgumentCount):
(JSC::FTL::LowerDFGToLLVM::compileGetClosureVar):
(JSC::FTL::LowerDFGToLLVM::compilePutClosureVar):
(JSC::FTL::LowerDFGToLLVM::compileGetFromArguments):
(JSC::FTL::LowerDFGToLLVM::compilePutToArguments):
(JSC::FTL::LowerDFGToLLVM::compileCallOrConstructVarargs):
(JSC::FTL::LowerDFGToLLVM::compileForwardVarargs):
(JSC::FTL::LowerDFGToLLVM::compileGetEnumeratorPname):
(JSC::FTL::LowerDFGToLLVM::ArgumentsLength::ArgumentsLength):
(JSC::FTL::LowerDFGToLLVM::getArgumentsLength):
(JSC::FTL::LowerDFGToLLVM::getCurrentCallee):
(JSC::FTL::LowerDFGToLLVM::getArgumentsStart):
(JSC::FTL::LowerDFGToLLVM::baseIndex):
(JSC::FTL::LowerDFGToLLVM::allocateObject):
(JSC::FTL::LowerDFGToLLVM::allocateVariableSizedObject):
(JSC::FTL::LowerDFGToLLVM::isArrayType):
(JSC::FTL::LowerDFGToLLVM::emitStoreBarrier):
(JSC::FTL::LowerDFGToLLVM::buildExitArguments):
(JSC::FTL::LowerDFGToLLVM::exitValueForAvailability):
(JSC::FTL::LowerDFGToLLVM::exitValueForNode):
(JSC::FTL::LowerDFGToLLVM::loadStructure):
(JSC::FTL::LowerDFGToLLVM::compilePhantomArguments): Deleted.
(JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentsLength): Deleted.
(JSC::FTL::LowerDFGToLLVM::compileGetClosureRegisters): Deleted.
(JSC::FTL::LowerDFGToLLVM::compileCheckArgumentsNotCreated): Deleted.
(JSC::FTL::LowerDFGToLLVM::checkArgumentsNotCreated): Deleted.
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileRecovery):
(JSC::FTL::compileStub):
* ftl/FTLOperations.cpp:
(JSC::FTL::operationMaterializeObjectInOSR):
* ftl/FTLOutput.h:
(JSC::FTL::Output::aShr):
(JSC::FTL::Output::lShr):
(JSC::FTL::Output::zeroExtPtr):
* heap/CopyToken.h:
* interpreter/CallFrame.h:
(JSC::ExecState::getArgumentUnsafe):
* interpreter/Interpreter.cpp:
(JSC::sizeOfVarargs):
(JSC::sizeFrameForVarargs):
(JSC::loadVarargs):
(JSC::unwindCallFrame):
* interpreter/Interpreter.h:
* interpreter/StackVisitor.cpp:
(JSC::StackVisitor::Frame::createArguments):
(JSC::StackVisitor::Frame::existingArguments): Deleted.
* interpreter/StackVisitor.h:
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::storeValue):
(JSC::AssemblyHelpers::loadValue):
(JSC::AssemblyHelpers::storeTrustedValue):
(JSC::AssemblyHelpers::branchIfNotCell):
(JSC::AssemblyHelpers::branchIsEmpty):
(JSC::AssemblyHelpers::argumentsStart):
(JSC::AssemblyHelpers::baselineArgumentsRegisterFor): Deleted.
(JSC::AssemblyHelpers::offsetOfLocals): Deleted.
(JSC::AssemblyHelpers::offsetOfArguments): Deleted.
* jit/CCallHelpers.h:
(JSC::CCallHelpers::setupArgument):
* jit/GPRInfo.h:
(JSC::JSValueRegs::withTwoAvailableRegs):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* jit/JIT.h:
* jit/JITCall.cpp:
(JSC::JIT::compileSetupVarargsFrame):
* jit/JITCall32_64.cpp:
(JSC::JIT::compileSetupVarargsFrame):
* jit/JITInlines.h:
(JSC::JIT::callOperation):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_create_lexical_environment):
(JSC::JIT::emit_op_new_func):
(JSC::JIT::emit_op_create_direct_arguments):
(JSC::JIT::emit_op_create_scoped_arguments):
(JSC::JIT::emit_op_create_out_of_band_arguments):
(JSC::JIT::emit_op_tear_off_arguments): Deleted.
(JSC::JIT::emit_op_create_arguments): Deleted.
(JSC::JIT::emit_op_init_lazy_reg): Deleted.
(JSC::JIT::emit_op_get_arguments_length): Deleted.
(JSC::JIT::emitSlow_op_get_arguments_length): Deleted.
(JSC::JIT::emit_op_get_argument_by_val): Deleted.
(JSC::JIT::emitSlow_op_get_argument_by_val): Deleted.
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_create_lexical_environment):
(JSC::JIT::emit_op_tear_off_arguments): Deleted.
(JSC::JIT::emit_op_create_arguments): Deleted.
(JSC::JIT::emit_op_init_lazy_reg): Deleted.
(JSC::JIT::emit_op_get_arguments_length): Deleted.
(JSC::JIT::emitSlow_op_get_arguments_length): Deleted.
(JSC::JIT::emit_op_get_argument_by_val): Deleted.
(JSC::JIT::emitSlow_op_get_argument_by_val): Deleted.
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emitGetClosureVar):
(JSC::JIT::emitPutClosureVar):
(JSC::JIT::emit_op_get_from_arguments):
(JSC::JIT::emit_op_put_to_arguments):
(JSC::JIT::emit_op_init_global_const):
(JSC::JIT::privateCompileGetByVal):
(JSC::JIT::emitDirectArgumentsGetByVal):
(JSC::JIT::emitScopedArgumentsGetByVal):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emitGetClosureVar):
(JSC::JIT::emitPutClosureVar):
(JSC::JIT::emit_op_get_from_arguments):
(JSC::JIT::emit_op_put_to_arguments):
(JSC::JIT::emit_op_init_global_const):
* jit/SetupVarargsFrame.cpp:
(JSC::emitSetupVarargsFrameFastCase):
* llint/LLIntOffsetsExtractor.cpp:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* parser/Nodes.h:
(JSC::ScopeNode::captures):
* runtime/Arguments.cpp: Removed.
* runtime/Arguments.h: Removed.
* runtime/ArgumentsMode.h: Added.
* runtime/DirectArgumentsOffset.cpp: Added.
(JSC::DirectArgumentsOffset::dump):
* runtime/DirectArgumentsOffset.h: Added.
(JSC::DirectArgumentsOffset::DirectArgumentsOffset):
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
* runtime/ConstantMode.cpp: Added.
(WTF::printInternal):
* runtime/ConstantMode.h:
(JSC::modeForIsConstant):
* runtime/DirectArguments.cpp: Added.
(JSC::DirectArguments::DirectArguments):
(JSC::DirectArguments::createUninitialized):
(JSC::DirectArguments::create):
(JSC::DirectArguments::createByCopying):
(JSC::DirectArguments::visitChildren):
(JSC::DirectArguments::copyBackingStore):
(JSC::DirectArguments::createStructure):
(JSC::DirectArguments::overrideThings):
(JSC::DirectArguments::overrideThingsIfNecessary):
(JSC::DirectArguments::overrideArgument):
(JSC::DirectArguments::copyToArguments):
(JSC::DirectArguments::overridesSize):
* runtime/DirectArguments.h: Added.
(JSC::DirectArguments::internalLength):
(JSC::DirectArguments::length):
(JSC::DirectArguments::canAccessIndexQuickly):
(JSC::DirectArguments::getIndexQuickly):
(JSC::DirectArguments::setIndexQuickly):
(JSC::DirectArguments::callee):
(JSC::DirectArguments::argument):
(JSC::DirectArguments::overrodeThings):
(JSC::DirectArguments::offsetOfCallee):
(JSC::DirectArguments::offsetOfLength):
(JSC::DirectArguments::offsetOfMinCapacity):
(JSC::DirectArguments::offsetOfOverrides):
(JSC::DirectArguments::storageOffset):
(JSC::DirectArguments::offsetOfSlot):
(JSC::DirectArguments::allocationSize):
(JSC::DirectArguments::storage):
* runtime/FunctionPrototype.cpp:
* runtime/GenericArguments.h: Added.
(JSC::GenericArguments::GenericArguments):
* runtime/GenericArgumentsInlines.h: Added.
(JSC::GenericArguments<Type>::getOwnPropertySlot):
(JSC::GenericArguments<Type>::getOwnPropertySlotByIndex):
(JSC::GenericArguments<Type>::getOwnPropertyNames):
(JSC::GenericArguments<Type>::put):
(JSC::GenericArguments<Type>::putByIndex):
(JSC::GenericArguments<Type>::deleteProperty):
(JSC::GenericArguments<Type>::deletePropertyByIndex):
(JSC::GenericArguments<Type>::defineOwnProperty):
(JSC::GenericArguments<Type>::copyToArguments):
* runtime/GenericOffset.h: Added.
(JSC::GenericOffset::GenericOffset):
(JSC::GenericOffset::operator!):
(JSC::GenericOffset::offsetUnchecked):
(JSC::GenericOffset::offset):
(JSC::GenericOffset::operator==):
(JSC::GenericOffset::operator!=):
(JSC::GenericOffset::operator<):
(JSC::GenericOffset::operator>):
(JSC::GenericOffset::operator<=):
(JSC::GenericOffset::operator>=):
(JSC::GenericOffset::operator+):
(JSC::GenericOffset::operator-):
(JSC::GenericOffset::operator+=):
(JSC::GenericOffset::operator-=):
* runtime/JSArgumentsIterator.cpp:
(JSC::JSArgumentsIterator::finishCreation):
(JSC::argumentsFuncIterator):
* runtime/JSArgumentsIterator.h:
(JSC::JSArgumentsIterator::create):
(JSC::JSArgumentsIterator::next):
* runtime/JSEnvironmentRecord.cpp:
(JSC::JSEnvironmentRecord::visitChildren):
* runtime/JSEnvironmentRecord.h:
(JSC::JSEnvironmentRecord::variables):
(JSC::JSEnvironmentRecord::isValid):
(JSC::JSEnvironmentRecord::variableAt):
(JSC::JSEnvironmentRecord::offsetOfVariables):
(JSC::JSEnvironmentRecord::offsetOfVariable):
(JSC::JSEnvironmentRecord::allocationSizeForScopeSize):
(JSC::JSEnvironmentRecord::allocationSize):
(JSC::JSEnvironmentRecord::JSEnvironmentRecord):
(JSC::JSEnvironmentRecord::finishCreationUninitialized):
(JSC::JSEnvironmentRecord::finishCreation):
(JSC::JSEnvironmentRecord::registers): Deleted.
(JSC::JSEnvironmentRecord::registerAt): Deleted.
(JSC::JSEnvironmentRecord::addressOfRegisters): Deleted.
(JSC::JSEnvironmentRecord::offsetOfRegisters): Deleted.
* runtime/JSFunction.cpp:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::addGlobalVar):
(JSC::JSGlobalObject::addFunction):
(JSC::JSGlobalObject::visitChildren):
(JSC::JSGlobalObject::addStaticGlobals):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::directArgumentsStructure):
(JSC::JSGlobalObject::scopedArgumentsStructure):
(JSC::JSGlobalObject::outOfBandArgumentsStructure):
(JSC::JSGlobalObject::argumentsStructure): Deleted.
* runtime/JSLexicalEnvironment.cpp:
(JSC::JSLexicalEnvironment::symbolTableGet):
(JSC::JSLexicalEnvironment::symbolTablePut):
(JSC::JSLexicalEnvironment::getOwnNonIndexPropertyNames):
(JSC::JSLexicalEnvironment::symbolTablePutWithAttributes):
(JSC::JSLexicalEnvironment::visitChildren): Deleted.
* runtime/JSLexicalEnvironment.h:
(JSC::JSLexicalEnvironment::create):
(JSC::JSLexicalEnvironment::JSLexicalEnvironment):
(JSC::JSLexicalEnvironment::registersOffset): Deleted.
(JSC::JSLexicalEnvironment::storageOffset): Deleted.
(JSC::JSLexicalEnvironment::storage): Deleted.
(JSC::JSLexicalEnvironment::allocationSize): Deleted.
(JSC::JSLexicalEnvironment::isValidIndex): Deleted.
(JSC::JSLexicalEnvironment::isValid): Deleted.
(JSC::JSLexicalEnvironment::registerAt): Deleted.
* runtime/JSNameScope.cpp:
(JSC::JSNameScope::visitChildren): Deleted.
* runtime/JSNameScope.h:
(JSC::JSNameScope::create):
(JSC::JSNameScope::value):
(JSC::JSNameScope::finishCreation):
(JSC::JSNameScope::JSNameScope):
* runtime/JSScope.cpp:
(JSC::abstractAccess):
* runtime/JSSegmentedVariableObject.cpp:
(JSC::JSSegmentedVariableObject::findVariableIndex):
(JSC::JSSegmentedVariableObject::addVariables):
(JSC::JSSegmentedVariableObject::visitChildren):
(JSC::JSSegmentedVariableObject::findRegisterIndex): Deleted.
(JSC::JSSegmentedVariableObject::addRegisters): Deleted.
* runtime/JSSegmentedVariableObject.h:
(JSC::JSSegmentedVariableObject::variableAt):
(JSC::JSSegmentedVariableObject::assertVariableIsInThisObject):
(JSC::JSSegmentedVariableObject::registerAt): Deleted.
(JSC::JSSegmentedVariableObject::assertRegisterIsInThisObject): Deleted.
* runtime/JSSymbolTableObject.h:
(JSC::JSSymbolTableObject::offsetOfSymbolTable):
(JSC::symbolTableGet):
(JSC::symbolTablePut):
(JSC::symbolTablePutWithAttributes):
* runtime/JSType.h:
* runtime/Options.h:
* runtime/ClonedArguments.cpp: Added.
(JSC::ClonedArguments::ClonedArguments):
(JSC::ClonedArguments::createEmpty):
(JSC::ClonedArguments::createWithInlineFrame):
(JSC::ClonedArguments::createWithMachineFrame):
(JSC::ClonedArguments::createByCopyingFrom):
(JSC::ClonedArguments::createStructure):
(JSC::ClonedArguments::getOwnPropertySlot):
(JSC::ClonedArguments::getOwnPropertyNames):
(JSC::ClonedArguments::put):
(JSC::ClonedArguments::deleteProperty):
(JSC::ClonedArguments::defineOwnProperty):
(JSC::ClonedArguments::materializeSpecials):
(JSC::ClonedArguments::materializeSpecialsIfNecessary):
* runtime/ClonedArguments.h: Added.
(JSC::ClonedArguments::specialsMaterialized):
* runtime/ScopeOffset.cpp: Added.
(JSC::ScopeOffset::dump):
* runtime/ScopeOffset.h: Added.
(JSC::ScopeOffset::ScopeOffset):
* runtime/ScopedArguments.cpp: Added.
(JSC::ScopedArguments::ScopedArguments):
(JSC::ScopedArguments::finishCreation):
(JSC::ScopedArguments::createUninitialized):
(JSC::ScopedArguments::create):
(JSC::ScopedArguments::createByCopying):
(JSC::ScopedArguments::createByCopyingFrom):
(JSC::ScopedArguments::visitChildren):
(JSC::ScopedArguments::createStructure):
(JSC::ScopedArguments::overrideThings):
(JSC::ScopedArguments::overrideThingsIfNecessary):
(JSC::ScopedArguments::overrideArgument):
(JSC::ScopedArguments::copyToArguments):
* runtime/ScopedArguments.h: Added.
(JSC::ScopedArguments::internalLength):
(JSC::ScopedArguments::length):
(JSC::ScopedArguments::canAccessIndexQuickly):
(JSC::ScopedArguments::getIndexQuickly):
(JSC::ScopedArguments::setIndexQuickly):
(JSC::ScopedArguments::callee):
(JSC::ScopedArguments::overrodeThings):
(JSC::ScopedArguments::offsetOfOverrodeThings):
(JSC::ScopedArguments::offsetOfTotalLength):
(JSC::ScopedArguments::offsetOfTable):
(JSC::ScopedArguments::offsetOfScope):
(JSC::ScopedArguments::overflowStorageOffset):
(JSC::ScopedArguments::allocationSize):
(JSC::ScopedArguments::overflowStorage):
* runtime/ScopedArgumentsTable.cpp: Added.
(JSC::ScopedArgumentsTable::ScopedArgumentsTable):
(JSC::ScopedArgumentsTable::~ScopedArgumentsTable):
(JSC::ScopedArgumentsTable::destroy):
(JSC::ScopedArgumentsTable::create):
(JSC::ScopedArgumentsTable::clone):
(JSC::ScopedArgumentsTable::setLength):
(JSC::ScopedArgumentsTable::set):
(JSC::ScopedArgumentsTable::createStructure):
* runtime/ScopedArgumentsTable.h: Added.
(JSC::ScopedArgumentsTable::length):
(JSC::ScopedArgumentsTable::get):
(JSC::ScopedArgumentsTable::lock):
(JSC::ScopedArgumentsTable::offsetOfLength):
(JSC::ScopedArgumentsTable::offsetOfArguments):
(JSC::ScopedArgumentsTable::at):
* runtime/SymbolTable.cpp:
(JSC::SymbolTableEntry::prepareToWatch):
(JSC::SymbolTable::SymbolTable):
(JSC::SymbolTable::visitChildren):
(JSC::SymbolTable::localToEntry):
(JSC::SymbolTable::entryFor):
(JSC::SymbolTable::cloneScopePart):
(JSC::SymbolTable::prepareForTypeProfiling):
(JSC::SymbolTable::uniqueIDForOffset):
(JSC::SymbolTable::globalTypeSetForOffset):
(JSC::SymbolTable::cloneCapturedNames): Deleted.
(JSC::SymbolTable::uniqueIDForRegister): Deleted.
(JSC::SymbolTable::globalTypeSetForRegister): Deleted.
* runtime/SymbolTable.h:
(JSC::SymbolTableEntry::varOffsetFromBits):
(JSC::SymbolTableEntry::scopeOffsetFromBits):
(JSC::SymbolTableEntry::Fast::varOffset):
(JSC::SymbolTableEntry::Fast::scopeOffset):
(JSC::SymbolTableEntry::Fast::isDontEnum):
(JSC::SymbolTableEntry::Fast::getAttributes):
(JSC::SymbolTableEntry::SymbolTableEntry):
(JSC::SymbolTableEntry::varOffset):
(JSC::SymbolTableEntry::isWatchable):
(JSC::SymbolTableEntry::scopeOffset):
(JSC::SymbolTableEntry::setAttributes):
(JSC::SymbolTableEntry::constantMode):
(JSC::SymbolTableEntry::isDontEnum):
(JSC::SymbolTableEntry::disableWatching):
(JSC::SymbolTableEntry::pack):
(JSC::SymbolTableEntry::isValidVarOffset):
(JSC::SymbolTable::createNameScopeTable):
(JSC::SymbolTable::maxScopeOffset):
(JSC::SymbolTable::didUseScopeOffset):
(JSC::SymbolTable::didUseVarOffset):
(JSC::SymbolTable::scopeSize):
(JSC::SymbolTable::nextScopeOffset):
(JSC::SymbolTable::takeNextScopeOffset):
(JSC::SymbolTable::add):
(JSC::SymbolTable::set):
(JSC::SymbolTable::argumentsLength):
(JSC::SymbolTable::setArgumentsLength):
(JSC::SymbolTable::argumentOffset):
(JSC::SymbolTable::setArgumentOffset):
(JSC::SymbolTable::arguments):
(JSC::SlowArgument::SlowArgument): Deleted.
(JSC::SymbolTableEntry::Fast::getIndex): Deleted.
(JSC::SymbolTableEntry::getIndex): Deleted.
(JSC::SymbolTableEntry::isValidIndex): Deleted.
(JSC::SymbolTable::captureStart): Deleted.
(JSC::SymbolTable::setCaptureStart): Deleted.
(JSC::SymbolTable::captureEnd): Deleted.
(JSC::SymbolTable::setCaptureEnd): Deleted.
(JSC::SymbolTable::captureCount): Deleted.
(JSC::SymbolTable::isCaptured): Deleted.
(JSC::SymbolTable::parameterCount): Deleted.
(JSC::SymbolTable::parameterCountIncludingThis): Deleted.
(JSC::SymbolTable::setParameterCountIncludingThis): Deleted.
(JSC::SymbolTable::slowArguments): Deleted.
(JSC::SymbolTable::setSlowArguments): Deleted.
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
* runtime/VarOffset.cpp: Added.
(JSC::VarOffset::dump):
(WTF::printInternal):
* runtime/VarOffset.h: Added.
(JSC::VarOffset::VarOffset):
(JSC::VarOffset::assemble):
(JSC::VarOffset::isValid):
(JSC::VarOffset::operator!):
(JSC::VarOffset::kind):
(JSC::VarOffset::isStack):
(JSC::VarOffset::isScope):
(JSC::VarOffset::isDirectArgument):
(JSC::VarOffset::stackOffsetUnchecked):
(JSC::VarOffset::scopeOffsetUnchecked):
(JSC::VarOffset::capturedArgumentsOffsetUnchecked):
(JSC::VarOffset::stackOffset):
(JSC::VarOffset::scopeOffset):
(JSC::VarOffset::capturedArgumentsOffset):
(JSC::VarOffset::rawOffset):
(JSC::VarOffset::checkSanity):
(JSC::VarOffset::operator==):
(JSC::VarOffset::operator!=):
(JSC::VarOffset::hash):
(JSC::VarOffset::isHashTableDeletedValue):
(JSC::VarOffsetHash::hash):
(JSC::VarOffsetHash::equal):
* tests/stress/arguments-exit-strict-mode.js: Added.
* tests/stress/arguments-exit.js: Added.
* tests/stress/arguments-inlined-exit-strict-mode-fixed.js: Added.
* tests/stress/arguments-inlined-exit-strict-mode.js: Added.
* tests/stress/arguments-inlined-exit.js: Added.
* tests/stress/arguments-interference.js: Added.
* tests/stress/arguments-interference-cfg.js: Added.
* tests/stress/dead-get-closure-var.js: Added.
* tests/stress/get-declared-unpassed-argument-in-direct-arguments.js: Added.
* tests/stress/get-declared-unpassed-argument-in-scoped-arguments.js: Added.
* tests/stress/varargs-closure-inlined-exit-strict-mode.js: Added.
* tests/stress/varargs-closure-inlined-exit.js: Added.
* tests/stress/varargs-exit.js: Added.
* tests/stress/varargs-inlined-exit.js: Added.
* tests/stress/varargs-inlined-simple-exit-aliasing-weird-reversed-args.js: Added.
* tests/stress/varargs-inlined-simple-exit-aliasing-weird.js: Added.
* tests/stress/varargs-inlined-simple-exit-aliasing.js: Added.
* tests/stress/varargs-inlined-simple-exit.js: Added.
* tests/stress/varargs-too-few-arguments.js: Added.
* tests/stress/varargs-varargs-closure-inlined-exit.js: Added.
* tests/stress/varargs-varargs-inlined-exit-strict-mode.js: Added.
* tests/stress/varargs-varargs-inlined-exit.js: Added.

Source/WTF:


* wtf/FastBitVector.h:
(WTF::FastBitVector::resize): Small change: don't resize if you don't have to resize.

LayoutTests:


* js/function-apply-aliased-expected.txt:
* js/function-dot-arguments-expected.txt:
* js/regress/arguments-expected.txt: Added.
* js/regress/arguments-named-and-reflective-expected.txt: Added.
* js/regress/arguments-named-and-reflective.html: Added.
* js/regress/arguments-strict-mode-expected.txt: Added.
* js/regress/arguments-strict-mode.html: Added.
* js/regress/arguments.html: Added.
* js/regress/script-tests/arguments-named-and-reflective.js: Added.
* js/regress/script-tests/arguments-strict-mode.js: Added.
* js/regress/script-tests/arguments.js: Added.
* js/regress/script-tests/try-catch-get-by-val-cloned-arguments.js: Added.
* js/regress/script-tests/try-catch-get-by-val-direct-arguments.js: Added.
* js/regress/script-tests/try-catch-get-by-val-scoped-arguments.js: Added.
* js/regress/script-tests/varargs-call.js: Added.
* js/regress/script-tests/varargs-construct-inline.js: Added.
* js/regress/script-tests/varargs-construct.js: Added.
* js/regress/script-tests/varargs-inline.js: Added.
* js/regress/script-tests/varargs-strict-mode.js: Added.
* js/regress/script-tests/varargs.js: Added.
* js/regress/try-catch-get-by-val-cloned-arguments-expected.txt: Added.
* js/regress/try-catch-get-by-val-cloned-arguments.html: Added.
* js/regress/try-catch-get-by-val-direct-arguments-expected.txt: Added.
* js/regress/try-catch-get-by-val-direct-arguments.html: Added.
* js/regress/try-catch-get-by-val-scoped-arguments-expected.txt: Added.
* js/regress/try-catch-get-by-val-scoped-arguments.html: Added.
* js/regress/varargs-call-expected.txt: Added.
* js/regress/varargs-call.html: Added.
* js/regress/varargs-construct-expected.txt: Added.
* js/regress/varargs-construct-inline-expected.txt: Added.
* js/regress/varargs-construct-inline.html: Added.
* js/regress/varargs-construct.html: Added.
* js/regress/varargs-expected.txt: Added.
* js/regress/varargs-inline-expected.txt: Added.
* js/regress/varargs-inline.html: Added.
* js/regress/varargs-strict-mode-expected.txt: Added.
* js/regress/varargs-strict-mode.html: Added.
* js/regress/varargs.html: Added.
* js/script-tests/function-apply-aliased.js:
* js/script-tests/function-dot-arguments.js:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@181993 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
index 4a15039..7211276 100644
--- a/Source/JavaScriptCore/CMakeLists.txt
+++ b/Source/JavaScriptCore/CMakeLists.txt
@@ -118,8 +118,9 @@
 
     dfg/DFGAbstractHeap.cpp
     dfg/DFGAbstractValue.cpp
-    dfg/DFGArgumentsSimplificationPhase.cpp
     dfg/DFGArithMode.cpp
+    dfg/DFGArgumentsEliminationPhase.cpp
+    dfg/DFGArgumentsUtilities.cpp
     dfg/DFGArrayMode.cpp
     dfg/DFGAtTailAbstractState.cpp
     dfg/DFGAvailability.cpp
@@ -232,6 +233,7 @@
     dfg/DFGValidate.cpp
     dfg/DFGValueSource.cpp
     dfg/DFGValueStrength.cpp
+    dfg/DFGVarargsForwardingPhase.cpp
     dfg/DFGVariableAccessData.cpp
     dfg/DFGVariableAccessDataDump.cpp
     dfg/DFGVariableEvent.cpp
@@ -398,7 +400,6 @@
 
 set(JavaScriptCore_RUNTIME_SOURCES
     runtime/ArgList.cpp
-    runtime/Arguments.cpp
     runtime/ArgumentsIteratorConstructor.cpp
     runtime/ArgumentsIteratorPrototype.cpp
     runtime/ArrayBuffer.cpp
@@ -414,6 +415,7 @@
     runtime/BooleanPrototype.cpp
     runtime/BundlePath.cpp
     runtime/CallData.cpp
+    runtime/ClonedArguments.cpp
     runtime/CodeCache.cpp
     runtime/CodeSpecializationKind.cpp
     runtime/CommonIdentifiers.cpp
@@ -423,6 +425,7 @@
     runtime/Completion.cpp
     runtime/ConsoleClient.cpp
     runtime/ConsolePrototype.cpp
+    runtime/ConstantMode.cpp
     runtime/ConstructData.cpp
     runtime/ControlFlowProfiler.cpp
     runtime/CustomGetterSetter.cpp
@@ -431,6 +434,8 @@
     runtime/DateConversion.cpp
     runtime/DateInstance.cpp
     runtime/DatePrototype.cpp
+    runtime/DirectArguments.cpp
+    runtime/DirectArgumentsOffset.cpp
     runtime/DumpContext.cpp
     runtime/Error.cpp
     runtime/ErrorConstructor.cpp
@@ -538,6 +543,9 @@
     runtime/RegExpPrototype.cpp
     runtime/RuntimeType.cpp
     runtime/SamplingCounter.cpp
+    runtime/ScopeOffset.cpp
+    runtime/ScopedArguments.cpp
+    runtime/ScopedArgumentsTable.cpp
     runtime/SetConstructor.cpp
     runtime/SetIteratorConstructor.cpp
     runtime/SetIteratorPrototype.cpp
@@ -570,6 +578,7 @@
     runtime/TypedArrayType.cpp
     runtime/VM.cpp
     runtime/VMEntryScope.cpp
+    runtime/VarOffset.cpp
     runtime/Watchdog.cpp
     runtime/WatchdogNone.cpp
     runtime/WeakMapConstructor.cpp
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 3633321..57f6090 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,1014 @@
+2015-03-25  Filip Pizlo  <fpizlo@apple.com>
+
+        Heap variables shouldn't end up in the stack frame
+        https://bugs.webkit.org/show_bug.cgi?id=141174
+
+        Reviewed by Geoffrey Garen.
+        
+        This is a major change to how JavaScriptCore handles declared variables (i.e. "var"). It removes
+        any ambiguity about whether a variable should be in the heap or on the stack. A variable will no
+        longer move between heap and stack during its lifetime. This enables a bunch of optimizations and
+        simplifications:
+        
+        - Accesses to variables no longer need checks or indirections to determine where the variable is
+          at that moment in time. For example, loading a closure variable now takes just one load instead
+          of two. Loading an argument by index now takes a bounds check and a load in the fastest case
+          (when no arguments object allocation is required) while previously that same operation required
+          a "did I allocate arguments yet" check, a bounds check, and then the load.
+        
+        - Reasoning about the allocation of an activation or arguments object now follows the same simple
+          logic as the allocation of any other kind of object. Previously, those objects were lazily
+          allocated - so an allocation instruction wasn't the actual allocation site, since it might not
+          allocate anything at all. This made the implementation of traditional escape analyses really
+          awkward, and ultimately it meant that we missed important cases. Now, we can reason about the
+          arguments object using the usual SSA tricks which allows for more comprehensive removal.
+        
+        - The allocations of arguments objects, functions, and activations are now much faster. While
+          this patch generally expands our ability to eliminate arguments object allocations, an earlier
+          version of the patch - which lacked that functionality - was a progression on some arguments-
+          and closure-happy benchmarks because although no allocations were eliminated, all allocations
+          were faster.
+        
+        - There is no tear-off. The runtime no loner needs to know about where on the stack a frame keeps
+          its arguments objects or activations. The runtime doesn't have to do things to the arguments
+          objects and activations that a frame allocated, when the frame is unwound. We always had horrid
+          bugs in that code, so it's good to see it go. This removes *a ton* of machinery from the DFG,
+          FTL, CodeBlock, and other places. All of the things having to do with "captured variables" is
+          now gone. This also enables implementing block-scoping. Without this change, block-scope
+          support would require telling CodeBlock and all of the rest of the runtime about all of the
+          variables that store currently-live scopes. That would have been so disastrously hard that it
+          might as well be impossible. With this change, it's fair game for the bytecode generator to
+          simply allocate whatever activations it wants, wherever it wants, and to keep them live for
+          however long it wants. This all works, because after bytecode generation, an activation is just
+          an object and variables that refer to it are just normal variables.
+        
+        - SymbolTable can now tell you explicitly where a variable lives. The answer is in the form of a
+          VarOffset object, which has methods like isStack(), isScope(), etc. VirtualRegister is never
+          used for offsets of non-stack variables anymore. We now have shiny new objects for other kinds
+          of offsets - ScopeOffset for offsets into scopes, and DirectArgumentsOffset for offsets into
+          an arguments object.
+        
+        - Functions that create activations can now tier-up into the FTL. Previously they couldn't. Also,
+          using activations used to prevent inlining; now functions that use activations can be inlined
+          just fine.
+        
+        This is a >1% speed-up on Octane. This is a >2% speed-up on CompressionBench. This is a tiny
+        speed-up on AsmBench (~0.4% or something). This looks like it might be a speed-up on SunSpider.
+        It's only a slow-down on very short-running microbenchmarks we had previously written for our old
+        style of tear-off-based arguments optimization. Those benchmarks are not part of any major suite.
+        
+        The easiest way of understanding this change is to start by looking at the changes in runtime/,
+        and then the changes in bytecompiler/, and then sort of work your way up the compiler tiers.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * assembler/AbortReason.h:
+        * assembler/AbstractMacroAssembler.h:
+        (JSC::AbstractMacroAssembler::BaseIndex::withOffset):
+        * bytecode/ByValInfo.h:
+        (JSC::hasOptimizableIndexingForJSType):
+        (JSC::hasOptimizableIndexing):
+        (JSC::jitArrayModeForJSType):
+        (JSC::jitArrayModePermitsPut):
+        (JSC::jitArrayModeForStructure):
+        * bytecode/BytecodeKills.h: Added.
+        (JSC::BytecodeKills::BytecodeKills):
+        (JSC::BytecodeKills::operandIsKilled):
+        (JSC::BytecodeKills::forEachOperandKilledAt):
+        (JSC::BytecodeKills::KillSet::KillSet):
+        (JSC::BytecodeKills::KillSet::add):
+        (JSC::BytecodeKills::KillSet::forEachLocal):
+        (JSC::BytecodeKills::KillSet::contains):
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeLivenessAnalysis.cpp:
+        (JSC::isValidRegisterForLiveness):
+        (JSC::stepOverInstruction):
+        (JSC::BytecodeLivenessAnalysis::runLivenessFixpoint):
+        (JSC::BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset):
+        (JSC::BytecodeLivenessAnalysis::operandIsLiveAtBytecodeOffset):
+        (JSC::BytecodeLivenessAnalysis::computeFullLiveness):
+        (JSC::BytecodeLivenessAnalysis::computeKills):
+        (JSC::indexForOperand): Deleted.
+        (JSC::BytecodeLivenessAnalysis::getLivenessInfoForNonCapturedVarsAtBytecodeOffset): Deleted.
+        (JSC::getLivenessInfo): Deleted.
+        * bytecode/BytecodeLivenessAnalysis.h:
+        * bytecode/BytecodeLivenessAnalysisInlines.h:
+        (JSC::operandIsAlwaysLive):
+        (JSC::operandThatIsNotAlwaysLiveIsLive):
+        (JSC::operandIsLive):
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::nameForRegister):
+        (JSC::CodeBlock::validate):
+        (JSC::CodeBlock::isCaptured): Deleted.
+        (JSC::CodeBlock::framePointerOffsetToGetActivationRegisters): Deleted.
+        (JSC::CodeBlock::machineSlowArguments): Deleted.
+        * bytecode/CodeBlock.h:
+        (JSC::unmodifiedArgumentsRegister): Deleted.
+        (JSC::CodeBlock::setArgumentsRegister): Deleted.
+        (JSC::CodeBlock::argumentsRegister): Deleted.
+        (JSC::CodeBlock::uncheckedArgumentsRegister): Deleted.
+        (JSC::CodeBlock::usesArguments): Deleted.
+        (JSC::CodeBlock::captureCount): Deleted.
+        (JSC::CodeBlock::captureStart): Deleted.
+        (JSC::CodeBlock::captureEnd): Deleted.
+        (JSC::CodeBlock::argumentIndexAfterCapture): Deleted.
+        (JSC::CodeBlock::hasSlowArguments): Deleted.
+        (JSC::ExecState::argumentAfterCapture): Deleted.
+        * bytecode/CodeOrigin.h:
+        * bytecode/DataFormat.h:
+        (JSC::dataFormatToString):
+        * bytecode/FullBytecodeLiveness.h:
+        (JSC::FullBytecodeLiveness::getLiveness):
+        (JSC::FullBytecodeLiveness::operandIsLive):
+        (JSC::FullBytecodeLiveness::FullBytecodeLiveness): Deleted.
+        (JSC::FullBytecodeLiveness::getOut): Deleted.
+        * bytecode/Instruction.h:
+        (JSC::Instruction::Instruction):
+        * bytecode/Operands.h:
+        (JSC::Operands::virtualRegisterForIndex):
+        * bytecode/SpeculatedType.cpp:
+        (JSC::dumpSpeculation):
+        (JSC::speculationToAbbreviatedString):
+        (JSC::speculationFromClassInfo):
+        * bytecode/SpeculatedType.h:
+        (JSC::isDirectArgumentsSpeculation):
+        (JSC::isScopedArgumentsSpeculation):
+        (JSC::isActionableMutableArraySpeculation):
+        (JSC::isActionableArraySpeculation):
+        (JSC::isArgumentsSpeculation): Deleted.
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedCodeBlock::setArgumentsRegister): Deleted.
+        (JSC::UnlinkedCodeBlock::usesArguments): Deleted.
+        (JSC::UnlinkedCodeBlock::argumentsRegister): Deleted.
+        * bytecode/ValueRecovery.cpp:
+        (JSC::ValueRecovery::dumpInContext):
+        * bytecode/ValueRecovery.h:
+        (JSC::ValueRecovery::directArgumentsThatWereNotCreated):
+        (JSC::ValueRecovery::outOfBandArgumentsThatWereNotCreated):
+        (JSC::ValueRecovery::nodeID):
+        (JSC::ValueRecovery::argumentsThatWereNotCreated): Deleted.
+        * bytecode/VirtualRegister.h:
+        (JSC::VirtualRegister::operator==):
+        (JSC::VirtualRegister::operator!=):
+        (JSC::VirtualRegister::operator<):
+        (JSC::VirtualRegister::operator>):
+        (JSC::VirtualRegister::operator<=):
+        (JSC::VirtualRegister::operator>=):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::generate):
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::initializeNextParameter):
+        (JSC::BytecodeGenerator::visibleNameForParameter):
+        (JSC::BytecodeGenerator::emitMove):
+        (JSC::BytecodeGenerator::variable):
+        (JSC::BytecodeGenerator::createVariable):
+        (JSC::BytecodeGenerator::emitResolveScope):
+        (JSC::BytecodeGenerator::emitGetFromScope):
+        (JSC::BytecodeGenerator::emitPutToScope):
+        (JSC::BytecodeGenerator::initializeVariable):
+        (JSC::BytecodeGenerator::emitInstanceOf):
+        (JSC::BytecodeGenerator::emitNewFunction):
+        (JSC::BytecodeGenerator::emitNewFunctionInternal):
+        (JSC::BytecodeGenerator::emitCall):
+        (JSC::BytecodeGenerator::emitReturn):
+        (JSC::BytecodeGenerator::emitConstruct):
+        (JSC::BytecodeGenerator::isArgumentNumber):
+        (JSC::BytecodeGenerator::emitEnumeration):
+        (JSC::BytecodeGenerator::addVar): Deleted.
+        (JSC::BytecodeGenerator::emitInitLazyRegister): Deleted.
+        (JSC::BytecodeGenerator::initializeCapturedVariable): Deleted.
+        (JSC::BytecodeGenerator::resolveCallee): Deleted.
+        (JSC::BytecodeGenerator::addCallee): Deleted.
+        (JSC::BytecodeGenerator::addParameter): Deleted.
+        (JSC::BytecodeGenerator::willResolveToArgumentsRegister): Deleted.
+        (JSC::BytecodeGenerator::uncheckedLocalArgumentsRegister): Deleted.
+        (JSC::BytecodeGenerator::createLazyRegisterIfNecessary): Deleted.
+        (JSC::BytecodeGenerator::isCaptured): Deleted.
+        (JSC::BytecodeGenerator::local): Deleted.
+        (JSC::BytecodeGenerator::constLocal): Deleted.
+        (JSC::BytecodeGenerator::emitResolveConstantLocal): Deleted.
+        (JSC::BytecodeGenerator::emitGetArgumentsLength): Deleted.
+        (JSC::BytecodeGenerator::emitGetArgumentByVal): Deleted.
+        (JSC::BytecodeGenerator::emitLazyNewFunction): Deleted.
+        (JSC::BytecodeGenerator::createArgumentsIfNecessary): Deleted.
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::Variable::Variable):
+        (JSC::Variable::isResolved):
+        (JSC::Variable::ident):
+        (JSC::Variable::offset):
+        (JSC::Variable::isLocal):
+        (JSC::Variable::local):
+        (JSC::Variable::isSpecial):
+        (JSC::BytecodeGenerator::argumentsRegister):
+        (JSC::BytecodeGenerator::emitNode):
+        (JSC::BytecodeGenerator::registerFor):
+        (JSC::Local::Local): Deleted.
+        (JSC::Local::operator bool): Deleted.
+        (JSC::Local::get): Deleted.
+        (JSC::Local::isSpecial): Deleted.
+        (JSC::ResolveScopeInfo::ResolveScopeInfo): Deleted.
+        (JSC::ResolveScopeInfo::isLocal): Deleted.
+        (JSC::ResolveScopeInfo::localIndex): Deleted.
+        (JSC::BytecodeGenerator::hasSafeLocalArgumentsRegister): Deleted.
+        (JSC::BytecodeGenerator::captureMode): Deleted.
+        (JSC::BytecodeGenerator::shouldTearOffArgumentsEagerly): Deleted.
+        (JSC::BytecodeGenerator::shouldCreateArgumentsEagerly): Deleted.
+        (JSC::BytecodeGenerator::hasWatchableVariable): Deleted.
+        (JSC::BytecodeGenerator::watchableVariableIdentifier): Deleted.
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ResolveNode::isPure):
+        (JSC::ResolveNode::emitBytecode):
+        (JSC::BracketAccessorNode::emitBytecode):
+        (JSC::DotAccessorNode::emitBytecode):
+        (JSC::EvalFunctionCallNode::emitBytecode):
+        (JSC::FunctionCallResolveNode::emitBytecode):
+        (JSC::CallFunctionCallDotNode::emitBytecode):
+        (JSC::ApplyFunctionCallDotNode::emitBytecode):
+        (JSC::PostfixNode::emitResolve):
+        (JSC::DeleteResolveNode::emitBytecode):
+        (JSC::TypeOfResolveNode::emitBytecode):
+        (JSC::PrefixNode::emitResolve):
+        (JSC::ReadModifyResolveNode::emitBytecode):
+        (JSC::AssignResolveNode::emitBytecode):
+        (JSC::ConstDeclNode::emitCodeSingle):
+        (JSC::EmptyVarExpression::emitBytecode):
+        (JSC::ForInNode::tryGetBoundLocal):
+        (JSC::ForInNode::emitLoopHeader):
+        (JSC::ForOfNode::emitBytecode):
+        (JSC::ArrayPatternNode::emitDirectBinding):
+        (JSC::BindingNode::bindValue):
+        (JSC::getArgumentByVal): Deleted.
+        * dfg/DFGAbstractHeap.h:
+        * dfg/DFGAbstractInterpreter.h:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::clobberWorld):
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::clobberCapturedVars): Deleted.
+        * dfg/DFGAbstractValue.h:
+        * dfg/DFGArgumentPosition.h:
+        (JSC::DFG::ArgumentPosition::addVariable):
+        * dfg/DFGArgumentsEliminationPhase.cpp: Added.
+        (JSC::DFG::performArgumentsElimination):
+        * dfg/DFGArgumentsEliminationPhase.h: Added.
+        * dfg/DFGArgumentsSimplificationPhase.cpp: Removed.
+        * dfg/DFGArgumentsSimplificationPhase.h: Removed.
+        * dfg/DFGArgumentsUtilities.cpp: Added.
+        (JSC::DFG::argumentsInvolveStackSlot):
+        (JSC::DFG::emitCodeToGetArgumentsArrayLength):
+        * dfg/DFGArgumentsUtilities.h: Added.
+        * dfg/DFGArrayMode.cpp:
+        (JSC::DFG::ArrayMode::refine):
+        (JSC::DFG::ArrayMode::alreadyChecked):
+        (JSC::DFG::arrayTypeToString):
+        * dfg/DFGArrayMode.h:
+        (JSC::DFG::ArrayMode::canCSEStorage):
+        (JSC::DFG::ArrayMode::modeForPut):
+        * dfg/DFGAvailabilityMap.cpp:
+        (JSC::DFG::AvailabilityMap::prune):
+        * dfg/DFGAvailabilityMap.h:
+        (JSC::DFG::AvailabilityMap::closeOverNodes):
+        (JSC::DFG::AvailabilityMap::closeStartingWithLocal):
+        * dfg/DFGBackwardsPropagationPhase.cpp:
+        (JSC::DFG::BackwardsPropagationPhase::propagate):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::newVariableAccessData):
+        (JSC::DFG::ByteCodeParser::getLocal):
+        (JSC::DFG::ByteCodeParser::setLocal):
+        (JSC::DFG::ByteCodeParser::getArgument):
+        (JSC::DFG::ByteCodeParser::setArgument):
+        (JSC::DFG::ByteCodeParser::flushDirect):
+        (JSC::DFG::ByteCodeParser::flush):
+        (JSC::DFG::ByteCodeParser::noticeArgumentsUse):
+        (JSC::DFG::ByteCodeParser::handleVarargsCall):
+        (JSC::DFG::ByteCodeParser::attemptToInlineCall):
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+        (JSC::DFG::ByteCodeParser::parseCodeBlock):
+        * dfg/DFGCPSRethreadingPhase.cpp:
+        (JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
+        (JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock):
+        * dfg/DFGCSEPhase.cpp:
+        * dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h: Added.
+        (JSC::DFG::CallCreateDirectArgumentsSlowPathGenerator::CallCreateDirectArgumentsSlowPathGenerator):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::isSupportedForInlining):
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGCommon.h:
+        * dfg/DFGCommonData.h:
+        (JSC::DFG::CommonData::CommonData):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGDCEPhase.cpp:
+        (JSC::DFG::DCEPhase::cleanVariables):
+        * dfg/DFGDisassembler.h:
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGFlushFormat.cpp:
+        (WTF::printInternal):
+        * dfg/DFGFlushFormat.h:
+        (JSC::DFG::resultFor):
+        (JSC::DFG::useKindFor):
+        (JSC::DFG::dataFormatFor):
+        * dfg/DFGForAllKills.h: Added.
+        (JSC::DFG::forAllLiveNodesAtTail):
+        (JSC::DFG::forAllDirectlyKilledOperands):
+        (JSC::DFG::forAllKilledOperands):
+        (JSC::DFG::forAllKilledNodesAtNodeIndex):
+        (JSC::DFG::forAllKillsInBlock):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::Graph):
+        (JSC::DFG::Graph::dump):
+        (JSC::DFG::Graph::substituteGetLocal):
+        (JSC::DFG::Graph::livenessFor):
+        (JSC::DFG::Graph::killsFor):
+        (JSC::DFG::Graph::tryGetConstantClosureVar):
+        (JSC::DFG::Graph::tryGetRegisters): Deleted.
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::symbolTableFor):
+        (JSC::DFG::Graph::uses):
+        (JSC::DFG::Graph::bytecodeRegisterForArgument): Deleted.
+        (JSC::DFG::Graph::capturedVarsFor): Deleted.
+        (JSC::DFG::Graph::usesArguments): Deleted.
+        (JSC::DFG::Graph::argumentsRegisterFor): Deleted.
+        (JSC::DFG::Graph::machineArgumentsRegisterFor): Deleted.
+        (JSC::DFG::Graph::uncheckedArgumentsRegisterFor): Deleted.
+        * dfg/DFGHeapLocation.cpp:
+        (WTF::printInternal):
+        * dfg/DFGHeapLocation.h:
+        * dfg/DFGInPlaceAbstractState.cpp:
+        (JSC::DFG::InPlaceAbstractState::initialize):
+        (JSC::DFG::InPlaceAbstractState::mergeStateAtTail):
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::link):
+        * dfg/DFGMayExit.cpp:
+        (JSC::DFG::mayExit):
+        * dfg/DFGMinifiedID.h:
+        * dfg/DFGMinifiedNode.cpp:
+        (JSC::DFG::MinifiedNode::fromNode):
+        * dfg/DFGMinifiedNode.h:
+        (JSC::DFG::belongsInMinifiedGraph):
+        (JSC::DFG::MinifiedNode::hasInlineCallFrame):
+        (JSC::DFG::MinifiedNode::inlineCallFrame):
+        * dfg/DFGNode.cpp:
+        (JSC::DFG::Node::convertToIdentityOn):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasConstant):
+        (JSC::DFG::Node::constant):
+        (JSC::DFG::Node::hasScopeOffset):
+        (JSC::DFG::Node::scopeOffset):
+        (JSC::DFG::Node::hasDirectArgumentsOffset):
+        (JSC::DFG::Node::capturedArgumentsOffset):
+        (JSC::DFG::Node::variablePointer):
+        (JSC::DFG::Node::hasCallVarargsData):
+        (JSC::DFG::Node::hasLoadVarargsData):
+        (JSC::DFG::Node::hasHeapPrediction):
+        (JSC::DFG::Node::hasCellOperand):
+        (JSC::DFG::Node::objectMaterializationData):
+        (JSC::DFG::Node::isPhantomAllocation):
+        (JSC::DFG::Node::willHaveCodeGenOrOSR):
+        (JSC::DFG::Node::shouldSpeculateDirectArguments):
+        (JSC::DFG::Node::shouldSpeculateScopedArguments):
+        (JSC::DFG::Node::isPhantomArguments): Deleted.
+        (JSC::DFG::Node::hasVarNumber): Deleted.
+        (JSC::DFG::Node::varNumber): Deleted.
+        (JSC::DFG::Node::registerPointer): Deleted.
+        (JSC::DFG::Node::shouldSpeculateArguments): Deleted.
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
+        (JSC::DFG::OSRAvailabilityAnalysisPhase::run):
+        (JSC::DFG::LocalOSRAvailabilityCalculator::executeNode):
+        * dfg/DFGOSRExitCompiler.cpp:
+        (JSC::DFG::OSRExitCompiler::emitRestoreArguments):
+        * dfg/DFGOSRExitCompiler.h:
+        (JSC::DFG::OSRExitCompiler::badIndex): Deleted.
+        (JSC::DFG::OSRExitCompiler::initializePoisoned): Deleted.
+        (JSC::DFG::OSRExitCompiler::poisonIndex): Deleted.
+        * dfg/DFGOSRExitCompiler32_64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompiler64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::reifyInlinedCallFrames):
+        (JSC::DFG::ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator): Deleted.
+        (JSC::DFG::ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator): Deleted.
+        (JSC::DFG::ArgumentsRecoveryGenerator::generateFor): Deleted.
+        * dfg/DFGOSRExitCompilerCommon.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGPreciseLocalClobberize.h:
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::read):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::write):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::def):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::readTop):
+        (JSC::DFG::preciseLocalClobberize):
+        (JSC::DFG::PreciseLocalClobberizeAdaptor::writeTop): Deleted.
+        (JSC::DFG::forEachLocalReadByUnwind): Deleted.
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::run):
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
+        (JSC::DFG::PredictionPropagationPhase::propagateThroughArgumentPositions):
+        * dfg/DFGPromoteHeapAccess.h:
+        (JSC::DFG::promoteHeapAccess):
+        * dfg/DFGPromotedHeapLocation.cpp:
+        (WTF::printInternal):
+        * dfg/DFGPromotedHeapLocation.h:
+        * dfg/DFGSSAConversionPhase.cpp:
+        (JSC::DFG::SSAConversionPhase::run):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitAllocateJSArray):
+        (JSC::DFG::SpeculativeJIT::emitGetLength):
+        (JSC::DFG::SpeculativeJIT::emitGetCallee):
+        (JSC::DFG::SpeculativeJIT::emitGetArgumentStart):
+        (JSC::DFG::SpeculativeJIT::checkArray):
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnDirectArguments):
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnScopedArguments):
+        (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
+        (JSC::DFG::SpeculativeJIT::compileNewFunction):
+        (JSC::DFG::SpeculativeJIT::compileForwardVarargs):
+        (JSC::DFG::SpeculativeJIT::compileCreateActivation):
+        (JSC::DFG::SpeculativeJIT::compileCreateDirectArguments):
+        (JSC::DFG::SpeculativeJIT::compileGetFromArguments):
+        (JSC::DFG::SpeculativeJIT::compilePutToArguments):
+        (JSC::DFG::SpeculativeJIT::compileCreateScopedArguments):
+        (JSC::DFG::SpeculativeJIT::compileCreateClonedArguments):
+        (JSC::DFG::SpeculativeJIT::emitAllocateArguments): Deleted.
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments): Deleted.
+        (JSC::DFG::SpeculativeJIT::compileGetArgumentsLength): Deleted.
+        (JSC::DFG::SpeculativeJIT::compileNewFunctionNoCheck): Deleted.
+        (JSC::DFG::SpeculativeJIT::compileNewFunctionExpression): Deleted.
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        (JSC::DFG::SpeculativeJIT::emitAllocateJSObjectWithKnownSize):
+        (JSC::DFG::SpeculativeJIT::emitAllocateJSObject):
+        (JSC::DFG::SpeculativeJIT::framePointerOffsetToGetActivationRegisters): Deleted.
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStackLayoutPhase.cpp:
+        (JSC::DFG::StackLayoutPhase::run):
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+        * dfg/DFGStructureRegistrationPhase.cpp:
+        (JSC::DFG::StructureRegistrationPhase::run):
+        * dfg/DFGUnificationPhase.cpp:
+        (JSC::DFG::UnificationPhase::run):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validateCPS):
+        * dfg/DFGValueSource.cpp:
+        (JSC::DFG::ValueSource::dump):
+        * dfg/DFGValueSource.h:
+        (JSC::DFG::dataFormatToValueSourceKind):
+        (JSC::DFG::valueSourceKindToDataFormat):
+        (JSC::DFG::ValueSource::ValueSource):
+        (JSC::DFG::ValueSource::forFlushFormat):
+        (JSC::DFG::ValueSource::valueRecovery):
+        * dfg/DFGVarargsForwardingPhase.cpp: Added.
+        (JSC::DFG::performVarargsForwarding):
+        * dfg/DFGVarargsForwardingPhase.h: Added.
+        * dfg/DFGVariableAccessData.cpp:
+        (JSC::DFG::VariableAccessData::VariableAccessData):
+        (JSC::DFG::VariableAccessData::flushFormat):
+        (JSC::DFG::VariableAccessData::mergeIsCaptured): Deleted.
+        * dfg/DFGVariableAccessData.h:
+        (JSC::DFG::VariableAccessData::shouldNeverUnbox):
+        (JSC::DFG::VariableAccessData::shouldUseDoubleFormat):
+        (JSC::DFG::VariableAccessData::isCaptured): Deleted.
+        (JSC::DFG::VariableAccessData::mergeIsArgumentsAlias): Deleted.
+        (JSC::DFG::VariableAccessData::isArgumentsAlias): Deleted.
+        * dfg/DFGVariableAccessDataDump.cpp:
+        (JSC::DFG::VariableAccessDataDump::dump):
+        * dfg/DFGVariableAccessDataDump.h:
+        * dfg/DFGVariableEventStream.cpp:
+        (JSC::DFG::VariableEventStream::tryToSetConstantRecovery):
+        * dfg/DFGVariableEventStream.h:
+        * ftl/FTLAbstractHeap.cpp:
+        (JSC::FTL::AbstractHeap::dump):
+        (JSC::FTL::AbstractField::dump):
+        (JSC::FTL::IndexedAbstractHeap::dump):
+        (JSC::FTL::NumberedAbstractHeap::dump):
+        (JSC::FTL::AbsoluteAbstractHeap::dump):
+        * ftl/FTLAbstractHeap.h:
+        * ftl/FTLAbstractHeapRepository.cpp:
+        * ftl/FTLAbstractHeapRepository.h:
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+        * ftl/FTLExitArgument.cpp:
+        (JSC::FTL::ExitArgument::dump):
+        * ftl/FTLExitPropertyValue.cpp:
+        (JSC::FTL::ExitPropertyValue::withLocalsOffset):
+        * ftl/FTLExitPropertyValue.h:
+        * ftl/FTLExitTimeObjectMaterialization.cpp:
+        (JSC::FTL::ExitTimeObjectMaterialization::ExitTimeObjectMaterialization):
+        (JSC::FTL::ExitTimeObjectMaterialization::accountForLocalsOffset):
+        * ftl/FTLExitTimeObjectMaterialization.h:
+        (JSC::FTL::ExitTimeObjectMaterialization::origin):
+        * ftl/FTLExitValue.cpp:
+        (JSC::FTL::ExitValue::withLocalsOffset):
+        (JSC::FTL::ExitValue::valueFormat):
+        (JSC::FTL::ExitValue::dumpInContext):
+        * ftl/FTLExitValue.h:
+        (JSC::FTL::ExitValue::isArgument):
+        (JSC::FTL::ExitValue::argumentsObjectThatWasNotCreated): Deleted.
+        (JSC::FTL::ExitValue::isArgumentsObjectThatWasNotCreated): Deleted.
+        (JSC::FTL::ExitValue::valueFormat): Deleted.
+        * ftl/FTLInlineCacheSize.cpp:
+        (JSC::FTL::sizeOfCallForwardVarargs):
+        (JSC::FTL::sizeOfConstructForwardVarargs):
+        (JSC::FTL::sizeOfICFor):
+        * ftl/FTLInlineCacheSize.h:
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLJSCallVarargs.cpp:
+        (JSC::FTL::JSCallVarargs::JSCallVarargs):
+        (JSC::FTL::JSCallVarargs::emit):
+        * ftl/FTLJSCallVarargs.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::lower):
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compilePutStack):
+        (JSC::FTL::LowerDFGToLLVM::compileGetArrayLength):
+        (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
+        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
+        (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
+        (JSC::FTL::LowerDFGToLLVM::compileArrayPush):
+        (JSC::FTL::LowerDFGToLLVM::compileArrayPop):
+        (JSC::FTL::LowerDFGToLLVM::compileCreateActivation):
+        (JSC::FTL::LowerDFGToLLVM::compileNewFunction):
+        (JSC::FTL::LowerDFGToLLVM::compileCreateDirectArguments):
+        (JSC::FTL::LowerDFGToLLVM::compileCreateScopedArguments):
+        (JSC::FTL::LowerDFGToLLVM::compileCreateClonedArguments):
+        (JSC::FTL::LowerDFGToLLVM::compileStringCharAt):
+        (JSC::FTL::LowerDFGToLLVM::compileStringCharCodeAt):
+        (JSC::FTL::LowerDFGToLLVM::compileGetGlobalVar):
+        (JSC::FTL::LowerDFGToLLVM::compilePutGlobalVar):
+        (JSC::FTL::LowerDFGToLLVM::compileGetArgumentCount):
+        (JSC::FTL::LowerDFGToLLVM::compileGetClosureVar):
+        (JSC::FTL::LowerDFGToLLVM::compilePutClosureVar):
+        (JSC::FTL::LowerDFGToLLVM::compileGetFromArguments):
+        (JSC::FTL::LowerDFGToLLVM::compilePutToArguments):
+        (JSC::FTL::LowerDFGToLLVM::compileCallOrConstructVarargs):
+        (JSC::FTL::LowerDFGToLLVM::compileForwardVarargs):
+        (JSC::FTL::LowerDFGToLLVM::compileGetEnumeratorPname):
+        (JSC::FTL::LowerDFGToLLVM::ArgumentsLength::ArgumentsLength):
+        (JSC::FTL::LowerDFGToLLVM::getArgumentsLength):
+        (JSC::FTL::LowerDFGToLLVM::getCurrentCallee):
+        (JSC::FTL::LowerDFGToLLVM::getArgumentsStart):
+        (JSC::FTL::LowerDFGToLLVM::baseIndex):
+        (JSC::FTL::LowerDFGToLLVM::allocateObject):
+        (JSC::FTL::LowerDFGToLLVM::allocateVariableSizedObject):
+        (JSC::FTL::LowerDFGToLLVM::isArrayType):
+        (JSC::FTL::LowerDFGToLLVM::emitStoreBarrier):
+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
+        (JSC::FTL::LowerDFGToLLVM::exitValueForAvailability):
+        (JSC::FTL::LowerDFGToLLVM::exitValueForNode):
+        (JSC::FTL::LowerDFGToLLVM::loadStructure):
+        (JSC::FTL::LowerDFGToLLVM::compilePhantomArguments): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentsLength): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::compileGetClosureRegisters): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::compileCheckArgumentsNotCreated): Deleted.
+        (JSC::FTL::LowerDFGToLLVM::checkArgumentsNotCreated): Deleted.
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileRecovery):
+        (JSC::FTL::compileStub):
+        * ftl/FTLOperations.cpp:
+        (JSC::FTL::operationMaterializeObjectInOSR):
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::aShr):
+        (JSC::FTL::Output::lShr):
+        (JSC::FTL::Output::zeroExtPtr):
+        * heap/CopyToken.h:
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::getArgumentUnsafe):
+        * interpreter/Interpreter.cpp:
+        (JSC::sizeOfVarargs):
+        (JSC::sizeFrameForVarargs):
+        (JSC::loadVarargs):
+        (JSC::unwindCallFrame):
+        * interpreter/Interpreter.h:
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::Frame::createArguments):
+        (JSC::StackVisitor::Frame::existingArguments): Deleted.
+        * interpreter/StackVisitor.h:
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::storeValue):
+        (JSC::AssemblyHelpers::loadValue):
+        (JSC::AssemblyHelpers::storeTrustedValue):
+        (JSC::AssemblyHelpers::branchIfNotCell):
+        (JSC::AssemblyHelpers::branchIsEmpty):
+        (JSC::AssemblyHelpers::argumentsStart):
+        (JSC::AssemblyHelpers::baselineArgumentsRegisterFor): Deleted.
+        (JSC::AssemblyHelpers::offsetOfLocals): Deleted.
+        (JSC::AssemblyHelpers::offsetOfArguments): Deleted.
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgument):
+        * jit/GPRInfo.h:
+        (JSC::JSValueRegs::withTwoAvailableRegs):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompileSlowCases):
+        * jit/JIT.h:
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileSetupVarargsFrame):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::compileSetupVarargsFrame):
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_create_lexical_environment):
+        (JSC::JIT::emit_op_new_func):
+        (JSC::JIT::emit_op_create_direct_arguments):
+        (JSC::JIT::emit_op_create_scoped_arguments):
+        (JSC::JIT::emit_op_create_out_of_band_arguments):
+        (JSC::JIT::emit_op_tear_off_arguments): Deleted.
+        (JSC::JIT::emit_op_create_arguments): Deleted.
+        (JSC::JIT::emit_op_init_lazy_reg): Deleted.
+        (JSC::JIT::emit_op_get_arguments_length): Deleted.
+        (JSC::JIT::emitSlow_op_get_arguments_length): Deleted.
+        (JSC::JIT::emit_op_get_argument_by_val): Deleted.
+        (JSC::JIT::emitSlow_op_get_argument_by_val): Deleted.
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_create_lexical_environment):
+        (JSC::JIT::emit_op_tear_off_arguments): Deleted.
+        (JSC::JIT::emit_op_create_arguments): Deleted.
+        (JSC::JIT::emit_op_init_lazy_reg): Deleted.
+        (JSC::JIT::emit_op_get_arguments_length): Deleted.
+        (JSC::JIT::emitSlow_op_get_arguments_length): Deleted.
+        (JSC::JIT::emit_op_get_argument_by_val): Deleted.
+        (JSC::JIT::emitSlow_op_get_argument_by_val): Deleted.
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitGetClosureVar):
+        (JSC::JIT::emitPutClosureVar):
+        (JSC::JIT::emit_op_get_from_arguments):
+        (JSC::JIT::emit_op_put_to_arguments):
+        (JSC::JIT::emit_op_init_global_const):
+        (JSC::JIT::privateCompileGetByVal):
+        (JSC::JIT::emitDirectArgumentsGetByVal):
+        (JSC::JIT::emitScopedArgumentsGetByVal):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emitGetClosureVar):
+        (JSC::JIT::emitPutClosureVar):
+        (JSC::JIT::emit_op_get_from_arguments):
+        (JSC::JIT::emit_op_put_to_arguments):
+        (JSC::JIT::emit_op_init_global_const):
+        * jit/SetupVarargsFrame.cpp:
+        (JSC::emitSetupVarargsFrameFastCase):
+        * llint/LLIntOffsetsExtractor.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * parser/Nodes.h:
+        (JSC::ScopeNode::captures):
+        * runtime/Arguments.cpp: Removed.
+        * runtime/Arguments.h: Removed.
+        * runtime/ArgumentsMode.h: Added.
+        * runtime/DirectArgumentsOffset.cpp: Added.
+        (JSC::DirectArgumentsOffset::dump):
+        * runtime/DirectArgumentsOffset.h: Added.
+        (JSC::DirectArgumentsOffset::DirectArgumentsOffset):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        * runtime/ConstantMode.cpp: Added.
+        (WTF::printInternal):
+        * runtime/ConstantMode.h:
+        (JSC::modeForIsConstant):
+        * runtime/DirectArguments.cpp: Added.
+        (JSC::DirectArguments::DirectArguments):
+        (JSC::DirectArguments::createUninitialized):
+        (JSC::DirectArguments::create):
+        (JSC::DirectArguments::createByCopying):
+        (JSC::DirectArguments::visitChildren):
+        (JSC::DirectArguments::copyBackingStore):
+        (JSC::DirectArguments::createStructure):
+        (JSC::DirectArguments::overrideThings):
+        (JSC::DirectArguments::overrideThingsIfNecessary):
+        (JSC::DirectArguments::overrideArgument):
+        (JSC::DirectArguments::copyToArguments):
+        (JSC::DirectArguments::overridesSize):
+        * runtime/DirectArguments.h: Added.
+        (JSC::DirectArguments::internalLength):
+        (JSC::DirectArguments::length):
+        (JSC::DirectArguments::canAccessIndexQuickly):
+        (JSC::DirectArguments::getIndexQuickly):
+        (JSC::DirectArguments::setIndexQuickly):
+        (JSC::DirectArguments::callee):
+        (JSC::DirectArguments::argument):
+        (JSC::DirectArguments::overrodeThings):
+        (JSC::DirectArguments::offsetOfCallee):
+        (JSC::DirectArguments::offsetOfLength):
+        (JSC::DirectArguments::offsetOfMinCapacity):
+        (JSC::DirectArguments::offsetOfOverrides):
+        (JSC::DirectArguments::storageOffset):
+        (JSC::DirectArguments::offsetOfSlot):
+        (JSC::DirectArguments::allocationSize):
+        (JSC::DirectArguments::storage):
+        * runtime/FunctionPrototype.cpp:
+        * runtime/GenericArguments.h: Added.
+        (JSC::GenericArguments::GenericArguments):
+        * runtime/GenericArgumentsInlines.h: Added.
+        (JSC::GenericArguments<Type>::getOwnPropertySlot):
+        (JSC::GenericArguments<Type>::getOwnPropertySlotByIndex):
+        (JSC::GenericArguments<Type>::getOwnPropertyNames):
+        (JSC::GenericArguments<Type>::put):
+        (JSC::GenericArguments<Type>::putByIndex):
+        (JSC::GenericArguments<Type>::deleteProperty):
+        (JSC::GenericArguments<Type>::deletePropertyByIndex):
+        (JSC::GenericArguments<Type>::defineOwnProperty):
+        (JSC::GenericArguments<Type>::copyToArguments):
+        * runtime/GenericOffset.h: Added.
+        (JSC::GenericOffset::GenericOffset):
+        (JSC::GenericOffset::operator!):
+        (JSC::GenericOffset::offsetUnchecked):
+        (JSC::GenericOffset::offset):
+        (JSC::GenericOffset::operator==):
+        (JSC::GenericOffset::operator!=):
+        (JSC::GenericOffset::operator<):
+        (JSC::GenericOffset::operator>):
+        (JSC::GenericOffset::operator<=):
+        (JSC::GenericOffset::operator>=):
+        (JSC::GenericOffset::operator+):
+        (JSC::GenericOffset::operator-):
+        (JSC::GenericOffset::operator+=):
+        (JSC::GenericOffset::operator-=):
+        * runtime/JSArgumentsIterator.cpp:
+        (JSC::JSArgumentsIterator::finishCreation):
+        (JSC::argumentsFuncIterator):
+        * runtime/JSArgumentsIterator.h:
+        (JSC::JSArgumentsIterator::create):
+        (JSC::JSArgumentsIterator::next):
+        * runtime/JSEnvironmentRecord.cpp:
+        (JSC::JSEnvironmentRecord::visitChildren):
+        * runtime/JSEnvironmentRecord.h:
+        (JSC::JSEnvironmentRecord::variables):
+        (JSC::JSEnvironmentRecord::isValid):
+        (JSC::JSEnvironmentRecord::variableAt):
+        (JSC::JSEnvironmentRecord::offsetOfVariables):
+        (JSC::JSEnvironmentRecord::offsetOfVariable):
+        (JSC::JSEnvironmentRecord::allocationSizeForScopeSize):
+        (JSC::JSEnvironmentRecord::allocationSize):
+        (JSC::JSEnvironmentRecord::JSEnvironmentRecord):
+        (JSC::JSEnvironmentRecord::finishCreationUninitialized):
+        (JSC::JSEnvironmentRecord::finishCreation):
+        (JSC::JSEnvironmentRecord::registers): Deleted.
+        (JSC::JSEnvironmentRecord::registerAt): Deleted.
+        (JSC::JSEnvironmentRecord::addressOfRegisters): Deleted.
+        (JSC::JSEnvironmentRecord::offsetOfRegisters): Deleted.
+        * runtime/JSFunction.cpp:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::addGlobalVar):
+        (JSC::JSGlobalObject::addFunction):
+        (JSC::JSGlobalObject::visitChildren):
+        (JSC::JSGlobalObject::addStaticGlobals):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::directArgumentsStructure):
+        (JSC::JSGlobalObject::scopedArgumentsStructure):
+        (JSC::JSGlobalObject::outOfBandArgumentsStructure):
+        (JSC::JSGlobalObject::argumentsStructure): Deleted.
+        * runtime/JSLexicalEnvironment.cpp:
+        (JSC::JSLexicalEnvironment::symbolTableGet):
+        (JSC::JSLexicalEnvironment::symbolTablePut):
+        (JSC::JSLexicalEnvironment::getOwnNonIndexPropertyNames):
+        (JSC::JSLexicalEnvironment::symbolTablePutWithAttributes):
+        (JSC::JSLexicalEnvironment::visitChildren): Deleted.
+        * runtime/JSLexicalEnvironment.h:
+        (JSC::JSLexicalEnvironment::create):
+        (JSC::JSLexicalEnvironment::JSLexicalEnvironment):
+        (JSC::JSLexicalEnvironment::registersOffset): Deleted.
+        (JSC::JSLexicalEnvironment::storageOffset): Deleted.
+        (JSC::JSLexicalEnvironment::storage): Deleted.
+        (JSC::JSLexicalEnvironment::allocationSize): Deleted.
+        (JSC::JSLexicalEnvironment::isValidIndex): Deleted.
+        (JSC::JSLexicalEnvironment::isValid): Deleted.
+        (JSC::JSLexicalEnvironment::registerAt): Deleted.
+        * runtime/JSNameScope.cpp:
+        (JSC::JSNameScope::visitChildren): Deleted.
+        * runtime/JSNameScope.h:
+        (JSC::JSNameScope::create):
+        (JSC::JSNameScope::value):
+        (JSC::JSNameScope::finishCreation):
+        (JSC::JSNameScope::JSNameScope):
+        * runtime/JSScope.cpp:
+        (JSC::abstractAccess):
+        * runtime/JSSegmentedVariableObject.cpp:
+        (JSC::JSSegmentedVariableObject::findVariableIndex):
+        (JSC::JSSegmentedVariableObject::addVariables):
+        (JSC::JSSegmentedVariableObject::visitChildren):
+        (JSC::JSSegmentedVariableObject::findRegisterIndex): Deleted.
+        (JSC::JSSegmentedVariableObject::addRegisters): Deleted.
+        * runtime/JSSegmentedVariableObject.h:
+        (JSC::JSSegmentedVariableObject::variableAt):
+        (JSC::JSSegmentedVariableObject::assertVariableIsInThisObject):
+        (JSC::JSSegmentedVariableObject::registerAt): Deleted.
+        (JSC::JSSegmentedVariableObject::assertRegisterIsInThisObject): Deleted.
+        * runtime/JSSymbolTableObject.h:
+        (JSC::JSSymbolTableObject::offsetOfSymbolTable):
+        (JSC::symbolTableGet):
+        (JSC::symbolTablePut):
+        (JSC::symbolTablePutWithAttributes):
+        * runtime/JSType.h:
+        * runtime/Options.h:
+        * runtime/ClonedArguments.cpp: Added.
+        (JSC::ClonedArguments::ClonedArguments):
+        (JSC::ClonedArguments::createEmpty):
+        (JSC::ClonedArguments::createWithInlineFrame):
+        (JSC::ClonedArguments::createWithMachineFrame):
+        (JSC::ClonedArguments::createByCopyingFrom):
+        (JSC::ClonedArguments::createStructure):
+        (JSC::ClonedArguments::getOwnPropertySlot):
+        (JSC::ClonedArguments::getOwnPropertyNames):
+        (JSC::ClonedArguments::put):
+        (JSC::ClonedArguments::deleteProperty):
+        (JSC::ClonedArguments::defineOwnProperty):
+        (JSC::ClonedArguments::materializeSpecials):
+        (JSC::ClonedArguments::materializeSpecialsIfNecessary):
+        * runtime/ClonedArguments.h: Added.
+        (JSC::ClonedArguments::specialsMaterialized):
+        * runtime/ScopeOffset.cpp: Added.
+        (JSC::ScopeOffset::dump):
+        * runtime/ScopeOffset.h: Added.
+        (JSC::ScopeOffset::ScopeOffset):
+        * runtime/ScopedArguments.cpp: Added.
+        (JSC::ScopedArguments::ScopedArguments):
+        (JSC::ScopedArguments::finishCreation):
+        (JSC::ScopedArguments::createUninitialized):
+        (JSC::ScopedArguments::create):
+        (JSC::ScopedArguments::createByCopying):
+        (JSC::ScopedArguments::createByCopyingFrom):
+        (JSC::ScopedArguments::visitChildren):
+        (JSC::ScopedArguments::createStructure):
+        (JSC::ScopedArguments::overrideThings):
+        (JSC::ScopedArguments::overrideThingsIfNecessary):
+        (JSC::ScopedArguments::overrideArgument):
+        (JSC::ScopedArguments::copyToArguments):
+        * runtime/ScopedArguments.h: Added.
+        (JSC::ScopedArguments::internalLength):
+        (JSC::ScopedArguments::length):
+        (JSC::ScopedArguments::canAccessIndexQuickly):
+        (JSC::ScopedArguments::getIndexQuickly):
+        (JSC::ScopedArguments::setIndexQuickly):
+        (JSC::ScopedArguments::callee):
+        (JSC::ScopedArguments::overrodeThings):
+        (JSC::ScopedArguments::offsetOfOverrodeThings):
+        (JSC::ScopedArguments::offsetOfTotalLength):
+        (JSC::ScopedArguments::offsetOfTable):
+        (JSC::ScopedArguments::offsetOfScope):
+        (JSC::ScopedArguments::overflowStorageOffset):
+        (JSC::ScopedArguments::allocationSize):
+        (JSC::ScopedArguments::overflowStorage):
+        * runtime/ScopedArgumentsTable.cpp: Added.
+        (JSC::ScopedArgumentsTable::ScopedArgumentsTable):
+        (JSC::ScopedArgumentsTable::~ScopedArgumentsTable):
+        (JSC::ScopedArgumentsTable::destroy):
+        (JSC::ScopedArgumentsTable::create):
+        (JSC::ScopedArgumentsTable::clone):
+        (JSC::ScopedArgumentsTable::setLength):
+        (JSC::ScopedArgumentsTable::set):
+        (JSC::ScopedArgumentsTable::createStructure):
+        * runtime/ScopedArgumentsTable.h: Added.
+        (JSC::ScopedArgumentsTable::length):
+        (JSC::ScopedArgumentsTable::get):
+        (JSC::ScopedArgumentsTable::lock):
+        (JSC::ScopedArgumentsTable::offsetOfLength):
+        (JSC::ScopedArgumentsTable::offsetOfArguments):
+        (JSC::ScopedArgumentsTable::at):
+        * runtime/SymbolTable.cpp:
+        (JSC::SymbolTableEntry::prepareToWatch):
+        (JSC::SymbolTable::SymbolTable):
+        (JSC::SymbolTable::visitChildren):
+        (JSC::SymbolTable::localToEntry):
+        (JSC::SymbolTable::entryFor):
+        (JSC::SymbolTable::cloneScopePart):
+        (JSC::SymbolTable::prepareForTypeProfiling):
+        (JSC::SymbolTable::uniqueIDForOffset):
+        (JSC::SymbolTable::globalTypeSetForOffset):
+        (JSC::SymbolTable::cloneCapturedNames): Deleted.
+        (JSC::SymbolTable::uniqueIDForRegister): Deleted.
+        (JSC::SymbolTable::globalTypeSetForRegister): Deleted.
+        * runtime/SymbolTable.h:
+        (JSC::SymbolTableEntry::varOffsetFromBits):
+        (JSC::SymbolTableEntry::scopeOffsetFromBits):
+        (JSC::SymbolTableEntry::Fast::varOffset):
+        (JSC::SymbolTableEntry::Fast::scopeOffset):
+        (JSC::SymbolTableEntry::Fast::isDontEnum):
+        (JSC::SymbolTableEntry::Fast::getAttributes):
+        (JSC::SymbolTableEntry::SymbolTableEntry):
+        (JSC::SymbolTableEntry::varOffset):
+        (JSC::SymbolTableEntry::isWatchable):
+        (JSC::SymbolTableEntry::scopeOffset):
+        (JSC::SymbolTableEntry::setAttributes):
+        (JSC::SymbolTableEntry::constantMode):
+        (JSC::SymbolTableEntry::isDontEnum):
+        (JSC::SymbolTableEntry::disableWatching):
+        (JSC::SymbolTableEntry::pack):
+        (JSC::SymbolTableEntry::isValidVarOffset):
+        (JSC::SymbolTable::createNameScopeTable):
+        (JSC::SymbolTable::maxScopeOffset):
+        (JSC::SymbolTable::didUseScopeOffset):
+        (JSC::SymbolTable::didUseVarOffset):
+        (JSC::SymbolTable::scopeSize):
+        (JSC::SymbolTable::nextScopeOffset):
+        (JSC::SymbolTable::takeNextScopeOffset):
+        (JSC::SymbolTable::add):
+        (JSC::SymbolTable::set):
+        (JSC::SymbolTable::argumentsLength):
+        (JSC::SymbolTable::setArgumentsLength):
+        (JSC::SymbolTable::argumentOffset):
+        (JSC::SymbolTable::setArgumentOffset):
+        (JSC::SymbolTable::arguments):
+        (JSC::SlowArgument::SlowArgument): Deleted.
+        (JSC::SymbolTableEntry::Fast::getIndex): Deleted.
+        (JSC::SymbolTableEntry::getIndex): Deleted.
+        (JSC::SymbolTableEntry::isValidIndex): Deleted.
+        (JSC::SymbolTable::captureStart): Deleted.
+        (JSC::SymbolTable::setCaptureStart): Deleted.
+        (JSC::SymbolTable::captureEnd): Deleted.
+        (JSC::SymbolTable::setCaptureEnd): Deleted.
+        (JSC::SymbolTable::captureCount): Deleted.
+        (JSC::SymbolTable::isCaptured): Deleted.
+        (JSC::SymbolTable::parameterCount): Deleted.
+        (JSC::SymbolTable::parameterCountIncludingThis): Deleted.
+        (JSC::SymbolTable::setParameterCountIncludingThis): Deleted.
+        (JSC::SymbolTable::slowArguments): Deleted.
+        (JSC::SymbolTable::setSlowArguments): Deleted.
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+        * runtime/VarOffset.cpp: Added.
+        (JSC::VarOffset::dump):
+        (WTF::printInternal):
+        * runtime/VarOffset.h: Added.
+        (JSC::VarOffset::VarOffset):
+        (JSC::VarOffset::assemble):
+        (JSC::VarOffset::isValid):
+        (JSC::VarOffset::operator!):
+        (JSC::VarOffset::kind):
+        (JSC::VarOffset::isStack):
+        (JSC::VarOffset::isScope):
+        (JSC::VarOffset::isDirectArgument):
+        (JSC::VarOffset::stackOffsetUnchecked):
+        (JSC::VarOffset::scopeOffsetUnchecked):
+        (JSC::VarOffset::capturedArgumentsOffsetUnchecked):
+        (JSC::VarOffset::stackOffset):
+        (JSC::VarOffset::scopeOffset):
+        (JSC::VarOffset::capturedArgumentsOffset):
+        (JSC::VarOffset::rawOffset):
+        (JSC::VarOffset::checkSanity):
+        (JSC::VarOffset::operator==):
+        (JSC::VarOffset::operator!=):
+        (JSC::VarOffset::hash):
+        (JSC::VarOffset::isHashTableDeletedValue):
+        (JSC::VarOffsetHash::hash):
+        (JSC::VarOffsetHash::equal):
+        * tests/stress/arguments-exit-strict-mode.js: Added.
+        * tests/stress/arguments-exit.js: Added.
+        * tests/stress/arguments-inlined-exit-strict-mode-fixed.js: Added.
+        * tests/stress/arguments-inlined-exit-strict-mode.js: Added.
+        * tests/stress/arguments-inlined-exit.js: Added.
+        * tests/stress/arguments-interference.js: Added.
+        * tests/stress/arguments-interference-cfg.js: Added.
+        * tests/stress/dead-get-closure-var.js: Added.
+        * tests/stress/get-declared-unpassed-argument-in-direct-arguments.js: Added.
+        * tests/stress/get-declared-unpassed-argument-in-scoped-arguments.js: Added.
+        * tests/stress/varargs-closure-inlined-exit-strict-mode.js: Added.
+        * tests/stress/varargs-closure-inlined-exit.js: Added.
+        * tests/stress/varargs-exit.js: Added.
+        * tests/stress/varargs-inlined-exit.js: Added.
+        * tests/stress/varargs-inlined-simple-exit-aliasing-weird-reversed-args.js: Added.
+        * tests/stress/varargs-inlined-simple-exit-aliasing-weird.js: Added.
+        * tests/stress/varargs-inlined-simple-exit-aliasing.js: Added.
+        * tests/stress/varargs-inlined-simple-exit.js: Added.
+        * tests/stress/varargs-too-few-arguments.js: Added.
+        * tests/stress/varargs-varargs-closure-inlined-exit.js: Added.
+        * tests/stress/varargs-varargs-inlined-exit-strict-mode.js: Added.
+        * tests/stress/varargs-varargs-inlined-exit.js: Added.
+
 2015-03-25  Andy Estes  <aestes@apple.com>
 
         [Cocoa] RemoteInspectorXPCConnection::deserializeMessage() leaks a NSDictionary under Objective-C GC
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
index 6545361..74330e7 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
@@ -362,7 +362,8 @@
     <ClCompile Include="..\debugger\DebuggerScope.cpp" />
     <ClCompile Include="..\dfg\DFGAbstractHeap.cpp" />
     <ClCompile Include="..\dfg\DFGAbstractValue.cpp" />
-    <ClCompile Include="..\dfg\DFGArgumentsSimplificationPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGArgumentsEliminationPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGArgumentsUtilities.cpp" />
     <ClCompile Include="..\dfg\DFGArithMode.cpp" />
     <ClCompile Include="..\dfg\DFGArrayMode.cpp" />
     <ClCompile Include="..\dfg\DFGAtTailAbstractState.cpp" />
@@ -478,6 +479,7 @@
     <ClCompile Include="..\dfg\DFGValidate.cpp" />
     <ClCompile Include="..\dfg\DFGValueSource.cpp" />
     <ClCompile Include="..\dfg\DFGValueStrength.cpp" />
+    <ClCompile Include="..\dfg\DFGVarargsForwardingPhase.cpp" />
     <ClCompile Include="..\dfg\DFGVariableAccessData.cpp" />
     <ClCompile Include="..\dfg\DFGVariableAccessDataDump.cpp" />
     <ClCompile Include="..\dfg\DFGVariableEvent.cpp" />
@@ -667,7 +669,6 @@
     <ClCompile Include="..\profiler\ProfilerOSRExitSite.cpp" />
     <ClCompile Include="..\profiler\ProfilerProfiledBytecodes.cpp" />
     <ClCompile Include="..\runtime\ArgList.cpp" />
-    <ClCompile Include="..\runtime\Arguments.cpp" />
     <ClCompile Include="..\runtime\ArgumentsIteratorConstructor.cpp" />
     <ClCompile Include="..\runtime\ArgumentsIteratorPrototype.cpp" />
     <ClCompile Include="..\runtime\ArrayBuffer.cpp" />
@@ -682,6 +683,7 @@
     <ClCompile Include="..\runtime\BooleanObject.cpp" />
     <ClCompile Include="..\runtime\BooleanPrototype.cpp" />
     <ClCompile Include="..\runtime\CallData.cpp" />
+    <ClCompile Include="..\runtime\ClonedArguments.cpp" />
     <ClCompile Include="..\runtime\CodeCache.cpp" />
     <ClCompile Include="..\runtime\CodeSpecializationKind.cpp" />
     <ClCompile Include="..\runtime\CommonIdentifiers.cpp" />
@@ -691,6 +693,7 @@
     <ClCompile Include="..\runtime\Completion.cpp" />
     <ClCompile Include="..\runtime\ConsoleClient.cpp" />
     <ClCompile Include="..\runtime\ConsolePrototype.cpp" />
+    <ClCompile Include="..\runtime\ConstantMode.cpp" />
     <ClCompile Include="..\runtime\ConstructData.cpp" />
     <ClCompile Include="..\runtime\ControlFlowProfiler.cpp" />
     <ClCompile Include="..\runtime\CustomGetterSetter.cpp" />
@@ -699,6 +702,8 @@
     <ClCompile Include="..\runtime\DateConversion.cpp" />
     <ClCompile Include="..\runtime\DateInstance.cpp" />
     <ClCompile Include="..\runtime\DatePrototype.cpp" />
+    <ClCompile Include="..\runtime\DirectArguments.cpp" />
+    <ClCompile Include="..\runtime\DirectArgumentsOffset.cpp" />
     <ClCompile Include="..\runtime\DumpContext.cpp" />
     <ClCompile Include="..\runtime\Error.cpp" />
     <ClCompile Include="..\runtime\ErrorConstructor.cpp" />
@@ -809,6 +814,9 @@
     <ClCompile Include="..\runtime\SetIteratorConstructor.cpp" />
     <ClCompile Include="..\runtime\SetIteratorPrototype.cpp" />
     <ClCompile Include="..\runtime\SetPrototype.cpp" />
+    <ClCompile Include="..\runtime\ScopeOffset.cpp" />
+    <ClCompile Include="..\runtime\ScopedArguments.cpp" />
+    <ClCompile Include="..\runtime\ScopedArgumentsTable.cpp" />
     <ClCompile Include="..\runtime\SimpleTypedArrayController.cpp" />
     <ClCompile Include="..\runtime\SmallStrings.cpp" />
     <ClCompile Include="..\runtime\SparseArrayValueMap.cpp" />
@@ -837,6 +845,7 @@
     <ClCompile Include="..\runtime\TypeSet.cpp" />
     <ClCompile Include="..\runtime\VM.cpp" />
     <ClCompile Include="..\runtime\VMEntryScope.cpp" />
+    <ClCompile Include="..\runtime\VarOffset.cpp" />
     <ClCompile Include="..\runtime\Watchdog.cpp" />
     <ClCompile Include="..\runtime\WatchdogNone.cpp" />
     <ClCompile Include="..\runtime\WeakMapConstructor.cpp" />
@@ -941,6 +950,7 @@
     <ClInclude Include="..\bytecode\ArrayProfile.h" />
     <ClInclude Include="..\bytecode\ByValInfo.h" />
     <ClInclude Include="..\bytecode\BytecodeBasicBlock.h" />
+    <ClInclude Include="..\bytecode\BytecodeKills.h" />
     <ClInclude Include="..\bytecode\BytecodeLivenessAnalysis.h" />
     <ClInclude Include="..\bytecode\BytecodeUseDef.h" />
     <ClInclude Include="..\bytecode\CallEdge.h" />
@@ -1016,7 +1026,8 @@
     <ClInclude Include="..\dfg\DFGAllocator.h" />
     <ClInclude Include="..\dfg\DFGAnalysis.h" />
     <ClInclude Include="..\dfg\DFGArgumentPosition.h" />
-    <ClInclude Include="..\dfg\DFGArgumentsSimplificationPhase.h" />
+    <ClInclude Include="..\dfg\DFGArgumentsEliminationPhase.h" />
+    <ClInclude Include="..\dfg\DFGArgumentsUtilities.h" />
     <ClInclude Include="..\dfg\DFGArrayifySlowPathGenerator.h" />
     <ClInclude Include="..\dfg\DFGArithMode.h" />
     <ClInclude Include="..\dfg\DFGArrayMode.h" />
@@ -1035,6 +1046,7 @@
     <ClInclude Include="..\dfg\DFGBranchDirection.h" />
     <ClInclude Include="..\dfg\DFGByteCodeParser.h" />
     <ClInclude Include="..\dfg\DFGCallArrayAllocatorSlowPathGenerator.h" />
+    <ClInclude Include="..\dfg\DFGCallCreateDirectArgumentsSlowPathGenerator.h" />
     <ClInclude Include="..\dfg\DFGCapabilities.h" />
     <ClInclude Include="..\dfg\DFGCCallHelpers.h" />
     <ClInclude Include="..\dfg\DFGCFAPhase.h" />
@@ -1069,6 +1081,7 @@
     <ClInclude Include="..\dfg\DFGFixupPhase.h" />
     <ClInclude Include="..\dfg\DFGFlushedAt.h" />
     <ClInclude Include="..\dfg\DFGFlushFormat.h" />
+    <ClInclude Include="..\dfg\DFGForAllKills.h" />
     <ClInclude Include="..\dfg\DFGFPRInfo.h" />
     <ClInclude Include="..\dfg\DFGFrozenValue.h" />
     <ClInclude Include="..\dfg\DFGFunctionWhitelist.h" />
@@ -1163,6 +1176,7 @@
     <ClInclude Include="..\dfg\DFGValidate.h" />
     <ClInclude Include="..\dfg\DFGValueSource.h" />
     <ClInclude Include="..\dfg\DFGValueStrength.h" />
+    <ClInclude Include="..\dfg\DFGVarargsForwardingPhase.h" />
     <ClInclude Include="..\dfg\DFGVariableAccessData.h" />
     <ClInclude Include="..\dfg\DFGVariableAccessDataDump.h" />
     <ClInclude Include="..\dfg\DFGVariableEvent.h" />
@@ -1424,7 +1438,7 @@
     <ClInclude Include="..\profiler\ProfilerOSRExitSite.h" />
     <ClInclude Include="..\profiler\ProfilerProfiledBytecodes.h" />
     <ClInclude Include="..\runtime\ArgList.h" />
-    <ClInclude Include="..\runtime\Arguments.h" />
+    <ClInclude Include="..\runtime\ArgumentsMode.h" />
     <ClInclude Include="..\runtime\ArrayBuffer.h" />
     <ClInclude Include="..\runtime\ArrayBufferNeuteringWatchpoint.h" />
     <ClInclude Include="..\runtime\ArrayBufferView.h" />
@@ -1444,6 +1458,7 @@
     <ClInclude Include="..\runtime\ButterflyInlines.h" />
     <ClInclude Include="..\runtime\CallData.h" />
     <ClInclude Include="..\runtime\ClassInfo.h" />
+    <ClInclude Include="..\runtime\ClonedArguments.h" />
     <ClInclude Include="..\runtime\CodeCache.h" />
     <ClInclude Include="..\runtime\CodeSpecializationKind.h" />
     <ClInclude Include="..\runtime\CommonIdentifiers.h" />
@@ -1464,6 +1479,8 @@
     <ClInclude Include="..\runtime\DateInstance.h" />
     <ClInclude Include="..\runtime\DateInstanceCache.h" />
     <ClInclude Include="..\runtime\DatePrototype.h" />
+    <ClInclude Include="..\runtime\DirectArguments.h" />
+    <ClInclude Include="..\runtime\DirectArgumentsOffset.h" />
     <ClInclude Include="..\runtime\DumpContext.h" />
     <ClInclude Include="..\runtime\EnumerationMode.h" />
     <ClInclude Include="..\runtime\Error.h" />
@@ -1480,6 +1497,9 @@
     <ClInclude Include="..\runtime\FunctionExecutableDump.h" />
     <ClInclude Include="..\runtime\FunctionHasExecutedCache.h" />
     <ClInclude Include="..\runtime\FunctionPrototype.h" />
+    <ClInclude Include="..\runtime\GenericArguments.h" />
+    <ClInclude Include="..\runtime\GenericArgumentsInlines.h" />
+    <ClInclude Include="..\runtime\GenericOffset.h" />
     <ClInclude Include="..\runtime\GenericTypedArrayView.h" />
     <ClInclude Include="..\runtime\GenericTypedArrayViewInlines.h" />
     <ClInclude Include="..\runtime\GetterSetter.h" />
@@ -1619,6 +1639,9 @@
     <ClInclude Include="..\runtime\RuntimeFlags.h" />
     <ClInclude Include="..\runtime\RuntimeType.h" />
     <ClInclude Include="..\runtime\SamplingCounter.h" />
+    <ClInclude Include="..\runtime\ScopeOffset.h" />
+    <ClInclude Include="..\runtime\ScopedArguments.h" />
+    <ClInclude Include="..\runtime\ScopedArgumentsTable.h" />
     <ClInclude Include="..\runtime\SetConstructor.h" />
     <ClInclude Include="..\runtime\SetIteratorConstructor.h" />
     <ClInclude Include="..\runtime\SetIteratorPrototype.h" />
@@ -1664,6 +1687,7 @@
     <ClInclude Include="..\runtime\Uint8Array.h" />
     <ClInclude Include="..\runtime\VM.h" />
     <ClInclude Include="..\runtime\VMEntryScope.h" />
+    <ClInclude Include="..\runtime\VarOffset.h" />
     <ClInclude Include="..\runtime\Watchdog.h" />
     <ClInclude Include="..\runtime\WeakGCMap.h" />
     <ClInclude Include="..\runtime\WeakMapConstructor.h" />
diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index edfaba7..ba2d136 100644
--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -104,8 +104,6 @@
 		0F13912C16771C3D009CCB07 /* ProfilerProfiledBytecodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F13912716771C30009CCB07 /* ProfilerProfiledBytecodes.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F13E04E16164A1F00DC8DE7 /* IndexingType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F13E04C16164A1B00DC8DE7 /* IndexingType.cpp */; };
 		0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		0F16015D156198C900C2587C /* DFGArgumentsSimplificationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F16015A156198BF00C2587C /* DFGArgumentsSimplificationPhase.cpp */; };
-		0F16015E156198C900C2587C /* DFGArgumentsSimplificationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F16015B156198BF00C2587C /* DFGArgumentsSimplificationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F190CAC189D82F6000AE5F0 /* ProfilerJettisonReason.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F190CAA189D82F6000AE5F0 /* ProfilerJettisonReason.cpp */; };
 		0F190CAD189D82F6000AE5F0 /* ProfilerJettisonReason.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F190CAB189D82F6000AE5F0 /* ProfilerJettisonReason.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F1DD84A18A945BE0026F3FA /* JSCInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1DD84918A945BE0026F3FA /* JSCInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -251,6 +249,12 @@
 		0F2D4DEC19832DC4007D4B19 /* TypeProfilerLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2D4DE019832D91007D4B19 /* TypeProfilerLog.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F2D4DEF19832DD3007D4B19 /* TypeSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2D4DE319832D91007D4B19 /* TypeSet.cpp */; };
 		0F2D4DF019832DD6007D4B19 /* TypeSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2D4DE419832D91007D4B19 /* TypeSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0F2DD80B1AB3D85800BBB8E8 /* BytecodeKills.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2DD80A1AB3D85800BBB8E8 /* BytecodeKills.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0F2DD8111AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2DD80C1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.cpp */; };
+		0F2DD8121AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2DD80D1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0F2DD8131AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2DD80E1AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.cpp */; };
+		0F2DD8141AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2DD80F1AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0F2DD8151AB3D8BE00BBB8E8 /* DFGForAllKills.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2DD8101AB3D8BE00BBB8E8 /* DFGForAllKills.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F2E892C16D028AD009E4FD2 /* UnusedPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = 65987F2F16828A7E003C2F8D /* UnusedPointer.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F2E892D16D02BAF009E4FD2 /* DFGMinifiedID.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB4B51016B3A964003F696B /* DFGMinifiedID.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F2FC77216E12F710038D976 /* DFGDCEPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2FC77016E12F6F0038D976 /* DFGDCEPhase.cpp */; };
@@ -441,6 +445,7 @@
 		0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F96EBB316676EF6008BADE3 /* CodeBlockWithJITType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F96EBB116676EF4008BADE3 /* CodeBlockWithJITType.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F9749711687ADE400A4FF6A /* JSCellInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F97496F1687ADE200A4FF6A /* JSCellInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0F978B3B1AAEA71D007C7369 /* ConstantMode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F978B3A1AAEA71D007C7369 /* ConstantMode.cpp */; };
 		0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F98205D16BFE37F00240D02 /* PreciseJumpTargets.cpp */; };
 		0F98206116BFE38300240D02 /* PreciseJumpTargets.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F98205E16BFE37F00240D02 /* PreciseJumpTargets.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F9C5E5E18E35F5E00D431C3 /* FTLDWARFRegister.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9C5E5C18E35F5E00D431C3 /* FTLDWARFRegister.cpp */; };
@@ -498,6 +503,7 @@
 		0FBC0AE71496C7C400D4FBDD /* DFGExitProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBC0AE41496C7C100D4FBDD /* DFGExitProfile.cpp */; };
 		0FBC0AE81496C7C700D4FBDD /* DFGExitProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FBD7E691447999600481315 /* CodeOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBD7E671447998F00481315 /* CodeOrigin.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FBDB9AD1AB0FBC6000B57E5 /* DFGCallCreateDirectArgumentsSlowPathGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBDB9AC1AB0FBC6000B57E5 /* DFGCallCreateDirectArgumentsSlowPathGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FBE0F7216C1DB030082C5E8 /* DFGCPSRethreadingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBE0F6B16C1DB010082C5E8 /* DFGCPSRethreadingPhase.cpp */; };
 		0FBE0F7316C1DB050082C5E8 /* DFGCPSRethreadingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBE0F6C16C1DB010082C5E8 /* DFGCPSRethreadingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FBE0F7416C1DB090082C5E8 /* DFGPredictionInjectionPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBE0F6D16C1DB010082C5E8 /* DFGPredictionInjectionPhase.cpp */; };
@@ -604,8 +610,28 @@
 		0FDB2CEA174896C7007B3C1B /* ConcurrentJITLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDB2CE9174896C7007B3C1B /* ConcurrentJITLock.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FDDBFB51666EED800C55FEF /* DFGVariableAccessDataDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDDBFB21666EED500C55FEF /* DFGVariableAccessDataDump.cpp */; };
 		0FDDBFB61666EEDA00C55FEF /* DFGVariableAccessDataDump.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDDBFB31666EED500C55FEF /* DFGVariableAccessDataDump.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FE050141AA9091100D33B33 /* ArgumentsMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE0500C1AA9091100D33B33 /* ArgumentsMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FE050151AA9091100D33B33 /* DirectArgumentsOffset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE0500D1AA9091100D33B33 /* DirectArgumentsOffset.cpp */; };
+		0FE050161AA9091100D33B33 /* DirectArgumentsOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE0500E1AA9091100D33B33 /* DirectArgumentsOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FE050171AA9091100D33B33 /* DirectArguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE0500F1AA9091100D33B33 /* DirectArguments.cpp */; };
+		0FE050181AA9091100D33B33 /* DirectArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050101AA9091100D33B33 /* DirectArguments.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FE050191AA9091100D33B33 /* GenericArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050111AA9091100D33B33 /* GenericArguments.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FE0501A1AA9091100D33B33 /* GenericArgumentsInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050121AA9091100D33B33 /* GenericArgumentsInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FE0501B1AA9091100D33B33 /* GenericOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050131AA9091100D33B33 /* GenericOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FE050251AA9095600D33B33 /* ClonedArguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE0501C1AA9095600D33B33 /* ClonedArguments.cpp */; };
+		0FE050261AA9095600D33B33 /* ClonedArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE0501D1AA9095600D33B33 /* ClonedArguments.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FE050271AA9095600D33B33 /* ScopedArguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE0501E1AA9095600D33B33 /* ScopedArguments.cpp */; };
+		0FE050281AA9095600D33B33 /* ScopedArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE0501F1AA9095600D33B33 /* ScopedArguments.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FE050291AA9095600D33B33 /* ScopedArgumentsTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050201AA9095600D33B33 /* ScopedArgumentsTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FE0502A1AA9095600D33B33 /* ScopeOffset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE050211AA9095600D33B33 /* ScopeOffset.cpp */; };
+		0FE0502B1AA9095600D33B33 /* ScopeOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050221AA9095600D33B33 /* ScopeOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FE0502C1AA9095600D33B33 /* VarOffset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE050231AA9095600D33B33 /* VarOffset.cpp */; };
+		0FE0502D1AA9095600D33B33 /* VarOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050241AA9095600D33B33 /* VarOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FE0502F1AAA806900D33B33 /* ScopedArgumentsTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE0502E1AAA806900D33B33 /* ScopedArgumentsTable.cpp */; };
 		0FE228ED1436AB2700196C48 /* Options.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE228EB1436AB2300196C48 /* Options.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FE228EE1436AB2C00196C48 /* Options.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE228EA1436AB2300196C48 /* Options.cpp */; };
+		0FE254F61ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE254F41ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.cpp */; };
+		0FE254F71ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE254F51ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FE7211D193B9C590031F6ED /* DFGTransition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE7211B193B9C590031F6ED /* DFGTransition.cpp */; };
 		0FE7211E193B9C590031F6ED /* DFGTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE7211C193B9C590031F6ED /* DFGTransition.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FE834171A6EF97B00D04847 /* PolymorphicCallStubRoutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE834151A6EF97B00D04847 /* PolymorphicCallStubRoutine.cpp */; };
@@ -803,7 +829,6 @@
 		147B83AC0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 147B83AA0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		147B84630E6DE6B1004775A4 /* PutPropertySlot.h in Headers */ = {isa = PBXBuildFile; fileRef = 147B84620E6DE6B1004775A4 /* PutPropertySlot.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		147F39BD107EC37600427A48 /* ArgList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCF605110E203EF800B9A64D /* ArgList.cpp */; };
-		147F39BE107EC37600427A48 /* Arguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC257DE50E1F51C50016B6C9 /* Arguments.cpp */; };
 		147F39BF107EC37600427A48 /* ArrayConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7952060E15E8A800A898AB /* ArrayConstructor.cpp */; };
 		147F39C0107EC37600427A48 /* ArrayPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A84D0255597D01FF60F7 /* ArrayPrototype.cpp */; };
 		147F39C1107EC37600427A48 /* CommonIdentifiers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65EA73620BAE35D1001BB560 /* CommonIdentifiers.cpp */; };
@@ -1523,7 +1548,6 @@
 		BC18C5240E16FC8A00B34460 /* ArrayPrototype.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C5230E16FC8A00B34460 /* ArrayPrototype.lut.h */; };
 		BC18C52C0E16FCD200B34460 /* RegExpObject.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C52B0E16FCD200B34460 /* RegExpObject.lut.h */; };
 		BC18C52E0E16FCE100B34460 /* Lexer.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C52D0E16FCE100B34460 /* Lexer.lut.h */; };
-		BC257DE80E1F51C50016B6C9 /* Arguments.h in Headers */ = {isa = PBXBuildFile; fileRef = BC257DE60E1F51C50016B6C9 /* Arguments.h */; };
 		BC3046070E1F497F003232CF /* Error.h in Headers */ = {isa = PBXBuildFile; fileRef = BC3046060E1F497F003232CF /* Error.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		BC756FC90E2031B200DE7D12 /* JSGlobalObjectFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */; };
@@ -1797,8 +1821,6 @@
 		0F13912716771C30009CCB07 /* ProfilerProfiledBytecodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerProfiledBytecodes.h; path = profiler/ProfilerProfiledBytecodes.h; sourceTree = "<group>"; };
 		0F13E04C16164A1B00DC8DE7 /* IndexingType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IndexingType.cpp; sourceTree = "<group>"; };
 		0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonSlowPaths.h; sourceTree = "<group>"; };
-		0F16015A156198BF00C2587C /* DFGArgumentsSimplificationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGArgumentsSimplificationPhase.cpp; path = dfg/DFGArgumentsSimplificationPhase.cpp; sourceTree = "<group>"; };
-		0F16015B156198BF00C2587C /* DFGArgumentsSimplificationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArgumentsSimplificationPhase.h; path = dfg/DFGArgumentsSimplificationPhase.h; sourceTree = "<group>"; };
 		0F190CAA189D82F6000AE5F0 /* ProfilerJettisonReason.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerJettisonReason.cpp; path = profiler/ProfilerJettisonReason.cpp; sourceTree = "<group>"; };
 		0F190CAB189D82F6000AE5F0 /* ProfilerJettisonReason.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerJettisonReason.h; path = profiler/ProfilerJettisonReason.h; sourceTree = "<group>"; };
 		0F1DD84918A945BE0026F3FA /* JSCInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCInlines.h; sourceTree = "<group>"; };
@@ -1945,6 +1967,12 @@
 		0F2D4DE519832DAC007D4B19 /* ToThisStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ToThisStatus.cpp; sourceTree = "<group>"; };
 		0F2D4DE619832DAC007D4B19 /* ToThisStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ToThisStatus.h; sourceTree = "<group>"; };
 		0F2D4DE719832DAC007D4B19 /* TypeLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeLocation.h; sourceTree = "<group>"; };
+		0F2DD80A1AB3D85800BBB8E8 /* BytecodeKills.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeKills.h; sourceTree = "<group>"; };
+		0F2DD80C1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGArgumentsEliminationPhase.cpp; path = dfg/DFGArgumentsEliminationPhase.cpp; sourceTree = "<group>"; };
+		0F2DD80D1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArgumentsEliminationPhase.h; path = dfg/DFGArgumentsEliminationPhase.h; sourceTree = "<group>"; };
+		0F2DD80E1AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGArgumentsUtilities.cpp; path = dfg/DFGArgumentsUtilities.cpp; sourceTree = "<group>"; };
+		0F2DD80F1AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArgumentsUtilities.h; path = dfg/DFGArgumentsUtilities.h; sourceTree = "<group>"; };
+		0F2DD8101AB3D8BE00BBB8E8 /* DFGForAllKills.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGForAllKills.h; path = dfg/DFGForAllKills.h; sourceTree = "<group>"; };
 		0F2FC77016E12F6F0038D976 /* DFGDCEPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDCEPhase.cpp; path = dfg/DFGDCEPhase.cpp; sourceTree = "<group>"; };
 		0F2FC77116E12F6F0038D976 /* DFGDCEPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDCEPhase.h; path = dfg/DFGDCEPhase.h; sourceTree = "<group>"; };
 		0F2FCCF218A60070001A27F8 /* DFGGraphSafepoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGGraphSafepoint.cpp; path = dfg/DFGGraphSafepoint.cpp; sourceTree = "<group>"; };
@@ -2132,6 +2160,7 @@
 		0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueProfile.h; sourceTree = "<group>"; };
 		0F96EBB116676EF4008BADE3 /* CodeBlockWithJITType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeBlockWithJITType.h; sourceTree = "<group>"; };
 		0F97496F1687ADE200A4FF6A /* JSCellInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCellInlines.h; sourceTree = "<group>"; };
+		0F978B3A1AAEA71D007C7369 /* ConstantMode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConstantMode.cpp; sourceTree = "<group>"; };
 		0F98205D16BFE37F00240D02 /* PreciseJumpTargets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PreciseJumpTargets.cpp; sourceTree = "<group>"; };
 		0F98205E16BFE37F00240D02 /* PreciseJumpTargets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PreciseJumpTargets.h; sourceTree = "<group>"; };
 		0F9C5E5C18E35F5E00D431C3 /* FTLDWARFRegister.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLDWARFRegister.cpp; path = ftl/FTLDWARFRegister.cpp; sourceTree = "<group>"; };
@@ -2199,6 +2228,7 @@
 		0FBC0AE41496C7C100D4FBDD /* DFGExitProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DFGExitProfile.cpp; sourceTree = "<group>"; };
 		0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DFGExitProfile.h; sourceTree = "<group>"; };
 		0FBD7E671447998F00481315 /* CodeOrigin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeOrigin.h; sourceTree = "<group>"; };
+		0FBDB9AC1AB0FBC6000B57E5 /* DFGCallCreateDirectArgumentsSlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCallCreateDirectArgumentsSlowPathGenerator.h; path = dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h; sourceTree = "<group>"; };
 		0FBE0F6B16C1DB010082C5E8 /* DFGCPSRethreadingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCPSRethreadingPhase.cpp; path = dfg/DFGCPSRethreadingPhase.cpp; sourceTree = "<group>"; };
 		0FBE0F6C16C1DB010082C5E8 /* DFGCPSRethreadingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCPSRethreadingPhase.h; path = dfg/DFGCPSRethreadingPhase.h; sourceTree = "<group>"; };
 		0FBE0F6D16C1DB010082C5E8 /* DFGPredictionInjectionPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPredictionInjectionPhase.cpp; path = dfg/DFGPredictionInjectionPhase.cpp; sourceTree = "<group>"; };
@@ -2309,8 +2339,28 @@
 		0FDB2CE9174896C7007B3C1B /* ConcurrentJITLock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConcurrentJITLock.h; sourceTree = "<group>"; };
 		0FDDBFB21666EED500C55FEF /* DFGVariableAccessDataDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVariableAccessDataDump.cpp; path = dfg/DFGVariableAccessDataDump.cpp; sourceTree = "<group>"; };
 		0FDDBFB31666EED500C55FEF /* DFGVariableAccessDataDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVariableAccessDataDump.h; path = dfg/DFGVariableAccessDataDump.h; sourceTree = "<group>"; };
+		0FE0500C1AA9091100D33B33 /* ArgumentsMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArgumentsMode.h; sourceTree = "<group>"; };
+		0FE0500D1AA9091100D33B33 /* DirectArgumentsOffset.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectArgumentsOffset.cpp; sourceTree = "<group>"; };
+		0FE0500E1AA9091100D33B33 /* DirectArgumentsOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectArgumentsOffset.h; sourceTree = "<group>"; };
+		0FE0500F1AA9091100D33B33 /* DirectArguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectArguments.cpp; sourceTree = "<group>"; };
+		0FE050101AA9091100D33B33 /* DirectArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectArguments.h; sourceTree = "<group>"; };
+		0FE050111AA9091100D33B33 /* GenericArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenericArguments.h; sourceTree = "<group>"; };
+		0FE050121AA9091100D33B33 /* GenericArgumentsInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenericArgumentsInlines.h; sourceTree = "<group>"; };
+		0FE050131AA9091100D33B33 /* GenericOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenericOffset.h; sourceTree = "<group>"; };
+		0FE0501C1AA9095600D33B33 /* ClonedArguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClonedArguments.cpp; sourceTree = "<group>"; };
+		0FE0501D1AA9095600D33B33 /* ClonedArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClonedArguments.h; sourceTree = "<group>"; };
+		0FE0501E1AA9095600D33B33 /* ScopedArguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScopedArguments.cpp; sourceTree = "<group>"; };
+		0FE0501F1AA9095600D33B33 /* ScopedArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopedArguments.h; sourceTree = "<group>"; };
+		0FE050201AA9095600D33B33 /* ScopedArgumentsTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopedArgumentsTable.h; sourceTree = "<group>"; };
+		0FE050211AA9095600D33B33 /* ScopeOffset.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScopeOffset.cpp; sourceTree = "<group>"; };
+		0FE050221AA9095600D33B33 /* ScopeOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopeOffset.h; sourceTree = "<group>"; };
+		0FE050231AA9095600D33B33 /* VarOffset.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VarOffset.cpp; sourceTree = "<group>"; };
+		0FE050241AA9095600D33B33 /* VarOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VarOffset.h; sourceTree = "<group>"; };
+		0FE0502E1AAA806900D33B33 /* ScopedArgumentsTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScopedArgumentsTable.cpp; sourceTree = "<group>"; };
 		0FE228EA1436AB2300196C48 /* Options.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Options.cpp; sourceTree = "<group>"; };
 		0FE228EB1436AB2300196C48 /* Options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Options.h; sourceTree = "<group>"; };
+		0FE254F41ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVarargsForwardingPhase.cpp; path = dfg/DFGVarargsForwardingPhase.cpp; sourceTree = "<group>"; };
+		0FE254F51ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVarargsForwardingPhase.h; path = dfg/DFGVarargsForwardingPhase.h; sourceTree = "<group>"; };
 		0FE7211B193B9C590031F6ED /* DFGTransition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGTransition.cpp; path = dfg/DFGTransition.cpp; sourceTree = "<group>"; };
 		0FE7211C193B9C590031F6ED /* DFGTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGTransition.h; path = dfg/DFGTransition.h; sourceTree = "<group>"; };
 		0FE834151A6EF97B00D04847 /* PolymorphicCallStubRoutine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PolymorphicCallStubRoutine.cpp; sourceTree = "<group>"; };
@@ -3198,8 +3248,6 @@
 		BC22A3980E16E14800AF21C8 /* JSObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSObject.cpp; sourceTree = "<group>"; };
 		BC22A3990E16E14800AF21C8 /* JSObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSObject.h; sourceTree = "<group>"; };
 		BC22A39A0E16E14800AF21C8 /* JSEnvironmentRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSEnvironmentRecord.cpp; sourceTree = "<group>"; };
-		BC257DE50E1F51C50016B6C9 /* Arguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Arguments.cpp; sourceTree = "<group>"; };
-		BC257DE60E1F51C50016B6C9 /* Arguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Arguments.h; sourceTree = "<group>"; };
 		BC2680C00E16D4E900A06E92 /* FunctionConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionConstructor.cpp; sourceTree = "<group>"; };
 		BC2680C10E16D4E900A06E92 /* FunctionConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionConstructor.h; sourceTree = "<group>"; };
 		BC2680C20E16D4E900A06E92 /* NumberConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NumberConstructor.cpp; sourceTree = "<group>"; };
@@ -4234,12 +4282,11 @@
 			children = (
 				BCF605110E203EF800B9A64D /* ArgList.cpp */,
 				BCF605120E203EF800B9A64D /* ArgList.h */,
-				BC257DE50E1F51C50016B6C9 /* Arguments.cpp */,
-				BC257DE60E1F51C50016B6C9 /* Arguments.h */,
 				A76140C7182982CB00750624 /* ArgumentsIteratorConstructor.cpp */,
 				A76140C8182982CB00750624 /* ArgumentsIteratorConstructor.h */,
 				A76140C9182982CB00750624 /* ArgumentsIteratorPrototype.cpp */,
 				A76140CA182982CB00750624 /* ArgumentsIteratorPrototype.h */,
+				0FE0500C1AA9091100D33B33 /* ArgumentsMode.h */,
 				0F6B1CB71861244C00845D97 /* ArityCheckMode.h */,
 				A7A8AF2517ADB5F2005AB174 /* ArrayBuffer.cpp */,
 				A7A8AF2617ADB5F3005AB174 /* ArrayBuffer.h */,
@@ -4274,6 +4321,8 @@
 				BCA62DFE0E2826230004F30D /* CallData.cpp */,
 				145C507F0D9DF63B0088F6B9 /* CallData.h */,
 				BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */,
+				0FE0501C1AA9095600D33B33 /* ClonedArguments.cpp */,
+				0FE0501D1AA9095600D33B33 /* ClonedArguments.h */,
 				A77F181F164088B200640A47 /* CodeCache.cpp */,
 				A77F1820164088B200640A47 /* CodeCache.h */,
 				0F8F943A1667631100D61971 /* CodeSpecializationKind.cpp */,
@@ -4294,6 +4343,7 @@
 				A53CE08118BC1A5600BEDF76 /* ConsolePrototype.cpp */,
 				A53CE08218BC1A5600BEDF76 /* ConsolePrototype.h */,
 				A5FD0071189B038C00633231 /* ConsoleTypes.h */,
+				0F978B3A1AAEA71D007C7369 /* ConstantMode.cpp */,
 				0FFC99D0184EC8AD009C10AB /* ConstantMode.h */,
 				BCA62DFF0E2826310004F30D /* ConstructData.cpp */,
 				BC8F3CCF0DAF17BA00577A80 /* ConstructData.h */,
@@ -4312,6 +4362,10 @@
 				14A1563010966365006FA260 /* DateInstanceCache.h */,
 				BCD203470E17135E002C7E82 /* DatePrototype.cpp */,
 				BCD203480E17135E002C7E82 /* DatePrototype.h */,
+				0FE0500F1AA9091100D33B33 /* DirectArguments.cpp */,
+				0FE050101AA9091100D33B33 /* DirectArguments.h */,
+				0FE0500D1AA9091100D33B33 /* DirectArgumentsOffset.cpp */,
+				0FE0500E1AA9091100D33B33 /* DirectArgumentsOffset.h */,
 				A70447EB17A0BD7000F5898E /* DumpContext.cpp */,
 				A70447EC17A0BD7000F5898E /* DumpContext.h */,
 				2AD2EDFA19799E38004D6478 /* EnumerationMode.h */,
@@ -4341,6 +4395,9 @@
 				52B310FA1974AE610080857C /* FunctionHasExecutedCache.h */,
 				F692A85C0255597D01FF60F7 /* FunctionPrototype.cpp */,
 				F692A85D0255597D01FF60F7 /* FunctionPrototype.h */,
+				0FE050111AA9091100D33B33 /* GenericArguments.h */,
+				0FE050121AA9091100D33B33 /* GenericArgumentsInlines.h */,
+				0FE050131AA9091100D33B33 /* GenericOffset.h */,
 				0F2B66B217B6B5AB00A7AE3F /* GenericTypedArrayView.h */,
 				0F2B66B317B6B5AB00A7AE3F /* GenericTypedArrayViewInlines.h */,
 				BC02E9B80E184545000F9297 /* GetterSetter.cpp */,
@@ -4578,6 +4635,12 @@
 				52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */,
 				0F7700911402FF280078EB39 /* SamplingCounter.cpp */,
 				0F77008E1402FDD60078EB39 /* SamplingCounter.h */,
+				0FE0501E1AA9095600D33B33 /* ScopedArguments.cpp */,
+				0FE0501F1AA9095600D33B33 /* ScopedArguments.h */,
+				0FE0502E1AAA806900D33B33 /* ScopedArgumentsTable.cpp */,
+				0FE050201AA9095600D33B33 /* ScopedArgumentsTable.h */,
+				0FE050211AA9095600D33B33 /* ScopeOffset.cpp */,
+				0FE050221AA9095600D33B33 /* ScopeOffset.h */,
 				A7299DA317D12858005F5FF9 /* SetConstructor.cpp */,
 				A7299DA417D12858005F5FF9 /* SetConstructor.h */,
 				A790DD65182F499700588807 /* SetIteratorConstructor.cpp */,
@@ -4654,6 +4717,8 @@
 				A7A8AF3217ADB5F3005AB174 /* Uint16Array.h */,
 				866739D113BFDE710023D87C /* Uint16WithFraction.h */,
 				A7A8AF3317ADB5F3005AB174 /* Uint32Array.h */,
+				0FE050231AA9095600D33B33 /* VarOffset.cpp */,
+				0FE050241AA9095600D33B33 /* VarOffset.h */,
 				E18E3A570DF9278C00D90B34 /* VM.cpp */,
 				E18E3A560DF9278C00D90B34 /* VM.h */,
 				FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */,
@@ -4724,8 +4789,10 @@
 				0FB4B51916B62772003F696B /* DFGAllocator.h */,
 				A73781091799EA2E00817533 /* DFGAnalysis.h */,
 				0F1E3A431534CBAD000F9456 /* DFGArgumentPosition.h */,
-				0F16015A156198BF00C2587C /* DFGArgumentsSimplificationPhase.cpp */,
-				0F16015B156198BF00C2587C /* DFGArgumentsSimplificationPhase.h */,
+				0F2DD80C1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.cpp */,
+				0F2DD80D1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.h */,
+				0F2DD80E1AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.cpp */,
+				0F2DD80F1AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.h */,
 				0F48531F187750560083B687 /* DFGArithMode.cpp */,
 				0F485320187750560083B687 /* DFGArithMode.h */,
 				0F05C3B21683CF8F00BAF45B /* DFGArrayifySlowPathGenerator.h */,
@@ -4755,6 +4822,7 @@
 				86EC9DB41328DF82002B2AD7 /* DFGByteCodeParser.cpp */,
 				86EC9DB51328DF82002B2AD7 /* DFGByteCodeParser.h */,
 				0F256C341627B0AA007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h */,
+				0FBDB9AC1AB0FBC6000B57E5 /* DFGCallCreateDirectArgumentsSlowPathGenerator.h */,
 				0FD82E1E14172C2F00179C94 /* DFGCapabilities.cpp */,
 				0FD82E1F14172C2F00179C94 /* DFGCapabilities.h */,
 				0FFFC94B14EF909500C72532 /* DFGCFAPhase.cpp */,
@@ -4817,6 +4885,7 @@
 				0F9D339517FFC4E60073C2BC /* DFGFlushedAt.h */,
 				A7D89CE817A0B8CC00773AD8 /* DFGFlushFormat.cpp */,
 				A7D89CE917A0B8CC00773AD8 /* DFGFlushFormat.h */,
+				0F2DD8101AB3D8BE00BBB8E8 /* DFGForAllKills.h */,
 				0F69CC86193AC60A0045759E /* DFGFrozenValue.cpp */,
 				0F69CC87193AC60A0045759E /* DFGFrozenValue.h */,
 				2A88067619107D5500CB0BBB /* DFGFunctionWhitelist.cpp */,
@@ -4984,6 +5053,8 @@
 				0F2BDC401522801700CD8910 /* DFGValueSource.h */,
 				0F0123301944EA1B00843A0C /* DFGValueStrength.cpp */,
 				0F0123311944EA1B00843A0C /* DFGValueStrength.h */,
+				0FE254F41ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.cpp */,
+				0FE254F51ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.h */,
 				0F6E845919030BEF00562741 /* DFGVariableAccessData.cpp */,
 				0F620172143FCD2F0068B77C /* DFGVariableAccessData.h */,
 				0FDDBFB21666EED500C55FEF /* DFGVariableAccessDataDump.cpp */,
@@ -5105,6 +5176,7 @@
 				C2FCAE0C17A9C24E0034C735 /* BytecodeBasicBlock.cpp */,
 				C2FCAE0D17A9C24E0034C735 /* BytecodeBasicBlock.h */,
 				0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */,
+				0F2DD80A1AB3D85800BBB8E8 /* BytecodeKills.h */,
 				6529FB3118B2D99900C61102 /* BytecodeList.json */,
 				C2FCAE0E17A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp */,
 				C2FCAE0F17A9C24E0034C735 /* BytecodeLivenessAnalysis.h */,
@@ -5459,18 +5531,19 @@
 			files = (
 				0FFA549816B8835300B3A982 /* A64DOpcode.h in Headers */,
 				860161E30F3A83C100F84710 /* AbstractMacroAssembler.h in Headers */,
+				0FE050291AA9095600D33B33 /* ScopedArgumentsTable.h in Headers */,
 				0F55F0F514D1063C00AC7649 /* AbstractPC.h in Headers */,
 				2A48D1911772365B00C65A5F /* APICallbackFunction.h in Headers */,
 				BC18C3E50E16F5CD00B34460 /* APICast.h in Headers */,
 				BCF605140E203EF800B9A64D /* ArgList.h in Headers */,
 				2A88067919107D5500CB0BBB /* DFGFunctionWhitelist.h in Headers */,
-				BC257DE80E1F51C50016B6C9 /* Arguments.h in Headers */,
 				A76140CE182982CB00750624 /* ArgumentsIteratorConstructor.h in Headers */,
 				A76140D0182982CB00750624 /* ArgumentsIteratorPrototype.h in Headers */,
 				0F6B1CCA18641DF800845D97 /* ArityCheckFailReturnThunks.h in Headers */,
 				0F6B1CB91861244C00845D97 /* ArityCheckMode.h in Headers */,
 				A1A009C11831A26E00CF8711 /* ARM64Assembler.h in Headers */,
 				86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */,
+				0FE050281AA9095600D33B33 /* ScopedArguments.h in Headers */,
 				52C0611F1AA51E1C00B4ADBA /* RuntimeType.h in Headers */,
 				C442CB251A6CDB8C005D3D7C /* JSInputs.json in Headers */,
 				52678F911A04177C006A306D /* ControlFlowProfiler.h in Headers */,
@@ -5631,7 +5704,6 @@
 				A737810C1799EA2E00817533 /* DFGAnalysis.h in Headers */,
 				0F1E3A461534CBAF000F9456 /* DFGArgumentPosition.h in Headers */,
 				A5C3A1A618C0490200C9593A /* JSGlobalObjectConsoleClient.h in Headers */,
-				0F16015E156198C900C2587C /* DFGArgumentsSimplificationPhase.h in Headers */,
 				0F485322187750560083B687 /* DFGArithMode.h in Headers */,
 				0F05C3B41683CF9200BAF45B /* DFGArrayifySlowPathGenerator.h in Headers */,
 				0F63948515E4811B006A597C /* DFGArrayMode.h in Headers */,
@@ -5646,6 +5718,7 @@
 				0F256C361627B0AD007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h in Headers */,
 				0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */,
 				0FFFC95814EF90A200C72532 /* DFGCFAPhase.h in Headers */,
+				0F2DD80B1AB3D85800BBB8E8 /* BytecodeKills.h in Headers */,
 				0F3B3A281544C997003ED0FF /* DFGCFGSimplificationPhase.h in Headers */,
 				A77A424017A0BBFD00A8DB81 /* DFGClobberize.h in Headers */,
 				A77A424217A0BBFD00A8DB81 /* DFGClobberSet.h in Headers */,
@@ -5735,6 +5808,7 @@
 				A77A424317A0BBFD00A8DB81 /* DFGSafeToExecute.h in Headers */,
 				A741017F179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h in Headers */,
 				0F2FCCFD18A60070001A27F8 /* DFGScannable.h in Headers */,
+				0F2DD8141AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.h in Headers */,
 				86ECA3FA132DF25A002B2AD7 /* DFGScoreBoard.h in Headers */,
 				0F1E3A67153A21E2000F9456 /* DFGSilentRegisterSavePlan.h in Headers */,
 				0FFB921D16D02F300055A5DB /* DFGSlowPathGenerator.h in Headers */,
@@ -5789,6 +5863,7 @@
 				0FDB2CC9173DA520007B3C1B /* FTLAbbreviatedTypes.h in Headers */,
 				0FEA0A08170513DB00BB722C /* FTLAbbreviations.h in Headers */,
 				A53CE08A18BC21C300BEDF76 /* ConsoleClient.h in Headers */,
+				0FE050191AA9091100D33B33 /* GenericArguments.h in Headers */,
 				0FEA0A1D1708B00700BB722C /* FTLAbstractHeap.h in Headers */,
 				DC00039319D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h in Headers */,
 				0FEA0A1F1708B00700BB722C /* FTLAbstractHeapRepository.h in Headers */,
@@ -5873,6 +5948,7 @@
 				C2C8D03114A3CEFC00578E65 /* HeapBlock.h in Headers */,
 				2AD8932B17E3868F00668276 /* HeapIterationScope.h in Headers */,
 				2A6F462617E959CE00C45C98 /* HeapOperation.h in Headers */,
+				0FE050141AA9091100D33B33 /* ArgumentsMode.h in Headers */,
 				14F97447138C853E00DA1C67 /* HeapRootVisitor.h in Headers */,
 				C24D31E3161CD695002AA4DB /* HeapStatistics.h in Headers */,
 				C2E526BE1590EF000054E48D /* HeapTimer.h in Headers */,
@@ -5899,6 +5975,7 @@
 				A593CF7F1840362C00BFCE27 /* InspectorAgentBase.h in Headers */,
 				0F3E01AB19D353A500F61B7F /* DFGPrePostNumbering.h in Headers */,
 				A593CF87184038CA00BFCE27 /* InspectorAgentRegistry.h in Headers */,
+				0FE050261AA9095600D33B33 /* ClonedArguments.h in Headers */,
 				A593CF7D1840360300BFCE27 /* InspectorBackendDispatcher.h in Headers */,
 				A5FD0082189B191A00633231 /* InspectorConsoleAgent.h in Headers */,
 				A57D23E61890CEBF0031C7FA /* InspectorDebuggerAgent.h in Headers */,
@@ -5974,6 +6051,7 @@
 				BC1167DA0E19BCC9008066DD /* JSCell.h in Headers */,
 				0F9749711687ADE400A4FF6A /* JSCellInlines.h in Headers */,
 				0F1DD84A18A945BE0026F3FA /* JSCInlines.h in Headers */,
+				0FE0501A1AA9091100D33B33 /* GenericArgumentsInlines.h in Headers */,
 				BC18C42B0E16F5CD00B34460 /* JSCJSValue.h in Headers */,
 				0F64B2721A784BAF006E4E66 /* BinarySwitch.h in Headers */,
 				865A30F1135007E100CDB49E /* JSCJSValueInlines.h in Headers */,
@@ -6054,6 +6132,7 @@
 				1A28D4A8177B71C80007FA3C /* JSStringRefPrivate.h in Headers */,
 				0F919D0D157EE0A2004A4E7D /* JSSymbolTableObject.h in Headers */,
 				BC18C42A0E16F5CD00B34460 /* JSType.h in Headers */,
+				0FE050161AA9091100D33B33 /* DirectArgumentsOffset.h in Headers */,
 				0F2B66FB17B6B5AB00A7AE3F /* JSTypedArrayConstructors.h in Headers */,
 				0F2B66FD17B6B5AB00A7AE3F /* JSTypedArrayPrototypes.h in Headers */,
 				0F2B66FF17B6B5AB00A7AE3F /* JSTypedArrays.h in Headers */,
@@ -6062,6 +6141,7 @@
 				0F2B670317B6B5AB00A7AE3F /* JSUint32Array.h in Headers */,
 				0F2D4DF019832DD6007D4B19 /* TypeSet.h in Headers */,
 				0F2B670017B6B5AB00A7AE3F /* JSUint8Array.h in Headers */,
+				0FE0502D1AA9095600D33B33 /* VarOffset.h in Headers */,
 				0F2B670117B6B5AB00A7AE3F /* JSUint8ClampedArray.h in Headers */,
 				86E3C612167BABD7006D760A /* JSValue.h in Headers */,
 				86E3C61B167BABEE006D760A /* JSValueInternal.h in Headers */,
@@ -6090,8 +6170,10 @@
 				A7E2EA6B0FB460CF00601F06 /* LiteralParser.h in Headers */,
 				0F0FC45A14BD15F500B81154 /* LLIntCallLinkInfo.h in Headers */,
 				0FC3CD0019ADA410006AC72A /* DFGBlockWorklist.h in Headers */,
+				0FE050181AA9091100D33B33 /* DirectArguments.h in Headers */,
 				FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */,
 				0F4680CA14BBB16C00BFE272 /* LLIntCommon.h in Headers */,
+				0FBDB9AD1AB0FBC6000B57E5 /* DFGCallCreateDirectArgumentsSlowPathGenerator.h in Headers */,
 				0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */,
 				0F38B01217CF078300B144D3 /* LLIntEntrypoint.h in Headers */,
 				0F4680A314BA7F8D00BFE272 /* LLIntExceptions.h in Headers */,
@@ -6164,6 +6246,7 @@
 				A70447EA17A0BD4600F5898E /* OperandsInlines.h in Headers */,
 				0F2D4DDE19832D34007D4B19 /* DebuggerScope.h in Headers */,
 				BC18C4480E16F5CD00B34460 /* Operations.h in Headers */,
+				0FE0501B1AA9091100D33B33 /* GenericOffset.h in Headers */,
 				0FE228ED1436AB2700196C48 /* Options.h in Headers */,
 				BC18C44B0E16F5CD00B34460 /* Parser.h in Headers */,
 				93052C350FB792190048FDC3 /* ParserArena.h in Headers */,
@@ -6173,6 +6256,7 @@
 				0F34B14C16D43E0D001CDA5A /* PolymorphicAccessStructureList.h in Headers */,
 				0F9FC8C414E1B60000D52AE0 /* PolymorphicPutByIdList.h in Headers */,
 				0F98206116BFE38300240D02 /* PreciseJumpTargets.h in Headers */,
+				0F2DD8151AB3D8BE00BBB8E8 /* DFGForAllKills.h in Headers */,
 				868916B0155F286300CB2B9A /* PrivateName.h in Headers */,
 				A5EA70E719F5B1010098F5EC /* AugmentableInspectorController.h in Headers */,
 				BC18C4500E16F5CD00B34460 /* Profile.h in Headers */,
@@ -6245,6 +6329,7 @@
 				869EBCB70E8C6D4A008722CC /* ResultType.h in Headers */,
 				C22B31B9140577D700DB475A /* SamplingCounter.h in Headers */,
 				1429D8860ED21C3D00B89619 /* SamplingTool.h in Headers */,
+				0FE254F71ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.h in Headers */,
 				0F24E55217EE274900ABB217 /* ScratchRegisterAllocator.h in Headers */,
 				A5FD0068189AFE9C00633231 /* ScriptArguments.h in Headers */,
 				A503FA21188EFF6800110F14 /* ScriptBreakpoint.h in Headers */,
@@ -6324,6 +6409,7 @@
 				0FF42749158EBE91004CB9FF /* udis86_types.h in Headers */,
 				70B0A9D11A9B66460001306A /* RuntimeFlags.h in Headers */,
 				A7E5AB391799E4B200D2833D /* UDis86Disassembler.h in Headers */,
+				0FE0502B1AA9095600D33B33 /* ScopeOffset.h in Headers */,
 				A7A8AF4117ADB5F3005AB174 /* Uint16Array.h in Headers */,
 				0FE834181A6EF97B00D04847 /* PolymorphicCallStubRoutine.h in Headers */,
 				866739D313BFDE710023D87C /* Uint16WithFraction.h in Headers */,
@@ -6348,6 +6434,7 @@
 				14BFCE6910CDB1FC00364CCE /* WeakGCMap.h in Headers */,
 				14F7256614EE265E00B1652B /* WeakHandleOwner.h in Headers */,
 				14E84FA214EE1ACC00D6D5D4 /* WeakImpl.h in Headers */,
+				0F2DD8121AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.h in Headers */,
 				14BE7D3317135CF400D1807A /* WeakInlines.h in Headers */,
 				A7CA3AE417DA41AE006538AF /* WeakMapConstructor.h in Headers */,
 				A7CA3AEC17DA5168006538AF /* WeakMapData.h in Headers */,
@@ -6834,9 +6921,9 @@
 				9E729408190F021E001A91B5 /* InitializeLLVMPOSIX.cpp in Sources */,
 				9E729407190F01A5001A91B5 /* InitializeThreading.cpp in Sources */,
 				0FFA549716B8835000B3A982 /* A64DOpcode.cpp in Sources */,
+				0FE050151AA9091100D33B33 /* DirectArgumentsOffset.cpp in Sources */,
 				0F55F0F414D1063900AC7649 /* AbstractPC.cpp in Sources */,
 				147F39BD107EC37600427A48 /* ArgList.cpp in Sources */,
-				147F39BE107EC37600427A48 /* Arguments.cpp in Sources */,
 				A76140CD182982CB00750624 /* ArgumentsIteratorConstructor.cpp in Sources */,
 				A76140CF182982CB00750624 /* ArgumentsIteratorPrototype.cpp in Sources */,
 				0F6B1CC918641DF800845D97 /* ArityCheckFailReturnThunks.cpp in Sources */,
@@ -6884,6 +6971,7 @@
 				A709F2F217A0AC2A00512E98 /* CommonSlowPaths.cpp in Sources */,
 				6553A33117A1F1EE008CF6F3 /* CommonSlowPathsExceptions.cpp in Sources */,
 				0F64B2791A7957B2006E4E66 /* CallEdge.cpp in Sources */,
+				0FE254F61ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.cpp in Sources */,
 				A7E5A3A71797432D00E893C0 /* CompilationResult.cpp in Sources */,
 				147F39C2107EC37600427A48 /* Completion.cpp in Sources */,
 				146B16D812EB5B59001BEC1B /* ConservativeRoots.cpp in Sources */,
@@ -6906,7 +6994,6 @@
 				0FC712DE17CD8779008CC93C /* DeferredCompilationCallback.cpp in Sources */,
 				A77A423D17A0BBFD00A8DB81 /* DFGAbstractHeap.cpp in Sources */,
 				0F55C19417276E4600CEABFD /* DFGAbstractValue.cpp in Sources */,
-				0F16015D156198C900C2587C /* DFGArgumentsSimplificationPhase.cpp in Sources */,
 				0F485321187750560083B687 /* DFGArithMode.cpp in Sources */,
 				0F2D4DDD19832D34007D4B19 /* DebuggerScope.cpp in Sources */,
 				0F63948415E48118006A597C /* DFGArrayMode.cpp in Sources */,
@@ -6916,6 +7003,7 @@
 				0F2B9CEC19D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.cpp in Sources */,
 				A7D89CF217A0B8CC00773AD8 /* DFGBasicBlock.cpp in Sources */,
 				2A88067819107D5500CB0BBB /* DFGFunctionWhitelist.cpp in Sources */,
+				0F2DD8131AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.cpp in Sources */,
 				A7D89CF317A0B8CC00773AD8 /* DFGBlockInsertionSet.cpp in Sources */,
 				86EC9DC41328DF82002B2AD7 /* DFGByteCodeParser.cpp in Sources */,
 				0FD82E2114172CE300179C94 /* DFGCapabilities.cpp in Sources */,
@@ -6962,6 +7050,7 @@
 				A5C3A1A518C0490200C9593A /* JSGlobalObjectConsoleClient.cpp in Sources */,
 				0FEA0A33170D40BF00BB722C /* DFGJITCode.cpp in Sources */,
 				86EC9DCB1328DF82002B2AD7 /* DFGJITCompiler.cpp in Sources */,
+				0FE0502A1AA9095600D33B33 /* ScopeOffset.cpp in Sources */,
 				A78A9778179738B8009DF744 /* DFGJITFinalizer.cpp in Sources */,
 				0FC97F3F18202119002C9B26 /* DFGJumpReplacement.cpp in Sources */,
 				A73A535A1799CD5D00170C19 /* DFGLazyJSValue.cpp in Sources */,
@@ -7040,12 +7129,15 @@
 				86CA032E1038E8440028A609 /* Executable.cpp in Sources */,
 				A7B48F490EE8936F00DCBDB6 /* ExecutableAllocator.cpp in Sources */,
 				86DB64640F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp in Sources */,
+				0F2DD8111AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.cpp in Sources */,
 				0F56A1D515001CF4002992B1 /* ExecutionCounter.cpp in Sources */,
 				52678F8E1A031009006A306D /* BasicBlockLocation.cpp in Sources */,
 				0F2D4DEB19832DC4007D4B19 /* TypeProfilerLog.cpp in Sources */,
 				0F0332C018ADFAE1005F979A /* ExitingJITType.cpp in Sources */,
 				0FB105851675480F00F8AB6E /* ExitKind.cpp in Sources */,
 				0FEA0A1C1708B00700BB722C /* FTLAbstractHeap.cpp in Sources */,
+				0F978B3B1AAEA71D007C7369 /* ConstantMode.cpp in Sources */,
+				0FE050251AA9095600D33B33 /* ClonedArguments.cpp in Sources */,
 				0F79085519A290B200F6310C /* DFGStructureRegistrationPhase.cpp in Sources */,
 				0FEA0A1E1708B00700BB722C /* FTLAbstractHeapRepository.cpp in Sources */,
 				0F485327187DFDEC0083B687 /* FTLAvailableRecovery.cpp in Sources */,
@@ -7184,6 +7276,7 @@
 				0F2B66ED17B6B5AB00A7AE3F /* JSDataViewPrototype.cpp in Sources */,
 				0F2D4DE819832DAC007D4B19 /* ToThisStatus.cpp in Sources */,
 				978801401471AD920041B016 /* JSDateMath.cpp in Sources */,
+				0FE050171AA9091100D33B33 /* DirectArguments.cpp in Sources */,
 				140566D6107EC271005DBC8D /* JSFunction.cpp in Sources */,
 				147F39D2107EC37600427A48 /* JSGlobalObject.cpp in Sources */,
 				A5FD0085189B1B7E00633231 /* JSGlobalObjectConsoleAgent.cpp in Sources */,
@@ -7332,6 +7425,7 @@
 				0FA7A8EB18B413C80052371D /* Reg.cpp in Sources */,
 				14280841107EC0930013E7B2 /* RegExp.cpp in Sources */,
 				A1712B3B11C7B212007A5315 /* RegExpCache.cpp in Sources */,
+				0FE0502C1AA9095600D33B33 /* VarOffset.cpp in Sources */,
 				8642C510151C06A90046D4EF /* RegExpCachedResult.cpp in Sources */,
 				14280842107EC0930013E7B2 /* RegExpConstructor.cpp in Sources */,
 				8642C512151C083D0046D4EF /* RegExpMatchesArray.cpp in Sources */,
@@ -7425,9 +7519,11 @@
 				14E84FA014EE1ACC00D6D5D4 /* WeakSet.cpp in Sources */,
 				2A4EC90B1860D6C20094F782 /* WriteBarrierBuffer.cpp in Sources */,
 				0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */,
+				0FE050271AA9095600D33B33 /* ScopedArguments.cpp in Sources */,
 				0F3B7E2A19A11B8000D9BC56 /* CallVariant.cpp in Sources */,
 				A7E5AB3A1799E4B200D2833D /* X86Disassembler.cpp in Sources */,
 				863C6D9C1521111A00585E4E /* YarrCanonicalizeUCS2.cpp in Sources */,
+				0FE0502F1AAA806900D33B33 /* ScopedArgumentsTable.cpp in Sources */,
 				86704B8412DBA33700A9FE7B /* YarrInterpreter.cpp in Sources */,
 				86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */,
 				86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
diff --git a/Source/JavaScriptCore/assembler/AbortReason.h b/Source/JavaScriptCore/assembler/AbortReason.h
index 34c345b..1a5f068 100644
--- a/Source/JavaScriptCore/assembler/AbortReason.h
+++ b/Source/JavaScriptCore/assembler/AbortReason.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -57,6 +57,7 @@
     DFGSlowPathGeneratorFellThrough                   = 210,
     DFGUnreachableBasicBlock                          = 220,
     DFGUnreasonableOSREntryJumpDestination            = 230,
+    DFGVarargsThrowingPathDidNotThrow                 = 235,
     JITDivOperandsAreNotNumbers                       = 240,
     JITGetByValResultIsNotEmpty                       = 250,
     JITNotSupported                                   = 260,
diff --git a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
index 1bc6194..6e82dcc 100644
--- a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
+++ b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2012, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012, 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -205,6 +205,11 @@
         RegisterID index;
         Scale scale;
         int32_t offset;
+        
+        BaseIndex withOffset(int32_t additionalOffset)
+        {
+            return BaseIndex(base, index, scale, offset + additionalOffset);
+        }
     };
 
     // AbsoluteAddress:
diff --git a/Source/JavaScriptCore/bytecode/ByValInfo.h b/Source/JavaScriptCore/bytecode/ByValInfo.h
index ebe587d..d988516 100644
--- a/Source/JavaScriptCore/bytecode/ByValInfo.h
+++ b/Source/JavaScriptCore/bytecode/ByValInfo.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -41,6 +41,8 @@
     JITDouble,
     JITContiguous,
     JITArrayStorage,
+    JITDirectArguments,
+    JITScopedArguments,
     JITInt8Array,
     JITInt16Array,
     JITInt32Array,
@@ -65,6 +67,17 @@
     }
 }
 
+inline bool hasOptimizableIndexingForJSType(JSType type)
+{
+    switch (type) {
+    case DirectArgumentsType:
+    case ScopedArgumentsType:
+        return true;
+    default:
+        return false;
+    }
+}
+
 inline bool hasOptimizableIndexingForClassInfo(const ClassInfo* classInfo)
 {
     return isTypedView(classInfo->typedArrayStorageType);
@@ -73,6 +86,7 @@
 inline bool hasOptimizableIndexing(Structure* structure)
 {
     return isOptimizableIndexingType(structure->indexingType())
+        || hasOptimizableIndexingForJSType(structure->typeInfo().type())
         || hasOptimizableIndexingForClassInfo(structure->classInfo());
 }
 
@@ -93,6 +107,19 @@
     }
 }
 
+inline JITArrayMode jitArrayModeForJSType(JSType type)
+{
+    switch (type) {
+    case DirectArgumentsType:
+        return JITDirectArguments;
+    case ScopedArgumentsType:
+        return JITScopedArguments;
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        return JITContiguous;
+    }
+}
+
 inline JITArrayMode jitArrayModeForClassInfo(const ClassInfo* classInfo)
 {
     switch (classInfo->typedArrayStorageType) {
@@ -120,6 +147,19 @@
     }
 }
 
+inline bool jitArrayModePermitsPut(JITArrayMode mode)
+{
+    switch (mode) {
+    case JITDirectArguments:
+    case JITScopedArguments:
+        // We could support put_by_val on these at some point, but it's just not that profitable
+        // at the moment.
+        return false;
+    default:
+        return true;
+    }
+}
+
 inline TypedArrayType typedArrayTypeForJITArrayMode(JITArrayMode mode)
 {
     switch (mode) {
@@ -152,6 +192,9 @@
     if (isOptimizableIndexingType(structure->indexingType()))
         return jitArrayModeForIndexingType(structure->indexingType());
     
+    if (hasOptimizableIndexingForJSType(structure->typeInfo().type()))
+        return jitArrayModeForJSType(structure->typeInfo().type());
+    
     ASSERT(hasOptimizableIndexingForClassInfo(structure->classInfo()));
     return jitArrayModeForClassInfo(structure->classInfo());
 }
diff --git a/Source/JavaScriptCore/bytecode/BytecodeKills.h b/Source/JavaScriptCore/bytecode/BytecodeKills.h
new file mode 100644
index 0000000..6e504a6
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/BytecodeKills.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BytecodeKills_h
+#define BytecodeKills_h
+
+#include "CodeBlock.h"
+#include <wtf/FastBitVector.h>
+
+namespace JSC {
+
+class BytecodeLivenessAnalysis;
+
+class BytecodeKills {
+public:
+    BytecodeKills()
+        : m_codeBlock(nullptr)
+    {
+    }
+    
+    // By convention, we say that non-local operands are never killed.
+    bool operandIsKilled(unsigned bytecodeIndex, int operand) const
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(bytecodeIndex < m_codeBlock->instructions().size());
+        VirtualRegister reg(operand);
+        if (reg.isLocal())
+            return m_killSets[bytecodeIndex].contains(operand);
+        return false;
+    }
+    
+    bool operandIsKilled(Instruction* instruction, int operand) const
+    {
+        return operandIsKilled(instruction - m_codeBlock->instructions().begin(), operand);
+    }
+    
+    template<typename Functor>
+    void forEachOperandKilledAt(unsigned bytecodeIndex, const Functor& functor) const
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(bytecodeIndex < m_codeBlock->instructions().size());
+        m_killSets[bytecodeIndex].forEachLocal(
+            [&] (unsigned local) {
+                functor(virtualRegisterForLocal(local));
+            });
+    }
+    
+    template<typename Functor>
+    void forEachOperandKilledAt(Instruction* pc, const Functor& functor) const
+    {
+        forEachOperandKilledAt(pc - m_codeBlock->instructions().begin(), functor);
+    }
+    
+private:
+    friend class BytecodeLivenessAnalysis;
+
+    class KillSet {
+    public:
+        KillSet()
+            : m_word(0)
+        {
+        }
+
+        ~KillSet()
+        {
+            if (hasVector())
+                delete vector();
+        }
+        
+        void add(unsigned local)
+        {
+            if (isEmpty()) {
+                setOneItem(local);
+                return;
+            }
+            if (hasOneItem()) {
+                ASSERT(oneItem() != local);
+                Vector<unsigned>* vector = new Vector<unsigned>();
+                vector->append(oneItem());
+                vector->append(local);
+                setVector(vector);
+                return;
+            }
+            ASSERT(!vector()->contains(local));
+            vector()->append(local);
+        }
+        
+        template<typename Functor>
+        void forEachLocal(const Functor& functor)
+        {
+            if (isEmpty())
+                return;
+            if (hasOneItem()) {
+                functor(oneItem());
+                return;
+            }
+            for (unsigned local : *vector())
+                functor(local);
+        }
+        
+        bool contains(unsigned expectedLocal)
+        {
+            if (isEmpty())
+                return false;
+            if (hasOneItem())
+                return oneItem() == expectedLocal;
+            for (unsigned local : *vector()) {
+                if (local == expectedLocal)
+                    return true;
+            }
+            return false;
+        }
+        
+    private:
+        bool isEmpty() const
+        {
+            return !m_word;
+        }
+        
+        bool hasOneItem() const
+        {
+            return m_word & 1;
+        }
+        
+        unsigned oneItem() const
+        {
+            return m_word >> 1;
+        }
+        
+        void setOneItem(unsigned value)
+        {
+            m_word = (value << 1) | 1;
+        }
+        
+        bool hasVector() const
+        {
+            return !isEmpty() && !hasOneItem();
+        }
+        
+        Vector<unsigned>* vector()
+        {
+            return bitwise_cast<Vector<unsigned>*>(m_word);
+        }
+        
+        void setVector(Vector<unsigned>* value)
+        {
+            m_word = bitwise_cast<uintptr_t>(value);
+        }
+        
+        uintptr_t m_word;
+    };
+    
+    CodeBlock* m_codeBlock;
+    std::unique_ptr<KillSet[]> m_killSets;
+};
+
+} // namespace JSC
+
+#endif // BytecodeKills_h
+
diff --git a/Source/JavaScriptCore/bytecode/BytecodeList.json b/Source/JavaScriptCore/bytecode/BytecodeList.json
index fed6c46..6b24391 100644
--- a/Source/JavaScriptCore/bytecode/BytecodeList.json
+++ b/Source/JavaScriptCore/bytecode/BytecodeList.json
@@ -7,8 +7,9 @@
             { "name" : "op_create_lexical_environment", "length" : 3 },
             { "name" : "op_get_scope", "length" : 2 },
             { "name" : "op_touch_entry", "length" : 1 },
-            { "name" : "op_init_lazy_reg", "length" : 2 },
-            { "name" : "op_create_arguments", "length" : 3 },
+            { "name" : "op_create_direct_arguments", "length" : 2 },
+            { "name" : "op_create_scoped_arguments", "length" : 3 },
+            { "name" : "op_create_out_of_band_arguments", "length" : 2 },
             { "name" : "op_create_this", "length" : 4 },
             { "name" : "op_to_this", "length" : 4 },
             { "name" : "op_check_tdz", "length" : 2 },
@@ -61,7 +62,6 @@
             { "name" : "op_get_by_id", "length" : 9  },
             { "name" : "op_get_by_id_out_of_line", "length" : 9  },
             { "name" : "op_get_array_length", "length" : 9 },
-            { "name" : "op_get_arguments_length", "length" : 4 },
             { "name" : "op_put_by_id", "length" : 9 },
             { "name" : "op_put_by_id_out_of_line", "length" : 9 },
             { "name" : "op_put_by_id_transition_direct", "length" : 9 },
@@ -70,7 +70,6 @@
             { "name" : "op_put_by_id_transition_normal_out_of_line", "length" : 9 },
             { "name" : "op_del_by_id", "length" : 4 },
             { "name" : "op_get_by_val", "length" : 6 },
-            { "name" : "op_get_argument_by_val", "length" : 7 },
             { "name" : "op_put_by_val", "length" : 5 },
             { "name" : "op_put_by_val_direct", "length" : 5 },
             { "name" : "op_del_by_val", "length" : 4 },
@@ -94,12 +93,11 @@
             { "name" : "op_switch_imm", "length" : 4 },
             { "name" : "op_switch_char", "length" : 4 },
             { "name" : "op_switch_string", "length" : 4 },
-            { "name" : "op_new_func", "length" : 5 },
+            { "name" : "op_new_func", "length" : 4 },
             { "name" : "op_new_func_exp", "length" : 4 },
             { "name" : "op_call", "length" : 9 },
             { "name" : "op_call_eval", "length" : 9 },
             { "name" : "op_call_varargs", "length" : 9 },
-            { "name" : "op_tear_off_arguments", "length" : 3 },
             { "name" : "op_ret", "length" : 2 },
             { "name" : "op_construct", "length" : 9 },
             { "name" : "op_construct_varargs", "length" : 9 },
@@ -108,6 +106,8 @@
             { "name" : "op_resolve_scope", "length" : 7 },
             { "name" : "op_get_from_scope", "length" : 8 },
             { "name" : "op_put_to_scope", "length" : 7 },
+            { "name" : "op_get_from_arguments", "length" : 5 },
+            { "name" : "op_put_to_arguments", "length" : 4 },
             { "name" : "op_push_with_scope", "length" : 3 },
             { "name" : "op_pop_scope", "length" : 2 },
             { "name" : "op_push_name_scope", "length" : 5 },
diff --git a/Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.cpp b/Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.cpp
index 20a71d5..e7dfc94 100644
--- a/Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.cpp
+++ b/Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.cpp
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "BytecodeLivenessAnalysis.h"
 
+#include "BytecodeKills.h"
 #include "BytecodeLivenessAnalysisInlines.h"
 #include "BytecodeUseDef.h"
 #include "CodeBlock.h"
@@ -47,24 +48,7 @@
         return false;
     
     VirtualRegister virtualReg(operand);
-    if (!virtualReg.isLocal())
-        return false;
-    
-    if (codeBlock->captureCount()
-        && operand <= codeBlock->captureStart()
-        && operand > codeBlock->captureEnd())
-        return false;
-    
-    return true;
-}
-
-static unsigned indexForOperand(CodeBlock* codeBlock, int operand)
-{
-    ASSERT(isValidRegisterForLiveness(codeBlock, operand));
-    VirtualRegister virtualReg(operand);
-    if (virtualReg.offset() > codeBlock->captureStart())
-        return virtualReg.toLocal();
-    return virtualReg.toLocal() - codeBlock->captureCount();
+    return virtualReg.isLocal();
 }
 
 static unsigned getLeaderOffsetForBasicBlock(RefPtr<BytecodeBasicBlock>* basicBlock)
@@ -135,14 +119,14 @@
         codeBlock, bytecodeOffset,
         [&] (CodeBlock* codeBlock, Instruction*, OpcodeID, int operand) {
             if (isValidRegisterForLiveness(codeBlock, operand))
-                def(indexForOperand(codeBlock, operand));
+                def(VirtualRegister(operand).toLocal());
         });
-    
+
     computeUsesForBytecodeOffset(
         codeBlock, bytecodeOffset,
         [&] (CodeBlock* codeBlock, Instruction*, OpcodeID, int operand) {
             if (isValidRegisterForLiveness(codeBlock, operand))
-                use(indexForOperand(codeBlock, operand));
+                use(VirtualRegister(operand).toLocal());
         });
         
     // If we have an exception handler, we want the live-in variables of the 
@@ -196,8 +180,7 @@
 void BytecodeLivenessAnalysis::runLivenessFixpoint()
 {
     UnlinkedCodeBlock* unlinkedCodeBlock = m_codeBlock->unlinkedCodeBlock();
-    unsigned numberOfVariables =
-        unlinkedCodeBlock->m_numCalleeRegisters - m_codeBlock->captureCount();
+    unsigned numberOfVariables = unlinkedCodeBlock->m_numCalleeRegisters;
 
     for (unsigned i = 0; i < m_basicBlocks.size(); i++) {
         BytecodeBasicBlock* block = m_basicBlocks[i].get();
@@ -212,7 +195,7 @@
     newOut.resize(m_basicBlocks.last()->out().numBits());
     do {
         changed = false;
-        for (int i = m_basicBlocks.size() - 2; i >= 0; i--) {
+        for (unsigned i = m_basicBlocks.size() - 1; i--;) {
             BytecodeBasicBlock* block = m_basicBlocks[i].get();
             newOut.clearAll();
             for (unsigned j = 0; j < block->successors().size(); j++)
@@ -224,7 +207,7 @@
     } while (changed);
 }
 
-void BytecodeLivenessAnalysis::getLivenessInfoForNonCapturedVarsAtBytecodeOffset(unsigned bytecodeOffset, FastBitVector& result)
+void BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset(unsigned bytecodeOffset, FastBitVector& result)
 {
     BytecodeBasicBlock* block = findBasicBlockForBytecodeOffset(m_basicBlocks, bytecodeOffset);
     ASSERT(block);
@@ -236,57 +219,24 @@
 
 bool BytecodeLivenessAnalysis::operandIsLiveAtBytecodeOffset(int operand, unsigned bytecodeOffset)
 {
-    if (operandIsAlwaysLive(m_codeBlock, operand))
+    if (operandIsAlwaysLive(operand))
         return true;
     FastBitVector result;
-    getLivenessInfoForNonCapturedVarsAtBytecodeOffset(bytecodeOffset, result);
-    return operandThatIsNotAlwaysLiveIsLive(m_codeBlock, result, operand);
-}
-
-FastBitVector getLivenessInfo(CodeBlock* codeBlock, const FastBitVector& out)
-{
-    FastBitVector result;
-
-    unsigned numCapturedVars = codeBlock->captureCount();
-    if (numCapturedVars) {
-        int firstCapturedLocal = VirtualRegister(codeBlock->captureStart()).toLocal();
-        result.resize(out.numBits() + numCapturedVars);
-        for (unsigned i = 0; i < numCapturedVars; ++i)
-            result.set(firstCapturedLocal + i);
-    } else
-        result.resize(out.numBits());
-
-    int outLength = out.numBits();
-    ASSERT(outLength >= 0);
-    for (int i = 0; i < outLength; i++) {
-        if (!out.get(i))
-            continue;
-
-        if (!numCapturedVars) {
-            result.set(i);
-            continue;
-        }
-
-        if (virtualRegisterForLocal(i).offset() > codeBlock->captureStart())
-            result.set(i);
-        else 
-            result.set(numCapturedVars + i);
-    }
-    return result;
+    getLivenessInfoAtBytecodeOffset(bytecodeOffset, result);
+    return operandThatIsNotAlwaysLiveIsLive(result, operand);
 }
 
 FastBitVector BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset(unsigned bytecodeOffset)
 {
     FastBitVector out;
-    getLivenessInfoForNonCapturedVarsAtBytecodeOffset(bytecodeOffset, out);
-    return getLivenessInfo(m_codeBlock, out);
+    getLivenessInfoAtBytecodeOffset(bytecodeOffset, out);
+    return out;
 }
 
 void BytecodeLivenessAnalysis::computeFullLiveness(FullBytecodeLiveness& result)
 {
     FastBitVector out;
     
-    result.m_codeBlock = m_codeBlock;
     result.m_map.clear();
     
     for (unsigned i = m_basicBlocks.size(); i--;) {
@@ -304,6 +254,39 @@
     }
 }
 
+void BytecodeLivenessAnalysis::computeKills(BytecodeKills& result)
+{
+    FastBitVector out;
+    
+    result.m_codeBlock = m_codeBlock;
+    result.m_killSets = std::make_unique<BytecodeKills::KillSet[]>(m_codeBlock->instructions().size());
+    
+    for (unsigned i = m_basicBlocks.size(); i--;) {
+        BytecodeBasicBlock* block = m_basicBlocks[i].get();
+        if (block->isEntryBlock() || block->isExitBlock())
+            continue;
+        
+        out = block->out();
+        
+        for (unsigned i = block->bytecodeOffsets().size(); i--;) {
+            unsigned bytecodeOffset = block->bytecodeOffsets()[i];
+            stepOverInstruction(
+                m_codeBlock, m_basicBlocks, bytecodeOffset,
+                [&] (unsigned index) {
+                    // This is for uses.
+                    if (out.get(index))
+                        return;
+                    result.m_killSets[bytecodeOffset].add(index);
+                    out.set(index);
+                },
+                [&] (unsigned index) {
+                    // This is for defs.
+                    out.clear(index);
+                });
+        }
+    }
+}
+
 void BytecodeLivenessAnalysis::dumpResults()
 {
     Interpreter* interpreter = m_codeBlock->vm()->interpreter;
diff --git a/Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.h b/Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.h
index 3499121..3f42c44 100644
--- a/Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.h
+++ b/Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,6 +33,7 @@
 
 namespace JSC {
 
+class BytecodeKills;
 class CodeBlock;
 class FullBytecodeLiveness;
 
@@ -44,23 +45,22 @@
     FastBitVector getLivenessInfoAtBytecodeOffset(unsigned bytecodeOffset);
     
     void computeFullLiveness(FullBytecodeLiveness& result);
+    void computeKills(BytecodeKills& result);
 
 private:
     void compute();
     void runLivenessFixpoint();
     void dumpResults();
 
-    void getLivenessInfoForNonCapturedVarsAtBytecodeOffset(unsigned bytecodeOffset, FastBitVector&);
+    void getLivenessInfoAtBytecodeOffset(unsigned bytecodeOffset, FastBitVector&);
 
     CodeBlock* m_codeBlock;
     Vector<RefPtr<BytecodeBasicBlock> > m_basicBlocks;
 };
 
-inline bool operandIsAlwaysLive(CodeBlock*, int operand);
-inline bool operandThatIsNotAlwaysLiveIsLive(CodeBlock*, const FastBitVector& out, int operand);
-inline bool operandIsLive(CodeBlock*, const FastBitVector& out, int operand);
-
-FastBitVector getLivenessInfo(CodeBlock*, const FastBitVector& out);
+inline bool operandIsAlwaysLive(int operand);
+inline bool operandThatIsNotAlwaysLiveIsLive(const FastBitVector& out, int operand);
+inline bool operandIsLive(const FastBitVector& out, int operand);
 
 } // namespace JSC
 
diff --git a/Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysisInlines.h b/Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysisInlines.h
index 6587cd2..9b5c755 100644
--- a/Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysisInlines.h
+++ b/Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysisInlines.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,27 +32,22 @@
 
 namespace JSC {
 
-inline bool operandIsAlwaysLive(CodeBlock* codeBlock, int operand)
+inline bool operandIsAlwaysLive(int operand)
 {
-    if (VirtualRegister(operand).isArgument())
-        return true;
-    return operand <= codeBlock->captureStart() && operand > codeBlock->captureEnd();
+    return !VirtualRegister(operand).isLocal();
 }
 
-inline bool operandThatIsNotAlwaysLiveIsLive(CodeBlock* codeBlock, const FastBitVector& out, int operand)
+inline bool operandThatIsNotAlwaysLiveIsLive(const FastBitVector& out, int operand)
 {
-    VirtualRegister virtualReg(operand);
-    if (virtualReg.offset() > codeBlock->captureStart())
-        return out.get(virtualReg.toLocal());
-    size_t index = virtualReg.toLocal() - codeBlock->captureCount();
-    if (index >= out.numBits())
+    unsigned local = VirtualRegister(operand).toLocal();
+    if (local >= out.numBits())
         return false;
-    return out.get(index);
+    return out.get(local);
 }
 
-inline bool operandIsLive(CodeBlock* codeBlock, const FastBitVector& out, int operand)
+inline bool operandIsLive(const FastBitVector& out, int operand)
 {
-    return operandIsAlwaysLive(codeBlock, operand) || operandThatIsNotAlwaysLiveIsLive(codeBlock, out, operand);
+    return operandIsAlwaysLive(operand) || operandThatIsNotAlwaysLiveIsLive(out, operand);
 }
 
 } // namespace JSC
diff --git a/Source/JavaScriptCore/bytecode/BytecodeUseDef.h b/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
index 79c7b7d..85f2915 100644
--- a/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
+++ b/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
@@ -48,11 +48,12 @@
     case op_loop_hint:
     case op_jmp:
     case op_new_object:
-    case op_init_lazy_reg:
     case op_enter:
     case op_catch:
     case op_touch_entry:
     case op_profile_control_flow:
+    case op_create_direct_arguments:
+    case op_create_out_of_band_arguments:
         return;
     case op_get_scope:
     case op_to_this:
@@ -73,8 +74,6 @@
         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
         return;
     }
-    case op_create_arguments:
-    case op_new_func:
     case op_jlesseq:
     case op_jgreater:
     case op_jgreatereq:
@@ -101,7 +100,8 @@
     case op_put_by_id_transition_normal_out_of_line:
     case op_put_by_id_out_of_line:
     case op_put_by_id:
-    case op_put_to_scope: {
+    case op_put_to_scope:
+    case op_put_to_arguments: {
         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
         functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
         return;
@@ -127,7 +127,6 @@
     case op_get_by_id:
     case op_get_by_id_out_of_line:
     case op_get_array_length:
-    case op_get_arguments_length:
     case op_typeof:
     case op_is_undefined:
     case op_is_boolean:
@@ -145,7 +144,10 @@
     case op_new_array_with_size:
     case op_create_this:
     case op_del_by_id:
-    case op_unsigned: {
+    case op_unsigned:
+    case op_new_func:
+    case op_create_scoped_arguments:
+    case op_get_from_arguments: {
         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
         return;
     }
@@ -182,7 +184,6 @@
         return;
     }
     case op_has_structure_property:
-    case op_get_argument_by_val:
     case op_construct_varargs:
     case op_call_varargs: {
         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
@@ -222,12 +223,6 @@
             functor(codeBlock, instruction, opcodeID, lastArg + i);
         return;
     }
-    case op_tear_off_arguments: {
-        functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
-        functor(codeBlock, instruction, opcodeID, unmodifiedArgumentsRegister(VirtualRegister(instruction[1].u.operand)).offset());
-        functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
-        return;
-    }
     default:
         RELEASE_ASSERT_NOT_REACHED();
         break;
@@ -281,10 +276,10 @@
     case op_put_by_val:
     case op_put_by_val_direct:
     case op_put_by_index:
-    case op_tear_off_arguments:
     case op_profile_type:
     case op_profile_control_flow:
     case op_touch_entry:
+    case op_put_to_arguments:
 #define LLINT_HELPER_OPCODES(opcode, length) case opcode:
         FOR_EACH_LLINT_OPCODE_EXTENSION(LLINT_HELPER_OPCODES);
 #undef LLINT_HELPER_OPCODES
@@ -325,8 +320,6 @@
     case op_check_has_instance:
     case op_instanceof:
     case op_get_by_val:
-    case op_get_argument_by_val:
-    case op_get_arguments_length:
     case op_typeof:
     case op_is_undefined:
     case op_is_boolean:
@@ -366,12 +359,14 @@
     case op_new_object:
     case op_to_this:
     case op_check_tdz:
-    case op_init_lazy_reg:
     case op_get_scope:
-    case op_create_arguments:
+    case op_create_direct_arguments:
+    case op_create_scoped_arguments:
+    case op_create_out_of_band_arguments:
     case op_del_by_id:
     case op_del_by_val:
-    case op_unsigned: {
+    case op_unsigned:
+    case op_get_from_arguments: {
         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
         return;
     }
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index 24bd405..8ad71ec 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -569,17 +569,6 @@
         static_cast<unsigned long>(instructions().size()),
         static_cast<unsigned long>(instructions().size() * sizeof(Instruction)),
         m_numParameters, m_numCalleeRegisters, m_numVars);
-    if (symbolTable() && symbolTable()->captureCount()) {
-        out.printf(
-            "; %d captured var(s) (from r%d to r%d, inclusive)",
-            symbolTable()->captureCount(), symbolTable()->captureStart(), symbolTable()->captureEnd() + 1);
-    }
-    if (usesArguments()) {
-        out.printf(
-            "; uses arguments, in r%d, r%d",
-            argumentsRegister().offset(),
-            unmodifiedArgumentsRegister(argumentsRegister()).offset());
-    }
     if (needsActivation() && codeType() == FunctionCode)
         out.printf("; lexical environment in r%d", activationRegister().offset());
     out.printf("\n");
@@ -752,7 +741,7 @@
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             printLocationAndOp(out, exec, location, it, "create_lexical_environment");
-            out.printf("%s %s", registerName(r0).data(), registerName(r1).data());
+            out.printf("%s, %s", registerName(r0).data(), registerName(r1).data());
             break;
         }
         case op_get_scope: {
@@ -760,16 +749,23 @@
             printLocationOpAndRegisterOperand(out, exec, location, it, "get_scope", r0);
             break;
         }
-        case op_create_arguments: {
+        case op_create_direct_arguments: {
             int r0 = (++it)->u.operand;
-            int r1 = (++it)->u.operand;
-            printLocationAndOp(out, exec, location, it, "create_arguments");
-            out.printf("%s %s", registerName(r0).data(), registerName(r1).data());
+            printLocationAndOp(out, exec, location, it, "create_direct_arguments");
+            out.printf("%s", registerName(r0).data());
             break;
         }
-        case op_init_lazy_reg: {
+        case op_create_scoped_arguments: {
             int r0 = (++it)->u.operand;
-            printLocationOpAndRegisterOperand(out, exec, location, it, "init_lazy_reg", r0);
+            int r1 = (++it)->u.operand;
+            printLocationAndOp(out, exec, location, it, "create_scoped_arguments");
+            out.printf("%s, %s", registerName(r0).data(), registerName(r1).data());
+            break;
+        }
+        case op_create_out_of_band_arguments: {
+            int r0 = (++it)->u.operand;
+            printLocationAndOp(out, exec, location, it, "create_out_of_band_arguments");
+            out.printf("%s", registerName(r0).data());
             break;
         }
         case op_create_this: {
@@ -785,8 +781,8 @@
             printLocationOpAndRegisterOperand(out, exec, location, it, "to_this", r0);
             Structure* structure = (++it)->u.structure.get();
             if (structure)
-                out.print(" cache(struct = ", RawPointer(structure), ")");
-            out.print(" ", (++it)->u.toThisStatus);
+                out.print(", cache(struct = ", RawPointer(structure), ")");
+            out.print(", ", (++it)->u.toThisStatus);
             break;
         }
         case op_check_tdz: {
@@ -1041,10 +1037,10 @@
             break;
         }
         case op_init_global_const: {
-            WriteBarrier<Unknown>* registerPointer = (++it)->u.registerPointer;
+            WriteBarrier<Unknown>* variablePointer = (++it)->u.variablePointer;
             int r0 = (++it)->u.operand;
             printLocationAndOp(out, exec, location, it, "init_global_const");
-            out.printf("g%d(%p), %s", m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(r0).data());
+            out.printf("g%d(%p), %s", m_globalObject->findVariableIndex(variablePointer).offset(), variablePointer, registerName(r0).data());
             it++;
             it++;
             break;
@@ -1057,11 +1053,6 @@
             dumpValueProfiling(out, it, hasPrintedProfiling);
             break;
         }
-        case op_get_arguments_length: {
-            printUnaryOp(out, exec, location, it, "get_arguments_length");
-            it++;
-            break;
-        }
         case op_put_by_id: {
             printPutByIdOp(out, exec, location, it, "put_by_id");
             printPutByIdCacheStatus(out, exec, location, stubInfos);
@@ -1119,17 +1110,6 @@
             dumpValueProfiling(out, it, hasPrintedProfiling);
             break;
         }
-        case op_get_argument_by_val: {
-            int r0 = (++it)->u.operand;
-            int r1 = (++it)->u.operand;
-            int r2 = (++it)->u.operand;
-            int r3 = (++it)->u.operand;
-            printLocationAndOp(out, exec, location, it, "get_argument_by_val");
-            out.printf("%s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), registerName(r3).data());
-            ++it;
-            dumpValueProfiling(out, it, hasPrintedProfiling);
-            break;
-        }
         case op_put_by_val: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
@@ -1290,9 +1270,8 @@
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int f0 = (++it)->u.operand;
-            int shouldCheck = (++it)->u.operand;
             printLocationAndOp(out, exec, location, it, "new_func");
-            out.printf("%s, %s, f%d, %s", registerName(r0).data(), registerName(r1).data(), f0, shouldCheck ? "<Checked>" : "<Unchecked>");
+            out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0);
             break;
         }
         case op_new_func_exp: {
@@ -1327,13 +1306,6 @@
             break;
         }
 
-        case op_tear_off_arguments: {
-            int r0 = (++it)->u.operand;
-            int r1 = (++it)->u.operand;
-            printLocationAndOp(out, exec, location, it, "tear_off_arguments");
-            out.printf("%s, %s", registerName(r0).data(), registerName(r1).data());
-            break;
-        }
         case op_ret: {
             int r0 = (++it)->u.operand;
             printLocationOpAndRegisterOperand(out, exec, location, it, "ret", r0);
@@ -1522,12 +1494,14 @@
             ResolveModeAndType modeAndType = ResolveModeAndType((++it)->u.operand);
             ++it; // Structure
             int operand = (++it)->u.operand; // Operand
-            ++it; // Skip value profile.
             printLocationAndOp(out, exec, location, it, "get_from_scope");
-            out.printf("%s, %s, %s, %u<%s|%s>, <structure>, %d",
-                registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data(),
-                modeAndType.operand(), resolveModeName(modeAndType.mode()), resolveTypeName(modeAndType.type()),
-                operand);
+            out.print(registerName(r0), ", ", registerName(r1));
+            if (static_cast<unsigned>(id0) == UINT_MAX)
+                out.print(", anonymous");
+            else
+                out.print(", ", idName(id0, identifier(id0)));
+            out.print(", ", modeAndType.operand(), "<", resolveModeName(modeAndType.mode()), "|", resolveTypeName(modeAndType.type()), ">, ", operand);
+            dumpValueProfiling(out, it, hasPrintedProfiling);
             break;
         }
         case op_put_to_scope: {
@@ -1538,10 +1512,29 @@
             ++it; // Structure
             int operand = (++it)->u.operand; // Operand
             printLocationAndOp(out, exec, location, it, "put_to_scope");
-            out.printf("%s, %s, %s, %u<%s|%s>, <structure>, %d",
-                registerName(r0).data(), idName(id0, identifier(id0)).data(), registerName(r1).data(),
-                modeAndType.operand(), resolveModeName(modeAndType.mode()), resolveTypeName(modeAndType.type()),
-                operand);
+            out.print(registerName(r0));
+            if (static_cast<unsigned>(id0) == UINT_MAX)
+                out.print(", anonymous");
+            else
+                out.print(", ", idName(id0, identifier(id0)));
+            out.print(", ", registerName(r1), ", ", modeAndType.operand(), "<", resolveModeName(modeAndType.mode()), "|", resolveTypeName(modeAndType.type()), ">, <structure>, ", operand);
+            break;
+        }
+        case op_get_from_arguments: {
+            int r0 = (++it)->u.operand;
+            int r1 = (++it)->u.operand;
+            int offset = (++it)->u.operand;
+            printLocationAndOp(out, exec, location, it, "get_from_arguments");
+            out.printf("%s, %s, %d", registerName(r0).data(), registerName(r1).data(), offset);
+            dumpValueProfiling(out, it, hasPrintedProfiling);
+            break;
+        }
+        case op_put_to_arguments: {
+            int r0 = (++it)->u.operand;
+            int offset = (++it)->u.operand;
+            int r1 = (++it)->u.operand;
+            printLocationAndOp(out, exec, location, it, "put_to_arguments");
+            out.printf("%s, %d, %s", registerName(r0).data(), offset, registerName(r1).data());
             break;
         }
         default:
@@ -1639,7 +1632,6 @@
     , m_instructions(other.m_instructions)
     , m_thisRegister(other.m_thisRegister)
     , m_scopeRegister(other.m_scopeRegister)
-    , m_argumentsRegister(other.m_argumentsRegister)
     , m_lexicalEnvironmentRegister(other.m_lexicalEnvironmentRegister)
     , m_isStrictMode(other.m_isStrictMode)
     , m_needsActivation(other.m_needsActivation)
@@ -1702,7 +1694,6 @@
     , m_vm(unlinkedCodeBlock->vm())
     , m_thisRegister(unlinkedCodeBlock->thisRegister())
     , m_scopeRegister(unlinkedCodeBlock->scopeRegister())
-    , m_argumentsRegister(unlinkedCodeBlock->argumentsRegister())
     , m_lexicalEnvironmentRegister(unlinkedCodeBlock->activationRegister())
     , m_isStrictMode(unlinkedCodeBlock->isStrictMode())
     , m_needsActivation(unlinkedCodeBlock->hasActivationRegister() && unlinkedCodeBlock->codeType() == FunctionCode)
@@ -1731,8 +1722,8 @@
             symbolTable->prepareForTypeProfiling(locker);
         }
 
-        if (codeType() == FunctionCode && symbolTable->captureCount()) {
-            m_symbolTable.set(*m_vm, m_ownerExecutable.get(), symbolTable->cloneCapturedNames(*m_vm));
+        if (codeType() == FunctionCode && symbolTable->scopeSize()) {
+            m_symbolTable.set(*m_vm, m_ownerExecutable.get(), symbolTable->cloneScopePart(*m_vm));
             didCloneSymbolTable = true;
         } else
             m_symbolTable.set(*m_vm, m_ownerExecutable.get(), symbolTable);
@@ -1849,8 +1840,7 @@
         }
         case op_call_varargs:
         case op_construct_varargs:
-        case op_get_by_val:
-        case op_get_argument_by_val: {
+        case op_get_by_val: {
             int arrayProfileIndex = pc[opLength - 2].u.operand;
             m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i);
 
@@ -1858,7 +1848,8 @@
             FALLTHROUGH;
         }
         case op_get_direct_pname:
-        case op_get_by_id: {
+        case op_get_by_id:
+        case op_get_from_arguments: {
             ValueProfile* profile = &m_valueProfiles[pc[opLength - 1].u.operand];
             ASSERT(profile->m_bytecodeOffset == -1);
             profile->m_bytecodeOffset = i;
@@ -1928,7 +1919,7 @@
                 break;
 
             instructions[i + 0] = vm()->interpreter->getOpcode(op_init_global_const);
-            instructions[i + 1] = &m_globalObject->registerAt(entry.getIndex());
+            instructions[i + 1] = &m_globalObject->variableAt(entry.varOffset().scopeOffset());
             break;
         }
 
@@ -1953,13 +1944,14 @@
 
             // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
 
-            const Identifier& ident = identifier(pc[3].u.operand);
             ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
             if (modeAndType.type() == LocalClosureVar) {
                 instructions[i + 4] = ResolveModeAndType(modeAndType.mode(), ClosureVar).operand();
                 break;
             }
 
+            const Identifier& ident = identifier(pc[3].u.operand);
+
             ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), needsActivation(), scope, ident, Get, modeAndType.type());
 
             instructions[i + 4].u.operand = ResolveModeAndType(modeAndType.mode(), op.type).operand();
@@ -1974,18 +1966,13 @@
 
         case op_put_to_scope: {
             // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
-            const Identifier& ident = identifier(pc[2].u.operand);
-
             ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
             if (modeAndType.type() == LocalClosureVar) {
-                bool isWatchableVariable = pc[5].u.operand;
-                if (!isWatchableVariable) {
-                    instructions[i + 5].u.watchpointSet = nullptr;
-                    break;
-                }
-                StringImpl* uid = ident.impl();
-                RELEASE_ASSERT(didCloneSymbolTable);
-                if (ident != m_vm->propertyNames->arguments) {
+                // Only do watching if the property we're putting to is not anonymous.
+                if (static_cast<unsigned>(pc[2].u.operand) != UINT_MAX) {
+                    RELEASE_ASSERT(didCloneSymbolTable);
+                    const Identifier& ident = identifier(pc[2].u.operand);
+                    StringImpl* uid = ident.impl();
                     ConcurrentJITLocker locker(m_symbolTable->m_lock);
                     SymbolTable::Map::iterator iter = m_symbolTable->find(locker, uid);
                     ASSERT(iter != m_symbolTable->end(locker));
@@ -1996,6 +1983,8 @@
                 break;
             }
 
+            const Identifier& ident = identifier(pc[2].u.operand);
+
             ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), needsActivation(), scope, ident, Put, modeAndType.type());
 
             instructions[i + 4].u.operand = ResolveModeAndType(modeAndType.mode(), op.type).operand();
@@ -2064,8 +2053,8 @@
             case ProfileTypeBytecodeHasGlobalID: {
                 symbolTable = m_symbolTable.get();
                 ConcurrentJITLocker locker(symbolTable->m_lock);
-                globalVariableID = symbolTable->uniqueIDForRegister(locker, profileRegister.offset(), *vm());
-                globalTypeSet = symbolTable->globalTypeSetForRegister(locker, profileRegister.offset(), *vm());
+                globalVariableID = symbolTable->uniqueIDForOffset(locker, VarOffset(profileRegister), *vm());
+                globalTypeSet = symbolTable->globalTypeSetForOffset(locker, VarOffset(profileRegister), *vm());
                 break;
             }
             case ProfileTypeBytecodeDoesNotHaveGlobalID: 
@@ -2821,63 +2810,6 @@
 }
 #endif
 
-bool CodeBlock::isCaptured(VirtualRegister operand, InlineCallFrame* inlineCallFrame) const
-{
-    if (operand.isArgument())
-        return operand.toArgument() && usesArguments();
-
-    if (inlineCallFrame)
-        return inlineCallFrame->capturedVars.get(operand.toLocal());
-
-    // The lexical environment object isn't in the captured region, but it's "captured"
-    // in the sense that stores to its location can be observed indirectly.
-    if (needsActivation() && operand == activationRegister())
-        return true;
-
-    // Ditto for the arguments object.
-    if (usesArguments() && operand == argumentsRegister())
-        return true;
-    if (usesArguments() && operand == unmodifiedArgumentsRegister(argumentsRegister()))
-        return true;
-
-    // We're in global code so there are no locals to capture
-    if (!symbolTable())
-        return false;
-
-    return symbolTable()->isCaptured(operand.offset());
-}
-
-int CodeBlock::framePointerOffsetToGetActivationRegisters(int machineCaptureStart)
-{
-    // We'll be adding this to the stack pointer to get a registers pointer that looks
-    // like it would have looked in the baseline engine. For example, if bytecode would
-    // have put the first captured variable at offset -5 but we put it at offset -1, then
-    // we'll have an offset of 4.
-    int32_t offset = 0;
-    
-    // Compute where we put the captured variables. This offset will point the registers
-    // pointer directly at the first captured var.
-    offset += machineCaptureStart;
-    
-    // Now compute the offset needed to make the runtime see the captured variables at the
-    // same offset that the bytecode would have used.
-    offset -= symbolTable()->captureStart();
-    
-    return offset;
-}
-
-int CodeBlock::framePointerOffsetToGetActivationRegisters()
-{
-    if (!JITCode::isOptimizingJIT(jitType()))
-        return 0;
-#if ENABLE(DFG_JIT)
-    return framePointerOffsetToGetActivationRegisters(jitCode()->dfgCommon()->machineCaptureStart);
-#else
-    RELEASE_ASSERT_NOT_REACHED();
-    return 0;
-#endif
-}
-
 HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
 {
     RELEASE_ASSERT(bytecodeOffset < instructions().size());
@@ -3062,18 +2994,6 @@
     return ownerExecutable()->newReplacementCodeBlockFor(specializationKind());
 }
 
-const SlowArgument* CodeBlock::machineSlowArguments()
-{
-    if (!JITCode::isOptimizingJIT(jitType()))
-        return symbolTable()->slowArguments();
-    
-#if ENABLE(DFG_JIT)
-    return jitCode()->dfgCommon()->slowArguments.get();
-#else // ENABLE(DFG_JIT)
-    return 0;
-#endif // ENABLE(DFG_JIT)
-}
-
 #if ENABLE(JIT)
 CodeBlock* ProgramCodeBlock::replacement()
 {
@@ -3856,73 +3776,20 @@
     ConcurrentJITLocker locker(symbolTable()->m_lock);
     SymbolTable::Map::iterator end = symbolTable()->end(locker);
     for (SymbolTable::Map::iterator ptr = symbolTable()->begin(locker); ptr != end; ++ptr) {
-        if (ptr->value.getIndex() == virtualRegister.offset()) {
+        if (ptr->value.varOffset() == VarOffset(virtualRegister)) {
             // FIXME: This won't work from the compilation thread.
             // https://bugs.webkit.org/show_bug.cgi?id=115300
             return String(ptr->key);
         }
     }
-    if (needsActivation() && virtualRegister == activationRegister())
-        return ASCIILiteral("lexical environment");
     if (virtualRegister == thisRegister())
         return ASCIILiteral("this");
-    if (usesArguments()) {
-        if (virtualRegister == argumentsRegister())
-            return ASCIILiteral("arguments");
-        if (unmodifiedArgumentsRegister(argumentsRegister()) == virtualRegister)
-            return ASCIILiteral("real arguments");
-    }
     if (virtualRegister.isArgument())
         return String::format("arguments[%3d]", virtualRegister.toArgument());
 
     return "";
 }
 
-namespace {
-
-struct VerifyCapturedDef {
-    void operator()(CodeBlock* codeBlock, Instruction* instruction, OpcodeID opcodeID, int operand) const
-    {
-        unsigned bytecodeOffset = instruction - codeBlock->instructions().begin();
-        
-        if (codeBlock->isConstantRegisterIndex(operand)) {
-            codeBlock->beginValidationDidFail();
-            dataLog("    At bc#", bytecodeOffset, " encountered a definition of a constant.\n");
-            codeBlock->endValidationDidFail();
-            return;
-        }
-
-        switch (opcodeID) {
-        case op_enter:
-        case op_init_lazy_reg:
-        case op_create_arguments:
-            return;
-        default:
-            break;
-        }
-
-        VirtualRegister virtualReg(operand);
-        if (!virtualReg.isLocal())
-            return;
-
-        if (codeBlock->usesArguments() && virtualReg == codeBlock->argumentsRegister())
-            return;
-        if (codeBlock->usesArguments() && virtualReg == unmodifiedArgumentsRegister(codeBlock->argumentsRegister()))
-            return;
-
-        if (codeBlock->captureCount() && codeBlock->symbolTable()->isCaptured(operand)) {
-            codeBlock->beginValidationDidFail();
-            dataLog("    At bc#", bytecodeOffset, " encountered invalid assignment to captured variable ", virtualReg, ".\n");
-            codeBlock->endValidationDidFail();
-            return;
-        }
-        
-        return;
-    }
-};
-
-} // anonymous namespace
-
 void CodeBlock::validate()
 {
     BytecodeLivenessAnalysis liveness(this); // Compute directly from scratch so it doesn't effect CodeBlock footprint.
@@ -3938,38 +3805,15 @@
     }
     
     for (unsigned i = m_numCalleeRegisters; i--;) {
-        bool isCaptured = false;
         VirtualRegister reg = virtualRegisterForLocal(i);
         
-        if (captureCount())
-            isCaptured = reg.offset() <= captureStart() && reg.offset() > captureEnd();
-        
-        if (isCaptured) {
-            if (!liveAtHead.get(i)) {
-                beginValidationDidFail();
-                dataLog("    Variable loc", i, " is expected to be live because it is captured, but it isn't live.\n");
-                dataLog("    Result: ", liveAtHead, "\n");
-                endValidationDidFail();
-            }
-        } else {
-            if (liveAtHead.get(i)) {
-                beginValidationDidFail();
-                dataLog("    Variable loc", i, " is expected to be dead.\n");
-                dataLog("    Result: ", liveAtHead, "\n");
-                endValidationDidFail();
-            }
+        if (liveAtHead.get(i)) {
+            beginValidationDidFail();
+            dataLog("    Variable ", reg, " is expected to be dead.\n");
+            dataLog("    Result: ", liveAtHead, "\n");
+            endValidationDidFail();
         }
     }
-    
-    for (unsigned bytecodeOffset = 0; bytecodeOffset < instructions().size();) {
-        Instruction* currentInstruction = instructions().begin() + bytecodeOffset;
-        OpcodeID opcodeID = m_vm->interpreter->getOpcodeID(currentInstruction->u.opcode);
-        
-        VerifyCapturedDef verifyCapturedDef;
-        computeDefsForBytecodeOffset(this, bytecodeOffset, verifyCapturedDef);
-        
-        bytecodeOffset += opcodeLength(opcodeID);
-    }
 }
 
 void CodeBlock::beginValidationDidFail()
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h
index 5e7a75c..91f7c30 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.h
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.h
@@ -83,8 +83,6 @@
 class RepatchBuffer;
 class TypeLocation;
 
-inline VirtualRegister unmodifiedArgumentsRegister(VirtualRegister argumentsRegister) { return VirtualRegister(argumentsRegister.offset() + 1); }
-
 enum ReoptimizationMode { DontCountReoptimization, CountReoptimization };
 
 class CodeBlock : public ThreadSafeRefCounted<CodeBlock>, public UnconditionalFinalizer, public WeakReferenceHarvester {
@@ -259,11 +257,6 @@
 
     unsigned instructionCount() const { return m_instructions.size(); }
 
-    int argumentIndexAfterCapture(size_t argument);
-    
-    bool hasSlowArguments();
-    const SlowArgument* machineSlowArguments();
-
     // Exactly equivalent to codeBlock->ownerExecutable()->installCode(codeBlock);
     void install();
     
@@ -327,24 +320,6 @@
         return m_scopeRegister;
     }
 
-    void setArgumentsRegister(VirtualRegister argumentsRegister)
-    {
-        ASSERT(argumentsRegister.isValid());
-        m_argumentsRegister = argumentsRegister;
-        ASSERT(usesArguments());
-    }
-    VirtualRegister argumentsRegister() const
-    {
-        ASSERT(usesArguments());
-        return m_argumentsRegister;
-    }
-    VirtualRegister uncheckedArgumentsRegister()
-    {
-        if (!usesArguments())
-            return VirtualRegister();
-        return argumentsRegister();
-    }
-
     void setActivationRegister(VirtualRegister activationRegister)
     {
         m_lexicalEnvironmentRegister = activationRegister;
@@ -361,40 +336,12 @@
         return m_lexicalEnvironmentRegister;
     }
 
-    bool usesArguments() const { return m_argumentsRegister.isValid(); }
-
     bool needsActivation() const
     {
         ASSERT(m_lexicalEnvironmentRegister.isValid() == m_needsActivation);
         return m_needsActivation;
     }
     
-    unsigned captureCount() const
-    {
-        if (!symbolTable())
-            return 0;
-        return symbolTable()->captureCount();
-    }
-    
-    int captureStart() const
-    {
-        if (!symbolTable())
-            return 0;
-        return symbolTable()->captureStart();
-    }
-    
-    int captureEnd() const
-    {
-        if (!symbolTable())
-            return 0;
-        return symbolTable()->captureEnd();
-    }
-    
-    bool isCaptured(VirtualRegister operand, InlineCallFrame* = 0) const;
-    
-    int framePointerOffsetToGetActivationRegisters(int machineCaptureStart);
-    int framePointerOffsetToGetActivationRegisters();
-
     CodeType codeType() const { return m_unlinkedCode->codeType(); }
     PutPropertySlot::Context putByIdContext() const
     {
@@ -1059,7 +1006,6 @@
     WriteBarrier<SymbolTable> m_symbolTable;
     VirtualRegister m_thisRegister;
     VirtualRegister m_scopeRegister;
-    VirtualRegister m_argumentsRegister;
     VirtualRegister m_lexicalEnvironmentRegister;
 
     bool m_isStrictMode;
@@ -1220,24 +1166,6 @@
     return baselineCodeBlock;
 }
 
-inline int CodeBlock::argumentIndexAfterCapture(size_t argument)
-{
-    if (argument >= static_cast<size_t>(symbolTable()->parameterCount()))
-        return CallFrame::argumentOffset(argument);
-    
-    const SlowArgument* slowArguments = symbolTable()->slowArguments();
-    if (!slowArguments || slowArguments[argument].status == SlowArgument::Normal)
-        return CallFrame::argumentOffset(argument);
-    
-    ASSERT(slowArguments[argument].status == SlowArgument::Captured);
-    return slowArguments[argument].index;
-}
-
-inline bool CodeBlock::hasSlowArguments()
-{
-    return !!symbolTable()->slowArguments();
-}
-
 inline Register& ExecState::r(int index)
 {
     CodeBlock* codeBlock = this->codeBlock();
@@ -1262,17 +1190,6 @@
     return uncheckedR(reg.offset());
 }
 
-inline JSValue ExecState::argumentAfterCapture(size_t argument)
-{
-    if (argument >= argumentCount())
-        return jsUndefined();
-    
-    if (!codeBlock())
-        return this[argumentOffset(argument)].jsValue();
-    
-    return this[codeBlock()->argumentIndexAfterCapture(argument)].jsValue();
-}
-
 inline void CodeBlockSet::mark(void* candidateCodeBlock)
 {
     // We have to check for 0 and -1 because those are used by the HashMap as markers.
diff --git a/Source/JavaScriptCore/bytecode/CodeOrigin.h b/Source/JavaScriptCore/bytecode/CodeOrigin.h
index 3a96d67..85ac926 100644
--- a/Source/JavaScriptCore/bytecode/CodeOrigin.h
+++ b/Source/JavaScriptCore/bytecode/CodeOrigin.h
@@ -189,12 +189,10 @@
     WriteBarrier<ScriptExecutable> executable;
     ValueRecovery calleeRecovery;
     CodeOrigin caller;
-    BitVector capturedVars; // Indexed by the machine call frame's variable numbering.
 
     signed stackOffset : 28;
     unsigned kind : 3; // real type is Kind
     bool isClosureCall : 1; // If false then we know that callee/scope are constants and the DFG won't treat them as variables, i.e. they have to be recovered manually.
-    VirtualRegister argumentsRegister; // This is only set if the code uses arguments. The unmodified arguments register follows the unmodifiedArgumentsRegister() convention (see CodeBlock.h).
     VirtualRegister argumentCountRegister; // Only set when we inline a varargs call.
     
     // There is really no good notion of a "default" set of values for
diff --git a/Source/JavaScriptCore/bytecode/DataFormat.h b/Source/JavaScriptCore/bytecode/DataFormat.h
index bb9da4c..6d7542e 100644
--- a/Source/JavaScriptCore/bytecode/DataFormat.h
+++ b/Source/JavaScriptCore/bytecode/DataFormat.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -56,7 +56,6 @@
     
     // Special data formats used only for OSR.
     DataFormatDead = 33, // Implies jsUndefined().
-    DataFormatArguments = 34 // Implies that the arguments object must be reified.
 };
 
 inline const char* dataFormatToString(DataFormat dataFormat)
@@ -90,8 +89,6 @@
         return "JSBoolean";
     case DataFormatDead:
         return "Dead";
-    case DataFormatArguments:
-        return "Arguments";
     default:
         RELEASE_ASSERT_NOT_REACHED();
         return "Unknown";
diff --git a/Source/JavaScriptCore/bytecode/FullBytecodeLiveness.h b/Source/JavaScriptCore/bytecode/FullBytecodeLiveness.h
index d343921..9287b39 100644
--- a/Source/JavaScriptCore/bytecode/FullBytecodeLiveness.h
+++ b/Source/JavaScriptCore/bytecode/FullBytecodeLiveness.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,11 +36,7 @@
 
 class FullBytecodeLiveness {
 public:
-    FullBytecodeLiveness() : m_codeBlock(0) { }
-    
-    // We say "out" to refer to the bitvector that contains raw results for a bytecode
-    // instruction.
-    const FastBitVector& getOut(unsigned bytecodeIndex) const
+    const FastBitVector& getLiveness(unsigned bytecodeIndex) const
     {
         BytecodeToBitmapMap::const_iterator iter = m_map.find(bytecodeIndex);
         ASSERT(iter != m_map.end());
@@ -49,18 +45,12 @@
     
     bool operandIsLive(int operand, unsigned bytecodeIndex) const
     {
-        return operandIsAlwaysLive(m_codeBlock, operand) || operandThatIsNotAlwaysLiveIsLive(m_codeBlock, getOut(bytecodeIndex), operand);
-    }
-    
-    FastBitVector getLiveness(unsigned bytecodeIndex) const
-    {
-        return getLivenessInfo(m_codeBlock, getOut(bytecodeIndex));
+        return operandIsAlwaysLive(operand) || operandThatIsNotAlwaysLiveIsLive(getLiveness(bytecodeIndex), operand);
     }
     
 private:
     friend class BytecodeLivenessAnalysis;
     
-    CodeBlock* m_codeBlock;
     BytecodeToBitmapMap m_map;
 };
 
diff --git a/Source/JavaScriptCore/bytecode/Instruction.h b/Source/JavaScriptCore/bytecode/Instruction.h
index dc5aa43..b973eb4 100644
--- a/Source/JavaScriptCore/bytecode/Instruction.h
+++ b/Source/JavaScriptCore/bytecode/Instruction.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -97,7 +97,7 @@
     Instruction(ArrayProfile* profile) { u.arrayProfile = profile; }
     Instruction(ArrayAllocationProfile* profile) { u.arrayAllocationProfile = profile; }
     Instruction(ObjectAllocationProfile* profile) { u.objectAllocationProfile = profile; }
-    Instruction(WriteBarrier<Unknown>* registerPointer) { u.registerPointer = registerPointer; }
+    Instruction(WriteBarrier<Unknown>* variablePointer) { u.variablePointer = variablePointer; }
     Instruction(Special::Pointer pointer) { u.specialPointer = pointer; }
     Instruction(StringImpl* uid) { u.uid = uid; }
     Instruction(bool* predicatePointer) { u.predicatePointer = predicatePointer; }
@@ -108,7 +108,7 @@
         WriteBarrierBase<Structure> structure;
         WriteBarrierBase<StructureChain> structureChain;
         WriteBarrierBase<JSCell> jsCell;
-        WriteBarrier<Unknown>* registerPointer;
+        WriteBarrier<Unknown>* variablePointer;
         Special::Pointer specialPointer;
         PropertySlot::GetValueFunc getterFunc;
         LLIntCallLinkInfo* callLinkInfo;
diff --git a/Source/JavaScriptCore/bytecode/Operands.h b/Source/JavaScriptCore/bytecode/Operands.h
index 168aad9..9182c1c 100644
--- a/Source/JavaScriptCore/bytecode/Operands.h
+++ b/Source/JavaScriptCore/bytecode/Operands.h
@@ -209,6 +209,10 @@
             return virtualRegisterForArgument(index).offset();
         return virtualRegisterForLocal(index - numberOfArguments()).offset();
     }
+    VirtualRegister virtualRegisterForIndex(size_t index) const
+    {
+        return VirtualRegister(operandForIndex(index));
+    }
     size_t indexForOperand(int operand) const
     {
         if (operandIsArgument(operand))
diff --git a/Source/JavaScriptCore/bytecode/SpeculatedType.cpp b/Source/JavaScriptCore/bytecode/SpeculatedType.cpp
index 48d1ffa..414f95c 100644
--- a/Source/JavaScriptCore/bytecode/SpeculatedType.cpp
+++ b/Source/JavaScriptCore/bytecode/SpeculatedType.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,10 +29,11 @@
 #include "config.h"
 #include "SpeculatedType.h"
 
-#include "Arguments.h"
+#include "DirectArguments.h"
 #include "JSArray.h"
 #include "JSFunction.h"
 #include "JSCInlines.h"
+#include "ScopedArguments.h"
 #include "StringObject.h"
 #include "ValueProfile.h"
 #include <wtf/BoundsCheckedPointer.h>
@@ -127,8 +128,13 @@
             else
                 isTop = false;
     
-            if (value & SpecArguments)
-                myOut.print("Arguments");
+            if (value & SpecDirectArguments)
+                myOut.print("Directarguments");
+            else
+                isTop = false;
+    
+            if (value & SpecScopedArguments)
+                myOut.print("Scopedarguments");
             else
                 isTop = false;
     
@@ -232,8 +238,10 @@
         return "<Float32array>";
     if (isFloat64ArraySpeculation(prediction))
         return "<Float64array>";
-    if (isArgumentsSpeculation(prediction))
-        return "<Arguments>";
+    if (isDirectArgumentsSpeculation(prediction))
+        return "<DirectArguments>";
+    if (isScopedArgumentsSpeculation(prediction))
+        return "<ScopedArguments>";
     if (isStringObjectSpeculation(prediction))
         return "<StringObject>";
     if (isStringOrStringObjectSpeculation(prediction))
@@ -305,8 +313,11 @@
     if (classInfo == JSArray::info())
         return SpecArray;
     
-    if (classInfo == Arguments::info())
-        return SpecArguments;
+    if (classInfo == DirectArguments::info())
+        return SpecDirectArguments;
+    
+    if (classInfo == ScopedArguments::info())
+        return SpecScopedArguments;
     
     if (classInfo == StringObject::info())
         return SpecStringObject;
diff --git a/Source/JavaScriptCore/bytecode/SpeculatedType.h b/Source/JavaScriptCore/bytecode/SpeculatedType.h
index f73c2a4..b60e382 100644
--- a/Source/JavaScriptCore/bytecode/SpeculatedType.h
+++ b/Source/JavaScriptCore/bytecode/SpeculatedType.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -52,8 +52,9 @@
 static const SpeculatedType SpecFloat32Array       = 0x00000400; // It's definitely an Uint16Array or one of its subclasses.
 static const SpeculatedType SpecFloat64Array       = 0x00000800; // It's definitely an Uint16Array or one of its subclasses.
 static const SpeculatedType SpecTypedArrayView     = SpecInt8Array | SpecInt16Array | SpecInt32Array | SpecUint8Array | SpecUint8ClampedArray | SpecUint16Array | SpecUint32Array | SpecFloat32Array | SpecFloat64Array;
-static const SpeculatedType SpecArguments          = 0x00001000; // It's definitely an Arguments object.
-static const SpeculatedType SpecStringObject       = 0x00002000; // It's definitely a StringObject.
+static const SpeculatedType SpecDirectArguments    = 0x00001000; // It's definitely a DirectArguments object.
+static const SpeculatedType SpecScopedArguments    = 0x00002000; // It's definitely a ScopedArguments object.
+static const SpeculatedType SpecStringObject       = 0x00004000; // It's definitely a StringObject.
 static const SpeculatedType SpecObjectOther        = 0x00008000; // It's definitely an object but not JSFinalObject, JSArray, or JSFunction.
 static const SpeculatedType SpecObject             = 0x0000ffff; // Bitmask used for testing for any kind of object prediction.
 static const SpeculatedType SpecStringIdent        = 0x00010000; // It's definitely a JSString, and it's an identifier.
@@ -193,9 +194,14 @@
     return value == SpecFloat64Array;
 }
 
-inline bool isArgumentsSpeculation(SpeculatedType value)
+inline bool isDirectArgumentsSpeculation(SpeculatedType value)
 {
-    return !!value && (value & SpecArguments) == value;
+    return value == SpecDirectArguments;
+}
+
+inline bool isScopedArgumentsSpeculation(SpeculatedType value)
+{
+    return value == SpecScopedArguments;
 }
 
 inline bool isActionableIntMutableArraySpeculation(SpeculatedType value)
@@ -224,13 +230,14 @@
 inline bool isActionableMutableArraySpeculation(SpeculatedType value)
 {
     return isArraySpeculation(value)
-        || isArgumentsSpeculation(value)
         || isActionableTypedMutableArraySpeculation(value);
 }
 
 inline bool isActionableArraySpeculation(SpeculatedType value)
 {
     return isStringSpeculation(value)
+        || isDirectArgumentsSpeculation(value)
+        || isScopedArgumentsSpeculation(value)
         || isActionableMutableArraySpeculation(value);
 }
 
diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
index 748a019..15711e2 100644
--- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2012, 2013, 2015 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -209,7 +209,6 @@
     , m_numCalleeRegisters(0)
     , m_numParameters(0)
     , m_vm(vm)
-    , m_argumentsRegister(VirtualRegister())
     , m_globalObjectRegister(VirtualRegister())
     , m_needsFullScopeChain(info.needsActivation())
     , m_usesEval(info.usesEval())
diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
index d8ea6f6..0aa83dc 100644
--- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
+++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -287,11 +287,6 @@
     void setScopeRegister(VirtualRegister scopeRegister) { m_scopeRegister = scopeRegister; }
     void setActivationRegister(VirtualRegister activationRegister) { m_lexicalEnvironmentRegister = activationRegister; }
 
-    void setArgumentsRegister(VirtualRegister argumentsRegister) { m_argumentsRegister = argumentsRegister; }
-    bool usesArguments() const { return m_argumentsRegister.isValid(); }
-    VirtualRegister argumentsRegister() const { return m_argumentsRegister; }
-
-
     bool usesGlobalObject() const { return m_globalObjectRegister.isValid(); }
     void setGlobalObjectRegister(VirtualRegister globalObjectRegister) { m_globalObjectRegister = globalObjectRegister; }
     VirtualRegister globalObjectRegister() const { return m_globalObjectRegister; }
@@ -531,7 +526,6 @@
     VM* m_vm;
 
     VirtualRegister m_thisRegister;
-    VirtualRegister m_argumentsRegister;
     VirtualRegister m_scopeRegister;
     VirtualRegister m_lexicalEnvironmentRegister;
     VirtualRegister m_globalObjectRegister;
diff --git a/Source/JavaScriptCore/bytecode/ValueRecovery.cpp b/Source/JavaScriptCore/bytecode/ValueRecovery.cpp
index 29aa56f..996fd3b 100644
--- a/Source/JavaScriptCore/bytecode/ValueRecovery.cpp
+++ b/Source/JavaScriptCore/bytecode/ValueRecovery.cpp
@@ -112,8 +112,11 @@
     case BooleanDisplacedInJSStack:
         out.print("*bool(", virtualRegister(), ")");
         return;
-    case ArgumentsThatWereNotCreated:
-        out.printf("arguments");
+    case DirectArgumentsThatWereNotCreated:
+        out.print("DirectArguments(", nodeID(), ")");
+        return;
+    case ClonedArgumentsThatWereNotCreated:
+        out.print("ClonedArguments(", nodeID(), ")");
         return;
     case Constant:
         out.print("[", inContext(constant(), context), "]");
diff --git a/Source/JavaScriptCore/bytecode/ValueRecovery.h b/Source/JavaScriptCore/bytecode/ValueRecovery.h
index c30b97a..42651e2 100644
--- a/Source/JavaScriptCore/bytecode/ValueRecovery.h
+++ b/Source/JavaScriptCore/bytecode/ValueRecovery.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,6 +26,7 @@
 #ifndef ValueRecovery_h
 #define ValueRecovery_h
 
+#include "DFGMinifiedID.h"
 #include "DataFormat.h"
 #if ENABLE(JIT)
 #include "GPRInfo.h"
@@ -38,6 +39,7 @@
 namespace JSC {
 
 struct DumpContext;
+struct InlineCallFrame;
 
 // Describes how to recover a given bytecode virtual register at a given
 // code point.
@@ -62,8 +64,9 @@
     DoubleDisplacedInJSStack,
     CellDisplacedInJSStack,
     BooleanDisplacedInJSStack,
-    // It's an Arguments object.
-    ArgumentsThatWereNotCreated,
+    // It's an Arguments object. This arises because of the simplified arguments simplification done by the DFG.
+    DirectArgumentsThatWereNotCreated,
+    ClonedArgumentsThatWereNotCreated,
     // It's a constant.
     Constant,
     // Don't know how to recover it.
@@ -167,10 +170,19 @@
         return result;
     }
     
-    static ValueRecovery argumentsThatWereNotCreated()
+    static ValueRecovery directArgumentsThatWereNotCreated(DFG::MinifiedID id)
     {
         ValueRecovery result;
-        result.m_technique = ArgumentsThatWereNotCreated;
+        result.m_technique = DirectArgumentsThatWereNotCreated;
+        result.m_source.nodeID = id.bits();
+        return result;
+    }
+    
+    static ValueRecovery outOfBandArgumentsThatWereNotCreated(DFG::MinifiedID id)
+    {
+        ValueRecovery result;
+        result.m_technique = ClonedArgumentsThatWereNotCreated;
+        result.m_source.nodeID = id.bits();
         return result;
     }
     
@@ -256,6 +268,12 @@
         return JSValue::decode(m_source.constant);
     }
     
+    DFG::MinifiedID nodeID() const
+    {
+        ASSERT(m_technique == DirectArgumentsThatWereNotCreated || m_technique == ClonedArgumentsThatWereNotCreated);
+        return DFG::MinifiedID::fromBits(m_source.nodeID);
+    }
+    
     JSValue recover(ExecState*) const;
     
 #if ENABLE(JIT)
@@ -276,6 +294,7 @@
 #endif
         int virtualReg;
         EncodedJSValue constant;
+        uintptr_t nodeID;
     } m_source;
 };
 
diff --git a/Source/JavaScriptCore/bytecode/VirtualRegister.h b/Source/JavaScriptCore/bytecode/VirtualRegister.h
index 6f37b25..07504a3 100644
--- a/Source/JavaScriptCore/bytecode/VirtualRegister.h
+++ b/Source/JavaScriptCore/bytecode/VirtualRegister.h
@@ -67,8 +67,12 @@
     int offset() const { return m_virtualRegister; }
     int offsetInBytes() const { return m_virtualRegister * sizeof(Register); }
 
-    bool operator==(const VirtualRegister other) const { return m_virtualRegister == other.m_virtualRegister; }
-    bool operator!=(const VirtualRegister other) const { return m_virtualRegister != other.m_virtualRegister; }
+    bool operator==(VirtualRegister other) const { return m_virtualRegister == other.m_virtualRegister; }
+    bool operator!=(VirtualRegister other) const { return m_virtualRegister != other.m_virtualRegister; }
+    bool operator<(VirtualRegister other) const { return m_virtualRegister < other.m_virtualRegister; }
+    bool operator>(VirtualRegister other) const { return m_virtualRegister > other.m_virtualRegister; }
+    bool operator<=(VirtualRegister other) const { return m_virtualRegister <= other.m_virtualRegister; }
+    bool operator>=(VirtualRegister other) const { return m_virtualRegister >= other.m_virtualRegister; }
     
     VirtualRegister operator+(int value) const
     {
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index e68e162..ac5e37e 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -64,6 +64,20 @@
     SamplingRegion samplingRegion("Bytecode Generation");
     
     m_codeBlock->setThisRegister(m_thisRegister.virtualRegister());
+    
+    // If we have declared a variable named "arguments" and we are using arguments then we should
+    // perform that assignment now.
+    if (m_needToInitializeArguments)
+        initializeVariable(variable(propertyNames().arguments), m_argumentsRegister);
+    
+    {
+        RefPtr<RegisterID> temp = newTemporary();
+        for (FunctionBodyNode* functionBody : m_functionsToInitialize) {
+            emitNewFunction(temp.get(), functionBody);
+            initializeVariable(variable(functionBody->ident()), temp.get());
+        }
+    }
+    
     for (size_t i = 0; i < m_deconstructedParameters.size(); i++) {
         auto& entry = m_deconstructedParameters[i];
         entry.second->bindValue(*this, entry.first.get());
@@ -119,38 +133,13 @@
     m_codeBlock->shrinkToFit();
 
     if (m_codeBlock->symbolTable() && !m_codeBlock->vm()->typeProfiler())
-        m_codeBlock->setSymbolTable(m_codeBlock->symbolTable()->cloneCapturedNames(*m_codeBlock->vm()));
+        m_codeBlock->setSymbolTable(m_codeBlock->symbolTable()->cloneScopePart(*m_codeBlock->vm()));
 
     if (m_expressionTooDeep)
         return ParserError(ParserError::OutOfMemory);
     return ParserError(ParserError::ErrorNone);
 }
 
-RegisterID* BytecodeGenerator::addVar(
-    const Identifier& ident, ConstantMode constantMode, WatchMode watchMode)
-{
-    ASSERT(static_cast<size_t>(m_codeBlock->m_numVars) == m_calleeRegisters.size());
-    
-    ConcurrentJITLocker locker(symbolTable().m_lock);
-    int index = virtualRegisterForLocal(m_calleeRegisters.size()).offset();
-    SymbolTableEntry newEntry(index, constantMode == IsConstant ? ReadOnly : 0);
-    SymbolTable::Map::AddResult result = symbolTable().add(locker, ident.impl(), newEntry);
-
-    if (!result.isNewEntry)
-        return &registerFor(result.iterator->value.getIndex());
-    
-    if (watchMode == IsWatchable) {
-        while (m_watchableVariables.size() < static_cast<size_t>(m_codeBlock->m_numVars))
-            m_watchableVariables.append(Identifier());
-        m_watchableVariables.append(ident);
-    }
-    
-    RegisterID* regID = addVar();
-    ASSERT(watchMode == NotWatchable || static_cast<size_t>(m_codeBlock->m_numVars) == m_watchableVariables.size());
-    
-    return regID;
-}
-
 BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
     : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
     , m_shouldEmitProfileHooks(Options::forceProfilerBytecodeGeneration() || profilerMode == ProfilerOn)
@@ -192,7 +181,7 @@
 {
     if (m_isBuiltinFunction)
         m_shouldEmitDebugHooks = false;
-
+    
     m_symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode());
     Vector<Identifier> boundParameterProperties;
     FunctionParameters& parameters = *functionNode->parameters();
@@ -203,12 +192,35 @@
         pattern->collectBoundIdentifiers(boundParameterProperties);
         continue;
     }
-    m_symbolTable->setParameterCountIncludingThis(functionNode->parameters()->size() + 1);
+
+    bool shouldCaptureSomeOfTheThings = m_shouldEmitDebugHooks || m_codeBlock->needsFullScopeChain();
+    bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
+    bool needsArguments = functionNode->usesArguments() || codeBlock->usesEval();
+    
+    auto captures = [&] (StringImpl* uid) -> bool {
+        if (shouldCaptureAllOfTheThings)
+            return true;
+        if (!shouldCaptureSomeOfTheThings)
+            return false;
+        if (needsArguments && uid == propertyNames().arguments.impl()) {
+            // Actually, we only need to capture the arguments object when we "need full activation"
+            // because of name scopes. But historically we did it this way, so for now we just preserve
+            // the old behavior.
+            // FIXME: https://bugs.webkit.org/show_bug.cgi?id=143072
+            return true;
+        }
+        return functionNode->captures(uid);
+    };
+    auto varKind = [&] (StringImpl* uid) -> VarKind {
+        return captures(uid) ? VarKind::Scope : VarKind::Stack;
+    };
 
     emitOpcode(op_enter);
 
     allocateAndEmitScope();
     
+    m_calleeRegister.setIndex(JSStack::Callee);
+    
     if (functionNameIsInScope(functionNode->ident(), functionNode->functionMode())
         && functionNameScopeIsDynamic(codeBlock->usesEval(), codeBlock->isStrictMode())) {
         // When we do this, we should make our local scope stack know about the function name symbol
@@ -217,191 +229,245 @@
         // Also, we could create the scope once per JSFunction instance that needs it. That wouldn't
         // be any more correct, but it would be more performant.
         // FIXME: https://bugs.webkit.org/show_bug.cgi?id=141887
-        RegisterID calleeRegister;
-        calleeRegister.setIndex(JSStack::Callee);
-        emitPushFunctionNameScope(m_scopeRegister, functionNode->ident(), &calleeRegister, ReadOnly | DontDelete);
+        emitPushFunctionNameScope(m_scopeRegister, functionNode->ident(), &m_calleeRegister, ReadOnly | DontDelete);
     }
 
-    if (m_codeBlock->needsFullScopeChain() || m_shouldEmitDebugHooks) {
+    if (shouldCaptureSomeOfTheThings) {
         m_lexicalEnvironmentRegister = addVar();
         m_codeBlock->setActivationRegister(m_lexicalEnvironmentRegister->virtualRegister());
         emitOpcode(op_create_lexical_environment);
         instructions().append(m_lexicalEnvironmentRegister->index());
         instructions().append(scopeRegister()->index());
+        emitOpcode(op_mov);
+        instructions().append(scopeRegister()->index());
+        instructions().append(m_lexicalEnvironmentRegister->index());
     }
-    RegisterID* localArgumentsRegister = nullptr;
-    RegisterID* scratch = addVar();
-    m_symbolTable->setCaptureStart(virtualRegisterForLocal(m_codeBlock->m_numVars).offset());
-
-    if (functionNode->usesArguments() || codeBlock->usesEval()) { // May reify arguments object.
-        RegisterID* unmodifiedArgumentsRegister = addVar(); // Anonymous, so it can't be modified by user code.
-        RegisterID* argumentsRegister = addVar(propertyNames().arguments, IsVariable, NotWatchable); // Can be changed by assigning to 'arguments'.
-
-        localArgumentsRegister = argumentsRegister;
-
-        // We can save a little space by hard-coding the knowledge that the two
-        // 'arguments' values are stored in consecutive registers, and storing
-        // only the index of the assignable one.
-        codeBlock->setArgumentsRegister(argumentsRegister->virtualRegister());
-        ASSERT_UNUSED(unmodifiedArgumentsRegister, unmodifiedArgumentsRegister->virtualRegister() == JSC::unmodifiedArgumentsRegister(codeBlock->argumentsRegister()));
-
-        emitInitLazyRegister(argumentsRegister);
-        emitInitLazyRegister(unmodifiedArgumentsRegister);
-        
-        if (shouldCreateArgumentsEagerly() || shouldTearOffArgumentsEagerly()) {
-            emitOpcode(op_create_arguments);
-            instructions().append(argumentsRegister->index());
-            instructions().append(m_codeBlock->activationRegister().offset());
-
-            if (m_codeBlock->hasActivationRegister()) {
-                RegisterID* argumentsRegister = &registerFor(m_codeBlock->argumentsRegister().offset());
-                initializeCapturedVariable(argumentsRegister, propertyNames().arguments, argumentsRegister);
-                RegisterID* uncheckedArgumentsRegister = &registerFor(JSC::unmodifiedArgumentsRegister(m_codeBlock->argumentsRegister()).offset());
-                initializeCapturedVariable(uncheckedArgumentsRegister, propertyNames().arguments, uncheckedArgumentsRegister);
-                if (functionNode->modifiesArguments()) {
-                    emitOpcode(op_mov);
-                    instructions().append(argumentsRegister->index());
-                    instructions().append(addConstantValue(jsUndefined())->index());
-                    emitOpcode(op_mov);
-                    instructions().append(uncheckedArgumentsRegister->index());
-                    instructions().append(addConstantValue(jsUndefined())->index());
-                    localArgumentsRegister = nullptr;
-                }
-            }
-        }
+    
+    // Make sure the code block knows about all of our parameters, and make sure that parameters
+    // needing deconstruction are noted.
+    m_parameters.grow(parameters.size() + 1); // reserve space for "this"
+    m_thisRegister.setIndex(initializeNextParameter()->index()); // this
+    for (unsigned i = 0; i < parameters.size(); ++i) {
+        auto pattern = parameters.at(i);
+        RegisterID* reg = initializeNextParameter();
+        if (!pattern->isBindingNode())
+            m_deconstructedParameters.append(std::make_pair(reg, pattern));
     }
-
-    bool shouldCaptureAllTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
-
+    
+    // Figure out some interesting facts about our arguments.
     bool capturesAnyArgumentByName = false;
-    Vector<RegisterID*, 0, UnsafeVectorOverflow> capturedArguments;
-    if (functionNode->hasCapturedVariables() || shouldCaptureAllTheThings) {
+    if (functionNode->hasCapturedVariables()) {
         FunctionParameters& parameters = *functionNode->parameters();
-        capturedArguments.resize(parameters.size());
         for (size_t i = 0; i < parameters.size(); ++i) {
-            capturedArguments[i] = 0;
             auto pattern = parameters.at(i);
             if (!pattern->isBindingNode())
                 continue;
             const Identifier& ident = static_cast<const BindingNode*>(pattern)->boundProperty();
-            if (!functionNode->captures(ident) && !shouldCaptureAllTheThings)
-                continue;
-            capturesAnyArgumentByName = true;
-            capturedArguments[i] = addVar(ident, IsVariable, IsWatchable);
+            capturesAnyArgumentByName |= captures(ident.impl());
         }
     }
 
-    if (capturesAnyArgumentByName && !shouldTearOffArgumentsEagerly()) {
-        size_t parameterCount = m_symbolTable->parameterCount();
-        auto slowArguments = std::make_unique<SlowArgument[]>(parameterCount);
-        for (size_t i = 0; i < parameterCount; ++i) {
-            if (!capturedArguments[i]) {
-                ASSERT(slowArguments[i].status == SlowArgument::Normal);
-                slowArguments[i].index = CallFrame::argumentOffset(i);
-                continue;
-            }
-            slowArguments[i].status = SlowArgument::Captured;
-            slowArguments[i].index = capturedArguments[i]->index();
-        }
-        m_symbolTable->setSlowArguments(WTF::move(slowArguments));
-    }
-
-    RegisterID* calleeRegister = resolveCallee(functionNode); // May push to the scope chain and/or add a captured var.
-
-    const DeclarationStacks::FunctionStack& functionStack = functionNode->functionStack();
-    const DeclarationStacks::VarStack& varStack = functionNode->varStack();
-    IdentifierSet test;
-
-    // Captured variables and functions go first so that activations don't have
-    // to step over the non-captured locals to mark them.
-    if (functionNode->hasCapturedVariables() || shouldCaptureAllTheThings) {
-        for (size_t i = 0; i < boundParameterProperties.size(); i++) {
-            const Identifier& ident = boundParameterProperties[i];
-            if (functionNode->captures(ident) || shouldCaptureAllTheThings)
-                addVar(ident, IsVariable, IsWatchable);
-        }
-        for (size_t i = 0; i < functionStack.size(); ++i) {
-            FunctionBodyNode* function = functionStack[i];
-            const Identifier& ident = function->ident();
-            if (functionNode->captures(ident) || shouldCaptureAllTheThings) {
-                m_functions.add(ident.impl());
-                emitNewFunction(scratch, function);
-                initializeCapturedVariable(addVar(ident, IsVariable, IsWatchable), ident, scratch);
-            }
-        }
-        for (size_t i = 0; i < varStack.size(); ++i) {
-            const Identifier& ident = varStack[i].first;
-            if (functionNode->captures(ident) || shouldCaptureAllTheThings)
-                addVar(ident, (varStack[i].second & DeclarationStacks::IsConstant) ? IsConstant : IsVariable, IsWatchable);
-        }
-    }
-
-    m_symbolTable->setCaptureEnd(virtualRegisterForLocal(codeBlock->m_numVars).offset());
-
-    bool canLazilyCreateFunctions = !functionNode->needsActivationForMoreThanVariables() && !m_shouldEmitDebugHooks && !m_vm->typeProfiler() && !m_vm->controlFlowProfiler();
-    m_firstLazyFunction = codeBlock->m_numVars;
-    if (!shouldCaptureAllTheThings) {
-        for (size_t i = 0; i < functionStack.size(); ++i) {
-            FunctionBodyNode* function = functionStack[i];
-            const Identifier& ident = function->ident();
-            if (!functionNode->captures(ident)) {
-                m_functions.add(ident.impl());
-                RefPtr<RegisterID> reg = addVar(ident, IsVariable, NotWatchable);
-                // Don't lazily create functions that override the name 'arguments'
-                // as this would complicate lazy instantiation of actual arguments.
-                if (!canLazilyCreateFunctions || ident == propertyNames().arguments)
-                    emitNewFunction(reg.get(), function);
-                else {
-                    emitInitLazyRegister(reg.get());
-                    m_lazyFunctions.set(reg->virtualRegister().toLocal(), function);
-                }
-            }
-        }
-        m_lastLazyFunction = canLazilyCreateFunctions ? codeBlock->m_numVars : m_firstLazyFunction;
-        for (size_t i = 0; i < boundParameterProperties.size(); i++) {
-            const Identifier& ident = boundParameterProperties[i];
-            if (!functionNode->captures(ident))
-                addVar(ident, IsVariable, IsWatchable);
-        }
-        for (size_t i = 0; i < varStack.size(); ++i) {
-            const Identifier& ident = varStack[i].first;
-            if (!functionNode->captures(ident))
-                addVar(ident, (varStack[i].second & DeclarationStacks::IsConstant) ? IsConstant : IsVariable, NotWatchable);
-        }
-    }
-
-    if (m_symbolTable->captureCount())
-        emitOpcode(op_touch_entry);
+    if (capturesAnyArgumentByName)
+        ASSERT(m_lexicalEnvironmentRegister);
     
-    m_parameters.grow(parameters.size() + 1); // reserve space for "this"
-
-    // Add "this" as a parameter
-    int nextParameterIndex = CallFrame::thisArgumentOffset();
-    m_thisRegister.setIndex(nextParameterIndex++);
-    m_codeBlock->addParameter();
-
-    for (size_t i = 0; i < parameters.size(); ++i, ++nextParameterIndex) {
-        int index = nextParameterIndex;
-        auto pattern = parameters.at(i);
-        if (!pattern->isBindingNode()) {
-            m_codeBlock->addParameter();
-            RegisterID& parameter = registerFor(index);
-            parameter.setIndex(index);
-            m_deconstructedParameters.append(std::make_pair(&parameter, pattern));
-            continue;
-        }
-        auto simpleParameter = static_cast<const BindingNode*>(pattern);
-        if (capturedArguments.size() && capturedArguments[i] && !m_functions.contains(simpleParameter->boundProperty().impl())) {
-            ASSERT((functionNode->hasCapturedVariables() && functionNode->captures(simpleParameter->boundProperty())) || shouldCaptureAllTheThings);
-            index = capturedArguments[i]->index();
-            RegisterID original(nextParameterIndex);
-            initializeCapturedVariable(capturedArguments[i], simpleParameter->boundProperty(), &original);
-        }
-        addParameter(simpleParameter->boundProperty(), index);
+    // Need to know what our functions are called. Parameters have some goofy behaviors when it
+    // comes to functions of the same name.
+    for (FunctionBodyNode* function : functionNode->functionStack())
+        m_functions.add(function->ident().impl());
+    
+    if (needsArguments) {
+        // Create the arguments object now. We may put the arguments object into the activation if
+        // it is captured. Either way, we create two arguments object variables: one is our
+        // private variable that is immutable, and another that is the user-visible variable. The
+        // immutable one is only used here, or during formal parameter resolutions if we opt for
+        // DirectArguments.
+        
+        m_argumentsRegister = addVar();
+        m_argumentsRegister->ref();
     }
-
-    // We declare the callee's name last because it should lose to a var, function, and/or parameter declaration.
-    addCallee(functionNode, calleeRegister);
+    
+    if (needsArguments && !codeBlock->isStrictMode()) {
+        // If we captured any formal parameter by name, then we use ScopedArguments. Otherwise we
+        // use DirectArguments. With ScopedArguments, we lift all of our arguments into the
+        // activation.
+        
+        if (capturesAnyArgumentByName) {
+            m_symbolTable->setArgumentsLength(vm, parameters.size());
+            
+            // For each parameter, we have two possibilities:
+            // Either it's a binding node with no function overlap, in which case it gets a name
+            // in the symbol table - or it just gets space reserved in the symbol table. Either
+            // way we lift the value into the scope.
+            for (unsigned i = 0; i < parameters.size(); ++i) {
+                ScopeOffset offset = m_symbolTable->takeNextScopeOffset();
+                m_symbolTable->setArgumentOffset(vm, i, offset);
+                if (StringImpl* name = visibleNameForParameter(parameters.at(i))) {
+                    VarOffset varOffset(offset);
+                    SymbolTableEntry entry(varOffset);
+                    // Stores to these variables via the ScopedArguments object will not do
+                    // notifyWrite(), since that would be cumbersome. Also, watching formal
+                    // parameters when "arguments" is in play is unlikely to be super profitable.
+                    // So, we just disable it.
+                    entry.disableWatching();
+                    m_symbolTable->set(name, entry);
+                }
+                emitOpcode(op_put_to_scope);
+                instructions().append(m_lexicalEnvironmentRegister->index());
+                instructions().append(UINT_MAX);
+                instructions().append(virtualRegisterForArgument(1 + i).offset());
+                instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
+                instructions().append(0);
+                instructions().append(offset.offset());
+            }
+            
+            // This creates a scoped arguments object and copies the overflow arguments into the
+            // scope. It's the equivalent of calling ScopedArguments::createByCopying().
+            emitOpcode(op_create_scoped_arguments);
+            instructions().append(m_argumentsRegister->index());
+            instructions().append(m_lexicalEnvironmentRegister->index());
+        } else {
+            // We're going to put all parameters into the DirectArguments object. First ensure
+            // that the symbol table knows that this is happening.
+            for (unsigned i = 0; i < parameters.size(); ++i) {
+                if (StringImpl* name = visibleNameForParameter(parameters.at(i)))
+                    m_symbolTable->set(name, SymbolTableEntry(VarOffset(DirectArgumentsOffset(i))));
+            }
+            
+            emitOpcode(op_create_direct_arguments);
+            instructions().append(m_argumentsRegister->index());
+        }
+    } else {
+        // Create the formal parameters the normal way. Any of them could be captured, or not. If
+        // captured, lift them into the scope.
+        for (unsigned i = 0; i < parameters.size(); ++i) {
+            StringImpl* name = visibleNameForParameter(parameters.at(i));
+            if (!name)
+                continue;
+            
+            if (!captures(name)) {
+                // This is the easy case - just tell the symbol table about the argument. It will
+                // be accessed directly.
+                m_symbolTable->set(name, SymbolTableEntry(VarOffset(virtualRegisterForArgument(1 + i))));
+                continue;
+            }
+            
+            ScopeOffset offset = m_symbolTable->takeNextScopeOffset();
+            const Identifier& ident =
+                static_cast<const BindingNode*>(parameters.at(i))->boundProperty();
+            m_symbolTable->set(name, SymbolTableEntry(VarOffset(offset)));
+            
+            emitOpcode(op_put_to_scope);
+            instructions().append(m_lexicalEnvironmentRegister->index());
+            instructions().append(addConstant(ident));
+            instructions().append(virtualRegisterForArgument(1 + i).offset());
+            instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
+            instructions().append(0);
+            instructions().append(offset.offset());
+        }
+    }
+    
+    if (needsArguments && codeBlock->isStrictMode()) {
+        // Allocate an out-of-bands arguments object.
+        emitOpcode(op_create_out_of_band_arguments);
+        instructions().append(m_argumentsRegister->index());
+    }
+    
+    // Now declare all variables.
+    for (const Identifier& ident : boundParameterProperties)
+        createVariable(ident, varKind(ident.impl()), IsVariable);
+    for (FunctionBodyNode* function : functionNode->functionStack()) {
+        const Identifier& ident = function->ident();
+        createVariable(ident, varKind(ident.impl()), IsVariable);
+        m_functionsToInitialize.append(function);
+    }
+    for (auto& entry : functionNode->varStack()) {
+        ConstantMode constantMode = modeForIsConstant(entry.second & DeclarationStacks::IsConstant);
+        // Variables named "arguments" are never const.
+        if (entry.first == propertyNames().arguments)
+            constantMode = IsVariable;
+        createVariable(entry.first, varKind(entry.first.impl()), constantMode, IgnoreExisting);
+    }
+    
+    // There are some variables that need to be preinitialized to something other than Undefined:
+    //
+    // - "arguments": unless it's used as a function or parameter, this should refer to the
+    //   arguments object.
+    //
+    // - callee: unless it's used as a var, function, or parameter, this should refer to the
+    //   callee (i.e. our function).
+    //
+    // - functions: these always override everything else.
+    //
+    // The most logical way to do all of this is to initialize none of the variables until now,
+    // and then initialize them in BytecodeGenerator::generate() in such an order that the rules
+    // for how these things override each other end up holding. We would initialize the callee
+    // first, then "arguments", then all arguments, then the functions.
+    //
+    // But some arguments are already initialized by default, since if they aren't captured and we
+    // don't have "arguments" then we just point the symbol table at the stack slot of those
+    // arguments. We end up initializing the rest of the arguments that have an uncomplicated
+    // binding (i.e. don't involve deconstruction) above when figuring out how to lay them out,
+    // because that's just the simplest thing. This means that when we initialize them, we have to
+    // watch out for the things that override arguments (namely, functions).
+    //
+    // We also initialize callee here as well, just because it's so weird. We know whether we want
+    // to do this because we can just check if it's in the symbol table.
+    if (functionNameIsInScope(functionNode->ident(), functionNode->functionMode())
+        && !functionNameScopeIsDynamic(codeBlock->usesEval(), codeBlock->isStrictMode())
+        && m_symbolTable->get(functionNode->ident().impl()).isNull()) {
+        if (captures(functionNode->ident().impl())) {
+            ScopeOffset offset;
+            {
+                ConcurrentJITLocker locker(m_symbolTable->m_lock);
+                offset = m_symbolTable->takeNextScopeOffset(locker);
+                m_symbolTable->add(
+                    locker, functionNode->ident().impl(),
+                    SymbolTableEntry(VarOffset(offset), ReadOnly));
+            }
+            
+            emitOpcode(op_put_to_scope);
+            instructions().append(m_lexicalEnvironmentRegister->index());
+            instructions().append(addConstant(functionNode->ident()));
+            instructions().append(m_calleeRegister.index());
+            instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
+            instructions().append(0);
+            instructions().append(offset.offset());
+        } else {
+            m_symbolTable->add(
+                functionNode->ident().impl(),
+                SymbolTableEntry(VarOffset(m_calleeRegister.virtualRegister()), ReadOnly));
+        }
+    }
+    
+    // This is our final act of weirdness. "arguments" is overridden by everything except the
+    // callee. We add it to the symbol table if it's not already there and it's not an argument.
+    if (needsArguments) {
+        // If "arguments" is overridden by a function or deconstructed parameter name, then it's
+        // OK for us to call createVariable() because it won't change anything. It's also OK for
+        // us to them tell BytecodeGenerator::generate() to write to it because it will do so
+        // before it initializes functions and deconstructed parameters. But if "arguments" is
+        // overridden by a "simple" function parameter, then we have to bail: createVariable()
+        // would assert and BytecodeGenerator::generate() would write the "arguments" after the
+        // argument value had already been properly initialized.
+        
+        bool haveParameterNamedArguments = false;
+        for (unsigned i = 0; i < parameters.size(); ++i) {
+            StringImpl* name = visibleNameForParameter(parameters.at(i));
+            if (name == propertyNames().arguments.impl()) {
+                haveParameterNamedArguments = true;
+                break;
+            }
+        }
+        
+        if (!haveParameterNamedArguments) {
+            createVariable(
+                propertyNames().arguments, varKind(propertyNames().arguments.impl()), IsVariable);
+            m_needToInitializeArguments = true;
+        }
+    }
+    
+    if (m_symbolTable->scopeSize())
+        emitOpcode(op_touch_entry);
 
     if (isConstructor()) {
         if (constructorKind() == ConstructorKind::Derived) {
@@ -419,7 +485,6 @@
         instructions().append(0);
         instructions().append(0);
     }
-    m_localArgumentsRegister = localArgumentsRegister;
 }
 
 BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
@@ -458,108 +523,23 @@
 {
 }
 
-RegisterID* BytecodeGenerator::emitInitLazyRegister(RegisterID* reg)
+RegisterID* BytecodeGenerator::initializeNextParameter()
 {
-    emitOpcode(op_init_lazy_reg);
-    instructions().append(reg->index());
-    ASSERT(!hasWatchableVariable(reg->index()));
-    return reg;
-}
-
-RegisterID* BytecodeGenerator::initializeCapturedVariable(RegisterID* dst, const Identifier& propertyName, RegisterID* value)
-{
-
-    m_codeBlock->addPropertyAccessInstruction(instructions().size());
-    emitOpcode(op_put_to_scope);
-    instructions().append(m_lexicalEnvironmentRegister->index());
-    instructions().append(addConstant(propertyName));
-    instructions().append(value->index());
-    instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
-    int operand = registerFor(dst->index()).index();
-    bool isWatchableVariable = hasWatchableVariable(operand);
-    ASSERT(!isWatchableVariable || watchableVariableIdentifier(operand) == propertyName);
-    instructions().append(isWatchableVariable);
-    instructions().append(dst->index());
-    return dst;
-}
-
-RegisterID* BytecodeGenerator::resolveCallee(FunctionNode* functionNode)
-{
-    if (!functionNameIsInScope(functionNode->ident(), functionNode->functionMode()))
-        return 0;
-
-    if (functionNameScopeIsDynamic(m_codeBlock->usesEval(), m_codeBlock->isStrictMode()))
-        return 0;
-
-    m_calleeRegister.setIndex(JSStack::Callee);
-    if (functionNode->captures(functionNode->ident()))
-        return initializeCapturedVariable(addVar(), functionNode->ident(), &m_calleeRegister);
-
-    return &m_calleeRegister;
-}
-
-void BytecodeGenerator::addCallee(FunctionNode* functionNode, RegisterID* calleeRegister)
-{
-    if (!calleeRegister)
-        return;
-
-    symbolTable().add(functionNode->ident().impl(), SymbolTableEntry(calleeRegister->index(), ReadOnly));
-}
-
-void BytecodeGenerator::addParameter(const Identifier& ident, int parameterIndex)
-{
-    // Parameters overwrite var declarations, but not function declarations.
-    StringImpl* rep = ident.impl();
-    if (!m_functions.contains(rep)) {
-        symbolTable().set(rep, parameterIndex);
-        RegisterID& parameter = registerFor(parameterIndex);
-        parameter.setIndex(parameterIndex);
-    }
-
-    // To maintain the calling convention, we have to allocate unique space for
-    // each parameter, even if the parameter doesn't make it into the symbol table.
+    VirtualRegister reg = virtualRegisterForArgument(m_codeBlock->numParameters());
+    RegisterID& parameter = registerFor(reg);
+    parameter.setIndex(reg.offset());
     m_codeBlock->addParameter();
+    return &parameter;
 }
 
-bool BytecodeGenerator::willResolveToArgumentsRegister(const Identifier& ident)
+StringImpl* BytecodeGenerator::visibleNameForParameter(DeconstructionPatternNode* pattern)
 {
-    if (ident != propertyNames().arguments)
-        return false;
-    
-    if (!shouldOptimizeLocals())
-        return false;
-    
-    SymbolTableEntry entry = symbolTable().get(ident.impl());
-    if (entry.isNull())
-        return false;
-
-    if (m_localArgumentsRegister && isCaptured(m_localArgumentsRegister->index()) && m_lexicalEnvironmentRegister)
-        return false;
-
-    if (m_codeBlock->usesArguments() && m_codeType == FunctionCode && m_localArgumentsRegister)
-        return true;
-    
-    return false;
-}
-
-RegisterID* BytecodeGenerator::uncheckedLocalArgumentsRegister()
-{
-    ASSERT(willResolveToArgumentsRegister(propertyNames().arguments));
-    ASSERT(m_localArgumentsRegister);
-    return m_localArgumentsRegister;
-}
-
-RegisterID* BytecodeGenerator::createLazyRegisterIfNecessary(RegisterID* reg)
-{
-    if (!reg->virtualRegister().isLocal())
-        return reg;
-
-    int localVariableNumber = reg->virtualRegister().toLocal();
-
-    if (m_lastLazyFunction <= localVariableNumber || localVariableNumber < m_firstLazyFunction)
-        return reg;
-    emitLazyNewFunction(reg, m_lazyFunctions.get(localVariableNumber));
-    return reg;
+    if (pattern->isBindingNode()) {
+        const Identifier& ident = static_cast<const BindingNode*>(pattern)->boundProperty();
+        if (!m_functions.contains(ident.impl()))
+            return ident.impl();
+    }
+    return nullptr;
 }
 
 RegisterID* BytecodeGenerator::newRegister()
@@ -964,7 +944,7 @@
     StringImpl* rep = ident.impl();
     return m_identifierMap.contains(rep);
 }
-    
+
 unsigned BytecodeGenerator::addConstant(const Identifier& ident)
 {
     StringImpl* rep = ident.impl();
@@ -1015,7 +995,6 @@
 RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src)
 {
     m_staticPropertyAnalyzer.mov(dst->index(), src->index());
-    ASSERT(dst->virtualRegister() == m_codeBlock->argumentsRegister() || !isCaptured(dst->index()));
     emitOpcode(op_mov);
     instructions().append(dst->index());
     instructions().append(src->index());
@@ -1197,51 +1176,96 @@
     return m_globalObjectRegister;
 }
 
-bool BytecodeGenerator::isCaptured(int operand)
+Variable BytecodeGenerator::variable(const Identifier& property)
 {
-    return m_symbolTable && m_symbolTable->isCaptured(operand);
-}
-
-Local BytecodeGenerator::local(const Identifier& property)
-{
-    if (property == propertyNames().thisIdentifier)
-        return Local(thisRegister(), ReadOnly, Local::SpecialLocal);
-    bool isArguments = property == propertyNames().arguments;
-    if (isArguments)
-        createArgumentsIfNecessary();
-
+    if (property == propertyNames().thisIdentifier) {
+        return Variable(
+            property, VarOffset(thisRegister()->virtualRegister()), thisRegister(),
+            ReadOnly, Variable::SpecialVariable);
+    }
+    
     if (!shouldOptimizeLocals())
-        return Local();
-
+        return Variable(property);
+    
     SymbolTableEntry entry = symbolTable().get(property.impl());
     if (entry.isNull())
-        return Local();
-
-
-    RegisterID* local = createLazyRegisterIfNecessary(&registerFor(entry.getIndex()));
-
-    if (isCaptured(local->index()) && m_lexicalEnvironmentRegister)
-        return Local();
-
-    return Local(local, entry.getAttributes(), isArguments ? Local::SpecialLocal : Local::NormalLocal);
+        return Variable(property);
+    
+    if (entry.varOffset().isScope() && m_localScopeDepth) {
+        // FIXME: We should be able to statically resolve through our local scopes.
+        // https://bugs.webkit.org/show_bug.cgi?id=141885
+        return Variable(property);
+    }
+    
+    return variableForLocalEntry(property, entry);
 }
 
-Local BytecodeGenerator::constLocal(const Identifier& property)
+Variable BytecodeGenerator::variablePerSymbolTable(const Identifier& property)
 {
-    if (m_codeType != FunctionCode)
-        return Local();
-
     SymbolTableEntry entry = symbolTable().get(property.impl());
     if (entry.isNull())
-        return Local();
+        return Variable(property);
+    
+    return variableForLocalEntry(property, entry);
+}
 
-    RegisterID* local = createLazyRegisterIfNecessary(&registerFor(entry.getIndex()));
+Variable BytecodeGenerator::variableForLocalEntry(
+    const Identifier& property, const SymbolTableEntry& entry)
+{
+    VarOffset offset = entry.varOffset();
+    
+    RegisterID* local;
+    if (offset.isStack())
+        local = &registerFor(offset.stackOffset());
+    else
+        local = nullptr;
+    
+    return Variable(property, offset, local, entry.getAttributes(), Variable::NormalVariable);
+}
 
-    bool isArguments = property == propertyNames().arguments;
-    if (isCaptured(local->index()) && m_lexicalEnvironmentRegister)
-        return Local();
+void BytecodeGenerator::createVariable(
+    const Identifier& property, VarKind varKind, ConstantMode constantMode,
+    ExistingVariableMode existingVariableMode)
+{
+    ASSERT(property != propertyNames().thisIdentifier);
+    
+    ConcurrentJITLocker locker(symbolTable().m_lock);
+    SymbolTableEntry entry = symbolTable().get(locker, property.impl());
+    
+    if (!entry.isNull()) {
+        if (existingVariableMode == IgnoreExisting)
+            return;
+        
+        // Do some checks to ensure that the variable we're being asked to create is sufficiently
+        // compatible with the one we have already created.
 
-    return Local(local, entry.getAttributes(), isArguments ? Local::SpecialLocal : Local::NormalLocal);
+        VarOffset offset = entry.varOffset();
+        
+        // We can't change our minds about whether it's captured.
+        if (offset.kind() != varKind || constantMode != entry.constantMode()) {
+            dataLog(
+                "Trying to add variable called ", property, " as ", varKind, "/", constantMode,
+                " but it was already added as ", offset, "/", entry.constantMode(), ".\n");
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+
+        return;
+    }
+    
+    VarOffset varOffset;
+    if (varKind == VarKind::Scope)
+        varOffset = VarOffset(symbolTable().takeNextScopeOffset(locker));
+    else {
+        ASSERT(varKind == VarKind::Stack);
+        varOffset = VarOffset(virtualRegisterForLocal(m_calleeRegisters.size()));
+    }
+    SymbolTableEntry newEntry(varOffset, constantMode == IsConstant ? ReadOnly : 0);
+    symbolTable().add(locker, property.impl(), newEntry);
+    
+    if (varKind == VarKind::Stack) {
+        RegisterID* local = addVar();
+        RELEASE_ASSERT(local->index() == varOffset.stackOffset().offset());
+    }
 }
 
 void BytecodeGenerator::emitCheckHasInstance(RegisterID* dst, RegisterID* value, RegisterID* base, Label* target)
@@ -1265,88 +1289,147 @@
     return GlobalProperty;
 }
 
-RegisterID* BytecodeGenerator::emitResolveScope(RegisterID* dst, const Identifier& identifier, ResolveScopeInfo& info)
+RegisterID* BytecodeGenerator::emitResolveScope(RegisterID* dst, const Variable& variable)
 {
-    if (m_symbolTable && m_codeType == FunctionCode && !m_localScopeDepth) {
-        SymbolTableEntry entry = m_symbolTable->get(identifier.impl());
-        if (!entry.isNull()) {
-            info = ResolveScopeInfo(entry.getIndex());
-            return scopeRegister();
+    switch (variable.offset().kind()) {
+    case VarKind::Stack:
+        return nullptr;
+        
+    case VarKind::DirectArgument:
+        return argumentsRegister();
+        
+    case VarKind::Scope:
+        // This always refers to the activation that *we* allocated, and not the current scope that code
+        // lives in. Note that this will change once we have proper support for block scoping. Once that
+        // changes, it will be correct for this code to return scopeRegister(). The only reason why we
+        // don't do that already is that m_lexicalEnvironment is required by ConstDeclNode. ConstDeclNode
+        // requires weird things because it is a shameful pile of nonsense, but block scoping would make
+        // that code sensible and obviate the need for us to do bad things.
+        return m_lexicalEnvironmentRegister;
+        
+    case VarKind::Invalid:
+        // Indicates non-local resolution.
+        
+        ASSERT(!m_symbolTable || !m_symbolTable->contains(variable.ident().impl()) || resolveType() == Dynamic);
+        
+        m_codeBlock->addPropertyAccessInstruction(instructions().size());
+        
+        // resolve_scope dst, id, ResolveType, depth
+        emitOpcode(op_resolve_scope);
+        dst = tempDestination(dst);
+        instructions().append(kill(dst));
+        instructions().append(scopeRegister()->index());
+        instructions().append(addConstant(variable.ident()));
+        instructions().append(resolveType());
+        instructions().append(0);
+        instructions().append(0);
+        return dst;
+    }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
+RegisterID* BytecodeGenerator::emitGetFromScope(RegisterID* dst, RegisterID* scope, const Variable& variable, ResolveMode resolveMode)
+{
+    switch (variable.offset().kind()) {
+    case VarKind::Stack:
+        return emitMove(dst, variable.local());
+        
+    case VarKind::DirectArgument: {
+        UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_arguments);
+        instructions().append(kill(dst));
+        instructions().append(scope->index());
+        instructions().append(variable.offset().capturedArgumentsOffset().offset());
+        instructions().append(profile);
+        return dst;
+    }
+        
+    case VarKind::Scope:
+    case VarKind::Invalid: {
+        m_codeBlock->addPropertyAccessInstruction(instructions().size());
+        
+        // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
+        UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_scope);
+        instructions().append(kill(dst));
+        instructions().append(scope->index());
+        instructions().append(addConstant(variable.ident()));
+        instructions().append(ResolveModeAndType(resolveMode, variable.offset().isScope() ? LocalClosureVar : resolveType()).operand());
+        instructions().append(0);
+        instructions().append(variable.offset().isScope() ? variable.offset().scopeOffset().offset() : 0);
+        instructions().append(profile);
+        return dst;
+    } }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Variable& variable, RegisterID* value, ResolveMode resolveMode)
+{
+    switch (variable.offset().kind()) {
+    case VarKind::Stack:
+        emitMove(variable.local(), value);
+        return value;
+        
+    case VarKind::DirectArgument:
+        emitOpcode(op_put_to_arguments);
+        instructions().append(scope->index());
+        instructions().append(variable.offset().capturedArgumentsOffset().offset());
+        instructions().append(value->index());
+        return value;
+        
+    case VarKind::Scope:
+    case VarKind::Invalid: {
+        m_codeBlock->addPropertyAccessInstruction(instructions().size());
+        
+        // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
+        emitOpcode(op_put_to_scope);
+        instructions().append(scope->index());
+        instructions().append(addConstant(variable.ident()));
+        instructions().append(value->index());
+        ScopeOffset offset;
+        if (variable.offset().isScope()) {
+            offset = variable.offset().scopeOffset();
+            instructions().append(ResolveModeAndType(resolveMode, LocalClosureVar).operand());
+        } else {
+            ASSERT(resolveType() != LocalClosureVar);
+            instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
         }
+        instructions().append(0);
+        instructions().append(!!offset ? offset.offset() : 0);
+        return value;
+    } }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+RegisterID* BytecodeGenerator::initializeVariable(const Variable& variable, RegisterID* value)
+{
+    RegisterID* scope;
+    switch (variable.offset().kind()) {
+    case VarKind::Stack:
+        scope = nullptr;
+        break;
+        
+    case VarKind::DirectArgument:
+        scope = argumentsRegister();
+        break;
+        
+    case VarKind::Scope:
+        scope = scopeRegister();
+        break;
+        
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        scope = nullptr;
+        break;
     }
 
-    ASSERT(!m_symbolTable || !m_symbolTable->contains(identifier.impl()) || resolveType() == Dynamic);
-
-    m_codeBlock->addPropertyAccessInstruction(instructions().size());
-
-    // resolve_scope dst, id, ResolveType, depth
-    emitOpcode(op_resolve_scope);
-    dst = tempDestination(dst);
-    instructions().append(kill(dst));
-    instructions().append(scopeRegister()->index());
-    instructions().append(addConstant(identifier));
-    instructions().append(resolveType());
-    instructions().append(0);
-    instructions().append(0);
-    return dst;
-}
-
-
-RegisterID* BytecodeGenerator::emitResolveConstantLocal(RegisterID* dst, const Identifier& identifier, ResolveScopeInfo& info)
-{
-    if (!m_symbolTable || m_codeType != FunctionCode)
-        return nullptr;
-
-    SymbolTableEntry entry = m_symbolTable->get(identifier.impl());
-    if (entry.isNull())
-        return nullptr;
-    info = ResolveScopeInfo(entry.getIndex());
-    return emitMove(dst, m_lexicalEnvironmentRegister);
-
-}
-
-RegisterID* BytecodeGenerator::emitGetFromScope(RegisterID* dst, RegisterID* scope, const Identifier& identifier, ResolveMode resolveMode, const ResolveScopeInfo& info)
-{
-    m_codeBlock->addPropertyAccessInstruction(instructions().size());
-
-    // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
-    UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_scope);
-    instructions().append(kill(dst));
-    instructions().append(scope->index());
-    instructions().append(addConstant(identifier));
-    instructions().append(ResolveModeAndType(resolveMode, info.isLocal() ? LocalClosureVar : resolveType()).operand());
-    instructions().append(0);
-    instructions().append(info.localIndex());
-    instructions().append(profile);
-    return dst;
-}
-
-RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Identifier& identifier, RegisterID* value, ResolveMode resolveMode, const ResolveScopeInfo& info)
-{
-    m_codeBlock->addPropertyAccessInstruction(instructions().size());
-
-    // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
-    emitOpcode(op_put_to_scope);
-    instructions().append(scope->index());
-    instructions().append(addConstant(identifier));
-    instructions().append(value->index());
-    if (info.isLocal()) {
-        instructions().append(ResolveModeAndType(resolveMode, LocalClosureVar).operand());
-        int operand = registerFor(info.localIndex()).index();
-        bool isWatchableVariable = hasWatchableVariable(operand);
-        ASSERT(!isWatchableVariable || watchableVariableIdentifier(operand) == identifier);
-        instructions().append(isWatchableVariable);
-    } else {
-        ASSERT(resolveType() != LocalClosureVar);
-        instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
-        instructions().append(false);
-    }
-    instructions().append(info.localIndex());
-    return value;
+    return emitPutToScope(scope, variable, value, ThrowIfNotFound);
 }
 
 RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype)
-{ 
+{
     emitOpcode(op_instanceof);
     instructions().append(dst->index());
     instructions().append(value->index());
@@ -1381,16 +1464,6 @@
     return dst;
 }
 
-RegisterID* BytecodeGenerator::emitGetArgumentsLength(RegisterID* dst, RegisterID* base)
-{
-    emitOpcode(op_get_arguments_length);
-    instructions().append(dst->index());
-    ASSERT(base->virtualRegister() == m_codeBlock->argumentsRegister());
-    instructions().append(base->index());
-    instructions().append(addConstant(propertyNames().length));
-    return dst;
-}
-
 RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
 {
     unsigned propertyIndex = addConstant(property);
@@ -1454,20 +1527,6 @@
     return dst;
 }
 
-RegisterID* BytecodeGenerator::emitGetArgumentByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
-{
-    UnlinkedArrayProfile arrayProfile = newArrayProfile();
-    UnlinkedValueProfile profile = emitProfiledOpcode(op_get_argument_by_val);
-    instructions().append(kill(dst));
-    ASSERT(base->virtualRegister() == m_codeBlock->argumentsRegister());
-    instructions().append(base->index());
-    instructions().append(property->index());
-    instructions().append(m_codeBlock->activationRegister().offset());
-    instructions().append(arrayProfile);
-    instructions().append(profile);
-    return dst;
-}
-
 RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
 {
     for (size_t i = m_forInContextStack.size(); i > 0; i--) {
@@ -1652,24 +1711,15 @@
 
 RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode* function)
 {
-    return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl(makeFunction(function)), false);
+    return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl(makeFunction(function)));
 }
 
-RegisterID* BytecodeGenerator::emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* function)
-{
-    FunctionOffsetMap::AddResult ptr = m_functionOffsets.add(function, 0);
-    if (ptr.isNewEntry)
-        ptr.iterator->value = m_codeBlock->addFunctionDecl(makeFunction(function));
-    return emitNewFunctionInternal(dst, ptr.iterator->value, true);
-}
-
-RegisterID* BytecodeGenerator::emitNewFunctionInternal(RegisterID* dst, unsigned index, bool doNullCheck)
+RegisterID* BytecodeGenerator::emitNewFunctionInternal(RegisterID* dst, unsigned index)
 {
     emitOpcode(op_new_func);
     instructions().append(dst->index());
     instructions().append(scopeRegister()->index());
     instructions().append(index);
-    instructions().append(doNullCheck);
     return dst;
 }
 
@@ -1711,23 +1761,6 @@
     return emitCall(op_call, dst, func, expectedFunction, callArguments, divot, divotStart, divotEnd);
 }
 
-void BytecodeGenerator::createArgumentsIfNecessary()
-{
-    if (m_codeType != FunctionCode)
-        return;
-    
-    if (!m_codeBlock->usesArguments())
-        return;
-
-    if (shouldTearOffArgumentsEagerly() || shouldCreateArgumentsEagerly())
-        return;
-
-    emitOpcode(op_create_arguments);
-    instructions().append(m_codeBlock->argumentsRegister().offset());
-    ASSERT(!hasWatchableVariable(m_codeBlock->argumentsRegister().offset()));
-    instructions().append(m_codeBlock->activationRegister().offset());
-}
-
 RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
 {
     return emitCall(op_call_eval, dst, func, NoExpectedFunction, callArguments, divot, divotStart, divotEnd);
@@ -1824,10 +1857,7 @@
             RELEASE_ASSERT(!n->m_next);
             auto expression = static_cast<SpreadExpressionNode*>(n->m_expr)->expression();
             RefPtr<RegisterID> argumentRegister;
-            if (expression->isResolveNode() && willResolveToArgumentsRegister(static_cast<ResolveNode*>(expression)->identifier()) && !symbolTable().slowArguments())
-                argumentRegister = uncheckedLocalArgumentsRegister();
-            else
-                argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
+            argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
             RefPtr<RegisterID> thisRegister = emitMove(newTemporary(), callArguments.thisRegister());
             return emitCallVarargs(dst, func, callArguments.thisRegister(), argumentRegister.get(), newTemporary(), 0, callArguments.profileHookRegister(), divot, divotStart, divotEnd);
         }
@@ -1916,20 +1946,6 @@
 
 RegisterID* BytecodeGenerator::emitReturn(RegisterID* src)
 {
-    if (m_codeBlock->usesArguments() && m_codeBlock->numParameters() != 1 && !isStrictMode()) {
-        RefPtr<RegisterID> scratchRegister;
-        int argumentsIndex = unmodifiedArgumentsRegister(m_codeBlock->argumentsRegister()).offset();
-        if (m_lexicalEnvironmentRegister && m_codeType == FunctionCode) {
-            scratchRegister = newTemporary();
-            ResolveScopeInfo scopeInfo(unmodifiedArgumentsRegister(m_codeBlock->argumentsRegister()).offset());
-            emitGetFromScope(scratchRegister.get(), scopeRegister(), propertyNames().arguments, ThrowIfNotFound, scopeInfo);
-            argumentsIndex = scratchRegister->index();
-        }
-        emitOpcode(op_tear_off_arguments);
-        instructions().append(argumentsIndex);
-        instructions().append(m_lexicalEnvironmentRegister ? m_lexicalEnvironmentRegister->index() : emitLoad(0, JSValue())->index());
-    }
-
     if (isConstructor()) {
         bool derived = constructorKind() == ConstructorKind::Derived;
         if (derived && src->index() == m_thisRegister.index())
@@ -1978,10 +1994,7 @@
             RELEASE_ASSERT(!n->m_next);
             auto expression = static_cast<SpreadExpressionNode*>(n->m_expr)->expression();
             RefPtr<RegisterID> argumentRegister;
-            if (expression->isResolveNode() && willResolveToArgumentsRegister(static_cast<ResolveNode*>(expression)->identifier()) && !symbolTable().slowArguments())
-                argumentRegister = uncheckedLocalArgumentsRegister();
-            else
-                argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
+            argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
             return emitConstructVarargs(dst, func, callArguments.thisRegister(), argumentRegister.get(), newTemporary(), 0, callArguments.profileHookRegister(), divot, divotStart, divotEnd);
         }
         
@@ -2543,9 +2556,9 @@
 
 bool BytecodeGenerator::isArgumentNumber(const Identifier& ident, int argumentNumber)
 {
-    RegisterID* registerID = local(ident).get();
-    if (!registerID || registerID->index() >= 0)
-         return 0;
+    RegisterID* registerID = variable(ident).local();
+    if (!registerID)
+        return false;
     return registerID->index() == CallFrame::argumentOffset(argumentNumber);
 }
 
@@ -2560,31 +2573,6 @@
     
 void BytecodeGenerator::emitEnumeration(ThrowableExpressionData* node, ExpressionNode* subjectNode, const std::function<void(BytecodeGenerator&, RegisterID*)>& callBack)
 {
-    if (subjectNode->isResolveNode()
-        && willResolveToArgumentsRegister(static_cast<ResolveNode*>(subjectNode)->identifier())
-        && !symbolTable().slowArguments()) {
-        RefPtr<RegisterID> index = emitLoad(newTemporary(), jsNumber(0));
-
-        LabelScopePtr scope = newLabelScope(LabelScope::Loop);
-        RefPtr<RegisterID> value = emitLoad(newTemporary(), jsUndefined());
-        
-        RefPtr<Label> loopCondition = newLabel();
-        RefPtr<Label> loopStart = newLabel();
-        emitJump(loopCondition.get());
-        emitLabel(loopStart.get());
-        emitLoopHint();
-        emitGetArgumentByVal(value.get(), uncheckedLocalArgumentsRegister(), index.get());
-        callBack(*this, value.get());
-    
-        emitLabel(scope->continueTarget());
-        emitInc(index.get());
-        emitLabel(loopCondition.get());
-        RefPtr<RegisterID> length = emitGetArgumentsLength(newTemporary(), uncheckedLocalArgumentsRegister());
-        emitJumpIfTrue(emitEqualityOp(op_less, newTemporary(), index.get(), length.get()), loopStart.get());
-        emitLabel(scope->breakTarget());
-        return;
-    }
-
     LabelScopePtr scope = newLabelScope(LabelScope::Loop);
     RefPtr<RegisterID> subject = newTemporary();
     emitNode(subject.get(), subjectNode);
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index 190b436..1c99aca 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2012-2015 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
  * Copyright (C) 2012 Igalia, S.L.
  *
@@ -178,61 +178,55 @@
         TryData* tryData;
     };
 
-    enum CaptureMode {
-        NotCaptured,
-        IsCaptured
-    };
-
-    class Local {
+    class Variable {
     public:
-        Local()
-            : m_local(0)
+        enum VariableKind { NormalVariable, SpecialVariable };
+
+        Variable()
+            : m_offset()
+            , m_local(nullptr)
             , m_attributes(0)
-            , m_kind(NormalLocal)
+            , m_kind(NormalVariable)
+        {
+        }
+        
+        Variable(const Identifier& ident)
+            : m_ident(ident)
+            , m_local(nullptr)
+            , m_attributes(0)
+            , m_kind(NormalVariable) // This is somewhat meaningless here for this kind of Variable.
         {
         }
 
-        enum LocalKind { NormalLocal, SpecialLocal };
-
-        Local(RegisterID* local, unsigned attributes, LocalKind kind)
-            : m_local(local)
+        Variable(const Identifier& ident, VarOffset offset, RegisterID* local, unsigned attributes, VariableKind kind)
+            : m_ident(ident)
+            , m_offset(offset)
+            , m_local(local)
             , m_attributes(attributes)
             , m_kind(kind)
         {
         }
 
-        operator bool() const { return m_local; }
-
-        RegisterID* get() const { return m_local; }
+        // If it's unset, then it is a non-locally-scoped variable. If it is set, then it could be
+        // a stack variable, a scoped variable in the local scope, or a variable captured in the
+        // direct arguments object.
+        bool isResolved() const { return !!m_offset; }
+        
+        const Identifier& ident() const { return m_ident; }
+        
+        VarOffset offset() const { return m_offset; }
+        bool isLocal() const { return m_offset.isStack(); }
+        RegisterID* local() const { return m_local; }
 
         bool isReadOnly() const { return m_attributes & ReadOnly; }
-        bool isSpecial() const { return m_kind != NormalLocal; }
+        bool isSpecial() const { return m_kind != NormalVariable; }
 
     private:
+        Identifier m_ident;
+        VarOffset m_offset;
         RegisterID* m_local;
         unsigned m_attributes;
-        LocalKind m_kind;
-    };
-
-    struct ResolveScopeInfo {
-        ResolveScopeInfo()
-            : m_localIndex(0)
-            , m_resolveScopeKind(NonLocalScope)
-        {
-        }
-
-        ResolveScopeInfo(int index)
-            : m_localIndex(index)
-            , m_resolveScopeKind(LocalScope)
-        {
-        }
-
-        bool isLocal() const { return m_resolveScopeKind == LocalScope; }
-        int localIndex() const { return m_localIndex; }
-
-    private:
-        int m_localIndex;
-        enum { LocalScope, NonLocalScope } m_resolveScopeKind;
+        VariableKind m_kind;
     };
 
     struct TryRange {
@@ -282,19 +276,17 @@
 
         void setIsNumericCompareFunction(bool isNumericCompareFunction);
 
-        bool willResolveToArgumentsRegister(const Identifier&);
-
-        bool hasSafeLocalArgumentsRegister() { return m_localArgumentsRegister; }
-        RegisterID* uncheckedLocalArgumentsRegister();
-
-        bool isCaptured(int operand);
-        CaptureMode captureMode(int operand) { return isCaptured(operand) ? IsCaptured : NotCaptured; }
+        Variable variable(const Identifier&);
         
-        Local local(const Identifier&);
-        Local constLocal(const Identifier&);
-
+        // Ignores the possibility of intervening scopes.
+        Variable variablePerSymbolTable(const Identifier&);
+        
+        enum ExistingVariableMode { VerifyExisting, IgnoreExisting };
+        void createVariable(const Identifier&, VarKind, ConstantMode, ExistingVariableMode = VerifyExisting); // Creates the variable, or asserts that the already-created variable is sufficiently compatible.
+        
         // Returns the register storing "this"
         RegisterID* thisRegister() { return &m_thisRegister; }
+        RegisterID* argumentsRegister() { return m_argumentsRegister; }
         RegisterID* newTarget() { return m_newTargetRegister; }
 
         RegisterID* scopeRegister() { return m_scopeRegister; }
@@ -353,8 +345,6 @@
         {
             // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
             ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
-            // Should never store directly into a captured variable.
-            ASSERT(!dst || dst == ignoredResult() || !isCaptured(dst->index()));
             if (!m_vm->isSafeToRecurse()) {
                 emitThrowExpressionTooDeepException();
                 return;
@@ -371,8 +361,6 @@
         {
             // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
             ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
-            // Should never store directly into a captured variable.
-            ASSERT(!dst || dst == ignoredResult() || !isCaptured(dst->index()));
             if (!m_vm->isSafeToRecurse())
                 return emitThrowExpressionTooDeepException();
             return n->emitBytecode(*this, dst);
@@ -463,8 +451,7 @@
         RegisterID* emitNewArray(RegisterID* dst, ElementNode*, unsigned length); // stops at first elision
 
         RegisterID* emitNewFunction(RegisterID* dst, FunctionBodyNode*);
-        RegisterID* emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* body);
-        RegisterID* emitNewFunctionInternal(RegisterID* dst, unsigned index, bool shouldNullCheck);
+        RegisterID* emitNewFunctionInternal(RegisterID* dst, unsigned index);
         RegisterID* emitNewFunctionExpression(RegisterID* dst, FuncExprNode* func);
         RegisterID* emitNewDefaultConstructor(RegisterID* dst, ConstructorKind, const Identifier& name);
         RegisterID* emitNewRegExp(RegisterID* dst, RegExp*);
@@ -483,7 +470,6 @@
         RegisterID* emitInitGlobalConst(const Identifier&, RegisterID* value);
 
         RegisterID* emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property);
-        RegisterID* emitGetArgumentsLength(RegisterID* dst, RegisterID* base);
         RegisterID* emitPutById(RegisterID* base, const Identifier& property, RegisterID* value);
         RegisterID* emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value, PropertyNode::PutType);
         RegisterID* emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier&);
@@ -510,14 +496,11 @@
         void emitToPrimitive(RegisterID* dst, RegisterID* src);
 
         ResolveType resolveType();
-        RegisterID* emitResolveConstantLocal(RegisterID* dst, const Identifier&, ResolveScopeInfo&);
-        // Calls tempDestination(dst), so it's safe to pass nullptr. It's also redundant to call
-        // tempDestination(dst) on the thing you pass as the destination. The reason why this
-        // calls tempDestination() for you is that it may not need a spare register. It may return
-        // scopeRegister() directly. So, you cannot rely on this storing to dst.
-        RegisterID* emitResolveScope(RegisterID* dst, const Identifier&, ResolveScopeInfo&);
-        RegisterID* emitGetFromScope(RegisterID* dst, RegisterID* scope, const Identifier&, ResolveMode, const ResolveScopeInfo&);
-        RegisterID* emitPutToScope(RegisterID* scope, const Identifier&, RegisterID* value, ResolveMode, const ResolveScopeInfo&);
+        RegisterID* emitResolveConstantLocal(RegisterID* dst, const Variable&);
+        RegisterID* emitResolveScope(RegisterID* dst, const Variable&);
+        RegisterID* emitGetFromScope(RegisterID* dst, RegisterID* scope, const Variable&, ResolveMode);
+        RegisterID* emitPutToScope(RegisterID* scope, const Variable&, RegisterID* value, ResolveMode);
+        RegisterID* initializeVariable(const Variable&, RegisterID* value);
 
         PassRefPtr<Label> emitLabel(Label*);
         void emitLoopHint();
@@ -597,6 +580,8 @@
         OpcodeID lastOpcodeID() const { return m_lastOpcodeID; }
 
     private:
+        Variable variableForLocalEntry(const Identifier&, const SymbolTableEntry&);
+
         void emitOpcode(OpcodeID);
         UnlinkedArrayAllocationProfile newArrayAllocationProfile();
         UnlinkedObjectAllocationProfile newObjectAllocationProfile();
@@ -629,11 +614,7 @@
 
         RegisterID* newRegister();
 
-        // Adds a var slot and maps it to the name ident in symbolTable().
-        enum WatchMode { IsWatchable, NotWatchable };
-        RegisterID* addVar(const Identifier&, ConstantMode, WatchMode);
-
-        // Adds an anonymous var slot. To give this slot a name, add it to symbolTable().
+        // Adds an anonymous local var slot. To give this slot a name, add it to symbolTable().
         RegisterID* addVar()
         {
             ++m_codeBlock->m_numVars;
@@ -643,23 +624,20 @@
             return result;
         }
 
-        // Returns the index of the added var.
-        void addParameter(const Identifier&, int parameterIndex);
-        RegisterID* resolveCallee(FunctionNode*);
-        void addCallee(FunctionNode*, RegisterID*);
-
-        void preserveLastVar();
-
-        RegisterID& registerFor(int index)
+        // Initializes the stack form the parameter; does nothing for the symbol table.
+        RegisterID* initializeNextParameter();
+        StringImpl* visibleNameForParameter(DeconstructionPatternNode*);
+        
+        RegisterID& registerFor(VirtualRegister reg)
         {
-            if (operandIsLocal(index))
-                return m_calleeRegisters[VirtualRegister(index).toLocal()];
+            if (reg.isLocal())
+                return m_calleeRegisters[reg.toLocal()];
 
-            if (index == JSStack::Callee)
+            if (reg.offset() == JSStack::Callee)
                 return m_calleeRegister;
 
             ASSERT(m_parameters.size());
-            return m_parameters[VirtualRegister(index).toArgument()];
+            return m_parameters[reg.toArgument()];
         }
 
         bool hasConstant(const Identifier&) const;
@@ -675,11 +653,8 @@
             return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), body, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction);
         }
 
-        RegisterID* emitInitLazyRegister(RegisterID*);
-        
         RegisterID* emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
         RegisterID* emitCallVarargs(OpcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
-        RegisterID* initializeCapturedVariable(RegisterID* dst, const Identifier&, RegisterID*);
 
     public:
         JSString* addStringConstant(const Identifier&);
@@ -713,44 +688,8 @@
             return true;
         }
 
-        bool shouldTearOffArgumentsEagerly()
-        {
-            return m_codeType == FunctionCode && isStrictMode() && m_scopeNode->modifiesParameter();
-        }
-
-        bool shouldCreateArgumentsEagerly()
-        {
-            if (m_codeType != FunctionCode)
-                return false;
-            return m_lexicalEnvironmentRegister && m_codeBlock->usesArguments();
-        }
-
         RegisterID* emitThrowExpressionTooDeepException();
 
-        void createArgumentsIfNecessary();
-        RegisterID* createLazyRegisterIfNecessary(RegisterID*);
-        
-        bool hasWatchableVariable(int operand) const
-        {
-            VirtualRegister reg(operand);
-            if (!reg.isLocal())
-                return false;
-            if (static_cast<size_t>(reg.toLocal()) >= m_watchableVariables.size())
-                return false;
-            const Identifier& ident = m_watchableVariables[reg.toLocal()];
-            if (ident.isNull())
-                return false;
-            ASSERT(hasConstant(ident)); // Should have already been added.
-            return true;
-        }
-        
-        const Identifier& watchableVariableIdentifier(int operand) const
-        {
-            ASSERT(hasWatchableVariable(operand));
-            VirtualRegister reg(operand);
-            return m_watchableVariables[reg.toLocal()];
-        }
-
     private:
         Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow> m_instructions;
 
@@ -769,13 +708,12 @@
         RegisterID m_thisRegister;
         RegisterID m_calleeRegister;
         RegisterID* m_scopeRegister { nullptr };
+        RegisterID* m_argumentsRegister { nullptr };
         RegisterID* m_lexicalEnvironmentRegister { nullptr };
         RegisterID* m_emptyValueRegister { nullptr };
         RegisterID* m_globalObjectRegister { nullptr };
-        RegisterID* m_localArgumentsRegister { nullptr };
         RegisterID* m_newTargetRegister { nullptr };
 
-        Vector<Identifier, 16> m_watchableVariables;
         SegmentedVector<RegisterID, 32> m_constantPoolRegisters;
         SegmentedVector<RegisterID, 32> m_calleeRegisters;
         SegmentedVector<RegisterID, 32> m_parameters;
@@ -790,15 +728,14 @@
         Vector<std::unique_ptr<ForInContext>> m_forInContextStack;
         Vector<TryContext> m_tryContextStack;
         Vector<std::pair<RefPtr<RegisterID>, const DeconstructionPatternNode*>> m_deconstructedParameters;
+        Vector<FunctionBodyNode*> m_functionsToInitialize;
+        bool m_needToInitializeArguments { false };
         
         Vector<TryRange> m_tryRanges;
         SegmentedVector<TryData, 8> m_tryData;
 
         int m_nextConstantOffset { 0 };
 
-        int m_firstLazyFunction { 0 };
-        int m_lastLazyFunction { 0 };
-        HashMap<unsigned int, FunctionBodyNode*, WTF::IntHash<unsigned int>, WTF::UnsignedWithZeroKeyHashTraits<unsigned int>> m_lazyFunctions;
         typedef HashMap<FunctionBodyNode*, unsigned> FunctionOffsetMap;
         FunctionOffsetMap m_functionOffsets;
         
diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index 02e447a..b5c3727 100644
--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -1,7 +1,7 @@
 /*
 *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
-*  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
+*  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012, 2013, 2015 Apple Inc. All rights reserved.
 *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
 *  Copyright (C) 2007 Maks Orlovich
 *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
@@ -187,29 +187,29 @@
 
 bool ResolveNode::isPure(BytecodeGenerator& generator) const
 {
-    return generator.local(m_ident).get();
+    return generator.variable(m_ident).offset().isStack();
 }
 
 RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (Local local = generator.local(m_ident)) {
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local()) {
         if (dst == generator.ignoredResult())
-            return 0;
+            return nullptr;
         if (generator.vm()->typeProfiler()) {
-            generator.emitProfileType(local.get(), ProfileTypeBytecodeHasGlobalID, nullptr);
+            generator.emitProfileType(local, ProfileTypeBytecodeHasGlobalID, nullptr);
             generator.emitTypeProfilerExpressionInfo(m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
         }
-        return generator.moveToDestinationIfNeeded(dst, local.get());
+        return generator.moveToDestinationIfNeeded(dst, local);
     }
     
     JSTextPosition divot = m_start + m_ident.length();
     generator.emitExpressionInfo(divot, m_start, divot);
-    ResolveScopeInfo resolveScopeInfo;
-    RefPtr<RegisterID> scope = generator.emitResolveScope(dst, m_ident, resolveScopeInfo);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
     RegisterID* finalDest = generator.finalDestination(dst);
-    RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), m_ident, ThrowIfNotFound, resolveScopeInfo);
+    RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), var, ThrowIfNotFound);
     if (generator.vm()->typeProfiler()) {
-        generator.emitProfileType(finalDest, resolveScopeInfo.isLocal() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
+        generator.emitProfileType(finalDest, var.isResolved() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
         generator.emitTypeProfilerExpressionInfo(m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
     }
     return result;
@@ -439,14 +439,6 @@
         return generator.emitGetByVal(generator.finalDestination(dst), emitSuperBaseForCallee(generator), generator.emitNode(m_subscript));
     }
 
-    if (m_base->isResolveNode() 
-        && generator.willResolveToArgumentsRegister(static_cast<ResolveNode*>(m_base)->identifier())
-        && !generator.symbolTable().slowArguments()) {
-        RefPtr<RegisterID> property = generator.emitNode(m_subscript);
-        generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-        return generator.emitGetArgumentByVal(generator.finalDestination(dst), generator.uncheckedLocalArgumentsRegister(), property.get());
-    }
-
     RegisterID* ret;
     RegisterID* finalDest = generator.finalDestination(dst);
 
@@ -472,17 +464,6 @@
 
 RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (m_ident == generator.propertyNames().length) {
-        if (!m_base->isResolveNode())
-            goto nonArgumentsPath;
-        ResolveNode* resolveNode = static_cast<ResolveNode*>(m_base);
-        if (!generator.willResolveToArgumentsRegister(resolveNode->identifier()))
-            goto nonArgumentsPath;
-        generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-        return generator.emitGetArgumentsLength(generator.finalDestination(dst), generator.uncheckedLocalArgumentsRegister());
-    }
-
-nonArgumentsPath:
     RefPtr<RegisterID> base = m_base->isSuperNode() ? emitSuperBaseForCallee(generator) : generator.emitNode(m_base);
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
     RegisterID* finalDest = generator.finalDestination(dst);
@@ -547,8 +528,9 @@
 
 RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (Local local = generator.local(generator.propertyNames().eval)) {
-        RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local.get());
+    Variable var = generator.variable(generator.propertyNames().eval);
+    if (RegisterID* local = var.local()) {
+        RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
         CallArguments callArguments(generator, m_args);
         generator.emitLoad(callArguments.thisRegister(), jsUndefined());
         return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd());
@@ -558,11 +540,10 @@
     CallArguments callArguments(generator, m_args);
     JSTextPosition newDivot = divotStart() + 4;
     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
-    ResolveScopeInfo resolveScopeInfo;
     generator.moveToDestinationIfNeeded(
         callArguments.thisRegister(),
-        generator.emitResolveScope(callArguments.thisRegister(), generator.propertyNames().eval, resolveScopeInfo));
-    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), generator.propertyNames().eval, ThrowIfNotFound, resolveScopeInfo);
+        generator.emitResolveScope(callArguments.thisRegister(), var));
+    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
     return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd());
 }
 
@@ -596,8 +577,9 @@
 {
     ExpectedFunction expectedFunction = generator.expectedFunctionForIdentifier(m_ident);
 
-    if (Local local = generator.local(m_ident)) {
-        RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local.get());
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local()) {
+        RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
         RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
         CallArguments callArguments(generator, m_args);
         generator.emitLoad(callArguments.thisRegister(), jsUndefined());
@@ -617,11 +599,10 @@
 
     JSTextPosition newDivot = divotStart() + m_ident.length();
     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
-    ResolveScopeInfo resolveScopeInfo;
     generator.moveToDestinationIfNeeded(
         callArguments.thisRegister(),
-        generator.emitResolveScope(callArguments.thisRegister(), m_ident, resolveScopeInfo));
-    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), m_ident, ThrowIfNotFound, resolveScopeInfo);
+        generator.emitResolveScope(callArguments.thisRegister(), var));
+    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
     RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
     if (generator.vm()->typeProfiler()) {
         generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
@@ -675,17 +656,6 @@
     return ret;
 }
 
-static RegisterID* getArgumentByVal(BytecodeGenerator& generator, ExpressionNode* base, RegisterID* property, RegisterID* dst, JSTextPosition divot, JSTextPosition divotStart, JSTextPosition divotEnd)
-{
-    if (base->isResolveNode()
-        && generator.willResolveToArgumentsRegister(static_cast<ResolveNode*>(base)->identifier())
-        && !generator.symbolTable().slowArguments()) {
-        generator.emitExpressionInfo(divot, divotStart, divotEnd);
-        return generator.emitGetArgumentByVal(generator.finalDestination(dst), generator.uncheckedLocalArgumentsRegister(), property);
-    }
-    return nullptr;
-}
-
 RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     RefPtr<Label> realCall = generator.newLabel();
@@ -706,15 +676,10 @@
                 profileHookRegister = generator.newTemporary();
             SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(m_args->m_listNode->m_expr);
             ExpressionNode* subject = spread->expression();
-            RefPtr<RegisterID> thisRegister = getArgumentByVal(generator, subject, generator.emitLoad(0, jsNumber(0)), 0, spread->divot(), spread->divotStart(), spread->divotEnd());
             RefPtr<RegisterID> argumentsRegister;
-            if (thisRegister)
-                argumentsRegister = generator.uncheckedLocalArgumentsRegister();
-            else {
-                argumentsRegister = generator.emitNode(subject);
-                generator.emitExpressionInfo(spread->divot(), spread->divotStart(), spread->divotEnd());
-                thisRegister = generator.emitGetByVal(generator.newTemporary(), argumentsRegister.get(), generator.emitLoad(0, jsNumber(0)));
-            }
+            argumentsRegister = generator.emitNode(subject);
+            generator.emitExpressionInfo(spread->divot(), spread->divotStart(), spread->divotEnd());
+            RefPtr<RegisterID> thisRegister = generator.emitGetByVal(generator.newTemporary(), argumentsRegister.get(), generator.emitLoad(0, jsNumber(0)));
             generator.emitCallVarargs(returnValue.get(), base.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 1, profileHookRegister.get(), divot(), divotStart(), divotEnd());
         } else if (m_args->m_listNode && m_args->m_listNode->m_expr) {
             ArgumentListNode* oldList = m_args->m_listNode;
@@ -836,10 +801,7 @@
         RefPtr<RegisterID> thisRegister = generator.emitNode(m_args->m_listNode->m_expr);
         RefPtr<RegisterID> argsRegister;
         ArgumentListNode* args = m_args->m_listNode->m_next;
-        if (args->m_expr->isResolveNode() && generator.willResolveToArgumentsRegister(static_cast<ResolveNode*>(args->m_expr)->identifier()) && !generator.symbolTable().slowArguments())
-            argsRegister = generator.uncheckedLocalArgumentsRegister();
-        else
-            argsRegister = generator.emitNode(args->m_expr);
+        argsRegister = generator.emitNode(args->m_expr);
 
         // Function.prototype.apply ignores extra arguments, but we still
         // need to evaluate them for side effects.
@@ -888,11 +850,12 @@
     ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
     const Identifier& ident = resolve->identifier();
 
-    if (Local local = generator.local(ident)) {
-        RefPtr<RegisterID> localReg = local.get();
-        if (local.isReadOnly()) {
+    Variable var = generator.variable(ident);
+    if (RegisterID* local = var.local()) {
+        RefPtr<RegisterID> localReg = local;
+        if (var.isReadOnly()) {
             generator.emitReadOnlyExceptionIfNeeded();
-            localReg = generator.emitMove(generator.tempDestination(dst), localReg.get());
+            localReg = generator.emitMove(generator.tempDestination(dst), local);
         } else if (generator.vm()->typeProfiler()) {
             RefPtr<RegisterID> tempDst = generator.finalDestination(dst);
             ASSERT(dst != localReg);
@@ -909,13 +872,12 @@
     }
 
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-    ResolveScopeInfo resolveScopeInfo;
-    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, ident, resolveScopeInfo);
-    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound, resolveScopeInfo);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
+    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
     RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
-    generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound, resolveScopeInfo);
+    generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound);
     if (generator.vm()->typeProfiler()) {
-        generator.emitProfileType(value.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
+        generator.emitProfileType(value.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
     }
 
@@ -991,12 +953,12 @@
 
 RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (generator.local(m_ident).get())
+    Variable var = generator.variable(m_ident);
+    if (var.local())
         return generator.emitLoad(generator.finalDestination(dst), false);
 
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-    ResolveScopeInfo resolveScopeInfo;
-    RefPtr<RegisterID> base = generator.emitResolveScope(dst, m_ident, resolveScopeInfo);
+    RefPtr<RegisterID> base = generator.emitResolveScope(dst, var);
     return generator.emitDeleteById(generator.finalDestination(dst, base.get()), base.get(), m_ident);
 }
 
@@ -1047,19 +1009,19 @@
     return generator.emitLoad(dst, jsUndefined());
 }
 
-// ------------------------------ TypeOfValueNode -----------------------------------
+// ------------------------------ TypeOfResolveNode -----------------------------------
 
 RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (Local local = generator.local(m_ident)) {
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local()) {
         if (dst == generator.ignoredResult())
             return 0;
-        return generator.emitTypeOf(generator.finalDestination(dst), local.get());
+        return generator.emitTypeOf(generator.finalDestination(dst), local);
     }
 
-    ResolveScopeInfo resolveScopeInfo;
-    RefPtr<RegisterID> scope = generator.emitResolveScope(dst, m_ident, resolveScopeInfo);
-    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, DoNotThrowIfNotFound, resolveScopeInfo);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
+    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
     if (dst == generator.ignoredResult())
         return 0;
     return generator.emitTypeOf(generator.finalDestination(dst, scope.get()), value.get());
@@ -1085,9 +1047,10 @@
     ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
     const Identifier& ident = resolve->identifier();
 
-    if (Local local = generator.local(ident)) {
-        RefPtr<RegisterID> localReg = local.get();
-        if (local.isReadOnly()) {
+    Variable var = generator.variable(ident);
+    if (RegisterID* local = var.local()) {
+        RefPtr<RegisterID> localReg = local;
+        if (var.isReadOnly()) {
             generator.emitReadOnlyExceptionIfNeeded();
             localReg = generator.emitMove(generator.tempDestination(dst), localReg.get());
         } else if (generator.vm()->typeProfiler()) {
@@ -1104,13 +1067,12 @@
     }
 
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-    ResolveScopeInfo resolveScopeInfo;
-    RefPtr<RegisterID> scope = generator.emitResolveScope(dst, ident, resolveScopeInfo);
-    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound, resolveScopeInfo);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
+    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
     emitIncOrDec(generator, value.get(), m_operator);
-    generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound, resolveScopeInfo);
+    generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound);
     if (generator.vm()->typeProfiler()) {
-        generator.emitProfileType(value.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
+        generator.emitProfileType(value.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
     }
     return generator.moveToDestinationIfNeeded(dst, value.get());
@@ -1602,37 +1564,37 @@
 RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     JSTextPosition newDivot = divotStart() + m_ident.length();
-    if (Local local = generator.local(m_ident)) {
-        if (local.isReadOnly()) {
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local()) {
+        if (var.isReadOnly()) {
             generator.emitReadOnlyExceptionIfNeeded();
-            return emitReadModifyAssignment(generator, generator.finalDestination(dst), local.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+            return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
         }
         
         if (generator.vm()->typeProfiler()
             || generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
             RefPtr<RegisterID> result = generator.newTemporary();
-            generator.emitMove(result.get(), local.get());
+            generator.emitMove(result.get(), local);
             emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
-            generator.emitMove(local.get(), result.get());
-            generator.invalidateForInContextForLocal(local.get());
+            generator.emitMove(local, result.get());
+            generator.invalidateForInContextForLocal(local);
             if (generator.vm()->typeProfiler())
                 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
             return generator.moveToDestinationIfNeeded(dst, result.get());
         }
         
-        RegisterID* result = emitReadModifyAssignment(generator, local.get(), local.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
-        generator.invalidateForInContextForLocal(local.get());
+        RegisterID* result = emitReadModifyAssignment(generator, local, local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+        generator.invalidateForInContextForLocal(local);
         return generator.moveToDestinationIfNeeded(dst, result);
     }
 
     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
-    ResolveScopeInfo resolveScopeInfo;
-    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, m_ident, resolveScopeInfo);
-    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, ThrowIfNotFound, resolveScopeInfo);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
+    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
     RefPtr<RegisterID> result = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this);
-    RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), ThrowIfNotFound, resolveScopeInfo);
+    RegisterID* returnResult = generator.emitPutToScope(scope.get(), var, result.get(), ThrowIfNotFound);
     if (generator.vm()->typeProfiler()) {
-        generator.emitProfileType(result.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
+        generator.emitProfileType(result.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
     }
     return returnResult;
@@ -1642,36 +1604,36 @@
 
 RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (Local local = generator.local(m_ident)) {
-        if (local.isReadOnly()) {
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local()) {
+        if (var.isReadOnly()) {
             generator.emitReadOnlyExceptionIfNeeded();
             return generator.emitNode(dst, m_right);
         }
-        if (local.isSpecial() || generator.vm()->typeProfiler()) {
+        if (var.isSpecial() || generator.vm()->typeProfiler()) {
             RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
             generator.emitNode(tempDst.get(), m_right);
-            generator.emitMove(local.get(), tempDst.get());
-            generator.invalidateForInContextForLocal(local.get());
+            generator.emitMove(local, tempDst.get());
+            generator.invalidateForInContextForLocal(local);
             if (generator.vm()->typeProfiler())
                 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
             return generator.moveToDestinationIfNeeded(dst, tempDst.get());
         }
-        RegisterID* result = generator.emitNode(local.get(), m_right);
-        generator.invalidateForInContextForLocal(local.get());
+        RegisterID* result = generator.emitNode(local, m_right);
+        generator.invalidateForInContextForLocal(local);
         return generator.moveToDestinationIfNeeded(dst, result);
     }
 
     if (generator.isStrictMode())
         generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-    ResolveScopeInfo resolveScopeInfo;
-    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, m_ident, resolveScopeInfo);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
     if (dst == generator.ignoredResult())
         dst = 0;
     RefPtr<RegisterID> result = generator.emitNode(dst, m_right);
     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-    RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
+    RegisterID* returnResult = generator.emitPutToScope(scope.get(), var, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
     if (generator.vm()->typeProfiler()) {
-        generator.emitProfileType(result.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
+        generator.emitProfileType(result.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
     } 
     return returnResult;
@@ -1780,18 +1742,19 @@
 RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator)
 {
     // FIXME: This code does not match the behavior of const in Firefox.
-    if (Local local = generator.constLocal(m_ident)) {
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local()) {
         if (!m_init)
-            return local.get();
+            return local;
 
         // FIXME: Maybe call emitExpressionInfo here.
-        if (local.isSpecial() || generator.vm()->typeProfiler()) {
+        if (var.isSpecial() || generator.vm()->typeProfiler()) {
             RefPtr<RegisterID> tempDst = generator.newTemporary();
             generator.emitNode(tempDst.get(), m_init);
-            return generator.emitMove(local.get(), tempDst.get());
+            return generator.emitMove(local, tempDst.get());
         }
         
-        return generator.emitNode(local.get(), m_init);
+        return generator.emitNode(local, m_init);
     }
 
     RefPtr<RegisterID> value = m_init ? generator.emitNode(m_init) : generator.emitLoad(0, jsUndefined());
@@ -1800,18 +1763,23 @@
         return generator.emitInitGlobalConst(m_ident, value.get());
 
     if (generator.codeType() != EvalCode) {
-
-        ResolveScopeInfo resolveScopeInfo;
-        if (RefPtr<RegisterID> scope = generator.emitResolveConstantLocal(generator.newTemporary(), m_ident, resolveScopeInfo))
-            return generator.emitPutToScope(scope.get(), m_ident, value.get(), DoNotThrowIfNotFound, resolveScopeInfo);
-
-        return value.get();
+        // Do a special kind of resolution. If anything fails, then don't perform the assignment. This is
+        // pretty shady - particularly how negligent it is with inteleaving scopes - but it's the
+        // behavior that JSC has had for a long time.
+        
+        ASSERT(generator.codeType() == FunctinCode);
+        
+        var = generator.variablePerSymbolTable(m_ident);
+        if (!var.isResolved())
+            return value.get();
+        
+        RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), var);
+        return generator.emitPutToScope(scope.get(), var, value.get(), DoNotThrowIfNotFound);
     }
 
     // FIXME: This will result in incorrect assignment if m_ident exists in an intervening with scope.
-    ResolveScopeInfo resolveScopeInfo;
-    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, m_ident, resolveScopeInfo);
-    return generator.emitPutToScope(scope.get(), m_ident, value.get(), DoNotThrowIfNotFound, resolveScopeInfo);
+    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
+    return generator.emitPutToScope(scope.get(), var, value.get(), DoNotThrowIfNotFound);
 }
 
 RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
@@ -1903,13 +1871,13 @@
     if (!generator.vm()->typeProfiler())
         return nullptr;
 
-    if (Local local = generator.local(m_ident))
-        generator.emitProfileType(local.get(), ProfileTypeBytecodeHasGlobalID, nullptr);
+    Variable var = generator.variable(m_ident);
+    if (RegisterID* local = var.local())
+        generator.emitProfileType(local, ProfileTypeBytecodeHasGlobalID, nullptr);
     else {
-        ResolveScopeInfo resolveScopeInfo;
-        RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, m_ident, resolveScopeInfo);
-        RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, DoNotThrowIfNotFound, resolveScopeInfo);
-        generator.emitProfileType(value.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
+        RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
+        RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
+        generator.emitProfileType(value.get(), var.isResolved() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
     }
 
     generator.emitTypeProfilerExpressionInfo(position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
@@ -2079,8 +2047,7 @@
 {
     if (m_lexpr->isResolveNode()) {
         const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
-        Local local = generator.local(ident);
-        return local.get();
+        return generator.variable(ident).local();
     }
 
     if (m_lexpr->isDeconstructionNode()) {
@@ -2091,10 +2058,10 @@
 
         auto simpleBinding = static_cast<BindingNode*>(binding);
         const Identifier& ident = simpleBinding->boundProperty();
-        Local local = generator.local(ident);
-        if (local.isSpecial())
+        Variable var = generator.variable(ident);
+        if (var.isSpecial())
             return nullptr;
-        return local.get();
+        return var.local();
     }
 
     return nullptr;
@@ -2104,18 +2071,17 @@
 {
     if (m_lexpr->isResolveNode()) {
         const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
-        Local local = generator.local(ident);
-        if (local.get())
-            generator.emitMove(local.get(), propertyName);
+        Variable var = generator.variable(ident);
+        if (RegisterID* local = var.local())
+            generator.emitMove(local, propertyName);
         else {
             if (generator.isStrictMode())
                 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-            ResolveScopeInfo resolveScopeInfo;
-            RegisterID* scope = generator.emitResolveScope(nullptr, ident, resolveScopeInfo);
+            RegisterID* scope = generator.emitResolveScope(nullptr, var);
             generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-            generator.emitPutToScope(scope, ident, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
+            generator.emitPutToScope(scope, var, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
             if (generator.vm()->typeProfiler())
-                generator.emitProfileType(propertyName, resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
+                generator.emitProfileType(propertyName, var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
         }
         if (generator.vm()->typeProfiler())
             generator.emitTypeProfilerExpressionInfo(m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
@@ -2156,12 +2122,12 @@
 
         auto simpleBinding = static_cast<BindingNode*>(binding);
         const Identifier& ident = simpleBinding->boundProperty();
-        Local local = generator.local(ident);
-        if (!local.get() || local.isSpecial()) {
+        Variable var = generator.variable(ident);
+        if (!var.local() || var.isSpecial()) {
             assignNode->bindings()->bindValue(generator, propertyName);
             return;
         }
-        generator.emitMove(local.get(), propertyName);
+        generator.emitMove(var.local(), propertyName);
         if (generator.vm()->typeProfiler())
             generator.emitTypeProfilerExpressionInfo(simpleBinding->divotStart(), simpleBinding->divotEnd());
         return;
@@ -2329,17 +2295,17 @@
     {
         if (m_lexpr->isResolveNode()) {
             const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
-            if (Local local = generator.local(ident))
-                generator.emitMove(local.get(), value);
+            Variable var = generator.variable(ident);
+            if (RegisterID* local = var.local())
+                generator.emitMove(local, value);
             else {
                 if (generator.isStrictMode())
                     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-                ResolveScopeInfo resolveScopeInfo;
-                RegisterID* scope = generator.emitResolveScope(nullptr, ident, resolveScopeInfo);
+                RegisterID* scope = generator.emitResolveScope(nullptr, var);
                 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
-                generator.emitPutToScope(scope, ident, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
+                generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
                 if (generator.vm()->typeProfiler())
-                    generator.emitProfileType(value, resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
+                    generator.emitProfileType(value, var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
             }
             if (generator.vm()->typeProfiler())
                 generator.emitTypeProfilerExpressionInfo(m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
@@ -2964,24 +2930,6 @@
 
 RegisterID* ArrayPatternNode::emitDirectBinding(BytecodeGenerator& generator, RegisterID* dst, ExpressionNode* rhs)
 {
-    if (rhs->isResolveNode()
-        && generator.willResolveToArgumentsRegister(static_cast<ResolveNode*>(rhs)->identifier())
-        && generator.hasSafeLocalArgumentsRegister()&& !generator.symbolTable().slowArguments()) {
-        for (size_t i = 0; i < m_targetPatterns.size(); i++) {
-            auto target = m_targetPatterns[i];
-            if (!target)
-                continue;
-            
-            RefPtr<RegisterID> temp = generator.newTemporary();
-            generator.emitLoad(temp.get(), jsNumber(i));
-            generator.emitGetArgumentByVal(temp.get(), generator.uncheckedLocalArgumentsRegister(), temp.get());
-            target->bindValue(generator, temp.get());
-        }
-        if (dst == generator.ignoredResult() || !dst)
-            return generator.emitLoad(generator.finalDestination(dst), jsUndefined());
-        Local local = generator.local(generator.vm()->propertyNames->arguments);
-        return generator.moveToDestinationIfNeeded(dst, local.get());
-    }
     if (!rhs->isSimpleArray())
         return 0;
 
@@ -3069,24 +3017,24 @@
 
 void BindingNode::bindValue(BytecodeGenerator& generator, RegisterID* value) const
 {
-    if (Local local = generator.local(m_boundProperty)) {
-        if (local.isReadOnly()) {
+    Variable var = generator.variable(m_boundProperty);
+    if (RegisterID* local = var.local()) {
+        if (var.isReadOnly()) {
             generator.emitReadOnlyExceptionIfNeeded();
             return;
         }
-        generator.emitMove(local.get(), value);
+        generator.emitMove(local, value);
         if (generator.vm()->typeProfiler())
             generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
         return;
     }
     if (generator.isStrictMode())
         generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
-    ResolveScopeInfo resolveScopeInfo;
-    RegisterID* scope = generator.emitResolveScope(nullptr, m_boundProperty, resolveScopeInfo);
+    RegisterID* scope = generator.emitResolveScope(nullptr, var);
     generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
-    generator.emitPutToScope(scope, m_boundProperty, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
+    generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
     if (generator.vm()->typeProfiler()) {
-        generator.emitProfileType(value, resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_boundProperty);
+        generator.emitProfileType(value, var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_boundProperty);
         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
     }
     return;
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractHeap.h b/Source/JavaScriptCore/dfg/DFGAbstractHeap.h
index 9fe9b89..05e9ddf 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractHeap.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractHeap.h
@@ -47,7 +47,6 @@
     macro(World) \
     macro(Stack) \
     macro(Heap) \
-    macro(Arguments_registers) \
     macro(Butterfly_publicLength) \
     macro(Butterfly_vectorLength) \
     macro(GetterSetter_getter) \
@@ -57,7 +56,6 @@
     macro(JSCell_typeInfoFlags) \
     macro(JSCell_typeInfoType) \
     macro(JSObject_butterfly) \
-    macro(JSEnvironmentRecord_registers) \
     macro(JSPropertyNameEnumerator_cachedPropertyNames) \
     macro(NamedProperties) \
     macro(IndexedInt32Properties) \
@@ -65,7 +63,8 @@
     macro(IndexedContiguousProperties) \
     macro(IndexedArrayStorageProperties) \
     macro(ArrayStorageProperties) \
-    macro(Variables) \
+    macro(DirectArgumentsProperties) \
+    macro(ScopeProperties) \
     macro(TypedArrayProperties) \
     macro(HeapObjectCount) /* Used to reflect the fact that some allocations reveal object identity */\
     macro(RegExpState) \
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h b/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h
index bbc38c1..f372f64 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -148,7 +148,6 @@
     
 private:
     void clobberWorld(const CodeOrigin&, unsigned indexInBlock);
-    void clobberCapturedVars(const CodeOrigin&);
     
     template<typename Functor>
     void forAllValues(unsigned indexInBlock, Functor&);
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
index 3769378..05de909 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
@@ -131,14 +131,15 @@
     switch (node->op()) {
     case JSConstant:
     case DoubleConstant:
-    case Int52Constant:
-    case PhantomArguments: {
+    case Int52Constant: {
         setBuiltInConstant(node, *node->constant());
         break;
     }
         
     case Identity: {
         forNode(node) = forNode(node->child1());
+        if (forNode(node).value())
+            m_state.setFoundConstants(true);
         break;
     }
         
@@ -207,7 +208,11 @@
         ASSERT(!m_state.variables().operand(node->local()).isClear());
         break;
         
-    case LoadVarargs: {
+    case LoadVarargs:
+    case ForwardVarargs: {
+        // FIXME: ForwardVarargs should check if the count becomes known, and if it does, it should turn
+        // itself into a straight-line sequence of GetStack/PutStack.
+        // https://bugs.webkit.org/show_bug.cgi?id=143071
         clobberWorld(node->origin.semantic, clobberLimit);
         LoadVarargsData* data = node->loadVarargsData();
         m_state.variables().operand(data->count).setType(SpecInt32);
@@ -879,7 +884,7 @@
             break;
         }
         
-        if (isFinalObjectSpeculation(abstractChild.m_type) || isArraySpeculation(abstractChild.m_type) || isArgumentsSpeculation(abstractChild.m_type)) {
+        if (isFinalObjectSpeculation(abstractChild.m_type) || isArraySpeculation(abstractChild.m_type) || isDirectArgumentsSpeculation(abstractChild.m_type) || isScopedArgumentsSpeculation(abstractChild.m_type)) {
             setConstant(node, *m_graph.freeze(vm->smallStrings.objectString()));
             break;
         }
@@ -1031,7 +1036,8 @@
             } else
                 forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
             break;
-        case Array::Arguments:
+        case Array::DirectArguments:
+        case Array::ScopedArguments:
             forNode(node).makeHeapTop();
             break;
         case Array::Int32:
@@ -1138,6 +1144,51 @@
         clobberWorld(node->origin.semantic, clobberLimit);
         forNode(node).makeHeapTop();
         break;
+        
+    case GetMyArgumentByVal: {
+        JSValue index = forNode(node->child2()).m_value;
+        InlineCallFrame* inlineCallFrame = node->child1()->origin.semantic.inlineCallFrame;
+
+        if (index && index.isInt32()) {
+            // This pretends to return TOP for accesses that are actually proven out-of-bounds because
+            // that's the conservative thing to do. Otherwise we'd need to write more code to mark such
+            // paths as unreachable, and it's almost certainly not worth the effort.
+            
+            if (inlineCallFrame) {
+                if (index.asUInt32() < inlineCallFrame->arguments.size() - 1) {
+                    forNode(node) = m_state.variables().operand(
+                        virtualRegisterForArgument(index.asInt32() + 1) + inlineCallFrame->stackOffset);
+                    m_state.setFoundConstants(true);
+                    break;
+                }
+            } else {
+                if (index.asUInt32() < m_state.variables().numberOfArguments() - 1) {
+                    forNode(node) = m_state.variables().argument(index.asInt32() + 1);
+                    m_state.setFoundConstants(true);
+                    break;
+                }
+            }
+        }
+        
+        if (inlineCallFrame) {
+            // We have a bound on the types even though it's random access. Take advantage of this.
+            
+            AbstractValue result;
+            for (unsigned i = inlineCallFrame->arguments.size(); i-- > 1;) {
+                result.merge(
+                    m_state.variables().operand(
+                        virtualRegisterForArgument(i) + inlineCallFrame->stackOffset));
+            }
+            
+            if (result.value())
+                m_state.setFoundConstants(true);
+            forNode(node) = result;
+            break;
+        }
+        
+        forNode(node).makeHeapTop();
+        break;
+    }
             
     case RegExpExec:
         forNode(node).makeHeapTop();
@@ -1303,6 +1354,8 @@
         break;
         
     case PhantomNewObject:
+    case PhantomDirectArguments:
+    case PhantomClonedArguments:
     case BottomValue:
         m_state.setDidClobber(true); // Prevent constant folding.
         // This claims to return bottom.
@@ -1332,87 +1385,19 @@
     case TypedArrayWatchpoint:
         break;
     
-    case CreateArguments:
-        forNode(node) = forNode(node->child1());
-        forNode(node).filter(~SpecEmpty);
-        forNode(node).merge(SpecArguments);
+    case CreateDirectArguments:
+        forNode(node).set(m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->directArgumentsStructure());
         break;
         
-    case TearOffArguments:
-        // Does nothing that is user-visible.
-        break;
-
-    case CheckArgumentsNotCreated:
-        if (isEmptySpeculation(
-                m_state.variables().operand(
-                    m_graph.argumentsRegisterFor(node->origin.semantic).offset()).m_type))
-            m_state.setFoundConstants(true);
+    case CreateScopedArguments:
+        forNode(node).set(m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->scopedArgumentsStructure());
         break;
         
-    case GetMyArgumentsLength:
-        // We know that this executable does not escape its arguments, so we can optimize
-        // the arguments a bit. Note that this is not sufficient to force constant folding
-        // of GetMyArgumentsLength, because GetMyArgumentsLength is a clobbering operation.
-        // We perform further optimizations on this later on.
-        if (node->origin.semantic.inlineCallFrame
-            && !node->origin.semantic.inlineCallFrame->isVarargs()) {
-            setConstant(
-                node, jsNumber(node->origin.semantic.inlineCallFrame->arguments.size() - 1));
-            m_state.setDidClobber(true); // Pretend that we clobbered to prevent constant folding.
-        } else
-            forNode(node).setType(SpecInt32);
+    case CreateClonedArguments:
+        forNode(node).setType(SpecObjectOther);
         break;
         
-    case GetMyArgumentsLengthSafe:
-        // This potentially clobbers all structures if the arguments object had a getter
-        // installed on the length property.
-        clobberWorld(node->origin.semantic, clobberLimit);
-        // We currently make no guarantee about what this returns because it does not
-        // speculate that the length property is actually a length.
-        forNode(node).makeHeapTop();
-        break;
-        
-    case GetMyArgumentByVal: {
-        InlineCallFrame* inlineCallFrame = node->origin.semantic.inlineCallFrame;
-        JSValue value = forNode(node->child1()).m_value;
-        if (inlineCallFrame && value && value.isInt32()) {
-            int32_t index = value.asInt32();
-            if (index >= 0
-                && static_cast<size_t>(index + 1) < inlineCallFrame->arguments.size()) {
-                forNode(node) = m_state.variables().operand(
-                    inlineCallFrame->stackOffset +
-                    m_graph.baselineCodeBlockFor(inlineCallFrame)->argumentIndexAfterCapture(index));
-                m_state.setFoundConstants(true);
-                break;
-            }
-        }
-        forNode(node).makeHeapTop();
-        break;
-    }
-        
-    case GetMyArgumentByValSafe:
-        // This potentially clobbers all structures if the property we're accessing has
-        // a getter. We don't speculate against this.
-        clobberWorld(node->origin.semantic, clobberLimit);
-        // And the result is unknown.
-        forNode(node).makeHeapTop();
-        break;
-        
-    case NewFunction: {
-        AbstractValue& value = forNode(node);
-        value = forNode(node->child1());
-        
-        if (!(value.m_type & SpecEmpty)) {
-            m_state.setFoundConstants(true);
-            break;
-        }
-
-        value.setType((value.m_type & ~SpecEmpty) | SpecFunction);
-        break;
-    }
-
-    case NewFunctionExpression:
-    case NewFunctionNoCheck:
+    case NewFunction:
         forNode(node).set(
             m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->functionStructure());
         break;
@@ -1421,6 +1406,10 @@
         forNode(node).setType(SpecFunction);
         break;
         
+    case GetArgumentCount:
+        forNode(node).setType(SpecInt32);
+        break;
+        
     case GetGetter: {
         JSValue base = forNode(node->child1()).m_value;
         if (base) {
@@ -1469,12 +1458,8 @@
         break;
     }
 
-    case GetClosureRegisters:
-        forNode(node).clear(); // The result is not a JS value.
-        break;
-
     case GetClosureVar:
-        if (JSValue value = m_graph.tryGetConstantClosureVar(forNode(node->child1()), VirtualRegister(node->varNumber()))) {
+        if (JSValue value = m_graph.tryGetConstantClosureVar(forNode(node->child1()), node->scopeOffset())) {
             setConstant(node, *m_graph.freeze(value));
             break;
         }
@@ -1482,7 +1467,13 @@
         break;
             
     case PutClosureVar:
-        clobberCapturedVars(node->origin.semantic);
+        break;
+        
+    case GetFromArguments:
+        forNode(node).makeHeapTop();
+        break;
+        
+    case PutToArguments:
         break;
             
     case GetById:
@@ -1626,8 +1617,11 @@
         case Array::ArrayStorage:
         case Array::SlowPutArrayStorage:
             break;
-        case Array::Arguments:
-            filter(node->child1(), SpecArguments);
+        case Array::DirectArguments:
+            filter(node->child1(), SpecDirectArguments);
+            break;
+        case Array::ScopedArguments:
+            filter(node->child1(), SpecScopedArguments);
             break;
         case Array::Int8Array:
             filter(node->child1(), SpecInt8Array);
@@ -2026,6 +2020,7 @@
     case CallVarargs:
     case CallForwardVarargs:
     case ConstructVarargs:
+    case ConstructForwardVarargs:
         clobberWorld(node->origin.semantic, clobberLimit);
         forNode(node).makeHeapTop();
         break;
@@ -2120,37 +2115,12 @@
 
 template<typename AbstractStateType>
 void AbstractInterpreter<AbstractStateType>::clobberWorld(
-    const CodeOrigin& codeOrigin, unsigned clobberLimit)
+    const CodeOrigin&, unsigned clobberLimit)
 {
-    clobberCapturedVars(codeOrigin);
     clobberStructures(clobberLimit);
 }
 
 template<typename AbstractStateType>
-void AbstractInterpreter<AbstractStateType>::clobberCapturedVars(const CodeOrigin& codeOrigin)
-{
-    SamplingRegion samplingRegion("DFG AI Clobber Captured Vars");
-    if (codeOrigin.inlineCallFrame) {
-        const BitVector& capturedVars = codeOrigin.inlineCallFrame->capturedVars;
-        for (size_t i = capturedVars.size(); i--;) {
-            if (!capturedVars.quickGet(i))
-                continue;
-            m_state.variables().local(i).makeHeapTop();
-        }
-    } else {
-        for (size_t i = m_codeBlock->m_numVars; i--;) {
-            if (m_codeBlock->isCaptured(virtualRegisterForLocal(i)))
-                m_state.variables().local(i).makeHeapTop();
-        }
-    }
-
-    for (size_t i = m_state.variables().numberOfArguments(); i--;) {
-        if (m_codeBlock->isCaptured(virtualRegisterForArgument(i)))
-            m_state.variables().argument(i).makeHeapTop();
-    }
-}
-
-template<typename AbstractStateType>
 template<typename Functor>
 void AbstractInterpreter<AbstractStateType>::forAllValues(
     unsigned clobberLimit, Functor& functor)
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractValue.h b/Source/JavaScriptCore/dfg/DFGAbstractValue.h
index 2608acb..7ee5a97 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractValue.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractValue.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -346,18 +346,16 @@
     
     // This is a proven constraint on the possible types that this value can have
     // now or any time in the future, unless it is reassigned. This field is
-    // impervious to side-effects unless the side-effect can reassign the value
-    // (for example if we're talking about a captured variable). The relationship
-    // between this field, and the structure fields above, is as follows. The
-    // fields above constraint the structures that a cell may have, but they say
-    // nothing about whether or not the value is known to be a cell. More formally,
-    // the m_structure is itself an abstract value that consists of the
-    // union of the set of all non-cell values and the set of cell values that have
-    // the given structure. This abstract value is then the intersection of the
-    // m_structure and the set of values whose type is m_type. So, for
-    // example if m_type is SpecFinal|SpecInt32 and m_structure is
-    // [0x12345] then this abstract value corresponds to the set of all integers
-    // unified with the set of all objects with structure 0x12345.
+    // impervious to side-effects. The relationship between this field, and the
+    // structure fields above, is as follows. The fields above constraint the
+    // structures that a cell may have, but they say nothing about whether or not
+    // the value is known to be a cell. More formally, the m_structure is itself an
+    // abstract value that consists of the union of the set of all non-cell values
+    // and the set of cell values that have the given structure. This abstract
+    // value is then the intersection of the m_structure and the set of values
+    // whose type is m_type. So, for example if m_type is SpecFinal|SpecInt32 and
+    // m_structure is [0x12345] then this abstract value corresponds to the set of
+    // all integers unified with the set of all objects with structure 0x12345.
     SpeculatedType m_type;
     
     // This is a proven constraint on the possible indexing types that this value
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentPosition.h b/Source/JavaScriptCore/dfg/DFGArgumentPosition.h
index 35c9a6f..a6983a7 100644
--- a/Source/JavaScriptCore/dfg/DFGArgumentPosition.h
+++ b/Source/JavaScriptCore/dfg/DFGArgumentPosition.h
@@ -46,6 +46,9 @@
     void addVariable(VariableAccessData* variable)
     {
         m_variables.append(variable);
+        
+        // We may set this early. Merging it here saves us time in prediction propagation.
+        variable->mergeShouldNeverUnbox(m_shouldNeverUnbox);
     }
     
     VariableAccessData* someVariable() const
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp b/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp
new file mode 100644
index 0000000..4901408
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp
@@ -0,0 +1,566 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGArgumentsEliminationPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "BytecodeLivenessAnalysisInlines.h"
+#include "DFGArgumentsUtilities.h"
+#include "DFGBasicBlockInlines.h"
+#include "DFGBlockMapInlines.h"
+#include "DFGClobberize.h"
+#include "DFGForAllKills.h"
+#include "DFGGraph.h"
+#include "DFGInsertionSet.h"
+#include "DFGLivenessAnalysisPhase.h"
+#include "DFGOSRAvailabilityAnalysisPhase.h"
+#include "DFGPhase.h"
+#include "JSCInlines.h"
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+
+namespace JSC { namespace DFG {
+
+namespace {
+
+class ArgumentsEliminationPhase : public Phase {
+public:
+    ArgumentsEliminationPhase(Graph& graph)
+        : Phase(graph, "arguments elimination")
+    {
+    }
+    
+    bool run()
+    {
+        // For now this phase only works on SSA. This could be changed; we could have a block-local
+        // version over LoadStore.
+        DFG_ASSERT(m_graph, nullptr, m_graph.m_form == SSA);
+        
+        identifyCandidates();
+        if (m_candidates.isEmpty())
+            return false;
+        
+        eliminateCandidatesThatEscape();
+        if (m_candidates.isEmpty())
+            return false;
+        
+        eliminateCandidatesThatInterfere();
+        if (m_candidates.isEmpty())
+            return false;
+        
+        transform();
+        
+        return true;
+    }
+
+private:
+    // Just finds nodes that we know how to work with.
+    void identifyCandidates()
+    {
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (Node* node : *block) {
+                switch (node->op()) {
+                case CreateDirectArguments:
+                case CreateClonedArguments:
+                    m_candidates.add(node);
+                    break;
+                    
+                case CreateScopedArguments:
+                    // FIXME: We could handle this if it wasn't for the fact that scoped arguments are
+                    // always stored into the activation.
+                    // https://bugs.webkit.org/show_bug.cgi?id=143072 and
+                    // https://bugs.webkit.org/show_bug.cgi?id=143073
+                    break;
+                    
+                default:
+                    break;
+                }
+            }
+        }
+    }
+    
+    // Look for escaping sites, and remove from the candidates set if we see an escape.
+    void eliminateCandidatesThatEscape()
+    {
+        auto escape = [&] (Edge edge) {
+            if (!edge)
+                return;
+            m_candidates.remove(edge.node());
+        };
+        
+        auto escapeBasedOnArrayMode = [&] (ArrayMode mode, Edge edge) {
+            switch (mode.type()) {
+            case Array::DirectArguments:
+                if (edge->op() != CreateDirectArguments)
+                    escape(edge);
+                break;
+            
+            case Array::Int32:
+            case Array::Double:
+            case Array::Contiguous:
+                if (edge->op() != CreateClonedArguments)
+                    escape(edge);
+                break;
+            
+            default:
+                escape(edge);
+                break;
+            }
+        };
+        
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (Node* node : *block) {
+                switch (node->op()) {
+                case GetFromArguments:
+                    DFG_ASSERT(m_graph, node, node->child1()->op() == CreateDirectArguments);
+                    break;
+                    
+                case GetByVal:
+                    escapeBasedOnArrayMode(node->arrayMode(), node->child1());
+                    escape(node->child2());
+                    escape(node->child3());
+                    break;
+                    
+                case GetArrayLength:
+                    escapeBasedOnArrayMode(node->arrayMode(), node->child1());
+                    escape(node->child2());
+                    break;
+                    
+                case LoadVarargs:
+                    break;
+                    
+                case CallVarargs:
+                case ConstructVarargs:
+                    escape(node->child1());
+                    escape(node->child3());
+                    break;
+
+                case Phantom:
+                case Check:
+                case HardPhantom:
+                case MovHint:
+                case PutHint:
+                    break;
+                    
+                case GetButterfly:
+                    // This barely works. The danger is that the GetButterfly is used by something that
+                    // does something escaping to a candidate. Fortunately, the only butterfly-using ops
+                    // that we exempt here also use the candidate directly. If there ever was a
+                    // butterfly-using op that we wanted to exempt, then we'd have to look at the
+                    // butterfly's child and check if it's a candidate.
+                    break;
+                    
+                case CheckArray:
+                    escapeBasedOnArrayMode(node->arrayMode(), node->child1());
+                    break;
+                    
+                // FIXME: For cloned arguments, we'd like to allow GetByOffset on length to not be
+                // an escape.
+                // https://bugs.webkit.org/show_bug.cgi?id=143074
+                    
+                // FIXME: We should be able to handle GetById/GetByOffset on callee.
+                // https://bugs.webkit.org/show_bug.cgi?id=143075
+                    
+                default:
+                    m_graph.doToChildren(node, escape);
+                    break;
+                }
+            }
+        }
+    }
+
+    // Anywhere that a candidate is live (in bytecode or in DFG), check if there is a chance of
+    // interference between the stack area that the arguments object copies from and the arguments
+    // object's payload. Conservatively this means that the stack region doesn't get stored to.
+    void eliminateCandidatesThatInterfere()
+    {
+        performLivenessAnalysis(m_graph);
+        performOSRAvailabilityAnalysis(m_graph);
+        m_graph.initializeNodeOwners();
+        
+        BlockMap<Operands<bool>> clobberedByBlock(m_graph);
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            Operands<bool>& clobberedByThisBlock = clobberedByBlock[block];
+            clobberedByThisBlock = Operands<bool>(OperandsLike, m_graph.block(0)->variablesAtHead);
+            for (Node* node : *block) {
+                clobberize(
+                    m_graph, node, NoOpClobberize(),
+                    [&] (AbstractHeap heap) {
+                        if (heap.kind() != Stack) {
+                            ASSERT(!heap.overlaps(Stack));
+                            return;
+                        }
+                        ASSERT(!heap.payload().isTop());
+                        VirtualRegister reg(heap.payload().value32());
+                        clobberedByThisBlock.operand(reg) = true;
+                    },
+                    NoOpClobberize());
+            }
+        }
+        
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            // Stop if we've already removed all candidates.
+            if (m_candidates.isEmpty())
+                return;
+            
+            // Ignore blocks that don't write to the stack.
+            bool writesToStack = false;
+            for (unsigned i = clobberedByBlock[block].size(); i--;) {
+                if (clobberedByBlock[block][i]) {
+                    writesToStack = true;
+                    break;
+                }
+            }
+            if (!writesToStack)
+                continue;
+            
+            forAllKillsInBlock(
+                m_graph, block,
+                [&] (unsigned nodeIndex, Node* candidate) {
+                    if (!m_candidates.contains(candidate))
+                        return;
+                    
+                    // Check if this block has any clobbers that affect this candidate. This is a fairly
+                    // fast check.
+                    bool isClobberedByBlock = false;
+                    Operands<bool>& clobberedByThisBlock = clobberedByBlock[block];
+                    
+                    if (InlineCallFrame* inlineCallFrame = candidate->origin.semantic.inlineCallFrame) {
+                        if (inlineCallFrame->isVarargs()) {
+                            isClobberedByBlock |= clobberedByThisBlock.operand(
+                                inlineCallFrame->stackOffset + JSStack::ArgumentCount);
+                        }
+                        
+                        if (!isClobberedByBlock || inlineCallFrame->isClosureCall) {
+                            isClobberedByBlock |= clobberedByThisBlock.operand(
+                                inlineCallFrame->stackOffset + JSStack::Callee);
+                        }
+                        
+                        if (!isClobberedByBlock) {
+                            for (unsigned i = 0; i < inlineCallFrame->arguments.size() - 1; ++i) {
+                                VirtualRegister reg =
+                                    VirtualRegister(inlineCallFrame->stackOffset) +
+                                    CallFrame::argumentOffset(i);
+                                if (clobberedByThisBlock.operand(reg)) {
+                                    isClobberedByBlock = true;
+                                    break;
+                                }
+                            }
+                        }
+                    } else {
+                        // We don't include the ArgumentCount or Callee in this case because we can be
+                        // damn sure that this won't be clobbered.
+                        for (unsigned i = 1; i < static_cast<unsigned>(codeBlock()->numParameters()); ++i) {
+                            if (clobberedByThisBlock.argument(i)) {
+                                isClobberedByBlock = true;
+                                break;
+                            }
+                        }
+                    }
+                    
+                    if (!isClobberedByBlock)
+                        return;
+                    
+                    // Check if we can immediately eliminate this candidate. If the block has a clobber
+                    // for this arguments allocation, and we'd have to examine every node in the block,
+                    // then we can just eliminate the candidate.
+                    if (nodeIndex == block->size() && candidate->owner != block) {
+                        m_candidates.remove(candidate);
+                        return;
+                    }
+                    
+                    while (nodeIndex--) {
+                        Node* node = block->at(nodeIndex);
+                        if (node == candidate)
+                            break;
+                        
+                        bool found = false;
+                        clobberize(
+                            m_graph, node, NoOpClobberize(),
+                            [&] (AbstractHeap heap) {
+                                if (heap.kind() == Stack && !heap.payload().isTop()) {
+                                    if (argumentsInvolveStackSlot(candidate, VirtualRegister(heap.payload().value32())))
+                                        found = true;
+                                    return;
+                                }
+                                if (heap.overlaps(Stack))
+                                    found = true;
+                            },
+                            NoOpClobberize());
+                        
+                        if (found) {
+                            m_candidates.remove(candidate);
+                            return;
+                        }
+                    }
+                });
+        }
+        
+        // Q: How do we handle OSR exit with a live PhantomArguments at a point where the inline call
+        // frame is dead?  A: Naively we could say that PhantomArguments must escape the stack slots. But
+        // that would break PutStack sinking, which in turn would break object allocation sinking, in
+        // cases where we have a varargs call to an otherwise pure method. So, we need something smarter.
+        // For the outermost arguments, we just have a PhantomArguments that magically knows that it
+        // should load the arguments from the call frame. For the inline arguments, we have the heap map
+        // in the availabiltiy map track each possible inline argument as a promoted heap location. If the
+        // PutStacks for those arguments aren't sunk, those heap locations will map to very trivial
+        // availabilities (they will be flush availabilities). But if sinking happens then those
+        // availabilities may become whatever. OSR exit should be able to handle this quite naturally,
+        // since those availabilities speak of the stack before the optimizing compiler stack frame is
+        // torn down.
+    }
+    
+    void transform()
+    {
+        InsertionSet insertionSet(m_graph);
+        
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
+                Node* node = block->at(nodeIndex);
+                
+                auto getArrayLength = [&] (Node* candidate) -> Node* {
+                    return emitCodeToGetArgumentsArrayLength(
+                        insertionSet, candidate, nodeIndex, node->origin);
+                };
+        
+                switch (node->op()) {
+                case CreateDirectArguments:
+                    if (!m_candidates.contains(node))
+                        break;
+                    
+                    node->setOpAndDefaultFlags(PhantomDirectArguments);
+                    insertionSet.insertNode(nodeIndex + 1, SpecNone, Phantom, node->origin, Edge(node));
+                    break;
+                    
+                case CreateClonedArguments:
+                    if (!m_candidates.contains(node))
+                        break;
+                    
+                    node->setOpAndDefaultFlags(PhantomClonedArguments);
+                    insertionSet.insertNode(nodeIndex + 1, SpecNone, Phantom, node->origin, Edge(node));
+                    break;
+                    
+                case GetFromArguments: {
+                    Node* candidate = node->child1().node();
+                    if (!m_candidates.contains(candidate))
+                        break;
+                    
+                    DFG_ASSERT(
+                        m_graph, node,
+                        node->child1()->op() == CreateDirectArguments
+                        || node->child1()->op() == PhantomDirectArguments);
+                    VirtualRegister reg =
+                        virtualRegisterForArgument(node->capturedArgumentsOffset().offset() + 1) +
+                        node->origin.semantic.stackOffset();
+                    StackAccessData* data = m_graph.m_stackAccessData.add(reg, FlushedJSValue);
+                    node->convertToGetStack(data);
+                    break;
+                }
+                    
+                case GetArrayLength: {
+                    Node* candidate = node->child1().node();
+                    if (!m_candidates.contains(candidate))
+                        break;
+                    
+                    // Meh, this is kind of hackish - we use an Identity so that we can reuse the
+                    // getArrayLength() helper.
+                    node->convertToIdentityOn(getArrayLength(candidate));
+                    break;
+                }
+                    
+                case GetByVal: {
+                    // FIXME: For ClonedArguments, we would have already done a separate bounds check.
+                    // This code will cause us to have two bounds checks - the original one that we
+                    // already factored out in SSALoweringPhase, and the new one we insert here, which is
+                    // often implicitly part of GetMyArgumentByVal. LLVM will probably eliminate the
+                    // second bounds check, but still - that's just silly.
+                    // https://bugs.webkit.org/show_bug.cgi?id=143076
+                    
+                    Node* candidate = node->child1().node();
+                    if (!m_candidates.contains(candidate))
+                        break;
+                    
+                    Node* result = nullptr;
+                    if (node->child2()->isInt32Constant()) {
+                        unsigned index = node->child2()->asUInt32();
+                        InlineCallFrame* inlineCallFrame = candidate->origin.semantic.inlineCallFrame;
+                        
+                        bool safeToGetStack;
+                        if (inlineCallFrame)
+                            safeToGetStack = index < inlineCallFrame->arguments.size() - 1;
+                        else {
+                            safeToGetStack =
+                                index < static_cast<unsigned>(codeBlock()->numParameters()) - 1;
+                        }
+                        if (safeToGetStack) {
+                            StackAccessData* data;
+                            VirtualRegister arg = virtualRegisterForArgument(index + 1);
+                            if (inlineCallFrame)
+                                arg += inlineCallFrame->stackOffset;
+                            data = m_graph.m_stackAccessData.add(arg, FlushedJSValue);
+                            
+                            if (!inlineCallFrame || inlineCallFrame->isVarargs()
+                                || index >= inlineCallFrame->arguments.size() - 1) {
+                                insertionSet.insertNode(
+                                    nodeIndex, SpecNone, CheckInBounds, node->origin,
+                                    node->child2(), Edge(getArrayLength(candidate), Int32Use));
+                            }
+                            
+                            result = insertionSet.insertNode(
+                                nodeIndex, node->prediction(), GetStack, node->origin, OpInfo(data));
+                        }
+                    }
+                    
+                    if (!result) {
+                        result = insertionSet.insertNode(
+                            nodeIndex, node->prediction(), GetMyArgumentByVal, node->origin,
+                            node->child1(), node->child2());
+                    }
+                    
+                    // Need to do this because we may have a data format conversion here.
+                    node->convertToIdentityOn(result);
+                    break;
+                }
+                    
+                case LoadVarargs: {
+                    Node* candidate = node->child1().node();
+                    if (!m_candidates.contains(candidate))
+                        break;
+                    
+                    LoadVarargsData* varargsData = node->loadVarargsData();
+                    InlineCallFrame* inlineCallFrame = candidate->origin.semantic.inlineCallFrame;
+                    if (inlineCallFrame && !inlineCallFrame->isVarargs()) {
+                        Node* argumentCount = insertionSet.insertConstant(
+                            nodeIndex, node->origin,
+                            jsNumber(inlineCallFrame->arguments.size() - varargsData->offset));
+                        insertionSet.insertNode(
+                            nodeIndex, SpecNone, MovHint, node->origin,
+                            OpInfo(varargsData->count.offset()), Edge(argumentCount));
+                        insertionSet.insertNode(
+                            nodeIndex, SpecNone, PutStack, node->origin,
+                            OpInfo(m_graph.m_stackAccessData.add(varargsData->count, FlushedInt32)),
+                            Edge(argumentCount, Int32Use));
+                        
+                        for (unsigned i = 1 + varargsData->offset; i < inlineCallFrame->arguments.size(); ++i) {
+                            StackAccessData* data = m_graph.m_stackAccessData.add(
+                                virtualRegisterForArgument(i) + inlineCallFrame->stackOffset,
+                                FlushedJSValue);
+                            
+                            Node* value = insertionSet.insertNode(
+                                nodeIndex, SpecNone, GetStack, node->origin, OpInfo(data));
+                            
+                            VirtualRegister reg = varargsData->start + i - 1 - varargsData->offset;
+                            
+                            insertionSet.insertNode(
+                                nodeIndex, SpecNone, MovHint, node->origin, OpInfo(reg.offset()),
+                                Edge(value));
+                            
+                            data = m_graph.m_stackAccessData.add(reg, FlushedJSValue);
+                            
+                            insertionSet.insertNode(
+                                nodeIndex, SpecNone, PutStack, node->origin, OpInfo(data), Edge(value));
+                        }
+                        
+                        node->convertToPhantom();
+                        break;
+                    }
+                    
+                    node->setOpAndDefaultFlags(ForwardVarargs);
+                    break;
+                }
+                    
+                case CallVarargs:
+                case ConstructVarargs: {
+                    Node* candidate = node->child2().node();
+                    if (!m_candidates.contains(candidate))
+                        break;
+                    
+                    CallVarargsData* varargsData = node->callVarargsData();
+                    InlineCallFrame* inlineCallFrame = candidate->origin.semantic.inlineCallFrame;
+                    if (inlineCallFrame && !inlineCallFrame->isVarargs()) {
+                        Vector<Node*> arguments;
+                        for (unsigned i = 1 + varargsData->firstVarArgOffset; i < inlineCallFrame->arguments.size(); ++i) {
+                            StackAccessData* data = m_graph.m_stackAccessData.add(
+                                virtualRegisterForArgument(i) + inlineCallFrame->stackOffset,
+                                FlushedJSValue);
+                            
+                            Node* value = insertionSet.insertNode(
+                                nodeIndex, SpecNone, GetStack, node->origin, OpInfo(data));
+                            
+                            arguments.append(value);
+                        }
+                        
+                        unsigned firstChild = m_graph.m_varArgChildren.size();
+                        m_graph.m_varArgChildren.append(node->child1());
+                        m_graph.m_varArgChildren.append(node->child3());
+                        for (Node* argument : arguments)
+                            m_graph.m_varArgChildren.append(Edge(argument));
+                        node->setOpAndDefaultFlags(
+                            node->op() == CallVarargs ? Call : Construct);
+                        node->children = AdjacencyList(
+                            AdjacencyList::Variable,
+                            firstChild, m_graph.m_varArgChildren.size() - firstChild);
+                        break;
+                    }
+                    
+                    node->setOpAndDefaultFlags(
+                        node->op() == CallVarargs ? CallForwardVarargs : ConstructForwardVarargs);
+                    break;
+                }
+                    
+                case CheckArray:
+                case GetButterfly: {
+                    if (!m_candidates.contains(node->child1().node()))
+                        break;
+                    node->convertToPhantom();
+                    break;
+                }
+                    
+                default:
+                    break;
+                }
+            }
+            
+            insertionSet.execute(block);
+        }
+    }
+    
+    HashSet<Node*> m_candidates;
+};
+
+} // anonymous namespace
+
+bool performArgumentsElimination(Graph& graph)
+{
+    SamplingRegion samplingRegion("DFG Arguments Elimination Phase");
+    return runPhase<ArgumentsEliminationPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h b/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.h
similarity index 77%
copy from Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h
copy to Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.h
index 25098ca..520b228 100644
--- a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h
+++ b/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,8 +23,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#ifndef DFGArgumentsSimplificationPhase_h
-#define DFGArgumentsSimplificationPhase_h
+#ifndef DFGArgumentsEliminationPhase_h
+#define DFGArgumentsEliminationPhase_h
 
 #if ENABLE(DFG_JIT)
 
@@ -32,16 +32,14 @@
 
 class Graph;
 
-// Simplifies reflective uses of the Arguments object:
-//
-// Inlined arguments.length -> constant
-// Inlined arguments[constant] -> GetLocalUnlinked
+// Eliminates allocations of the Arguments-class objects when it can prove that the object doesn't escape
+// and none of the arguments are mutated (either via the object or via the stack).
 
-bool performArgumentsSimplification(Graph&);
+bool performArgumentsElimination(Graph&);
 
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
 
-#endif // DFGArgumentsSimplificationPhase_h
+#endif // DFGArgumentsEliminationPhase_h
 
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp b/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp
deleted file mode 100644
index c98fad5..0000000
--- a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp
+++ /dev/null
@@ -1,794 +0,0 @@
-/*
- * Copyright (C) 2012, 2013, 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "config.h"
-#include "DFGArgumentsSimplificationPhase.h"
-
-#if ENABLE(DFG_JIT)
-
-#include "DFGBasicBlock.h"
-#include "DFGGraph.h"
-#include "DFGInsertionSet.h"
-#include "DFGPhase.h"
-#include "DFGValidate.h"
-#include "DFGVariableAccessDataDump.h"
-#include "JSCInlines.h"
-#include <wtf/HashSet.h>
-#include <wtf/HashMap.h>
-
-namespace JSC { namespace DFG {
-
-namespace {
-
-struct ArgumentsAliasingData {
-    InlineCallFrame* callContext;
-    bool callContextSet;
-    bool multipleCallContexts;
-    
-    bool assignedFromArguments;
-    bool assignedFromManyThings;
-    
-    bool escapes;
-    
-    ArgumentsAliasingData()
-        : callContext(0)
-        , callContextSet(false)
-        , multipleCallContexts(false)
-        , assignedFromArguments(false)
-        , assignedFromManyThings(false)
-        , escapes(false)
-    {
-    }
-    
-    void mergeCallContext(InlineCallFrame* newCallContext)
-    {
-        if (multipleCallContexts)
-            return;
-        
-        if (!callContextSet) {
-            callContext = newCallContext;
-            callContextSet = true;
-            return;
-        }
-        
-        if (callContext == newCallContext)
-            return;
-        
-        multipleCallContexts = true;
-    }
-    
-    bool callContextIsValid()
-    {
-        return callContextSet && !multipleCallContexts;
-    }
-    
-    void mergeArgumentsAssignment()
-    {
-        assignedFromArguments = true;
-    }
-    
-    void mergeNonArgumentsAssignment()
-    {
-        assignedFromManyThings = true;
-    }
-    
-    bool argumentsAssignmentIsValid()
-    {
-        return assignedFromArguments && !assignedFromManyThings;
-    }
-    
-    bool isValid()
-    {
-        return callContextIsValid() && argumentsAssignmentIsValid() && !escapes;
-    }
-};
-
-} // end anonymous namespace
-
-class ArgumentsSimplificationPhase : public Phase {
-public:
-    ArgumentsSimplificationPhase(Graph& graph)
-        : Phase(graph, "arguments simplification")
-    {
-    }
-    
-    bool run()
-    {
-        if (!m_graph.m_hasArguments)
-            return false;
-        
-        bool changed = false;
-        
-        // Record which arguments are known to escape no matter what.
-        for (InlineCallFrameSet::iterator iter = m_graph.m_plan.inlineCallFrames->begin(); !!iter; ++iter)
-            pruneObviousArgumentCreations(*iter);
-        pruneObviousArgumentCreations(0); // the machine call frame.
-        
-        // Create data for variable access datas that we will want to analyze.
-        for (unsigned i = m_graph.m_variableAccessData.size(); i--;) {
-            VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
-            if (!variableAccessData->isRoot())
-                continue;
-            if (variableAccessData->isCaptured())
-                continue;
-            m_argumentsAliasing.add(variableAccessData, ArgumentsAliasingData());
-        }
-        
-        // Figure out which variables are live, using a conservative approximation of
-        // liveness.
-        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) {
-                Node* node = block->at(indexInBlock);
-                switch (node->op()) {
-                case GetLocal:
-                case Flush:
-                case PhantomLocal:
-                    m_isLive.add(node->variableAccessData());
-                    break;
-                default:
-                    break;
-                }
-            }
-        }
-        
-        // Figure out which variables alias the arguments and nothing else, and are
-        // 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.numBlocks(); ++blockIndex) {
-            BasicBlock* block = m_graph.block(blockIndex);
-            if (!block)
-                continue;
-            for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
-                Node* node = block->at(indexInBlock);
-                switch (node->op()) {
-                case CreateArguments: {
-                    // Ignore this op. If we see a lone CreateArguments then we want to
-                    // completely ignore it because:
-                    // 1) The default would be to see that the child is a GetLocal on the
-                    //    arguments register and conclude that we have an arguments escape.
-                    // 2) The fact that a CreateArguments exists does not mean that it
-                    //    will continue to exist after we're done with this phase. As far
-                    //    as this phase is concerned, a CreateArguments only "exists" if it
-                    //    is used in a manner that necessitates its existance.
-                    break;
-                }
-                    
-                case TearOffArguments: {
-                    // Ignore arguments tear off, because it's only relevant if we actually
-                    // need to create the arguments.
-                    break;
-                }
-                    
-                case SetLocal: {
-                    Node* source = node->child1().node();
-                    VariableAccessData* variableAccessData = node->variableAccessData();
-                    VirtualRegister argumentsRegister =
-                        m_graph.uncheckedArgumentsRegisterFor(node->origin.semantic);
-                    if (source->op() != CreateArguments && source->op() != PhantomArguments) {
-                        // Make sure that the source of the SetLocal knows that if it's
-                        // a variable that we think is aliased to the arguments, then it
-                        // may escape at this point. In future, we could track transitive
-                        // aliasing. But not yet.
-                        observeBadArgumentsUse(source);
-                        
-                        // If this is an assignment to the arguments register, then
-                        // pretend as if the arguments were created. We don't want to
-                        // optimize code that explicitly assigns to the arguments,
-                        // because that seems too ugly.
-                        
-                        // But, before getting rid of CreateArguments, we will have
-                        // an assignment to the arguments registers with JSValue().
-                        // That's because CSE will refuse to get rid of the
-                        // init_lazy_reg since it treats CreateArguments as reading
-                        // local variables. That could be fixed, but it's easier to
-                        // work around this here.
-                        if (source->op() == JSConstant && !*source->constant())
-                            break;
-                        
-                        // If the variable is totally dead, then ignore it.
-                        if (!m_isLive.contains(variableAccessData))
-                            break;
-                        
-                        if (argumentsRegister.isValid()
-                            && (variableAccessData->local() == argumentsRegister
-                                || variableAccessData->local() == unmodifiedArgumentsRegister(argumentsRegister))) {
-                            m_createsArguments.add(node->origin.semantic.inlineCallFrame);
-                            break;
-                        }
-
-                        if (variableAccessData->isCaptured())
-                            break;
-                        
-                        // Make sure that if it's a variable that we think is aliased to
-                        // the arguments, that we know that it might actually not be.
-                        ArgumentsAliasingData& data =
-                            m_argumentsAliasing.find(variableAccessData)->value;
-                        data.mergeNonArgumentsAssignment();
-                        data.mergeCallContext(node->origin.semantic.inlineCallFrame);
-                        break;
-                    }
-                    if (argumentsRegister.isValid()
-                        && (variableAccessData->local() == argumentsRegister
-                            || variableAccessData->local() == unmodifiedArgumentsRegister(argumentsRegister))) {
-                        if (node->origin.semantic.inlineCallFrame == source->origin.semantic.inlineCallFrame)
-                            break;
-                        m_createsArguments.add(source->origin.semantic.inlineCallFrame);
-                        break;
-                    }
-                    if (variableAccessData->isCaptured()) {
-                        m_createsArguments.add(source->origin.semantic.inlineCallFrame);
-                        break;
-                    }
-                    ArgumentsAliasingData& data =
-                        m_argumentsAliasing.find(variableAccessData)->value;
-                    data.mergeArgumentsAssignment();
-                    // This ensures that the variable's uses are in the same context as
-                    // the arguments it is aliasing.
-                    data.mergeCallContext(node->origin.semantic.inlineCallFrame);
-                    data.mergeCallContext(source->origin.semantic.inlineCallFrame);
-                    break;
-                }
-                    
-                case GetLocal:
-                case Phi: /* FIXME: https://bugs.webkit.org/show_bug.cgi?id=108555 */ {
-                    VariableAccessData* variableAccessData = node->variableAccessData();
-                    if (variableAccessData->isCaptured())
-                        break;
-                    ArgumentsAliasingData& data =
-                        m_argumentsAliasing.find(variableAccessData)->value;
-                    data.mergeCallContext(node->origin.semantic.inlineCallFrame);
-                    break;
-                }
-                    
-                case Flush: {
-                    VariableAccessData* variableAccessData = node->variableAccessData();
-                    if (variableAccessData->isCaptured())
-                        break;
-                    ArgumentsAliasingData& data =
-                        m_argumentsAliasing.find(variableAccessData)->value;
-                    data.mergeCallContext(node->origin.semantic.inlineCallFrame);
-                    
-                    // If a variable is used in a flush then by definition it escapes.
-                    data.escapes = true;
-                    break;
-                }
-                    
-                case SetArgument: {
-                    VariableAccessData* variableAccessData = node->variableAccessData();
-                    if (variableAccessData->isCaptured())
-                        break;
-                    ArgumentsAliasingData& data =
-                        m_argumentsAliasing.find(variableAccessData)->value;
-                    data.mergeNonArgumentsAssignment();
-                    data.mergeCallContext(node->origin.semantic.inlineCallFrame);
-                    break;
-                }
-                    
-                case GetByVal: {
-                    if (node->arrayMode().type() != Array::Arguments) {
-                        observeBadArgumentsUses(node);
-                        break;
-                    }
-
-                    // That's so awful and pretty much impossible since it would
-                    // imply that the arguments were predicted integer, but it's
-                    // good to be defensive and thorough.
-                    observeBadArgumentsUse(node->child2().node());
-                    observeProperArgumentsUse(node, node->child1());
-                    break;
-                }
-                    
-                case GetArrayLength: {
-                    if (node->arrayMode().type() != Array::Arguments) {
-                        observeBadArgumentsUses(node);
-                        break;
-                    }
-                        
-                    observeProperArgumentsUse(node, node->child1());
-                    break;
-                }
-                    
-                case Phantom:
-                case HardPhantom:
-                    // We don't care about phantom uses, since phantom uses are all about
-                    // just keeping things alive for OSR exit. If something - like the
-                    // CreateArguments - is just being kept alive, then this transformation
-                    // will not break this, since the Phantom will now just keep alive a
-                    // PhantomArguments and OSR exit will still do the right things.
-                    break;
-                    
-                case CheckStructure:
-                case CheckArray:
-                    // We don't care about these because if we get uses of the relevant
-                    // variable then we can safely get rid of these, too. This of course
-                    // relies on there not being any information transferred by the CFA
-                    // from a CheckStructure on one variable to the information about the
-                    // structures of another variable.
-                    break;
-                    
-                case MovHint:
-                    // We don't care about MovHints at all, since they represent what happens
-                    // in bytecode. We rematerialize arguments objects on OSR exit anyway.
-                    break;
-                    
-                default:
-                    observeBadArgumentsUses(node);
-                    break;
-                }
-            }
-        }
-
-        // Now we know which variables are aliased to arguments. But if any of them are
-        // found to have escaped, or were otherwise invalidated, then we need to mark
-        // 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.numBlocks(); ++blockIndex) {
-            BasicBlock* block = m_graph.block(blockIndex);
-            if (!block)
-                continue;
-            for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
-                Node* node = block->at(indexInBlock);
-                if (node->op() != SetLocal)
-                    continue;
-                Node* source = node->child1().node();
-                if (source->op() != CreateArguments)
-                    continue;
-                VariableAccessData* variableAccessData = node->variableAccessData();
-                if (variableAccessData->isCaptured()) {
-                    // The captured case would have already been taken care of in the
-                    // previous pass.
-                    continue;
-                }
-                
-                ArgumentsAliasingData& data =
-                    m_argumentsAliasing.find(variableAccessData)->value;
-                if (data.isValid())
-                    continue;
-                
-                m_createsArguments.add(source->origin.semantic.inlineCallFrame);
-            }
-        }
-        
-        InsertionSet insertionSet(m_graph);
-        
-        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++) {
-                Node* node = block->at(indexInBlock);
-                switch (node->op()) {
-                case SetLocal: {
-                    Node* source = node->child1().node();
-                    if (source->op() != CreateArguments)
-                        break;
-                    
-                    if (m_createsArguments.contains(source->origin.semantic.inlineCallFrame))
-                        break;
-                    
-                    VariableAccessData* variableAccessData = node->variableAccessData();
-                    
-                    if (variableAccessData->mergeIsArgumentsAlias(true)) {
-                        changed = true;
-                        
-                        // Make sure that the variable knows, that it may now hold non-cell values.
-                        variableAccessData->predict(SpecEmpty);
-                    }
-                    
-                    // Make sure that the SetLocal doesn't check that the input is a Cell.
-                    if (node->child1().useKind() != UntypedUse) {
-                        node->child1().setUseKind(UntypedUse);
-                        changed = true;
-                    }
-                    break;
-                }
-                    
-                case Flush: {
-                    VariableAccessData* variableAccessData = node->variableAccessData();
-                    
-                    if (variableAccessData->isCaptured()
-                        || !m_argumentsAliasing.find(variableAccessData)->value.isValid()
-                        || m_createsArguments.contains(node->origin.semantic.inlineCallFrame))
-                        break;
-                    
-                    RELEASE_ASSERT_NOT_REACHED();
-                    break;
-                }
-                    
-                case Phantom:
-                case HardPhantom: {
-                    // It's highly likely that we will have a Phantom referencing either
-                    // CreateArguments, or a local op for the arguments register, or a
-                    // local op for an arguments-aliased variable. In any of those cases,
-                    // we should remove the phantom reference, since:
-                    // 1) Phantoms only exist to aid OSR exit. But arguments simplification
-                    //    has its own OSR exit story, which is to inform OSR exit to reify
-                    //    the arguments as necessary.
-                    // 2) The Phantom may keep the CreateArguments node alive, which is
-                    //    precisely what we don't want.
-                    for (unsigned i = 0; i < AdjacencyList::Size; ++i)
-                        detypeArgumentsReferencingPhantomChild(node, i);
-                    break;
-                }
-                    
-                case CheckStructure:
-                case CheckArray: {
-                    // We can just get rid of this node, if it references a phantom argument.
-                    if (!isOKToOptimize(node->child1().node()))
-                        break;
-                    node->convertToPhantom();
-                    break;
-                }
-                    
-                case GetByVal: {
-                    if (node->arrayMode().type() != Array::Arguments)
-                        break;
-
-                    // This can be simplified to GetMyArgumentByVal if we know that
-                    // it satisfies either condition (1) or (2):
-                    // 1) Its first child is a valid ArgumentsAliasingData and the
-                    //    InlineCallFrame* is not marked as creating arguments.
-                    // 2) Its first child is CreateArguments and its InlineCallFrame*
-                    //    is not marked as creating arguments.
-                    
-                    if (!isOKToOptimize(node->child1().node()))
-                        break;
-                    
-                    insertionSet.insertNode(
-                        indexInBlock, SpecNone, Phantom, node->origin, node->child1());
-                    
-                    node->child1() = node->child2();
-                    node->child2() = Edge();
-                    node->setOpAndDefaultFlags(GetMyArgumentByVal);
-                    changed = true;
-                    --indexInBlock; // Force reconsideration of this op now that it's a GetMyArgumentByVal.
-                    break;
-                }
-                    
-                case GetArrayLength: {
-                    if (node->arrayMode().type() != Array::Arguments)
-                        break;
-                    
-                    if (!isOKToOptimize(node->child1().node()))
-                        break;
-                    
-                    insertionSet.insertNode(
-                        indexInBlock, SpecNone, Phantom, node->origin, node->child1());
-                    
-                    node->child1() = Edge();
-                    node->setOpAndDefaultFlags(GetMyArgumentsLength);
-                    changed = true;
-                    --indexInBlock; // Force reconsideration of this op noew that it's a GetMyArgumentsLength.
-                    break;
-                }
-                    
-                case GetMyArgumentsLength:
-                case GetMyArgumentsLengthSafe: {
-                    if (m_createsArguments.contains(node->origin.semantic.inlineCallFrame)) {
-                        ASSERT(node->op() == GetMyArgumentsLengthSafe);
-                        break;
-                    }
-                    if (node->op() == GetMyArgumentsLengthSafe) {
-                        node->setOp(GetMyArgumentsLength);
-                        changed = true;
-                    }
-                    
-                    NodeOrigin origin = node->origin;
-                    if (!origin.semantic.inlineCallFrame)
-                        break;
-                    if (origin.semantic.inlineCallFrame->isVarargs())
-                        break;
-                    
-                    // We know exactly what this will return. But only after we have checked
-                    // that nobody has escaped our arguments.
-                    insertionSet.insertNode(
-                        indexInBlock, SpecNone, CheckArgumentsNotCreated, origin);
-                    
-                    m_graph.convertToConstant(
-                        node, m_graph.freeze(
-                            jsNumber(origin.semantic.inlineCallFrame->arguments.size() - 1)));
-                    changed = true;
-                    break;
-                }
-                    
-                case GetMyArgumentByVal:
-                case GetMyArgumentByValSafe: {
-                    if (m_createsArguments.contains(node->origin.semantic.inlineCallFrame)) {
-                        ASSERT(node->op() == GetMyArgumentByValSafe);
-                        break;
-                    }
-                    if (node->op() == GetMyArgumentByValSafe) {
-                        node->setOp(GetMyArgumentByVal);
-                        changed = true;
-                    }
-                    if (!node->origin.semantic.inlineCallFrame)
-                        break;
-                    if (!node->child1()->isInt32Constant())
-                        break;
-                    int32_t index = node->child1()->asInt32();
-                    if (index < 0
-                        || static_cast<size_t>(index + 1) >=
-                            node->origin.semantic.inlineCallFrame->arguments.size())
-                        break;
-                    
-                    // We know which argument this is accessing. But only after we have checked
-                    // that nobody has escaped our arguments. We also need to ensure that the
-                    // index is kept alive. That's somewhat pointless since it's a constant, but
-                    // it's important because this is one of those invariants that we like to
-                    // have in the DFG. Note finally that we use the GetLocalUnlinked opcode
-                    // here, since this is being done _after_ the prediction propagation phase
-                    // has run - therefore it makes little sense to link the GetLocal operation
-                    // into the VariableAccessData and Phi graphs.
-
-                    NodeOrigin origin = node->origin;
-                    AdjacencyList children = node->children;
-                    
-                    node->convertToGetLocalUnlinked(
-                        VirtualRegister(
-                            origin.semantic.inlineCallFrame->stackOffset +
-                            m_graph.baselineCodeBlockFor(origin.semantic)->argumentIndexAfterCapture(index)));
-
-                    insertionSet.insertNode(
-                        indexInBlock, SpecNone, CheckArgumentsNotCreated, origin);
-                    insertionSet.insertNode(
-                        indexInBlock, SpecNone, Phantom, origin, children);
-                    
-                    changed = true;
-                    break;
-                }
-                    
-                case TearOffArguments: {
-                    if (m_createsArguments.contains(node->origin.semantic.inlineCallFrame))
-                        continue;
-                    
-                    node->convertToPhantom();
-                    break;
-                }
-                    
-                default:
-                    break;
-                }
-            }
-            insertionSet.execute(block);
-        }
-        
-        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) {
-                Node* node = block->at(indexInBlock);
-                if (node->op() != CreateArguments)
-                    continue;
-                // If this is a CreateArguments for an InlineCallFrame* that does
-                // not create arguments, then replace it with a PhantomArguments.
-                // PhantomArguments is a non-executing node that just indicates
-                // that the node should be reified as an arguments object on OSR
-                // exit.
-                if (m_createsArguments.contains(node->origin.semantic.inlineCallFrame))
-                    continue;
-                insertionSet.insertNode(
-                    indexInBlock, SpecNone, Phantom, node->origin, node->children);
-                node->setOpAndDefaultFlags(PhantomArguments);
-                node->children.reset();
-                changed = true;
-            }
-            insertionSet.execute(block);
-        }
-        
-        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) {
-                Node* node = block->at(indexInBlock);
-                if (node->op() != Phantom)
-                    continue;
-                for (unsigned i = 0; i < AdjacencyList::Size; ++i)
-                    detypeArgumentsReferencingPhantomChild(node, i);
-            }
-        }
-        
-        if (changed) {
-            m_graph.dethread();
-            m_graph.m_form = LoadStore;
-        }
-        
-        return changed;
-    }
-    
-private:
-    HashSet<InlineCallFrame*,
-            DefaultHash<InlineCallFrame*>::Hash,
-            NullableHashTraits<InlineCallFrame*>> m_createsArguments;
-    HashMap<VariableAccessData*, ArgumentsAliasingData,
-            DefaultHash<VariableAccessData*>::Hash,
-            NullableHashTraits<VariableAccessData*>> m_argumentsAliasing;
-    HashSet<VariableAccessData*> m_isLive;
-
-    void pruneObviousArgumentCreations(InlineCallFrame* inlineCallFrame)
-    {
-        ScriptExecutable* executable = m_graph.executableFor(inlineCallFrame);
-        if (m_graph.m_executablesWhoseArgumentsEscaped.contains(executable)
-            || executable->isStrictMode())
-            m_createsArguments.add(inlineCallFrame);
-    }
-    
-    void observeBadArgumentsUse(Node* node)
-    {
-        if (!node)
-            return;
-        
-        switch (node->op()) {
-        case CreateArguments: {
-            m_createsArguments.add(node->origin.semantic.inlineCallFrame);
-            break;
-        }
-            
-        case GetLocal: {
-            VirtualRegister argumentsRegister =
-                m_graph.uncheckedArgumentsRegisterFor(node->origin.semantic);
-            if (argumentsRegister.isValid()
-                && (node->local() == argumentsRegister
-                    || node->local() == unmodifiedArgumentsRegister(argumentsRegister))) {
-                m_createsArguments.add(node->origin.semantic.inlineCallFrame);
-                break;
-            }
-            
-            VariableAccessData* variableAccessData = node->variableAccessData();
-            if (variableAccessData->isCaptured())
-                break;
-            
-            ArgumentsAliasingData& data = m_argumentsAliasing.find(variableAccessData)->value;
-            data.escapes = true;
-            break;
-        }
-            
-        default:
-            break;
-        }
-    }
-    
-    void observeBadArgumentsUses(Node* node)
-    {
-        for (unsigned i = m_graph.numChildren(node); i--;)
-            observeBadArgumentsUse(m_graph.child(node, i).node());
-    }
-    
-    void observeProperArgumentsUse(Node* node, Edge edge)
-    {
-        if (edge->op() != GetLocal) {
-            // When can this happen? At least two cases that I can think
-            // of:
-            //
-            // 1) Aliased use of arguments in the same basic block,
-            //    like:
-            //
-            //    var a = arguments;
-            //    var x = arguments[i];
-            //
-            // 2) If we're accessing arguments we got from the heap!
-                            
-            if (edge->op() == CreateArguments
-                && node->origin.semantic.inlineCallFrame
-                    != edge->origin.semantic.inlineCallFrame)
-                m_createsArguments.add(edge->origin.semantic.inlineCallFrame);
-            
-            return;
-        }
-                        
-        VariableAccessData* variableAccessData = edge->variableAccessData();
-        if (edge->local() == m_graph.uncheckedArgumentsRegisterFor(edge->origin.semantic)
-            && node->origin.semantic.inlineCallFrame != edge->origin.semantic.inlineCallFrame) {
-            m_createsArguments.add(edge->origin.semantic.inlineCallFrame);
-            return;
-        }
-
-        if (variableAccessData->isCaptured())
-            return;
-        
-        ArgumentsAliasingData& data = m_argumentsAliasing.find(variableAccessData)->value;
-        data.mergeCallContext(node->origin.semantic.inlineCallFrame);
-    }
-    
-    bool isOKToOptimize(Node* source)
-    {
-        if (m_createsArguments.contains(source->origin.semantic.inlineCallFrame))
-            return false;
-        
-        switch (source->op()) {
-        case GetLocal: {
-            VariableAccessData* variableAccessData = source->variableAccessData();
-            VirtualRegister argumentsRegister =
-                m_graph.uncheckedArgumentsRegisterFor(source->origin.semantic);
-            if (!argumentsRegister.isValid())
-                break;
-            if (argumentsRegister == variableAccessData->local())
-                return true;
-            if (unmodifiedArgumentsRegister(argumentsRegister) == variableAccessData->local())
-                return true;
-            if (variableAccessData->isCaptured())
-                break;
-            ArgumentsAliasingData& data =
-                m_argumentsAliasing.find(variableAccessData)->value;
-            if (!data.isValid())
-                break;
-                            
-            return true;
-        }
-                            
-        case CreateArguments: {
-            return true;
-        }
-                            
-        default:
-            break;
-        }
-        
-        return false;
-    }
-    
-    void detypeArgumentsReferencingPhantomChild(Node* node, unsigned edgeIndex)
-    {
-        Edge edge = node->children.child(edgeIndex);
-        if (!edge)
-            return;
-        
-        switch (edge->op()) {
-        case GetLocal: {
-            VariableAccessData* variableAccessData = edge->variableAccessData();
-            if (!variableAccessData->isArgumentsAlias())
-                break;
-            node->children.child(edgeIndex).setUseKind(UntypedUse);
-            break;
-        }
-            
-        case PhantomArguments: {
-            node->children.child(edgeIndex).setUseKind(UntypedUse);
-            break;
-        }
-            
-        default:
-            break;
-        }
-    }
-};
-
-bool performArgumentsSimplification(Graph& graph)
-{
-    SamplingRegion samplingRegion("DFG Arguments Simplification Phase");
-    return runPhase<ArgumentsSimplificationPhase>(graph);
-}
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentsUtilities.cpp b/Source/JavaScriptCore/dfg/DFGArgumentsUtilities.cpp
new file mode 100644
index 0000000..5d512b1b
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGArgumentsUtilities.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGArgumentsUtilities.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "JSCInlines.h"
+
+namespace JSC { namespace DFG {
+
+bool argumentsInvolveStackSlot(InlineCallFrame* inlineCallFrame, VirtualRegister reg)
+{
+    if (!inlineCallFrame)
+        return (reg.isArgument() && reg.toArgument()) || reg.isHeader();
+    
+    if (inlineCallFrame->isClosureCall
+        && reg == VirtualRegister(inlineCallFrame->stackOffset + JSStack::Callee))
+        return true;
+    
+    if (inlineCallFrame->isVarargs()
+        && reg == VirtualRegister(inlineCallFrame->stackOffset + JSStack::ArgumentCount))
+        return true;
+    
+    unsigned numArguments = inlineCallFrame->arguments.size() - 1;
+    VirtualRegister argumentStart =
+        VirtualRegister(inlineCallFrame->stackOffset) + CallFrame::argumentOffset(0);
+    return reg >= argumentStart && reg < argumentStart + numArguments;
+}
+
+bool argumentsInvolveStackSlot(Node* candidate, VirtualRegister reg)
+{
+    return argumentsInvolveStackSlot(candidate->origin.semantic.inlineCallFrame, reg);
+}
+
+Node* emitCodeToGetArgumentsArrayLength(
+    InsertionSet& insertionSet, Node* arguments, unsigned nodeIndex, NodeOrigin origin)
+{
+    Graph& graph = insertionSet.graph();
+
+    DFG_ASSERT(
+        graph, arguments,
+        arguments->op() == CreateDirectArguments || arguments->op() == CreateScopedArguments
+        || arguments->op() == CreateClonedArguments || arguments->op() == PhantomDirectArguments
+        || arguments->op() == PhantomClonedArguments);
+    
+    InlineCallFrame* inlineCallFrame = arguments->origin.semantic.inlineCallFrame;
+    
+    if (inlineCallFrame && !inlineCallFrame->isVarargs()) {
+        return insertionSet.insertConstant(
+            nodeIndex, origin, jsNumber(inlineCallFrame->arguments.size() - 1));
+    }
+    
+    Node* argumentCount;
+    if (!inlineCallFrame)
+        argumentCount = insertionSet.insertNode(nodeIndex, SpecInt32, GetArgumentCount, origin);
+    else {
+        VirtualRegister argumentCountRegister(inlineCallFrame->stackOffset + JSStack::ArgumentCount);
+        
+        argumentCount = insertionSet.insertNode(
+            nodeIndex, SpecInt32, GetStack, origin,
+            OpInfo(graph.m_stackAccessData.add(argumentCountRegister, FlushedInt32)));
+    }
+    
+    return insertionSet.insertNode(
+        nodeIndex, SpecInt32, ArithSub, origin, OpInfo(Arith::Unchecked),
+        Edge(argumentCount, Int32Use),
+        insertionSet.insertConstantForUse(
+            nodeIndex, origin, jsNumber(1), Int32Use));
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h b/Source/JavaScriptCore/dfg/DFGArgumentsUtilities.h
similarity index 75%
copy from Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h
copy to Source/JavaScriptCore/dfg/DFGArgumentsUtilities.h
index 25098ca..82bfec3 100644
--- a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h
+++ b/Source/JavaScriptCore/dfg/DFGArgumentsUtilities.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,25 +23,25 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#ifndef DFGArgumentsSimplificationPhase_h
-#define DFGArgumentsSimplificationPhase_h
+#ifndef DFGArgumentsUtilities_h
+#define DFGArgumentsUtilities_h
 
 #if ENABLE(DFG_JIT)
 
+#include "DFGGraph.h"
+#include "DFGInsertionSet.h"
+
 namespace JSC { namespace DFG {
 
-class Graph;
+bool argumentsInvolveStackSlot(InlineCallFrame*, VirtualRegister);
+bool argumentsInvolveStackSlot(Node* candidate, VirtualRegister);
 
-// Simplifies reflective uses of the Arguments object:
-//
-// Inlined arguments.length -> constant
-// Inlined arguments[constant] -> GetLocalUnlinked
-
-bool performArgumentsSimplification(Graph&);
+Node* emitCodeToGetArgumentsArrayLength(
+    InsertionSet&, Node* arguments, unsigned nodeIndex, NodeOrigin);
 
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
 
-#endif // DFGArgumentsSimplificationPhase_h
+#endif // DFGArgumentsUtilities_h
 
diff --git a/Source/JavaScriptCore/dfg/DFGArrayMode.cpp b/Source/JavaScriptCore/dfg/DFGArrayMode.cpp
index fcc9b2a..a5994fb 100644
--- a/Source/JavaScriptCore/dfg/DFGArrayMode.cpp
+++ b/Source/JavaScriptCore/dfg/DFGArrayMode.cpp
@@ -197,8 +197,15 @@
         if (isStringSpeculation(base))
             return withType(Array::String);
         
-        if (isArgumentsSpeculation(base))
-            return withType(Array::Arguments);
+        if (isDirectArgumentsSpeculation(base) || isScopedArgumentsSpeculation(base)) {
+            // Handle out-of-bounds accesses as generic accesses.
+            if (graph.hasExitSite(node->origin.semantic, OutOfBounds) || !isInBounds())
+                return ArrayMode(Array::Generic);
+            
+            if (isDirectArgumentsSpeculation(base))
+                return withType(Array::DirectArguments);
+            return withType(Array::ScopedArguments);
+        }
         
         ArrayMode result;
         switch (node->op()) {
@@ -396,8 +403,11 @@
             return true;
         } }
         
-    case Array::Arguments:
-        return speculationChecked(value.m_type, SpecArguments);
+    case Array::DirectArguments:
+        return speculationChecked(value.m_type, SpecDirectArguments);
+        
+    case Array::ScopedArguments:
+        return speculationChecked(value.m_type, SpecScopedArguments);
         
     case Array::Int8Array:
         return speculationChecked(value.m_type, SpecInt8Array);
@@ -461,8 +471,10 @@
         return "ArrayStorage";
     case Array::SlowPutArrayStorage:
         return "SlowPutArrayStorage";
-    case Array::Arguments:
-        return "Arguments";
+    case Array::DirectArguments:
+        return "DirectArguments";
+    case Array::ScopedArguments:
+        return "ScopedArguments";
     case Array::Int8Array:
         return "Int8Array";
     case Array::Int16Array:
diff --git a/Source/JavaScriptCore/dfg/DFGArrayMode.h b/Source/JavaScriptCore/dfg/DFGArrayMode.h
index 084c985..b381ce3 100644
--- a/Source/JavaScriptCore/dfg/DFGArrayMode.h
+++ b/Source/JavaScriptCore/dfg/DFGArrayMode.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -65,7 +65,9 @@
     ArrayStorage,
     SlowPutArrayStorage,
     
-    Arguments,
+    DirectArguments,
+    ScopedArguments,
+    
     Int8Array,
     Int16Array,
     Int32Array,
@@ -294,7 +296,8 @@
         case Array::Unprofiled:
         case Array::ForceExit:
         case Array::Generic:
-        case Array::Arguments:
+        case Array::DirectArguments:
+        case Array::ScopedArguments:
             return false;
         default:
             return true;
@@ -320,11 +323,9 @@
     {
         switch (type()) {
         case Array::String:
+        case Array::DirectArguments:
+        case Array::ScopedArguments:
             return ArrayMode(Array::Generic);
-#if USE(JSVALUE32_64)
-        case Array::Arguments:
-            return ArrayMode(Array::Generic);
-#endif
         default:
             return *this;
         }
diff --git a/Source/JavaScriptCore/dfg/DFGAvailabilityMap.cpp b/Source/JavaScriptCore/dfg/DFGAvailabilityMap.cpp
index 655f178..1071015 100644
--- a/Source/JavaScriptCore/dfg/DFGAvailabilityMap.cpp
+++ b/Source/JavaScriptCore/dfg/DFGAvailabilityMap.cpp
@@ -45,14 +45,13 @@
             possibleNodes.add(m_locals[i].node());
     }
 
-    unsigned oldPossibleNodesSize;
-    do {
-        oldPossibleNodesSize = possibleNodes.size();
-        for (auto pair : m_heap) {
-            if (pair.value.hasNode() && possibleNodes.contains(pair.key.base()))
-                possibleNodes.add(pair.value.node());
-        }
-    } while (oldPossibleNodesSize != possibleNodes.size());
+    closeOverNodes(
+        [&] (Node* node) -> bool {
+            return possibleNodes.contains(node);
+        },
+        [&] (Node* node) -> bool {
+            return possibleNodes.add(node).isNewEntry;
+        });
     
     HashMap<PromotedHeapLocation, Availability> newHeap;
     for (auto pair : m_heap) {
diff --git a/Source/JavaScriptCore/dfg/DFGAvailabilityMap.h b/Source/JavaScriptCore/dfg/DFGAvailabilityMap.h
index bc2e41b..9be6fb3 100644
--- a/Source/JavaScriptCore/dfg/DFGAvailabilityMap.h
+++ b/Source/JavaScriptCore/dfg/DFGAvailabilityMap.h
@@ -52,6 +52,32 @@
             functor(pair.value);
     }
     
+    template<typename HasFunctor, typename AddFunctor>
+    void closeOverNodes(const HasFunctor& has, const AddFunctor& add)
+    {
+        bool changed;
+        do {
+            changed = false;
+            for (auto pair : m_heap) {
+                if (pair.value.hasNode() && has(pair.key.base()))
+                    changed |= add(pair.value.node());
+            }
+        } while (changed);
+    }
+    
+    template<typename HasFunctor, typename AddFunctor>
+    void closeStartingWithLocal(VirtualRegister reg, const HasFunctor& has, const AddFunctor& add)
+    {
+        Availability availability = m_locals.operand(reg);
+        if (!availability.hasNode())
+            return;
+        
+        if (!add(availability.node()))
+            return;
+        
+        closeOverNodes(has, add);
+    }
+    
     Operands<Availability> m_locals;
     HashMap<PromotedHeapLocation, Availability> m_heap;
 };
diff --git a/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp
index 47d4a5c..43c3d5d 100644
--- a/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -326,11 +326,6 @@
             break;
         }
             
-        case GetMyArgumentByValSafe: {
-            node->child1()->mergeFlags(NodeBytecodeUsesAsNumber | NodeBytecodeUsesAsOther | NodeBytecodeUsesAsInt | NodeBytecodeUsesAsArrayIndex);
-            break;
-        }
-            
         case NewArrayWithSize: {
             node->child1()->mergeFlags(NodeBytecodeUsesAsValue | NodeBytecodeUsesAsInt | NodeBytecodeUsesAsArrayIndex);
             break;
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
index 151f162..69fd4ad 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
@@ -225,11 +225,11 @@
     void linkBlock(BasicBlock*, Vector<BasicBlock*>& possibleTargets);
     void linkBlocks(Vector<UnlinkedBlock>& unlinkedBlocks, Vector<BasicBlock*>& possibleTargets);
     
-    VariableAccessData* newVariableAccessData(VirtualRegister operand, bool isCaptured)
+    VariableAccessData* newVariableAccessData(VirtualRegister operand)
     {
         ASSERT(!operand.isConstant());
         
-        m_graph.m_variableAccessData.append(VariableAccessData(operand, isCaptured));
+        m_graph.m_variableAccessData.append(VariableAccessData(operand));
         return &m_graph.m_variableAccessData.last();
     }
     
@@ -346,7 +346,6 @@
         unsigned local = operand.toLocal();
 
         Node* node = m_currentBlock->variablesAtTail.local(local);
-        bool isCaptured = m_codeBlock->isCaptured(operand, inlineCallFrame());
         
         // This has two goals: 1) link together variable access datas, and 2)
         // try to avoid creating redundant GetLocals. (1) is required for
@@ -358,20 +357,17 @@
         
         if (node) {
             variable = node->variableAccessData();
-            variable->mergeIsCaptured(isCaptured);
             
-            if (!isCaptured) {
-                switch (node->op()) {
-                case GetLocal:
-                    return node;
-                case SetLocal:
-                    return node->child1().node();
-                default:
-                    break;
-                }
+            switch (node->op()) {
+            case GetLocal:
+                return node;
+            case SetLocal:
+                return node->child1().node();
+            default:
+                break;
             }
         } else
-            variable = newVariableAccessData(operand, isCaptured);
+            variable = newVariableAccessData(operand);
         
         node = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(variable)));
         m_currentBlock->variablesAtTail.local(local) = node;
@@ -384,15 +380,14 @@
         m_currentSemanticOrigin = semanticOrigin;
 
         unsigned local = operand.toLocal();
-        bool isCaptured = m_codeBlock->isCaptured(operand, inlineCallFrame());
         
         if (setMode != ImmediateNakedSet) {
             ArgumentPosition* argumentPosition = findArgumentPositionForLocal(operand);
-            if (isCaptured || argumentPosition)
+            if (argumentPosition)
                 flushDirect(operand, argumentPosition);
         }
 
-        VariableAccessData* variableAccessData = newVariableAccessData(operand, isCaptured);
+        VariableAccessData* variableAccessData = newVariableAccessData(operand);
         variableAccessData->mergeStructureCheckHoistingFailed(
             m_inlineStackTop->m_exitProfile.hasExitSite(semanticOrigin.bytecodeIndex, BadCache));
         variableAccessData->mergeCheckArrayHoistingFailed(
@@ -411,26 +406,22 @@
         ASSERT(argument < m_numArguments);
         
         Node* node = m_currentBlock->variablesAtTail.argument(argument);
-        bool isCaptured = m_codeBlock->isCaptured(operand);
 
         VariableAccessData* variable;
         
         if (node) {
             variable = node->variableAccessData();
-            variable->mergeIsCaptured(isCaptured);
             
-            if (!isCaptured) {
-                switch (node->op()) {
-                case GetLocal:
-                    return node;
-                case SetLocal:
-                    return node->child1().node();
-                default:
-                    break;
-                }
+            switch (node->op()) {
+            case GetLocal:
+                return node;
+            case SetLocal:
+                return node->child1().node();
+            default:
+                break;
             }
         } else
-            variable = newVariableAccessData(operand, isCaptured);
+            variable = newVariableAccessData(operand);
         
         node = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(variable)));
         m_currentBlock->variablesAtTail.argument(argument) = node;
@@ -444,9 +435,7 @@
         unsigned argument = operand.toArgument();
         ASSERT(argument < m_numArguments);
         
-        bool isCaptured = m_codeBlock->isCaptured(operand);
-
-        VariableAccessData* variableAccessData = newVariableAccessData(operand, isCaptured);
+        VariableAccessData* variableAccessData = newVariableAccessData(operand);
 
         // Always flush arguments, except for 'this'. If 'this' is created by us,
         // then make sure that it's never unboxed.
@@ -512,19 +501,16 @@
     
     void flushDirect(VirtualRegister operand, ArgumentPosition* argumentPosition)
     {
-        bool isCaptured = m_codeBlock->isCaptured(operand, inlineCallFrame());
-        
         ASSERT(!operand.isConstant());
         
         Node* node = m_currentBlock->variablesAtTail.operand(operand);
         
         VariableAccessData* variable;
         
-        if (node) {
+        if (node)
             variable = node->variableAccessData();
-            variable->mergeIsCaptured(isCaptured);
-        } else
-            variable = newVariableAccessData(operand, isCaptured);
+        else
+            variable = newVariableAccessData(operand);
         
         node = addToGraph(Flush, OpInfo(variable));
         m_currentBlock->variablesAtTail.operand(operand) = node;
@@ -545,11 +531,6 @@
             numArguments = inlineStackEntry->m_codeBlock->numParameters();
         for (unsigned argument = numArguments; argument-- > 1;)
             flushDirect(inlineStackEntry->remapOperand(virtualRegisterForArgument(argument)));
-        for (int local = 0; local < inlineStackEntry->m_codeBlock->m_numVars; ++local) {
-            if (!inlineStackEntry->m_codeBlock->isCaptured(virtualRegisterForLocal(local)))
-                continue;
-            flushDirect(inlineStackEntry->remapOperand(virtualRegisterForLocal(local)));
-        }
     }
 
     void flushForTerminal()
@@ -844,6 +825,16 @@
         return node;
     }
     
+    void noticeArgumentsUse()
+    {
+        // All of the arguments in this function need to be formatted as JSValues because we will
+        // load from them in a random-access fashion and we don't want to have to switch on
+        // format.
+        
+        for (ArgumentPosition* argument : m_inlineStackTop->m_argumentPositions)
+            argument->mergeShouldNeverUnbox(true);
+    }
+    
     void buildOperandMapsIfNecessary();
     
     VM* m_vm;
@@ -1123,6 +1114,9 @@
     if (callTarget->isCellConstant())
         callLinkStatus.setProvenConstantCallee(CallVariant(callTarget->asCell()));
     
+    if (Options::verboseDFGByteCodeParsing())
+        dataLog("    Varargs call link status at ", currentCodeOrigin(), ": ", callLinkStatus, "\n");
+    
     if (callLinkStatus.canOptimize()
         && handleInlining(callTarget, result, callLinkStatus, firstFreeReg, VirtualRegister(thisReg), VirtualRegister(arguments), firstVarArgOffset, 0, m_currentIndex + OPCODE_LENGTH(op_call_varargs), op, InlineCallFrame::varargsKindFor(kind), prediction)) {
         if (m_graph.compilation())
@@ -1431,29 +1425,38 @@
     if (verbose)
         dataLog("    Considering callee ", callee, "\n");
     
-    if (InternalFunction* function = callee.internalFunction()) {
-        if (handleConstantInternalFunction(resultOperand, function, registerOffset, argumentCountIncludingThis, specializationKind, insertChecksWithAccounting)) {
-            RELEASE_ASSERT(didInsertChecks);
-            addToGraph(Phantom, callTargetNode);
-            emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
-            inliningBalance--;
-            return true;
+    // Intrinsics and internal functions can only be inlined if we're not doing varargs. This is because
+    // we currently don't have any way of getting profiling information for arguments to non-JS varargs
+    // calls. The prediction propagator won't be of any help because LoadVarargs obscures the data flow,
+    // and there are no callsite value profiles and native function won't have callee value profiles for
+    // those arguments. Even worse, if the intrinsic decides to exit, it won't really have anywhere to
+    // exit to: LoadVarargs is effectful and it's part of the op_call_varargs, so we can't exit without
+    // calling LoadVarargs twice.
+    if (!InlineCallFrame::isVarargs(kind)) {
+        if (InternalFunction* function = callee.internalFunction()) {
+            if (handleConstantInternalFunction(resultOperand, function, registerOffset, argumentCountIncludingThis, specializationKind, insertChecksWithAccounting)) {
+                RELEASE_ASSERT(didInsertChecks);
+                addToGraph(Phantom, callTargetNode);
+                emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
+                inliningBalance--;
+                return true;
+            }
+            RELEASE_ASSERT(!didInsertChecks);
+            return false;
         }
-        RELEASE_ASSERT(!didInsertChecks);
-        return false;
-    }
     
-    Intrinsic intrinsic = callee.intrinsicFor(specializationKind);
-    if (intrinsic != NoIntrinsic) {
-        if (handleIntrinsic(resultOperand, intrinsic, registerOffset, argumentCountIncludingThis, prediction, insertChecksWithAccounting)) {
-            RELEASE_ASSERT(didInsertChecks);
-            addToGraph(Phantom, callTargetNode);
-            emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
-            inliningBalance--;
-            return true;
+        Intrinsic intrinsic = callee.intrinsicFor(specializationKind);
+        if (intrinsic != NoIntrinsic) {
+            if (handleIntrinsic(resultOperand, intrinsic, registerOffset, argumentCountIncludingThis, prediction, insertChecksWithAccounting)) {
+                RELEASE_ASSERT(didInsertChecks);
+                addToGraph(Phantom, callTargetNode);
+                emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
+                inliningBalance--;
+                return true;
+            }
+            RELEASE_ASSERT(!didInsertChecks);
+            return false;
         }
-        RELEASE_ASSERT(!didInsertChecks);
-        return false;
     }
     
     unsigned myInliningCost = inliningCost(callee, argumentCountIncludingThis, specializationKind);
@@ -1540,6 +1543,8 @@
                     int remappedRegisterOffset =
                         m_inlineStackTop->remapOperand(VirtualRegister(registerOffset)).offset();
                     
+                    ensureLocals(VirtualRegister(remappedRegisterOffset).toLocal());
+                    
                     int argumentStart = registerOffset + JSStack::CallFrameHeaderSize;
                     int remappedArgumentStart =
                         m_inlineStackTop->remapOperand(VirtualRegister(argumentStart)).offset();
@@ -1559,7 +1564,7 @@
                     // before SSA.
             
                     VariableAccessData* countVariable = newVariableAccessData(
-                        VirtualRegister(remappedRegisterOffset + JSStack::ArgumentCount), false);
+                        VirtualRegister(remappedRegisterOffset + JSStack::ArgumentCount));
                     // This is pretty lame, but it will force the count to be flushed as an int. This doesn't
                     // matter very much, since our use of a SetArgument and Flushes for this local slot is
                     // mostly just a formality.
@@ -1571,7 +1576,7 @@
                     set(VirtualRegister(argumentStart), get(thisArgument), ImmediateNakedSet);
                     for (unsigned argument = 1; argument < maxNumArguments; ++argument) {
                         VariableAccessData* variable = newVariableAccessData(
-                            VirtualRegister(remappedArgumentStart + argument), false);
+                            VirtualRegister(remappedArgumentStart + argument));
                         variable->mergeShouldNeverUnbox(true); // We currently have nowhere to put the type check on the LoadVarargs. LoadVarargs is effectful, so after it finishes, we cannot exit.
                         
                         // For a while it had been my intention to do things like this inside the
@@ -2534,7 +2539,7 @@
         m_graph.m_arguments.resize(m_numArguments);
         for (unsigned argument = 0; argument < m_numArguments; ++argument) {
             VariableAccessData* variable = newVariableAccessData(
-                virtualRegisterForArgument(argument), m_codeBlock->isCaptured(virtualRegisterForArgument(argument)));
+                virtualRegisterForArgument(argument));
             variable->mergeStructureCheckHoistingFailed(
                 m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
             variable->mergeCheckArrayHoistingFailed(
@@ -3084,7 +3089,7 @@
             Node* value = get(VirtualRegister(currentInstruction[2].u.operand));
             addToGraph(
                 PutGlobalVar,
-                OpInfo(m_inlineStackTop->m_codeBlock->globalObject()->assertRegisterIsInThisObject(currentInstruction[1].u.registerPointer)),
+                OpInfo(m_inlineStackTop->m_codeBlock->globalObject()->assertVariableIsInThisObject(currentInstruction[1].u.variablePointer)),
                 value);
             NEXT_OPCODE(op_init_global_const);
         }
@@ -3327,66 +3332,6 @@
             NEXT_OPCODE(op_construct);
             
         case op_call_varargs: {
-            int result = currentInstruction[1].u.operand;
-            int callee = currentInstruction[2].u.operand;
-            int thisReg = currentInstruction[3].u.operand;
-            int arguments = currentInstruction[4].u.operand;
-            int firstFreeReg = currentInstruction[5].u.operand;
-            int firstVarArgOffset = currentInstruction[6].u.operand;
-            
-            if (arguments == m_inlineStackTop->m_codeBlock->uncheckedArgumentsRegister().offset()
-                && !m_inlineStackTop->m_codeBlock->symbolTable()->slowArguments()) {
-                if (inlineCallFrame()
-                    && !inlineCallFrame()->isVarargs()
-                    && !firstVarArgOffset) {
-                    addToGraph(CheckArgumentsNotCreated);
-
-                    unsigned argCount = inlineCallFrame()->arguments.size();
-            
-                    // Let's compute the register offset. We start with the last used register, and
-                    // then adjust for the things we want in the call frame.
-                    int registerOffset = firstFreeReg + 1;
-                    registerOffset -= argCount; // We will be passing some arguments.
-                    registerOffset -= JSStack::CallFrameHeaderSize; // We will pretend to have a call frame header.
-            
-                    // Get the alignment right.
-                    registerOffset = -WTF::roundUpToMultipleOf(
-                        stackAlignmentRegisters(),
-                        -registerOffset);
-
-                    ensureLocals(
-                        m_inlineStackTop->remapOperand(
-                            VirtualRegister(registerOffset)).toLocal());
-            
-                    // The bytecode wouldn't have set up the arguments. But we'll do it and make it
-                    // look like the bytecode had done it.
-                    int nextRegister = registerOffset + JSStack::CallFrameHeaderSize;
-                    set(VirtualRegister(nextRegister++), get(VirtualRegister(thisReg)), ImmediateNakedSet);
-                    for (unsigned argument = 1; argument < argCount; ++argument)
-                        set(VirtualRegister(nextRegister++), get(virtualRegisterForArgument(argument)), ImmediateNakedSet);
-            
-                    handleCall(
-                        result, Call, CodeForCall, OPCODE_LENGTH(op_call_varargs),
-                        callee, argCount, registerOffset);
-                    NEXT_OPCODE(op_call_varargs);
-                }
-                
-                // Emit CallForwardVarargs
-                // FIXME: This means we cannot inline forwarded varargs calls inside a varargs
-                // call frame. We will probably fix that once we finally get rid of the
-                // arguments object special-casing.
-                CallVarargsData* data = m_graph.m_callVarargsData.add();
-                data->firstVarArgOffset = firstVarArgOffset;
-                
-                Node* call = addToGraph(
-                    CallForwardVarargs, OpInfo(data), OpInfo(getPrediction()),
-                    get(VirtualRegister(callee)), get(VirtualRegister(thisReg)));
-                VirtualRegister resultReg(result);
-                if (resultReg.isValid())
-                    set(resultReg, call);
-                NEXT_OPCODE(op_call_varargs);
-            }
-            
             handleVarargsCall(currentInstruction, CallVarargs, CodeForCall);
             NEXT_OPCODE(op_call_varargs);
         }
@@ -3511,16 +3456,23 @@
             case ClosureVar:
             case ClosureVarWithVarInjectionChecks: {
                 Node* scopeNode = get(VirtualRegister(scope));
-                if (JSValue value = m_graph.tryGetConstantClosureVar(scopeNode, VirtualRegister(operand))) {
-                    addToGraph(Phantom, scopeNode);
+                
+                // Ideally we wouldn't have to do this Phantom. But:
+                //
+                // For the constant case: we must do it because otherwise we would have no way of knowing
+                // that the scope is live at OSR here.
+                //
+                // For the non-constant case: GetClosureVar could be DCE'd, but baseline's implementation
+                // won't be able to handle an Undefined scope.
+                addToGraph(Phantom, scopeNode);
+                
+                if (JSValue value = m_graph.tryGetConstantClosureVar(scopeNode, ScopeOffset(operand))) {
                     set(VirtualRegister(dst), weakJSConstant(value));
                     break;
                 }
                 SpeculatedType prediction = getPrediction();
                 set(VirtualRegister(dst),
-                    addToGraph(
-                        GetClosureVar, OpInfo(operand), OpInfo(prediction),
-                        scopeNode, addToGraph(GetClosureRegisters, scopeNode)));
+                    addToGraph(GetClosureVar, OpInfo(operand), OpInfo(prediction), scopeNode));
                 break;
             }
             case Dynamic:
@@ -3532,13 +3484,19 @@
 
         case op_put_to_scope: {
             unsigned scope = currentInstruction[1].u.operand;
-            unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[2].u.operand];
+            unsigned identifierNumber = currentInstruction[2].u.operand;
+            if (identifierNumber != UINT_MAX)
+                identifierNumber = m_inlineStackTop->m_identifierRemap[identifierNumber];
             unsigned value = currentInstruction[3].u.operand;
             ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type();
-            AtomicStringImpl* uid = m_graph.identifiers()[identifierNumber];
-
-            Structure* structure = 0;
-            VariableWatchpointSet* watchpoints = 0;
+            AtomicStringImpl* uid;
+            if (identifierNumber != UINT_MAX)
+                uid = m_graph.identifiers()[identifierNumber];
+            else
+                uid = nullptr;
+            
+            Structure* structure = nullptr;
+            VariableWatchpointSet* watchpoints = nullptr;
             uintptr_t operand;
             {
                 ConcurrentJITLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
@@ -3554,7 +3512,11 @@
             switch (resolveType) {
             case GlobalProperty:
             case GlobalPropertyWithVarInjectionChecks: {
-                PutByIdStatus status = PutByIdStatus::computeFor(globalObject, structure, uid, false);
+                PutByIdStatus status;
+                if (uid)
+                    status = PutByIdStatus::computeFor(globalObject, structure, uid, false);
+                else
+                    status = PutByIdStatus(PutByIdStatus::TakesSlowPath);
                 if (status.numVariants() != 1
                     || status[0].kind() != PutByIdVariant::Replace
                     || status[0].structure().size() != 1) {
@@ -3571,11 +3533,13 @@
             }
             case GlobalVar:
             case GlobalVarWithVarInjectionChecks: {
-                SymbolTableEntry entry = globalObject->symbolTable()->get(uid);
-                ASSERT(watchpoints == entry.watchpointSet());
+                if (watchpoints) {
+                    SymbolTableEntry entry = globalObject->symbolTable()->get(uid);
+                    ASSERT_UNUSED(entry, watchpoints == entry.watchpointSet());
+                }
                 Node* valueNode = get(VirtualRegister(value));
                 addToGraph(PutGlobalVar, OpInfo(operand), valueNode);
-                if (watchpoints->state() != IsInvalidated)
+                if (watchpoints && watchpoints->state() != IsInvalidated)
                     addToGraph(NotifyWrite, OpInfo(watchpoints), valueNode);
                 // Keep scope alive until after put.
                 addToGraph(Phantom, get(VirtualRegister(scope)));
@@ -3585,13 +3549,12 @@
             case ClosureVar:
             case ClosureVarWithVarInjectionChecks: {
                 Node* scopeNode = get(VirtualRegister(scope));
-                Node* scopeRegisters = addToGraph(GetClosureRegisters, scopeNode);
                 Node* valueNode = get(VirtualRegister(value));
 
                 if (watchpoints && watchpoints->state() != IsInvalidated)
                     addToGraph(NotifyWrite, OpInfo(watchpoints), valueNode);
 
-                addToGraph(PutClosureVar, OpInfo(operand), scopeNode, scopeRegisters, valueNode);
+                addToGraph(PutClosureVar, OpInfo(operand), scopeNode, valueNode);
                 break;
             }
             case Dynamic:
@@ -3621,15 +3584,8 @@
             NEXT_OPCODE(op_loop_hint);
         }
             
-        case op_init_lazy_reg: {
-            set(VirtualRegister(currentInstruction[1].u.operand), jsConstant(JSValue()));
-            ASSERT(operandIsLocal(currentInstruction[1].u.operand));
-            m_graph.m_lazyVars.set(VirtualRegister(currentInstruction[1].u.operand).toLocal());
-            NEXT_OPCODE(op_init_lazy_reg);
-        }
-            
         case op_create_lexical_environment: {
-            Node* lexicalEnvironment = addToGraph(CreateActivation, get(VirtualRegister(currentInstruction[1].u.operand)), get(VirtualRegister(currentInstruction[2].u.operand)));
+            Node* lexicalEnvironment = addToGraph(CreateActivation, get(VirtualRegister(currentInstruction[2].u.operand)));
             set(VirtualRegister(currentInstruction[1].u.operand), lexicalEnvironment);
             set(VirtualRegister(currentInstruction[2].u.operand), lexicalEnvironment);
             NEXT_OPCODE(op_create_lexical_environment);
@@ -3650,48 +3606,51 @@
             NEXT_OPCODE(op_get_scope);
         }
             
-        case op_create_arguments: {
-            m_graph.m_hasArguments = true;
-            Node* createArguments = addToGraph(CreateArguments, get(VirtualRegister(currentInstruction[1].u.operand)));
+        case op_create_direct_arguments: {
+            noticeArgumentsUse();
+            Node* createArguments = addToGraph(CreateDirectArguments);
             set(VirtualRegister(currentInstruction[1].u.operand), createArguments);
-            set(unmodifiedArgumentsRegister(VirtualRegister(currentInstruction[1].u.operand)), createArguments);
-            NEXT_OPCODE(op_create_arguments);
+            NEXT_OPCODE(op_create_direct_arguments);
+        }
+            
+        case op_create_scoped_arguments: {
+            noticeArgumentsUse();
+            Node* createArguments = addToGraph(CreateScopedArguments, get(VirtualRegister(currentInstruction[2].u.operand)));
+            set(VirtualRegister(currentInstruction[1].u.operand), createArguments);
+            NEXT_OPCODE(op_create_scoped_arguments);
         }
 
-        case op_tear_off_arguments: {
-            m_graph.m_hasArguments = true;
-            addToGraph(TearOffArguments, get(VirtualRegister(currentInstruction[1].u.operand)), get(VirtualRegister(currentInstruction[2].u.operand)));
-            NEXT_OPCODE(op_tear_off_arguments);
+        case op_create_out_of_band_arguments: {
+            noticeArgumentsUse();
+            Node* createArguments = addToGraph(CreateClonedArguments);
+            set(VirtualRegister(currentInstruction[1].u.operand), createArguments);
+            NEXT_OPCODE(op_create_out_of_band_arguments);
         }
             
-        case op_get_arguments_length: {
-            m_graph.m_hasArguments = true;
-            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetMyArgumentsLengthSafe));
-            NEXT_OPCODE(op_get_arguments_length);
-        }
-            
-        case op_get_argument_by_val: {
-            m_graph.m_hasArguments = true;
+        case op_get_from_arguments: {
             set(VirtualRegister(currentInstruction[1].u.operand),
                 addToGraph(
-                    GetMyArgumentByValSafe, OpInfo(0), OpInfo(getPrediction()),
-                    get(VirtualRegister(currentInstruction[3].u.operand))));
-            NEXT_OPCODE(op_get_argument_by_val);
+                    GetFromArguments,
+                    OpInfo(currentInstruction[3].u.operand),
+                    OpInfo(getPrediction()),
+                    get(VirtualRegister(currentInstruction[2].u.operand))));
+            NEXT_OPCODE(op_get_from_arguments);
+        }
+            
+        case op_put_to_arguments: {
+            addToGraph(
+                PutToArguments,
+                OpInfo(currentInstruction[2].u.operand),
+                get(VirtualRegister(currentInstruction[1].u.operand)),
+                get(VirtualRegister(currentInstruction[3].u.operand)));
+            NEXT_OPCODE(op_put_to_arguments);
         }
             
         case op_new_func: {
             FunctionExecutable* decl = m_inlineStackTop->m_profiledBlock->functionDecl(currentInstruction[3].u.operand);
             FrozenValue* frozen = m_graph.freezeStrong(decl);
-            if (!currentInstruction[4].u.operand) {
-                set(VirtualRegister(currentInstruction[1].u.operand),
-                    addToGraph(NewFunctionNoCheck, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand))));
-            } else {
-                set(VirtualRegister(currentInstruction[1].u.operand),
-                    addToGraph(
-                        NewFunction,
-                        OpInfo(frozen),
-                        get(VirtualRegister(currentInstruction[1].u.operand)), get(VirtualRegister(currentInstruction[2].u.operand))));
-            }
+            set(VirtualRegister(currentInstruction[1].u.operand),
+                addToGraph(NewFunction, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand))));
             NEXT_OPCODE(op_new_func);
         }
 
@@ -3699,7 +3658,7 @@
             FunctionExecutable* expr = m_inlineStackTop->m_profiledBlock->functionExpr(currentInstruction[3].u.operand);
             FrozenValue* frozen = m_graph.freezeStrong(expr);
             set(VirtualRegister(currentInstruction[1].u.operand),
-                addToGraph(NewFunctionExpression, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand))));
+                addToGraph(NewFunction, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand))));
             NEXT_OPCODE(op_new_func_exp);
         }
 
@@ -3906,12 +3865,6 @@
         m_argumentPositions[i] = argumentPosition;
     }
     
-    // Track the code-block-global exit sites.
-    if (m_exitProfile.hasExitSite(ArgumentsEscaped)) {
-        byteCodeParser->m_graph.m_executablesWhoseArgumentsEscaped.add(
-            codeBlock->ownerExecutable());
-    }
-        
     if (m_caller) {
         // Inline case.
         ASSERT(codeBlock != byteCodeParser->m_codeBlock);
@@ -3936,22 +3889,6 @@
         m_inlineCallFrame->arguments.resize(argumentCountIncludingThis); // Set the number of arguments including this, but don't configure the value recoveries, yet.
         m_inlineCallFrame->kind = kind;
         
-        if (m_inlineCallFrame->caller.inlineCallFrame)
-            m_inlineCallFrame->capturedVars = m_inlineCallFrame->caller.inlineCallFrame->capturedVars;
-        else
-            m_inlineCallFrame->capturedVars = byteCodeParser->m_graph.m_outermostCapturedVars;
-
-        for (int i = argumentCountIncludingThis; i--;) {
-            VirtualRegister argument = virtualRegisterForArgument(i);
-            if (codeBlock->isCaptured(argument))
-                m_inlineCallFrame->capturedVars.set(VirtualRegister(argument.offset() + m_inlineCallFrame->stackOffset).toLocal());
-        }
-        for (size_t i = codeBlock->m_numVars; i--;) {
-            VirtualRegister local = virtualRegisterForLocal(i);
-            if (codeBlock->isCaptured(local))
-                m_inlineCallFrame->capturedVars.set(VirtualRegister(local.offset() + m_inlineCallFrame->stackOffset).toLocal());
-        }
-
         byteCodeParser->buildOperandMapsIfNecessary();
         
         m_identifierRemap.resize(codeBlock->numberOfIdentifiers());
@@ -4029,8 +3966,7 @@
                 " ", inlineCallFrame()->caller);
         }
         dataLog(
-            ": captureCount = ", codeBlock->symbolTable() ? codeBlock->symbolTable()->captureCount() : 0,
-            ", needsActivation = ", codeBlock->needsActivation(),
+            ": needsActivation = ", codeBlock->needsActivation(),
             ", isStrictMode = ", codeBlock->ownerExecutable()->isStrictMode(), "\n");
         codeBlock->baselineVersion()->dumpBytecode();
     }
diff --git a/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp b/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp
index 745bcc0..095fd1a 100644
--- a/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp
@@ -192,21 +192,6 @@
                 return;
             }
             
-            if (variable->isCaptured()) {
-                variable->setIsLoadedFrom(true);
-                if (otherNode->op() == GetLocal)
-                    otherNode = otherNode->child1().node();
-                else
-                    ASSERT(otherNode->op() == SetLocal || otherNode->op() == SetArgument);
-                
-                ASSERT(otherNode->op() == Phi || otherNode->op() == SetLocal || otherNode->op() == SetArgument);
-                
-                // Keep this GetLocal but link it to the prior ones.
-                node->children.setChild1(Edge(otherNode));
-                m_block->variablesAtTail.atFor<operandKind>(idx) = node;
-                return;
-            }
-            
             if (otherNode->op() == GetLocal) {
                 // Replace all references to this GetLocal with otherNode.
                 node->replacement = otherNode;
@@ -335,10 +320,8 @@
             // there ever was a SetLocal and it was followed by Flushes, then the tail
             // variable will be a SetLocal and not those subsequent Flushes.
             //
-            // Child of GetLocal: the operation that the GetLocal keeps alive. For
-            // uncaptured locals, it may be a Phi from the current block. For arguments,
-            // it may be a SetArgument. For captured locals and arguments it may also be
-            // a SetLocal.
+            // Child of GetLocal: the operation that the GetLocal keeps alive. It may be
+            // a Phi from the current block. For arguments, it may be a SetArgument.
             //
             // Child of SetLocal: must be a value producing node.
             //
diff --git a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
index 692ab6e..4148bd8 100644
--- a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -326,8 +326,8 @@
                 return;
         
             if (m_node->op() == GetLocal) {
-                // For uncaptured locals, usually the CPS rethreading phase does this. But it's OK
-                // for us to mess with locals - regardless of their capturedness - so long as:
+                // Usually the CPS rethreading phase does this. But it's OK for us to mess with
+                // locals so long as:
                 // 
                 // - We dethread the graph. Any changes we make may invalidate the assumptions of
                 //   our CPS form, particularly if this GetLocal is linked to the variablesAtTail.
@@ -466,7 +466,7 @@
         // clobbering the value. So, we just search for all of the like values that have been
         // computed. We pick one that is in a block that dominates ours. Note that this means that
         // a PureValue will map to a list of nodes, since there may be many places in the control
-        // flow graph that compute a value but only one of them that dominates us. we may build up
+        // flow graph that compute a value but only one of them that dominates us. We may build up
         // a large list of nodes that compute some value in the case of gnarly control flow. This
         // is probably OK.
         
diff --git a/Source/JavaScriptCore/dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h b/Source/JavaScriptCore/dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h
new file mode 100644
index 0000000..871854c
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGCallCreateDirectArgumentsSlowPathGenerator_h
+#define DFGCallCreateDirectArgumentsSlowPathGenerator_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGCommon.h"
+#include "DFGOperations.h"
+#include "DFGSlowPathGenerator.h"
+#include "DFGSpeculativeJIT.h"
+#include "DirectArguments.h"
+
+namespace JSC { namespace DFG {
+
+// This calls operationCreateDirectArguments but then restores the value of lengthGPR.
+class CallCreateDirectArgumentsSlowPathGenerator : public JumpingSlowPathGenerator<MacroAssembler::JumpList> {
+public:
+    CallCreateDirectArgumentsSlowPathGenerator(
+        MacroAssembler::JumpList from, SpeculativeJIT* jit, GPRReg resultGPR, Structure* structure,
+        GPRReg lengthGPR, unsigned minCapacity)
+        : JumpingSlowPathGenerator<MacroAssembler::JumpList>(from, jit)
+        , m_resultGPR(resultGPR)
+        , m_structure(structure)
+        , m_lengthGPR(lengthGPR)
+        , m_minCapacity(minCapacity)
+    {
+        jit->silentSpillAllRegistersImpl(false, m_plans, resultGPR);
+    }
+
+protected:
+    void generateInternal(SpeculativeJIT* jit) override
+    {
+        linkFrom(jit);
+        for (unsigned i = 0; i < m_plans.size(); ++i)
+            jit->silentSpill(m_plans[i]);
+        jit->callOperation(
+            operationCreateDirectArguments, m_resultGPR, m_structure, m_lengthGPR, m_minCapacity);
+        GPRReg canTrample = SpeculativeJIT::pickCanTrample(m_resultGPR);
+        for (unsigned i = m_plans.size(); i--;)
+            jit->silentFill(m_plans[i], canTrample);
+        jit->m_jit.loadPtr(
+            MacroAssembler::Address(m_resultGPR, DirectArguments::offsetOfLength()), m_lengthGPR);
+        jumpTo(jit);
+    }
+    
+private:
+    GPRReg m_resultGPR;
+    Structure* m_structure;
+    GPRReg m_lengthGPR;
+    unsigned m_minCapacity;
+    Vector<SilentRegisterSavePlan, 2> m_plans;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGCallCreateDirectArgumentsSlowPathGenerator_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGCapabilities.cpp b/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
index f54b223..8ef4dcf15 100644
--- a/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
@@ -44,8 +44,7 @@
 
 bool isSupportedForInlining(CodeBlock* codeBlock)
 {
-    return !codeBlock->ownerExecutable()->needsActivation()
-        && codeBlock->ownerExecutable()->isInliningCandidate();
+    return codeBlock->ownerExecutable()->isInliningCandidate();
 }
 
 bool mightCompileEval(CodeBlock* codeBlock)
@@ -184,11 +183,11 @@
     case op_construct:
     case op_call_varargs:
     case op_construct_varargs:
-    case op_init_lazy_reg:
-    case op_create_arguments:
-    case op_tear_off_arguments:
-    case op_get_argument_by_val:
-    case op_get_arguments_length:
+    case op_create_direct_arguments:
+    case op_create_scoped_arguments:
+    case op_create_out_of_band_arguments:
+    case op_get_from_arguments:
+    case op_put_to_arguments:
     case op_jneq_ptr:
     case op_typeof:
     case op_to_number:
@@ -208,6 +207,7 @@
     case op_to_index_string:
     case op_new_func:
     case op_new_func_exp:
+    case op_create_lexical_environment:
         return CanCompileAndInline;
 
     case op_put_to_scope: {
@@ -227,8 +227,7 @@
         return CanCompileAndInline;
     }
 
-    case op_new_regexp: 
-    case op_create_lexical_environment:
+    case op_new_regexp:
     case op_switch_string: // Don't inline because we don't want to copy string tables in the concurrent JIT.
         return CanCompile;
 
diff --git a/Source/JavaScriptCore/dfg/DFGClobberize.h b/Source/JavaScriptCore/dfg/DFGClobberize.h
index a695607..521b3e9 100644
--- a/Source/JavaScriptCore/dfg/DFGClobberize.h
+++ b/Source/JavaScriptCore/dfg/DFGClobberize.h
@@ -270,7 +270,6 @@
     case Phi:
     case PhantomLocal:
     case SetArgument:
-    case PhantomArguments:
     case Jump:
     case Branch:
     case Switch:
@@ -300,7 +299,7 @@
         return;
 
     case Flush:
-        read(AbstractHeap(Variables, node->local()));
+        read(AbstractHeap(Stack, node->local()));
         write(SideState);
         return;
 
@@ -317,16 +316,26 @@
     case CreateActivation:
         read(HeapObjectCount);
         write(HeapObjectCount);
-        write(SideState);
-        write(Watchpoint_fire);
         return;
         
-    case CreateArguments:
-        read(Variables);
+    case CreateDirectArguments:
+    case CreateScopedArguments:
+    case CreateClonedArguments:
+        read(Stack);
         read(HeapObjectCount);
         write(HeapObjectCount);
-        write(SideState);
-        write(Watchpoint_fire);
+        return;
+
+    case PhantomDirectArguments:
+    case PhantomClonedArguments:
+        // DFG backend requires that the locals that this reads are flushed. FTL backend can handle those
+        // locals being promoted.
+        if (!isFTL(graph.m_plan.mode))
+            read(Stack);
+        
+        // Even though it's phantom, it still has the property that one can't be replaced with another.
+        read(HeapObjectCount);
+        write(HeapObjectCount);
         return;
 
     case ToThis:
@@ -375,10 +384,9 @@
     case CallVarargs:
     case CallForwardVarargs:
     case ConstructVarargs:
+    case ConstructForwardVarargs:
     case ToPrimitive:
     case In:
-    case GetMyArgumentsLengthSafe:
-    case GetMyArgumentByValSafe:
     case ValueAdd:
         read(World);
         write(Heap);
@@ -395,44 +403,63 @@
         return;
         
     case GetCallee:
-        read(AbstractHeap(Variables, JSStack::Callee));
-        def(HeapLocation(VariableLoc, AbstractHeap(Variables, JSStack::Callee)), node);
+        read(AbstractHeap(Stack, JSStack::Callee));
+        def(HeapLocation(StackLoc, AbstractHeap(Stack, JSStack::Callee)), node);
+        return;
+        
+    case GetArgumentCount:
+        read(AbstractHeap(Stack, JSStack::ArgumentCount));
+        def(HeapLocation(StackPayloadLoc, AbstractHeap(Stack, JSStack::ArgumentCount)), node);
         return;
         
     case GetLocal:
-        read(AbstractHeap(Variables, node->local()));
-        def(HeapLocation(VariableLoc, AbstractHeap(Variables, node->local())), node);
+        read(AbstractHeap(Stack, node->local()));
+        def(HeapLocation(StackLoc, AbstractHeap(Stack, node->local())), node);
         return;
         
     case SetLocal:
-        write(AbstractHeap(Variables, node->local()));
-        def(HeapLocation(VariableLoc, AbstractHeap(Variables, node->local())), node->child1().node());
+        write(AbstractHeap(Stack, node->local()));
+        def(HeapLocation(StackLoc, AbstractHeap(Stack, node->local())), node->child1().node());
         return;
         
     case GetStack: {
-        AbstractHeap heap(Variables, node->stackAccessData()->local);
+        AbstractHeap heap(Stack, node->stackAccessData()->local);
         read(heap);
-        def(HeapLocation(VariableLoc, heap), node);
+        def(HeapLocation(StackLoc, heap), node);
         return;
     }
         
     case PutStack: {
-        AbstractHeap heap(Variables, node->stackAccessData()->local);
+        AbstractHeap heap(Stack, node->stackAccessData()->local);
         write(heap);
-        def(HeapLocation(VariableLoc, heap), node->child1().node());
+        def(HeapLocation(StackLoc, heap), node->child1().node());
         return;
     }
         
-    case LoadVarargs:
-        // This actually writes to local variables as well. But when it reads the array, it does
-        // so in a way that may trigger getters or various traps.
+    case LoadVarargs: {
         read(World);
-        write(World);
+        write(Heap);
+        LoadVarargsData* data = node->loadVarargsData();
+        write(AbstractHeap(Stack, data->count.offset()));
+        for (unsigned i = data->limit; i--;)
+            write(AbstractHeap(Stack, data->start.offset() + static_cast<int>(i)));
         return;
+    }
+        
+    case ForwardVarargs: {
+        // We could be way more precise here.
+        read(Stack);
+        
+        LoadVarargsData* data = node->loadVarargsData();
+        write(AbstractHeap(Stack, data->count.offset()));
+        for (unsigned i = data->limit; i--;)
+            write(AbstractHeap(Stack, data->start.offset() + static_cast<int>(i)));
+        return;
+    }
         
     case GetLocalUnlinked:
-        read(AbstractHeap(Variables, node->unlinkedLocal()));
-        def(HeapLocation(VariableLoc, AbstractHeap(Variables, node->unlinkedLocal())), node);
+        read(AbstractHeap(Stack, node->unlinkedLocal()));
+        def(HeapLocation(StackLoc, AbstractHeap(Stack, node->unlinkedLocal())), node);
         return;
         
     case GetByVal: {
@@ -465,10 +492,14 @@
             def(PureValue(node, mode.asWord()));
             return;
             
-        case Array::Arguments:
-            read(Arguments_registers);
-            read(Variables);
-            def(HeapLocation(IndexedPropertyLoc, Variables, node->child1(), node->child2()), node);
+        case Array::DirectArguments:
+            read(DirectArgumentsProperties);
+            def(HeapLocation(IndexedPropertyLoc, DirectArgumentsProperties, node->child1(), node->child2()), node);
+            return;
+            
+        case Array::ScopedArguments:
+            read(ScopeProperties);
+            def(HeapLocation(IndexedPropertyLoc, ScopeProperties, node->child1(), node->child2()), node);
             return;
             
         case Array::Int32:
@@ -532,6 +563,13 @@
         RELEASE_ASSERT_NOT_REACHED();
         return;
     }
+        
+    case GetMyArgumentByVal: {
+        read(Stack);
+        // FIXME: It would be trivial to have a def here.
+        // https://bugs.webkit.org/show_bug.cgi?id=143077
+        return;
+    }
 
     case PutByValDirect:
     case PutByVal:
@@ -544,7 +582,6 @@
         case Array::SelectUsingPredictions:
         case Array::Unprofiled:
         case Array::Undecided:
-        case Array::String:
             // Assume the worst since we don't have profiling yet.
             read(World);
             write(Heap);
@@ -559,13 +596,6 @@
             write(Heap);
             return;
             
-        case Array::Arguments:
-            read(Arguments_registers);
-            read(MiscFields);
-            write(Variables);
-            def(HeapLocation(IndexedPropertyLoc, Variables, base, index), value);
-            return;
-            
         case Array::Int32:
             if (node->arrayMode().isOutOfBounds()) {
                 read(World);
@@ -632,6 +662,11 @@
             // FIXME: We can't def() anything here because these operations truncate their inputs.
             // https://bugs.webkit.org/show_bug.cgi?id=134737
             return;
+        case Array::String:
+        case Array::DirectArguments:
+        case Array::ScopedArguments:
+            DFG_CRASH(graph, node, "impossible array mode for put");
+            return;
         }
         RELEASE_ASSERT_NOT_REACHED();
         return;
@@ -760,7 +795,8 @@
             def(PureValue(node, mode.asWord()));
             return;
             
-        case Array::Arguments:
+        case Array::DirectArguments:
+        case Array::ScopedArguments:
             read(MiscFields);
             def(HeapLocation(ArrayLengthLoc, MiscFields, node->child1()), node);
             return;
@@ -773,29 +809,38 @@
         }
     }
         
-    case GetClosureRegisters:
-        read(JSEnvironmentRecord_registers);
-        def(HeapLocation(ClosureRegistersLoc, JSEnvironmentRecord_registers, node->child1()), node);
-        return;
-
     case GetClosureVar:
-        read(AbstractHeap(Variables, node->varNumber()));
-        def(HeapLocation(ClosureVariableLoc, AbstractHeap(Variables, node->varNumber()), node->child1()), node);
+        read(AbstractHeap(ScopeProperties, node->scopeOffset().offset()));
+        def(HeapLocation(ClosureVariableLoc, AbstractHeap(ScopeProperties, node->scopeOffset().offset()), node->child1()), node);
         return;
         
     case PutClosureVar:
-        write(AbstractHeap(Variables, node->varNumber()));
-        def(HeapLocation(ClosureVariableLoc, AbstractHeap(Variables, node->varNumber()), node->child1()), node->child3().node());
+        write(AbstractHeap(ScopeProperties, node->scopeOffset().offset()));
+        def(HeapLocation(ClosureVariableLoc, AbstractHeap(ScopeProperties, node->scopeOffset().offset()), node->child2()), node->child2().node());
         return;
         
+    case GetFromArguments: {
+        AbstractHeap heap(DirectArgumentsProperties, node->capturedArgumentsOffset().offset());
+        read(heap);
+        def(HeapLocation(DirectArgumentsLoc, heap), node);
+        return;
+    }
+        
+    case PutToArguments: {
+        AbstractHeap heap(DirectArgumentsProperties, node->capturedArgumentsOffset().offset());
+        write(heap);
+        def(HeapLocation(DirectArgumentsLoc, heap), node->child2().node());
+        return;
+    }
+        
     case GetGlobalVar:
-        read(AbstractHeap(Absolute, node->registerPointer()));
-        def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node->registerPointer())), node);
+        read(AbstractHeap(Absolute, node->variablePointer()));
+        def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node->variablePointer())), node);
         return;
         
     case PutGlobalVar:
-        write(AbstractHeap(Absolute, node->registerPointer()));
-        def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node->registerPointer())), node->child1().node());
+        write(AbstractHeap(Absolute, node->variablePointer()));
+        def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node->variablePointer())), node->child1().node());
         return;
 
     case NewArray:
@@ -815,9 +860,7 @@
     case NewStringObject:
     case PhantomNewObject:
     case MaterializeNewObject:
-    case NewFunctionNoCheck:
     case NewFunction:
-    case NewFunctionExpression:
         read(HeapObjectCount);
         write(HeapObjectCount);
         return;
@@ -869,30 +912,6 @@
             return;
         }
         
-    case TearOffArguments:
-        read(Variables);
-        write(Arguments_registers);
-        return;
-        
-    case GetMyArgumentsLength:
-        read(AbstractHeap(Variables, graph.argumentsRegisterFor(node->origin.semantic)));
-        read(AbstractHeap(Variables, JSStack::ArgumentCount));
-        // FIXME: We could def() this by specifying the code origin as a kind of m_info, like we
-        // have for PureValue.
-        // https://bugs.webkit.org/show_bug.cgi?id=134797
-        return;
-        
-    case GetMyArgumentByVal:
-        read(Variables);
-        // FIXME: We could def() this by specifying the code origin as a kind of m_info, like we
-        // have for PureValue.
-        // https://bugs.webkit.org/show_bug.cgi?id=134797
-        return;
-        
-    case CheckArgumentsNotCreated:
-        read(AbstractHeap(Variables, graph.argumentsRegisterFor(node->origin.semantic)));
-        return;
-
     case ThrowReferenceError:
         write(SideState);
         read(HeapObjectCount);
diff --git a/Source/JavaScriptCore/dfg/DFGCommon.h b/Source/JavaScriptCore/dfg/DFGCommon.h
index 887c939..163b254 100644
--- a/Source/JavaScriptCore/dfg/DFGCommon.h
+++ b/Source/JavaScriptCore/dfg/DFGCommon.h
@@ -30,7 +30,6 @@
 
 #if ENABLE(DFG_JIT)
 
-#include "CodeOrigin.h"
 #include "Options.h"
 #include "VirtualRegister.h"
 
@@ -193,12 +192,10 @@
     // expect to be live at the head, and which locals they make available at the
     // tail. ThreadedCPS form also implies that:
     //
-    // - GetLocals and SetLocals to uncaptured variables are not redundant within
-    //   a basic block.
+    // - GetLocals and SetLocals are not redundant within a basic block.
     //
     // - All GetLocals and Flushes are linked directly to the last access point
-    //   of the variable, which must not be another GetLocal if the variable is
-    //   uncaptured.
+    //   of the variable, which must not be another GetLocal.
     //
     // - Phantom(Phi) is not legal, but PhantomLocal is.
     //
diff --git a/Source/JavaScriptCore/dfg/DFGCommonData.h b/Source/JavaScriptCore/dfg/DFGCommonData.h
index 593ea95..f3afec7 100644
--- a/Source/JavaScriptCore/dfg/DFGCommonData.h
+++ b/Source/JavaScriptCore/dfg/DFGCommonData.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -71,7 +71,6 @@
 public:
     CommonData()
         : isStillValid(true)
-        , machineCaptureStart(std::numeric_limits<int>::max())
         , frameRegisterCount(std::numeric_limits<unsigned>::max())
         , requiredRegisterCountForExit(std::numeric_limits<unsigned>::max())
     { }
@@ -103,9 +102,6 @@
     bool allTransitionsHaveBeenMarked; // Initialized and used on every GC.
     bool isStillValid;
     
-    int machineCaptureStart;
-    std::unique_ptr<SlowArgument[]> slowArguments;
-
 #if USE(JSVALUE32_64)
     std::unique_ptr<Bag<double>> doubleConstants;
 #endif
diff --git a/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp b/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
index dd13a89..a1d107d 100644
--- a/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +29,7 @@
 #if ENABLE(DFG_JIT)
 
 #include "DFGAbstractInterpreterInlines.h"
+#include "DFGArgumentsUtilities.h"
 #include "DFGBasicBlock.h"
 #include "DFGGraph.h"
 #include "DFGInPlaceAbstractState.h"
@@ -97,16 +98,6 @@
                 break;
             }
                 
-            case CheckArgumentsNotCreated: {
-                if (!isEmptySpeculation(
-                        m_state.variables().operand(
-                            m_graph.argumentsRegisterFor(node->origin.semantic)).m_type))
-                    break;
-                node->convertToPhantom();
-                eliminated = true;
-                break;
-            }
-                    
             case CheckStructure:
             case ArrayifyToStructure: {
                 AbstractValue& value = m_state.forNode(node->child1());
@@ -207,6 +198,63 @@
                 break;
             }
                 
+            case GetMyArgumentByVal: {
+                JSValue index = m_state.forNode(node->child2()).value();
+                if (!index || !index.isInt32())
+                    break;
+                
+                Node* arguments = node->child1().node();
+                InlineCallFrame* inlineCallFrame = arguments->origin.semantic.inlineCallFrame;
+                
+                // Don't try to do anything if the index is known to be outside our static bounds. Note
+                // that our static bounds are usually strictly larger than the dynamic bounds. The
+                // exception is something like this, assuming foo() is not inlined:
+                //
+                // function foo() { return arguments[5]; }
+                //
+                // Here the static bound on number of arguments is 0, and we're accessing index 5. We
+                // will not strength-reduce this to GetStack because GetStack is otherwise assumed by the
+                // compiler to access those variables that are statically accounted for; for example if
+                // we emitted a GetStack on arg6 we would have out-of-bounds access crashes anywhere that
+                // uses an Operands<> map. There is not much cost to continuing to use a
+                // GetMyArgumentByVal in such statically-out-of-bounds accesses; we just lose CFA unless
+                // GCSE removes the access entirely.
+                if (inlineCallFrame) {
+                    if (index.isUInt32() >= inlineCallFrame->arguments.size() - 1)
+                        break;
+                } else {
+                    if (index.isUInt32() >= m_state.variables().numberOfArguments() - 1)
+                        break;
+                }
+                
+                m_interpreter.execute(indexInBlock); // Push CFA over this node after we get the state before.
+                
+                StackAccessData* data;
+                if (inlineCallFrame) {
+                    data = m_graph.m_stackAccessData.add(
+                        inlineCallFrame->arguments[index.asInt32() + 1].virtualRegister(), FlushedJSValue);
+                } else {
+                    data = m_graph.m_stackAccessData.add(
+                        virtualRegisterForArgument(index.asInt32() + 1), FlushedJSValue);
+                }
+                
+                if (inlineCallFrame && !inlineCallFrame->isVarargs()
+                    && index.asUInt32() < inlineCallFrame->arguments.size() - 1) {
+                    node->convertToGetStack(data);
+                    eliminated = true;
+                    break;
+                }
+                
+                Node* length = emitCodeToGetArgumentsArrayLength(
+                    m_insertionSet, arguments, indexInBlock, node->origin);
+                m_insertionSet.insertNode(
+                    indexInBlock, SpecNone, CheckInBounds, node->origin,
+                    node->child2(), Edge(length, Int32Use));
+                node->convertToGetStack(data);
+                eliminated = true;
+                break;
+            }
+                
             case MultiGetByOffset: {
                 Edge baseEdge = node->child1();
                 Node* base = baseEdge.node();
@@ -385,37 +433,6 @@
                 break;
             }
                 
-            case GetMyArgumentByVal: {
-                InlineCallFrame* inlineCallFrame = node->origin.semantic.inlineCallFrame;
-                JSValue value = m_state.forNode(node->child1()).m_value;
-                if (inlineCallFrame && value && value.isInt32()) {
-                    int32_t index = value.asInt32();
-                    if (index >= 0
-                        && static_cast<size_t>(index + 1) < inlineCallFrame->arguments.size()) {
-                        // Roll the interpreter over this.
-                        m_interpreter.execute(indexInBlock);
-                        eliminated = true;
-                        
-                        int operand =
-                            inlineCallFrame->stackOffset +
-                            m_graph.baselineCodeBlockFor(inlineCallFrame)->argumentIndexAfterCapture(index);
-                        
-                        m_insertionSet.insertNode(
-                            indexInBlock, SpecNone, CheckArgumentsNotCreated, node->origin);
-                        m_insertionSet.insertNode(
-                            indexInBlock, SpecNone, Phantom, node->origin, node->children);
-                        
-                        if (m_graph.m_form == SSA)
-                            node->convertToGetStack(m_graph.m_stackAccessData.add(VirtualRegister(operand), FlushedJSValue));
-                        else
-                            node->convertToGetLocalUnlinked(VirtualRegister(operand));
-                        break;
-                    }
-                }
-                
-                break;
-            }
-                
             case Check: {
                 alreadyHandled = true;
                 m_interpreter.execute(indexInBlock);
diff --git a/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp b/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp
index 9a4bbda..36042d9 100644
--- a/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -205,37 +205,7 @@
             if (node->op() == GetLocal) {
                 node = node->child1().node();
                 
-                // FIXME: In the case that the variable is captured, we really want to be able
-                // to replace the variable-at-tail with the last use of the variable in the same
-                // way that CPS rethreading would do. The child of the GetLocal isn't necessarily
-                // the same as what CPS rethreading would do. For example, we may have:
-                //
-                // a: SetLocal(...) // live
-                // b: GetLocal(@a) // live
-                // c: GetLocal(@a) // dead
-                //
-                // When killing @c, the code below will set the variable-at-tail to @a, while CPS
-                // rethreading would have set @b. This is a benign bug, since all clients of CPS
-                // only use the variable-at-tail of captured variables to get the
-                // VariableAccessData and observe that it is in fact captured. But, this feels
-                // like it could cause bugs in the future.
-                //
-                // It's tempting to just dethread and then invoke CPS rethreading, but CPS
-                // rethreading fails to preserve exact ref-counts. So we would need a fixpoint.
-                // It's probably the case that this fixpoint will be guaranteed to converge after
-                // the second iteration (i.e. the second run of DCE will not kill anything and so
-                // will not need to dethread), but for now the safest approach is probably just to
-                // allow for this tiny bit of sloppiness.
-                //
-                // Another possible solution would be to simply say that DCE dethreads but then
-                // we never rethread before going to the backend. That feels intuitively right
-                // because it's unlikely that any of the phases after DCE in the backend rely on
-                // ThreadedCPS.
-                //
-                // https://bugs.webkit.org/show_bug.cgi?id=130115
-                ASSERT(
-                    node->op() == Phi || node->op() == SetArgument
-                    || node->variableAccessData()->isCaptured());
+                ASSERT(node->op() == Phi || node->op() == SetArgument);
                 
                 if (node->shouldGenerate()) {
                     variables[i] = node;
diff --git a/Source/JavaScriptCore/dfg/DFGDisassembler.h b/Source/JavaScriptCore/dfg/DFGDisassembler.h
index 7844fc2..7b31946 100644
--- a/Source/JavaScriptCore/dfg/DFGDisassembler.h
+++ b/Source/JavaScriptCore/dfg/DFGDisassembler.h
@@ -28,6 +28,7 @@
 
 #if ENABLE(DFG_JIT)
 
+#include "CodeOrigin.h"
 #include "DFGCommon.h"
 #include "DumpContext.h"
 #include "MacroAssembler.h"
diff --git a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
index 375ac75..adee2f5 100644
--- a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
+++ b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
@@ -49,6 +49,7 @@
     case Int52Constant:
     case Identity:
     case GetCallee:
+    case GetArgumentCount:
     case GetLocal:
     case SetLocal:
     case MovHint:
@@ -98,7 +99,6 @@
     case CheckArray:
     case GetScope:
     case SkipScope:
-    case GetClosureRegisters:
     case GetClosureVar:
     case PutClosureVar:
     case GetGlobalVar:
@@ -122,6 +122,7 @@
     case ConstructVarargs:
     case LoadVarargs:
     case CallForwardVarargs:
+    case ConstructForwardVarargs:
     case NativeCall:
     case NativeConstruct:
     case Breakpoint:
@@ -143,13 +144,6 @@
     case ToPrimitive:
     case ToString:
     case In:
-    case PhantomArguments:
-    case TearOffArguments:
-    case GetMyArgumentsLength:
-    case GetMyArgumentByVal:
-    case GetMyArgumentsLengthSafe:
-    case GetMyArgumentByValSafe:
-    case CheckArgumentsNotCreated:
     case Jump:
     case Branch:
     case Switch:
@@ -204,15 +198,23 @@
     case CheckBadCell:
     case BottomValue:
     case PhantomNewObject:
+    case PhantomDirectArguments:
+    case PhantomClonedArguments:
+    case GetMyArgumentByVal:
+    case ForwardVarargs:
     case PutHint:
     case CheckStructureImmediate:
     case PutStack:
     case KillStack:
     case GetStack:
+    case GetFromArguments:
+    case PutToArguments:
         return false;
 
     case CreateActivation:
-    case CreateArguments:
+    case CreateDirectArguments:
+    case CreateScopedArguments:
+    case CreateClonedArguments:
     case ToThis:
     case CreateThis:
     case AllocatePropertyStorage:
@@ -226,9 +228,7 @@
     case NewRegexp:
     case NewStringObject:
     case MakeRope:
-    case NewFunctionNoCheck:
     case NewFunction:
-    case NewFunctionExpression:
     case NewTypedArray:
     case ThrowReferenceError:
     case GetPropertyEnumerator:
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index 191925a..146ee5c 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -658,7 +658,6 @@
             case Array::Contiguous:
             case Array::ArrayStorage:
             case Array::SlowPutArrayStorage:
-            case Array::Arguments:
                 fixEdge<KnownCellUse>(child1);
                 fixEdge<Int32Use>(child2);
                 insertStoreBarrier(m_indexInBlock, child1, child3);
@@ -857,30 +856,25 @@
             break;
         }
             
-        case GetMyArgumentByVal:
-        case GetMyArgumentByValSafe: {
-            fixEdge<Int32Use>(node->child1());
-            break;
-        }
-            
         case PutStructure: {
             fixEdge<KnownCellUse>(node->child1());
             insertStoreBarrier(m_indexInBlock, node->child1());
             break;
         }
-
-        case GetClosureVar: {
+            
+        case GetClosureVar:
+        case GetFromArguments: {
             fixEdge<KnownCellUse>(node->child1());
             break;
         }
 
-        case PutClosureVar: {
+        case PutClosureVar:
+        case PutToArguments: {
             fixEdge<KnownCellUse>(node->child1());
-            insertStoreBarrier(m_indexInBlock, node->child1(), node->child3());
+            insertStoreBarrier(m_indexInBlock, node->child1(), node->child2());
             break;
         }
-
-        case GetClosureRegisters:
+            
         case SkipScope:
         case GetScope:
         case GetGetter:
@@ -1041,6 +1035,10 @@
         case Identity: // This should have been cleaned up.
         case BooleanToNumber:
         case PhantomNewObject:
+        case PhantomDirectArguments:
+        case PhantomClonedArguments:
+        case ForwardVarargs:
+        case GetMyArgumentByVal:
         case PutHint:
         case CheckStructureImmediate:
         case MaterializeNewObject:
@@ -1180,14 +1178,9 @@
             break;
         }
 
+        case CreateScopedArguments:
         case CreateActivation:
         case NewFunction: {
-            fixEdge<CellUse>(node->child2());
-            break;
-        }
-
-        case NewFunctionNoCheck:
-        case NewFunctionExpression: {
             fixEdge<CellUse>(node->child1());
             break;
         }
@@ -1199,6 +1192,7 @@
         case DoubleConstant:
         case GetLocal:
         case GetCallee:
+        case GetArgumentCount:
         case Flush:
         case PhantomLocal:
         case GetLocalUnlinked:
@@ -1211,6 +1205,7 @@
         case CallVarargs:
         case ConstructVarargs:
         case CallForwardVarargs:
+        case ConstructForwardVarargs:
         case LoadVarargs:
         case ProfileControlFlow:
         case NativeCall:
@@ -1226,12 +1221,8 @@
         case IsNumber:
         case IsObjectOrNull:
         case IsFunction:
-        case CreateArguments:
-        case PhantomArguments:
-        case TearOffArguments:
-        case GetMyArgumentsLength:
-        case GetMyArgumentsLengthSafe:
-        case CheckArgumentsNotCreated:
+        case CreateDirectArguments:
+        case CreateClonedArguments:
         case Jump:
         case Return:
         case Throw:
diff --git a/Source/JavaScriptCore/dfg/DFGFlushFormat.cpp b/Source/JavaScriptCore/dfg/DFGFlushFormat.cpp
index 0bf55ba..fa483ac 100644
--- a/Source/JavaScriptCore/dfg/DFGFlushFormat.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFlushFormat.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -58,9 +58,6 @@
     case FlushedJSValue:
         out.print("FlushedJSValue");
         return;
-    case FlushedArguments:
-        out.print("FlushedArguments");
-        return;
     case ConflictingFlush:
         out.print("ConflictingFlush");
         return;
diff --git a/Source/JavaScriptCore/dfg/DFGFlushFormat.h b/Source/JavaScriptCore/dfg/DFGFlushFormat.h
index 268c1de..480944b 100644
--- a/Source/JavaScriptCore/dfg/DFGFlushFormat.h
+++ b/Source/JavaScriptCore/dfg/DFGFlushFormat.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -44,7 +44,6 @@
     FlushedCell,
     FlushedBoolean,
     FlushedJSValue,
-    FlushedArguments,
     ConflictingFlush
 };
 
@@ -55,7 +54,6 @@
     case FlushedJSValue:
     case FlushedCell:
     case ConflictingFlush:
-    case FlushedArguments:
         return NodeResultJS;
     case FlushedInt32:
         return NodeResultInt32;
@@ -76,7 +74,6 @@
     case DeadFlush:
     case FlushedJSValue:
     case ConflictingFlush:
-    case FlushedArguments:
         return UntypedUse;
     case FlushedCell:
         return CellUse;
@@ -116,8 +113,6 @@
         return DataFormatCell;
     case FlushedBoolean:
         return DataFormatBoolean;
-    case FlushedArguments:
-        return DataFormatArguments;
     }
     RELEASE_ASSERT_NOT_REACHED();
     return DataFormatDead;
diff --git a/Source/JavaScriptCore/dfg/DFGForAllKills.h b/Source/JavaScriptCore/dfg/DFGForAllKills.h
new file mode 100644
index 0000000..c3b5b09
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGForAllKills.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGForAllKills_h
+#define DFGForAllKills_h
+
+#include "BytecodeKills.h"
+#include "DFGGraph.h"
+#include "DFGOSRAvailabilityAnalysisPhase.h"
+#include "FullBytecodeLiveness.h"
+
+namespace JSC { namespace DFG {
+
+// Utilities for finding the last points where a node is live in DFG SSA. This accounts for liveness due
+// to OSR exit. This is usually used for enumerating over all of the program points where a node is live,
+// by exploring all blocks where the node is live at tail and then exploring all program points where the
+// node is killed. A prerequisite to using these utilities is having liveness and OSR availability
+// computed.
+
+template<typename Functor>
+void forAllLiveNodesAtTail(Graph& graph, BasicBlock* block, const Functor& functor)
+{
+    HashSet<Node*> seen;
+    for (Node* node : block->ssa->liveAtTail) {
+        if (seen.add(node).isNewEntry)
+            functor(node);
+    }
+    
+    DFG_ASSERT(graph, block->last(), block->last()->origin.forExit.isSet());
+    
+    AvailabilityMap& availabilityMap = block->ssa->availabilityAtTail;
+    for (unsigned i = availabilityMap.m_locals.size(); i--;) {
+        VirtualRegister reg = availabilityMap.m_locals.virtualRegisterForIndex(i);
+        
+        if (!graph.isLiveInBytecode(reg, block->last()->origin.forExit))
+            continue;
+        
+        availabilityMap.closeStartingWithLocal(
+            reg,
+            [&] (Node* node) -> bool {
+                return seen.contains(node);
+            },
+            [&] (Node* node) -> bool {
+                if (!seen.add(node).isNewEntry)
+                    return false;
+                functor(node);
+                return true;
+            });
+    }
+}
+
+template<typename Functor>
+void forAllDirectlyKilledOperands(Graph& graph, CodeOrigin origin, const Functor& functor)
+{
+    graph.killsFor(origin.inlineCallFrame).forEachOperandKilledAt(origin.bytecodeIndex, functor);
+}
+
+template<typename Functor>
+void forAllKilledOperands(Graph& graph, CodeOrigin before, CodeOrigin after, const Functor& functor)
+{
+    // The philosophy here is that if we're on the boundary between exiting to origin A and exiting
+    // to origin B, then we note the kills for A. Kills for A are the bytecode kills plus the things
+    // that were live at whatever callsites are popped between A and B. It's legal to conservatively
+    // just consider everything live at A.
+    
+    if (!before) {
+        if (!after)
+            return;
+        // The true before-origin is the origin at predecessors that jump to us. But there can be
+        // many such predecessors and they will likely all have a different origin. So, it's better
+        // to do the conservative thing.
+        for (unsigned i = graph.block(0)->variablesAtHead.numberOfLocals(); i--;) {
+            VirtualRegister reg = virtualRegisterForLocal(i);
+            if (graph.isLiveInBytecode(reg, after))
+                functor(reg);
+        }
+        return;
+    }
+    
+    if (before == after)
+        return;
+    
+    // before could be unset even if after is, but the opposite cannot happen.
+    ASSERT(!!after);
+    
+    if (before.inlineCallFrame != after.inlineCallFrame) {
+        // Is before deeper than after?
+        bool beforeIsDeeper;
+        if (!after.inlineCallFrame)
+            beforeIsDeeper = true;
+        else {
+            beforeIsDeeper = false;
+            for (InlineCallFrame* current = before.inlineCallFrame; current; current = current->caller.inlineCallFrame) {
+                if (current == after.inlineCallFrame) {
+                    beforeIsDeeper = true;
+                    break;
+                }
+            }
+        }
+        if (beforeIsDeeper) {
+            ASSERT(before.inlineCallFrame);
+            for (CodeOrigin current = before; current.inlineCallFrame != after.inlineCallFrame; current = current.inlineCallFrame->caller) {
+                ASSERT(current.inlineCallFrame);
+                CodeBlock* codeBlock = graph.baselineCodeBlockFor(current.inlineCallFrame);
+                FullBytecodeLiveness& liveness = graph.livenessFor(codeBlock);
+                for (unsigned i = codeBlock->m_numCalleeRegisters; i--;) {
+                    VirtualRegister reg = virtualRegisterForLocal(i);
+                    if (liveness.operandIsLive(reg.offset(), current.bytecodeIndex))
+                        functor(reg + current.inlineCallFrame->stackOffset);
+                }
+                forAllDirectlyKilledOperands(graph, current.inlineCallFrame->caller, functor);
+            }
+        }
+    }
+    
+    forAllDirectlyKilledOperands(graph, before, functor);
+}
+    
+// Tells you all of the nodes that would no longer be live across the node at this nodeIndex.
+template<typename Functor>
+void forAllKilledNodesAtNodeIndex(
+    Graph& graph, AvailabilityMap& availabilityMap, BasicBlock* block, unsigned nodeIndex,
+    const Functor& functor)
+{
+    static const unsigned seenInClosureFlag = 1;
+    static const unsigned calledFunctorFlag = 2;
+    HashMap<Node*, unsigned> flags;
+    
+    Node* node = block->at(nodeIndex);
+    
+    graph.doToChildren(
+        node,
+        [&] (Edge edge) {
+            if (edge.doesKill()) {
+                auto& result = flags.add(edge.node(), 0).iterator->value;
+                if (!(result & calledFunctorFlag)) {
+                    functor(edge.node());
+                    result |= calledFunctorFlag;
+                }
+            }
+        });
+
+    CodeOrigin before;
+    if (nodeIndex)
+        before = block->at(nodeIndex - 1)->origin.forExit;
+
+    forAllKilledOperands(
+        graph, before, node->origin.forExit,
+        [&] (VirtualRegister reg) {
+            availabilityMap.closeStartingWithLocal(
+                reg,
+                [&] (Node* node) -> bool {
+                    return flags.get(node) & seenInClosureFlag;
+                },
+                [&] (Node* node) -> bool {
+                    auto& resultFlags = flags.add(node, 0).iterator->value;
+                    bool result = resultFlags & seenInClosureFlag;
+                    if (!(resultFlags & calledFunctorFlag))
+                        functor(node);
+                    resultFlags |= seenInClosureFlag | calledFunctorFlag;
+                    return result;
+                });
+        });
+}
+
+// Tells you all of the places to start searching from in a basic block. Gives you the node index at which
+// the value is either no longer live. This pretends that nodes are dead at the end of the block, so that
+// you can use this to do per-basic-block analyses.
+template<typename Functor>
+void forAllKillsInBlock(Graph& graph, BasicBlock* block, const Functor& functor)
+{
+    forAllLiveNodesAtTail(
+        graph, block,
+        [&] (Node* node) {
+            functor(block->size(), node);
+        });
+    
+    LocalOSRAvailabilityCalculator localAvailability;
+    localAvailability.beginBlock(block);
+    // Start at the second node, because the functor is expected to only inspect nodes from the start of
+    // the block up to nodeIndex (exclusive), so if nodeIndex is zero then the functor has nothing to do.
+    for (unsigned nodeIndex = 1; nodeIndex < block->size(); ++nodeIndex) {
+        forAllKilledNodesAtNodeIndex(
+            graph, localAvailability.m_availability, block, nodeIndex,
+            [&] (Node* node) {
+                functor(nodeIndex, node);
+            });
+        localAvailability.executeNode(block->at(nodeIndex));
+    }
+}
+
+} } // namespace JSC::DFG
+
+#endif // DFGForAllKills_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.cpp b/Source/JavaScriptCore/dfg/DFGGraph.cpp
index ecf2619..040cb127 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.cpp
+++ b/Source/JavaScriptCore/dfg/DFGGraph.cpp
@@ -28,6 +28,7 @@
 
 #if ENABLE(DFG_JIT)
 
+#include "BytecodeKills.h"
 #include "BytecodeLivenessAnalysisInlines.h"
 #include "CodeBlock.h"
 #include "CodeBlockWithJITType.h"
@@ -62,9 +63,7 @@
     , m_profiledBlock(m_codeBlock->alternative())
     , m_allocator(longLivedState.m_allocator)
     , m_mustHandleValues(OperandsLike, plan.mustHandleValues)
-    , m_hasArguments(false)
     , m_nextMachineLocal(0)
-    , m_machineCaptureStart(std::numeric_limits<int>::max())
     , m_fixpointState(BeforeFixpoint)
     , m_structureRegistrationState(HaveNotStartedRegistering)
     , m_form(LoadStore)
@@ -75,11 +74,6 @@
     
     for (unsigned i = m_mustHandleValues.size(); i--;)
         m_mustHandleValues[i] = freezeFragile(plan.mustHandleValues[i]);
-    
-    for (unsigned i = m_codeBlock->m_numVars; i--;) {
-        if (m_codeBlock->isCaptured(virtualRegisterForLocal(i)))
-            m_outermostCapturedVars.set(i);
-    }
 }
 
 Graph::~Graph()
@@ -216,10 +210,12 @@
         out.print(comma, node->arrayMode());
     if (node->hasArithMode())
         out.print(comma, node->arithMode());
-    if (node->hasVarNumber())
-        out.print(comma, node->varNumber());
+    if (node->hasScopeOffset())
+        out.print(comma, node->scopeOffset());
+    if (node->hasDirectArgumentsOffset())
+        out.print(comma, node->capturedArgumentsOffset());
     if (node->hasRegisterPointer())
-        out.print(comma, "global", globalObjectFor(node->origin.semantic)->findRegisterIndex(node->registerPointer()), "(", RawPointer(node->registerPointer()), ")");
+        out.print(comma, "global", globalObjectFor(node->origin.semantic)->findVariableIndex(node->variablePointer()), "(", RawPointer(node->variablePointer()), ")");
     if (node->hasIdentifier())
         out.print(comma, "id", node->identifierNumber(), "{", identifiers()[node->identifierNumber()], "}");
     if (node->hasPromotedLocationDescriptor())
@@ -228,8 +224,14 @@
         out.print(comma, inContext(node->structureSet(), context));
     if (node->hasStructure())
         out.print(comma, inContext(*node->structure(), context));
-    if (node->hasTransition())
+    if (node->hasTransition()) {
         out.print(comma, pointerDumpInContext(node->transition(), context));
+#if USE(JSVALUE64)
+        out.print(", ID:", node->transition()->next->id());
+#else
+        out.print(", ID:", RawPointer(node->transition()->next));
+#endif
+    }
     if (node->hasCellOperand()) {
         if (!node->cellOperand()->value() || !node->cellOperand()->value().isCell())
             out.print(comma, "invalid cell operand: ", node->cellOperand()->value());
@@ -748,10 +750,6 @@
 
 void Graph::substituteGetLocal(BasicBlock& block, unsigned startIndexInBlock, VariableAccessData* variableAccessData, Node* newGetLocal)
 {
-    if (variableAccessData->isCaptured()) {
-        // Let CSE worry about this one.
-        return;
-    }
     for (unsigned indexInBlock = startIndexInBlock; indexInBlock < block.size(); ++indexInBlock) {
         Node* node = block[indexInBlock];
         bool shouldContinue = true;
@@ -871,6 +869,24 @@
     return livenessFor(baselineCodeBlockFor(inlineCallFrame));
 }
 
+BytecodeKills& Graph::killsFor(CodeBlock* codeBlock)
+{
+    HashMap<CodeBlock*, std::unique_ptr<BytecodeKills>>::iterator iter = m_bytecodeKills.find(codeBlock);
+    if (iter != m_bytecodeKills.end())
+        return *iter->value;
+    
+    std::unique_ptr<BytecodeKills> kills = std::make_unique<BytecodeKills>();
+    codeBlock->livenessAnalysis().computeKills(*kills);
+    BytecodeKills& result = *kills;
+    m_bytecodeKills.add(codeBlock, WTF::move(kills));
+    return result;
+}
+
+BytecodeKills& Graph::killsFor(InlineCallFrame* inlineCallFrame)
+{
+    return killsFor(baselineCodeBlockFor(inlineCallFrame));
+}
+
 bool Graph::isLiveInBytecode(VirtualRegister operand, CodeOrigin codeOrigin)
 {
     for (;;) {
@@ -1007,7 +1023,7 @@
     return tryGetConstantProperty(base.m_value, base.m_structure, offset);
 }
 
-JSValue Graph::tryGetConstantClosureVar(JSValue base, VirtualRegister reg)
+JSValue Graph::tryGetConstantClosureVar(JSValue base, ScopeOffset offset)
 {
     if (!base)
         return JSValue();
@@ -1022,7 +1038,7 @@
     if (symbolTable->m_functionEnteredOnce.hasBeenInvalidated())
         return JSValue();
     
-    SymbolTableEntry* entry = symbolTable->entryFor(locker, reg);
+    SymbolTableEntry* entry = symbolTable->entryFor(locker, offset);
     if (!entry)
         return JSValue();
     
@@ -1040,24 +1056,16 @@
     return value;
 }
 
-JSValue Graph::tryGetConstantClosureVar(const AbstractValue& value, VirtualRegister reg)
+JSValue Graph::tryGetConstantClosureVar(const AbstractValue& value, ScopeOffset offset)
 {
-    return tryGetConstantClosureVar(value.m_value, reg);
+    return tryGetConstantClosureVar(value.m_value, offset);
 }
 
-JSValue Graph::tryGetConstantClosureVar(Node* node, VirtualRegister reg)
+JSValue Graph::tryGetConstantClosureVar(Node* node, ScopeOffset offset)
 {
     if (!node->hasConstant())
         return JSValue();
-    return tryGetConstantClosureVar(node->asJSValue(), reg);
-}
-
-WriteBarrierBase<Unknown>* Graph::tryGetRegisters(Node* node)
-{
-    JSLexicalEnvironment* lexicalEnvironment = node->dynamicCastConstant<JSLexicalEnvironment*>();
-    if (!lexicalEnvironment)
-        return 0;
-    return lexicalEnvironment->registers();
+    return tryGetConstantClosureVar(node->asJSValue(), offset);
 }
 
 JSArrayBufferView* Graph::tryGetFoldableView(Node* node)
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h
index a836350..ea41d51 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.h
+++ b/Source/JavaScriptCore/dfg/DFGGraph.h
@@ -315,13 +315,6 @@
             && negate->canSpeculateInt52(pass);
     }
     
-    VirtualRegister bytecodeRegisterForArgument(CodeOrigin codeOrigin, int argument)
-    {
-        return VirtualRegister(
-            codeOrigin.inlineCallFrame->stackOffset +
-            baselineCodeBlockFor(codeOrigin)->argumentIndexAfterCapture(argument));
-    }
-    
     static const char *opName(NodeType);
     
     StructureSet* addStructureSet(const StructureSet& structureSet)
@@ -367,11 +360,14 @@
         return baselineCodeBlockForOriginAndBaselineCodeBlock(codeOrigin, m_profiledBlock);
     }
     
-    const BitVector& capturedVarsFor(InlineCallFrame* inlineCallFrame)
+    SymbolTable* symbolTableFor(InlineCallFrame* inlineCallFrame)
     {
-        if (!inlineCallFrame)
-            return m_outermostCapturedVars;
-        return inlineCallFrame->capturedVars;
+        return baselineCodeBlockFor(inlineCallFrame)->symbolTable();
+    }
+    
+    SymbolTable* symbolTableFor(const CodeOrigin& codeOrigin)
+    {
+        return symbolTableFor(codeOrigin.inlineCallFrame);
     }
     
     bool isStrictModeFor(CodeOrigin codeOrigin)
@@ -406,60 +402,6 @@
         return hasExitSite(node->origin.semantic, exitKind);
     }
     
-    bool usesArguments(InlineCallFrame* inlineCallFrame)
-    {
-        if (!inlineCallFrame)
-            return m_profiledBlock->usesArguments();
-        
-        return baselineCodeBlockForInlineCallFrame(inlineCallFrame)->usesArguments();
-    }
-    
-    VirtualRegister argumentsRegisterFor(InlineCallFrame* inlineCallFrame)
-    {
-        if (!inlineCallFrame)
-            return m_profiledBlock->argumentsRegister();
-        
-        return VirtualRegister(baselineCodeBlockForInlineCallFrame(
-            inlineCallFrame)->argumentsRegister().offset() +
-            inlineCallFrame->stackOffset);
-    }
-    
-    VirtualRegister argumentsRegisterFor(const CodeOrigin& codeOrigin)
-    {
-        return argumentsRegisterFor(codeOrigin.inlineCallFrame);
-    }
-    
-    VirtualRegister machineArgumentsRegisterFor(InlineCallFrame* inlineCallFrame)
-    {
-        if (!inlineCallFrame)
-            return m_codeBlock->argumentsRegister();
-        
-        return inlineCallFrame->argumentsRegister;
-    }
-    
-    VirtualRegister machineArgumentsRegisterFor(const CodeOrigin& codeOrigin)
-    {
-        return machineArgumentsRegisterFor(codeOrigin.inlineCallFrame);
-    }
-    
-    VirtualRegister uncheckedArgumentsRegisterFor(InlineCallFrame* inlineCallFrame)
-    {
-        if (!inlineCallFrame)
-            return m_profiledBlock->uncheckedArgumentsRegister();
-        
-        CodeBlock* codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
-        if (!codeBlock->usesArguments())
-            return VirtualRegister();
-        
-        return VirtualRegister(codeBlock->argumentsRegister().offset() +
-            inlineCallFrame->stackOffset);
-    }
-    
-    VirtualRegister uncheckedArgumentsRegisterFor(const CodeOrigin& codeOrigin)
-    {
-        return uncheckedArgumentsRegisterFor(codeOrigin.inlineCallFrame);
-    }
-    
     VirtualRegister activationRegister()
     {
         return m_profiledBlock->activationRegister();
@@ -483,11 +425,6 @@
     ValueProfile* valueProfileFor(Node*);
     MethodOfGettingAValueProfile methodOfGettingAValueProfileFor(Node*);
     
-    bool usesArguments() const
-    {
-        return m_codeBlock->usesArguments();
-    }
-    
     BlockIndex numBlocks() const { return m_blocks.size(); }
     BasicBlock* block(BlockIndex blockIndex) const { return m_blocks[blockIndex].get(); }
     BasicBlock* lastBlock() const { return block(numBlocks() - 1); }
@@ -722,6 +659,13 @@
             });
     }
     
+    bool uses(Node* node, Node* child)
+    {
+        bool result = false;
+        doToChildren(node, [&] (Edge edge) { result |= edge == child; });
+        return result;
+    }
+    
     Profiler::Compilation* compilation() { return m_plan.compilation.get(); }
     
     DesiredIdentifiers& identifiers() { return m_plan.identifiers; }
@@ -731,6 +675,9 @@
     FullBytecodeLiveness& livenessFor(InlineCallFrame*);
     bool isLiveInBytecode(VirtualRegister, CodeOrigin);
     
+    BytecodeKills& killsFor(CodeBlock*);
+    BytecodeKills& killsFor(InlineCallFrame*);
+    
     unsigned frameRegisterCount();
     unsigned stackPointerOffset();
     unsigned requiredRegisterCountForExit();
@@ -741,10 +688,9 @@
     JSValue tryGetConstantProperty(JSValue base, const StructureAbstractValue&, PropertyOffset);
     JSValue tryGetConstantProperty(const AbstractValue&, PropertyOffset);
     
-    JSValue tryGetConstantClosureVar(JSValue base, VirtualRegister);
-    JSValue tryGetConstantClosureVar(const AbstractValue&, VirtualRegister);
-    JSValue tryGetConstantClosureVar(Node*, VirtualRegister);
-    WriteBarrierBase<Unknown>* tryGetRegisters(Node*);
+    JSValue tryGetConstantClosureVar(JSValue base, ScopeOffset);
+    JSValue tryGetConstantClosureVar(const AbstractValue&, ScopeOffset);
+    JSValue tryGetConstantClosureVar(Node*, ScopeOffset);
     
     JSArrayBufferView* tryGetFoldableView(Node*);
     JSArrayBufferView* tryGetFoldableView(Node*, ArrayMode);
@@ -826,18 +772,13 @@
     Bag<StackAccessData> m_stackAccessData;
     Vector<InlineVariableData, 4> m_inlineVariableData;
     HashMap<CodeBlock*, std::unique_ptr<FullBytecodeLiveness>> m_bytecodeLiveness;
-    bool m_hasArguments;
-    HashSet<ExecutableBase*> m_executablesWhoseArgumentsEscaped;
-    BitVector m_lazyVars;
+    HashMap<CodeBlock*, std::unique_ptr<BytecodeKills>> m_bytecodeKills;
     Dominators m_dominators;
     PrePostNumbering m_prePostNumbering;
     NaturalLoops m_naturalLoops;
     unsigned m_localVars;
     unsigned m_nextMachineLocal;
     unsigned m_parameterSlots;
-    int m_machineCaptureStart;
-    std::unique_ptr<SlowArgument[]> m_slowArguments;
-    BitVector m_outermostCapturedVars;
 
 #if USE(JSVALUE32_64)
     std::unordered_map<int64_t, double*> m_doubleConstantsMap;
diff --git a/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp b/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp
index 944a8a6..4ed1e04 100644
--- a/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp
+++ b/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -80,8 +80,12 @@
         out.print("SetterLoc");
         return;
         
-    case VariableLoc:
-        out.print("VariableLoc");
+    case StackLoc:
+        out.print("StackLoc");
+        return;
+        
+    case StackPayloadLoc:
+        out.print("StackPayloadLoc");
         return;
         
     case ArrayLengthLoc:
@@ -96,14 +100,14 @@
         out.print("CheckHasInstanceLoc");
         return;
         
-    case ClosureRegistersLoc:
-        out.print("ClosureRegistersLoc");
-        return;
-        
     case ClosureVariableLoc:
         out.print("ClosureVariableLoc");
         return;
         
+    case DirectArgumentsLoc:
+        out.print("DirectArgumentsLoc");
+        return;
+        
     case GlobalVariableLoc:
         out.print("GlobalVariableLoc");
         return;
@@ -124,14 +128,6 @@
         out.print("InstanceOfLoc");
         return;
         
-    case MyArgumentByValLoc:
-        out.print("MyArgumentByValLoc");
-        return;
-        
-    case MyArgumentsLengthLoc:
-        out.print("MyArgumentsLengthLoc");
-        return;
-        
     case NamedPropertyLoc:
         out.print("NamedPropertyLoc");
         return;
diff --git a/Source/JavaScriptCore/dfg/DFGHeapLocation.h b/Source/JavaScriptCore/dfg/DFGHeapLocation.h
index 568d30d..be95f3d 100644
--- a/Source/JavaScriptCore/dfg/DFGHeapLocation.h
+++ b/Source/JavaScriptCore/dfg/DFGHeapLocation.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -40,8 +40,8 @@
     ArrayLengthLoc,
     ButterflyLoc,
     CheckHasInstanceLoc,
-    ClosureRegistersLoc,
     ClosureVariableLoc,
+    DirectArgumentsLoc,
     GetterLoc,
     GlobalVariableLoc,
     HasIndexedPropertyLoc,
@@ -51,15 +51,14 @@
     InvalidationPointLoc,
     IsFunctionLoc,
     IsObjectOrNullLoc,
-    MyArgumentByValLoc,
-    MyArgumentsLengthLoc,
     NamedPropertyLoc,
     SetterLoc,
     StructureLoc,
     TypeOfLoc,
     TypedArrayByteOffsetLoc,
     VarInjectionWatchpointLoc,
-    VariableLoc
+    StackLoc,
+    StackPayloadLoc
 };
 
 class HeapLocation {
diff --git a/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp
index 9696c6e..65bd068 100644
--- a/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp
+++ b/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -129,11 +129,7 @@
         }
     }
     for (size_t i = 0; i < root->valuesAtHead.numberOfLocals(); ++i) {
-        Node* node = root->variablesAtHead.local(i);
-        if (node && node->variableAccessData()->isCaptured())
-            root->valuesAtHead.local(i).makeHeapTop();
-        else
-            root->valuesAtHead.local(i).clear();
+        root->valuesAtHead.local(i).clear();
         root->valuesAtTail.local(i).clear();
     }
     for (BlockIndex blockIndex = 1 ; blockIndex < m_graph.numBlocks(); ++blockIndex) {
@@ -263,40 +259,31 @@
         
     AbstractValue source;
     
-    if (node->variableAccessData()->isCaptured()) {
-        // If it's captured then we know that whatever value was stored into the variable last is the
-        // one we care about. This is true even if the variable at tail is dead, which might happen if
-        // the last thing we did to the variable was a GetLocal and then ended up not using the
-        // GetLocal's result.
-        
+    switch (node->op()) {
+    case Phi:
+    case SetArgument:
+    case PhantomLocal:
+    case Flush:
+        // The block transfers the value from head to tail.
         source = inVariable;
-    } else {
-        switch (node->op()) {
-        case Phi:
-        case SetArgument:
-        case PhantomLocal:
-        case Flush:
-            // The block transfers the value from head to tail.
-            source = inVariable;
-            break;
+        break;
             
-        case GetLocal:
-            // The block refines the value with additional speculations.
-            source = forNode(node);
-            break;
+    case GetLocal:
+        // The block refines the value with additional speculations.
+        source = forNode(node);
+        break;
             
-        case SetLocal:
-            // The block sets the variable, and potentially refines it, both
-            // before and after setting it.
-            source = forNode(node->child1());
-            if (node->variableAccessData()->flushFormat() == FlushedDouble)
-                RELEASE_ASSERT(!(source.m_type & ~SpecFullDouble));
-            break;
+    case SetLocal:
+        // The block sets the variable, and potentially refines it, both
+        // before and after setting it.
+        source = forNode(node->child1());
+        if (node->variableAccessData()->flushFormat() == FlushedDouble)
+            RELEASE_ASSERT(!(source.m_type & ~SpecFullDouble));
+        break;
         
-        default:
-            RELEASE_ASSERT_NOT_REACHED();
-            break;
-        }
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        break;
     }
     
     if (destination == source) {
diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
index 8c2bc31..e2a18eb 100644
--- a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
+++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
@@ -161,9 +161,6 @@
     if (!m_graph.m_plan.inlineCallFrames->isEmpty())
         m_jitCode->common.inlineCallFrames = m_graph.m_plan.inlineCallFrames;
     
-    m_jitCode->common.machineCaptureStart = m_graph.m_machineCaptureStart;
-    m_jitCode->common.slowArguments = WTF::move(m_graph.m_slowArguments);
-
 #if USE(JSVALUE32_64)
     m_jitCode->common.doubleConstants = WTF::move(m_graph.m_doubleConstants);
 #endif
diff --git a/Source/JavaScriptCore/dfg/DFGMayExit.cpp b/Source/JavaScriptCore/dfg/DFGMayExit.cpp
index 47c8920..9670540 100644
--- a/Source/JavaScriptCore/dfg/DFGMayExit.cpp
+++ b/Source/JavaScriptCore/dfg/DFGMayExit.cpp
@@ -71,7 +71,6 @@
     case HardPhantom:
     case GetLocal:
     case LoopHint:
-    case PhantomArguments:
     case Phi:
     case Upsilon:
     case ZombieHint:
@@ -82,6 +81,7 @@
     case KillStack:
     case GetStack:
     case GetCallee:
+    case GetArgumentCount:
     case GetScope:
     case PhantomLocal:
     case CountExecution:
diff --git a/Source/JavaScriptCore/dfg/DFGMinifiedID.h b/Source/JavaScriptCore/dfg/DFGMinifiedID.h
index 5f947d1..f5ace12 100644
--- a/Source/JavaScriptCore/dfg/DFGMinifiedID.h
+++ b/Source/JavaScriptCore/dfg/DFGMinifiedID.h
@@ -37,6 +37,7 @@
 class Graph;
 class MinifiedNode;
 class ValueSource;
+struct Node;
 
 class MinifiedID {
 public:
@@ -98,7 +99,9 @@
 };
 
 template<typename T> struct HashTraits;
-template<> struct HashTraits<JSC::DFG::MinifiedID> : SimpleClassHashTraits<JSC::DFG::MinifiedID> { };
+template<> struct HashTraits<JSC::DFG::MinifiedID> : SimpleClassHashTraits<JSC::DFG::MinifiedID> {
+    static const bool emptyValueIsZero = false;
+};
 
 } // namespace WTF
 
diff --git a/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp b/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp
index 72b52be..80795c2 100644
--- a/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp
+++ b/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -42,8 +42,8 @@
     if (hasConstant(node->op()))
         result.m_info = JSValue::encode(node->asJSValue());
     else {
-        ASSERT(node->op() == PhantomArguments);
-        result.m_info = 0;
+        ASSERT(node->op() == PhantomDirectArguments || node->op() == PhantomClonedArguments);
+        result.m_info = bitwise_cast<uintptr_t>(node->origin.semantic.inlineCallFrame);
     }
     return result;
 }
diff --git a/Source/JavaScriptCore/dfg/DFGMinifiedNode.h b/Source/JavaScriptCore/dfg/DFGMinifiedNode.h
index 8b3c570..29798bc 100644
--- a/Source/JavaScriptCore/dfg/DFGMinifiedNode.h
+++ b/Source/JavaScriptCore/dfg/DFGMinifiedNode.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -42,7 +42,8 @@
     case JSConstant:
     case Int52Constant:
     case DoubleConstant:
-    case PhantomArguments:
+    case PhantomDirectArguments:
+    case PhantomClonedArguments:
         return true;
     default:
         return false;
@@ -65,6 +66,13 @@
         return JSValue::decode(bitwise_cast<EncodedJSValue>(m_info));
     }
     
+    bool hasInlineCallFrame() const { return hasInlineCallFrame(m_op); }
+    
+    InlineCallFrame* inlineCallFrame() const
+    {
+        return bitwise_cast<InlineCallFrame*>(static_cast<uintptr_t>(m_info));
+    }
+    
     static MinifiedID getID(MinifiedNode* node) { return node->id(); }
     static bool compareByNodeIndex(const MinifiedNode& a, const MinifiedNode& b)
     {
@@ -77,6 +85,11 @@
         return type == JSConstant || type == Int52Constant || type == DoubleConstant;
     }
     
+    static bool hasInlineCallFrame(NodeType type)
+    {
+        return type == PhantomDirectArguments || type == PhantomClonedArguments;
+    }
+    
     MinifiedID m_id;
     uint64_t m_info;
     NodeType m_op;
diff --git a/Source/JavaScriptCore/dfg/DFGNode.cpp b/Source/JavaScriptCore/dfg/DFGNode.cpp
index 84cb853..10e175b 100644
--- a/Source/JavaScriptCore/dfg/DFGNode.cpp
+++ b/Source/JavaScriptCore/dfg/DFGNode.cpp
@@ -94,6 +94,36 @@
     setResult(result);
 }
 
+void Node::convertToIdentityOn(Node* child)
+{
+    children.reset();
+    child1() = child->defaultEdge();
+    NodeFlags output = canonicalResultRepresentation(this->result());
+    NodeFlags input = canonicalResultRepresentation(child->result());
+    if (output == input) {
+        setOpAndDefaultFlags(Identity);
+        setResult(output);
+        return;
+    }
+    switch (output) {
+    case NodeResultDouble:
+        RELEASE_ASSERT(input == NodeResultInt52 || input == NodeResultJS);
+        setOpAndDefaultFlags(DoubleRep);
+        return;
+    case NodeResultInt52:
+        RELEASE_ASSERT(input == NodeResultDouble || input == NodeResultJS);
+        setOpAndDefaultFlags(Int52Rep);
+        return;
+    case NodeResultJS:
+        RELEASE_ASSERT(input == NodeResultDouble || input == NodeResultInt52);
+        setOpAndDefaultFlags(ValueRep);
+        return;
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        return;
+    }
+}
+
 void Node::convertToPutHint(const PromotedLocationDescriptor& descriptor, Node* base, Node* value)
 {
     m_op = PutHint;
diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h
index 081f31f..d27a6da 100644
--- a/Source/JavaScriptCore/dfg/DFGNode.h
+++ b/Source/JavaScriptCore/dfg/DFGNode.h
@@ -429,6 +429,7 @@
     }
 
     void convertToIdentity();
+    void convertToIdentityOn(Node*);
 
     bool mustGenerate()
     {
@@ -447,19 +448,20 @@
         }
     }
     
-    bool isPhantomArguments()
-    {
-        return op() == PhantomArguments;
-    }
-    
     bool hasConstant()
     {
         switch (op()) {
         case JSConstant:
         case DoubleConstant:
         case Int52Constant:
-        case PhantomArguments:
             return true;
+            
+        case PhantomDirectArguments:
+        case PhantomClonedArguments:
+            // These pretend to be the empty value constant for the benefit of the DFG backend, which
+            // otherwise wouldn't take kindly to a node that doesn't compute a value.
+            return true;
+            
         default:
             return false;
         }
@@ -468,8 +470,13 @@
     FrozenValue* constant()
     {
         ASSERT(hasConstant());
-        if (op() == PhantomArguments)
+        
+        if (op() == PhantomDirectArguments || op() == PhantomClonedArguments) {
+            // These pretend to be the empty value constant for the benefit of the DFG backend, which
+            // otherwise wouldn't take kindly to a node that doesn't compute a value.
             return FrozenValue::emptySingleton();
+        }
+        
         return bitwise_cast<FrozenValue*>(m_opInfo);
     }
     
@@ -934,15 +941,26 @@
         return m_opInfo;
     }
     
-    bool hasVarNumber()
+    bool hasScopeOffset()
     {
         return op() == GetClosureVar || op() == PutClosureVar;
     }
 
-    int varNumber()
+    ScopeOffset scopeOffset()
     {
-        ASSERT(hasVarNumber());
-        return m_opInfo;
+        ASSERT(hasScopeOffset());
+        return ScopeOffset(m_opInfo);
+    }
+    
+    bool hasDirectArgumentsOffset()
+    {
+        return op() == GetFromArguments || op() == PutToArguments;
+    }
+    
+    DirectArgumentsOffset capturedArgumentsOffset()
+    {
+        ASSERT(hasDirectArgumentsOffset());
+        return DirectArgumentsOffset(m_opInfo);
     }
     
     bool hasRegisterPointer()
@@ -950,7 +968,7 @@
         return op() == GetGlobalVar || op() == PutGlobalVar;
     }
     
-    WriteBarrier<Unknown>* registerPointer()
+    WriteBarrier<Unknown>* variablePointer()
     {
         return bitwise_cast<WriteBarrier<Unknown>*>(m_opInfo);
     }
@@ -961,6 +979,7 @@
         case CallVarargs:
         case CallForwardVarargs:
         case ConstructVarargs:
+        case ConstructForwardVarargs:
             return true;
         default:
             return false;
@@ -975,7 +994,7 @@
     
     bool hasLoadVarargsData()
     {
-        return op() == LoadVarargs;
+        return op() == LoadVarargs || op() == ForwardVarargs;
     }
     
     LoadVarargsData* loadVarargsData()
@@ -1134,8 +1153,6 @@
         case GetById:
         case GetByIdFlush:
         case GetByVal:
-        case GetMyArgumentByVal:
-        case GetMyArgumentByValSafe:
         case Call:
         case Construct:
         case CallVarargs:
@@ -1146,6 +1163,7 @@
         case GetByOffset:
         case MultiGetByOffset:
         case GetClosureVar:
+        case GetFromArguments:
         case ArrayPop:
         case ArrayPush:
         case RegExpExec:
@@ -1176,9 +1194,7 @@
         case CheckCell:
         case NativeConstruct:
         case NativeCall:
-        case NewFunctionNoCheck:
         case NewFunction:
-        case NewFunctionExpression:
             return true;
         default:
             return false;
@@ -1330,6 +1346,7 @@
     
     ObjectMaterializationData& objectMaterializationData()
     {
+        ASSERT(hasObjectMaterializationData());
         return *reinterpret_cast<ObjectMaterializationData*>(m_opInfo);
     }
     
@@ -1343,6 +1360,18 @@
         }
     }
     
+    bool isPhantomAllocation()
+    {
+        switch (op()) {
+        case PhantomNewObject:
+        case PhantomDirectArguments:
+        case PhantomClonedArguments:
+            return true;
+        default:
+            return false;
+        }
+    }
+    
     bool hasArrayMode()
     {
         switch (op()) {
@@ -1451,7 +1480,6 @@
         case SetLocal:
         case MovHint:
         case ZombieHint:
-        case PhantomArguments:
             return true;
         case Phantom:
         case HardPhantom:
@@ -1671,9 +1699,14 @@
         return isArraySpeculation(prediction());
     }
     
-    bool shouldSpeculateArguments()
+    bool shouldSpeculateDirectArguments()
     {
-        return isArgumentsSpeculation(prediction());
+        return isDirectArgumentsSpeculation(prediction());
+    }
+    
+    bool shouldSpeculateScopedArguments()
+    {
+        return isScopedArgumentsSpeculation(prediction());
     }
     
     bool shouldSpeculateInt8Array()
diff --git a/Source/JavaScriptCore/dfg/DFGNodeType.h b/Source/JavaScriptCore/dfg/DFGNodeType.h
index 7b09dd7..5dc1eb6 100644
--- a/Source/JavaScriptCore/dfg/DFGNodeType.h
+++ b/Source/JavaScriptCore/dfg/DFGNodeType.h
@@ -50,6 +50,7 @@
     macro(ToThis, NodeResultJS) \
     macro(CreateThis, NodeResultJS) /* Note this is not MustGenerate since we're returning it anyway. */ \
     macro(GetCallee, NodeResultJS) \
+    macro(GetArgumentCount, NodeResultInt32) \
     \
     /* Nodes for local variable access. These nodes are linked together using Phi nodes. */\
     /* Any two nodes that are part of the same Phi graph will share the same */\
@@ -151,7 +152,9 @@
     /* this must be the directly subsequent property put. Note that PutByVal */\
     /* opcodes use VarArgs beause they may have up to 4 children. */\
     macro(GetByVal, NodeResultJS | NodeMustGenerate) \
+    macro(GetMyArgumentByVal, NodeResultJS | NodeMustGenerate) \
     macro(LoadVarargs, NodeMustGenerate) \
+    macro(ForwardVarargs, NodeMustGenerate) \
     macro(PutByValDirect, NodeMustGenerate | NodeHasVarArgs) \
     macro(PutByVal, NodeMustGenerate | NodeHasVarArgs) \
     macro(PutByValAlias, NodeMustGenerate | NodeHasVarArgs) \
@@ -183,7 +186,6 @@
     macro(GetTypedArrayByteOffset, NodeResultInt32) \
     macro(GetScope, NodeResultJS) \
     macro(SkipScope, NodeResultJS) \
-    macro(GetClosureRegisters, NodeResultStorage) \
     macro(GetClosureVar, NodeResultJS) \
     macro(PutClosureVar, NodeMustGenerate) \
     macro(GetGlobalVar, NodeResultJS) \
@@ -224,6 +226,7 @@
     macro(CallVarargs, NodeResultJS | NodeMustGenerate) \
     macro(CallForwardVarargs, NodeResultJS | NodeMustGenerate) \
     macro(ConstructVarargs, NodeResultJS | NodeMustGenerate) \
+    macro(ConstructForwardVarargs, NodeResultJS | NodeMustGenerate) \
     macro(NativeCall, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
     macro(NativeConstruct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
     \
@@ -264,26 +267,17 @@
     macro(ProfileType, NodeMustGenerate) \
     macro(ProfileControlFlow, NodeMustGenerate) \
     \
-    /* Nodes used for activations. Activation support works by having it anchored at */\
-    /* epilgoues via TearOffActivation, and all CreateActivation nodes kept alive by */\
-    /* being threaded with each other. */\
     macro(CreateActivation, NodeResultJS) \
     \
-    /* Nodes used for arguments. Similar to lexical environment support, only it makes even less */\
-    /* sense. */\
-    macro(CreateArguments, NodeResultJS) \
-    macro(PhantomArguments, NodeResultJS) \
-    macro(TearOffArguments, NodeMustGenerate) \
-    macro(GetMyArgumentsLength, NodeResultJS | NodeMustGenerate) \
-    macro(GetMyArgumentByVal, NodeResultJS | NodeMustGenerate) \
-    macro(GetMyArgumentsLengthSafe, NodeResultJS | NodeMustGenerate) \
-    macro(GetMyArgumentByValSafe, NodeResultJS | NodeMustGenerate) \
-    macro(CheckArgumentsNotCreated, NodeMustGenerate) \
+    macro(CreateDirectArguments, NodeResultJS) \
+    macro(PhantomDirectArguments, NodeResultJS) \
+    macro(CreateScopedArguments, NodeResultJS) \
+    macro(CreateClonedArguments, NodeResultJS) \
+    macro(PhantomClonedArguments, NodeResultJS) \
+    macro(GetFromArguments, NodeResultJS) \
+    macro(PutToArguments, NodeMustGenerate) \
     \
-    /* Nodes for creating functions. */\
-    macro(NewFunctionNoCheck, NodeResultJS) \
     macro(NewFunction, NodeResultJS) \
-    macro(NewFunctionExpression, NodeResultJS) \
     \
     /* These aren't terminals but always exit */ \
     macro(Throw, NodeMustGenerate) \
diff --git a/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp b/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp
index fe67a66..a6224d7 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp
@@ -82,8 +82,10 @@
                 for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex)
                     calculator.executeNode(block->at(nodeIndex));
                 
+                // FIXME: we should probably prune by liveness here.
+                // https://bugs.webkit.org/show_bug.cgi?id=143078
                 calculator.m_availability.prune();
-                
+
                 if (calculator.m_availability == block->ssa->availabilityAtTail)
                     continue;
                 
@@ -155,7 +157,8 @@
         break;
     }
         
-    case LoadVarargs: {
+    case LoadVarargs:
+    case ForwardVarargs: {
         LoadVarargsData* data = node->loadVarargsData();
         m_availability.m_locals.operand(data->count) =
             Availability(FlushedAt(FlushedInt32, data->machineCount));
@@ -166,6 +169,38 @@
         break;
     }
         
+    case PhantomDirectArguments:
+    case PhantomClonedArguments: {
+        InlineCallFrame* inlineCallFrame = node->origin.semantic.inlineCallFrame;
+        if (!inlineCallFrame) {
+            // We don't need to record anything about how the arguments are to be recovered. It's just a
+            // given that we can read them from the stack.
+            break;
+        }
+        
+        if (inlineCallFrame->isVarargs()) {
+            // Record how to read each argument and the argument count.
+            Availability argumentCount =
+                m_availability.m_locals.operand(inlineCallFrame->stackOffset + JSStack::ArgumentCount);
+            
+            m_availability.m_heap.set(PromotedHeapLocation(ArgumentCountPLoc, node), argumentCount);
+        }
+        
+        if (inlineCallFrame->isClosureCall) {
+            Availability callee = m_availability.m_locals.operand(
+                inlineCallFrame->stackOffset + JSStack::Callee);
+            m_availability.m_heap.set(PromotedHeapLocation(ArgumentsCalleePLoc, node), callee);
+        }
+        
+        for (unsigned i = 0; i < inlineCallFrame->arguments.size() - 1; ++i) {
+            Availability argument = m_availability.m_locals.operand(
+                inlineCallFrame->stackOffset + CallFrame::argumentOffset(i));
+            
+            m_availability.m_heap.set(PromotedHeapLocation(ArgumentPLoc, node, i), argument);
+        }
+        break;
+    }
+        
     case PutHint: {
         m_availability.m_heap.set(
             PromotedHeapLocation(node->child1().node(), node->promotedLocationDescriptor()),
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp
index 17a59c2..23d51c6 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -40,6 +40,75 @@
 
 namespace JSC { namespace DFG {
 
+void OSRExitCompiler::emitRestoreArguments(const Operands<ValueRecovery>& operands)
+{
+    HashMap<MinifiedID, int> alreadyAllocatedArguments; // Maps phantom arguments node ID to operand.
+    for (size_t index = 0; index < operands.size(); ++index) {
+        const ValueRecovery& recovery = operands[index];
+        int operand = operands.operandForIndex(index);
+        
+        if (recovery.technique() != DirectArgumentsThatWereNotCreated
+            && recovery.technique() != ClonedArgumentsThatWereNotCreated)
+            continue;
+        
+        MinifiedID id = recovery.nodeID();
+        auto iter = alreadyAllocatedArguments.find(id);
+        if (iter != alreadyAllocatedArguments.end()) {
+            JSValueRegs regs = JSValueRegs::withTwoAvailableRegs(GPRInfo::regT0, GPRInfo::regT1);
+            m_jit.loadValue(CCallHelpers::addressFor(iter->value), regs);
+            m_jit.storeValue(regs, CCallHelpers::addressFor(operand));
+            continue;
+        }
+        
+        InlineCallFrame* inlineCallFrame =
+            m_jit.codeBlock()->jitCode()->dfg()->minifiedDFG.at(id)->inlineCallFrame();
+
+        int stackOffset;
+        if (inlineCallFrame)
+            stackOffset = inlineCallFrame->stackOffset;
+        else
+            stackOffset = 0;
+        
+        if (!inlineCallFrame || inlineCallFrame->isClosureCall) {
+            m_jit.loadPtr(
+                AssemblyHelpers::addressFor(stackOffset + JSStack::Callee),
+                GPRInfo::regT0);
+        } else {
+            m_jit.move(
+                AssemblyHelpers::TrustedImmPtr(inlineCallFrame->calleeRecovery.constant().asCell()),
+                GPRInfo::regT0);
+        }
+        
+        if (!inlineCallFrame || inlineCallFrame->isVarargs()) {
+            m_jit.load32(
+                AssemblyHelpers::payloadFor(stackOffset + JSStack::ArgumentCount),
+                GPRInfo::regT1);
+        } else {
+            m_jit.move(
+                AssemblyHelpers::TrustedImm32(inlineCallFrame->arguments.size()),
+                GPRInfo::regT1);
+        }
+        
+        m_jit.setupArgumentsWithExecState(
+            AssemblyHelpers::TrustedImmPtr(inlineCallFrame), GPRInfo::regT0, GPRInfo::regT1);
+        switch (recovery.technique()) {
+        case DirectArgumentsThatWereNotCreated:
+            m_jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(operationCreateDirectArgumentsDuringExit)), GPRInfo::nonArgGPR0);
+            break;
+        case ClonedArgumentsThatWereNotCreated:
+            m_jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(operationCreateClonedArgumentsDuringExit)), GPRInfo::nonArgGPR0);
+            break;
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            break;
+        }
+        m_jit.call(GPRInfo::nonArgGPR0);
+        m_jit.storeCell(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(operand));
+        
+        alreadyAllocatedArguments.add(id, operand);
+    }
+}
+
 extern "C" {
 
 void compileOSRExit(ExecState* exec)
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.h b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.h
index 556fe0b..cb262d4 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.h
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -49,28 +49,9 @@
     void compileExit(const OSRExit&, const Operands<ValueRecovery>&, SpeculationRecovery*);
 
 private:
-#if !ASSERT_DISABLED
-    static unsigned badIndex() { return static_cast<unsigned>(-1); };
-#endif
-    
-    void initializePoisoned(unsigned size)
-    {
-#if ASSERT_DISABLED
-        m_poisonScratchIndices.resize(size);
-#else
-        m_poisonScratchIndices.fill(badIndex(), size);
-#endif
-    }
-    
-    unsigned poisonIndex(unsigned index)
-    {
-        unsigned result = m_poisonScratchIndices[index];
-        ASSERT(result != badIndex());
-        return result;
-    }
+    void emitRestoreArguments(const Operands<ValueRecovery>&);
     
     CCallHelpers& m_jit;
-    Vector<unsigned> m_poisonScratchIndices;
 };
 
 extern "C" {
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
index 0e177e8..0851a58 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -38,7 +38,7 @@
 
 void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecovery>& operands, SpeculationRecovery* recovery)
 {
-    // 1) Pro-forma stuff.
+    // Pro-forma stuff.
     if (Options::printEachOSRExit()) {
         SpeculationFailureDebugInfo* debugInfo = new SpeculationFailureDebugInfo;
         debugInfo->codeBlock = m_jit.codeBlock();
@@ -48,8 +48,8 @@
         m_jit.debugCall(debugOperationPrintSpeculationFailure, debugInfo);
     }
     
-    // 2) Perform speculation recovery. This only comes into play when an operation
-    //    starts mutating state before verifying the speculation it has already made.
+    // Perform speculation recovery. This only comes into play when an operation
+    // starts mutating state before verifying the speculation it has already made.
     
     if (recovery) {
         switch (recovery->type()) {
@@ -65,7 +65,7 @@
         }
     }
 
-    // 3) Refine some value profile, if appropriate.
+    // Refine some value profile, if appropriate.
     
     if (!!exit.m_jsValueSource) {
         if (exit.m_kind == BadCache || exit.m_kind == BadIndexingType) {
@@ -102,13 +102,8 @@
                 scratch1 = AssemblyHelpers::selectScratchGPR(usedRegister1, usedRegister2);
                 scratch2 = AssemblyHelpers::selectScratchGPR(usedRegister1, usedRegister2, scratch1);
                 
-#if CPU(ARM64)
-                m_jit.pushToSave(scratch1);
-                m_jit.pushToSave(scratch2);
-#else
                 m_jit.push(scratch1);
                 m_jit.push(scratch2);
-#endif
                 
                 GPRReg value;
                 if (exit.m_jsValueSource.isAddress()) {
@@ -124,13 +119,8 @@
                 m_jit.lshift32(scratch1, scratch2);
                 m_jit.or32(scratch2, AssemblyHelpers::AbsoluteAddress(arrayProfile->addressOfArrayModes()));
                 
-#if CPU(ARM64)
-                m_jit.popToRestore(scratch2);
-                m_jit.popToRestore(scratch1);
-#else
                 m_jit.pop(scratch2);
                 m_jit.pop(scratch1);
-#endif
             }
         }
         
@@ -141,22 +131,14 @@
                 // Save a register so we can use it.
                 GPRReg scratch = AssemblyHelpers::selectScratchGPR(exit.m_jsValueSource.base());
                 
-#if CPU(ARM64)
-                m_jit.pushToSave(scratch);
-#else
                 m_jit.push(scratch);
-#endif
 
                 m_jit.load32(exit.m_jsValueSource.asAddress(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), scratch);
                 m_jit.store32(scratch, &bitwise_cast<EncodedValueDescriptor*>(bucket)->asBits.tag);
                 m_jit.load32(exit.m_jsValueSource.asAddress(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), scratch);
                 m_jit.store32(scratch, &bitwise_cast<EncodedValueDescriptor*>(bucket)->asBits.payload);
                 
-#if CPU(ARM64)
-                m_jit.popToRestore(scratch);
-#else
                 m_jit.pop(scratch);
-#endif
             } else if (exit.m_jsValueSource.hasKnownTag()) {
                 m_jit.store32(AssemblyHelpers::TrustedImm32(exit.m_jsValueSource.tag()), &bitwise_cast<EncodedValueDescriptor*>(bucket)->asBits.tag);
                 m_jit.store32(exit.m_jsValueSource.payloadGPR(), &bitwise_cast<EncodedValueDescriptor*>(bucket)->asBits.payload);
@@ -170,7 +152,7 @@
     // Do a simplified OSR exit. See DFGOSRExitCompiler64.cpp's comment regarding how and wny we
     // do this simple approach.
 
-    // 4) Save all state from GPRs into the scratch buffer.
+    // Save all state from GPRs into the scratch buffer.
     
     ScratchBuffer* scratchBuffer = m_jit.vm()->scratchBufferForSize(sizeof(EncodedJSValue) * operands.size());
     EncodedJSValue* scratch = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0;
@@ -203,7 +185,7 @@
     
     // Now all GPRs are free to reuse.
     
-    // 5) Save all state from FPRs into the scratch buffer.
+    // Save all state from FPRs into the scratch buffer.
     
     for (size_t index = 0; index < operands.size(); ++index) {
         const ValueRecovery& recovery = operands[index];
@@ -221,9 +203,9 @@
     
     // Now all FPRs are free to reuse.
     
-    // 6) Save all state from the stack into the scratch buffer. For simplicity we
-    //    do this even for state that's already in the right place on the stack.
-    //    It makes things simpler later.
+    // Save all state from the stack into the scratch buffer. For simplicity we
+    // do this even for state that's already in the right place on the stack.
+    // It makes things simpler later.
     
     for (size_t index = 0; index < operands.size(); ++index) {
         const ValueRecovery& recovery = operands[index];
@@ -261,9 +243,7 @@
             -m_jit.codeBlock()->jitCode()->dfgCommon()->requiredRegisterCountForExit * sizeof(Register)),
         CCallHelpers::framePointerRegister, CCallHelpers::stackPointerRegister);
     
-    // 7) Do all data format conversions and store the results into the stack.
-    
-    bool haveArguments = false;
+    // Do all data format conversions and store the results into the stack.
     
     for (size_t index = 0; index < operands.size(); ++index) {
         const ValueRecovery& recovery = operands[index];
@@ -342,14 +322,9 @@
                 AssemblyHelpers::payloadFor(operand));
             break;
             
-        case ArgumentsThatWereNotCreated:
-            haveArguments = true;
-            m_jit.store32(
-                AssemblyHelpers::TrustedImm32(JSValue().tag()),
-                AssemblyHelpers::tagFor(operand));
-            m_jit.store32(
-                AssemblyHelpers::TrustedImm32(JSValue().payload()),
-                AssemblyHelpers::payloadFor(operand));
+        case DirectArgumentsThatWereNotCreated:
+        case ClonedArgumentsThatWereNotCreated:
+            // Don't do this, yet.
             break;
             
         default:
@@ -357,64 +332,57 @@
         }
     }
     
-    // 8) Adjust the old JIT's execute counter. Since we are exiting OSR, we know
-    //    that all new calls into this code will go to the new JIT, so the execute
-    //    counter only affects call frames that performed OSR exit and call frames
-    //    that were still executing the old JIT at the time of another call frame's
-    //    OSR exit. We want to ensure that the following is true:
+    // Now that things on the stack are recovered, do the arguments recovery. We assume that arguments
+    // recoveries don't recursively refer to each other. But, we don't try to assume that they only
+    // refer to certain ranges of locals. Hence why we need to do this here, once the stack is sensible.
+    // Note that we also roughly assume that the arguments might still be materialized outside of its
+    // inline call frame scope - but for now the DFG wouldn't do that.
+    
+    emitRestoreArguments(operands);
+
+    // Adjust the old JIT's execute counter. Since we are exiting OSR, we know
+    // that all new calls into this code will go to the new JIT, so the execute
+    // counter only affects call frames that performed OSR exit and call frames
+    // that were still executing the old JIT at the time of another call frame's
+    // OSR exit. We want to ensure that the following is true:
     //
-    //    (a) Code the performs an OSR exit gets a chance to reenter optimized
-    //        code eventually, since optimized code is faster. But we don't
-    //        want to do such reentery too aggressively (see (c) below).
+    // (a) Code the performs an OSR exit gets a chance to reenter optimized
+    //     code eventually, since optimized code is faster. But we don't
+    //     want to do such reentery too aggressively (see (c) below).
     //
-    //    (b) If there is code on the call stack that is still running the old
-    //        JIT's code and has never OSR'd, then it should get a chance to
-    //        perform OSR entry despite the fact that we've exited.
+    // (b) If there is code on the call stack that is still running the old
+    //     JIT's code and has never OSR'd, then it should get a chance to
+    //     perform OSR entry despite the fact that we've exited.
     //
-    //    (c) Code the performs an OSR exit should not immediately retry OSR
-    //        entry, since both forms of OSR are expensive. OSR entry is
-    //        particularly expensive.
+    // (c) Code the performs an OSR exit should not immediately retry OSR
+    //     entry, since both forms of OSR are expensive. OSR entry is
+    //     particularly expensive.
     //
-    //    (d) Frequent OSR failures, even those that do not result in the code
-    //        running in a hot loop, result in recompilation getting triggered.
+    // (d) Frequent OSR failures, even those that do not result in the code
+    //     running in a hot loop, result in recompilation getting triggered.
     //
-    //    To ensure (c), we'd like to set the execute counter to
-    //    counterValueForOptimizeAfterWarmUp(). This seems like it would endanger
-    //    (a) and (b), since then every OSR exit would delay the opportunity for
-    //    every call frame to perform OSR entry. Essentially, if OSR exit happens
-    //    frequently and the function has few loops, then the counter will never
-    //    become non-negative and OSR entry will never be triggered. OSR entry
-    //    will only happen if a loop gets hot in the old JIT, which does a pretty
-    //    good job of ensuring (a) and (b). But that doesn't take care of (d),
-    //    since each speculation failure would reset the execute counter.
-    //    So we check here if the number of speculation failures is significantly
-    //    larger than the number of successes (we want 90% success rate), and if
-    //    there have been a large enough number of failures. If so, we set the
-    //    counter to 0; otherwise we set the counter to
-    //    counterValueForOptimizeAfterWarmUp().
+    // To ensure (c), we'd like to set the execute counter to
+    // counterValueForOptimizeAfterWarmUp(). This seems like it would endanger
+    // (a) and (b), since then every OSR exit would delay the opportunity for
+    // every call frame to perform OSR entry. Essentially, if OSR exit happens
+    // frequently and the function has few loops, then the counter will never
+    // become non-negative and OSR entry will never be triggered. OSR entry
+    // will only happen if a loop gets hot in the old JIT, which does a pretty
+    // good job of ensuring (a) and (b). But that doesn't take care of (d),
+    // since each speculation failure would reset the execute counter.
+    // So we check here if the number of speculation failures is significantly
+    // larger than the number of successes (we want 90% success rate), and if
+    // there have been a large enough number of failures. If so, we set the
+    // counter to 0; otherwise we set the counter to
+    // counterValueForOptimizeAfterWarmUp().
     
     handleExitCounts(m_jit, exit);
     
-    // 9) Reify inlined call frames.
+    // Reify inlined call frames.
     
     reifyInlinedCallFrames(m_jit, exit);
     
-    // 10) Create arguments if necessary and place them into the appropriate aliased
-    //     registers.
-    
-    if (haveArguments) {
-        ArgumentsRecoveryGenerator argumentsRecovery;
-
-        for (size_t index = 0; index < operands.size(); ++index) {
-            const ValueRecovery& recovery = operands[index];
-            if (recovery.technique() != ArgumentsThatWereNotCreated)
-                continue;
-            argumentsRecovery.generateFor(
-                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
-        }
-    }
-
-    // 12) And finish.
+    // And finish.
     adjustAndJumpToTarget(m_jit, exit);
 }
 
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
index f8c4fad..5bb0a4f 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
@@ -42,7 +42,7 @@
 {
     m_jit.jitAssertTagsInPlace();
 
-    // 1) Pro-forma stuff.
+    // Pro-forma stuff.
     if (Options::printEachOSRExit()) {
         SpeculationFailureDebugInfo* debugInfo = new SpeculationFailureDebugInfo;
         debugInfo->codeBlock = m_jit.codeBlock();
@@ -52,8 +52,8 @@
         m_jit.debugCall(debugOperationPrintSpeculationFailure, debugInfo);
     }
     
-    // 2) Perform speculation recovery. This only comes into play when an operation
-    //    starts mutating state before verifying the speculation it has already made.
+    // Perform speculation recovery. This only comes into play when an operation
+    // starts mutating state before verifying the speculation it has already made.
     
     if (recovery) {
         switch (recovery->type()) {
@@ -71,7 +71,7 @@
         }
     }
 
-    // 3) Refine some array and/or value profile, if appropriate.
+    // Refine some array and/or value profile, if appropriate.
     
     if (!!exit.m_jsValueSource) {
         if (exit.m_kind == BadCache || exit.m_kind == BadIndexingType) {
@@ -97,13 +97,13 @@
                 scratch1 = AssemblyHelpers::selectScratchGPR(usedRegister);
                 scratch2 = AssemblyHelpers::selectScratchGPR(usedRegister, scratch1);
                 
-#if CPU(ARM64)
-                m_jit.pushToSave(scratch1);
-                m_jit.pushToSave(scratch2);
-#else
-                m_jit.push(scratch1);
-                m_jit.push(scratch2);
-#endif
+                if (isARM64()) {
+                    m_jit.pushToSave(scratch1);
+                    m_jit.pushToSave(scratch2);
+                } else {
+                    m_jit.push(scratch1);
+                    m_jit.push(scratch2);
+                }
                 
                 GPRReg value;
                 if (exit.m_jsValueSource.isAddress()) {
@@ -119,13 +119,13 @@
                 m_jit.lshift32(scratch1, scratch2);
                 m_jit.or32(scratch2, AssemblyHelpers::AbsoluteAddress(arrayProfile->addressOfArrayModes()));
                 
-#if CPU(ARM64)
-                m_jit.popToRestore(scratch2);
-                m_jit.popToRestore(scratch1);
-#else
-                m_jit.pop(scratch2);
-                m_jit.pop(scratch1);
-#endif
+                if (isARM64()) {
+                    m_jit.popToRestore(scratch2);
+                    m_jit.popToRestore(scratch1);
+                } else {
+                    m_jit.pop(scratch2);
+                    m_jit.pop(scratch1);
+                }
             }
         }
         
@@ -179,7 +179,7 @@
     // variable" from "how was it represented", which will make it more difficult to add
     // features in the future and it will make it harder to reason about bugs.
 
-    // 4) Save all state from GPRs into the scratch buffer.
+    // Save all state from GPRs into the scratch buffer.
     
     ScratchBuffer* scratchBuffer = m_jit.vm()->scratchBufferForSize(sizeof(EncodedJSValue) * operands.size());
     EncodedJSValue* scratch = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0;
@@ -203,7 +203,7 @@
     
     // And voila, all GPRs are free to reuse.
     
-    // 5) Save all state from FPRs into the scratch buffer.
+    // Save all state from FPRs into the scratch buffer.
     
     for (size_t index = 0; index < operands.size(); ++index) {
         const ValueRecovery& recovery = operands[index];
@@ -221,9 +221,9 @@
     
     // Now, all FPRs are also free.
     
-    // 6) Save all state from the stack into the scratch buffer. For simplicity we
-    //    do this even for state that's already in the right place on the stack.
-    //    It makes things simpler later.
+    // Save all state from the stack into the scratch buffer. For simplicity we
+    // do this even for state that's already in the right place on the stack.
+    // It makes things simpler later.
 
     for (size_t index = 0; index < operands.size(); ++index) {
         const ValueRecovery& recovery = operands[index];
@@ -253,9 +253,7 @@
             -m_jit.codeBlock()->jitCode()->dfgCommon()->requiredRegisterCountForExit * sizeof(Register)),
         CCallHelpers::framePointerRegister, CCallHelpers::stackPointerRegister);
     
-    // 7) Do all data format conversions and store the results into the stack.
-    
-    bool haveArguments = false;
+    // Do all data format conversions and store the results into the stack.
     
     for (size_t index = 0; index < operands.size(); ++index) {
         const ValueRecovery& recovery = operands[index];
@@ -310,78 +308,68 @@
                 AssemblyHelpers::addressFor(operand));
             break;
             
-        case ArgumentsThatWereNotCreated:
-            haveArguments = true;
-            // We can't restore this yet but we can make sure that the stack appears
-            // sane.
-            m_jit.store64(
-                AssemblyHelpers::TrustedImm64(JSValue::encode(JSValue())),
-                AssemblyHelpers::addressFor(operand));
+        case DirectArgumentsThatWereNotCreated:
+        case ClonedArgumentsThatWereNotCreated:
+            // Don't do this, yet.
             break;
             
         default:
+            RELEASE_ASSERT_NOT_REACHED();
             break;
         }
     }
     
-    // 8) Adjust the old JIT's execute counter. Since we are exiting OSR, we know
-    //    that all new calls into this code will go to the new JIT, so the execute
-    //    counter only affects call frames that performed OSR exit and call frames
-    //    that were still executing the old JIT at the time of another call frame's
-    //    OSR exit. We want to ensure that the following is true:
+    // Now that things on the stack are recovered, do the arguments recovery. We assume that arguments
+    // recoveries don't recursively refer to each other. But, we don't try to assume that they only
+    // refer to certain ranges of locals. Hence why we need to do this here, once the stack is sensible.
+    // Note that we also roughly assume that the arguments might still be materialized outside of its
+    // inline call frame scope - but for now the DFG wouldn't do that.
+    
+    emitRestoreArguments(operands);
+    
+    // Adjust the old JIT's execute counter. Since we are exiting OSR, we know
+    // that all new calls into this code will go to the new JIT, so the execute
+    // counter only affects call frames that performed OSR exit and call frames
+    // that were still executing the old JIT at the time of another call frame's
+    // OSR exit. We want to ensure that the following is true:
     //
-    //    (a) Code the performs an OSR exit gets a chance to reenter optimized
-    //        code eventually, since optimized code is faster. But we don't
-    //        want to do such reentery too aggressively (see (c) below).
+    // (a) Code the performs an OSR exit gets a chance to reenter optimized
+    //     code eventually, since optimized code is faster. But we don't
+    //     want to do such reentery too aggressively (see (c) below).
     //
-    //    (b) If there is code on the call stack that is still running the old
-    //        JIT's code and has never OSR'd, then it should get a chance to
-    //        perform OSR entry despite the fact that we've exited.
+    // (b) If there is code on the call stack that is still running the old
+    //     JIT's code and has never OSR'd, then it should get a chance to
+    //     perform OSR entry despite the fact that we've exited.
     //
-    //    (c) Code the performs an OSR exit should not immediately retry OSR
-    //        entry, since both forms of OSR are expensive. OSR entry is
-    //        particularly expensive.
+    // (c) Code the performs an OSR exit should not immediately retry OSR
+    //     entry, since both forms of OSR are expensive. OSR entry is
+    //     particularly expensive.
     //
-    //    (d) Frequent OSR failures, even those that do not result in the code
-    //        running in a hot loop, result in recompilation getting triggered.
+    // (d) Frequent OSR failures, even those that do not result in the code
+    //     running in a hot loop, result in recompilation getting triggered.
     //
-    //    To ensure (c), we'd like to set the execute counter to
-    //    counterValueForOptimizeAfterWarmUp(). This seems like it would endanger
-    //    (a) and (b), since then every OSR exit would delay the opportunity for
-    //    every call frame to perform OSR entry. Essentially, if OSR exit happens
-    //    frequently and the function has few loops, then the counter will never
-    //    become non-negative and OSR entry will never be triggered. OSR entry
-    //    will only happen if a loop gets hot in the old JIT, which does a pretty
-    //    good job of ensuring (a) and (b). But that doesn't take care of (d),
-    //    since each speculation failure would reset the execute counter.
-    //    So we check here if the number of speculation failures is significantly
-    //    larger than the number of successes (we want 90% success rate), and if
-    //    there have been a large enough number of failures. If so, we set the
-    //    counter to 0; otherwise we set the counter to
-    //    counterValueForOptimizeAfterWarmUp().
+    // To ensure (c), we'd like to set the execute counter to
+    // counterValueForOptimizeAfterWarmUp(). This seems like it would endanger
+    // (a) and (b), since then every OSR exit would delay the opportunity for
+    // every call frame to perform OSR entry. Essentially, if OSR exit happens
+    // frequently and the function has few loops, then the counter will never
+    // become non-negative and OSR entry will never be triggered. OSR entry
+    // will only happen if a loop gets hot in the old JIT, which does a pretty
+    // good job of ensuring (a) and (b). But that doesn't take care of (d),
+    // since each speculation failure would reset the execute counter.
+    // So we check here if the number of speculation failures is significantly
+    // larger than the number of successes (we want 90% success rate), and if
+    // there have been a large enough number of failures. If so, we set the
+    // counter to 0; otherwise we set the counter to
+    // counterValueForOptimizeAfterWarmUp().
     
     handleExitCounts(m_jit, exit);
     
-    // 9) Reify inlined call frames.
+    // Reify inlined call frames.
     
     reifyInlinedCallFrames(m_jit, exit);
     
-    // 10) Create arguments if necessary and place them into the appropriate aliased
-    //     registers.
-    
-    if (haveArguments) {
-        ArgumentsRecoveryGenerator argumentsRecovery;
-
-        for (size_t index = 0; index < operands.size(); ++index) {
-            const ValueRecovery& recovery = operands[index];
-            if (recovery.technique() != ArgumentsThatWereNotCreated)
-                continue;
-            argumentsRecovery.generateFor(
-                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
-        }
-    }
-
-    // 12) And finish.
+    // And finish.
     adjustAndJumpToTarget(m_jit, exit);
 }
 
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp b/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp
index 4caa0ee..e3c9a21 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp
@@ -28,7 +28,6 @@
 
 #if ENABLE(DFG_JIT)
 
-#include "Arguments.h"
 #include "DFGJITCode.h"
 #include "DFGOperations.h"
 #include "JIT.h"
@@ -206,10 +205,6 @@
         jit.store32(AssemblyHelpers::TrustedImm32(locationBits), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ArgumentCount)));
         if (!inlineCallFrame->isClosureCall)
             jit.store64(AssemblyHelpers::TrustedImm64(JSValue::encode(JSValue(inlineCallFrame->calleeConstant()))), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::Callee)));
-        
-        // Leave the captured arguments in regT3.
-        if (baselineCodeBlock->usesArguments())
-            jit.loadPtr(AssemblyHelpers::addressFor(VirtualRegister(inlineCallFrame->stackOffset + unmodifiedArgumentsRegister(baselineCodeBlock->argumentsRegister()).offset())), GPRInfo::regT3);
 #else // USE(JSVALUE64) // so this is the 32-bit part
         jit.storePtr(callerFrameGPR, AssemblyHelpers::addressForByteOffset(inlineCallFrame->callerFrameOffset()));
         Instruction* instruction = baselineCodeBlock->instructions().begin() + codeOrigin.bytecodeIndex;
@@ -218,18 +213,7 @@
         jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::Callee)));
         if (!inlineCallFrame->isClosureCall)
             jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->calleeConstant()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::Callee)));
-
-        // Leave the captured arguments in regT3.
-        if (baselineCodeBlock->usesArguments())
-            jit.loadPtr(AssemblyHelpers::payloadFor(VirtualRegister(inlineCallFrame->stackOffset + unmodifiedArgumentsRegister(baselineCodeBlock->argumentsRegister()).offset())), GPRInfo::regT3);
 #endif // USE(JSVALUE64) // ending the #else part, so directly above is the 32-bit part
-        
-        if (baselineCodeBlock->usesArguments()) {
-            AssemblyHelpers::Jump noArguments = jit.branchTestPtr(AssemblyHelpers::Zero, GPRInfo::regT3);
-            jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
-            jit.storePtr(GPRInfo::regT0, AssemblyHelpers::Address(GPRInfo::regT3, Arguments::offsetOfRegisters()));
-            noArguments.link(&jit);
-        }
     }
 
 #if USE(JSVALUE64)
@@ -299,75 +283,6 @@
     jit.jump(GPRInfo::regT2);
 }
 
-ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator() { }
-ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator() { }
-
-void ArgumentsRecoveryGenerator::generateFor(
-    int operand, CodeOrigin codeOrigin, CCallHelpers& jit)
-{
-    // Find the right inline call frame.
-    InlineCallFrame* inlineCallFrame = 0;
-    for (InlineCallFrame* current = codeOrigin.inlineCallFrame;
-         current;
-         current = current->caller.inlineCallFrame) {
-        if (current->stackOffset >= operand) {
-            inlineCallFrame = current;
-            break;
-        }
-    }
-
-    if (!jit.baselineCodeBlockFor(inlineCallFrame)->usesArguments())
-        return;
-    VirtualRegister argumentsRegister = jit.baselineArgumentsRegisterFor(inlineCallFrame);
-    if (m_didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
-        // We know this call frame optimized out an arguments object that
-        // the baseline JIT would have created. Do that creation now.
-        if (inlineCallFrame) {
-            jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
-            jit.setupArguments(GPRInfo::regT0);
-        } else
-            jit.setupArgumentsExecState();
-        jit.move(
-            AssemblyHelpers::TrustedImmPtr(
-                bitwise_cast<void*>(operationCreateArgumentsDuringOSRExit)),
-            GPRInfo::nonArgGPR0);
-#if USE(JSVALUE64)
-        jit.call(GPRInfo::nonArgGPR0);
-        jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
-        jit.store64(
-            GPRInfo::returnValueGPR,
-            AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
-        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
-#else // USE(JSVALUE64) -> so the 32_64 part
-        jit.call(GPRInfo::nonArgGPR0);
-        jit.store32(
-            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
-            AssemblyHelpers::tagFor(argumentsRegister));
-        jit.store32(
-            GPRInfo::returnValueGPR,
-            AssemblyHelpers::payloadFor(argumentsRegister));
-        jit.store32(
-            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
-            AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
-        jit.store32(
-            GPRInfo::returnValueGPR,
-            AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
-        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
-#endif // USE(JSVALUE64)
-    }
-
-#if USE(JSVALUE64)
-    jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
-    jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
-#else // USE(JSVALUE64) -> so the 32_64 part
-    jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
-    jit.store32(
-        AssemblyHelpers::TrustedImm32(JSValue::CellTag),
-        AssemblyHelpers::tagFor(operand));
-    jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
-#endif // USE(JSVALUE64)
-}
-    
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h b/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h
index 93ecf47..ce1836f 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,18 +37,6 @@
 void reifyInlinedCallFrames(CCallHelpers&, const OSRExitBase&);
 void adjustAndJumpToTarget(CCallHelpers&, const OSRExitBase&);
 
-class ArgumentsRecoveryGenerator {
-public:
-    ArgumentsRecoveryGenerator();
-    ~ArgumentsRecoveryGenerator();
-    
-    void generateFor(int operand, CodeOrigin, CCallHelpers&);
-    
-private:
-    HashSet<InlineCallFrame*, DefaultHash<InlineCallFrame*>::Hash,
-        NullableHashTraits<InlineCallFrame*>> m_didCreateArgumentsObject;
-};
-
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp
index 02077c5..62eca89 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp
@@ -26,8 +26,8 @@
 #include "config.h"
 #include "DFGOperations.h"
 
-#include "Arguments.h"
 #include "ButterflyInlines.h"
+#include "ClonedArguments.h"
 #include "CodeBlock.h"
 #include "CommonSlowPaths.h"
 #include "CopiedSpaceInlines.h"
@@ -38,6 +38,7 @@
 #include "DFGToFTLDeferredCompilationCallback.h"
 #include "DFGToFTLForOSREntryDeferredCompilationCallback.h"
 #include "DFGWorklist.h"
+#include "DirectArguments.h"
 #include "FTLForOSREntryJITCode.h"
 #include "FTLOSREntry.h"
 #include "HostCallReturnValue.h"
@@ -45,16 +46,17 @@
 #include "Interpreter.h"
 #include "JIT.h"
 #include "JITExceptions.h"
+#include "JSCInlines.h"
 #include "JSLexicalEnvironment.h"
-#include "VM.h"
 #include "JSNameScope.h"
 #include "ObjectConstructor.h"
-#include "JSCInlines.h"
 #include "Repatch.h"
+#include "ScopedArguments.h"
 #include "StringConstructor.h"
 #include "Symbol.h"
 #include "TypeProfilerLog.h"
 #include "TypedArrayInlines.h"
+#include "VM.h"
 #include <wtf/InlineASM.h>
 
 #if ENABLE(JIT)
@@ -746,66 +748,102 @@
     return newTypedArrayWithOneArgument<JSFloat64Array>(exec, structure, encodedValue);
 }
 
-JSCell* JIT_OPERATION operationCreateInlinedArguments(
-    ExecState* exec, InlineCallFrame* inlineCallFrame)
+JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState* exec, Structure* structure, JSScope* scope, SymbolTable* table)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
-    // NB: This needs to be exceedingly careful with top call frame tracking, since it
-    // may be called from OSR exit, while the state of the call stack is bizarre.
-    Arguments* result = Arguments::create(vm, exec, inlineCallFrame);
-    ASSERT(!vm.exception());
+    return JSLexicalEnvironment::create(vm, structure, scope, table);
+}
+
+JSCell* JIT_OPERATION operationCreateDirectArguments(ExecState* exec, Structure* structure, int32_t length, int32_t minCapacity)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer target(&vm, exec);
+    DirectArguments* result = DirectArguments::create(
+        vm, structure, length, std::max(length, minCapacity));
+    // The caller will store to this object without barriers. Most likely, at this point, this is
+    // still a young object and so no barriers are needed. But it's good to be careful anyway,
+    // since the GC should be allowed to do crazy (like pretenuring, for example).
+    vm.heap.writeBarrier(result);
     return result;
 }
 
-void JIT_OPERATION operationTearOffInlinedArguments(
-    ExecState* exec, JSCell* argumentsCell, JSCell* activationCell, InlineCallFrame* inlineCallFrame)
-{
-    ASSERT_UNUSED(activationCell, !activationCell); // Currently, we don't inline functions with activations.
-    jsCast<Arguments*>(argumentsCell)->tearOff(exec, inlineCallFrame);
-}
-
-EncodedJSValue JIT_OPERATION operationGetArgumentByVal(ExecState* exec, int32_t argumentsRegister, int32_t index)
+JSCell* JIT_OPERATION operationCreateScopedArguments(ExecState* exec, Structure* structure, Register* argumentStart, int32_t length, JSFunction* callee, JSLexicalEnvironment* scope)
 {
     VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-
-    JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue();
+    NativeCallFrameTracer target(&vm, exec);
     
-    // If there are no arguments, and we're accessing out of bounds, then we have to create the
-    // arguments in case someone has installed a getter on a numeric property.
-    if (!argumentsValue) {
-        JSLexicalEnvironment* lexicalEnvironment = exec->lexicalEnvironmentOrNullptr();
-        exec->uncheckedR(argumentsRegister) = argumentsValue = Arguments::create(exec->vm(), exec, lexicalEnvironment);
-    }
+    // We could pass the ScopedArgumentsTable* as an argument. We currently don't because I
+    // didn't feel like changing the max number of arguments for a slow path call from 6 to 7.
+    ScopedArgumentsTable* table = scope->symbolTable()->arguments();
     
-    return JSValue::encode(argumentsValue.get(exec, index));
+    return ScopedArguments::createByCopyingFrom(
+        vm, structure, argumentStart, length, callee, table, scope);
 }
 
-EncodedJSValue JIT_OPERATION operationGetInlinedArgumentByVal(
-    ExecState* exec, int32_t argumentsRegister, InlineCallFrame* inlineCallFrame, int32_t index)
+JSCell* JIT_OPERATION operationCreateClonedArguments(ExecState* exec, Structure* structure, Register* argumentStart, int32_t length, JSFunction* callee)
 {
     VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-
-    JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue();
-    
-    // If there are no arguments, and we're accessing out of bounds, then we have to create the
-    // arguments in case someone has installed a getter on a numeric property.
-    if (!argumentsValue) {
-        exec->uncheckedR(argumentsRegister) = argumentsValue =
-            Arguments::create(exec->vm(), exec, inlineCallFrame);
-    }
-    
-    return JSValue::encode(argumentsValue.get(exec, index));
+    NativeCallFrameTracer target(&vm, exec);
+    return ClonedArguments::createByCopyingFrom(
+        exec, structure, argumentStart, length, callee);
 }
 
-JSCell* JIT_OPERATION operationNewFunctionNoCheck(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
+JSCell* JIT_OPERATION operationCreateDirectArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, int32_t argumentCount)
 {
-    ASSERT(functionExecutable->inherits(FunctionExecutable::info()));
     VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-    return JSFunction::create(vm, static_cast<FunctionExecutable*>(functionExecutable), scope);
+    NativeCallFrameTracer target(&vm, exec);
+    
+    DeferGCForAWhile deferGC(vm.heap);
+    
+    CodeBlock* codeBlock;
+    if (inlineCallFrame)
+        codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
+    else
+        codeBlock = exec->codeBlock();
+    
+    unsigned length = argumentCount - 1;
+    unsigned capacity = std::max(length, static_cast<unsigned>(codeBlock->numParameters() - 1));
+    DirectArguments* result = DirectArguments::create(
+        vm, codeBlock->globalObject()->directArgumentsStructure(), length, capacity);
+    
+    result->callee().set(vm, result, callee);
+    
+    Register* arguments =
+        exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
+        CallFrame::argumentOffset(0);
+    for (unsigned i = length; i--;)
+        result->setIndexQuickly(vm, i, arguments[i].jsValue());
+    
+    return result;
+}
+
+JSCell* JIT_OPERATION operationCreateClonedArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, int32_t argumentCount)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer target(&vm, exec);
+    
+    DeferGCForAWhile deferGC(vm.heap);
+    
+    CodeBlock* codeBlock;
+    if (inlineCallFrame)
+        codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
+    else
+        codeBlock = exec->codeBlock();
+    
+    unsigned length = argumentCount - 1;
+    ClonedArguments* result = ClonedArguments::createEmpty(
+        vm, codeBlock->globalObject()->outOfBandArgumentsStructure(), callee);
+    
+    Register* arguments =
+        exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
+        CallFrame::argumentOffset(0);
+    for (unsigned i = length; i--;)
+        result->putDirectIndex(exec, i, arguments[i].jsValue());
+    
+    result->putDirect(vm, vm.propertyNames->length, jsNumber(length));
+    
+    return result;
 }
 
 size_t JIT_OPERATION operationIsObjectOrNull(ExecState* exec, EncodedJSValue value)
@@ -1018,6 +1056,13 @@
     set->notifyWrite(vm, value, "Executed NotifyWrite");
 }
 
+void JIT_OPERATION operationThrowStackOverflowForVarargs(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    throwStackOverflowError(exec);
+}
+
 int32_t JIT_OPERATION operationSizeOfVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t firstVarArgOffset)
 {
     VM& vm = exec->vm();
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.h b/Source/JavaScriptCore/dfg/DFGOperations.h
index 9fed98b..d13eccf 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.h
+++ b/Source/JavaScriptCore/dfg/DFGOperations.h
@@ -96,11 +96,12 @@
 size_t JIT_OPERATION operationRegExpTest(ExecState*, JSCell*, JSCell*) WTF_INTERNAL;
 size_t JIT_OPERATION operationCompareStrictEqCell(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
 size_t JIT_OPERATION operationCompareStrictEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationCreateInlinedArguments(ExecState*, InlineCallFrame*) WTF_INTERNAL;
-void JIT_OPERATION operationTearOffInlinedArguments(ExecState*, JSCell*, JSCell*, InlineCallFrame*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationGetInlinedArgumentByVal(ExecState*, int32_t, InlineCallFrame*, int32_t) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationGetArgumentByVal(ExecState*, int32_t, int32_t) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationNewFunctionNoCheck(ExecState*, JSScope*, JSCell*) WTF_INTERNAL;
+JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState*, Structure*, JSScope*, SymbolTable*);
+JSCell* JIT_OPERATION operationCreateDirectArguments(ExecState*, Structure*, int32_t length, int32_t minCapacity);
+JSCell* JIT_OPERATION operationCreateDirectArgumentsDuringExit(ExecState*, InlineCallFrame*, JSFunction*, int32_t argumentCount);
+JSCell* JIT_OPERATION operationCreateScopedArguments(ExecState*, Structure*, Register* argumentStart, int32_t length, JSFunction* callee, JSLexicalEnvironment*);
+JSCell* JIT_OPERATION operationCreateClonedArgumentsDuringExit(ExecState*, InlineCallFrame*, JSFunction*, int32_t argumentCount);
+JSCell* JIT_OPERATION operationCreateClonedArguments(ExecState*, Structure*, Register* argumentStart, int32_t length, JSFunction* callee);
 double JIT_OPERATION operationFModOnInts(int32_t, int32_t) WTF_INTERNAL;
 size_t JIT_OPERATION operationIsObjectOrNull(ExecState*, EncodedJSValue) WTF_INTERNAL;
 size_t JIT_OPERATION operationIsFunction(EncodedJSValue) WTF_INTERNAL;
@@ -125,6 +126,7 @@
 char* JIT_OPERATION operationFindSwitchImmTargetForDouble(ExecState*, EncodedJSValue, size_t tableIndex);
 char* JIT_OPERATION operationSwitchString(ExecState*, size_t tableIndex, JSString*);
 void JIT_OPERATION operationNotifyWrite(ExecState*, VariableWatchpointSet*, EncodedJSValue);
+void JIT_OPERATION operationThrowStackOverflowForVarargs(ExecState*) WTF_INTERNAL;
 int32_t JIT_OPERATION operationSizeOfVarargs(ExecState*, EncodedJSValue arguments, int32_t firstVarArgOffset);
 void JIT_OPERATION operationLoadVarargs(ExecState*, int32_t firstElementDest, EncodedJSValue arguments, int32_t offset, int32_t length, int32_t mandatoryMinimum);
 
diff --git a/Source/JavaScriptCore/dfg/DFGPlan.cpp b/Source/JavaScriptCore/dfg/DFGPlan.cpp
index a3f33ab..4b292bb 100644
--- a/Source/JavaScriptCore/dfg/DFGPlan.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPlan.cpp
@@ -28,7 +28,7 @@
 
 #if ENABLE(DFG_JIT)
 
-#include "DFGArgumentsSimplificationPhase.h"
+#include "DFGArgumentsEliminationPhase.h"
 #include "DFGBackwardsPropagationPhase.h"
 #include "DFGByteCodeParser.h"
 #include "DFGCFAPhase.h"
@@ -67,6 +67,7 @@
 #include "DFGTypeCheckHoistingPhase.h"
 #include "DFGUnificationPhase.h"
 #include "DFGValidate.h"
+#include "DFGVarargsForwardingPhase.h"
 #include "DFGVirtualRegisterAllocationPhase.h"
 #include "DFGWatchpointCollectionPhase.h"
 #include "Debugger.h"
@@ -220,6 +221,11 @@
     if (validationEnabled())
         validate(dfg);
     
+    if (Options::dumpGraphAfterParsing()) {
+        dataLog("Graph after parsing:\n");
+        dfg.dump();
+    }
+    
     performCPSRethreading(dfg);
     performUnification(dfg);
     performPredictionInjection(dfg);
@@ -257,9 +263,7 @@
         
     performStrengthReduction(dfg);
     performLocalCSE(dfg);
-    performCPSRethreading(dfg); // Canonicalize PhantomLocal to Phantom
-    performArgumentsSimplification(dfg);
-    performCPSRethreading(dfg); // This should do nothing, if arguments simplification did nothing.
+    performCPSRethreading(dfg);
     performCFA(dfg);
     performConstantFolding(dfg);
     bool changed = false;
@@ -270,6 +274,28 @@
         validate(dfg);
     
     performCPSRethreading(dfg);
+    if (!isFTL(mode)) {
+        // Only run this if we're not FTLing, because currently for a LoadVarargs that is forwardable and
+        // in a non-varargs inlined call frame, this will generate ForwardVarargs while the FTL
+        // ArgumentsEliminationPhase will create a sequence of GetStack+PutStacks. The GetStack+PutStack
+        // sequence then gets sunk, eliminating anything that looks like an escape for subsequent phases,
+        // while the ForwardVarargs doesn't get simplified until later (or not at all) and looks like an
+        // escape for all of the arguments. This then disables object allocation sinking.
+        //
+        // So, for now, we just disable this phase for the FTL.
+        //
+        // If we wanted to enable it, we'd have to do any of the following:
+        // - Enable ForwardVarargs->GetStack+PutStack strength reduction, and have that run before
+        //   PutStack sinking and object allocation sinking.
+        // - Make VarargsForwarding emit a GetLocal+SetLocal sequence, that we can later turn into
+        //   GetStack+PutStack.
+        //
+        // But, it's not super valuable to enable those optimizations, since the FTL
+        // ArgumentsEliminationPhase does everything that this phase does, and it doesn't introduce this
+        // pathology.
+        
+        changed |= performVarargsForwarding(dfg); // Do this after CFG simplification and CPS rethreading.
+    }
     if (changed) {
         performCFA(dfg);
         performConstantFolding(dfg);
@@ -321,7 +347,11 @@
         performCPSRethreading(dfg);
         performSSAConversion(dfg);
         performSSALowering(dfg);
+        
+        // Ideally, these would be run to fixpoint with the object allocation sinking phase.
+        performArgumentsElimination(dfg);
         performPutStackSinking(dfg);
+        
         performGlobalCSE(dfg);
         performLivenessAnalysis(dfg);
         performCFA(dfg);
@@ -340,7 +370,14 @@
             performCFA(dfg);
             performConstantFolding(dfg);
         }
+        
+        // Currently, this relies on pre-headers still being valid. That precludes running CFG
+        // simplification before it, unless we re-created the pre-headers. There wouldn't be anything
+        // wrong with running LICM earlier, if we wanted to put other CFG transforms above this point.
+        // Alternatively, we could run loop pre-header creation after SSA conversion - but if we did that
+        // then we'd need to do some simple SSA fix-up.
         performLICM(dfg);
+        
         performPhantomCanonicalization(dfg);
         performIntegerCheckCombining(dfg);
         performGlobalCSE(dfg);
diff --git a/Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h b/Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h
index cbda2c4..907f565 100644
--- a/Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h
+++ b/Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h
@@ -49,7 +49,7 @@
     
     void read(AbstractHeap heap)
     {
-        if (heap.kind() == Variables) {
+        if (heap.kind() == Stack) {
             if (heap.payload().isTop()) {
                 readTop();
                 return;
@@ -59,7 +59,7 @@
             return;
         }
         
-        if (heap.overlaps(Variables)) {
+        if (heap.overlaps(Stack)) {
             readTop();
             return;
         }
@@ -67,20 +67,14 @@
     
     void write(AbstractHeap heap)
     {
-        if (heap.kind() == Variables) {
-            if (heap.payload().isTop()) {
-                writeTop();
-                return;
-            }
-            
+        // We expect stack writes to already be precisely characterized by DFG::clobberize().
+        if (heap.kind() == Stack) {
+            RELEASE_ASSERT(!heap.payload().isTop());
             callIfAppropriate(m_write, VirtualRegister(heap.payload().value32()));
             return;
         }
         
-        if (heap.overlaps(Variables)) {
-            writeTop();
-            return;
-        }
+        RELEASE_ASSERT(!heap.overlaps(Stack));
     }
     
     void def(PureValue)
@@ -90,10 +84,10 @@
     
     void def(HeapLocation location, Node* node)
     {
-        if (location.kind() != VariableLoc)
+        if (location.kind() != StackLoc)
             return;
         
-        RELEASE_ASSERT(location.heap().kind() == Variables);
+        RELEASE_ASSERT(location.heap().kind() == Stack);
         
         m_def(VirtualRegister(location.heap().payload().value32()), node);
     }
@@ -121,12 +115,6 @@
         for (unsigned i = 0; i < JSStack::ThisArgument; ++i)
             m_read(VirtualRegister(i));
         
-        // Read all of the captured variables.
-        const BitVector& capturedVars =
-            m_graph.capturedVarsFor(m_node->origin.semantic.inlineCallFrame);
-        for (unsigned i : capturedVars.setBits())
-            m_read(virtualRegisterForLocal(i));
-        
         // Read all of the inline arguments and call frame headers that we didn't already capture.
         for (InlineCallFrame* inlineCallFrame = m_node->origin.semantic.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->caller.inlineCallFrame) {
             for (unsigned i = inlineCallFrame->arguments.size(); i-- > 1;)
@@ -136,31 +124,9 @@
             if (inlineCallFrame->isVarargs())
                 m_read(VirtualRegister(inlineCallFrame->stackOffset + JSStack::ArgumentCount));
         }
-    }
-    
-    void writeTop()
-    {
-        if (m_node->op() == LoadVarargs) {
-            // Make sure we note the writes to the locals that will store the array elements and
-            // count.
-            LoadVarargsData* data = m_node->loadVarargsData();
-            m_write(data->count);
-            for (unsigned i = data->limit; i--;)
-                m_write(VirtualRegister(data->start.offset() + i));
-        }
-        
+
         // Note that we don't need to do anything special for CallForwardVarargs, since it reads
         // our arguments the same way that any effectful thing might.
-        
-        if (m_graph.m_codeBlock->usesArguments()) {
-            for (unsigned i = m_graph.m_codeBlock->numParameters(); i-- > 1;)
-                m_write(virtualRegisterForArgument(i));
-        }
-
-        const BitVector& capturedVars =
-            m_graph.capturedVarsFor(m_node->origin.semantic.inlineCallFrame);
-        for (unsigned i : capturedVars.setBits())
-            m_write(virtualRegisterForLocal(i));
     }
     
     Graph& m_graph;
@@ -170,20 +136,6 @@
     const DefFunctor& m_def;
 };
 
-template<typename ReadFunctor>
-void forEachLocalReadByUnwind(Graph& graph, CodeOrigin codeOrigin, const ReadFunctor& read)
-{
-    if (graph.uncheckedActivationRegister().isValid())
-        read(graph.activationRegister());
-    if (graph.m_codeBlock->usesArguments())
-        read(unmodifiedArgumentsRegister(graph.argumentsRegisterFor(nullptr)));
-    
-    for (InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->caller.inlineCallFrame) {
-        if (inlineCallFrame->executable->usesArguments())
-            read(unmodifiedArgumentsRegister(graph.argumentsRegisterFor(inlineCallFrame)));
-    }
-}
-
 template<typename ReadFunctor, typename WriteFunctor, typename DefFunctor>
 void preciseLocalClobberize(
     Graph& graph, Node* node,
@@ -192,8 +144,6 @@
     PreciseLocalClobberizeAdaptor<ReadFunctor, WriteFunctor, DefFunctor>
         adaptor(graph, node, read, write, def);
     clobberize(graph, node, adaptor);
-    if (mayExit(graph, node))
-        forEachLocalReadByUnwind(graph, node->origin.forExit, read);
 }
 
 } } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
index 5a6271f..0818fa3 100644
--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
@@ -57,6 +57,8 @@
         ASSERT(m_graph.m_form == ThreadedCPS);
         ASSERT(m_graph.m_unificationState == GloballyUnified);
 
+        propagateThroughArgumentPositions();
+
         m_pass = PrimaryPass;
         propagateToFixpoint();
         
@@ -187,7 +189,6 @@
         case RegExpTest:
         case GetById:
         case GetByIdFlush:
-        case GetMyArgumentByValSafe:
         case GetByOffset:
         case MultiGetByOffset:
         case GetDirectPname:
@@ -196,10 +197,12 @@
         case CallVarargs:
         case ConstructVarargs:
         case CallForwardVarargs:
+        case ConstructForwardVarargs:
         case NativeCall:
         case NativeConstruct:
         case GetGlobalVar:
-        case GetClosureVar: {
+        case GetClosureVar:
+        case GetFromArguments: {
             changed |= setPrediction(node->getHeapPrediction());
             break;
         }
@@ -213,11 +216,15 @@
         case GetGetter:
         case GetSetter:
         case GetCallee:
-        case NewFunctionNoCheck:
-        case NewFunctionExpression: {
+        case NewFunction: {
             changed |= setPrediction(SpecFunction);
             break;
         }
+            
+        case GetArgumentCount: {
+            changed |= setPrediction(SpecInt32);
+            break;
+        }
 
         case StringCharCodeAt: {
             changed |= setPrediction(SpecInt32);
@@ -418,12 +425,6 @@
             break;
         }
             
-        case GetMyArgumentsLengthSafe: {
-            changed |= setPrediction(SpecInt32);
-            break;
-        }
-
-        case GetClosureRegisters:            
         case GetButterfly: 
         case GetIndexedPropertyStorage:
         case AllocatePropertyStorage:
@@ -497,17 +498,18 @@
             break;
         }
             
-        case CreateArguments: {
-            changed |= setPrediction(SpecArguments);
+        case CreateDirectArguments: {
+            changed |= setPrediction(SpecDirectArguments);
             break;
         }
             
-        case NewFunction: {
-            SpeculatedType child = node->child1()->prediction();
-            if (child & SpecEmpty)
-                changed |= mergePrediction((child & ~SpecEmpty) | SpecFunction);
-            else
-                changed |= mergePrediction(child);
+        case CreateScopedArguments: {
+            changed |= setPrediction(SpecScopedArguments);
+            break;
+        }
+            
+        case CreateClonedArguments: {
+            changed |= setPrediction(SpecObjectOther);
             break;
         }
             
@@ -522,9 +524,6 @@
         case GetTypedArrayByteOffset:
         case DoubleAsInt32:
         case GetLocalUnlinked:
-        case GetMyArgumentsLength:
-        case GetMyArgumentByVal:
-        case PhantomArguments:
         case CheckArray:
         case Arrayify:
         case ArrayifyToStructure:
@@ -542,6 +541,10 @@
         case Identity:
         case BooleanToNumber:
         case PhantomNewObject:
+        case PhantomDirectArguments:
+        case PhantomClonedArguments:
+        case GetMyArgumentByVal:
+        case ForwardVarargs:
         case PutHint:
         case CheckStructureImmediate:
         case MaterializeNewObject:
@@ -607,6 +610,7 @@
         case PutByValDirect:
         case PutByVal:
         case PutClosureVar:
+        case PutToArguments:
         case Return:
         case Throw:
         case PutById:
@@ -631,8 +635,6 @@
         case CheckNotEmpty:
         case CheckBadCell:
         case PutStructure:
-        case TearOffArguments:
-        case CheckArgumentsNotCreated:
         case VarInjectionWatchpoint:
         case AllocationProfileWatchpoint:
         case Phantom:
@@ -854,8 +856,7 @@
                 continue;
             m_changed |= variableAccessData->tallyVotesForShouldUseDoubleFormat();
         }
-        for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i)
-            m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness();
+        propagateThroughArgumentPositions();
         for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
             VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
             if (!variableAccessData->isRoot())
@@ -864,6 +865,12 @@
         }
     }
     
+    void propagateThroughArgumentPositions()
+    {
+        for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i)
+            m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness();
+    }
+    
     Node* m_currentNode;
     bool m_changed;
     PredictionPass m_pass; // We use different logic for considering predictions depending on how far along we are in propagation.
diff --git a/Source/JavaScriptCore/dfg/DFGPromoteHeapAccess.h b/Source/JavaScriptCore/dfg/DFGPromoteHeapAccess.h
index 9551bf2..645784e 100644
--- a/Source/JavaScriptCore/dfg/DFGPromoteHeapAccess.h
+++ b/Source/JavaScriptCore/dfg/DFGPromoteHeapAccess.h
@@ -61,7 +61,7 @@
     }
         
     case PutHint: {
-        ASSERT(node->child1()->isPhantomObjectAllocation());
+        ASSERT(node->child1()->isPhantomAllocation());
         write(
             PromotedHeapLocation(node->child1().node(), node->promotedLocationDescriptor()),
             node->child2());
diff --git a/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.cpp b/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.cpp
index 5a57a13..8c83c42 100644
--- a/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -70,6 +70,18 @@
     case NamedPropertyPLoc:
         out.print("NamedPropertyPLoc");
         return;
+        
+    case ArgumentPLoc:
+        out.print("ArgumentPLoc");
+        return;
+        
+    case ArgumentCountPLoc:
+        out.print("ArgumentCountPLoc");
+        return;
+        
+    case ArgumentsCalleePLoc:
+        out.print("ArgumentsCalleePLoc");
+        return;
     }
     
     RELEASE_ASSERT_NOT_REACHED();
diff --git a/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h b/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h
index bbd52e1..c674f0e 100644
--- a/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h
+++ b/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,7 +37,10 @@
     InvalidPromotedLocationKind,
     
     StructurePLoc,
-    NamedPropertyPLoc
+    NamedPropertyPLoc,
+    ArgumentPLoc,
+    ArgumentCountPLoc,
+    ArgumentsCalleePLoc
 };
 
 class PromotedLocationDescriptor {
diff --git a/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp b/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp
index 632a378b..bcc91f5 100644
--- a/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp
@@ -63,7 +63,7 @@
 
         // Create a SSACalculator::Variable for every root VariableAccessData.
         for (VariableAccessData& variable : m_graph.m_variableAccessData) {
-            if (!variable.isRoot() || variable.isCaptured())
+            if (!variable.isRoot())
                 continue;
             
             SSACalculator::Variable* ssaVariable = m_calculator.newVariable();
@@ -87,8 +87,6 @@
                     continue;
                 
                 VariableAccessData* variable = node->variableAccessData();
-                if (variable->isCaptured())
-                    continue;
                 
                 Node* childNode;
                 if (node->op() == SetLocal)
@@ -190,10 +188,8 @@
         //
         //   - MovHint has KillLocal prepended to it.
         //
-        //   - GetLocal over captured variables lose their phis and become GetStack.
-        //
-        //   - GetLocal over uncaptured variables die and get replaced with references to the node
-        //     specified by valueForOperand.
+        //   - GetLocal die and get replaced with references to the node specified by
+        //     valueForOperand.
         //
         //   - SetLocal turns into PutStack if it's flushed, or turns into a Check otherwise.
         //
@@ -218,8 +214,6 @@
                         continue;
                     
                     VariableAccessData* variable = nodeAtHead->variableAccessData();
-                    if (variable->isCaptured())
-                        continue;
                     
                     if (verbose)
                         dataLog("Considering live variable ", VariableAccessDataDump(m_graph, variable), " at head of block ", *block, "\n");
@@ -283,18 +277,16 @@
                 case SetLocal: {
                     VariableAccessData* variable = node->variableAccessData();
                     
-                    if (variable->isCaptured() || !!(node->flags() & NodeIsFlushed)) {
+                    if (!!(node->flags() & NodeIsFlushed)) {
                         node->convertToPutStack(
                             m_graph.m_stackAccessData.add(
                                 variable->local(), variable->flushFormat()));
                     } else
                         node->setOpAndDefaultFlags(Check);
                     
-                    if (!variable->isCaptured()) {
-                        if (verbose)
-                            dataLog("Mapping: ", variable->local(), " -> ", node->child1().node(), "\n");
-                        valueForOperand.operand(variable->local()) = node->child1().node();
-                    }
+                    if (verbose)
+                        dataLog("Mapping: ", variable->local(), " -> ", node->child1().node(), "\n");
+                    valueForOperand.operand(variable->local()) = node->child1().node();
                     break;
                 }
                     
@@ -308,11 +300,6 @@
                     VariableAccessData* variable = node->variableAccessData();
                     node->children.reset();
                     
-                    if (variable->isCaptured()) {
-                        node->convertToGetStack(m_graph.m_stackAccessData.add(variable->local(), variable->flushFormat()));
-                        break;
-                    }
-                    
                     node->convertToPhantom();
                     if (verbose)
                         dataLog("Replacing node ", node, " with ", valueForOperand.operand(variable->local()), "\n");
@@ -329,19 +316,7 @@
                 case PhantomLocal: {
                     ASSERT(node->child1().useKind() == UntypedUse);
                     VariableAccessData* variable = node->variableAccessData();
-                    if (variable->isCaptured()) {
-                        // This is a fun case. We could have a captured variable that had some
-                        // or all of its uses strength reduced to phantoms rather than flushes.
-                        // SSA conversion will currently still treat it as flushed, in the sense
-                        // that it will just keep the SetLocal. Therefore, there is nothing that
-                        // needs to be done here: we don't need to also keep the source value
-                        // alive. And even if we did want to keep the source value alive, we
-                        // wouldn't be able to, because the variablesAtHead value for a captured
-                        // local wouldn't have been computed by the Phi reduction algorithm
-                        // above.
-                        node->children.reset();
-                    } else
-                        node->child1() = valueForOperand.operand(variable->local())->defaultEdge();
+                    node->child1() = valueForOperand.operand(variable->local())->defaultEdge();
                     node->convertToPhantom();
                     break;
                 }
@@ -402,12 +377,9 @@
             FlushFormat format = FlushedJSValue;
 
             Node* node = m_argumentMapping.get(m_graph.m_arguments[i]);
-
-            // m_argumentMapping.get could return null for a captured local. That's fine. We only
-            // track the argument loads of those arguments for which we speculate type. We don't
-            // speculate type for captured arguments.
-            if (node)
-                format = node->stackAccessData()->format;
+            
+            RELEASE_ASSERT(node);
+            format = node->stackAccessData()->format;
             
             m_graph.m_argumentFormats[i] = format;
             m_graph.m_arguments[i] = node; // Record the load that loads the arguments for the benefit of exit profiling.
diff --git a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
index b1e1e9e..f6676de 100644
--- a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
+++ b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
@@ -116,6 +116,7 @@
     case ToThis:
     case CreateThis:
     case GetCallee:
+    case GetArgumentCount:
     case GetLocal:
     case SetLocal:
     case PutStack:
@@ -170,7 +171,6 @@
     case ArrayifyToStructure:
     case GetScope:
     case SkipScope:
-    case GetClosureRegisters:
     case GetClosureVar:
     case PutClosureVar:
     case GetGlobalVar:
@@ -195,6 +195,7 @@
     case ConstructVarargs:
     case LoadVarargs:
     case CallForwardVarargs:
+    case ConstructForwardVarargs:
     case NewObject:
     case NewArray:
     case NewArrayWithSize:
@@ -222,17 +223,12 @@
     case MakeRope:
     case In:
     case CreateActivation:
-    case CreateArguments:
-    case PhantomArguments:
-    case TearOffArguments:
-    case GetMyArgumentsLength:
-    case GetMyArgumentByVal:
-    case GetMyArgumentsLengthSafe:
-    case GetMyArgumentByValSafe:
-    case CheckArgumentsNotCreated:
-    case NewFunctionNoCheck:
+    case CreateDirectArguments:
+    case CreateScopedArguments:
+    case CreateClonedArguments:
+    case GetFromArguments:
+    case PutToArguments:
     case NewFunction:
-    case NewFunctionExpression:
     case Jump:
     case Branch:
     case Switch:
@@ -280,6 +276,10 @@
     case PutHint:
     case CheckStructureImmediate:
     case MaterializeNewObject:
+    case PhantomDirectArguments:
+    case PhantomClonedArguments:
+    case GetMyArgumentByVal:
+    case ForwardVarargs:
         return true;
 
     case NativeCall:
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index e17df4e..8146b9a 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,16 +28,20 @@
 
 #if ENABLE(DFG_JIT)
 
-#include "Arguments.h"
 #include "BinarySwitch.h"
 #include "DFGAbstractInterpreterInlines.h"
 #include "DFGArrayifySlowPathGenerator.h"
 #include "DFGCallArrayAllocatorSlowPathGenerator.h"
+#include "DFGCallCreateDirectArgumentsSlowPathGenerator.h"
 #include "DFGMayExit.h"
 #include "DFGSaneStringGetByValSlowPathGenerator.h"
 #include "DFGSlowPathGenerator.h"
-#include "LinkBuffer.h"
+#include "DirectArguments.h"
 #include "JSCInlines.h"
+#include "JSEnvironmentRecord.h"
+#include "JSLexicalEnvironment.h"
+#include "LinkBuffer.h"
+#include "ScopedArguments.h"
 #include "ScratchRegisterAllocator.h"
 #include "WriteBarrierBuffer.h"
 #include <wtf/MathExtras.h>
@@ -103,35 +107,53 @@
     // what this custom CallArrayAllocatorSlowPathGenerator gives me. It's a lot
     // of work for a very small piece of functionality. :-/
     addSlowPathGenerator(std::make_unique<CallArrayAllocatorSlowPathGenerator>(
-            slowCases, this, operationNewArrayWithSize, resultGPR, storageGPR,
-            structure, numElements));
+        slowCases, this, operationNewArrayWithSize, resultGPR, storageGPR,
+        structure, numElements));
 }
 
-void SpeculativeJIT::emitAllocateArguments(GPRReg resultGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
+void SpeculativeJIT::emitGetLength(InlineCallFrame* inlineCallFrame, GPRReg lengthGPR, bool includeThis)
 {
-    Structure* structure = m_jit.graph().globalObjectFor(m_currentNode->origin.semantic)->argumentsStructure();
+    if (inlineCallFrame && !inlineCallFrame->isVarargs())
+        m_jit.move(TrustedImm32(inlineCallFrame->arguments.size() - !includeThis), lengthGPR);
+    else {
+        VirtualRegister argumentCountRegister;
+        if (!inlineCallFrame)
+            argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
+        else
+            argumentCountRegister = inlineCallFrame->argumentCountRegister;
+        m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), lengthGPR);
+        if (!includeThis)
+            m_jit.sub32(TrustedImm32(1), lengthGPR);
+    }
+}
 
-    m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), scratchGPR1);
-    m_jit.lshift32(TrustedImm32(3), scratchGPR1);
-    m_jit.add32(TrustedImm32(Arguments::offsetOfInlineRegisterArray()), scratchGPR1);
-    emitAllocateVariableSizedJSObject<Arguments>(resultGPR, TrustedImmPtr(structure), scratchGPR1, scratchGPR1, scratchGPR2, slowPath);
+void SpeculativeJIT::emitGetLength(CodeOrigin origin, GPRReg lengthGPR, bool includeThis)
+{
+    emitGetLength(origin.inlineCallFrame, lengthGPR, includeThis);
+}
 
-    m_jit.storePtr(TrustedImmPtr(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfActivation()));
+void SpeculativeJIT::emitGetCallee(CodeOrigin origin, GPRReg calleeGPR)
+{
+    if (origin.inlineCallFrame) {
+        if (origin.inlineCallFrame->isClosureCall) {
+            m_jit.loadPtr(
+                JITCompiler::addressFor(origin.inlineCallFrame->calleeRecovery.virtualRegister()),
+                calleeGPR);
+        } else {
+            m_jit.move(
+                TrustedImmPtr(origin.inlineCallFrame->calleeRecovery.constant().asCell()),
+                calleeGPR);
+        }
+    } else
+        m_jit.loadPtr(JITCompiler::addressFor(JSStack::Callee), calleeGPR);
+}
 
-    m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), scratchGPR1);
-    m_jit.sub32(TrustedImm32(1), scratchGPR1);
-    m_jit.store32(scratchGPR1, MacroAssembler::Address(resultGPR, Arguments::offsetOfNumArguments()));
-
-    m_jit.store32(TrustedImm32(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfOverrodeLength()));
-    if (m_jit.isStrictModeFor(m_currentNode->origin.semantic))
-        m_jit.store8(TrustedImm32(1), MacroAssembler::Address(resultGPR, Arguments::offsetOfIsStrictMode()));
-
-    m_jit.storePtr(GPRInfo::callFrameRegister, MacroAssembler::Address(resultGPR, Arguments::offsetOfRegisters()));
-    m_jit.storePtr(TrustedImmPtr(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfSlowArgumentData()));
-
-    m_jit.loadPtr(JITCompiler::addressFor(JSStack::Callee), scratchGPR1);
-    m_jit.storePtr(scratchGPR1, MacroAssembler::Address(resultGPR, Arguments::offsetOfCallee()));
-
+void SpeculativeJIT::emitGetArgumentStart(CodeOrigin origin, GPRReg startGPR)
+{
+    m_jit.addPtr(
+        TrustedImm32(
+            JITCompiler::argumentsStart(origin).offset() * static_cast<int>(sizeof(Register))),
+        GPRInfo::callFrameRegister, startGPR);
 }
 
 void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, MacroAssembler::Jump jumpToFail)
@@ -722,9 +744,12 @@
         noResult(m_currentNode);
         return;
     }
-    case Array::Arguments:
-        speculateCellTypeWithoutTypeFiltering(node->child1(), baseReg, ArgumentsType);
-
+    case Array::DirectArguments:
+        speculateCellTypeWithoutTypeFiltering(node->child1(), baseReg, DirectArgumentsType);
+        noResult(m_currentNode);
+        return;
+    case Array::ScopedArguments:
+        speculateCellTypeWithoutTypeFiltering(node->child1(), baseReg, ScopedArgumentsType);
         noResult(m_currentNode);
         return;
     default:
@@ -4098,7 +4123,50 @@
     int32Result(vectorGPR, node);
 }
 
-void SpeculativeJIT::compileGetByValOnArguments(Node* node)
+void SpeculativeJIT::compileGetByValOnDirectArguments(Node* node)
+{
+    SpeculateCellOperand base(this, node->child1());
+    SpeculateStrictInt32Operand property(this, node->child2());
+    GPRTemporary result(this);
+#if USE(JSVALUE32_64)
+    GPRTemporary resultTag(this);
+#endif
+    
+    GPRReg baseReg = base.gpr();
+    GPRReg propertyReg = property.gpr();
+    GPRReg resultReg = result.gpr();
+#if USE(JSVALUE32_64)
+    GPRReg resultTagReg = resultTag.gpr();
+    JSValueRegs resultRegs = JSValueRegs(resultTagReg, resultReg);
+#else
+    JSValueRegs resultRegs = JSValueRegs(resultReg);
+#endif
+    
+    if (!m_compileOkay)
+        return;
+    
+    ASSERT(ArrayMode(Array::DirectArguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
+    
+    speculationCheck(
+        ExoticObjectMode, JSValueSource(), 0,
+        m_jit.branchTestPtr(
+            MacroAssembler::NonZero,
+            MacroAssembler::Address(baseReg, DirectArguments::offsetOfOverrides())));
+    speculationCheck(
+        ExoticObjectMode, JSValueSource(), 0,
+        m_jit.branch32(
+            MacroAssembler::AboveOrEqual, propertyReg,
+            MacroAssembler::Address(baseReg, DirectArguments::offsetOfLength())));
+    
+    m_jit.loadValue(
+        MacroAssembler::BaseIndex(
+            baseReg, propertyReg, MacroAssembler::TimesEight, DirectArguments::storageOffset()),
+        resultRegs);
+    
+    jsValueResult(resultRegs, node);
+}
+
+void SpeculativeJIT::compileGetByValOnScopedArguments(Node* node)
 {
     SpeculateCellOperand base(this, node->child1());
     SpeculateStrictInt32Operand property(this, node->child2());
@@ -4107,86 +4175,74 @@
     GPRTemporary resultTag(this);
 #endif
     GPRTemporary scratch(this);
+    GPRTemporary scratch2(this);
     
     GPRReg baseReg = base.gpr();
     GPRReg propertyReg = property.gpr();
     GPRReg resultReg = result.gpr();
 #if USE(JSVALUE32_64)
     GPRReg resultTagReg = resultTag.gpr();
+    JSValueRegs resultRegs = JSValueRegs(resultTagReg, resultReg);
+#else
+    JSValueRegs resultRegs = JSValueRegs(resultReg);
 #endif
     GPRReg scratchReg = scratch.gpr();
+    GPRReg scratch2Reg = scratch2.gpr();
     
     if (!m_compileOkay)
         return;
-  
-    ASSERT(ArrayMode(Array::Arguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
     
-    // Two really lame checks.
+    ASSERT(ArrayMode(Array::ScopedArguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
+    
     speculationCheck(
-        ExoticObjectMode, JSValueSource(), 0,
+        ExoticObjectMode, JSValueSource(), nullptr,
         m_jit.branch32(
             MacroAssembler::AboveOrEqual, propertyReg,
-            MacroAssembler::Address(baseReg, Arguments::offsetOfNumArguments())));
-    speculationCheck(
-        ExoticObjectMode, JSValueSource(), 0,
-        m_jit.branchTestPtr(
-            MacroAssembler::NonZero,
-            MacroAssembler::Address(
-                baseReg, Arguments::offsetOfSlowArgumentData())));
+            MacroAssembler::Address(baseReg, ScopedArguments::offsetOfTotalLength())));
     
-    m_jit.move(propertyReg, resultReg);
-    m_jit.signExtend32ToPtr(resultReg, resultReg);
+    m_jit.loadPtr(MacroAssembler::Address(baseReg, ScopedArguments::offsetOfTable()), scratchReg);
+    m_jit.load32(
+        MacroAssembler::Address(scratchReg, ScopedArgumentsTable::offsetOfLength()), scratch2Reg);
+    
+    MacroAssembler::Jump overflowArgument = m_jit.branch32(
+        MacroAssembler::AboveOrEqual, propertyReg, scratch2Reg);
+    
+    m_jit.loadPtr(MacroAssembler::Address(baseReg, ScopedArguments::offsetOfScope()), scratch2Reg);
+
     m_jit.loadPtr(
-        MacroAssembler::Address(baseReg, Arguments::offsetOfRegisters()),
+        MacroAssembler::Address(scratchReg, ScopedArgumentsTable::offsetOfArguments()),
+        scratchReg);
+    m_jit.load32(
+        MacroAssembler::BaseIndex(scratchReg, propertyReg, MacroAssembler::TimesFour),
         scratchReg);
     
-#if USE(JSVALUE32_64)
-    m_jit.load32(
-        MacroAssembler::BaseIndex(
-            scratchReg, resultReg, MacroAssembler::TimesEight,
-            CallFrame::thisArgumentOffset() * sizeof(Register) + sizeof(Register) +
-            OBJECT_OFFSETOF(JSValue, u.asBits.tag)),
-        resultTagReg);
-    m_jit.load32(
-        MacroAssembler::BaseIndex(
-            scratchReg, resultReg, MacroAssembler::TimesEight,
-            CallFrame::thisArgumentOffset() * sizeof(Register) + sizeof(Register) +
-            OBJECT_OFFSETOF(JSValue, u.asBits.payload)),
-        resultReg);
-    jsValueResult(resultTagReg, resultReg, node);
-#else
-    m_jit.load64(
-        MacroAssembler::BaseIndex(
-            scratchReg, resultReg, MacroAssembler::TimesEight,
-            CallFrame::thisArgumentOffset() * sizeof(Register) + sizeof(Register)),
-        resultReg);
-    jsValueResult(resultReg, node);
-#endif
-}
-
-void SpeculativeJIT::compileGetArgumentsLength(Node* node)
-{
-    SpeculateCellOperand base(this, node->child1());
-    GPRTemporary result(this, Reuse, base);
-    
-    GPRReg baseReg = base.gpr();
-    GPRReg resultReg = result.gpr();
-    
-    if (!m_compileOkay)
-        return;
-    
-    ASSERT(ArrayMode(Array::Arguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
-    
     speculationCheck(
-        ExoticObjectMode, JSValueSource(), 0,
-        m_jit.branchTest8(
-            MacroAssembler::NonZero,
-            MacroAssembler::Address(baseReg, Arguments::offsetOfOverrodeLength())));
+        ExoticObjectMode, JSValueSource(), nullptr,
+        m_jit.branch32(
+            MacroAssembler::Equal, scratchReg, TrustedImm32(ScopeOffset::invalidOffset)));
     
-    m_jit.load32(
-        MacroAssembler::Address(baseReg, Arguments::offsetOfNumArguments()),
-        resultReg);
-    int32Result(resultReg, node);
+    m_jit.loadValue(
+        MacroAssembler::BaseIndex(
+            scratch2Reg, propertyReg, MacroAssembler::TimesEight,
+            JSEnvironmentRecord::offsetOfVariables()),
+        resultRegs);
+    
+    MacroAssembler::Jump done = m_jit.jump();
+    overflowArgument.link(&m_jit);
+    
+    m_jit.sub32(propertyReg, scratch2Reg);
+    m_jit.neg32(scratch2Reg);
+    
+    m_jit.loadValue(
+        MacroAssembler::BaseIndex(
+            baseReg, scratch2Reg, MacroAssembler::TimesEight,
+            ScopedArguments::overflowStorageOffset()),
+        resultRegs);
+    speculationCheck(ExoticObjectMode, JSValueSource(), nullptr, m_jit.branchIsEmpty(resultRegs));
+    
+    done.link(&m_jit);
+    
+    jsValueResult(resultRegs, node);
 }
 
 void SpeculativeJIT::compileGetScope(Node* node)
@@ -4242,8 +4298,52 @@
         int32Result(resultGPR, node);
         break;
     }
-    case Array::Arguments: {
-        compileGetArgumentsLength(node);
+    case Array::DirectArguments: {
+        SpeculateCellOperand base(this, node->child1());
+        GPRTemporary result(this, Reuse, base);
+        
+        GPRReg baseReg = base.gpr();
+        GPRReg resultReg = result.gpr();
+        
+        if (!m_compileOkay)
+            return;
+        
+        ASSERT(ArrayMode(Array::DirectArguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
+        
+        speculationCheck(
+            ExoticObjectMode, JSValueSource(), 0,
+            m_jit.branchTestPtr(
+                MacroAssembler::NonZero,
+                MacroAssembler::Address(baseReg, DirectArguments::offsetOfOverrides())));
+        
+        m_jit.load32(
+            MacroAssembler::Address(baseReg, DirectArguments::offsetOfLength()), resultReg);
+        
+        int32Result(resultReg, node);
+        break;
+    }
+    case Array::ScopedArguments: {
+        SpeculateCellOperand base(this, node->child1());
+        GPRTemporary result(this, Reuse, base);
+        
+        GPRReg baseReg = base.gpr();
+        GPRReg resultReg = result.gpr();
+        
+        if (!m_compileOkay)
+            return;
+        
+        ASSERT(ArrayMode(Array::ScopedArguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
+        
+        speculationCheck(
+            ExoticObjectMode, JSValueSource(), 0,
+            m_jit.branchTest8(
+                MacroAssembler::NonZero,
+                MacroAssembler::Address(baseReg, ScopedArguments::offsetOfOverrodeThings())));
+        
+        m_jit.load32(
+            MacroAssembler::Address(baseReg, ScopedArguments::offsetOfTotalLength()), resultReg);
+        
+        int32Result(resultReg, node);
         break;
     }
     default: {
@@ -4258,7 +4358,7 @@
     } }
 }
 
-void SpeculativeJIT::compileNewFunctionNoCheck(Node* node)
+void SpeculativeJIT::compileNewFunction(Node* node)
 {
     GPRFlushedCallResult result(this);
     GPRReg resultGPR = result.gpr();
@@ -4266,21 +4366,349 @@
     GPRReg scopeGPR = scope.gpr();
     flushRegisters();
     callOperation(
-        operationNewFunctionNoCheck, resultGPR, scopeGPR,
-        node->castOperand<FunctionExecutable*>());
+        operationNewFunction, resultGPR, scopeGPR, node->castOperand<FunctionExecutable*>());
     cellResult(resultGPR, node);
 }
 
-void SpeculativeJIT::compileNewFunctionExpression(Node* node)
+void SpeculativeJIT::compileForwardVarargs(Node* node)
+{
+    LoadVarargsData* data = node->loadVarargsData();
+    InlineCallFrame* inlineCallFrame = node->child1()->origin.semantic.inlineCallFrame;
+        
+    GPRTemporary length(this);
+    JSValueRegsTemporary temp(this);
+    GPRReg lengthGPR = length.gpr();
+    JSValueRegs tempRegs = temp.regs();
+        
+    emitGetLength(inlineCallFrame, lengthGPR, /* includeThis = */ true);
+    if (data->offset)
+        m_jit.sub32(TrustedImm32(data->offset), lengthGPR);
+        
+    speculationCheck(
+        VarargsOverflow, JSValueSource(), Edge(), m_jit.branch32(
+            MacroAssembler::Above,
+            lengthGPR, TrustedImm32(data->limit)));
+        
+    m_jit.store32(lengthGPR, JITCompiler::payloadFor(data->machineCount));
+        
+    VirtualRegister sourceStart = JITCompiler::argumentsStart(inlineCallFrame) + data->offset;
+    VirtualRegister targetStart = data->machineStart;
+
+    m_jit.sub32(TrustedImm32(1), lengthGPR);
+        
+    // First have a loop that fills in the undefined slots in case of an arity check failure.
+    m_jit.move(TrustedImm32(data->mandatoryMinimum), tempRegs.payloadGPR());
+    JITCompiler::Jump done = m_jit.branch32(JITCompiler::BelowOrEqual, tempRegs.payloadGPR(), lengthGPR);
+        
+    JITCompiler::Label loop = m_jit.label();
+    m_jit.sub32(TrustedImm32(1), tempRegs.payloadGPR());
+    m_jit.storeTrustedValue(
+        jsUndefined(),
+        JITCompiler::BaseIndex(
+            GPRInfo::callFrameRegister, tempRegs.payloadGPR(), JITCompiler::TimesEight,
+            targetStart.offset() * sizeof(EncodedJSValue)));
+    m_jit.branch32(JITCompiler::Above, tempRegs.payloadGPR(), lengthGPR).linkTo(loop, &m_jit);
+    done.link(&m_jit);
+        
+    // And then fill in the actual argument values.
+    done = m_jit.branchTest32(JITCompiler::Zero, lengthGPR);
+        
+    loop = m_jit.label();
+    m_jit.sub32(TrustedImm32(1), lengthGPR);
+    m_jit.loadValue(
+        JITCompiler::BaseIndex(
+            GPRInfo::callFrameRegister, lengthGPR, JITCompiler::TimesEight,
+            sourceStart.offset() * sizeof(EncodedJSValue)),
+        tempRegs);
+    m_jit.storeValue(
+        tempRegs,
+        JITCompiler::BaseIndex(
+            GPRInfo::callFrameRegister, lengthGPR, JITCompiler::TimesEight,
+            targetStart.offset() * sizeof(EncodedJSValue)));
+    m_jit.branchTest32(JITCompiler::NonZero, lengthGPR).linkTo(loop, &m_jit);
+        
+    done.link(&m_jit);
+        
+    noResult(node);
+}
+
+void SpeculativeJIT::compileCreateActivation(Node* node)
+{
+    SpeculateCellOperand scope(this, node->child1());
+    GPRTemporary result(this);
+    GPRTemporary scratch1(this);
+    GPRTemporary scratch2(this);
+    GPRReg scopeGPR = scope.gpr();
+    GPRReg resultGPR = result.gpr();
+    GPRReg scratch1GPR = scratch1.gpr();
+    GPRReg scratch2GPR = scratch2.gpr();
+        
+    SymbolTable* table = m_jit.graph().symbolTableFor(node->origin.semantic);
+    Structure* structure = m_jit.graph().globalObjectFor(
+        node->origin.semantic)->activationStructure();
+        
+    JITCompiler::JumpList slowPath;
+    emitAllocateJSObjectWithKnownSize<JSLexicalEnvironment>(
+        resultGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratch1GPR, scratch2GPR,
+        slowPath, JSLexicalEnvironment::allocationSize(table));
+        
+    // Don't need a memory barriers since we just fast-created the activation, so the
+    // activation must be young.
+    m_jit.storePtr(scopeGPR, JITCompiler::Address(resultGPR, JSScope::offsetOfNext()));
+    m_jit.storePtr(
+        TrustedImmPtr(table),
+        JITCompiler::Address(resultGPR, JSLexicalEnvironment::offsetOfSymbolTable()));
+        
+    // Must initialize all members to undefined.
+    for (unsigned i = 0; i < table->scopeSize(); ++i) {
+        m_jit.storeTrustedValue(
+            jsUndefined(),
+            JITCompiler::Address(
+                resultGPR, JSLexicalEnvironment::offsetOfVariable(ScopeOffset(i))));
+    }
+
+    addSlowPathGenerator(
+        slowPathCall(
+            slowPath, this, operationCreateActivationDirect, resultGPR, structure, scopeGPR, table));
+
+    cellResult(resultGPR, node);
+}
+
+void SpeculativeJIT::compileCreateDirectArguments(Node* node)
+{
+    // FIXME: A more effective way of dealing with the argument count and callee is to have
+    // them be explicit arguments to this node.
+    // https://bugs.webkit.org/show_bug.cgi?id=142207
+    
+    GPRTemporary result(this);
+    GPRTemporary scratch1(this);
+    GPRTemporary scratch2(this);
+    GPRTemporary length;
+    GPRReg resultGPR = result.gpr();
+    GPRReg scratch1GPR = scratch1.gpr();
+    GPRReg scratch2GPR = scratch2.gpr();
+    GPRReg lengthGPR = InvalidGPRReg;
+    JSValueRegs valueRegs = JSValueRegs::withTwoAvailableRegs(scratch1GPR, scratch2GPR);
+        
+    unsigned minCapacity = m_jit.graph().baselineCodeBlockFor(node->origin.semantic)->numParameters() - 1;
+        
+    unsigned knownLength;
+    bool lengthIsKnown; // if false, lengthGPR will have the length.
+    if (node->origin.semantic.inlineCallFrame
+        && !node->origin.semantic.inlineCallFrame->isVarargs()) {
+        knownLength = node->origin.semantic.inlineCallFrame->arguments.size() - 1;
+        lengthIsKnown = true;
+    } else {
+        knownLength = UINT_MAX;
+        lengthIsKnown = false;
+            
+        GPRTemporary realLength(this);
+        length.adopt(realLength);
+        lengthGPR = length.gpr();
+
+        VirtualRegister argumentCountRegister;
+        if (!node->origin.semantic.inlineCallFrame)
+            argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
+        else
+            argumentCountRegister = node->origin.semantic.inlineCallFrame->argumentCountRegister;
+        m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), lengthGPR);
+        m_jit.sub32(TrustedImm32(1), lengthGPR);
+    }
+        
+    Structure* structure =
+        m_jit.graph().globalObjectFor(node->origin.semantic)->directArgumentsStructure();
+        
+    // Use a different strategy for allocating the object depending on whether we know its
+    // size statically.
+    JITCompiler::JumpList slowPath;
+    if (lengthIsKnown) {
+        emitAllocateJSObjectWithKnownSize<DirectArguments>(
+            resultGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratch1GPR, scratch2GPR,
+            slowPath, DirectArguments::allocationSize(std::max(knownLength, minCapacity)));
+            
+        m_jit.store32(
+            TrustedImm32(knownLength),
+            JITCompiler::Address(resultGPR, DirectArguments::offsetOfLength()));
+    } else {
+        JITCompiler::Jump tooFewArguments;
+        if (minCapacity) {
+            tooFewArguments =
+                m_jit.branch32(JITCompiler::Below, lengthGPR, TrustedImm32(minCapacity));
+        }
+        m_jit.lshift32(lengthGPR, TrustedImm32(3), scratch1GPR);
+        m_jit.add32(TrustedImm32(DirectArguments::storageOffset()), scratch1GPR);
+        if (minCapacity) {
+            JITCompiler::Jump done = m_jit.jump();
+            tooFewArguments.link(&m_jit);
+            m_jit.move(TrustedImm32(DirectArguments::allocationSize(minCapacity)), scratch1GPR);
+            done.link(&m_jit);
+        }
+            
+        emitAllocateVariableSizedJSObject<DirectArguments>(
+            resultGPR, TrustedImmPtr(structure), scratch1GPR, scratch1GPR, scratch2GPR,
+            slowPath);
+            
+        m_jit.store32(
+            lengthGPR, JITCompiler::Address(resultGPR, DirectArguments::offsetOfLength()));
+    }
+        
+    m_jit.store32(
+        TrustedImm32(minCapacity),
+        JITCompiler::Address(resultGPR, DirectArguments::offsetOfMinCapacity()));
+        
+    m_jit.storePtr(
+        TrustedImmPtr(0), JITCompiler::Address(resultGPR, DirectArguments::offsetOfOverrides()));
+        
+    if (lengthIsKnown) {
+        addSlowPathGenerator(
+            slowPathCall(
+                slowPath, this, operationCreateDirectArguments, resultGPR, structure,
+                knownLength, minCapacity));
+    } else {
+        auto generator = std::make_unique<CallCreateDirectArgumentsSlowPathGenerator>(
+            slowPath, this, resultGPR, structure, lengthGPR, minCapacity);
+        addSlowPathGenerator(WTF::move(generator));
+    }
+        
+    if (node->origin.semantic.inlineCallFrame) {
+        if (node->origin.semantic.inlineCallFrame->isClosureCall) {
+            m_jit.loadPtr(
+                JITCompiler::addressFor(
+                    node->origin.semantic.inlineCallFrame->calleeRecovery.virtualRegister()),
+                scratch1GPR);
+        } else {
+            m_jit.move(
+                TrustedImmPtr(
+                    node->origin.semantic.inlineCallFrame->calleeRecovery.constant().asCell()),
+                scratch1GPR);
+        }
+    } else
+        m_jit.loadPtr(JITCompiler::addressFor(JSStack::Callee), scratch1GPR);
+
+    // Don't need a memory barriers since we just fast-created the activation, so the
+    // activation must be young.
+    m_jit.storePtr(
+        scratch1GPR, JITCompiler::Address(resultGPR, DirectArguments::offsetOfCallee()));
+        
+    VirtualRegister start = m_jit.argumentsStart(node->origin.semantic);
+    if (lengthIsKnown) {
+        for (unsigned i = 0; i < std::max(knownLength, minCapacity); ++i) {
+            m_jit.loadValue(JITCompiler::addressFor(start + i), valueRegs);
+            m_jit.storeValue(
+                valueRegs, JITCompiler::Address(resultGPR, DirectArguments::offsetOfSlot(i)));
+        }
+    } else {
+        JITCompiler::Jump done;
+        if (minCapacity) {
+            JITCompiler::Jump startLoop = m_jit.branch32(
+                JITCompiler::AboveOrEqual, lengthGPR, TrustedImm32(minCapacity));
+            m_jit.move(TrustedImm32(minCapacity), lengthGPR);
+            startLoop.link(&m_jit);
+        } else
+            done = m_jit.branchTest32(MacroAssembler::Zero, lengthGPR);
+        JITCompiler::Label loop = m_jit.label();
+        m_jit.sub32(TrustedImm32(1), lengthGPR);
+        m_jit.loadValue(
+            JITCompiler::BaseIndex(
+                GPRInfo::callFrameRegister, lengthGPR, JITCompiler::TimesEight,
+                start.offset() * static_cast<int>(sizeof(Register))),
+            valueRegs);
+        m_jit.storeValue(
+            valueRegs,
+            JITCompiler::BaseIndex(
+                resultGPR, lengthGPR, JITCompiler::TimesEight,
+                DirectArguments::storageOffset()));
+        m_jit.branchTest32(MacroAssembler::NonZero, lengthGPR).linkTo(loop, &m_jit);
+        if (done.isSet())
+            done.link(&m_jit);
+    }
+        
+    cellResult(resultGPR, node);
+}
+
+void SpeculativeJIT::compileGetFromArguments(Node* node)
+{
+    SpeculateCellOperand arguments(this, node->child1());
+    JSValueRegsTemporary result(this);
+    
+    GPRReg argumentsGPR = arguments.gpr();
+    JSValueRegs resultRegs = result.regs();
+    
+    m_jit.loadValue(JITCompiler::Address(argumentsGPR, DirectArguments::offsetOfSlot(node->capturedArgumentsOffset().offset())), resultRegs);
+    jsValueResult(resultRegs, node);
+}
+
+void SpeculativeJIT::compilePutToArguments(Node* node)
+{
+    SpeculateCellOperand arguments(this, node->child1());
+    JSValueOperand value(this, node->child2());
+    
+    GPRReg argumentsGPR = arguments.gpr();
+    JSValueRegs valueRegs = value.jsValueRegs();
+    
+    m_jit.storeValue(valueRegs, JITCompiler::Address(argumentsGPR, DirectArguments::offsetOfSlot(node->capturedArgumentsOffset().offset())));
+    noResult(node);
+}
+
+void SpeculativeJIT::compileCreateScopedArguments(Node* node)
+{
+    SpeculateCellOperand scope(this, node->child1());
+    GPRReg scopeGPR = scope.gpr();
+    
+    GPRFlushedCallResult result(this);
+    GPRReg resultGPR = result.gpr();
+    flushRegisters();
+    
+    // We set up the arguments ourselves, because we have the whole register file and we can
+    // set them up directly into the argument registers. This also means that we don't have to
+    // invent a four-argument-register shuffle.
+    
+    // Arguments: 0:exec, 1:structure, 2:start, 3:length, 4:callee, 5:scope
+    
+    // Do the scopeGPR first, since it might alias an argument register.
+    m_jit.setupArgument(5, [&] (GPRReg destGPR) { m_jit.move(scopeGPR, destGPR); });
+    
+    // These other things could be done in any order.
+    m_jit.setupArgument(4, [&] (GPRReg destGPR) { emitGetCallee(node->origin.semantic, destGPR); });
+    m_jit.setupArgument(3, [&] (GPRReg destGPR) { emitGetLength(node->origin.semantic, destGPR); });
+    m_jit.setupArgument(2, [&] (GPRReg destGPR) { emitGetArgumentStart(node->origin.semantic, destGPR); });
+    m_jit.setupArgument(
+        1, [&] (GPRReg destGPR) {
+            m_jit.move(
+                TrustedImmPtr(m_jit.globalObjectFor(node->origin.semantic)->scopedArgumentsStructure()),
+                destGPR);
+        });
+    m_jit.setupArgument(0, [&] (GPRReg destGPR) { m_jit.move(GPRInfo::callFrameRegister, destGPR); });
+    
+    appendCallWithExceptionCheckSetResult(operationCreateScopedArguments, resultGPR);
+    
+    cellResult(resultGPR, node);
+}
+
+void SpeculativeJIT::compileCreateClonedArguments(Node* node)
 {
     GPRFlushedCallResult result(this);
     GPRReg resultGPR = result.gpr();
-    SpeculateCellOperand scope(this, node->child1());
-    GPRReg scopeGPR = scope.gpr();
     flushRegisters();
-    callOperation(
-        operationNewFunctionNoCheck,
-        resultGPR, scopeGPR,  node->castOperand<FunctionExecutable*>());
+    
+    // We set up the arguments ourselves, because we have the whole register file and we can
+    // set them up directly into the argument registers.
+    
+    // Arguments: 0:exec, 1:structure, 2:start, 3:length, 4:callee
+    m_jit.setupArgument(4, [&] (GPRReg destGPR) { emitGetCallee(node->origin.semantic, destGPR); });
+    m_jit.setupArgument(3, [&] (GPRReg destGPR) { emitGetLength(node->origin.semantic, destGPR); });
+    m_jit.setupArgument(2, [&] (GPRReg destGPR) { emitGetArgumentStart(node->origin.semantic, destGPR); });
+    m_jit.setupArgument(
+        1, [&] (GPRReg destGPR) {
+            m_jit.move(
+                TrustedImmPtr(
+                    m_jit.globalObjectFor(node->origin.semantic)->outOfBandArgumentsStructure()),
+                destGPR);
+        });
+    m_jit.setupArgument(0, [&] (GPRReg destGPR) { m_jit.move(GPRInfo::callFrameRegister, destGPR); });
+    
+    appendCallWithExceptionCheckSetResult(operationCreateClonedArguments, resultGPR);
+    
     cellResult(resultGPR, node);
 }
 
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
index 0e5d03d..9e064b2 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
@@ -717,12 +717,6 @@
     
     void emitCall(Node*);
     
-    int32_t framePointerOffsetToGetActivationRegisters()
-    {
-        return m_jit.codeBlock()->framePointerOffsetToGetActivationRegisters(
-            m_jit.graph().m_machineCaptureStart);
-    }
-    
     // Called once a node has completed code generation but prior to setting
     // its result, to free up its children. (This must happen prior to setting
     // the nodes result, since the node may have the same VirtualRegister as
@@ -902,7 +896,7 @@
     JITCompiler::Call callOperation(V_JITOperation_E operation)
     {
         m_jit.setupArgumentsExecState();
-        return appendCall(operation);
+        return appendCallWithExceptionCheck(operation);
     }
     JITCompiler::Call callOperation(P_JITOperation_E operation, GPRReg result)
     {
@@ -1019,6 +1013,31 @@
         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
         return appendCallWithExceptionCheckSetResult(operation, result);
     }
+    JITCompiler::Call callOperation(C_JITOperation_EStJscSymtab operation, GPRReg result, Structure* structure, GPRReg scope, SymbolTable* table)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), scope, TrustedImmPtr(table));
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(C_JITOperation_EStZ operation, GPRReg result, Structure* structure, unsigned knownLength)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(knownLength));
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(C_JITOperation_EStZZ operation, GPRReg result, Structure* structure, unsigned knownLength, unsigned minCapacity)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(knownLength), TrustedImm32(minCapacity));
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(C_JITOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg length)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), length);
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+    JITCompiler::Call callOperation(C_JITOperation_EStZZ operation, GPRReg result, Structure* structure, GPRReg length, unsigned minCapacity)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), length, TrustedImm32(minCapacity));
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
     JITCompiler::Call callOperation(C_JITOperation_EJssSt operation, GPRReg result, GPRReg arg1, Structure* structure)
     {
         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(structure));
@@ -1175,6 +1194,12 @@
         return appendCallWithExceptionCheckSetResult(operation, result);
     }
 
+    JITCompiler::Call callOperation(J_JITOperation_EJscC operation, GPRReg result, GPRReg arg1, JSCell* cell)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
+        return appendCallWithExceptionCheckSetResult(operation, result);
+    }
+
 #if USE(JSVALUE64)
     JITCompiler::Call callOperation(J_JITOperation_E operation, GPRReg result)
     {
@@ -1248,11 +1273,6 @@
         m_jit.setupArgumentsWithExecState(arg1, arg2);
         return appendCallWithExceptionCheckSetResult(operation, result);
     }
-    JITCompiler::Call callOperation(J_JITOperation_EJscC operation, GPRReg result, GPRReg arg1, JSCell* cell)
-    {
-        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
-        return appendCallWithExceptionCheckSetResult(operation, result);
-    }
     JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg result, StructureStubInfo* stubInfo, GPRReg arg1, const StringImpl* uid)
     {
         m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
@@ -2152,8 +2172,9 @@
     void compileGetByValOnString(Node*);
     void compileFromCharCode(Node*); 
 
-    void compileGetByValOnArguments(Node*);
-    void compileGetArgumentsLength(Node*);
+    void compileGetByValOnDirectArguments(Node*);
+    void compileGetByValOnScopedArguments(Node*);
+    
     void compileGetScope(Node*);
     void compileSkipScope(Node*);
 
@@ -2184,8 +2205,14 @@
     void compilePutByValForIntTypedArray(GPRReg base, GPRReg property, Node*, TypedArrayType);
     void compileGetByValOnFloatTypedArray(Node*, TypedArrayType);
     void compilePutByValForFloatTypedArray(GPRReg base, GPRReg property, Node*, TypedArrayType);
-    void compileNewFunctionNoCheck(Node*);
-    void compileNewFunctionExpression(Node*);
+    void compileNewFunction(Node*);
+    void compileForwardVarargs(Node*);
+    void compileCreateActivation(Node*);
+    void compileCreateDirectArguments(Node*);
+    void compileGetFromArguments(Node*);
+    void compilePutToArguments(Node*);
+    void compileCreateScopedArguments(Node*);
+    void compileCreateClonedArguments(Node*);
     bool compileRegExpExec(Node*);
     
     JITCompiler::Jump branchIsCell(JSValueRegs);
@@ -2254,15 +2281,24 @@
         m_jit.storePtr(storage, MacroAssembler::Address(resultGPR, JSObject::butterflyOffset()));
     }
 
+    template <typename ClassType, typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
+    void emitAllocateJSObjectWithKnownSize(
+        GPRReg resultGPR, StructureType structure, StorageType storage, GPRReg scratchGPR1,
+        GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath, size_t size)
+    {
+        MarkedAllocator* allocator = &m_jit.vm()->heap.allocatorForObjectOfType<ClassType>(size);
+        m_jit.move(TrustedImmPtr(allocator), scratchGPR1);
+        emitAllocateJSObject(resultGPR, scratchGPR1, structure, storage, scratchGPR2, slowPath);
+    }
+
     // Convenience allocator for a built-in object.
     template <typename ClassType, typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
     void emitAllocateJSObject(GPRReg resultGPR, StructureType structure, StorageType storage,
         GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
     {
-        size_t size = ClassType::allocationSize(0);
-        MarkedAllocator* allocator = &m_jit.vm()->heap.allocatorForObjectOfType<ClassType>(size);
-        m_jit.move(TrustedImmPtr(allocator), scratchGPR1);
-        emitAllocateJSObject(resultGPR, scratchGPR1, structure, storage, scratchGPR2, slowPath);
+        emitAllocateJSObjectWithKnownSize<ClassType>(
+            resultGPR, structure, storage, scratchGPR1, scratchGPR2, slowPath,
+            ClassType::allocationSize(0));
     }
 
     template <typename ClassType, typename StructureType> // StructureType and StorageType can be GPR or ImmPtr.
@@ -2299,8 +2335,12 @@
     }
 
     void emitAllocateJSArray(GPRReg resultGPR, Structure*, GPRReg storageGPR, unsigned numElements);
-    void emitAllocateArguments(GPRReg resultGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath);
-
+    
+    void emitGetLength(InlineCallFrame*, GPRReg lengthGPR, bool includeThis = false);
+    void emitGetLength(CodeOrigin, GPRReg lengthGPR, bool includeThis = false);
+    void emitGetCallee(CodeOrigin, GPRReg calleeGPR);
+    void emitGetArgumentStart(CodeOrigin, GPRReg startGPR);
+    
     // Add a speculation check.
     void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail);
     void speculationCheck(ExitKind, JSValueSource, Node*, const MacroAssembler::JumpList& jumpsToFail);
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
index b624de4..ff58834 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
@@ -35,7 +35,9 @@
 #include "DFGOperations.h"
 #include "DFGSlowPathGenerator.h"
 #include "Debugger.h"
+#include "DirectArguments.h"
 #include "GetterSetter.h"
+#include "JSEnvironmentRecord.h"
 #include "JSLexicalEnvironment.h"
 #include "JSPropertyNameEnumerator.h"
 #include "ObjectPrototype.h"
@@ -640,18 +642,16 @@
 void SpeculativeJIT::emitCall(Node* node)
 {
     CallLinkInfo::CallType callType;
-    bool isVarargs;
+    bool isVarargs = false;
+    bool isForwardVarargs = false;
     switch (node->op()) {
     case Call:
         callType = CallLinkInfo::Call;
-        isVarargs = false;
         break;
     case Construct:
         callType = CallLinkInfo::Construct;
-        isVarargs = false;
         break;
     case CallVarargs:
-    case CallForwardVarargs:
         callType = CallLinkInfo::CallVarargs;
         isVarargs = true;
         break;
@@ -659,6 +659,14 @@
         callType = CallLinkInfo::ConstructVarargs;
         isVarargs = true;
         break;
+    case CallForwardVarargs:
+        callType = CallLinkInfo::CallVarargs;
+        isForwardVarargs = true;
+        break;
+    case ConstructForwardVarargs:
+        callType = CallLinkInfo::ConstructVarargs;
+        isForwardVarargs = true;
+        break;
     default:
         DFG_CRASH(m_jit.graph(), node, "bad node type");
         break;
@@ -667,33 +675,41 @@
     Edge calleeEdge = m_jit.graph().child(node, 0);
     
     // Gotta load the arguments somehow. Varargs is trickier.
-    if (isVarargs) {
+    if (isVarargs || isForwardVarargs) {
         CallVarargsData* data = node->callVarargsData();
 
-        GPRReg argumentsPayloadGPR;
-        GPRReg argumentsTagGPR;
-        GPRReg scratchGPR1;
-        GPRReg scratchGPR2;
-        GPRReg scratchGPR3;
+        GPRReg resultGPR;
+        unsigned numUsedStackSlots = m_jit.graph().m_nextMachineLocal;
         
-        if (node->op() == CallForwardVarargs) {
-            // We avoid calling flushRegisters() inside the control flow of CallForwardVarargs.
+        if (isForwardVarargs) {
             flushRegisters();
-        }
+            use(node->child2());
+            
+            GPRReg scratchGPR1;
+            GPRReg scratchGPR2;
+            GPRReg scratchGPR3;
+            
+            scratchGPR1 = JITCompiler::selectScratchGPR();
+            scratchGPR2 = JITCompiler::selectScratchGPR(scratchGPR1);
+            scratchGPR3 = JITCompiler::selectScratchGPR(scratchGPR1, scratchGPR2);
+            
+            m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR2);
+            JITCompiler::JumpList slowCase;
+            emitSetupVarargsFrameFastCase(m_jit, scratchGPR2, scratchGPR1, scratchGPR2, scratchGPR3, node->child2()->origin.semantic.inlineCallFrame, data->firstVarArgOffset, slowCase);
+            JITCompiler::Jump done = m_jit.jump();
+            slowCase.link(&m_jit);
+            callOperation(operationThrowStackOverflowForVarargs);
+            m_jit.abortWithReason(DFGVarargsThrowingPathDidNotThrow);
+            done.link(&m_jit);
+            resultGPR = scratchGPR2;
+        } else {
+            GPRReg argumentsPayloadGPR;
+            GPRReg argumentsTagGPR;
+            GPRReg scratchGPR1;
+            GPRReg scratchGPR2;
+            GPRReg scratchGPR3;
         
-        auto loadArgumentsGPR = [&] (GPRReg reservedGPR) {
-            if (node->op() == CallForwardVarargs) {
-                argumentsTagGPR = JITCompiler::selectScratchGPR(reservedGPR);
-                argumentsPayloadGPR = JITCompiler::selectScratchGPR(reservedGPR, argumentsTagGPR);
-                m_jit.load32(
-                    JITCompiler::tagFor(
-                        m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
-                    argumentsTagGPR);
-                m_jit.load32(
-                    JITCompiler::payloadFor(
-                        m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
-                    argumentsPayloadGPR);
-            } else {
+            auto loadArgumentsGPR = [&] (GPRReg reservedGPR) {
                 if (reservedGPR != InvalidGPRReg)
                     lock(reservedGPR);
                 JSValueOperand arguments(this, node->child2());
@@ -702,72 +718,37 @@
                 if (reservedGPR != InvalidGPRReg)
                     unlock(reservedGPR);
                 flushRegisters();
-            }
+                
+                scratchGPR1 = JITCompiler::selectScratchGPR(argumentsPayloadGPR, argumentsTagGPR, reservedGPR);
+                scratchGPR2 = JITCompiler::selectScratchGPR(argumentsPayloadGPR, argumentsTagGPR, scratchGPR1, reservedGPR);
+                scratchGPR3 = JITCompiler::selectScratchGPR(argumentsPayloadGPR, argumentsTagGPR, scratchGPR1, scratchGPR2, reservedGPR);
+            };
             
-            scratchGPR1 = JITCompiler::selectScratchGPR(argumentsPayloadGPR, argumentsTagGPR, reservedGPR);
-            scratchGPR2 = JITCompiler::selectScratchGPR(argumentsPayloadGPR, argumentsTagGPR, scratchGPR1, reservedGPR);
-            scratchGPR3 = JITCompiler::selectScratchGPR(argumentsPayloadGPR, argumentsTagGPR, scratchGPR1, scratchGPR2, reservedGPR);
-        };
+            loadArgumentsGPR(InvalidGPRReg);
         
-        loadArgumentsGPR(InvalidGPRReg);
-        
-        // At this point we have the whole register file to ourselves, and argumentsGPR has the
-        // arguments register. Select some scratch registers.
-        
-        // We will use scratchGPR2 to point to our stack frame.
-        
-        unsigned numUsedStackSlots = m_jit.graph().m_nextMachineLocal;
-        
-        JITCompiler::Jump haveArguments;
-        GPRReg resultGPR = GPRInfo::regT0;
-        if (node->op() == CallForwardVarargs) {
-            // Do the horrific foo.apply(this, arguments) optimization.
-            // FIXME: do this optimization at the IR level instead of dynamically by testing the
-            // arguments register. This will happen once we get rid of the arguments lazy creation and
-            // lazy tear-off.
-            
-            JITCompiler::JumpList slowCase;
-            slowCase.append(
-                m_jit.branch32(
-                    JITCompiler::NotEqual,
-                    argumentsTagGPR, TrustedImm32(JSValue::EmptyValueTag)));
-            
-            m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR2);
-            emitSetupVarargsFrameFastCase(m_jit, scratchGPR2, scratchGPR1, scratchGPR2, scratchGPR3, node->origin.semantic.inlineCallFrame, data->firstVarArgOffset, slowCase);
-            resultGPR = scratchGPR2;
-            
-            haveArguments = m_jit.jump();
-            slowCase.link(&m_jit);
-        }
+            DFG_ASSERT(m_jit.graph(), node, isFlushed());
 
-        DFG_ASSERT(m_jit.graph(), node, isFlushed());
-        
-        // Right now, arguments is in argumentsTagGPR/argumentsPayloadGPR and the register file is
-        // flushed.
-        callOperation(operationSizeFrameForVarargs, GPRInfo::returnValueGPR, argumentsTagGPR, argumentsPayloadGPR, numUsedStackSlots, data->firstVarArgOffset);
-        
-        // Now we have the argument count of the callee frame, but we've lost the arguments operand.
-        // Reconstruct the arguments operand while preserving the callee frame.
-        loadArgumentsGPR(GPRInfo::returnValueGPR);
-        m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR1);
-        emitSetVarargsFrame(m_jit, GPRInfo::returnValueGPR, false, scratchGPR1, scratchGPR1);
-        m_jit.addPtr(TrustedImm32(-(sizeof(CallerFrameAndPC) + WTF::roundUpToMultipleOf(stackAlignmentBytes(), 6 * sizeof(void*)))), scratchGPR1, JITCompiler::stackPointerRegister);
-        
-        callOperation(operationSetupVarargsFrame, GPRInfo::returnValueGPR, scratchGPR1, argumentsTagGPR, argumentsPayloadGPR, data->firstVarArgOffset, GPRInfo::returnValueGPR);
-        m_jit.move(GPRInfo::returnValueGPR, resultGPR);
-        
-        if (node->op() == CallForwardVarargs)
-            haveArguments.link(&m_jit);
-        
+            // Right now, arguments is in argumentsTagGPR/argumentsPayloadGPR and the register file is
+            // flushed.
+            callOperation(operationSizeFrameForVarargs, GPRInfo::returnValueGPR, argumentsTagGPR, argumentsPayloadGPR, numUsedStackSlots, data->firstVarArgOffset);
+            
+            // Now we have the argument count of the callee frame, but we've lost the arguments operand.
+            // Reconstruct the arguments operand while preserving the callee frame.
+            loadArgumentsGPR(GPRInfo::returnValueGPR);
+            m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR1);
+            emitSetVarargsFrame(m_jit, GPRInfo::returnValueGPR, false, scratchGPR1, scratchGPR1);
+            m_jit.addPtr(TrustedImm32(-(sizeof(CallerFrameAndPC) + WTF::roundUpToMultipleOf(stackAlignmentBytes(), 6 * sizeof(void*)))), scratchGPR1, JITCompiler::stackPointerRegister);
+            
+            callOperation(operationSetupVarargsFrame, GPRInfo::returnValueGPR, scratchGPR1, argumentsTagGPR, argumentsPayloadGPR, data->firstVarArgOffset, GPRInfo::returnValueGPR);
+            resultGPR = GPRInfo::returnValueGPR;
+        }
+            
         m_jit.addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), resultGPR, JITCompiler::stackPointerRegister);
         
         DFG_ASSERT(m_jit.graph(), node, isFlushed());
         
-        if (node->op() != CallForwardVarargs)
-            use(node->child2());
-
         // Now set up the "this" argument.
-        JSValueOperand thisArgument(this, node->op() == CallForwardVarargs ? node->child2() : node->child3());
+        JSValueOperand thisArgument(this, node->child3());
         GPRReg thisArgumentTagGPR = thisArgument.tagGPR();
         GPRReg thisArgumentPayloadGPR = thisArgument.payloadGPR();
         thisArgument.use();
@@ -1753,10 +1734,8 @@
     switch (op) {
     case JSConstant:
     case DoubleConstant:
-        initConstantInfo(node);
-        break;
-
-    case PhantomArguments:
+    case PhantomDirectArguments:
+    case PhantomClonedArguments:
         initConstantInfo(node);
         break;
 
@@ -1840,8 +1819,7 @@
             break;
         }
             
-        case FlushedJSValue:
-        case FlushedArguments: {
+        case FlushedJSValue: {
             GPRTemporary result(this);
             GPRTemporary tag(this);
             m_jit.load32(JITCompiler::payloadFor(node->machineLocal()), result.gpr());
@@ -1916,8 +1894,7 @@
             break;
         }
             
-        case FlushedJSValue:
-        case FlushedArguments: {
+        case FlushedJSValue: {
             JSValueOperand value(this, node->child1());
             m_jit.store32(value.payloadGPR(), JITCompiler::payloadFor(node->machineLocal()));
             m_jit.store32(value.tagGPR(), JITCompiler::tagFor(node->machineLocal()));
@@ -2500,8 +2477,11 @@
         case Array::String:
             compileGetByValOnString(node);
             break;
-        case Array::Arguments:
-            compileGetByValOnArguments(node);
+        case Array::DirectArguments:
+            compileGetByValOnDirectArguments(node);
+            break;
+        case Array::ScopedArguments:
+            compileGetByValOnScopedArguments(node);
             break;
         default: {
             TypedArrayType type = node->arrayMode().typedArrayType();
@@ -2680,12 +2660,6 @@
             break;
         }
             
-        case Array::Arguments:
-            // FIXME: we could at some point make this work. Right now we're assuming that the register
-            // pressure would be too great.
-            RELEASE_ASSERT_NOT_REACHED();
-            break;
-            
         default: {
             TypedArrayType type = arrayMode.typedArrayType();
             if (isInt(type))
@@ -3586,6 +3560,13 @@
         break;
     }
         
+    case GetArgumentCount: {
+        GPRTemporary result(this);
+        m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), result.gpr());
+        int32Result(result.gpr(), node);
+        break;
+    }
+        
     case GetScope:
         compileGetScope(node);
         break;
@@ -3594,51 +3575,29 @@
         compileSkipScope(node);
         break;
         
-    case GetClosureRegisters: {
-        if (WriteBarrierBase<Unknown>* registers = m_jit.graph().tryGetRegisters(node->child1().node())) {
-            GPRTemporary result(this);
-            GPRReg resultGPR = result.gpr();
-            m_jit.move(TrustedImmPtr(registers), resultGPR);
-            storageResult(resultGPR, node);
-            break;
-        }
-        
-        SpeculateCellOperand scope(this, node->child1());
-        GPRTemporary result(this);
-        GPRReg scopeGPR = scope.gpr();
-        GPRReg resultGPR = result.gpr();
-
-        m_jit.loadPtr(JITCompiler::Address(scopeGPR, JSEnvironmentRecord::offsetOfRegisters()), resultGPR);
-        storageResult(resultGPR, node);
-        break;
-    }
     case GetClosureVar: {
-        speculate(node, node->child1());
-
-        StorageOperand registers(this, node->child2());
+        SpeculateCellOperand base(this, node->child1());
         GPRTemporary resultTag(this);
         GPRTemporary resultPayload(this);
-        GPRReg registersGPR = registers.gpr();
+        GPRReg baseGPR = base.gpr();
         GPRReg resultTagGPR = resultTag.gpr();
         GPRReg resultPayloadGPR = resultPayload.gpr();
-        m_jit.load32(JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
-        m_jit.load32(JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayloadGPR);
+        m_jit.load32(JITCompiler::Address(baseGPR, JSEnvironmentRecord::offsetOfVariable(node->scopeOffset()) + TagOffset), resultTagGPR);
+        m_jit.load32(JITCompiler::Address(baseGPR, JSEnvironmentRecord::offsetOfVariable(node->scopeOffset()) + PayloadOffset), resultPayloadGPR);
         jsValueResult(resultTagGPR, resultPayloadGPR, node);
         break;
     }
+    
     case PutClosureVar: {
-        speculate(node, node->child1());
+        SpeculateCellOperand base(this, node->child1());
+        JSValueOperand value(this, node->child2());
 
-        StorageOperand registers(this, node->child2());
-        JSValueOperand value(this, node->child3());
-        GPRTemporary scratchRegister(this);
-
-        GPRReg registersGPR = registers.gpr();
+        GPRReg baseGPR = base.gpr();
         GPRReg valueTagGPR = value.tagGPR();
         GPRReg valuePayloadGPR = value.payloadGPR();
 
-        m_jit.store32(valueTagGPR, JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
-        m_jit.store32(valuePayloadGPR, JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
+        m_jit.store32(valueTagGPR, JITCompiler::Address(baseGPR, JSEnvironmentRecord::offsetOfVariable(node->scopeOffset()) + TagOffset));
+        m_jit.store32(valuePayloadGPR, JITCompiler::Address(baseGPR, JSEnvironmentRecord::offsetOfVariable(node->scopeOffset()) + PayloadOffset));
         noResult(node);
         break;
     }
@@ -3996,7 +3955,7 @@
         GPRTemporary resultPayload(this);
         GPRTemporary resultTag(this);
 
-        m_jit.move(TrustedImmPtr(node->registerPointer()), resultPayload.gpr());
+        m_jit.move(TrustedImmPtr(node->variablePointer()), resultPayload.gpr());
         m_jit.load32(JITCompiler::Address(resultPayload.gpr(), OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTag.gpr());
         m_jit.load32(JITCompiler::Address(resultPayload.gpr(), OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayload.gpr());
 
@@ -4011,8 +3970,8 @@
         // a spare register - a good optimization would be to put the register pointer into
         // a register and then do a zero offset store followed by a four-offset store (or
         // vice-versa depending on endianness).
-        m_jit.store32(value.tagGPR(), node->registerPointer()->tagPointer());
-        m_jit.store32(value.payloadGPR(), node->registerPointer()->payloadPointer());
+        m_jit.store32(value.tagGPR(), node->variablePointer()->tagPointer());
+        m_jit.store32(value.payloadGPR(), node->variablePointer()->payloadPointer());
 
         noResult(node);
         break;
@@ -4262,6 +4221,7 @@
     case CallVarargs:
     case CallForwardVarargs:
     case ConstructVarargs:
+    case ConstructForwardVarargs:
         emitCall(node);
         break;
 
@@ -4312,396 +4272,43 @@
         break;
     }
         
+    case ForwardVarargs: {
+        compileForwardVarargs(node);
+        break;
+    }
+        
     case CreateActivation: {
-        GPRTemporary result(this);
-        GPRReg resultGPR = result.gpr();
-        SpeculateCellOperand scope(this, node->child2());
-        GPRReg scopeGPR = scope.gpr();
-
-        flushRegisters();
-        callOperation(operationCreateActivation, resultGPR, scopeGPR, framePointerOffsetToGetActivationRegisters());
-        
-        cellResult(resultGPR, node);
+        compileCreateActivation(node);
         break;
     }
         
-    case CreateArguments: {
-        JSValueOperand value(this, node->child1());
-        GPRTemporary scratch1(this);
-        GPRTemporary scratch2(this);
-        GPRTemporary result(this, Reuse, value, PayloadWord);
-        
-        GPRReg valueTagGPR = value.tagGPR();
-        GPRReg valuePayloadGPR = value.payloadGPR();
-        GPRReg scratch1GPR = scratch1.gpr();
-        GPRReg scratch2GPR = scratch2.gpr();
-        GPRReg resultGPR = result.gpr();
-        
-        m_jit.move(valuePayloadGPR, resultGPR);
-        
-        if (node->origin.semantic.inlineCallFrame) {
-            JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
-            addSlowPathGenerator(
-                slowPathCall(
-                    notCreated, this, operationCreateInlinedArguments, resultGPR,
-                    node->origin.semantic.inlineCallFrame));
-            cellResult(resultGPR, node);
-            break;
-        } 
-
-        FunctionExecutable* executable = jsCast<FunctionExecutable*>(m_jit.graph().executableFor(node->origin.semantic));
-        if (m_jit.codeBlock()->hasSlowArguments()
-            || executable->isStrictMode() 
-            || !executable->parameterCount()) {
-            JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
-            addSlowPathGenerator(
-                slowPathCall(notCreated, this, operationCreateArgumentsForDFG, resultGPR));
-            cellResult(resultGPR, node);
-            break;
-        }
-
-        JITCompiler::Jump alreadyCreated = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
-
-        MacroAssembler::JumpList slowPaths;
-        emitAllocateArguments(resultGPR, scratch1GPR, scratch2GPR, slowPaths);
-            addSlowPathGenerator(
-                slowPathCall(slowPaths, this, operationCreateArgumentsForDFG, resultGPR));
-
-        alreadyCreated.link(&m_jit); 
-        cellResult(resultGPR, node);
+    case CreateDirectArguments: {
+        compileCreateDirectArguments(node);
         break;
     }
         
-    case TearOffArguments: {
-        JSValueOperand unmodifiedArgumentsValue(this, node->child1());
-        JSValueOperand activationValue(this, node->child2());
-        GPRReg unmodifiedArgumentsValuePayloadGPR = unmodifiedArgumentsValue.payloadGPR();
-        GPRReg activationValuePayloadGPR = activationValue.payloadGPR();
-        
-        JITCompiler::Jump created = m_jit.branchTest32(
-            JITCompiler::NonZero, unmodifiedArgumentsValuePayloadGPR);
-        
-        if (node->origin.semantic.inlineCallFrame) {
-            addSlowPathGenerator(
-                slowPathCall(
-                    created, this, operationTearOffInlinedArguments, NoResult,
-                    unmodifiedArgumentsValuePayloadGPR, activationValuePayloadGPR, node->origin.semantic.inlineCallFrame));
-        } else {
-            addSlowPathGenerator(
-                slowPathCall(
-                    created, this, operationTearOffArguments, NoResult,
-                    unmodifiedArgumentsValuePayloadGPR, activationValuePayloadGPR));
-        }
-        
-        noResult(node);
+    case GetFromArguments: {
+        compileGetFromArguments(node);
         break;
     }
         
-    case CheckArgumentsNotCreated: {
-        ASSERT(!isEmptySpeculation(
-            m_state.variables().operand(
-                m_jit.graph().argumentsRegisterFor(node->origin.semantic)).m_type));
-        speculationCheck(
-            Uncountable, JSValueRegs(), 0,
-            m_jit.branch32(
-                JITCompiler::NotEqual,
-                JITCompiler::tagFor(m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
-                TrustedImm32(JSValue::EmptyValueTag)));
-        noResult(node);
+    case PutToArguments: {
+        compilePutToArguments(node);
         break;
     }
         
-    case GetMyArgumentsLength: {
-        GPRTemporary result(this);
-        GPRReg resultGPR = result.gpr();
-        
-        if (!isEmptySpeculation(
-                m_state.variables().operand(
-                    m_jit.graph().argumentsRegisterFor(node->origin.semantic)).m_type)) {
-            speculationCheck(
-                ArgumentsEscaped, JSValueRegs(), 0,
-                m_jit.branch32(
-                    JITCompiler::NotEqual,
-                    JITCompiler::tagFor(m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
-                    TrustedImm32(JSValue::EmptyValueTag)));
-        }
-        
-        if (node->origin.semantic.inlineCallFrame
-            && !node->origin.semantic.inlineCallFrame->isVarargs()) {
-            m_jit.move(
-                TrustedImm32(node->origin.semantic.inlineCallFrame->arguments.size() - 1),
-                resultGPR);
-        } else {
-            VirtualRegister argumentCountRegister;
-            if (!node->origin.semantic.inlineCallFrame)
-                argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
-            else
-                argumentCountRegister = node->origin.semantic.inlineCallFrame->argumentCountRegister;
-            m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), resultGPR);
-            m_jit.sub32(TrustedImm32(1), resultGPR);
-        }
-        int32Result(resultGPR, node);
+    case CreateScopedArguments: {
+        compileCreateScopedArguments(node);
         break;
     }
         
-    case GetMyArgumentsLengthSafe: {
-        GPRTemporary resultPayload(this);
-        GPRTemporary resultTag(this);
-        GPRReg resultPayloadGPR = resultPayload.gpr();
-        GPRReg resultTagGPR = resultTag.gpr();
-        
-        JITCompiler::Jump created = m_jit.branch32(
-            JITCompiler::NotEqual,
-            JITCompiler::tagFor(m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
-            TrustedImm32(JSValue::EmptyValueTag));
-        
-        if (node->origin.semantic.inlineCallFrame
-            && !node->origin.semantic.inlineCallFrame->isVarargs()) {
-            m_jit.move(
-                TrustedImm32(node->origin.semantic.inlineCallFrame->arguments.size() - 1),
-                resultPayloadGPR);
-        } else {
-            VirtualRegister argumentCountRegister;
-            if (!node->origin.semantic.inlineCallFrame)
-                argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
-            else
-                argumentCountRegister = node->origin.semantic.inlineCallFrame->argumentCountRegister;
-            m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), resultPayloadGPR);
-            m_jit.sub32(TrustedImm32(1), resultPayloadGPR);
-        }
-        
-        m_jit.move(TrustedImm32(JSValue::Int32Tag), resultTagGPR);
-        
-        // FIXME: the slow path generator should perform a forward speculation that the
-        // result is an integer. For now we postpone the speculation by having this return
-        // a JSValue.
-        
-        addSlowPathGenerator(
-            slowPathCall(
-                created, this, operationGetArgumentsLength,
-                JSValueRegs(resultTagGPR, resultPayloadGPR),
-                m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic).offset()));
-        
-        jsValueResult(resultTagGPR, resultPayloadGPR, node);
+    case CreateClonedArguments: {
+        compileCreateClonedArguments(node);
         break;
     }
         
-    case GetMyArgumentByVal: {
-        SpeculateStrictInt32Operand index(this, node->child1());
-        GPRTemporary resultPayload(this);
-        GPRTemporary resultTag(this);
-        GPRReg indexGPR = index.gpr();
-        GPRReg resultPayloadGPR = resultPayload.gpr();
-        GPRReg resultTagGPR = resultTag.gpr();
-        
-        if (!isEmptySpeculation(
-                m_state.variables().operand(
-                    m_jit.graph().argumentsRegisterFor(node->origin.semantic)).m_type)) {
-            speculationCheck(
-                ArgumentsEscaped, JSValueRegs(), 0,
-                m_jit.branch32(
-                    JITCompiler::NotEqual,
-                    JITCompiler::tagFor(m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
-                    TrustedImm32(JSValue::EmptyValueTag)));
-        }
-            
-        if (node->origin.semantic.inlineCallFrame
-            && !node->origin.semantic.inlineCallFrame->isVarargs()) {
-            speculationCheck(
-                Uncountable, JSValueRegs(), 0,
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual,
-                    indexGPR,
-                    Imm32(node->origin.semantic.inlineCallFrame->arguments.size() - 1)));
-        } else {
-            VirtualRegister argumentCountRegister;
-            if (!node->origin.semantic.inlineCallFrame)
-                argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
-            else
-                argumentCountRegister = node->origin.semantic.inlineCallFrame->argumentCountRegister;
-            m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), resultPayloadGPR);
-            m_jit.sub32(TrustedImm32(1), resultPayloadGPR);
-            speculationCheck(
-                Uncountable, JSValueRegs(), 0,
-                m_jit.branch32(JITCompiler::AboveOrEqual, indexGPR, resultPayloadGPR));
-        }
-        
-        JITCompiler::JumpList slowArgument;
-        JITCompiler::JumpList slowArgumentOutOfBounds;
-        if (m_jit.symbolTableFor(node->origin.semantic)->slowArguments()) {
-            RELEASE_ASSERT(!node->origin.semantic.inlineCallFrame);
-            const SlowArgument* slowArguments = m_jit.graph().m_slowArguments.get();
-            slowArgumentOutOfBounds.append(
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual, indexGPR,
-                    Imm32(m_jit.symbolTableFor(node->origin.semantic)->parameterCount())));
-
-            COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
-            m_jit.move(ImmPtr(slowArguments), resultPayloadGPR);
-            m_jit.load32(
-                JITCompiler::BaseIndex(
-                    resultPayloadGPR, indexGPR, JITCompiler::TimesEight, 
-                    OBJECT_OFFSETOF(SlowArgument, index)), 
-                resultPayloadGPR);
-
-            m_jit.load32(
-                JITCompiler::BaseIndex(
-                    GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
-                    OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
-                resultTagGPR);
-            m_jit.load32(
-                JITCompiler::BaseIndex(
-                    GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
-                    OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
-                resultPayloadGPR);
-            slowArgument.append(m_jit.jump());
-        }
-        slowArgumentOutOfBounds.link(&m_jit);
-
-        m_jit.load32(
-            JITCompiler::BaseIndex(
-                GPRInfo::callFrameRegister, indexGPR, JITCompiler::TimesEight,
-                m_jit.offsetOfArguments(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
-            resultTagGPR);
-        m_jit.load32(
-            JITCompiler::BaseIndex(
-                GPRInfo::callFrameRegister, indexGPR, JITCompiler::TimesEight,
-                m_jit.offsetOfArguments(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
-            resultPayloadGPR);
-            
-        slowArgument.link(&m_jit);
-        jsValueResult(resultTagGPR, resultPayloadGPR, node);
-        break;
-    }
-    case GetMyArgumentByValSafe: {
-        SpeculateStrictInt32Operand index(this, node->child1());
-        GPRTemporary resultPayload(this);
-        GPRTemporary resultTag(this);
-        GPRReg indexGPR = index.gpr();
-        GPRReg resultPayloadGPR = resultPayload.gpr();
-        GPRReg resultTagGPR = resultTag.gpr();
-        
-        JITCompiler::JumpList slowPath;
-        slowPath.append(
-            m_jit.branch32(
-                JITCompiler::NotEqual,
-                JITCompiler::tagFor(m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
-                TrustedImm32(JSValue::EmptyValueTag)));
-        
-        if (node->origin.semantic.inlineCallFrame
-            && !node->origin.semantic.inlineCallFrame->isVarargs()) {
-            slowPath.append(
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual,
-                    indexGPR,
-                    Imm32(node->origin.semantic.inlineCallFrame->arguments.size() - 1)));
-        } else {
-            VirtualRegister argumentCountRegister;
-            if (!node->origin.semantic.inlineCallFrame)
-                argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
-            else
-                argumentCountRegister = node->origin.semantic.inlineCallFrame->argumentCountRegister;
-            m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), resultPayloadGPR);
-            m_jit.sub32(TrustedImm32(1), resultPayloadGPR);
-            slowPath.append(
-                m_jit.branch32(JITCompiler::AboveOrEqual, indexGPR, resultPayloadGPR));
-        }
-        
-        JITCompiler::JumpList slowArgument;
-        JITCompiler::JumpList slowArgumentOutOfBounds;
-        if (m_jit.symbolTableFor(node->origin.semantic)->slowArguments()) {
-            RELEASE_ASSERT(!node->origin.semantic.inlineCallFrame);
-            const SlowArgument* slowArguments = m_jit.graph().m_slowArguments.get();
-            slowArgumentOutOfBounds.append(
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual, indexGPR,
-                    Imm32(m_jit.symbolTableFor(node->origin.semantic)->parameterCount())));
-
-            COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
-            m_jit.move(ImmPtr(slowArguments), resultPayloadGPR);
-            m_jit.load32(
-                JITCompiler::BaseIndex(
-                    resultPayloadGPR, indexGPR, JITCompiler::TimesEight, 
-                    OBJECT_OFFSETOF(SlowArgument, index)), 
-                resultPayloadGPR);
-            m_jit.load32(
-                JITCompiler::BaseIndex(
-                    GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
-                    OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
-                resultTagGPR);
-            m_jit.load32(
-                JITCompiler::BaseIndex(
-                    GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
-                    OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
-                resultPayloadGPR);
-            slowArgument.append(m_jit.jump());
-        }
-        slowArgumentOutOfBounds.link(&m_jit);
-
-        m_jit.load32(
-            JITCompiler::BaseIndex(
-                GPRInfo::callFrameRegister, indexGPR, JITCompiler::TimesEight,
-                m_jit.offsetOfArguments(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
-            resultTagGPR);
-        m_jit.load32(
-            JITCompiler::BaseIndex(
-                GPRInfo::callFrameRegister, indexGPR, JITCompiler::TimesEight,
-                m_jit.offsetOfArguments(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
-            resultPayloadGPR);
-        
-        if (node->origin.semantic.inlineCallFrame) {
-            addSlowPathGenerator(
-                slowPathCall(
-                    slowPath, this, operationGetInlinedArgumentByVal,
-                    JSValueRegs(resultTagGPR, resultPayloadGPR),
-                    m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic).offset(),
-                    node->origin.semantic.inlineCallFrame, indexGPR));
-        } else {
-            addSlowPathGenerator(
-                slowPathCall(
-                    slowPath, this, operationGetArgumentByVal,
-                    JSValueRegs(resultTagGPR, resultPayloadGPR),
-                    m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic).offset(),
-                    indexGPR));
-        }
-        
-        slowArgument.link(&m_jit);
-        jsValueResult(resultTagGPR, resultPayloadGPR, node);
-        break;
-    }
-        
-    case NewFunctionNoCheck:
-        compileNewFunctionNoCheck(node);
-        break;
-        
-    case NewFunction: {
-        JSValueOperand value(this, node->child1());
-        GPRTemporary resultTag(this, Reuse, value, TagWord);
-        GPRTemporary resultPayload(this, Reuse, value, PayloadWord);
-        
-        GPRReg valueTagGPR = value.tagGPR();
-        GPRReg valuePayloadGPR = value.payloadGPR();
-        GPRReg resultTagGPR = resultTag.gpr();
-        GPRReg resultPayloadGPR = resultPayload.gpr();
-        SpeculateCellOperand scope(this, node->child2());
-        GPRReg scopeGPR = scope.gpr();
-
-        m_jit.move(valuePayloadGPR, resultPayloadGPR);
-        m_jit.move(valueTagGPR, resultTagGPR);
-        
-        JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
-        
-        addSlowPathGenerator(
-            slowPathCall(
-                notCreated, this, operationNewFunction, JSValueRegs(resultTagGPR, resultPayloadGPR), scopeGPR,
-                node->castOperand<FunctionExecutable*>()));
-        
-        jsValueResult(resultTagGPR, resultPayloadGPR, node);
-        break;
-    }
-        
-    case NewFunctionExpression:
-        compileNewFunctionExpression(node);
+    case NewFunction:
+        compileNewFunction(node);
         break;
         
     case In:
@@ -5087,7 +4694,8 @@
     case PutStack:
     case KillStack:
     case GetStack:
-        RELEASE_ASSERT_NOT_REACHED();
+    case GetMyArgumentByVal:
+        DFG_CRASH(m_jit.graph(), node, "unexpected node in DFG backend");
         break;
     }
 
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
index 96e05c0..0c67e54 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
@@ -28,15 +28,17 @@
 
 #if ENABLE(DFG_JIT)
 
-#include "Arguments.h"
 #include "ArrayPrototype.h"
 #include "DFGAbstractInterpreterInlines.h"
 #include "DFGCallArrayAllocatorSlowPathGenerator.h"
 #include "DFGOperations.h"
 #include "DFGSlowPathGenerator.h"
 #include "Debugger.h"
+#include "DirectArguments.h"
 #include "GetterSetter.h"
 #include "JSCInlines.h"
+#include "JSEnvironmentRecord.h"
+#include "JSLexicalEnvironment.h"
 #include "JSPropertyNameEnumerator.h"
 #include "ObjectPrototype.h"
 #include "SetupVarargsFrame.h"
@@ -626,18 +628,16 @@
 void SpeculativeJIT::emitCall(Node* node)
 {
     CallLinkInfo::CallType callType;
-    bool isVarargs;
+    bool isVarargs = false;
+    bool isForwardVarargs = false;
     switch (node->op()) {
     case Call:
         callType = CallLinkInfo::Call;
-        isVarargs = false;
         break;
     case Construct:
         callType = CallLinkInfo::Construct;
-        isVarargs = false;
         break;
     case CallVarargs:
-    case CallForwardVarargs:
         callType = CallLinkInfo::CallVarargs;
         isVarargs = true;
         break;
@@ -645,6 +645,14 @@
         callType = CallLinkInfo::ConstructVarargs;
         isVarargs = true;
         break;
+    case CallForwardVarargs:
+        callType = CallLinkInfo::CallVarargs;
+        isForwardVarargs = true;
+        break;
+    case ConstructForwardVarargs:
+        callType = CallLinkInfo::ConstructVarargs;
+        isForwardVarargs = true;
+        break;
     default:
         DFG_CRASH(m_jit.graph(), node, "bad node type");
         break;
@@ -653,27 +661,40 @@
     Edge calleeEdge = m_jit.graph().child(node, 0);
     
     // Gotta load the arguments somehow. Varargs is trickier.
-    if (isVarargs) {
+    if (isVarargs || isForwardVarargs) {
         CallVarargsData* data = node->callVarargsData();
 
-        GPRReg argumentsGPR;
-        GPRReg scratchGPR1;
-        GPRReg scratchGPR2;
-        GPRReg scratchGPR3;
+        GPRReg resultGPR;
+        unsigned numUsedStackSlots = m_jit.graph().m_nextMachineLocal;
         
-        if (node->op() == CallForwardVarargs) {
-            // We avoid calling flushRegisters() inside the control flow of CallForwardVarargs.
+        if (isForwardVarargs) {
             flushRegisters();
-        }
-        
-        auto loadArgumentsGPR = [&] (GPRReg reservedGPR) {
-            if (node->op() == CallForwardVarargs) {
-                argumentsGPR = JITCompiler::selectScratchGPR(reservedGPR);
-                m_jit.load64(
-                    JITCompiler::addressFor(
-                        m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
-                    argumentsGPR);
-            } else {
+            use(node->child2());
+            
+            GPRReg scratchGPR1;
+            GPRReg scratchGPR2;
+            GPRReg scratchGPR3;
+            
+            scratchGPR1 = JITCompiler::selectScratchGPR();
+            scratchGPR2 = JITCompiler::selectScratchGPR(scratchGPR1);
+            scratchGPR3 = JITCompiler::selectScratchGPR(scratchGPR1, scratchGPR2);
+            
+            m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR2);
+            JITCompiler::JumpList slowCase;
+            emitSetupVarargsFrameFastCase(m_jit, scratchGPR2, scratchGPR1, scratchGPR2, scratchGPR3, node->child2()->origin.semantic.inlineCallFrame, data->firstVarArgOffset, slowCase);
+            JITCompiler::Jump done = m_jit.jump();
+            slowCase.link(&m_jit);
+            callOperation(operationThrowStackOverflowForVarargs);
+            m_jit.abortWithReason(DFGVarargsThrowingPathDidNotThrow);
+            done.link(&m_jit);
+            resultGPR = scratchGPR2;
+        } else {
+            GPRReg argumentsGPR;
+            GPRReg scratchGPR1;
+            GPRReg scratchGPR2;
+            GPRReg scratchGPR3;
+            
+            auto loadArgumentsGPR = [&] (GPRReg reservedGPR) {
                 if (reservedGPR != InvalidGPRReg)
                     lock(reservedGPR);
                 JSValueOperand arguments(this, node->child2());
@@ -681,69 +702,40 @@
                 if (reservedGPR != InvalidGPRReg)
                     unlock(reservedGPR);
                 flushRegisters();
-            }
+                
+                scratchGPR1 = JITCompiler::selectScratchGPR(argumentsGPR, reservedGPR);
+                scratchGPR2 = JITCompiler::selectScratchGPR(argumentsGPR, scratchGPR1, reservedGPR);
+                scratchGPR3 = JITCompiler::selectScratchGPR(argumentsGPR, scratchGPR1, scratchGPR2, reservedGPR);
+            };
             
-            scratchGPR1 = JITCompiler::selectScratchGPR(argumentsGPR, reservedGPR);
-            scratchGPR2 = JITCompiler::selectScratchGPR(argumentsGPR, scratchGPR1, reservedGPR);
-            scratchGPR3 = JITCompiler::selectScratchGPR(argumentsGPR, scratchGPR1, scratchGPR2, reservedGPR);
-        };
-        
-        loadArgumentsGPR(InvalidGPRReg);
-        
-        // At this point we have the whole register file to ourselves, and argumentsGPR has the
-        // arguments register. Select some scratch registers.
-        
-        // We will use scratchGPR2 to point to our stack frame.
-
-        unsigned numUsedStackSlots = m_jit.graph().m_nextMachineLocal;
-        
-        JITCompiler::Jump haveArguments;
-        GPRReg resultGPR = GPRInfo::regT0;
-        if (node->op() == CallForwardVarargs) {
-            // Do the horrific foo.apply(this, arguments) optimization.
-            // FIXME: do this optimization at the IR level instead of dynamically by testing the
-            // arguments register. This will happen once we get rid of the arguments lazy creation and
-            // lazy tear-off.
+            loadArgumentsGPR(InvalidGPRReg);
             
-            JITCompiler::JumpList slowCase;
-            slowCase.append(m_jit.branchTest64(JITCompiler::NonZero, argumentsGPR));
+            DFG_ASSERT(m_jit.graph(), node, isFlushed());
             
-            m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR2);
-            emitSetupVarargsFrameFastCase(m_jit, scratchGPR2, scratchGPR1, scratchGPR2, scratchGPR3, node->origin.semantic.inlineCallFrame, data->firstVarArgOffset, slowCase);
-            resultGPR = scratchGPR2;
+            // Right now, arguments is in argumentsGPR and the register file is flushed.
+            callOperation(operationSizeFrameForVarargs, GPRInfo::returnValueGPR, argumentsGPR, numUsedStackSlots, data->firstVarArgOffset);
             
-            haveArguments = m_jit.jump();
-            slowCase.link(&m_jit);
+            // Now we have the argument count of the callee frame, but we've lost the arguments operand.
+            // Reconstruct the arguments operand while preserving the callee frame.
+            loadArgumentsGPR(GPRInfo::returnValueGPR);
+            m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR1);
+            emitSetVarargsFrame(m_jit, GPRInfo::returnValueGPR, false, scratchGPR1, scratchGPR1);
+            m_jit.addPtr(TrustedImm32(-(sizeof(CallerFrameAndPC) + WTF::roundUpToMultipleOf(stackAlignmentBytes(), 5 * sizeof(void*)))), scratchGPR1, JITCompiler::stackPointerRegister);
+            
+            callOperation(operationSetupVarargsFrame, GPRInfo::returnValueGPR, scratchGPR1, argumentsGPR, data->firstVarArgOffset, GPRInfo::returnValueGPR);
+            resultGPR = GPRInfo::returnValueGPR;
         }
-
-        DFG_ASSERT(m_jit.graph(), node, isFlushed());
-        
-        // Right now, arguments is in argumentsGPR and the register file is flushed.
-        callOperation(operationSizeFrameForVarargs, GPRInfo::returnValueGPR, argumentsGPR, numUsedStackSlots, data->firstVarArgOffset);
-        
-        // Now we have the argument count of the callee frame, but we've lost the arguments operand.
-        // Reconstruct the arguments operand while preserving the callee frame.
-        loadArgumentsGPR(GPRInfo::returnValueGPR);
-        m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR1);
-        emitSetVarargsFrame(m_jit, GPRInfo::returnValueGPR, false, scratchGPR1, scratchGPR1);
-        m_jit.addPtr(TrustedImm32(-(sizeof(CallerFrameAndPC) + WTF::roundUpToMultipleOf(stackAlignmentBytes(), 5 * sizeof(void*)))), scratchGPR1, JITCompiler::stackPointerRegister);
-        
-        callOperation(operationSetupVarargsFrame, GPRInfo::returnValueGPR, scratchGPR1, argumentsGPR, data->firstVarArgOffset, GPRInfo::returnValueGPR);
-        m_jit.move(GPRInfo::returnValueGPR, resultGPR);
-        
-        if (node->op() == CallForwardVarargs)
-            haveArguments.link(&m_jit);
         
         m_jit.addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), resultGPR, JITCompiler::stackPointerRegister);
         
         DFG_ASSERT(m_jit.graph(), node, isFlushed());
         
         // We don't need the arguments array anymore.
-        if (node->op() != CallForwardVarargs)
+        if (isVarargs)
             use(node->child2());
 
         // Now set up the "this" argument.
-        JSValueOperand thisArgument(this, node->op() == CallForwardVarargs ? node->child2() : node->child3());
+        JSValueOperand thisArgument(this, node->child3());
         GPRReg thisArgumentGPR = thisArgument.gpr();
         thisArgument.use();
         
@@ -1846,10 +1838,8 @@
     case JSConstant:
     case DoubleConstant:
     case Int52Constant:
-        initConstantInfo(node);
-        break;
-
-    case PhantomArguments:
+    case PhantomDirectArguments:
+    case PhantomClonedArguments:
         initConstantInfo(node);
         break;
 
@@ -2009,8 +1999,7 @@
             break;
         }
             
-        case FlushedJSValue:
-        case FlushedArguments: {
+        case FlushedJSValue: {
             JSValueOperand value(this, node->child1());
             m_jit.store64(value.gpr(), JITCompiler::addressFor(node->machineLocal()));
             noResult(node);
@@ -2602,8 +2591,11 @@
         case Array::String:
             compileGetByValOnString(node);
             break;
-        case Array::Arguments:
-            compileGetByValOnArguments(node);
+        case Array::DirectArguments:
+            compileGetByValOnDirectArguments(node);
+            break;
+        case Array::ScopedArguments:
+            compileGetByValOnScopedArguments(node);
             break;
         default: {
             TypedArrayType type = node->arrayMode().typedArrayType();
@@ -2833,47 +2825,6 @@
             break;
         }
             
-        case Array::Arguments: {
-            JSValueOperand value(this, child3);
-            GPRTemporary scratch(this);
-            GPRTemporary scratch2(this);
-            
-            GPRReg valueReg = value.gpr();
-            GPRReg scratchReg = scratch.gpr();
-            GPRReg scratch2Reg = scratch2.gpr();
-            
-            if (!m_compileOkay)
-                return;
-
-            // Two really lame checks.
-            speculationCheck(
-                Uncountable, JSValueSource(), 0,
-                m_jit.branch32(
-                    MacroAssembler::AboveOrEqual, propertyReg,
-                    MacroAssembler::Address(baseReg, Arguments::offsetOfNumArguments())));
-            speculationCheck(
-                Uncountable, JSValueSource(), 0,
-                m_jit.branchTestPtr(
-                    MacroAssembler::NonZero,
-                    MacroAssembler::Address(
-                        baseReg, Arguments::offsetOfSlowArgumentData())));
-
-            m_jit.move(propertyReg, scratch2Reg);
-            m_jit.signExtend32ToPtr(scratch2Reg, scratch2Reg);
-            m_jit.loadPtr(
-                MacroAssembler::Address(baseReg, Arguments::offsetOfRegisters()),
-                scratchReg);
-            
-            m_jit.store64(
-                valueReg,
-                MacroAssembler::BaseIndex(
-                    scratchReg, scratch2Reg, MacroAssembler::TimesEight,
-                    CallFrame::thisArgumentOffset() * sizeof(Register) + sizeof(Register)));
-            
-            noResult(node);
-            break;
-        }
-            
         default: {
             TypedArrayType type = arrayMode.typedArrayType();
             if (isInt(type))
@@ -3639,7 +3590,7 @@
         GPRReg scratchGPR = scratch.gpr();
 
         MacroAssembler::JumpList slowPath;
-
+        
         m_jit.loadPtr(JITCompiler::Address(calleeGPR, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()), allocatorGPR);
         m_jit.loadPtr(JITCompiler::Address(calleeGPR, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()), structureGPR);
         slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, allocatorGPR));
@@ -3688,6 +3639,13 @@
         break;
     }
         
+    case GetArgumentCount: {
+        GPRTemporary result(this);
+        m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), result.gpr());
+        int32Result(result.gpr(), node);
+        break;
+    }
+        
     case GetScope:
         compileGetScope(node);
         break;
@@ -3696,46 +3654,24 @@
         compileSkipScope(node);
         break;
         
-    case GetClosureRegisters: {
-        if (WriteBarrierBase<Unknown>* registers = m_jit.graph().tryGetRegisters(node->child1().node())) {
-            GPRTemporary result(this);
-            GPRReg resultGPR = result.gpr();
-            m_jit.move(TrustedImmPtr(registers), resultGPR);
-            storageResult(resultGPR, node);
-            break;
-        }
-        
-        SpeculateCellOperand scope(this, node->child1());
-        GPRTemporary result(this);
-        GPRReg scopeGPR = scope.gpr();
-        GPRReg resultGPR = result.gpr();
-
-        m_jit.loadPtr(JITCompiler::Address(scopeGPR, JSEnvironmentRecord::offsetOfRegisters()), resultGPR);
-        storageResult(resultGPR, node);
-        break;
-    }
     case GetClosureVar: {
-        speculate(node, node->child1());
-
-        StorageOperand registers(this, node->child2());
+        SpeculateCellOperand base(this, node->child1());
         GPRTemporary result(this);
-        GPRReg registersGPR = registers.gpr();
+        GPRReg baseGPR = base.gpr();
         GPRReg resultGPR = result.gpr();
 
-        m_jit.load64(JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register)), resultGPR);
+        m_jit.load64(JITCompiler::Address(baseGPR, JSEnvironmentRecord::offsetOfVariable(node->scopeOffset())), resultGPR);
         jsValueResult(resultGPR, node);
         break;
     }
     case PutClosureVar: {
-        speculate(node, node->child1());
+        SpeculateCellOperand base(this, node->child1());
+        JSValueOperand value(this, node->child2());
 
-        StorageOperand registers(this, node->child2());
-        JSValueOperand value(this, node->child3());
-
-        GPRReg registersGPR = registers.gpr();
+        GPRReg baseGPR = base.gpr();
         GPRReg valueGPR = value.gpr();
 
-        m_jit.store64(valueGPR, JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register)));
+        m_jit.store64(valueGPR, JITCompiler::Address(baseGPR, JSEnvironmentRecord::offsetOfVariable(node->scopeOffset())));
         noResult(node);
         break;
     }
@@ -4062,7 +3998,7 @@
     case GetGlobalVar: {
         GPRTemporary result(this);
 
-        m_jit.load64(node->registerPointer(), result.gpr());
+        m_jit.load64(node->variablePointer(), result.gpr());
 
         jsValueResult(result.gpr(), node);
         break;
@@ -4071,7 +4007,7 @@
     case PutGlobalVar: {
         JSValueOperand value(this, node->child1());
 
-        m_jit.store64(value.gpr(), node->registerPointer());
+        m_jit.store64(value.gpr(), node->variablePointer());
 
         noResult(node);
         break;
@@ -4318,6 +4254,7 @@
     case CallVarargs:
     case CallForwardVarargs:
     case ConstructVarargs:
+    case ConstructForwardVarargs:
         emitCall(node);
         break;
         
@@ -4365,358 +4302,43 @@
         break;
     }
         
+    case ForwardVarargs: {
+        compileForwardVarargs(node);
+        break;
+    }
+        
     case CreateActivation: {
-        DFG_ASSERT(m_jit.graph(), node, !node->origin.semantic.inlineCallFrame);
-        
-        GPRTemporary result(this);
-        GPRReg resultGPR = result.gpr();
-        SpeculateCellOperand scope(this, node->child2());
-        GPRReg scopeGPR = scope.gpr();
-
-        flushRegisters();
-        callOperation(operationCreateActivation, resultGPR, scopeGPR, framePointerOffsetToGetActivationRegisters());
-
-        cellResult(resultGPR, node);
+        compileCreateActivation(node);
         break;
     }
         
-    case CreateArguments: {
-        JSValueOperand value(this, node->child1());
-        GPRTemporary scratch1(this);
-        GPRTemporary scratch2(this);
-        GPRTemporary result(this, Reuse, value);
-        
-        GPRReg valueGPR = value.gpr();
-        GPRReg scratchGPR1 = scratch1.gpr();
-        GPRReg scratchGPR2 = scratch2.gpr();
-        GPRReg resultGPR = result.gpr();
-        
-        m_jit.move(valueGPR, resultGPR);
-        
-        if (node->origin.semantic.inlineCallFrame) {
-            JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR);
-            addSlowPathGenerator(
-                slowPathCall(
-                    notCreated, this, operationCreateInlinedArguments, resultGPR,
-                    node->origin.semantic.inlineCallFrame));
-            cellResult(resultGPR, node);
-            break;
-        } 
-
-        FunctionExecutable* executable = jsCast<FunctionExecutable*>(m_jit.graph().executableFor(node->origin.semantic));
-        if (m_jit.codeBlock()->hasSlowArguments()
-            || executable->isStrictMode() 
-            || !executable->parameterCount()) {
-            JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR);
-            addSlowPathGenerator(
-                slowPathCall(notCreated, this, operationCreateArgumentsForDFG, resultGPR));
-            cellResult(resultGPR, node);
-            break;
-        }
-
-        JITCompiler::Jump alreadyCreated = m_jit.branchTest64(JITCompiler::NonZero, resultGPR);
-
-        MacroAssembler::JumpList slowPaths;
-        emitAllocateArguments(resultGPR, scratchGPR1, scratchGPR2, slowPaths);
-        addSlowPathGenerator(
-            slowPathCall(slowPaths, this, operationCreateArgumentsForDFG, resultGPR));
-
-        alreadyCreated.link(&m_jit);
-        cellResult(resultGPR, node);
-        break;
-    }
-
-    case TearOffArguments: {
-        JSValueOperand unmodifiedArgumentsValue(this, node->child1());
-        JSValueOperand activationValue(this, node->child2());
-        GPRReg unmodifiedArgumentsValueGPR = unmodifiedArgumentsValue.gpr();
-        GPRReg activationValueGPR = activationValue.gpr();
-
-        JITCompiler::Jump created = m_jit.branchTest64(JITCompiler::NonZero, unmodifiedArgumentsValueGPR);
-
-        if (node->origin.semantic.inlineCallFrame) {
-            addSlowPathGenerator(
-                slowPathCall(
-                    created, this, operationTearOffInlinedArguments, NoResult,
-                    unmodifiedArgumentsValueGPR, activationValueGPR, node->origin.semantic.inlineCallFrame));
-        } else {
-            addSlowPathGenerator(
-                slowPathCall(
-                    created, this, operationTearOffArguments, NoResult, unmodifiedArgumentsValueGPR, activationValueGPR));
-        }
-        
-        noResult(node);
+    case CreateDirectArguments: {
+        compileCreateDirectArguments(node);
         break;
     }
         
-    case GetMyArgumentsLength: {
-        GPRTemporary result(this);
-        GPRReg resultGPR = result.gpr();
-        
-        if (!isEmptySpeculation(
-                m_state.variables().operand(
-                    m_jit.graph().argumentsRegisterFor(node->origin.semantic)).m_type)) {
-            speculationCheck(
-                ArgumentsEscaped, JSValueRegs(), 0,
-                m_jit.branchTest64(
-                    JITCompiler::NonZero,
-                    JITCompiler::addressFor(
-                        m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic))));
-        }
-        
-        if (node->origin.semantic.inlineCallFrame
-            && !node->origin.semantic.inlineCallFrame->isVarargs()) {
-            m_jit.move(
-                TrustedImm32(node->origin.semantic.inlineCallFrame->arguments.size() - 1),
-                resultGPR);
-        } else {
-            VirtualRegister argumentCountRegister;
-            if (!node->origin.semantic.inlineCallFrame)
-                argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
-            else
-                argumentCountRegister = node->origin.semantic.inlineCallFrame->argumentCountRegister;
-            m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), resultGPR);
-            m_jit.sub32(TrustedImm32(1), resultGPR);
-        }
-        int32Result(resultGPR, node);
+    case GetFromArguments: {
+        compileGetFromArguments(node);
         break;
     }
         
-    case GetMyArgumentsLengthSafe: {
-        GPRTemporary result(this);
-        GPRReg resultGPR = result.gpr();
-        
-        JITCompiler::Jump created = m_jit.branchTest64(
-            JITCompiler::NonZero,
-            JITCompiler::addressFor(
-                m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)));
-        
-        if (node->origin.semantic.inlineCallFrame
-            && !node->origin.semantic.inlineCallFrame->isVarargs()) {
-            m_jit.move(
-                Imm64(JSValue::encode(jsNumber(node->origin.semantic.inlineCallFrame->arguments.size() - 1))),
-                resultGPR);
-        } else {
-            VirtualRegister argumentCountRegister;
-            if (!node->origin.semantic.inlineCallFrame)
-                argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
-            else
-                argumentCountRegister = node->origin.semantic.inlineCallFrame->argumentCountRegister;
-            m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), resultGPR);
-            m_jit.sub32(TrustedImm32(1), resultGPR);
-            m_jit.or64(GPRInfo::tagTypeNumberRegister, resultGPR);
-        }
-        
-        addSlowPathGenerator(
-            slowPathCall(
-                created, this, operationGetArgumentsLength, resultGPR,
-                m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic).offset()));
-        
-        jsValueResult(resultGPR, node);
+    case PutToArguments: {
+        compilePutToArguments(node);
         break;
     }
         
-    case GetMyArgumentByVal: {
-        SpeculateStrictInt32Operand index(this, node->child1());
-        GPRTemporary result(this);
-        GPRReg indexGPR = index.gpr();
-        GPRReg resultGPR = result.gpr();
-
-        if (!isEmptySpeculation(
-                m_state.variables().operand(
-                    m_jit.graph().argumentsRegisterFor(node->origin.semantic)).m_type)) {
-            speculationCheck(
-                ArgumentsEscaped, JSValueRegs(), 0,
-                m_jit.branchTest64(
-                    JITCompiler::NonZero,
-                    JITCompiler::addressFor(
-                        m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic))));
-        }
-
-        if (node->origin.semantic.inlineCallFrame
-            && !node->origin.semantic.inlineCallFrame->isVarargs()) {
-            speculationCheck(
-                Uncountable, JSValueRegs(), 0,
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual,
-                    indexGPR,
-                    Imm32(node->origin.semantic.inlineCallFrame->arguments.size() - 1)));
-        } else {
-            VirtualRegister argumentCountRegister;
-            if (!node->origin.semantic.inlineCallFrame)
-                argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
-            else
-                argumentCountRegister = node->origin.semantic.inlineCallFrame->argumentCountRegister;
-            m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), resultGPR);
-            m_jit.sub32(TrustedImm32(1), resultGPR);
-            speculationCheck(
-                Uncountable, JSValueRegs(), 0,
-                m_jit.branch32(JITCompiler::AboveOrEqual, indexGPR, resultGPR));
-        }
-
-        JITCompiler::JumpList slowArgument;
-        JITCompiler::JumpList slowArgumentOutOfBounds;
-        if (m_jit.symbolTableFor(node->origin.semantic)->slowArguments()) {
-            DFG_ASSERT(m_jit.graph(), node, !node->origin.semantic.inlineCallFrame);
-            const SlowArgument* slowArguments = m_jit.graph().m_slowArguments.get();
-            
-            slowArgumentOutOfBounds.append(
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual, indexGPR,
-                    Imm32(m_jit.symbolTableFor(node->origin.semantic)->parameterCount())));
-
-            COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
-            m_jit.move(ImmPtr(slowArguments), resultGPR);
-            m_jit.load32(
-                JITCompiler::BaseIndex(
-                    resultGPR, indexGPR, JITCompiler::TimesEight, 
-                    OBJECT_OFFSETOF(SlowArgument, index)),
-                resultGPR);
-            m_jit.signExtend32ToPtr(resultGPR, resultGPR);
-            m_jit.load64(
-                JITCompiler::BaseIndex(
-                    GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight),
-                resultGPR);
-            slowArgument.append(m_jit.jump());
-        }
-        slowArgumentOutOfBounds.link(&m_jit);
-
-        m_jit.load64(
-            JITCompiler::BaseIndex(
-                GPRInfo::callFrameRegister, indexGPR, JITCompiler::TimesEight, m_jit.offsetOfArguments(node->origin.semantic)),
-            resultGPR);
-
-        slowArgument.link(&m_jit);
-        jsValueResult(resultGPR, node);
+    case CreateScopedArguments: {
+        compileCreateScopedArguments(node);
         break;
     }
         
-    case GetMyArgumentByValSafe: {
-        SpeculateStrictInt32Operand index(this, node->child1());
-        GPRTemporary result(this);
-        GPRReg indexGPR = index.gpr();
-        GPRReg resultGPR = result.gpr();
-        
-        JITCompiler::JumpList slowPath;
-        slowPath.append(
-            m_jit.branchTest64(
-                JITCompiler::NonZero,
-                JITCompiler::addressFor(
-                    m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic))));
-        
-        if (node->origin.semantic.inlineCallFrame
-            && !node->origin.semantic.inlineCallFrame->isVarargs()) {
-            slowPath.append(
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual,
-                    resultGPR,
-                    Imm32(node->origin.semantic.inlineCallFrame->arguments.size() - 1)));
-        } else {
-            VirtualRegister argumentCountRegister;
-            if (!node->origin.semantic.inlineCallFrame)
-                argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
-            else
-                argumentCountRegister = node->origin.semantic.inlineCallFrame->argumentCountRegister;
-            m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), resultGPR);
-            m_jit.sub32(TrustedImm32(1), resultGPR);
-            slowPath.append(
-                m_jit.branch32(JITCompiler::AboveOrEqual, indexGPR, resultGPR));
-        }
-        
-        JITCompiler::JumpList slowArgument;
-        JITCompiler::JumpList slowArgumentOutOfBounds;
-        if (m_jit.symbolTableFor(node->origin.semantic)->slowArguments()) {
-            DFG_ASSERT(m_jit.graph(), node, !node->origin.semantic.inlineCallFrame);
-            const SlowArgument* slowArguments = m_jit.graph().m_slowArguments.get();
-
-            slowArgumentOutOfBounds.append(
-                m_jit.branch32(
-                    JITCompiler::AboveOrEqual, indexGPR,
-                    Imm32(m_jit.symbolTableFor(node->origin.semantic)->parameterCount())));
-
-            COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
-            m_jit.move(ImmPtr(slowArguments), resultGPR);
-            m_jit.load32(
-                JITCompiler::BaseIndex(
-                    resultGPR, indexGPR, JITCompiler::TimesEight, 
-                    OBJECT_OFFSETOF(SlowArgument, index)), 
-                resultGPR);
-            m_jit.signExtend32ToPtr(resultGPR, resultGPR);
-            m_jit.load64(
-                JITCompiler::BaseIndex(
-                    GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight),
-                resultGPR);
-            slowArgument.append(m_jit.jump());
-        }
-        slowArgumentOutOfBounds.link(&m_jit);
-
-        m_jit.load64(
-            JITCompiler::BaseIndex(
-                GPRInfo::callFrameRegister, indexGPR, JITCompiler::TimesEight, m_jit.offsetOfArguments(node->origin.semantic)),
-            resultGPR);
-        
-        if (node->origin.semantic.inlineCallFrame) {
-            addSlowPathGenerator(
-                slowPathCall(
-                    slowPath, this, operationGetInlinedArgumentByVal, resultGPR, 
-                    m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic).offset(),
-                    node->origin.semantic.inlineCallFrame,
-                    indexGPR));
-        } else {
-            addSlowPathGenerator(
-                slowPathCall(
-                    slowPath, this, operationGetArgumentByVal, resultGPR, 
-                    m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic).offset(),
-                    indexGPR));
-        }
-        
-        slowArgument.link(&m_jit);
-        jsValueResult(resultGPR, node);
+    case CreateClonedArguments: {
+        compileCreateClonedArguments(node);
         break;
     }
         
-    case CheckArgumentsNotCreated: {
-        ASSERT(!isEmptySpeculation(
-            m_state.variables().operand(
-                m_jit.graph().argumentsRegisterFor(node->origin.semantic)).m_type));
-        speculationCheck(
-            ArgumentsEscaped, JSValueRegs(), 0,
-            m_jit.branchTest64(
-                JITCompiler::NonZero,
-                JITCompiler::addressFor(
-                    m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic))));
-        noResult(node);
-        break;
-    }
-        
-    case NewFunctionNoCheck:
-        compileNewFunctionNoCheck(node);
-        break;
-        
-    case NewFunction: {
-        JSValueOperand value(this, node->child1());
-        GPRTemporary result(this, Reuse, value);
-        SpeculateCellOperand scope(this, node->child2());
-        GPRReg scopeGPR = scope.gpr();
-        
-        GPRReg valueGPR = value.gpr();
-        GPRReg resultGPR = result.gpr();
-        
-        m_jit.move(valueGPR, resultGPR);
-        
-        JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR);
-        
-        addSlowPathGenerator(
-            slowPathCall(
-                notCreated, this, operationNewFunction,
-                resultGPR, scopeGPR, node->castOperand<FunctionExecutable*>()));
-        
-        jsValueResult(resultGPR, node);
-        break;
-    }
-        
-    case NewFunctionExpression:
-        compileNewFunctionExpression(node);
+    case NewFunction:
+        compileNewFunction(node);
         break;
         
     case In:
@@ -5152,6 +4774,7 @@
     case CheckBadCell:
     case BottomValue:
     case PhantomNewObject:
+    case GetMyArgumentByVal:
     case PutHint:
     case CheckStructureImmediate:
     case MaterializeNewObject:
diff --git a/Source/JavaScriptCore/dfg/DFGStackLayoutPhase.cpp b/Source/JavaScriptCore/dfg/DFGStackLayoutPhase.cpp
index 7221f2d..a992395 100644
--- a/Source/JavaScriptCore/dfg/DFGStackLayoutPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGStackLayoutPhase.cpp
@@ -46,8 +46,6 @@
     
     bool run()
     {
-        SymbolTable* symbolTable = codeBlock()->symbolTable();
-
         // This enumerates the locals that we actually care about and packs them. So for example
         // if we use local 1, 3, 4, 5, 7, then we remap them: 1->0, 3->1, 4->2, 5->3, 7->4. We
         // treat a variable as being "used" if there exists an access to it (SetLocal, GetLocal,
@@ -84,7 +82,8 @@
                     break;
                 }
                     
-                case LoadVarargs: {
+                case LoadVarargs:
+                case ForwardVarargs: {
                     LoadVarargsData* data = node->loadVarargsData();
                     if (data->count.isLocal())
                         usedLocals.set(data->count.toLocal());
@@ -114,27 +113,8 @@
             }
         }
         
-        // Ensure that captured variables and captured inline arguments are pinned down.
-        // They should have been because of flushes, except that the flushes can be optimized
-        // away.
-        if (symbolTable) {
-            for (int i = symbolTable->captureStart(); i > symbolTable->captureEnd(); i--)
-                usedLocals.set(VirtualRegister(i).toLocal());
-        }
-        if (codeBlock()->usesArguments()) {
-            usedLocals.set(codeBlock()->argumentsRegister().toLocal());
-            usedLocals.set(unmodifiedArgumentsRegister(codeBlock()->argumentsRegister()).toLocal());
-        }
-        if (codeBlock()->uncheckedActivationRegister().isValid())
-            usedLocals.set(codeBlock()->activationRegister().toLocal());
         for (InlineCallFrameSet::iterator iter = m_graph.m_plan.inlineCallFrames->begin(); !!iter; ++iter) {
             InlineCallFrame* inlineCallFrame = *iter;
-            if (!m_graph.usesArguments(inlineCallFrame))
-                continue;
-            
-            VirtualRegister argumentsRegister = m_graph.argumentsRegisterFor(inlineCallFrame);
-            usedLocals.set(argumentsRegister.toLocal());
-            usedLocals.set(unmodifiedArgumentsRegister(argumentsRegister).toLocal());
             
             if (inlineCallFrame->isVarargs()) {
                 usedLocals.set(VirtualRegister(
@@ -193,36 +173,14 @@
             data->machineLocal = assign(allocation, data->local);
         }
         
-        if (codeBlock()->usesArguments()) {
-            VirtualRegister argumentsRegister =
-                assign(allocation, codeBlock()->argumentsRegister());
-            RELEASE_ASSERT(
-                assign(allocation, unmodifiedArgumentsRegister(codeBlock()->argumentsRegister()))
-                == unmodifiedArgumentsRegister(argumentsRegister));
-            codeBlock()->setArgumentsRegister(argumentsRegister);
-        }
-        
-        if (codeBlock()->uncheckedActivationRegister().isValid()) {
-            codeBlock()->setActivationRegister(
-                assign(allocation, codeBlock()->activationRegister()));
-        }
-        
         // This register is never valid for DFG code blocks.
+        codeBlock()->setActivationRegister(VirtualRegister());
         codeBlock()->setScopeRegister(VirtualRegister());
 
         for (unsigned i = m_graph.m_inlineVariableData.size(); i--;) {
             InlineVariableData data = m_graph.m_inlineVariableData[i];
             InlineCallFrame* inlineCallFrame = data.inlineCallFrame;
             
-            if (m_graph.usesArguments(inlineCallFrame)) {
-                inlineCallFrame->argumentsRegister = assign(
-                    allocation, m_graph.argumentsRegisterFor(inlineCallFrame));
-
-                RELEASE_ASSERT(
-                    assign(allocation, unmodifiedArgumentsRegister(m_graph.argumentsRegisterFor(inlineCallFrame)))
-                    == unmodifiedArgumentsRegister(inlineCallFrame->argumentsRegister));
-            }
-            
             if (inlineCallFrame->isVarargs()) {
                 inlineCallFrame->argumentCountRegister = assign(
                     allocation, VirtualRegister(inlineCallFrame->stackOffset + JSStack::ArgumentCount));
@@ -253,30 +211,6 @@
                 RELEASE_ASSERT(inlineCallFrame->calleeRecovery.isConstant());
         }
         
-        if (symbolTable) {
-            if (symbolTable->captureCount()) {
-                unsigned captureStartLocal = allocation[
-                    VirtualRegister(codeBlock()->symbolTable()->captureStart()).toLocal()];
-                ASSERT(captureStartLocal != UINT_MAX);
-                m_graph.m_machineCaptureStart = virtualRegisterForLocal(captureStartLocal).offset();
-            } else
-                m_graph.m_machineCaptureStart = virtualRegisterForLocal(0).offset();
-        
-            // This is an abomination. If we had captured an argument then the argument ends
-            // up being "slow", meaning that loads of the argument go through an extra lookup
-            // table.
-            if (const SlowArgument* slowArguments = symbolTable->slowArguments()) {
-                auto newSlowArguments = std::make_unique<SlowArgument[]>(
-                    symbolTable->parameterCount());
-                for (size_t i = symbolTable->parameterCount(); i--;) {
-                    newSlowArguments[i] = slowArguments[i];
-                    newSlowArguments[i].index = assign(allocation, VirtualRegister(slowArguments[i].index)).offset();
-                }
-            
-                m_graph.m_slowArguments = WTF::move(newSlowArguments);
-            }
-        }
-        
         // Fix GetLocalUnlinked's variable references.
         if (hasNodesThatNeedFixup) {
             for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
@@ -291,7 +225,8 @@
                         break;
                     }
                         
-                    case LoadVarargs: {
+                    case LoadVarargs:
+                    case ForwardVarargs: {
                         LoadVarargsData* data = node->loadVarargsData();
                         data->machineCount = assign(allocation, data->count);
                         data->machineStart = assign(allocation, data->start);
diff --git a/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp b/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp
index f214cb9..7a7d42c 100644
--- a/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp
@@ -237,60 +237,14 @@
             Node* setLocal = nullptr;
             VirtualRegister local = m_node->local();
             
-            if (m_node->variableAccessData()->isCaptured()) {
-                for (unsigned i = m_nodeIndex; i--;) {
-                    Node* node = m_block->at(i);
-                    bool done = false;
-                    switch (node->op()) {
-                    case GetLocal:
-                    case Flush:
-                        if (node->local() == local)
-                            done = true;
-                        break;
-                
-                    case GetLocalUnlinked:
-                        if (node->unlinkedLocal() == local)
-                            done = true;
-                        break;
-                
-                    case SetLocal: {
-                        if (node->local() != local)
-                            break;
-                        setLocal = node;
-                        done = true;
-                        break;
-                    }
-                
-                    case Phantom:
-                    case Check:
-                    case HardPhantom:
-                    case MovHint:
-                    case JSConstant:
-                    case DoubleConstant:
-                    case Int52Constant:
-                    case GetScope:
-                    case PhantomLocal:
-                    case GetCallee:
-                    case CountExecution:
-                        break;
-                
-                    default:
-                        done = true;
-                        break;
-                    }
-                    if (done)
-                        break;
+            for (unsigned i = m_nodeIndex; i--;) {
+                Node* node = m_block->at(i);
+                if (node->op() == SetLocal && node->local() == local) {
+                    setLocal = node;
+                    break;
                 }
-            } else {
-                for (unsigned i = m_nodeIndex; i--;) {
-                    Node* node = m_block->at(i);
-                    if (node->op() == SetLocal && node->local() == local) {
-                        setLocal = node;
-                        break;
-                    }
-                    if (accessesOverlap(m_graph, node, AbstractHeap(Variables, local)))
-                        break;
-                }
+                if (accessesOverlap(m_graph, node, AbstractHeap(Stack, local)))
+                    break;
             }
             
             if (!setLocal)
diff --git a/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp b/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp
index a7cad80..4c8276b 100644
--- a/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -118,12 +118,19 @@
                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->activationStructure());
                     break;
                     
+                case CreateDirectArguments:
+                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->directArgumentsStructure());
+                    break;
+                    
+                case CreateScopedArguments:
+                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->scopedArgumentsStructure());
+                    break;
+                    
                 case NewRegexp:
                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->regExpStructure());
                     break;
                     
-                case NewFunctionExpression:
-                case NewFunctionNoCheck:
+                case NewFunction:
                     registerStructure(m_graph.globalObjectFor(node->origin.semantic)->functionStructure());
                     break;
                     
diff --git a/Source/JavaScriptCore/dfg/DFGUnificationPhase.cpp b/Source/JavaScriptCore/dfg/DFGUnificationPhase.cpp
index 4e43eeb..0722dd9 100644
--- a/Source/JavaScriptCore/dfg/DFGUnificationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGUnificationPhase.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -70,7 +70,6 @@
         for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
             VariableAccessData* data = &m_graph.m_variableAccessData[i];
             data->find()->predict(data->nonUnifiedPrediction());
-            data->find()->mergeIsCaptured(data->isCaptured());
             data->find()->mergeStructureCheckHoistingFailed(data->structureCheckHoistingFailed());
             data->find()->mergeCheckArrayHoistingFailed(data->checkArrayHoistingFailed());
             data->find()->mergeShouldNeverUnbox(data->shouldNeverUnbox());
diff --git a/Source/JavaScriptCore/dfg/DFGValidate.cpp b/Source/JavaScriptCore/dfg/DFGValidate.cpp
index 3fe1998..a70c8be 100644
--- a/Source/JavaScriptCore/dfg/DFGValidate.cpp
+++ b/Source/JavaScriptCore/dfg/DFGValidate.cpp
@@ -438,6 +438,7 @@
                 case Upsilon:
                 case CheckInBounds:
                 case PhantomNewObject:
+                case GetMyArgumentByVal:
                 case PutHint:
                 case CheckStructureImmediate:
                 case MaterializeNewObject:
@@ -454,8 +455,6 @@
                     continue;
                 switch (node->op()) {
                 case GetLocal:
-                    if (node->variableAccessData()->isCaptured())
-                        break;
                     // Ignore GetLocal's that we know to be dead, but that the graph
                     // doesn't yet know to be dead.
                     if (!m_myRefCounts.get(node))
@@ -465,8 +464,6 @@
                     getLocalPositions.operand(node->local()) = i;
                     break;
                 case SetLocal:
-                    if (node->variableAccessData()->isCaptured())
-                        break;
                     // Only record the first SetLocal. There may be multiple SetLocals
                     // because of flushing.
                     if (setLocalPositions.operand(node->local()) != notSet)
@@ -474,8 +471,6 @@
                     setLocalPositions.operand(node->local()) = i;
                     break;
                 case SetArgument:
-                    if (node->variableAccessData()->isCaptured())
-                        break;
                     // This acts like a reset. It's ok to have a second GetLocal for a local in the same
                     // block if we had a SetArgument for that local.
                     getLocalPositions.operand(node->local()) = notSet;
diff --git a/Source/JavaScriptCore/dfg/DFGValueSource.cpp b/Source/JavaScriptCore/dfg/DFGValueSource.cpp
index 020eb6b..41d8b47 100644
--- a/Source/JavaScriptCore/dfg/DFGValueSource.cpp
+++ b/Source/JavaScriptCore/dfg/DFGValueSource.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -59,9 +59,6 @@
     case DoubleInJSStack:
         out.print("Double:", virtualRegister());
         break;
-    case ArgumentsSource:
-        out.print("Arguments");
-        break;
     case HaveNode:
         out.print("Node(", m_value, ")");
         break;
diff --git a/Source/JavaScriptCore/dfg/DFGValueSource.h b/Source/JavaScriptCore/dfg/DFGValueSource.h
index 33bb457..1b55797d 100644
--- a/Source/JavaScriptCore/dfg/DFGValueSource.h
+++ b/Source/JavaScriptCore/dfg/DFGValueSource.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,7 +45,6 @@
     CellInJSStack,
     BooleanInJSStack,
     DoubleInJSStack,
-    ArgumentsSource,
     SourceIsDead,
     HaveNode
 };
@@ -65,8 +64,6 @@
         return CellInJSStack;
     case DataFormatDead:
         return SourceIsDead;
-    case DataFormatArguments:
-        return ArgumentsSource;
     default:
         RELEASE_ASSERT(dataFormat & DataFormatJS);
         return ValueInJSStack;
@@ -88,8 +85,6 @@
         return DataFormatBoolean;
     case DoubleInJSStack:
         return DataFormatDouble;
-    case ArgumentsSource:
-        return DataFormatArguments;
     case SourceIsDead:
         return DataFormatDead;
     default:
@@ -120,7 +115,7 @@
     explicit ValueSource(ValueSourceKind valueSourceKind)
         : m_kind(valueSourceKind)
     {
-        ASSERT(kind() == ArgumentsSource || kind() == SourceIsDead || kind() == ArgumentsSource);
+        ASSERT(kind() == SourceIsDead);
     }
     
     explicit ValueSource(MinifiedID id)
@@ -157,8 +152,6 @@
             return ValueSource(CellInJSStack, where);
         case FlushedBoolean:
             return ValueSource(BooleanInJSStack, where);
-        case FlushedArguments:
-            return ValueSource(ArgumentsSource);
         }
         RELEASE_ASSERT_NOT_REACHED();
         return ValueSource();
@@ -196,9 +189,6 @@
         case SourceIsDead:
             return ValueRecovery::constant(jsUndefined());
             
-        case ArgumentsSource:
-            return ValueRecovery::argumentsThatWereNotCreated();
-            
         default:
             return ValueRecovery::displacedInJSStack(virtualRegister(), dataFormat());
         }
diff --git a/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp b/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp
new file mode 100644
index 0000000..2e742ee
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGVarargsForwardingPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGArgumentsUtilities.h"
+#include "DFGClobberize.h"
+#include "DFGGraph.h"
+#include "DFGPhase.h"
+
+namespace JSC { namespace DFG {
+
+namespace {
+
+bool verbose = false;
+
+class VarargsForwardingPhase : public Phase {
+public:
+    VarargsForwardingPhase(Graph& graph)
+        : Phase(graph, "varargs forwarding")
+    {
+    }
+    
+    bool run()
+    {
+        if (verbose) {
+            dataLog("Graph before varargs forwarding:\n");
+            m_graph.dump();
+        }
+        
+        m_changed = false;
+        for (BasicBlock* block : m_graph.blocksInNaturalOrder())
+            handleBlock(block);
+        return m_changed;
+    }
+
+private:
+    void handleBlock(BasicBlock* block)
+    {
+        for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
+            Node* node = block->at(nodeIndex);
+            switch (node->op()) {
+            case CreateDirectArguments:
+            case CreateClonedArguments:
+                handleCandidate(block, nodeIndex);
+                break;
+            default:
+                break;
+            }
+        }
+    }
+    
+    void handleCandidate(BasicBlock* block, unsigned candidateNodeIndex)
+    {
+        // We expect calls into this function to be rare. So, this is written in a simple O(n) manner.
+        
+        Node* candidate = block->at(candidateNodeIndex);
+        if (verbose)
+            dataLog("Handling candidate ", candidate, "\n");
+        
+        // Find the index of the last node in this block to use the candidate, and look for escaping
+        // sites.
+        unsigned lastUserIndex = candidateNodeIndex;
+        for (unsigned nodeIndex = candidateNodeIndex + 1; nodeIndex < block->size(); ++nodeIndex) {
+            Node* node = block->at(nodeIndex);
+            switch (node->op()) {
+            case Phantom:
+            case Check:
+            case HardPhantom:
+            case MovHint:
+            case PutHint:
+            case LoadVarargs:
+                if (m_graph.uses(node, candidate))
+                    lastUserIndex = nodeIndex;
+                break;
+                
+            case CallVarargs:
+            case ConstructVarargs:
+                if (node->child1() == candidate || node->child3() == candidate) {
+                    if (verbose)
+                        dataLog("    Escape at ", node, "\n");
+                    return;
+                }
+                if (node->child2() == candidate)
+                    lastUserIndex = nodeIndex;
+                break;
+                
+            case SetLocal:
+                if (node->child1() == candidate && node->variableAccessData()->isLoadedFrom()) {
+                    if (verbose)
+                        dataLog("    Escape at ", node, "\n");
+                    return;
+                }
+                break;
+                
+            default:
+                if (m_graph.uses(node, candidate)) {
+                    if (verbose)
+                        dataLog("    Escape at ", node, "\n");
+                    return;
+                }
+            }
+        }
+        if (verbose)
+            dataLog("Selected lastUserIndex = ", lastUserIndex, ", ", block->at(lastUserIndex), "\n");
+        
+        // We're still in business. Determine if between the candidate and the last user there is any
+        // effect that could interfere with sinking.
+        for (unsigned nodeIndex = candidateNodeIndex + 1; nodeIndex <= lastUserIndex; ++nodeIndex) {
+            Node* node = block->at(nodeIndex);
+            
+            // We have our own custom switch to detect some interferences that clobberize() wouldn't know
+            // about, and also some of the common ones, too. In particular, clobberize() doesn't know
+            // that Flush, MovHint, ZombieHint, and KillStack are bad because it's not worried about
+            // what gets read on OSR exit.
+            switch (node->op()) {
+            case MovHint:
+            case ZombieHint:
+            case KillStack:
+                if (argumentsInvolveStackSlot(candidate, node->unlinkedLocal())) {
+                    if (verbose)
+                        dataLog("    Interference at ", node, "\n");
+                    return;
+                }
+                break;
+                
+            case PutStack:
+                if (argumentsInvolveStackSlot(candidate, node->stackAccessData()->local)) {
+                    if (verbose)
+                        dataLog("    Interference at ", node, "\n");
+                    return;
+                }
+                break;
+                
+            case SetLocal:
+            case Flush:
+                if (argumentsInvolveStackSlot(candidate, node->local())) {
+                    if (verbose)
+                        dataLog("    Interference at ", node, "\n");
+                    return;
+                }
+                break;
+                
+            default: {
+                bool doesInterfere = false;
+                clobberize(
+                    m_graph, node, NoOpClobberize(),
+                    [&] (AbstractHeap heap) {
+                        if (heap.kind() != Stack) {
+                            ASSERT(!heap.overlaps(Stack));
+                            return;
+                        }
+                        ASSERT(!heap.payload().isTop());
+                        VirtualRegister reg(heap.payload().value32());
+                        if (argumentsInvolveStackSlot(candidate, reg))
+                            doesInterfere = true;
+                    },
+                    NoOpClobberize());
+                if (doesInterfere) {
+                    if (verbose)
+                        dataLog("    Interference at ", node, "\n");
+                    return;
+                }
+            } }
+        }
+        
+        // We can make this work.
+        if (verbose)
+            dataLog("    Will do forwarding!\n");
+        m_changed = true;
+        
+        // Transform the program.
+        switch (candidate->op()) {
+        case CreateDirectArguments:
+            candidate->setOpAndDefaultFlags(PhantomDirectArguments);
+            break;
+
+        case CreateClonedArguments:
+            candidate->setOpAndDefaultFlags(PhantomClonedArguments);
+            break;
+            
+        default:
+            DFG_CRASH(m_graph, candidate, "bad node type");
+            break;
+        }
+        for (unsigned nodeIndex = candidateNodeIndex + 1; nodeIndex <= lastUserIndex; ++nodeIndex) {
+            Node* node = block->at(nodeIndex);
+            switch (node->op()) {
+            case Phantom:
+            case Check:
+            case HardPhantom:
+            case MovHint:
+            case PutHint:
+                // We don't need to change anything with these.
+                break;
+                
+            case LoadVarargs:
+                if (node->child1() != candidate)
+                    break;
+                node->setOpAndDefaultFlags(ForwardVarargs);
+                break;
+                
+            case CallVarargs:
+                if (node->child2() != candidate)
+                    break;
+                node->setOpAndDefaultFlags(CallForwardVarargs);
+                break;
+                
+            case ConstructVarargs:
+                if (node->child2() != candidate)
+                    break;
+                node->setOpAndDefaultFlags(ConstructForwardVarargs);
+                break;
+                
+            case SetLocal:
+                // This is super odd. We don't have to do anything here, since in DFG IR, the phantom
+                // arguments nodes do produce a JSValue. Also, we know that if this SetLocal referenecs a
+                // candidate then the SetLocal - along with all of its references - will die off pretty
+                // soon, since it has no real users. DCE will surely kill it. If we make it to SSA, then
+                // SSA conversion will kill it.
+                break;
+                
+            default:
+                if (ASSERT_DISABLED)
+                    break;
+                m_graph.doToChildren(
+                    node,
+                    [&] (Edge edge) {
+                        DFG_ASSERT(m_graph, node, edge != candidate);
+                    });
+                break;
+            }
+        }
+    }
+    
+    bool m_changed;
+};
+
+} // anonymous namespace
+
+bool performVarargsForwarding(Graph& graph)
+{
+    SamplingRegion samplingRegion("DFG Varargs Forwarding Phase");
+    return runPhase<VarargsForwardingPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h b/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.h
similarity index 78%
rename from Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h
rename to Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.h
index 25098ca..ece3747 100644
--- a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h
+++ b/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,8 +23,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#ifndef DFGArgumentsSimplificationPhase_h
-#define DFGArgumentsSimplificationPhase_h
+#ifndef DFGVarargsForwardingPhase_h
+#define DFGVarargsForwardingPhase_h
 
 #if ENABLE(DFG_JIT)
 
@@ -32,16 +32,14 @@
 
 class Graph;
 
-// Simplifies reflective uses of the Arguments object:
-//
-// Inlined arguments.length -> constant
-// Inlined arguments[constant] -> GetLocalUnlinked
+// Eliminates allocations of Arguments-class objects when they flow into CallVarargs, ConstructVarargs,
+// or LoadVarargs.
 
-bool performArgumentsSimplification(Graph&);
+bool performVarargsForwarding(Graph&);
 
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
 
-#endif // DFGArgumentsSimplificationPhase_h
+#endif // DFGVarargsForwardingPhase_h
 
diff --git a/Source/JavaScriptCore/dfg/DFGVariableAccessData.cpp b/Source/JavaScriptCore/dfg/DFGVariableAccessData.cpp
index d199f84..bd1ba87e 100644
--- a/Source/JavaScriptCore/dfg/DFGVariableAccessData.cpp
+++ b/Source/JavaScriptCore/dfg/DFGVariableAccessData.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,9 +35,7 @@
     , m_prediction(SpecNone)
     , m_argumentAwarePrediction(SpecNone)
     , m_flags(0)
-    , m_isCaptured(false)
     , m_shouldNeverUnbox(false)
-    , m_isArgumentsAlias(false)
     , m_structureCheckHoistingFailed(false)
     , m_checkArrayHoistingFailed(false)
     , m_isProfitableToUnbox(false)
@@ -47,14 +45,12 @@
     clearVotes();
 }
 
-VariableAccessData::VariableAccessData(VirtualRegister local, bool isCaptured)
+VariableAccessData::VariableAccessData(VirtualRegister local)
     : m_local(local)
     , m_prediction(SpecNone)
     , m_argumentAwarePrediction(SpecNone)
     , m_flags(0)
-    , m_isCaptured(isCaptured)
-    , m_shouldNeverUnbox(isCaptured)
-    , m_isArgumentsAlias(false)
+    , m_shouldNeverUnbox(false)
     , m_structureCheckHoistingFailed(false)
     , m_checkArrayHoistingFailed(false)
     , m_isProfitableToUnbox(false)
@@ -64,12 +60,6 @@
     clearVotes();
 }
 
-bool VariableAccessData::mergeIsCaptured(bool isCaptured)
-{
-    return checkAndSet(m_shouldNeverUnbox, m_shouldNeverUnbox || isCaptured)
-        | checkAndSet(m_isCaptured, m_isCaptured || isCaptured);
-}
-
 bool VariableAccessData::mergeShouldNeverUnbox(bool shouldNeverUnbox)
 {
     bool newShouldNeverUnbox = m_shouldNeverUnbox | shouldNeverUnbox;
@@ -198,9 +188,6 @@
 {
     ASSERT(find() == this);
     
-    if (isArgumentsAlias())
-        return FlushedArguments;
-    
     if (!shouldUnboxIfPossible())
         return FlushedJSValue;
     
diff --git a/Source/JavaScriptCore/dfg/DFGVariableAccessData.h b/Source/JavaScriptCore/dfg/DFGVariableAccessData.h
index 9ead285..0f81756 100644
--- a/Source/JavaScriptCore/dfg/DFGVariableAccessData.h
+++ b/Source/JavaScriptCore/dfg/DFGVariableAccessData.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -48,7 +48,7 @@
 class VariableAccessData : public UnionFind<VariableAccessData> {
 public:
     VariableAccessData();
-    VariableAccessData(VirtualRegister local, bool isCaptured);
+    VariableAccessData(VirtualRegister local);
     
     VirtualRegister local()
     {
@@ -62,13 +62,6 @@
         return m_machineLocal;
     }
 
-    bool mergeIsCaptured(bool isCaptured);
-    
-    bool isCaptured()
-    {
-        return m_isCaptured;
-    }
-    
     bool mergeIsProfitableToUnbox(bool isProfitableToUnbox)
     {
         return checkAndSet(m_isProfitableToUnbox, m_isProfitableToUnbox || isProfitableToUnbox);
@@ -86,7 +79,6 @@
     // mean that we have actually done so.
     bool shouldNeverUnbox()
     {
-        ASSERT(!(m_isCaptured && !m_shouldNeverUnbox));
         return m_shouldNeverUnbox;
     }
     
@@ -118,16 +110,6 @@
         return m_checkArrayHoistingFailed;
     }
     
-    bool mergeIsArgumentsAlias(bool isArgumentsAlias)
-    {
-        return checkAndSet(m_isArgumentsAlias, m_isArgumentsAlias || isArgumentsAlias);
-    }
-    
-    bool isArgumentsAlias()
-    {
-        return m_isArgumentsAlias;
-    }
-    
     bool mergeIsLoadedFrom(bool isLoadedFrom)
     {
         return checkAndSet(m_isLoadedFrom, m_isLoadedFrom || isLoadedFrom);
@@ -193,7 +175,6 @@
         ASSERT(isRoot());
         bool doubleState = m_doubleFormatState == UsingDoubleFormat;
         ASSERT(!(doubleState && shouldNeverUnbox()));
-        ASSERT(!(doubleState && isCaptured()));
         return doubleState && isProfitableToUnbox();
     }
     
@@ -233,9 +214,7 @@
     SpeculatedType m_argumentAwarePrediction;
     NodeFlags m_flags;
 
-    bool m_isCaptured;
     bool m_shouldNeverUnbox;
-    bool m_isArgumentsAlias;
     bool m_structureCheckHoistingFailed;
     bool m_checkArrayHoistingFailed;
     bool m_isProfitableToUnbox;
diff --git a/Source/JavaScriptCore/dfg/DFGVariableAccessDataDump.cpp b/Source/JavaScriptCore/dfg/DFGVariableAccessDataDump.cpp
index 105964c..0062173 100644
--- a/Source/JavaScriptCore/dfg/DFGVariableAccessDataDump.cpp
+++ b/Source/JavaScriptCore/dfg/DFGVariableAccessDataDump.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -62,9 +62,7 @@
         index /= 26;
     }
     
-    if (m_data->isCaptured())
-        out.print("*");
-    else if (m_data->shouldNeverUnbox())
+    if (m_data->shouldNeverUnbox())
         out.print("!");
     else if (!m_data->shouldUnboxIfPossible())
         out.print("~");
diff --git a/Source/JavaScriptCore/dfg/DFGVariableAccessDataDump.h b/Source/JavaScriptCore/dfg/DFGVariableAccessDataDump.h
index fd64e1a..fd53fcd 100644
--- a/Source/JavaScriptCore/dfg/DFGVariableAccessDataDump.h
+++ b/Source/JavaScriptCore/dfg/DFGVariableAccessDataDump.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp b/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp
index 8981de7..50212fa 100644
--- a/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp
+++ b/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -91,8 +91,13 @@
         return true;
     }
     
-    if (node->op() == PhantomArguments) {
-        recovery = ValueRecovery::argumentsThatWereNotCreated();
+    if (node->op() == PhantomDirectArguments) {
+        recovery = ValueRecovery::directArgumentsThatWereNotCreated(node->id());
+        return true;
+    }
+    
+    if (node->op() == PhantomClonedArguments) {
+        recovery = ValueRecovery::outOfBandArgumentsThatWereNotCreated(node->id());
         return true;
     }
     
diff --git a/Source/JavaScriptCore/dfg/DFGVariableEventStream.h b/Source/JavaScriptCore/dfg/DFGVariableEventStream.h
index 9cb78cb..b0e4afa 100644
--- a/Source/JavaScriptCore/dfg/DFGVariableEventStream.h
+++ b/Source/JavaScriptCore/dfg/DFGVariableEventStream.h
@@ -32,6 +32,7 @@
 #include "DFGMinifiedGraph.h"
 #include "DFGVariableEvent.h"
 #include "Operands.h"
+#include "ValueRecovery.h"
 #include <wtf/Vector.h>
 
 namespace JSC { namespace DFG {
diff --git a/Source/JavaScriptCore/ftl/FTLAbstractHeap.cpp b/Source/JavaScriptCore/ftl/FTLAbstractHeap.cpp
index 0037a7a..ce9fa0f 100644
--- a/Source/JavaScriptCore/ftl/FTLAbstractHeap.cpp
+++ b/Source/JavaScriptCore/ftl/FTLAbstractHeap.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -53,6 +53,20 @@
     setMetadata(instruction, repository.m_tbaaKind, tbaaMetadata(repository));
 }
 
+void AbstractHeap::dump(PrintStream& out) const
+{
+    out.print(heapName());
+    if (m_parent)
+        out.print("->", *m_parent);
+}
+
+void AbstractField::dump(PrintStream& out) const
+{
+    out.print(heapName(), "(", m_offset, ")");
+    if (parent())
+        out.print("->", *parent());
+}
+
 IndexedAbstractHeap::IndexedAbstractHeap(LContext context, AbstractHeap* parent, const char* heapName, ptrdiff_t offset, size_t elementSize)
     : m_heapForAnyIndex(parent, heapName)
     , m_heapNameLength(strlen(heapName))
@@ -176,6 +190,11 @@
     RELEASE_ASSERT_NOT_REACHED();
 }
 
+void IndexedAbstractHeap::dump(PrintStream& out) const
+{
+    out.print("Indexed:", atAnyIndex());
+}
+
 NumberedAbstractHeap::NumberedAbstractHeap(LContext context, AbstractHeap* heap, const char* heapName)
     : m_indexedHeap(context, heap, heapName, 0, 1)
 {
@@ -185,6 +204,11 @@
 {
 }
 
+void NumberedAbstractHeap::dump(PrintStream& out) const
+{
+    out.print("Numbered: ", atAnyNumber());
+}
+
 AbsoluteAbstractHeap::AbsoluteAbstractHeap(LContext context, AbstractHeap* heap, const char* heapName)
     : m_indexedHeap(context, heap, heapName, 0, 1)
 {
@@ -194,6 +218,11 @@
 {
 }
 
+void AbsoluteAbstractHeap::dump(PrintStream& out) const
+{
+    out.print("Absolute:", atAnyAddress());
+}
+
 } } // namespace JSC::FTL
 
 #endif // ENABLE(FTL_JIT)
diff --git a/Source/JavaScriptCore/ftl/FTLAbstractHeap.h b/Source/JavaScriptCore/ftl/FTLAbstractHeap.h
index eb163c1..a19ce38 100644
--- a/Source/JavaScriptCore/ftl/FTLAbstractHeap.h
+++ b/Source/JavaScriptCore/ftl/FTLAbstractHeap.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -99,6 +99,8 @@
     
     void decorateInstruction(LValue instruction, const AbstractHeapRepository&) const;
 
+    void dump(PrintStream&) const;
+
 private:
     friend class AbstractHeapRepository;
     
@@ -135,6 +137,8 @@
         return m_offset;
     }
     
+    void dump(PrintStream&) const;
+
 private:
     ptrdiff_t m_offset;
 };
@@ -157,6 +161,8 @@
     
     TypedPointer baseIndex(Output& out, LValue base, LValue index, JSValue indexAsConstant = JSValue(), ptrdiff_t offset = 0);
     
+    void dump(PrintStream&) const;
+
 private:
     const AbstractField& returnInitialized(AbstractField& field, ptrdiff_t index)
     {
@@ -201,6 +207,8 @@
     const AbstractHeap& at(unsigned number) { return m_indexedHeap.at(number); }
     const AbstractHeap& operator[](unsigned number) { return at(number); }
 
+    void dump(PrintStream&) const;
+
 private:
     
     // We use the fact that the indexed heap already has a superset of the
@@ -222,6 +230,8 @@
     
     const AbstractHeap& operator[](void* address) { return at(address); }
 
+    void dump(PrintStream&) const;
+
 private:
     // The trick here is that the indexed heap is "indexed" by a pointer-width
     // integer. Pointers are themselves pointer-width integers. So we can reuse
diff --git a/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.cpp b/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.cpp
index a5fba3a..e416fda 100644
--- a/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.cpp
+++ b/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,11 +28,14 @@
 
 #if ENABLE(FTL_JIT)
 
+#include "DirectArguments.h"
 #include "GetterSetter.h"
 #include "JSEnvironmentRecord.h"
 #include "JSPropertyNameEnumerator.h"
 #include "JSScope.h"
 #include "JSCInlines.h"
+#include "ScopedArguments.h"
+#include "ScopedArgumentsTable.h"
 
 namespace JSC { namespace FTL {
 
diff --git a/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h b/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h
index 19c1ff0f..97cc8f3 100644
--- a/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h
+++ b/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,10 +35,7 @@
 namespace JSC { namespace FTL {
 
 #define FOR_EACH_ABSTRACT_HEAP(macro) \
-    macro(length) \
-    macro(structureTable) \
-    macro(typedArrayProperties) \
-    macro(WriteBarrierBuffer_bufferContents)
+    macro(typedArrayProperties)
 
 #define FOR_EACH_ABSTRACT_FIELD(macro) \
     macro(ArrayBuffer_data, ArrayBuffer::offsetOfData()) \
@@ -46,6 +43,10 @@
     macro(Butterfly_publicLength, Butterfly::offsetOfPublicLength()) \
     macro(Butterfly_vectorLength, Butterfly::offsetOfVectorLength()) \
     macro(CallFrame_callerFrame, CallFrame::callerFrameOffset()) \
+    macro(DirectArguments_callee, DirectArguments::offsetOfCallee()) \
+    macro(DirectArguments_length, DirectArguments::offsetOfLength()) \
+    macro(DirectArguments_minCapacity, DirectArguments::offsetOfMinCapacity()) \
+    macro(DirectArguments_overrides, DirectArguments::offsetOfOverrides()) \
     macro(GetterSetter_getter, GetterSetter::offsetOfGetter()) \
     macro(GetterSetter_setter, GetterSetter::offsetOfSetter()) \
     macro(JSArrayBufferView_length, JSArrayBufferView::offsetOfLength()) \
@@ -70,10 +71,16 @@
     macro(JSString_flags, JSString::offsetOfFlags()) \
     macro(JSString_length, JSString::offsetOfLength()) \
     macro(JSString_value, JSString::offsetOfValue()) \
-    macro(JSEnvironmentRecord_registers, JSEnvironmentRecord::offsetOfRegisters()) \
+    macro(JSSymbolTableObject_symbolTable, JSSymbolTableObject::offsetOfSymbolTable()) \
     macro(JSWrapperObject_internalValue, JSWrapperObject::internalValueOffset()) \
     macro(MarkedAllocator_freeListHead, MarkedAllocator::offsetOfFreeListHead()) \
     macro(MarkedBlock_markBits, MarkedBlock::offsetOfMarks()) \
+    macro(ScopedArguments_overrodeThings, ScopedArguments::offsetOfOverrodeThings()) \
+    macro(ScopedArguments_scope, ScopedArguments::offsetOfScope()) \
+    macro(ScopedArguments_table, ScopedArguments::offsetOfTable()) \
+    macro(ScopedArguments_totalLength, ScopedArguments::offsetOfTotalLength()) \
+    macro(ScopedArgumentsTable_arguments, ScopedArgumentsTable::offsetOfArguments()) \
+    macro(ScopedArgumentsTable_length, ScopedArgumentsTable::offsetOfLength()) \
     macro(StringImpl_data, StringImpl::dataOffset()) \
     macro(StringImpl_hashAndFlags, StringImpl::flagsOffset()) \
     macro(Structure_classInfo, Structure::classInfoOffset()) \
@@ -82,14 +89,23 @@
     macro(Structure_structureID, Structure::structureIDOffset())
 
 #define FOR_EACH_INDEXED_ABSTRACT_HEAP(macro) \
+    macro(DirectArguments_storage, DirectArguments::storageOffset(), sizeof(EncodedJSValue)) \
+    macro(JSEnvironmentRecord_variables, JSEnvironmentRecord::offsetOfVariables(), sizeof(EncodedJSValue)) \
+    macro(JSPropertyNameEnumerator_cachedPropertyNamesVectorContents, 0, sizeof(WriteBarrier<JSString>)) \
     macro(JSRopeString_fibers, JSRopeString::offsetOfFibers(), sizeof(WriteBarrier<JSString>)) \
+    macro(MarkedSpace_Subspace_impreciseAllocators, OBJECT_OFFSETOF(MarkedSpace::Subspace, impreciseAllocators), sizeof(MarkedAllocator)) \
+    macro(MarkedSpace_Subspace_preciseAllocators, OBJECT_OFFSETOF(MarkedSpace::Subspace, preciseAllocators), sizeof(MarkedAllocator)) \
+    macro(ScopedArguments_overflowStorage, ScopedArguments::overflowStorageOffset(), sizeof(EncodedJSValue)) \
+    macro(WriteBarrierBuffer_bufferContents, 0, sizeof(JSCell*)) \
     macro(characters8, 0, sizeof(LChar)) \
     macro(characters16, 0, sizeof(UChar)) \
     macro(indexedInt32Properties, 0, sizeof(EncodedJSValue)) \
     macro(indexedDoubleProperties, 0, sizeof(double)) \
     macro(indexedContiguousProperties, 0, sizeof(EncodedJSValue)) \
     macro(indexedArrayStorageProperties, 0, sizeof(EncodedJSValue)) \
+    macro(scopedArgumentsTableArguments, 0, sizeof(int32_t)) \
     macro(singleCharacterStrings, 0, sizeof(JSString*)) \
+    macro(structureTable, 0, sizeof(Structure*)) \
     macro(variables, 0, sizeof(Register))
     
 #define FOR_EACH_NUMBERED_ABSTRACT_HEAP(macro) \
diff --git a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp b/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
index e0a21db..85de49b 100644
--- a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
+++ b/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
@@ -44,7 +44,6 @@
     
     switch (node->op()) {
     case JSConstant:
-    case GetMyArgumentsLength:
     case GetLocal:
     case SetLocal:
     case PutStack:
@@ -103,9 +102,15 @@
     case ExtractOSREntryLocal:
     case LoopHint:
     case SkipScope:
-    case GetClosureRegisters:
+    case CreateActivation:
+    case NewFunction:
     case GetClosureVar:
     case PutClosureVar:
+    case CreateDirectArguments:
+    case CreateScopedArguments:
+    case CreateClonedArguments:
+    case GetFromArguments:
+    case PutToArguments:
     case InvalidationPoint:
     case StringCharAt:
     case CheckCell:
@@ -124,6 +129,7 @@
     case CallVarargs:
     case CallForwardVarargs:
     case ConstructVarargs:
+    case ConstructForwardVarargs:
     case LoadVarargs:
     case NativeCall:
     case NativeConstruct:
@@ -137,8 +143,8 @@
     case GetExecutable:
     case GetScope:
     case AllocationProfileWatchpoint:
-    case CheckArgumentsNotCreated:
     case GetCallee:
+    case GetArgumentCount:
     case ToString:
     case MakeRope:
     case NewArrayWithSize:
@@ -147,11 +153,9 @@
     case MultiGetByOffset:
     case MultiPutByOffset:
     case ToPrimitive:
-    case PhantomArguments:
     case Throw:
     case ThrowReferenceError:
     case Unreachable:
-    case GetMyArgumentByVal:
     case IsUndefined:
     case IsBoolean:
     case IsNumber:
@@ -180,6 +184,10 @@
     case PutHint:
     case CheckStructureImmediate:
     case MaterializeNewObject:
+    case PhantomDirectArguments:
+    case PhantomClonedArguments:
+    case GetMyArgumentByVal:
+    case ForwardVarargs:
         // These are OK.
         break;
     case Identity:
@@ -208,6 +216,8 @@
         case Array::Int32:
         case Array::Double:
         case Array::Contiguous:
+        case Array::DirectArguments:
+        case Array::ScopedArguments:
             break;
         default:
             if (isTypedView(node->arrayMode().typedArrayType()))
@@ -221,6 +231,8 @@
         case Array::Double:
         case Array::Contiguous:
         case Array::String:
+        case Array::DirectArguments:
+        case Array::ScopedArguments:
             break;
         default:
             if (isTypedView(node->arrayMode().typedArrayType()))
@@ -247,6 +259,8 @@
         case Array::Int32:
         case Array::Double:
         case Array::Contiguous:
+        case Array::DirectArguments:
+        case Array::ScopedArguments:
             break;
         default:
             if (isTypedView(node->arrayMode().typedArrayType()))
@@ -367,17 +381,6 @@
         return CannotCompile;
     }
     
-    if (graph.m_codeBlock->needsActivation()) {
-        // Need this because although we also don't support
-        // CreateActivation, we might not see those nodes in case of
-        // OSR entry.
-        // FIXME: Support activations.
-        // https://bugs.webkit.org/show_bug.cgi?id=129576
-        if (verboseCapabilities())
-            dataLog("FTL rejecting ", *graph.m_codeBlock, " because it uses activations.\n");
-        return CannotCompile;
-    }
-    
     CapabilityLevel result = CanCompileAndOSREnter;
     
     for (BlockIndex blockIndex = graph.numBlocks(); blockIndex--;) {
diff --git a/Source/JavaScriptCore/ftl/FTLCompile.cpp b/Source/JavaScriptCore/ftl/FTLCompile.cpp
index 4b41b89..a83e891 100644
--- a/Source/JavaScriptCore/ftl/FTLCompile.cpp
+++ b/Source/JavaScriptCore/ftl/FTLCompile.cpp
@@ -140,6 +140,9 @@
 
 static int offsetOfStackRegion(StackMaps::RecordMap& recordMap, uint32_t stackmapID)
 {
+    if (stackmapID == UINT_MAX)
+        return 0;
+    
     StackMaps::RecordMap::iterator iter = recordMap.find(stackmapID);
     RELEASE_ASSERT(iter != recordMap.end());
     RELEASE_ASSERT(iter->value.size() == 1);
@@ -301,21 +304,12 @@
     VM& vm = graph.m_vm;
     StackMaps stackmaps = jitCode->stackmaps;
     
-    int localsOffset =
-        offsetOfStackRegion(recordMap, state.capturedStackmapID) + graph.m_nextMachineLocal;
-    
-    int varargsSpillSlotsOffset;
-    if (state.varargsSpillSlotsStackmapID != UINT_MAX)
-        varargsSpillSlotsOffset = offsetOfStackRegion(recordMap, state.varargsSpillSlotsStackmapID);
-    else
-        varargsSpillSlotsOffset = 0;
+    int localsOffset = offsetOfStackRegion(recordMap, state.capturedStackmapID) + graph.m_nextMachineLocal;
+    int varargsSpillSlotsOffset = offsetOfStackRegion(recordMap, state.varargsSpillSlotsStackmapID);
     
     for (unsigned i = graph.m_inlineVariableData.size(); i--;) {
         InlineCallFrame* inlineCallFrame = graph.m_inlineVariableData[i].inlineCallFrame;
         
-        if (inlineCallFrame->argumentsRegister.isValid())
-            inlineCallFrame->argumentsRegister += localsOffset;
-        
         if (inlineCallFrame->argumentCountRegister.isValid())
             inlineCallFrame->argumentCountRegister += localsOffset;
         
@@ -330,11 +324,6 @@
         }
     }
     
-    if (codeBlock->usesArguments()) {
-        codeBlock->setArgumentsRegister(
-            VirtualRegister(codeBlock->argumentsRegister().offset() + localsOffset));
-    }
-
     MacroAssembler::Label stackOverflowException;
 
     {
@@ -396,15 +385,10 @@
             info.m_thunkAddress = linkBuffer->locationOf(info.m_thunkLabel);
             exit.m_patchableCodeOffset = linkBuffer->offsetOf(info.m_thunkJump);
             
-            for (unsigned j = exit.m_values.size(); j--;) {
-                ExitValue value = exit.m_values[j];
-                if (!value.isInJSStackSomehow())
-                    continue;
-                if (!value.virtualRegister().isLocal())
-                    continue;
-                exit.m_values[j] = value.withVirtualRegister(
-                    VirtualRegister(value.virtualRegister().offset() + localsOffset));
-            }
+            for (unsigned j = exit.m_values.size(); j--;)
+                exit.m_values[j] = exit.m_values[j].withLocalsOffset(localsOffset);
+            for (ExitTimeObjectMaterialization* materialization : exit.m_materializations)
+                materialization->accountForLocalsOffset(localsOffset);
             
             if (verboseCompilationEnabled()) {
                 DumpContext context;
@@ -588,7 +572,7 @@
         JSCallVarargs& call = state.jsCallVarargses[i];
         
         CCallHelpers fastPathJIT(&vm, codeBlock);
-        call.emit(fastPathJIT, graph, varargsSpillSlotsOffset);
+        call.emit(fastPathJIT, varargsSpillSlotsOffset);
         
         char* startOfIC = bitwise_cast<char*>(generatedFunction) + call.m_instructionOffset;
         size_t sizeOfIC = sizeOfICFor(call.node());
diff --git a/Source/JavaScriptCore/ftl/FTLExitArgument.cpp b/Source/JavaScriptCore/ftl/FTLExitArgument.cpp
index cbe0de7..381b3d3 100644
--- a/Source/JavaScriptCore/ftl/FTLExitArgument.cpp
+++ b/Source/JavaScriptCore/ftl/FTLExitArgument.cpp
@@ -32,7 +32,7 @@
 
 void ExitArgument::dump(PrintStream& out) const
 {
-    out.print("arg", argument(), " as ", format());
+    out.print("#", argument(), " as ", format());
 }
 
 } } // namespace JSC::FTL
diff --git a/Source/JavaScriptCore/ftl/FTLExitPropertyValue.cpp b/Source/JavaScriptCore/ftl/FTLExitPropertyValue.cpp
index 2b72b69..698874a 100644
--- a/Source/JavaScriptCore/ftl/FTLExitPropertyValue.cpp
+++ b/Source/JavaScriptCore/ftl/FTLExitPropertyValue.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,6 +30,11 @@
 
 namespace JSC { namespace FTL {
 
+ExitPropertyValue ExitPropertyValue::withLocalsOffset(int offset) const
+{
+    return ExitPropertyValue(m_location, m_value.withLocalsOffset(offset));
+}
+
 void ExitPropertyValue::dump(PrintStream& out) const
 {
     out.print(m_location, " => ", m_value);
diff --git a/Source/JavaScriptCore/ftl/FTLExitPropertyValue.h b/Source/JavaScriptCore/ftl/FTLExitPropertyValue.h
index bdb47b9..00ef77c 100644
--- a/Source/JavaScriptCore/ftl/FTLExitPropertyValue.h
+++ b/Source/JavaScriptCore/ftl/FTLExitPropertyValue.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -51,6 +51,8 @@
     DFG::PromotedLocationDescriptor location() const { return m_location; }
     const ExitValue& value() const { return m_value; }
     
+    ExitPropertyValue withLocalsOffset(int offset) const;
+    
     void dump(PrintStream& out) const;
 
 private:
diff --git a/Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.cpp b/Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.cpp
index d57cdac..1fd86a0 100644
--- a/Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.cpp
+++ b/Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,8 +34,9 @@
 
 using namespace JSC::DFG;
 
-ExitTimeObjectMaterialization::ExitTimeObjectMaterialization(NodeType type)
+ExitTimeObjectMaterialization::ExitTimeObjectMaterialization(NodeType type, CodeOrigin codeOrigin)
     : m_type(type)
+    , m_origin(codeOrigin)
 {
 }
 
@@ -58,6 +59,12 @@
     return ExitValue();
 }
 
+void ExitTimeObjectMaterialization::accountForLocalsOffset(int offset)
+{
+    for (ExitPropertyValue& property : m_properties)
+        property = property.withLocalsOffset(offset);
+}
+
 void ExitTimeObjectMaterialization::dump(PrintStream& out) const
 {
     out.print(RawPointer(this), ":", Graph::opName(m_type), "(", listDump(m_properties), ")");
diff --git a/Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.h b/Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.h
index d55affc..b6ac38b 100644
--- a/Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.h
+++ b/Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -38,20 +38,24 @@
 class ExitTimeObjectMaterialization {
     WTF_MAKE_NONCOPYABLE(ExitTimeObjectMaterialization)
 public:
-    ExitTimeObjectMaterialization(DFG::NodeType);
+    ExitTimeObjectMaterialization(DFG::NodeType, CodeOrigin);
     ~ExitTimeObjectMaterialization();
     
     void add(DFG::PromotedLocationDescriptor, const ExitValue&);
     
     DFG::NodeType type() const { return m_type; }
+    CodeOrigin origin() const { return m_origin; }
     
     ExitValue get(DFG::PromotedLocationDescriptor) const;
     const Vector<ExitPropertyValue>& properties() const { return m_properties; }
     
+    void accountForLocalsOffset(int offset);
+    
     void dump(PrintStream& out) const;
     
 private:
     DFG::NodeType m_type;
+    CodeOrigin m_origin;
     Vector<ExitPropertyValue> m_properties;
 };
 
diff --git a/Source/JavaScriptCore/ftl/FTLExitValue.cpp b/Source/JavaScriptCore/ftl/FTLExitValue.cpp
index 275b30a..2bcce6c 100644
--- a/Source/JavaScriptCore/ftl/FTLExitValue.cpp
+++ b/Source/JavaScriptCore/ftl/FTLExitValue.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -41,6 +41,48 @@
     return result;
 }
 
+ExitValue ExitValue::withLocalsOffset(int offset) const
+{
+    if (!isInJSStackSomehow())
+        return *this;
+    if (!virtualRegister().isLocal())
+        return *this;
+    return withVirtualRegister(virtualRegister() + offset);
+}
+
+ValueFormat ExitValue::valueFormat() const
+{
+    switch (kind()) {
+    case InvalidExitValue:
+        RELEASE_ASSERT_NOT_REACHED();
+        return InvalidValueFormat;
+            
+    case ExitValueDead:
+    case ExitValueConstant:
+    case ExitValueInJSStack:
+    case ExitValueMaterializeNewObject:
+        return ValueFormatJSValue;
+            
+    case ExitValueArgument:
+        return exitArgument().format();
+            
+    case ExitValueInJSStackAsInt32:
+        return ValueFormatInt32;
+            
+    case ExitValueInJSStackAsInt52:
+        return ValueFormatInt52;
+            
+    case ExitValueInJSStackAsDouble:
+        return ValueFormatDouble;
+            
+    case ExitValueRecovery:
+        return recoveryFormat();
+    }
+        
+    RELEASE_ASSERT_NOT_REACHED();
+    return InvalidValueFormat;
+}
+
 void ExitValue::dumpInContext(PrintStream& out, DumpContext* context) const
 {
     switch (kind()) {
@@ -68,9 +110,6 @@
     case ExitValueInJSStackAsDouble:
         out.print("InJSStackAsDouble:", virtualRegister());
         return;
-    case ExitValueArgumentsObjectThatWasNotCreated:
-        out.print("ArgumentsObjectThatWasNotCreated");
-        return;
     case ExitValueRecovery:
         out.print("Recovery(", recoveryOpcode(), ", arg", leftRecoveryArgument(), ", arg", rightRecoveryArgument(), ", ", recoveryFormat(), ")");
         return;
diff --git a/Source/JavaScriptCore/ftl/FTLExitValue.h b/Source/JavaScriptCore/ftl/FTLExitValue.h
index b19c350..b34f23a 100644
--- a/Source/JavaScriptCore/ftl/FTLExitValue.h
+++ b/Source/JavaScriptCore/ftl/FTLExitValue.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -51,7 +51,6 @@
     ExitValueInJSStackAsInt32,
     ExitValueInJSStackAsInt52,
     ExitValueInJSStackAsDouble,
-    ExitValueArgumentsObjectThatWasNotCreated,
     ExitValueRecovery,
     ExitValueMaterializeNewObject
 };
@@ -122,13 +121,6 @@
         return result;
     }
     
-    static ExitValue argumentsObjectThatWasNotCreated()
-    {
-        ExitValue result;
-        result.m_kind = ExitValueArgumentsObjectThatWasNotCreated;
-        return result;
-    }
-    
     static ExitValue recovery(RecoveryOpcode opcode, unsigned leftArgument, unsigned rightArgument, ValueFormat format)
     {
         ExitValue result;
@@ -159,7 +151,6 @@
     }
     bool isConstant() const { return kind() == ExitValueConstant; }
     bool isArgument() const { return kind() == ExitValueArgument; }
-    bool isArgumentsObjectThatWasNotCreated() const { return kind() == ExitValueArgumentsObjectThatWasNotCreated; }
     bool isRecovery() const { return kind() == ExitValueRecovery; }
     bool isObjectMaterialization() const { return kind() == ExitValueMaterializeNewObject; }
     
@@ -220,43 +211,13 @@
         return result;
     }
     
+    ExitValue withLocalsOffset(int offset) const;
+    
     // If it's in the JSStack somehow, this will tell you what format it's in, in a manner
     // that is compatible with exitArgument().format(). If it's a constant or it's dead, it
     // will claim to be a JSValue. If it's an argument then it will tell you the argument's
     // format.
-    ValueFormat valueFormat() const
-    {
-        switch (kind()) {
-        case InvalidExitValue:
-            RELEASE_ASSERT_NOT_REACHED();
-            return InvalidValueFormat;
-            
-        case ExitValueDead:
-        case ExitValueConstant:
-        case ExitValueInJSStack:
-        case ExitValueArgumentsObjectThatWasNotCreated:
-        case ExitValueMaterializeNewObject:
-            return ValueFormatJSValue;
-            
-        case ExitValueArgument:
-            return exitArgument().format();
-            
-        case ExitValueInJSStackAsInt32:
-            return ValueFormatInt32;
-            
-        case ExitValueInJSStackAsInt52:
-            return ValueFormatInt52;
-            
-        case ExitValueInJSStackAsDouble:
-            return ValueFormatDouble;
-            
-        case ExitValueRecovery:
-            return recoveryFormat();
-        }
-        
-        RELEASE_ASSERT_NOT_REACHED();
-        return InvalidValueFormat;
-    }
+    ValueFormat valueFormat() const;
 
     void dump(PrintStream&) const;
     void dumpInContext(PrintStream&, DumpContext*) const;
diff --git a/Source/JavaScriptCore/ftl/FTLInlineCacheSize.cpp b/Source/JavaScriptCore/ftl/FTLInlineCacheSize.cpp
index 230a264..dcd5d65 100644
--- a/Source/JavaScriptCore/ftl/FTLInlineCacheSize.cpp
+++ b/Source/JavaScriptCore/ftl/FTLInlineCacheSize.cpp
@@ -85,21 +85,30 @@
 size_t sizeOfCallForwardVarargs()
 {
 #if CPU(ARM64)
-    return 460;
+    return 312;
 #else
-    return 372;
+    return 250;
 #endif
 }
 
 size_t sizeOfConstructVarargs()
 {
 #if CPU(ARM64)
-    return 300;
+    return 332;
 #else
     return 275;
 #endif
 }
 
+size_t sizeOfConstructForwardVarargs()
+{
+#if CPU(ARM64)
+    return 312;
+#else
+    return 250;
+#endif
+}
+
 size_t sizeOfIn()
 {
 #if CPU(ARM64)
@@ -125,6 +134,8 @@
         return sizeOfCallForwardVarargs();
     case ConstructVarargs:
         return sizeOfConstructVarargs();
+    case ConstructForwardVarargs:
+        return sizeOfConstructForwardVarargs();
     case In:
         return sizeOfIn();
     default:
diff --git a/Source/JavaScriptCore/ftl/FTLInlineCacheSize.h b/Source/JavaScriptCore/ftl/FTLInlineCacheSize.h
index 6fe9116..82f3bbc 100644
--- a/Source/JavaScriptCore/ftl/FTLInlineCacheSize.h
+++ b/Source/JavaScriptCore/ftl/FTLInlineCacheSize.h
@@ -42,6 +42,7 @@
 size_t sizeOfCallVarargs();
 size_t sizeOfCallForwardVarargs();
 size_t sizeOfConstructVarargs();
+size_t sizeOfConstructForwardVarargs();
 size_t sizeOfIn();
 
 size_t sizeOfICFor(DFG::Node*);
diff --git a/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h b/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h
index 8f0b274..7a413fc 100644
--- a/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h
+++ b/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h
@@ -63,6 +63,11 @@
     macro(C_JITOperation_EJssJss, functionType(intPtr, intPtr, intPtr, intPtr)) \
     macro(C_JITOperation_EJssJssJss, functionType(intPtr, intPtr, intPtr, intPtr, intPtr)) \
     macro(C_JITOperation_ESt, functionType(intPtr, intPtr, intPtr)) \
+    macro(C_JITOperation_EStJscSymtab, functionType(intPtr, intPtr, intPtr, intPtr, intPtr)) \
+    macro(C_JITOperation_EStRZJsf, functionType(intPtr, intPtr, intPtr, intPtr, int32, intPtr)) \
+    macro(C_JITOperation_EStRZJsfL, functionType(intPtr, intPtr, intPtr, intPtr, int32, intPtr, intPtr)) \
+    macro(C_JITOperation_EStZ, functionType(intPtr, intPtr, intPtr, int32)) \
+    macro(C_JITOperation_EStZZ, functionType(intPtr, intPtr, intPtr, int32, int32)) \
     macro(C_JITOperation_EZ, functionType(intPtr, intPtr, int32)) \
     macro(D_JITOperation_D, functionType(doubleType, doubleType)) \
     macro(I_JITOperation_EJss, functionType(intPtr, intPtr, intPtr)) \
@@ -76,6 +81,7 @@
     macro(J_JITOperation_EJA, functionType(int64, intPtr, int64, intPtr)) \
     macro(J_JITOperation_EJC, functionType(int64, intPtr, int64, intPtr)) \
     macro(J_JITOperation_EJJ, functionType(int64, intPtr, int64, int64)) \
+    macro(J_JITOperation_EJscC, functionType(intPtr, intPtr, intPtr, intPtr)) \
     macro(J_JITOperation_EJssZ, functionType(int64, intPtr, intPtr, int32)) \
     macro(J_JITOperation_ESsiJI, functionType(int64, intPtr, intPtr, int64, intPtr)) \
     macro(Jss_JITOperation_EZ, functionType(intPtr, intPtr, int32)) \
diff --git a/Source/JavaScriptCore/ftl/FTLJSCallVarargs.cpp b/Source/JavaScriptCore/ftl/FTLJSCallVarargs.cpp
index e9b41c7..ac87a3c 100644
--- a/Source/JavaScriptCore/ftl/FTLJSCallVarargs.cpp
+++ b/Source/JavaScriptCore/ftl/FTLJSCallVarargs.cpp
@@ -28,7 +28,6 @@
 
 #if ENABLE(FTL_JIT)
 
-#include "DFGGraph.h"
 #include "DFGNode.h"
 #include "DFGOperations.h"
 #include "JSCInlines.h"
@@ -51,11 +50,14 @@
     : m_stackmapID(stackmapID)
     , m_node(node)
     , m_callBase(
-        node->op() == ConstructVarargs ? CallLinkInfo::ConstructVarargs : CallLinkInfo::CallVarargs,
+        (node->op() == ConstructVarargs || node->op() == ConstructForwardVarargs)
+        ? CallLinkInfo::ConstructVarargs : CallLinkInfo::CallVarargs,
         node->origin.semantic)
     , m_instructionOffset(0)
 {
-    ASSERT(node->op() == CallVarargs || node->op() == CallForwardVarargs || node->op() == ConstructVarargs);
+    ASSERT(
+        node->op() == CallVarargs || node->op() == CallForwardVarargs
+        || node->op() == ConstructVarargs || node->op() == ConstructForwardVarargs);
 }
 
 unsigned JSCallVarargs::numSpillSlotsNeeded()
@@ -63,11 +65,11 @@
     return 4;
 }
 
-void JSCallVarargs::emit(CCallHelpers& jit, Graph& graph, int32_t spillSlotsOffset)
+void JSCallVarargs::emit(CCallHelpers& jit, int32_t spillSlotsOffset)
 {
     // We are passed three pieces of information:
     // - The callee.
-    // - The arguments object.
+    // - The arguments object, if it's not a forwarding call.
     // - The "this" value, if it's a constructor call.
 
     CallVarargsData* data = m_node->callVarargsData();
@@ -76,20 +78,19 @@
     
     GPRReg argumentsGPR = InvalidGPRReg;
     GPRReg thisGPR = InvalidGPRReg;
-    bool argumentsOnStack = false;
+    
+    bool forwarding = false;
     
     switch (m_node->op()) {
     case CallVarargs:
+    case ConstructVarargs:
         argumentsGPR = GPRInfo::argumentGPR1;
         thisGPR = GPRInfo::argumentGPR2;
         break;
     case CallForwardVarargs:
+    case ConstructForwardVarargs:
         thisGPR = GPRInfo::argumentGPR1;
-        argumentsOnStack = true;
-        break;
-    case ConstructVarargs:
-        argumentsGPR = GPRInfo::argumentGPR1;
-        thisGPR = GPRInfo::argumentGPR2;
+        forwarding = true;
         break;
     default:
         RELEASE_ASSERT_NOT_REACHED();
@@ -115,21 +116,9 @@
     GPRReg scratchGPR1 = allocator.allocateScratchGPR();
     GPRReg scratchGPR2 = allocator.allocateScratchGPR();
     GPRReg scratchGPR3 = allocator.allocateScratchGPR();
-    if (argumentsOnStack)
-        argumentsGPR = allocator.allocateScratchGPR();
+
     RELEASE_ASSERT(!allocator.numberOfReusedRegisters());
     
-    auto loadArguments = [&] (bool clobbered) {
-        if (argumentsOnStack) {
-            jit.load64(
-                CCallHelpers::addressFor(graph.machineArgumentsRegisterFor(m_node->origin.semantic)),
-                argumentsGPR);
-        } else if (clobbered) {
-            jit.load64(
-                CCallHelpers::addressFor(spillSlotsOffset + argumentsSpillSlot), argumentsGPR);
-        }
-    };
-    
     auto computeUsedStack = [&] (GPRReg targetGPR, unsigned extra) {
         if (isARM64()) {
             // Have to do this the weird way because $sp on ARM64 means zero when used in a subtraction.
@@ -151,60 +140,54 @@
         m_exceptions.append(jit.emitExceptionCheck(AssemblyHelpers::NormalExceptionCheck, AssemblyHelpers::FarJumpWidth));
     };
     
-    loadArguments(false);
-
     if (isARM64()) {
         jit.move(CCallHelpers::stackPointerRegister, scratchGPR1);
         jit.storePtr(scratchGPR1, CCallHelpers::addressFor(spillSlotsOffset + stackPointerSpillSlot));
     } else
         jit.storePtr(CCallHelpers::stackPointerRegister, CCallHelpers::addressFor(spillSlotsOffset + stackPointerSpillSlot));
-    
-    // Attempt the forwarding fast path, if it's been requested.
-    CCallHelpers::Jump haveArguments;
-    if (m_node->op() == CallForwardVarargs) {
-        // Do the horrific foo.apply(this, arguments) optimization.
-        // FIXME: do this optimization at the IR level.
-        
-        CCallHelpers::JumpList slowCase;
-        slowCase.append(jit.branchTest64(CCallHelpers::NonZero, argumentsGPR));
-        
-        computeUsedStack(scratchGPR2, 0);
-        emitSetupVarargsFrameFastCase(jit, scratchGPR2, scratchGPR1, scratchGPR2, scratchGPR3, m_node->origin.semantic.inlineCallFrame, data->firstVarArgOffset, slowCase);
-        
-        jit.move(calleeGPR, GPRInfo::regT0);
-        haveArguments = jit.jump();
-        slowCase.link(&jit);
-    }
-    
-    // Gotta spill the callee, arguments, and this because we will need them later and we will have some
-    // calls that clobber them.
-    jit.store64(calleeGPR, CCallHelpers::addressFor(spillSlotsOffset + calleeSpillSlot));
-    if (!argumentsOnStack)
-        jit.store64(argumentsGPR, CCallHelpers::addressFor(spillSlotsOffset + argumentsSpillSlot));
-    jit.store64(thisGPR, CCallHelpers::addressFor(spillSlotsOffset + thisSpillSlot));
-    
+
     unsigned extraStack = sizeof(CallerFrameAndPC) +
         WTF::roundUpToMultipleOf(stackAlignmentBytes(), 5 * sizeof(void*));
-    computeUsedStack(scratchGPR1, 0);
-    jit.subPtr(CCallHelpers::TrustedImm32(extraStack), CCallHelpers::stackPointerRegister);
-    jit.setupArgumentsWithExecState(argumentsGPR, scratchGPR1, CCallHelpers::TrustedImm32(data->firstVarArgOffset));
-    callWithExceptionCheck(bitwise_cast<void*>(operationSizeFrameForVarargs));
-    
-    jit.move(GPRInfo::returnValueGPR, scratchGPR1);
-    computeUsedStack(scratchGPR2, extraStack);
-    loadArguments(true);
-    emitSetVarargsFrame(jit, scratchGPR1, false, scratchGPR2, scratchGPR2);
-    jit.addPtr(CCallHelpers::TrustedImm32(-extraStack), scratchGPR2, CCallHelpers::stackPointerRegister);
-    jit.setupArgumentsWithExecState(scratchGPR2, argumentsGPR, CCallHelpers::TrustedImm32(data->firstVarArgOffset), scratchGPR1);
-    callWithExceptionCheck(bitwise_cast<void*>(operationSetupVarargsFrame));
-    
-    jit.move(GPRInfo::returnValueGPR, scratchGPR2);
 
-    jit.load64(CCallHelpers::addressFor(spillSlotsOffset + thisSpillSlot), thisGPR);
-    jit.load64(CCallHelpers::addressFor(spillSlotsOffset + calleeSpillSlot), GPRInfo::regT0);
+    if (forwarding) {
+        CCallHelpers::JumpList slowCase;
+        computeUsedStack(scratchGPR2, 0);
+        emitSetupVarargsFrameFastCase(jit, scratchGPR2, scratchGPR1, scratchGPR2, scratchGPR3, m_node->child2()->origin.semantic.inlineCallFrame, data->firstVarArgOffset, slowCase);
+        
+        CCallHelpers::Jump done = jit.jump();
+        slowCase.link(&jit);
+        jit.subPtr(CCallHelpers::TrustedImm32(extraStack), CCallHelpers::stackPointerRegister);
+        jit.setupArgumentsExecState();
+        callWithExceptionCheck(bitwise_cast<void*>(operationThrowStackOverflowForVarargs));
+        jit.abortWithReason(DFGVarargsThrowingPathDidNotThrow);
+        
+        done.link(&jit);
+        jit.move(calleeGPR, GPRInfo::regT0);
+    } else {
+        // Gotta spill the callee, arguments, and this because we will need them later and we will have some
+        // calls that clobber them.
+        jit.store64(calleeGPR, CCallHelpers::addressFor(spillSlotsOffset + calleeSpillSlot));
+        jit.store64(argumentsGPR, CCallHelpers::addressFor(spillSlotsOffset + argumentsSpillSlot));
+        jit.store64(thisGPR, CCallHelpers::addressFor(spillSlotsOffset + thisSpillSlot));
     
-    if (m_node->op() == CallForwardVarargs)
-        haveArguments.link(&jit);
+        computeUsedStack(scratchGPR1, 0);
+        jit.subPtr(CCallHelpers::TrustedImm32(extraStack), CCallHelpers::stackPointerRegister);
+        jit.setupArgumentsWithExecState(argumentsGPR, scratchGPR1, CCallHelpers::TrustedImm32(data->firstVarArgOffset));
+        callWithExceptionCheck(bitwise_cast<void*>(operationSizeFrameForVarargs));
+    
+        jit.move(GPRInfo::returnValueGPR, scratchGPR1);
+        computeUsedStack(scratchGPR2, extraStack);
+        jit.load64(CCallHelpers::addressFor(spillSlotsOffset + argumentsSpillSlot), argumentsGPR);
+        emitSetVarargsFrame(jit, scratchGPR1, false, scratchGPR2, scratchGPR2);
+        jit.addPtr(CCallHelpers::TrustedImm32(-extraStack), scratchGPR2, CCallHelpers::stackPointerRegister);
+        jit.setupArgumentsWithExecState(scratchGPR2, argumentsGPR, CCallHelpers::TrustedImm32(data->firstVarArgOffset), scratchGPR1);
+        callWithExceptionCheck(bitwise_cast<void*>(operationSetupVarargsFrame));
+    
+        jit.move(GPRInfo::returnValueGPR, scratchGPR2);
+
+        jit.load64(CCallHelpers::addressFor(spillSlotsOffset + thisSpillSlot), thisGPR);
+        jit.load64(CCallHelpers::addressFor(spillSlotsOffset + calleeSpillSlot), GPRInfo::regT0);
+    }
     
     jit.addPtr(CCallHelpers::TrustedImm32(sizeof(CallerFrameAndPC)), scratchGPR2, CCallHelpers::stackPointerRegister);
 
diff --git a/Source/JavaScriptCore/ftl/FTLJSCallVarargs.h b/Source/JavaScriptCore/ftl/FTLJSCallVarargs.h
index cdaefb9..5128ff8 100644
--- a/Source/JavaScriptCore/ftl/FTLJSCallVarargs.h
+++ b/Source/JavaScriptCore/ftl/FTLJSCallVarargs.h
@@ -35,7 +35,6 @@
 class LinkBuffer;
 
 namespace DFG {
-class Graph;
 struct Node;
 }
 
@@ -50,7 +49,7 @@
     
     static unsigned numSpillSlotsNeeded();
     
-    void emit(CCallHelpers&, DFG::Graph&, int32_t spillSlotsOffset);
+    void emit(CCallHelpers&, int32_t spillSlotsOffset);
     void link(VM&, LinkBuffer&, CodeLocationLabel exceptionHandler);
     
     unsigned stackmapID() const { return m_stackmapID; }
diff --git a/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp b/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
index 252c31d..a040d67 100644
--- a/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
+++ b/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
@@ -32,6 +32,7 @@
 #include "DFGAbstractInterpreterInlines.h"
 #include "DFGInPlaceAbstractState.h"
 #include "DFGOSRAvailabilityAnalysisPhase.h"
+#include "DirectArguments.h"
 #include "FTLAbstractHeapRepository.h"
 #include "FTLAvailableRecovery.h"
 #include "FTLForOSREntryJITCode.h"
@@ -43,7 +44,10 @@
 #include "FTLThunks.h"
 #include "FTLWeightedTarget.h"
 #include "JSCInlines.h"
+#include "JSLexicalEnvironment.h"
 #include "OperandsInlines.h"
+#include "ScopedArguments.h"
+#include "ScopedArgumentsTable.h"
 #include "VirtualRegister.h"
 #include <atomic>
 #include <dlfcn.h>
@@ -167,21 +171,18 @@
                 }
             }
         }
-
-        LValue capturedAlloca = m_out.alloca(arrayType(m_out.int64, m_graph.m_nextMachineLocal));
-
+        
         if (maxNumberOfArguments >= 0) {
             m_execState = m_out.alloca(arrayType(m_out.int64, JSStack::CallFrameHeaderSize + maxNumberOfArguments));
             m_execStorage = m_out.ptrToInt(m_execState, m_out.intPtr);        
         }
 
+        LValue capturedAlloca = m_out.alloca(arrayType(m_out.int64, m_graph.m_nextMachineLocal));
+        
         m_captured = m_out.add(
             m_out.ptrToInt(capturedAlloca, m_out.intPtr),
             m_out.constIntPtr(m_graph.m_nextMachineLocal * sizeof(Register)));
         
-        // We should not create any alloca's after this point, since they will cease to
-        // be mem2reg candidates.
-        
         m_ftlState.capturedStackmapID = m_stackmapIDs++;
         m_out.call(
             m_out.stackmapIntrinsic(), m_out.constInt64(m_ftlState.capturedStackmapID),
@@ -195,6 +196,7 @@
                 case CallVarargs:
                 case CallForwardVarargs:
                 case ConstructVarargs:
+                case ConstructForwardVarargs:
                     hasVarargs = true;
                     break;
                 default:
@@ -211,6 +213,9 @@
                 m_out.int32Zero, varargsSpillSlots);
         }
         
+        // We should not create any alloca's after this point, since they will cease to
+        // be mem2reg candidates.
+        
         m_callFrame = m_out.ptrToInt(
             m_out.call(m_out.frameAddressIntrinsic(), m_out.int32Zero), m_out.intPtr);
         m_tagTypeNumber = m_out.constInt64(TagTypeNumber);
@@ -434,9 +439,6 @@
         case Int52Constant:
             compileInt52Constant();
             break;
-        case PhantomArguments:
-            compilePhantomArguments();
-            break;
         case DoubleRep:
             compileDoubleRep();
             break;
@@ -461,12 +463,6 @@
         case PutStack:
             compilePutStack();
             break;
-        case GetMyArgumentsLength:
-            compileGetMyArgumentsLength();
-            break;
-        case GetMyArgumentByVal:
-            compileGetMyArgumentByVal();
-            break;
         case Phantom:
         case HardPhantom:
         case Check:
@@ -592,6 +588,9 @@
         case GetByVal:
             compileGetByVal();
             break;
+        case GetMyArgumentByVal:
+            compileGetMyArgumentByVal();
+            break;
         case PutByVal:
         case PutByValAlias:
         case PutByValDirect:
@@ -603,6 +602,21 @@
         case ArrayPop:
             compileArrayPop();
             break;
+        case CreateActivation:
+            compileCreateActivation();
+            break;
+        case NewFunction:
+            compileNewFunction();
+            break;
+        case CreateDirectArguments:
+            compileCreateDirectArguments();
+            break;
+        case CreateScopedArguments:
+            compileCreateScopedArguments();
+            break;
+        case CreateClonedArguments:
+            compileCreateClonedArguments();
+            break;
         case NewObject:
             compileNewObject();
             break;
@@ -670,21 +684,27 @@
         case GetCallee:
             compileGetCallee();
             break;
+        case GetArgumentCount:
+            compileGetArgumentCount();
+            break;
         case GetScope:
             compileGetScope();
             break;
         case SkipScope:
             compileSkipScope();
             break;
-        case GetClosureRegisters:
-            compileGetClosureRegisters();
-            break;
         case GetClosureVar:
             compileGetClosureVar();
             break;
         case PutClosureVar:
             compilePutClosureVar();
             break;
+        case GetFromArguments:
+            compileGetFromArguments();
+            break;
+        case PutToArguments:
+            compilePutToArguments();
+            break;
         case CompareEq:
             compileCompareEq();
             break;
@@ -716,11 +736,15 @@
         case CallVarargs:
         case CallForwardVarargs:
         case ConstructVarargs:
+        case ConstructForwardVarargs:
             compileCallOrConstructVarargs();
             break;
         case LoadVarargs:
             compileLoadVarargs();
             break;
+        case ForwardVarargs:
+            compileForwardVarargs();
+            break;
 #if ENABLE(FTL_NATIVE_CALL_INLINING)
         case NativeCall:
         case NativeConstruct:
@@ -749,9 +773,6 @@
         case InvalidationPoint:
             compileInvalidationPoint();
             break;
-        case CheckArgumentsNotCreated:
-            compileCheckArgumentsNotCreated();
-            break;
         case IsUndefined:
             compileIsUndefined();
             break;
@@ -829,6 +850,8 @@
         case MovHint:
         case ZombieHint:
         case PhantomNewObject:
+        case PhantomDirectArguments:
+        case PhantomClonedArguments:
         case PutHint:
         case BottomValue:
         case KillStack:
@@ -838,7 +861,7 @@
             break;
         }
 
-        if (!m_state.isValid()) {
+        if (!m_state.isValid() && !m_node->isTerminal()) {
             safelyInvalidateAfterTermination();
             return false;
         }
@@ -917,11 +940,6 @@
         setStrictInt52(m_out.constInt64(value));
     }
 
-    void compilePhantomArguments()
-    {
-        setJSValue(m_out.constInt64(JSValue::encode(JSValue())));
-    }
-    
     void compileDoubleRep()
     {
         switch (m_node->child1().useKind()) {
@@ -1095,8 +1113,7 @@
     {
         StackAccessData* data = m_node->stackAccessData();
         switch (data->format) {
-        case FlushedJSValue:
-        case FlushedArguments: {
+        case FlushedJSValue: {
             LValue value = lowJSValue(m_node->child1());
             m_out.store64(value, addressFor(data->machineLocal));
             break;
@@ -2116,79 +2133,6 @@
         setInt32(m_out.castToInt32(m_out.phi(m_out.intPtr, simpleOut, wastefulOut)));
     }
     
-    void compileGetMyArgumentsLength() 
-    {
-        checkArgumentsNotCreated();
-
-        if (m_node->origin.semantic.inlineCallFrame
-            && !m_node->origin.semantic.inlineCallFrame->isVarargs()) {
-            setInt32(
-                m_out.constInt32(
-                    m_node->origin.semantic.inlineCallFrame->arguments.size() - 1));
-        } else {
-            VirtualRegister argumentCountRegister;
-            if (!m_node->origin.semantic.inlineCallFrame)
-                argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
-            else
-                argumentCountRegister = m_node->origin.semantic.inlineCallFrame->argumentCountRegister;
-            setInt32(
-                m_out.add(
-                    m_out.load32NonNegative(payloadFor(argumentCountRegister)),
-                    m_out.constInt32(-1)));
-        }
-    }
-    
-    void compileGetMyArgumentByVal()
-    {
-        checkArgumentsNotCreated();
-        
-        CodeOrigin codeOrigin = m_node->origin.semantic;
-        
-        LValue index = lowInt32(m_node->child1());
-        
-        LValue limit;
-        if (codeOrigin.inlineCallFrame
-            && !codeOrigin.inlineCallFrame->isVarargs())
-            limit = m_out.constInt32(codeOrigin.inlineCallFrame->arguments.size() - 1);
-        else {
-            VirtualRegister argumentCountRegister;
-            if (!codeOrigin.inlineCallFrame)
-                argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
-            else
-                argumentCountRegister = codeOrigin.inlineCallFrame->argumentCountRegister;
-            limit = m_out.sub(m_out.load32(payloadFor(argumentCountRegister)), m_out.int32One);
-        }
-        
-        speculate(Uncountable, noValue(), 0, m_out.aboveOrEqual(index, limit));
-        
-        SymbolTable* symbolTable = m_graph.baselineCodeBlockFor(codeOrigin)->symbolTable();
-        if (symbolTable->slowArguments()) {
-            // FIXME: FTL should support activations.
-            // https://bugs.webkit.org/show_bug.cgi?id=129576
-            
-            DFG_CRASH(m_graph, m_node, "Unimplemented");
-        }
-        
-        TypedPointer base;
-        if (codeOrigin.inlineCallFrame) {
-            if (codeOrigin.inlineCallFrame->arguments.size() <= 1) {
-                // We should have already exited due to the bounds check, above. Just tell the
-                // compiler that anything dominated by this instruction is not reachable, so
-                // that we don't waste time generating such code. This will also plant some
-                // kind of crashing instruction so that if by some fluke the bounds check didn't
-                // work, we'll crash in an easy-to-see way.
-                didAlreadyTerminate();
-                return;
-            }
-            base = addressFor(codeOrigin.inlineCallFrame->arguments[1].virtualRegister());
-        } else
-            base = addressFor(virtualRegisterForArgument(1));
-        
-        LValue pointer = m_out.baseIndex(
-            base.value(), m_out.zeroExt(index, m_out.intPtr), ScaleEight);
-        setJSValue(m_out.load64(TypedPointer(m_heaps.variables.atAnyIndex(), pointer)));
-    }
-
     void compileGetArrayLength()
     {
         switch (m_node->arrayMode().type()) {
@@ -2205,6 +2149,24 @@
             return;
         }
             
+        case Array::DirectArguments: {
+            LValue arguments = lowCell(m_node->child1());
+            speculate(
+                ExoticObjectMode, noValue(), nullptr,
+                m_out.notNull(m_out.loadPtr(arguments, m_heaps.DirectArguments_overrides)));
+            setInt32(m_out.load32NonNegative(arguments, m_heaps.DirectArguments_length));
+            return;
+        }
+            
+        case Array::ScopedArguments: {
+            LValue arguments = lowCell(m_node->child1());
+            speculate(
+                ExoticObjectMode, noValue(), nullptr,
+                m_out.notZero8(m_out.loadPtr(arguments, m_heaps.ScopedArguments_overrodeThings)));
+            setInt32(m_out.load32NonNegative(arguments, m_heaps.ScopedArguments_totalLength));
+            return;
+        }
+            
         default:
             if (isTypedView(m_node->arrayMode().typedArrayType())) {
                 setInt32(
@@ -2322,6 +2284,78 @@
             return;
         }
             
+        case Array::DirectArguments: {
+            LValue base = lowCell(m_node->child1());
+            LValue index = lowInt32(m_node->child2());
+            
+            speculate(
+                ExoticObjectMode, noValue(), nullptr,
+                m_out.notNull(m_out.loadPtr(base, m_heaps.DirectArguments_overrides)));
+            speculate(
+                ExoticObjectMode, noValue(), nullptr,
+                m_out.aboveOrEqual(
+                    index,
+                    m_out.load32NonNegative(base, m_heaps.DirectArguments_length)));
+
+            TypedPointer address = m_out.baseIndex(
+                m_heaps.DirectArguments_storage, base, m_out.zeroExtPtr(index));
+            setJSValue(m_out.load64(address));
+            return;
+        }
+            
+        case Array::ScopedArguments: {
+            LValue base = lowCell(m_node->child1());
+            LValue index = lowInt32(m_node->child2());
+            
+            speculate(
+                ExoticObjectMode, noValue(), nullptr,
+                m_out.aboveOrEqual(
+                    index,
+                    m_out.load32NonNegative(base, m_heaps.ScopedArguments_totalLength)));
+            
+            LValue table = m_out.loadPtr(base, m_heaps.ScopedArguments_table);
+            LValue namedLength = m_out.load32(table, m_heaps.ScopedArgumentsTable_length);
+            
+            LBasicBlock namedCase = FTL_NEW_BLOCK(m_out, ("GetByVal ScopedArguments named case"));
+            LBasicBlock overflowCase = FTL_NEW_BLOCK(m_out, ("GetByVal ScopedArguments overflow case"));
+            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetByVal ScopedArguments continuation"));
+            
+            m_out.branch(
+                m_out.aboveOrEqual(index, namedLength), unsure(overflowCase), unsure(namedCase));
+            
+            LBasicBlock lastNext = m_out.appendTo(namedCase, overflowCase);
+            
+            LValue scope = m_out.loadPtr(base, m_heaps.ScopedArguments_scope);
+            LValue arguments = m_out.loadPtr(table, m_heaps.ScopedArgumentsTable_arguments);
+            
+            TypedPointer address = m_out.baseIndex(
+                m_heaps.scopedArgumentsTableArguments, arguments, m_out.zeroExtPtr(index));
+            LValue scopeOffset = m_out.load32(address);
+            
+            speculate(
+                ExoticObjectMode, noValue(), nullptr,
+                m_out.equal(scopeOffset, m_out.constInt32(ScopeOffset::invalidOffset)));
+            
+            address = m_out.baseIndex(
+                m_heaps.JSEnvironmentRecord_variables, scope, m_out.zeroExtPtr(scopeOffset));
+            ValueFromBlock namedResult = m_out.anchor(m_out.load64(address));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(overflowCase, continuation);
+            
+            address = m_out.baseIndex(
+                m_heaps.ScopedArguments_overflowStorage, base,
+                m_out.zeroExtPtr(m_out.sub(index, namedLength)));
+            LValue overflowValue = m_out.load64(address);
+            speculate(ExoticObjectMode, noValue(), nullptr, m_out.isZero64(overflowValue));
+            ValueFromBlock overflowResult = m_out.anchor(overflowValue);
+            m_out.jump(continuation);
+            
+            m_out.appendTo(continuation, lastNext);
+            setJSValue(m_out.phi(m_out.int64, namedResult, overflowResult));
+            return;
+        }
+            
         case Array::Generic: {
             setJSValue(vmCall(
                 m_out.operation(operationGetByVal), m_callFrame,
@@ -2346,7 +2380,7 @@
                     m_out.add(
                         storage,
                         m_out.shl(
-                            m_out.zeroExt(index, m_out.intPtr),
+                            m_out.zeroExtPtr(index),
                             m_out.constIntPtr(logElementSize(type)))));
                 
                 if (isInt(type)) {
@@ -2418,6 +2452,46 @@
         } }
     }
     
+    void compileGetMyArgumentByVal()
+    {
+        InlineCallFrame* inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
+        
+        LValue index = lowInt32(m_node->child2());
+        
+        LValue limit;
+        if (inlineCallFrame && !inlineCallFrame->isVarargs())
+            limit = m_out.constInt32(inlineCallFrame->arguments.size() - 1);
+        else {
+            VirtualRegister argumentCountRegister;
+            if (!inlineCallFrame)
+                argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
+            else
+                argumentCountRegister = inlineCallFrame->argumentCountRegister;
+            limit = m_out.sub(m_out.load32(payloadFor(argumentCountRegister)), m_out.int32One);
+        }
+        
+        speculate(ExoticObjectMode, noValue(), 0, m_out.aboveOrEqual(index, limit));
+        
+        TypedPointer base;
+        if (inlineCallFrame) {
+            if (inlineCallFrame->arguments.size() <= 1) {
+                // We should have already exited due to the bounds check, above. Just tell the
+                // compiler that anything dominated by this instruction is not reachable, so
+                // that we don't waste time generating such code. This will also plant some
+                // kind of crashing instruction so that if by some fluke the bounds check didn't
+                // work, we'll crash in an easy-to-see way.
+                didAlreadyTerminate();
+                return;
+            }
+            base = addressFor(inlineCallFrame->arguments[1].virtualRegister());
+        } else
+            base = addressFor(virtualRegisterForArgument(1));
+        
+        LValue pointer = m_out.baseIndex(
+            base.value(), m_out.zeroExt(index, m_out.intPtr), ScaleEight);
+        setJSValue(m_out.load64(TypedPointer(m_heaps.variables.atAnyIndex(), pointer)));
+    }
+    
     void compilePutByVal()
     {
         Edge child1 = m_graph.varArgChild(m_node, 0);
@@ -2473,8 +2547,7 @@
                 TypedPointer elementPointer = m_out.baseIndex(
                     m_node->arrayMode().type() == Array::Int32 ?
                     m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties,
-                    storage, m_out.zeroExt(index, m_out.intPtr),
-                    m_state.forNode(child2).m_value);
+                    storage, m_out.zeroExtPtr(index), m_state.forNode(child2).m_value);
                 
                 if (m_node->op() == PutByValAlias) {
                     m_out.store64(value, elementPointer);
@@ -2499,8 +2572,7 @@
                     m_out.doubleNotEqualOrUnordered(value, value));
                 
                 TypedPointer elementPointer = m_out.baseIndex(
-                    m_heaps.indexedDoubleProperties,
-                    storage, m_out.zeroExt(index, m_out.intPtr),
+                    m_heaps.indexedDoubleProperties, storage, m_out.zeroExtPtr(index),
                     m_state.forNode(child2).m_value);
                 
                 if (m_node->op() == PutByValAlias) {
@@ -2714,9 +2786,7 @@
             
             LBasicBlock lastNext = m_out.appendTo(fastPath, slowPath);
             m_out.store(
-                value,
-                m_out.baseIndex(heap, storage, m_out.zeroExt(prevLength, m_out.intPtr)),
-                refType);
+                value, m_out.baseIndex(heap, storage, m_out.zeroExtPtr(prevLength)), refType);
             LValue newLength = m_out.add(prevLength, m_out.int32One);
             m_out.store32(newLength, storage, m_heaps.Butterfly_publicLength);
             
@@ -2769,8 +2839,7 @@
             LBasicBlock lastNext = m_out.appendTo(fastCase, slowCase);
             LValue newLength = m_out.sub(prevLength, m_out.int32One);
             m_out.store32(newLength, storage, m_heaps.Butterfly_publicLength);
-            TypedPointer pointer = m_out.baseIndex(
-                heap, storage, m_out.zeroExt(newLength, m_out.intPtr));
+            TypedPointer pointer = m_out.baseIndex(heap, storage, m_out.zeroExtPtr(newLength));
             if (m_node->arrayMode().type() != Array::Double) {
                 LValue result = m_out.load64(pointer);
                 m_out.store64(m_out.int64Zero, pointer);
@@ -2802,6 +2871,173 @@
         }
     }
     
+    void compileCreateActivation()
+    {
+        LValue scope = lowCell(m_node->child1());
+        SymbolTable* table = m_graph.symbolTableFor(m_node->origin.semantic);
+        Structure* structure = m_graph.globalObjectFor(m_node->origin.semantic)->activationStructure();
+        
+        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("CreateActivation slow path"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("CreateActivation continuation"));
+        
+        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
+        
+        LValue fastObject = allocateObject<JSLexicalEnvironment>(
+            JSLexicalEnvironment::allocationSize(table), structure, m_out.intPtrZero, slowPath);
+        
+        // We don't need memory barriers since we just fast-created the activation, so the
+        // activation must be young.
+        m_out.storePtr(scope, fastObject, m_heaps.JSScope_next);
+        m_out.storePtr(weakPointer(table), fastObject, m_heaps.JSSymbolTableObject_symbolTable);
+        
+        for (unsigned i = 0; i < table->scopeSize(); ++i) {
+            m_out.store64(
+                m_out.constInt64(JSValue::encode(jsUndefined())),
+                fastObject, m_heaps.JSEnvironmentRecord_variables[i]);
+        }
+        
+        ValueFromBlock fastResult = m_out.anchor(fastObject);
+        m_out.jump(continuation);
+        
+        m_out.appendTo(slowPath, continuation);
+        LValue callResult = vmCall(
+            m_out.operation(operationCreateActivationDirect), m_callFrame, weakPointer(structure),
+            scope, weakPointer(table));
+        ValueFromBlock slowResult = m_out.anchor(callResult);
+        m_out.jump(continuation);
+        
+        m_out.appendTo(continuation, lastNext);
+        setJSValue(m_out.phi(m_out.intPtr, fastResult, slowResult));
+    }
+    
+    void compileNewFunction()
+    {
+        LValue result = vmCall(
+            m_out.operation(operationNewFunction), m_callFrame,
+            lowCell(m_node->child1()), weakPointer(m_node->castOperand<FunctionExecutable*>()));
+        setJSValue(result);
+    }
+    
+    void compileCreateDirectArguments()
+    {
+        // FIXME: A more effective way of dealing with the argument count and callee is to have
+        // them be explicit arguments to this node.
+        // https://bugs.webkit.org/show_bug.cgi?id=142207
+        
+        Structure* structure =
+            m_graph.globalObjectFor(m_node->origin.semantic)->directArgumentsStructure();
+        
+        unsigned minCapacity = m_graph.baselineCodeBlockFor(m_node->origin.semantic)->numParameters() - 1;
+        
+        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("CreateDirectArguments slow path"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("CreateDirectArguments continuation"));
+        
+        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
+        
+        ArgumentsLength length = getArgumentsLength();
+        
+        LValue fastObject;
+        if (length.isKnown) {
+            fastObject = allocateObject<DirectArguments>(
+                DirectArguments::allocationSize(std::max(length.known, minCapacity)), structure,
+                m_out.intPtrZero, slowPath);
+        } else {
+            LValue size = m_out.add(
+                m_out.shl(length.value, m_out.constInt32(3)),
+                m_out.constInt32(DirectArguments::storageOffset()));
+            
+            size = m_out.select(
+                m_out.aboveOrEqual(length.value, m_out.constInt32(minCapacity)),
+                size, m_out.constInt32(DirectArguments::allocationSize(minCapacity)));
+            
+            fastObject = allocateVariableSizedObject<DirectArguments>(
+                size, structure, m_out.intPtrZero, slowPath);
+        }
+        
+        m_out.store32(length.value, fastObject, m_heaps.DirectArguments_length);
+        m_out.store32(m_out.constInt32(minCapacity), fastObject, m_heaps.DirectArguments_minCapacity);
+        m_out.storePtr(m_out.intPtrZero, fastObject, m_heaps.DirectArguments_overrides);
+        m_out.storePtr(getCurrentCallee(), fastObject, m_heaps.DirectArguments_callee);
+        
+        ValueFromBlock fastResult = m_out.anchor(fastObject);
+        m_out.jump(continuation);
+        
+        m_out.appendTo(slowPath, continuation);
+        LValue callResult = vmCall(
+            m_out.operation(operationCreateDirectArguments), m_callFrame, weakPointer(structure),
+            length.value, m_out.constInt32(minCapacity));
+        ValueFromBlock slowResult = m_out.anchor(callResult);
+        m_out.jump(continuation);
+        
+        m_out.appendTo(continuation, lastNext);
+        LValue result = m_out.phi(m_out.intPtr, fastResult, slowResult);
+        
+        if (length.isKnown) {
+            VirtualRegister start = AssemblyHelpers::argumentsStart(m_node->origin.semantic);
+            for (unsigned i = 0; i < std::max(length.known, minCapacity); ++i) {
+                m_out.store64(
+                    m_out.load64(addressFor(start + i)),
+                    result, m_heaps.DirectArguments_storage[i]);
+            }
+        } else {
+            LValue stackBase = getArgumentsStart();
+            
+            LBasicBlock loop = FTL_NEW_BLOCK(m_out, ("CreateDirectArguments loop body"));
+            LBasicBlock end = FTL_NEW_BLOCK(m_out, ("CreateDirectArguments loop end"));
+            
+            ValueFromBlock originalLength;
+            if (minCapacity) {
+                LValue capacity = m_out.select(
+                    m_out.aboveOrEqual(length.value, m_out.constInt32(minCapacity)),
+                    length.value,
+                    m_out.constInt32(minCapacity));
+                originalLength = m_out.anchor(m_out.zeroExtPtr(capacity));
+                m_out.jump(loop);
+            } else {
+                originalLength = m_out.anchor(m_out.zeroExtPtr(length.value));
+                m_out.branch(m_out.isNull(originalLength.value()), unsure(end), unsure(loop));
+            }
+            
+            lastNext = m_out.appendTo(loop, end);
+            LValue previousIndex = m_out.phi(m_out.intPtr, originalLength);
+            LValue index = m_out.sub(previousIndex, m_out.intPtrOne);
+            m_out.store64(
+                m_out.load64(m_out.baseIndex(m_heaps.variables, stackBase, index)),
+                m_out.baseIndex(m_heaps.DirectArguments_storage, result, index));
+            ValueFromBlock nextIndex = m_out.anchor(index);
+            addIncoming(previousIndex, nextIndex);
+            m_out.branch(m_out.isNull(index), unsure(end), unsure(loop));
+            
+            m_out.appendTo(end, lastNext);
+        }
+        
+        setJSValue(result);
+    }
+    
+    void compileCreateScopedArguments()
+    {
+        LValue scope = lowCell(m_node->child1());
+        
+        LValue result = vmCall(
+            m_out.operation(operationCreateScopedArguments), m_callFrame,
+            weakPointer(
+                m_graph.globalObjectFor(m_node->origin.semantic)->scopedArgumentsStructure()),
+            getArgumentsStart(), getArgumentsLength().value, getCurrentCallee(), scope);
+        
+        setJSValue(result);
+    }
+    
+    void compileCreateClonedArguments()
+    {
+        LValue result = vmCall(
+            m_out.operation(operationCreateClonedArguments), m_callFrame,
+            weakPointer(
+                m_graph.globalObjectFor(m_node->origin.semantic)->outOfBandArgumentsStructure()),
+            getArgumentsStart(), getArgumentsLength().value, getCurrentCallee());
+        
+        setJSValue(result);
+    }
+    
     void compileNewObject()
     {
         setJSValue(allocateObject(m_node->structure()));
@@ -3267,8 +3503,7 @@
             
         ValueFromBlock char8Bit = m_out.anchor(m_out.zeroExt(
             m_out.load8(m_out.baseIndex(
-                m_heaps.characters8,
-                storage, m_out.zeroExt(index, m_out.intPtr),
+                m_heaps.characters8, storage, m_out.zeroExtPtr(index),
                 m_state.forNode(m_node->child2()).m_value)),
             m_out.int32));
         m_out.jump(bitsContinuation);
@@ -3277,8 +3512,7 @@
             
         ValueFromBlock char16Bit = m_out.anchor(m_out.zeroExt(
             m_out.load16(m_out.baseIndex(
-                m_heaps.characters16,
-                storage, m_out.zeroExt(index, m_out.intPtr),
+                m_heaps.characters16, storage, m_out.zeroExtPtr(index),
                 m_state.forNode(m_node->child2()).m_value)),
             m_out.int32));
         m_out.branch(
@@ -3300,8 +3534,7 @@
         LValue smallStrings = m_out.constIntPtr(vm().smallStrings.singleCharacterStrings());
             
         results.append(m_out.anchor(m_out.loadPtr(m_out.baseIndex(
-            m_heaps.singleCharacterStrings, smallStrings,
-            m_out.zeroExt(character, m_out.intPtr)))));
+            m_heaps.singleCharacterStrings, smallStrings, m_out.zeroExtPtr(character)))));
         m_out.jump(continuation);
             
         m_out.appendTo(slowPath, continuation);
@@ -3360,8 +3593,7 @@
             
         ValueFromBlock char8Bit = m_out.anchor(m_out.zeroExt(
             m_out.load8(m_out.baseIndex(
-                m_heaps.characters8,
-                storage, m_out.zeroExt(index, m_out.intPtr),
+                m_heaps.characters8, storage, m_out.zeroExtPtr(index),
                 m_state.forNode(m_node->child2()).m_value)),
             m_out.int32));
         m_out.jump(continuation);
@@ -3370,8 +3602,7 @@
             
         ValueFromBlock char16Bit = m_out.anchor(m_out.zeroExt(
             m_out.load16(m_out.baseIndex(
-                m_heaps.characters16,
-                storage, m_out.zeroExt(index, m_out.intPtr),
+                m_heaps.characters16, storage, m_out.zeroExtPtr(index),
                 m_state.forNode(m_node->child2()).m_value)),
             m_out.int32));
         m_out.jump(continuation);
@@ -3541,13 +3772,13 @@
     
     void compileGetGlobalVar()
     {
-        setJSValue(m_out.load64(m_out.absolute(m_node->registerPointer())));
+        setJSValue(m_out.load64(m_out.absolute(m_node->variablePointer())));
     }
     
     void compilePutGlobalVar()
     {
         m_out.store64(
-            lowJSValue(m_node->child1()), m_out.absolute(m_node->registerPointer()));
+            lowJSValue(m_node->child1()), m_out.absolute(m_node->variablePointer()));
     }
     
     void compileNotifyWrite()
@@ -3585,6 +3816,11 @@
         setJSValue(m_out.loadPtr(addressFor(JSStack::Callee)));
     }
     
+    void compileGetArgumentCount()
+    {
+        setInt32(m_out.load32(payloadFor(JSStack::ArgumentCount)));
+    }
+    
     void compileGetScope()
     {
         setJSValue(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSFunction_scope));
@@ -3595,28 +3831,36 @@
         setJSValue(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSScope_next));
     }
     
-    void compileGetClosureRegisters()
-    {
-        if (WriteBarrierBase<Unknown>* registers = m_graph.tryGetRegisters(m_node->child1().node())) {
-            setStorage(m_out.constIntPtr(registers));
-            return;
-        }
-        
-        setStorage(m_out.loadPtr(
-            lowCell(m_node->child1()), m_heaps.JSEnvironmentRecord_registers));
-    }
-    
     void compileGetClosureVar()
     {
-        setJSValue(m_out.load64(
-            addressFor(lowStorage(m_node->child2()), m_node->varNumber())));
+        setJSValue(
+            m_out.load64(
+                lowCell(m_node->child1()),
+                m_heaps.JSEnvironmentRecord_variables[m_node->scopeOffset().offset()]));
     }
     
     void compilePutClosureVar()
     {
         m_out.store64(
-            lowJSValue(m_node->child3()),
-            addressFor(lowStorage(m_node->child2()), m_node->varNumber()));
+            lowJSValue(m_node->child2()),
+            lowCell(m_node->child1()),
+            m_heaps.JSEnvironmentRecord_variables[m_node->scopeOffset().offset()]);
+    }
+    
+    void compileGetFromArguments()
+    {
+        setJSValue(
+            m_out.load64(
+                lowCell(m_node->child1()),
+                m_heaps.DirectArguments_storage[m_node->capturedArgumentsOffset().offset()]));
+    }
+    
+    void compilePutToArguments()
+    {
+        m_out.store64(
+            lowJSValue(m_node->child2()),
+            lowCell(m_node->child1()),
+            m_heaps.DirectArguments_storage[m_node->capturedArgumentsOffset().offset()]);
     }
     
     void compileCompareEq()
@@ -3858,21 +4102,17 @@
     void compileCallOrConstructVarargs()
     {
         LValue jsCallee = lowJSValue(m_node->child1());
+        LValue thisArg = lowJSValue(m_node->child3());
         
         LValue jsArguments = nullptr;
-        LValue thisArg = nullptr;
         
         switch (m_node->op()) {
         case CallVarargs:
-            jsArguments = lowJSValue(m_node->child2());
-            thisArg = lowJSValue(m_node->child3());
-            break;
-        case CallForwardVarargs:
-            thisArg = lowJSValue(m_node->child2());
-            break;
         case ConstructVarargs:
             jsArguments = lowJSValue(m_node->child2());
-            thisArg = lowJSValue(m_node->child3());
+            break;
+        case CallForwardVarargs:
+        case ConstructForwardVarargs:
             break;
         default:
             DFG_CRASH(m_graph, m_node, "bad node type");
@@ -3936,6 +4176,63 @@
             m_out.castToInt32(machineStart), jsArguments, m_out.constInt32(data->offset),
             length, m_out.constInt32(data->mandatoryMinimum));
     }
+    
+    void compileForwardVarargs()
+    {
+        LoadVarargsData* data = m_node->loadVarargsData();
+        InlineCallFrame* inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
+        
+        LValue length = getArgumentsLength(inlineCallFrame).value;
+        LValue lengthIncludingThis = m_out.add(length, m_out.constInt32(1 - data->offset));
+        
+        speculate(
+            VarargsOverflow, noValue(), nullptr,
+            m_out.above(lengthIncludingThis, m_out.constInt32(data->limit)));
+        
+        m_out.store32(lengthIncludingThis, payloadFor(data->machineCount));
+        
+        LValue sourceStart = getArgumentsStart(inlineCallFrame);
+        LValue targetStart = addressFor(data->machineStart).value();
+
+        LBasicBlock undefinedLoop = FTL_NEW_BLOCK(m_out, ("ForwardVarargs undefined loop body"));
+        LBasicBlock mainLoopEntry = FTL_NEW_BLOCK(m_out, ("ForwardVarargs main loop entry"));
+        LBasicBlock mainLoop = FTL_NEW_BLOCK(m_out, ("ForwardVarargs main loop body"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ForwardVarargs continuation"));
+        
+        LValue lengthAsPtr = m_out.zeroExtPtr(length);
+        ValueFromBlock loopBound = m_out.anchor(m_out.constIntPtr(data->mandatoryMinimum));
+        m_out.branch(
+            m_out.above(loopBound.value(), lengthAsPtr), unsure(undefinedLoop), unsure(mainLoopEntry));
+        
+        LBasicBlock lastNext = m_out.appendTo(undefinedLoop, mainLoopEntry);
+        LValue previousIndex = m_out.phi(m_out.intPtr, loopBound);
+        LValue currentIndex = m_out.sub(previousIndex, m_out.intPtrOne);
+        m_out.store64(
+            m_out.constInt64(JSValue::encode(jsUndefined())),
+            m_out.baseIndex(m_heaps.variables, targetStart, currentIndex));
+        ValueFromBlock nextIndex = m_out.anchor(currentIndex);
+        addIncoming(previousIndex, nextIndex);
+        m_out.branch(
+            m_out.above(currentIndex, lengthAsPtr), unsure(undefinedLoop), unsure(mainLoopEntry));
+        
+        m_out.appendTo(mainLoopEntry, mainLoop);
+        loopBound = m_out.anchor(lengthAsPtr);
+        m_out.branch(m_out.notNull(loopBound.value()), unsure(mainLoop), unsure(continuation));
+        
+        m_out.appendTo(mainLoop, continuation);
+        previousIndex = m_out.phi(m_out.intPtr, loopBound);
+        currentIndex = m_out.sub(previousIndex, m_out.intPtrOne);
+        LValue value = m_out.load64(
+            m_out.baseIndex(
+                m_heaps.variables, sourceStart,
+                m_out.add(currentIndex, m_out.constIntPtr(data->offset))));
+        m_out.store64(value, m_out.baseIndex(m_heaps.variables, targetStart, currentIndex));
+        nextIndex = m_out.anchor(currentIndex);
+        addIncoming(previousIndex, nextIndex);
+        m_out.branch(m_out.isNull(currentIndex), unsure(continuation), unsure(mainLoop));
+        
+        m_out.appendTo(continuation, lastNext);
+    }
 
     void compileJump()
     {
@@ -4171,15 +4468,6 @@
         info.m_isInvalidationPoint = true;
     }
     
-    void compileCheckArgumentsNotCreated()
-    {
-        ASSERT(!isEmptySpeculation(
-            m_state.variables().operand(
-                m_graph.argumentsRegisterFor(m_node->origin.semantic)).m_type));
-        
-        checkArgumentsNotCreated();
-    }
-    
     void compileIsUndefined()
     {
         setBoolean(equalNullOrUndefined(m_node->child1(), AllCellsAreFalse, EqualUndefined));
@@ -4551,8 +4839,7 @@
         LBasicBlock lastNext = m_out.appendTo(inBounds, outOfBounds);
         LValue storage = m_out.loadPtr(enumerator, m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVector);
         ValueFromBlock inBoundsResult = m_out.anchor(
-            m_out.load64(m_out.baseIndex(m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVector, 
-                storage, m_out.signExt(index, m_out.int64), ScaleEight)));
+            m_out.loadPtr(m_out.baseIndex(m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVectorContents, storage, m_out.zeroExtPtr(index))));
         m_out.jump(continuation);
 
         m_out.appendTo(outOfBounds, continuation);
@@ -4578,8 +4865,7 @@
         LBasicBlock lastNext = m_out.appendTo(inBounds, outOfBounds);
         LValue storage = m_out.loadPtr(enumerator, m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVector);
         ValueFromBlock inBoundsResult = m_out.anchor(
-            m_out.load64(m_out.baseIndex(m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVector,
-                storage, m_out.signExt(index, m_out.int64), ScaleEight)));
+            m_out.loadPtr(m_out.baseIndex(m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVectorContents, storage, m_out.zeroExtPtr(index))));
         m_out.jump(continuation);
 
         m_out.appendTo(outOfBounds, continuation);
@@ -4878,6 +5164,67 @@
         return m_out.booleanFalse;
     }
     
+    struct ArgumentsLength {
+        ArgumentsLength()
+            : isKnown(false)
+            , known(UINT_MAX)
+            , value(nullptr)
+        {
+        }
+        
+        bool isKnown;
+        unsigned known;
+        LValue value;
+    };
+    ArgumentsLength getArgumentsLength(InlineCallFrame* inlineCallFrame)
+    {
+        ArgumentsLength length;
+
+        if (inlineCallFrame && !inlineCallFrame->isVarargs()) {
+            length.known = inlineCallFrame->arguments.size() - 1;
+            length.isKnown = true;
+            length.value = m_out.constInt32(length.known);
+        } else {
+            length.known = UINT_MAX;
+            length.isKnown = false;
+            
+            VirtualRegister argumentCountRegister;
+            if (!inlineCallFrame)
+                argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
+            else
+                argumentCountRegister = inlineCallFrame->argumentCountRegister;
+            length.value = m_out.sub(m_out.load32(payloadFor(argumentCountRegister)), m_out.int32One);
+        }
+        
+        return length;
+    }
+    
+    ArgumentsLength getArgumentsLength()
+    {
+        return getArgumentsLength(m_node->origin.semantic.inlineCallFrame);
+    }
+    
+    LValue getCurrentCallee()
+    {
+        if (InlineCallFrame* frame = m_node->origin.semantic.inlineCallFrame) {
+            if (frame->isClosureCall)
+                return m_out.loadPtr(addressFor(frame->calleeRecovery.virtualRegister()));
+            return weakPointer(frame->calleeRecovery.constant().asCell());
+        }
+        return m_out.loadPtr(addressFor(JSStack::Callee));
+    }
+    
+    LValue getArgumentsStart(InlineCallFrame* inlineCallFrame)
+    {
+        VirtualRegister start = AssemblyHelpers::argumentsStart(inlineCallFrame);
+        return addressFor(start).value();
+    }
+    
+    LValue getArgumentsStart()
+    {
+        return getArgumentsStart(m_node->origin.semantic.inlineCallFrame);
+    }
+    
     void checkStructure(
         LValue structureID, const FormattedValue& formattedValue, ExitKind exitKind,
         const StructureSet& set)
@@ -5098,11 +5445,10 @@
         return call;
     }
     
-    TypedPointer baseIndex(IndexedAbstractHeap& heap, LValue storage, LValue index, Edge edge)
+    TypedPointer baseIndex(IndexedAbstractHeap& heap, LValue storage, LValue index, Edge edge, ptrdiff_t offset = 0)
     {
         return m_out.baseIndex(
-            heap, storage, m_out.zeroExt(index, m_out.intPtr),
-            m_state.forNode(edge).m_value);
+            heap, storage, m_out.zeroExtPtr(index), m_state.forNode(edge).m_value, offset);
     }
     
     void compare(
@@ -5253,13 +5599,63 @@
     }
     
     template<typename ClassType>
-    LValue allocateObject(Structure* structure, LValue butterfly, LBasicBlock slowPath)
+    LValue allocateObject(
+        size_t size, Structure* structure, LValue butterfly, LBasicBlock slowPath)
     {
-        size_t size = ClassType::allocationSize(0);
         MarkedAllocator* allocator = &vm().heap.allocatorForObjectOfType<ClassType>(size);
         return allocateObject(m_out.constIntPtr(allocator), structure, butterfly, slowPath);
     }
     
+    template<typename ClassType>
+    LValue allocateObject(Structure* structure, LValue butterfly, LBasicBlock slowPath)
+    {
+        return allocateObject<ClassType>(
+            ClassType::allocationSize(0), structure, butterfly, slowPath);
+    }
+    
+    template<typename ClassType>
+    LValue allocateVariableSizedObject(
+        LValue size, Structure* structure, LValue butterfly, LBasicBlock slowPath)
+    {
+        static_assert(!(MarkedSpace::preciseStep & (MarkedSpace::preciseStep - 1)), "MarkedSpace::preciseStep must be a power of two.");
+        static_assert(!(MarkedSpace::impreciseStep & (MarkedSpace::impreciseStep - 1)), "MarkedSpace::impreciseStep must be a power of two.");
+
+        LValue subspace = m_out.constIntPtr(&vm().heap.subspaceForObjectOfType<ClassType>());
+        
+        LBasicBlock smallCaseBlock = FTL_NEW_BLOCK(m_out, ("allocateVariableSizedObject small case"));
+        LBasicBlock largeOrOversizeCaseBlock = FTL_NEW_BLOCK(m_out, ("allocateVariableSizedObject large or oversize case"));
+        LBasicBlock largeCaseBlock = FTL_NEW_BLOCK(m_out, ("allocateVariableSizedObject large case"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("allocateVariableSizedObject continuation"));
+        
+        LValue uproundedSize = m_out.add(size, m_out.constInt32(MarkedSpace::preciseStep - 1));
+        LValue isSmall = m_out.below(uproundedSize, m_out.constInt32(MarkedSpace::preciseCutoff));
+        m_out.branch(isSmall, unsure(smallCaseBlock), unsure(largeOrOversizeCaseBlock));
+        
+        LBasicBlock lastNext = m_out.appendTo(smallCaseBlock, largeOrOversizeCaseBlock);
+        TypedPointer address = m_out.baseIndex(
+            m_heaps.MarkedSpace_Subspace_preciseAllocators, subspace,
+            m_out.zeroExtPtr(m_out.lShr(uproundedSize, m_out.constInt32(getLSBSet(MarkedSpace::preciseStep)))));
+        ValueFromBlock smallAllocator = m_out.anchor(address.value());
+        m_out.jump(continuation);
+        
+        m_out.appendTo(largeOrOversizeCaseBlock, largeCaseBlock);
+        m_out.branch(
+            m_out.below(uproundedSize, m_out.constInt32(MarkedSpace::impreciseCutoff)),
+            usually(largeCaseBlock), rarely(slowPath));
+        
+        m_out.appendTo(largeCaseBlock, continuation);
+        address = m_out.baseIndex(
+            m_heaps.MarkedSpace_Subspace_impreciseAllocators, subspace,
+            m_out.zeroExtPtr(m_out.lShr(uproundedSize, m_out.constInt32(getLSBSet(MarkedSpace::impreciseStep)))));
+        ValueFromBlock largeAllocator = m_out.anchor(address.value());
+        m_out.jump(continuation);
+        
+        m_out.appendTo(continuation, lastNext);
+        LValue allocator = m_out.phi(m_out.intPtr, smallAllocator, largeAllocator);
+        
+        return allocateObject(allocator, structure, butterfly, slowPath);
+    }
+    
     // Returns a pointer to the end of the allocation.
     LValue allocateBasicStorageAndGetEnd(LValue size, LBasicBlock slowPath)
     {
@@ -5663,19 +6059,6 @@
         return m_out.phi(m_out.int32, fastResult, slowResult);
     }
     
-    void checkArgumentsNotCreated()
-    {
-        CodeOrigin codeOrigin = m_node->origin.semantic;
-        VirtualRegister argumentsRegister = m_graph.argumentsRegisterFor(codeOrigin);
-        if (isEmptySpeculation(m_state.variables().operand(argumentsRegister).m_type))
-            return;
-        
-        VirtualRegister argsReg = m_graph.machineArgumentsRegisterFor(codeOrigin);
-        speculate(
-            ArgumentsEscaped, noValue(), 0,
-            m_out.notZero64(m_out.load64(addressFor(argsReg))));
-    }
-    
     void speculate(
         ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition)
     {
@@ -6363,6 +6746,16 @@
             DFG_CRASH(m_graph, m_node, "Corrupt array class");
         }
             
+        case Array::DirectArguments:
+            return m_out.equal(
+                m_out.load8(cell, m_heaps.JSCell_typeInfoType),
+                m_out.constInt8(DirectArgumentsType));
+            
+        case Array::ScopedArguments:
+            return m_out.equal(
+                m_out.load8(cell, m_heaps.JSCell_typeInfoType),
+                m_out.constInt8(ScopedArgumentsType));
+            
         default:
             return m_out.equal(
                 m_out.load8(cell, m_heaps.JSCell_typeInfoType), 
@@ -6651,7 +7044,7 @@
         // Buffer has space, store to it.
         m_out.appendTo(bufferHasSpace, bufferIsFull);
         LValue writeBarrierBufferBase = m_out.loadPtr(m_out.absolute(&vm().heap.writeBarrierBuffer().m_buffer));
-        m_out.storePtr(base, m_out.baseIndex(m_heaps.WriteBarrierBuffer_bufferContents, writeBarrierBufferBase, m_out.zeroExt(currentBufferIndex, m_out.intPtr), ScalePtr));
+        m_out.storePtr(base, m_out.baseIndex(m_heaps.WriteBarrierBuffer_bufferContents, writeBarrierBufferBase, m_out.zeroExtPtr(currentBufferIndex)));
         m_out.store32(m_out.add(currentBufferIndex, m_out.constInt32(1)), m_out.absolute(&vm().heap.writeBarrierBuffer().m_currentIndex));
         m_out.jump(continuation);
 
@@ -6789,12 +7182,14 @@
                     return;
                 
                 Node* node = availability.node();
-                if (!node->isPhantomObjectAllocation())
+                if (!node->isPhantomAllocation())
                     return;
                 
                 auto result = map.add(node, nullptr);
-                if (result.isNewEntry)
-                    result.iterator->value = exit.m_materializations.add(node->op());
+                if (result.isNewEntry) {
+                    result.iterator->value =
+                        exit.m_materializations.add(node->op(), node->origin.semantic);
+                }
             });
         
         for (unsigned i = 0; i < exit.m_values.size(); ++i) {
@@ -6861,9 +7256,6 @@
                 
         case FlushedDouble:
             return ExitValue::inJSStackAsDouble(flush.virtualRegister());
-                
-        case FlushedArguments:
-            return ExitValue::argumentsObjectThatWasNotCreated();
         }
         
         DFG_CRASH(m_graph, m_node, "Invalid flush format");
@@ -6889,13 +7281,9 @@
             case DoubleConstant:
                 return ExitValue::constant(node->asJSValue());
                 
-            case PhantomArguments:
-                return ExitValue::argumentsObjectThatWasNotCreated();
-                
-            case PhantomNewObject:
-                return ExitValue::materializeNewObject(map.get(node));
-                
             default:
+                if (node->isPhantomAllocation())
+                    return ExitValue::materializeNewObject(map.get(node));
                 break;
             }
         }
@@ -7068,9 +7456,9 @@
         LValue tableIndex = m_out.load32(value, m_heaps.JSCell_structureID);
         LValue tableBase = m_out.loadPtr(
             m_out.absolute(vm().heap.structureIDTable().base()));
-        LValue pointerIntoTable = m_out.baseIndex(
-            tableBase, m_out.zeroExt(tableIndex, m_out.intPtr), ScaleEight);
-        return m_out.loadPtr(TypedPointer(m_heaps.structureTable, pointerIntoTable));
+        TypedPointer address = m_out.baseIndex(
+            m_heaps.structureTable, tableBase, m_out.zeroExtPtr(tableIndex));
+        return m_out.loadPtr(address);
     }
 
     LValue weakPointer(JSCell* pointer)
diff --git a/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp b/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
index 597ab97..8fddc39a 100644
--- a/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
+++ b/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -73,10 +73,6 @@
         jit.load64(AssemblyHelpers::addressFor(value.virtualRegister()), GPRInfo::regT0);
         break;
             
-    case ExitValueArgumentsObjectThatWasNotCreated:
-        jit.move(MacroAssembler::TrustedImm64(JSValue::encode(JSValue())), GPRInfo::regT0);
-        break;
-            
     case ExitValueRecovery:
         record->locations[value.rightRecoveryArgument()].restoreInto(
             jit, stackmaps, registerScratch, GPRInfo::regT1);
@@ -230,7 +226,11 @@
     }
     
     // Materialize all objects. Don't materialize an object until all of the objects it needs
-    // have been materialized.
+    // have been materialized. Curiously, this is the only place that we have an algorithm that prevents
+    // OSR exit from handling cyclic object materializations. Of course, object allocation sinking
+    // currently wouldn't recognize a cycle as being sinkable - but if it did then the only thing that
+    // would ahve to change is this fixpoint. Instead we would allocate the objects first and populate
+    // them with data later.
     HashSet<ExitTimeObjectMaterialization*> toMaterialize;
     for (ExitTimeObjectMaterialization* materialization : exit.m_materializations)
         toMaterialize.add(materialization);
@@ -443,15 +443,6 @@
     
     handleExitCounts(jit, exit);
     reifyInlinedCallFrames(jit, exit);
-    
-    ArgumentsRecoveryGenerator argumentsRecovery;
-    for (unsigned index = exit.m_values.size(); index--;) {
-        if (!exit.m_values[index].isArgumentsObjectThatWasNotCreated())
-            continue;
-        int operand = exit.m_values.operandForIndex(index);
-        argumentsRecovery.generateFor(operand, exit.m_codeOrigin, jit);
-    }
-    
     adjustAndJumpToTarget(jit, exit);
     
     LinkBuffer patchBuffer(*vm, jit, codeBlock);
diff --git a/Source/JavaScriptCore/ftl/FTLOperations.cpp b/Source/JavaScriptCore/ftl/FTLOperations.cpp
index 045e678..0d9be3e 100644
--- a/Source/JavaScriptCore/ftl/FTLOperations.cpp
+++ b/Source/JavaScriptCore/ftl/FTLOperations.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,6 +28,8 @@
 
 #if ENABLE(FTL_JIT)
 
+#include "ClonedArguments.h"
+#include "DirectArguments.h"
 #include "JSCInlines.h"
 
 namespace JSC { namespace FTL {
@@ -54,42 +56,139 @@
     // We cannot GC. We've got pointers in evil places.
     DeferGCForAWhile deferGC(vm.heap);
     
-    // In the future, we may have many different kinds of materializations. For now we just
-    // materialize NewObject.
-    RELEASE_ASSERT(materialization->type() == PhantomNewObject);
-    
-    // First figure out what the structure is.
-    Structure* structure = nullptr;
-    for (unsigned i = materialization->properties().size(); i--;) {
-        const ExitPropertyValue& property = materialization->properties()[i];
-        if (property.location() != PromotedLocationDescriptor(StructurePLoc))
-            continue;
-        
-        structure = jsCast<Structure*>(JSValue::decode(values[i]));
-    }
-    RELEASE_ASSERT(structure);
-    
-    // Let's create that object!
-    JSFinalObject* result = JSFinalObject::create(vm, structure);
-    
-    // Now figure out what the heck to populate the object with. Use getPropertiesConcurrently()
-    // because that happens to be lower-level and more convenient. It doesn't change the
-    // materialization of the property table. We want to have minimal visible effects on the
-    // system. Also, don't mind that this is O(n^2). It doesn't matter. We only get here from OSR
-    // exit.
-    for (PropertyMapEntry entry : structure->getPropertiesConcurrently()) {
+    switch (materialization->type()) {
+    case PhantomNewObject: {
+        // First figure out what the structure is.
+        Structure* structure = nullptr;
         for (unsigned i = materialization->properties().size(); i--;) {
             const ExitPropertyValue& property = materialization->properties()[i];
-            if (property.location().kind() != NamedPropertyPLoc)
+            if (property.location() != PromotedLocationDescriptor(StructurePLoc))
                 continue;
-            if (codeBlock->identifier(property.location().info()).impl() != entry.key)
-                continue;
+        
+            structure = jsCast<Structure*>(JSValue::decode(values[i]));
+            break;
+        }
+        RELEASE_ASSERT(structure);
+    
+        // Let's create that object!
+        JSFinalObject* result = JSFinalObject::create(vm, structure);
+    
+        // Now figure out what the heck to populate the object with. Use getPropertiesConcurrently()
+        // because that happens to be lower-level and more convenient. It doesn't change the
+        // materialization of the property table. We want to have minimal visible effects on the
+        // system. Also, don't mind that this is O(n^2). It doesn't matter. We only get here from OSR
+        // exit.
+        for (PropertyMapEntry entry : structure->getPropertiesConcurrently()) {
+            for (unsigned i = materialization->properties().size(); i--;) {
+                const ExitPropertyValue& property = materialization->properties()[i];
+                if (property.location().kind() != NamedPropertyPLoc)
+                    continue;
+                if (codeBlock->identifier(property.location().info()).impl() != entry.key)
+                    continue;
             
-            result->putDirect(vm, entry.offset, JSValue::decode(values[i]));
+                result->putDirect(vm, entry.offset, JSValue::decode(values[i]));
+            }
+        }
+    
+        return result;
+    }
+        
+    case PhantomDirectArguments:
+    case PhantomClonedArguments: {
+        if (!materialization->origin().inlineCallFrame) {
+            switch (materialization->type()) {
+            case PhantomDirectArguments:
+                return DirectArguments::createByCopying(exec);
+            case PhantomClonedArguments:
+                return ClonedArguments::createWithMachineFrame(exec, exec, ArgumentsMode::Cloned);
+            default:
+                RELEASE_ASSERT_NOT_REACHED();
+                return nullptr;
+            }
+        }
+
+        // First figure out the argument count. If there isn't one then we represent the machine frame.
+        unsigned argumentCount = 0;
+        if (materialization->origin().inlineCallFrame->isVarargs()) {
+            for (unsigned i = materialization->properties().size(); i--;) {
+                const ExitPropertyValue& property = materialization->properties()[i];
+                if (property.location() != PromotedLocationDescriptor(ArgumentCountPLoc))
+                    continue;
+                
+                argumentCount = JSValue::decode(values[i]).asUInt32();
+                RELEASE_ASSERT(argumentCount);
+                break;
+            }
+            RELEASE_ASSERT(argumentCount);
+        } else
+            argumentCount = materialization->origin().inlineCallFrame->arguments.size();
+        
+        JSFunction* callee = nullptr;
+        if (materialization->origin().inlineCallFrame->isClosureCall) {
+            for (unsigned i = materialization->properties().size(); i--;) {
+                const ExitPropertyValue& property = materialization->properties()[i];
+                if (property.location() != PromotedLocationDescriptor(ArgumentsCalleePLoc))
+                    continue;
+                
+                callee = jsCast<JSFunction*>(JSValue::decode(values[i]));
+                break;
+            }
+        } else
+            callee = materialization->origin().inlineCallFrame->calleeConstant();
+        RELEASE_ASSERT(callee);
+        
+        CodeBlock* codeBlock = baselineCodeBlockForOriginAndBaselineCodeBlock(
+            materialization->origin(), exec->codeBlock());
+        
+        // We have an inline frame and we have all of the data we need to recreate it.
+        switch (materialization->type()) {
+        case PhantomDirectArguments: {
+            unsigned length = argumentCount - 1;
+            unsigned capacity = std::max(length, static_cast<unsigned>(codeBlock->numParameters() - 1));
+            DirectArguments* result = DirectArguments::create(
+                vm, codeBlock->globalObject()->directArgumentsStructure(), length, capacity);
+            result->callee().set(vm, result, callee);
+            for (unsigned i = materialization->properties().size(); i--;) {
+                const ExitPropertyValue& property = materialization->properties()[i];
+                if (property.location().kind() != ArgumentPLoc)
+                    continue;
+                
+                unsigned index = property.location().info();
+                if (index >= capacity)
+                    continue;
+                result->setIndexQuickly(vm, index, JSValue::decode(values[i]));
+            }
+            return result;
+        }
+        case PhantomClonedArguments: {
+            unsigned length = argumentCount - 1;
+            ClonedArguments* result = ClonedArguments::createEmpty(
+                vm, codeBlock->globalObject()->outOfBandArgumentsStructure(), callee);
+            
+            for (unsigned i = materialization->properties().size(); i--;) {
+                const ExitPropertyValue& property = materialization->properties()[i];
+                if (property.location().kind() != ArgumentPLoc)
+                    continue;
+                
+                unsigned index = property.location().info();
+                if (index >= length)
+                    continue;
+                result->putDirectIndex(exec, index, JSValue::decode(values[i]));
+            }
+            
+            result->putDirect(vm, vm.propertyNames->length, jsNumber(length));
+            return result;
+        }
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            return nullptr;
         }
     }
-    
-    return result;
+        
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        return nullptr;
+    }
 }
 
 } } // namespace JSC::FTL
diff --git a/Source/JavaScriptCore/ftl/FTLOutput.h b/Source/JavaScriptCore/ftl/FTLOutput.h
index cd3751e..65a6746 100644
--- a/Source/JavaScriptCore/ftl/FTLOutput.h
+++ b/Source/JavaScriptCore/ftl/FTLOutput.h
@@ -133,8 +133,8 @@
     LValue bitOr(LValue left, LValue right) { return buildOr(m_builder, left, right); }
     LValue bitXor(LValue left, LValue right) { return buildXor(m_builder, left, right); }
     LValue shl(LValue left, LValue right) { return buildShl(m_builder, left, right); }
-    LValue aShr(LValue left, LValue right) { return buildAShr(m_builder, left, right); }
-    LValue lShr(LValue left, LValue right) { return buildLShr(m_builder, left, right); }
+    LValue aShr(LValue left, LValue right) { return buildAShr(m_builder, left, right); } // arithmetic = signed
+    LValue lShr(LValue left, LValue right) { return buildLShr(m_builder, left, right); } // logical = unsigned
     LValue bitNot(LValue value) { return buildNot(m_builder, value); }
     
     LValue insertElement(LValue vector, LValue element, LValue index) { return buildInsertElement(m_builder, vector, element, index); }
@@ -202,6 +202,7 @@
     
     LValue signExt(LValue value, LType type) { return buildSExt(m_builder, value, type); }
     LValue zeroExt(LValue value, LType type) { return buildZExt(m_builder, value, type); }
+    LValue zeroExtPtr(LValue value) { return zeroExt(value, intPtr); }
     LValue fpToInt(LValue value, LType type) { return buildFPToSI(m_builder, value, type); }
     LValue fpToUInt(LValue value, LType type) { return buildFPToUI(m_builder, value, type); }
     LValue fpToInt32(LValue value) { return fpToInt(value, int32); }
@@ -217,6 +218,8 @@
     LValue ptrToInt(LValue value, LType type) { return buildPtrToInt(m_builder, value, type); }
     LValue bitCast(LValue value, LType type) { return buildBitCast(m_builder, value, type); }
     
+    // Hilariously, the #define machinery in the stdlib means that this method is actually called
+    // __builtin_alloca. So far this appears benign. :-|
     LValue alloca(LType type) { return buildAlloca(m_builder, type); }
     
     // Access the value of an alloca. Also used as a low-level implementation primitive for
diff --git a/Source/JavaScriptCore/heap/CopyToken.h b/Source/JavaScriptCore/heap/CopyToken.h
index 3e1679a..5aceb5b 100644
--- a/Source/JavaScriptCore/heap/CopyToken.h
+++ b/Source/JavaScriptCore/heap/CopyToken.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,7 +32,7 @@
     ButterflyCopyToken,
     TypedArrayVectorCopyToken,
     MapBackingStoreCopyToken,
-    ArgumentsSlowArgumentDataCopyToken
+    DirectArgumentsOverridesCopyToken
 };
 
 } // namespace JSC
diff --git a/Source/JavaScriptCore/interpreter/CallFrame.h b/Source/JavaScriptCore/interpreter/CallFrame.h
index 7c41f44..3087b6b 100644
--- a/Source/JavaScriptCore/interpreter/CallFrame.h
+++ b/Source/JavaScriptCore/interpreter/CallFrame.h
@@ -239,6 +239,15 @@
             this[argumentOffset(argument)] = value;
         }
 
+        JSValue getArgumentUnsafe(size_t argIndex)
+        {
+            // User beware! This method does not verify that there is a valid
+            // argument at the specified argIndex. This is used for debugging
+            // and verification code only. The caller is expected to know what
+            // he/she is doing when calling this method.
+            return this[argumentOffset(argIndex)].jsValue();
+        }
+
         static int thisArgumentOffset() { return argumentOffsetIncludingThis(0); }
         JSValue thisValue() { return this[thisArgumentOffset()].jsValue(); }
         void setThisValue(JSValue value) { this[thisArgumentOffset()] = value; }
@@ -295,15 +304,6 @@
             return argIndex;
         }
 
-        JSValue getArgumentUnsafe(size_t argIndex)
-        {
-            // User beware! This method does not verify that there is a valid
-            // argument at the specified argIndex. This is used for debugging
-            // and verification code only. The caller is expected to know what
-            // he/she is doing when calling this method.
-            return this[argumentOffset(argIndex)].jsValue();
-        }
-
         void* callerFrameOrVMEntryFrame() const { return callerFrameAndPC().callerFrame; }
 
         CallerFrameAndPC& callerFrameAndPC() { return *reinterpret_cast<CallerFrameAndPC*>(this); }
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp
index dde665c..bc885a6 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp
@@ -30,11 +30,12 @@
 #include "config.h"
 #include "Interpreter.h"
 
-#include "Arguments.h"
 #include "BatchedTransitionOptimizer.h"
 #include "CallFrameClosure.h"
 #include "CallFrameInlines.h"
+#include "ClonedArguments.h"
 #include "CodeBlock.h"
+#include "DirectArguments.h"
 #include "Heap.h"
 #include "Debugger.h"
 #include "DebuggerCallFrame.h"
@@ -44,6 +45,7 @@
 #include "GetterSetter.h"
 #include "JSArray.h"
 #include "JSBoundFunction.h"
+#include "JSCInlines.h"
 #include "JSLexicalEnvironment.h"
 #include "JSNameScope.h"
 #include "JSNotAnObject.h"
@@ -55,13 +57,13 @@
 #include "LegacyProfiler.h"
 #include "LiteralParser.h"
 #include "ObjectPrototype.h"
-#include "JSCInlines.h"
 #include "Parser.h"
 #include "ProtoCallFrame.h"
 #include "RegExpObject.h"
 #include "RegExpPrototype.h"
 #include "Register.h"
 #include "SamplingTool.h"
+#include "ScopedArguments.h"
 #include "StackAlignment.h"
 #include "StackVisitor.h"
 #include "StrictEvalActivation.h"
@@ -136,20 +138,34 @@
 
 unsigned sizeOfVarargs(CallFrame* callFrame, JSValue arguments, uint32_t firstVarArgOffset)
 {
+    if (UNLIKELY(!arguments.isCell())) {
+        if (arguments.isUndefinedOrNull())
+            return 0;
+        
+        callFrame->vm().throwException(callFrame, createInvalidFunctionApplyParameterError(callFrame, arguments));
+        return 0;
+    }
+    
+    JSCell* cell = arguments.asCell();
     unsigned length;
-    if (!arguments)
-        length = callFrame->argumentCount();
-    else if (arguments.isUndefinedOrNull())
-        length = 0;
-    else if (!arguments.isObject()) {
+    switch (cell->type()) {
+    case DirectArgumentsType:
+        length = jsCast<DirectArguments*>(cell)->length(callFrame);
+        break;
+    case ScopedArgumentsType:
+        length =jsCast<ScopedArguments*>(cell)->length(callFrame);
+        break;
+    case StringType:
         callFrame->vm().throwException(callFrame, createInvalidFunctionApplyParameterError(callFrame,  arguments));
         return 0;
-    } else if (asObject(arguments)->classInfo() == Arguments::info())
-        length = asArguments(arguments)->length(callFrame);
-    else if (isJSArray(arguments))
-        length = asArray(arguments)->length();
-    else
-        length = asObject(arguments)->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
+    default:
+        ASSERT(arguments.isObject());
+        if (isJSArray(cell))
+            length = jsCast<JSArray*>(cell)->length();
+        else
+            length = jsCast<JSObject*>(cell)->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
+        break;
+    }
     
     if (length >= firstVarArgOffset)
         length -= firstVarArgOffset;
@@ -164,7 +180,7 @@
     unsigned length = sizeOfVarargs(callFrame, arguments, firstVarArgOffset);
     
     CallFrame* calleeFrame = calleeFrameForVarargs(callFrame, numUsedStackSlots, length + 1);
-    if (length > Arguments::MaxArguments || !stack->ensureCapacityFor(calleeFrame->registers())) {
+    if (length > maxArguments || !stack->ensureCapacityFor(calleeFrame->registers())) {
         throwStackOverflowError(callFrame);
         return 0;
     }
@@ -174,30 +190,31 @@
 
 void loadVarargs(CallFrame* callFrame, VirtualRegister firstElementDest, JSValue arguments, uint32_t offset, uint32_t length)
 {
-    if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
-        for (size_t i = 0; i < length; ++i)
-            callFrame->r(firstElementDest + i) = callFrame->argumentAfterCapture(i + offset);
-        return;
-    }
-    
-    if (arguments.isUndefinedOrNull())
+    if (UNLIKELY(!arguments.isCell()))
         return;
     
-    if (asObject(arguments)->classInfo() == Arguments::info()) {
-        asArguments(arguments)->copyToArguments(callFrame, firstElementDest, offset, length);
+    JSCell* cell = arguments.asCell();
+    switch (cell->type()) {
+    case DirectArgumentsType:
+        jsCast<DirectArguments*>(cell)->copyToArguments(callFrame, firstElementDest, offset, length);
         return;
-    }
-    
-    if (isJSArray(arguments)) {
-        asArray(arguments)->copyToArguments(callFrame, firstElementDest, offset, length);
+    case ScopedArgumentsType:
+        jsCast<ScopedArguments*>(cell)->copyToArguments(callFrame, firstElementDest, offset, length);
         return;
-    }
-    
-    for (unsigned i = 0; i < length; ++i) {
-        callFrame->r(firstElementDest + i) = asObject(arguments)->get(callFrame, i + offset);
-        if (UNLIKELY(callFrame->vm().exception()))
+    default: {
+        ASSERT(arguments.isObject());
+        JSObject* object = jsCast<JSObject*>(cell);
+        if (isJSArray(object)) {
+            jsCast<JSArray*>(object)->copyToArguments(callFrame, firstElementDest, offset, length);
             return;
-    }
+        }
+        unsigned i;
+        for (i = 0; i < length && object->canGetIndexQuickly(i + offset); ++i)
+            callFrame->r(firstElementDest + i) = object->getIndexQuickly(i + offset);
+        for (; i < length; ++i)
+            callFrame->r(firstElementDest + i) = object->get(callFrame, i + offset);
+        return;
+    } }
 }
 
 void setupVarargsFrame(CallFrame* callFrame, CallFrame* newCallFrame, JSValue arguments, uint32_t offset, uint32_t length)
@@ -386,25 +403,6 @@
         ASSERT(!callFrame->hadException());
     }
 
-    if (CodeBlock* codeBlock = visitor->codeBlock()) {
-        if (codeBlock->codeType() == FunctionCode && codeBlock->needsActivation()) {
-#if ENABLE(DFG_JIT)
-            RELEASE_ASSERT(!visitor->isInlinedFrame());
-#endif
-        }
-
-        if (codeBlock->codeType() == FunctionCode && codeBlock->usesArguments()) {
-            if (Arguments* arguments = visitor->existingArguments()) {
-#if ENABLE(DFG_JIT)
-                if (visitor->isInlinedFrame())
-                    arguments->tearOff(callFrame, visitor->inlineCallFrame());
-                else
-#endif
-                    arguments->tearOff(callFrame);
-            }
-        }
-    }
-
     return !visitor->callerIsVMEntryFrame();
 }
 
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.h b/Source/JavaScriptCore/interpreter/Interpreter.h
index 3bfed01..6315c4a 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.h
+++ b/Source/JavaScriptCore/interpreter/Interpreter.h
@@ -309,6 +309,7 @@
     }
 
     unsigned sizeOfVarargs(CallFrame* exec, JSValue arguments, uint32_t firstVarArgOffset);
+    static const unsigned maxArguments = 0x10000;
     unsigned sizeFrameForVarargs(CallFrame* exec, JSStack*, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset);
     void loadVarargs(CallFrame* execCaller, VirtualRegister firstElementDest, JSValue source, uint32_t offset, uint32_t length);
     void setupVarargsFrame(CallFrame* execCaller, CallFrame* execCallee, JSValue arguments, uint32_t firstVarArgOffset, uint32_t length);
diff --git a/Source/JavaScriptCore/interpreter/StackVisitor.cpp b/Source/JavaScriptCore/interpreter/StackVisitor.cpp
index c3a088d..669e3b6 100644
--- a/Source/JavaScriptCore/interpreter/StackVisitor.cpp
+++ b/Source/JavaScriptCore/interpreter/StackVisitor.cpp
@@ -26,8 +26,8 @@
 #include "config.h"
 #include "StackVisitor.h"
 
-#include "Arguments.h"
 #include "CallFrameInlines.h"
+#include "ClonedArguments.h"
 #include "Executable.h"
 #include "Interpreter.h"
 #include "JSCInlines.h"
@@ -255,65 +255,26 @@
     return traceBuild.toString().impl();
 }
 
-Arguments* StackVisitor::Frame::createArguments()
+ClonedArguments* StackVisitor::Frame::createArguments()
 {
     ASSERT(m_callFrame);
     CallFrame* physicalFrame = m_callFrame;
-    VM& vm = physicalFrame->vm();
-    Arguments* arguments;
+    ClonedArguments* arguments;
     ArgumentsMode mode;
     if (Options::enableFunctionDotArguments())
-        mode = ClonedArgumentsCreationMode;
+        mode = ArgumentsMode::Cloned;
     else
-        mode = FakeArgumentValuesCreationMode;
+        mode = ArgumentsMode::FakeValues;
 #if ENABLE(DFG_JIT)
     if (isInlinedFrame()) {
         ASSERT(m_inlineCallFrame);
-        arguments = Arguments::create(vm, physicalFrame, m_inlineCallFrame, mode);
-        arguments->tearOff(physicalFrame, m_inlineCallFrame);
-        jsCast<Arguments*>((JSCell*)arguments);
+        arguments = ClonedArguments::createWithInlineFrame(physicalFrame, physicalFrame, m_inlineCallFrame, mode);
     } else 
 #endif
-    {
-        JSLexicalEnvironment* lexicalEnvironment = nullptr;
-        arguments = Arguments::create(vm, physicalFrame, lexicalEnvironment, mode);
-        arguments->tearOff(physicalFrame);
-    }
+        arguments = ClonedArguments::createWithMachineFrame(physicalFrame, physicalFrame, mode);
     return arguments;
 }
 
-Arguments* StackVisitor::Frame::existingArguments()
-{
-    if (codeBlock()->codeType() != FunctionCode)
-        return 0;
-    if (!codeBlock()->usesArguments())
-        return 0;
-    
-    VirtualRegister reg;
-        
-#if ENABLE(DFG_JIT)
-    if (isInlinedFrame())
-        reg = inlineCallFrame()->argumentsRegister;
-    else
-#endif // ENABLE(DFG_JIT)
-        reg = codeBlock()->argumentsRegister();
-
-    // Care should be taken here since exception fuzzing may raise exceptions in
-    // places where they would be otherwise impossible. Therefore, callFrame may
-    // lack activation even if the codeBlock signals need of activation. Also,
-    // even if codeBlock signals the use of arguments, the
-    // unmodifiedArgumentsRegister may not be initialized yet (neither locally
-    // nor in lexicalEnvironment).
-    JSValue result = jsUndefined();
-    if (codeBlock()->needsActivation() && callFrame()->hasActivation())
-        result = callFrame()->lexicalEnvironment()->registerAt(unmodifiedArgumentsRegister(reg).offset()).get();
-    if (!result || !result.isCell()) // Try local unmodifiedArgumentsRegister if lexicalEnvironment is not present (generally possible) or has not set up registers yet (only possible if fuzzing exceptions).
-        result = callFrame()->r(unmodifiedArgumentsRegister(reg).offset()).jsValue();
-    if (!result || !result.isCell()) // Protect against the case when exception fuzzing throws when unmodifiedArgumentsRegister is not set up yet (e.g., in op_enter).
-        return 0;
-    return jsCast<Arguments*>(result);
-}
-
 void StackVisitor::Frame::computeLineAndColumn(unsigned& line, unsigned& column)
 {
     CodeBlock* codeBlock = this->codeBlock();
diff --git a/Source/JavaScriptCore/interpreter/StackVisitor.h b/Source/JavaScriptCore/interpreter/StackVisitor.h
index 749540f..bda84d1 100644
--- a/Source/JavaScriptCore/interpreter/StackVisitor.h
+++ b/Source/JavaScriptCore/interpreter/StackVisitor.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,12 +34,12 @@
 struct CodeOrigin;
 struct InlineCallFrame;
 
-class Arguments;
 class CodeBlock;
 class ExecState;
 class JSFunction;
 class JSObject;
 class JSScope;
+class ClonedArguments;
 class Register;
 
 typedef ExecState CallFrame;
@@ -78,8 +78,7 @@
         CodeType codeType() const;
         JS_EXPORT_PRIVATE void computeLineAndColumn(unsigned& line, unsigned& column);
 
-        Arguments* createArguments();
-        Arguments* existingArguments();
+        ClonedArguments* createArguments();
         VMEntryFrame* vmEntryFrame() const { return m_VMEntryFrame; }
         CallFrame* callFrame() const { return m_callFrame; }
         
diff --git a/Source/JavaScriptCore/jit/AssemblyHelpers.h b/Source/JavaScriptCore/jit/AssemblyHelpers.h
index 70213ef..34814f3 100644
--- a/Source/JavaScriptCore/jit/AssemblyHelpers.h
+++ b/Source/JavaScriptCore/jit/AssemblyHelpers.h
@@ -88,6 +88,16 @@
 #endif
     }
     
+    void storeValue(JSValueRegs regs, BaseIndex address)
+    {
+#if USE(JSVALUE64)
+        store64(regs.gpr(), address);
+#else
+        store32(regs.payloadGPR(), address.withOffset(PayloadOffset));
+        store32(regs.tagGPR(), address.withOffset(TagOffset));
+#endif
+    }
+    
     void storeValue(JSValueRegs regs, void* address)
     {
 #if USE(JSVALUE64)
@@ -113,6 +123,26 @@
 #endif
     }
     
+    void loadValue(BaseIndex address, JSValueRegs regs)
+    {
+#if USE(JSVALUE64)
+        load64(address, regs.gpr());
+#else
+        if (address.base == regs.payloadGPR() || address.index == regs.payloadGPR()) {
+            // We actually could handle the case where the registers are aliased to both
+            // tag and payload, but we don't for now.
+            RELEASE_ASSERT(address.base != regs.tagGPR());
+            RELEASE_ASSERT(address.index != regs.tagGPR());
+            
+            load32(address.withOffset(TagOffset), regs.tagGPR());
+            load32(address.withOffset(PayloadOffset), regs.payloadGPR());
+        } else {
+            load32(address.withOffset(PayloadOffset), regs.payloadGPR());
+            load32(address.withOffset(TagOffset), regs.tagGPR());
+        }
+#endif
+    }
+    
     void moveTrustedValue(JSValue value, JSValueRegs regs)
     {
 #if USE(JSVALUE64)
@@ -122,6 +152,26 @@
         move(TrustedImm32(value.payload()), regs.payloadGPR());
 #endif
     }
+    
+    void storeTrustedValue(JSValue value, Address address)
+    {
+#if USE(JSVALUE64)
+        store64(TrustedImm64(JSValue::encode(value)), address);
+#else
+        store32(TrustedImm32(value.tag()), address.withOffset(TagOffset));
+        store32(TrustedImm32(value.payload()), address.withOffset(PayloadOffset));
+#endif
+    }
+
+    void storeTrustedValue(JSValue value, BaseIndex address)
+    {
+#if USE(JSVALUE64)
+        store64(TrustedImm64(JSValue::encode(value)), address);
+#else
+        store32(TrustedImm32(value.tag()), address.withOffset(TagOffset));
+        store32(TrustedImm32(value.payload()), address.withOffset(PayloadOffset));
+#endif
+    }
 
 #if CPU(X86_64) || CPU(X86)
     static size_t prologueStackPointerDelta()
@@ -326,6 +376,23 @@
         return branch32(MacroAssembler::NotEqual, reg, TrustedImm32(JSValue::CellTag));
 #endif
     }
+    Jump branchIfNotCell(JSValueRegs regs)
+    {
+#if USE(JSVALUE64)
+        return branchIfNotCell(regs.gpr());
+#else
+        return branchIfNotCell(regs.tagGPR());
+#endif
+    }
+    
+    Jump branchIsEmpty(JSValueRegs regs)
+    {
+#if USE(JSVALUE64)
+        return branchTest64(Zero, regs.gpr());
+#else
+        return branch32(Equal, regs.tagGPR(), TrustedImm32(JSValue::EmptyValueTag));
+#endif
+    }
     
     static Address addressForByteOffset(ptrdiff_t byteOffset)
     {
@@ -634,46 +701,25 @@
         return m_baselineCodeBlock;
     }
     
-    VirtualRegister baselineArgumentsRegisterFor(InlineCallFrame* inlineCallFrame)
-    {
-        if (!inlineCallFrame)
-            return baselineCodeBlock()->argumentsRegister();
-        
-        return VirtualRegister(baselineCodeBlockForInlineCallFrame(
-            inlineCallFrame)->argumentsRegister().offset() + inlineCallFrame->stackOffset);
-    }
-    
-    VirtualRegister baselineArgumentsRegisterFor(const CodeOrigin& codeOrigin)
-    {
-        return baselineArgumentsRegisterFor(codeOrigin.inlineCallFrame);
-    }
-    
     SymbolTable* symbolTableFor(const CodeOrigin& codeOrigin)
     {
         return baselineCodeBlockFor(codeOrigin)->symbolTable();
     }
 
-    int offsetOfLocals(const CodeOrigin& codeOrigin)
-    {
-        if (!codeOrigin.inlineCallFrame)
-            return 0;
-        return codeOrigin.inlineCallFrame->stackOffset * sizeof(Register);
-    }
-
-    int offsetOfArguments(InlineCallFrame* inlineCallFrame)
+    static VirtualRegister argumentsStart(InlineCallFrame* inlineCallFrame)
     {
         if (!inlineCallFrame)
-            return CallFrame::argumentOffset(0) * sizeof(Register);
+            return VirtualRegister(CallFrame::argumentOffset(0));
         if (inlineCallFrame->arguments.size() <= 1)
-            return 0;
+            return virtualRegisterForLocal(0);
         ValueRecovery recovery = inlineCallFrame->arguments[1];
         RELEASE_ASSERT(recovery.technique() == DisplacedInJSStack);
-        return recovery.virtualRegister().offset() * sizeof(Register);
+        return recovery.virtualRegister();
     }
     
-    int offsetOfArguments(const CodeOrigin& codeOrigin)
+    static VirtualRegister argumentsStart(const CodeOrigin& codeOrigin)
     {
-        return offsetOfArguments(codeOrigin.inlineCallFrame);
+        return argumentsStart(codeOrigin.inlineCallFrame);
     }
     
     void emitLoadStructure(RegisterID source, RegisterID dest, RegisterID scratch)
diff --git a/Source/JavaScriptCore/jit/CCallHelpers.h b/Source/JavaScriptCore/jit/CCallHelpers.h
index c8b346c..fd344ad 100644
--- a/Source/JavaScriptCore/jit/CCallHelpers.h
+++ b/Source/JavaScriptCore/jit/CCallHelpers.h
@@ -33,12 +33,34 @@
 
 namespace JSC {
 
+#if CPU(MIPS) || (OS(WINDOWS) && CPU(X86_64))
+#define POKE_ARGUMENT_OFFSET 4
+#else
+#define POKE_ARGUMENT_OFFSET 0
+#endif
+
 class CCallHelpers : public AssemblyHelpers {
 public:
     CCallHelpers(VM* vm, CodeBlock* codeBlock = 0)
         : AssemblyHelpers(vm, codeBlock)
     {
     }
+    
+    // The most general helper for setting arguments that fit in a GPR, if you can compute each
+    // argument without using any argument registers. You usually want one of the setupArguments*()
+    // methods below instead of this. This thing is most useful if you have *a lot* of arguments.
+    template<typename Functor>
+    void setupArgument(unsigned argumentIndex, const Functor& functor)
+    {
+        unsigned numberOfRegs = GPRInfo::numberOfArgumentRegisters; // Disguise the constant from clang's tautological compare warning.
+        if (argumentIndex < numberOfRegs) {
+            functor(GPRInfo::toArgumentRegister(argumentIndex));
+            return;
+        }
+        
+        functor(GPRInfo::nonArgGPR0);
+        poke(GPRInfo::nonArgGPR0, POKE_ARGUMENT_OFFSET + argumentIndex - GPRInfo::numberOfArgumentRegisters);
+    }
 
     // These methods used to sort arguments into the correct registers.
     // On X86 we use cdecl calling conventions, which pass all arguments on the
@@ -863,12 +885,6 @@
         setupThreeStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg1, arg2, arg3);
     }
 
-#if CPU(MIPS) || (OS(WINDOWS) && CPU(X86_64))
-#define POKE_ARGUMENT_OFFSET 4
-#else
-#define POKE_ARGUMENT_OFFSET 0
-#endif
-
 #if CPU(X86_64) || CPU(ARM64)
     ALWAYS_INLINE void setupArguments(FPRReg arg1)
     {
diff --git a/Source/JavaScriptCore/jit/GPRInfo.h b/Source/JavaScriptCore/jit/GPRInfo.h
index df8c3c0..a5e301b 100644
--- a/Source/JavaScriptCore/jit/GPRInfo.h
+++ b/Source/JavaScriptCore/jit/GPRInfo.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -54,6 +54,11 @@
         return JSValueRegs(gpr);
     }
     
+    static JSValueRegs withTwoAvailableRegs(GPRReg gpr, GPRReg)
+    {
+        return JSValueRegs(gpr);
+    }
+    
     bool operator!() const { return m_gpr == InvalidGPRReg; }
     
     GPRReg gpr() const { return m_gpr; }
@@ -146,6 +151,11 @@
     {
     }
     
+    static JSValueRegs withTwoAvailableRegs(GPRReg gpr1, GPRReg gpr2)
+    {
+        return JSValueRegs(gpr1, gpr2);
+    }
+    
     static JSValueRegs payloadOnly(GPRReg gpr)
     {
         return JSValueRegs(InvalidGPRReg, gpr);
@@ -325,6 +335,12 @@
         return registerForIndex[index];
     }
 
+    static GPRReg toArgumentRegister(unsigned)
+    {
+        UNREACHABLE_FOR_PLATFORM();
+        return InvalidGPRReg;
+    }
+
     static unsigned toIndex(GPRReg reg)
     {
         ASSERT(reg != InvalidGPRReg);
@@ -497,6 +513,13 @@
         return registerForIndex[index];
     }
 
+    static GPRReg toArgumentRegister(unsigned index)
+    {
+        ASSERT(index < numberOfArgumentRegisters);
+        static const GPRReg registerForIndex[numberOfArgumentRegisters] = { argumentGPR0, argumentGPR1, argumentGPR2, argumentGPR3 };
+        return registerForIndex[index];
+    }
+
     static unsigned toIndex(GPRReg reg)
     {
         ASSERT(reg != InvalidGPRReg);
diff --git a/Source/JavaScriptCore/jit/JIT.cpp b/Source/JavaScriptCore/jit/JIT.cpp
index c1f1746..42a82d4 100644
--- a/Source/JavaScriptCore/jit/JIT.cpp
+++ b/Source/JavaScriptCore/jit/JIT.cpp
@@ -202,9 +202,10 @@
         DEFINE_OP(op_construct)
         DEFINE_OP(op_create_this)
         DEFINE_OP(op_to_this)
+        DEFINE_OP(op_create_direct_arguments)
+        DEFINE_OP(op_create_scoped_arguments)
+        DEFINE_OP(op_create_out_of_band_arguments)
         DEFINE_OP(op_check_tdz)
-        DEFINE_OP(op_init_lazy_reg)
-        DEFINE_OP(op_create_arguments)
         DEFINE_OP(op_debug)
         DEFINE_OP(op_del_by_id)
         DEFINE_OP(op_div)
@@ -217,9 +218,7 @@
         case op_get_by_id_out_of_line:
         case op_get_array_length:
         DEFINE_OP(op_get_by_id)
-        DEFINE_OP(op_get_arguments_length)
         DEFINE_OP(op_get_by_val)
-        DEFINE_OP(op_get_argument_by_val)
         DEFINE_OP(op_check_has_instance)
         DEFINE_OP(op_instanceof)
         DEFINE_OP(op_is_undefined)
@@ -291,7 +290,6 @@
         DEFINE_OP(op_switch_char)
         DEFINE_OP(op_switch_imm)
         DEFINE_OP(op_switch_string)
-        DEFINE_OP(op_tear_off_arguments)
         DEFINE_OP(op_throw)
         DEFINE_OP(op_throw_static_error)
         DEFINE_OP(op_to_number)
@@ -300,6 +298,8 @@
         DEFINE_OP(op_resolve_scope)
         DEFINE_OP(op_get_from_scope)
         DEFINE_OP(op_put_to_scope)
+        DEFINE_OP(op_get_from_arguments)
+        DEFINE_OP(op_put_to_arguments)
 
         DEFINE_OP(op_get_enumerable_length)
         DEFINE_OP(op_has_generic_property)
@@ -384,9 +384,7 @@
         case op_get_by_id_out_of_line:
         case op_get_array_length:
         DEFINE_SLOWCASE_OP(op_get_by_id)
-        DEFINE_SLOWCASE_OP(op_get_arguments_length)
         DEFINE_SLOWCASE_OP(op_get_by_val)
-        DEFINE_SLOWCASE_OP(op_get_argument_by_val)
         DEFINE_SLOWCASE_OP(op_check_has_instance)
         DEFINE_SLOWCASE_OP(op_instanceof)
         DEFINE_SLOWCASE_OP(op_jfalse)
diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h
index 193a0ff..ee4855d 100644
--- a/Source/JavaScriptCore/jit/JIT.h
+++ b/Source/JavaScriptCore/jit/JIT.h
@@ -346,6 +346,8 @@
         JumpList emitDoubleGetByVal(Instruction*, PatchableJump& badType);
         JumpList emitContiguousGetByVal(Instruction*, PatchableJump& badType, IndexingType expectedShape = ContiguousShape);
         JumpList emitArrayStorageGetByVal(Instruction*, PatchableJump& badType);
+        JumpList emitDirectArgumentsGetByVal(Instruction*, PatchableJump& badType);
+        JumpList emitScopedArgumentsGetByVal(Instruction*, PatchableJump& badType);
         JumpList emitIntTypedArrayGetByVal(Instruction*, PatchableJump& badType, TypedArrayType);
         JumpList emitFloatTypedArrayGetByVal(Instruction*, PatchableJump& badType, TypedArrayType);
         
@@ -468,8 +470,10 @@
         void emit_op_construct(Instruction*);
         void emit_op_create_this(Instruction*);
         void emit_op_to_this(Instruction*);
+        void emit_op_create_direct_arguments(Instruction*);
+        void emit_op_create_scoped_arguments(Instruction*);
+        void emit_op_create_out_of_band_arguments(Instruction*);
         void emit_op_check_tdz(Instruction*);
-        void emit_op_create_arguments(Instruction*);
         void emit_op_debug(Instruction*);
         void emit_op_del_by_id(Instruction*);
         void emit_op_div(Instruction*);
@@ -620,6 +624,8 @@
         void emit_op_resolve_scope(Instruction*);
         void emit_op_get_from_scope(Instruction*);
         void emit_op_put_to_scope(Instruction*);
+        void emit_op_get_from_arguments(Instruction*);
+        void emit_op_put_to_arguments(Instruction*);
         void emitSlow_op_resolve_scope(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_get_from_scope(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_put_to_scope(Instruction*, Vector<SlowCaseEntry>::iterator&);
@@ -697,6 +703,7 @@
 #endif
         MacroAssembler::Call callOperation(J_JITOperation_EJIdc, int, GPRReg, const Identifier*);
         MacroAssembler::Call callOperation(J_JITOperation_EJJ, int, GPRReg, GPRReg);
+        MacroAssembler::Call callOperation(C_JITOperation_EJsc, GPRReg);
         MacroAssembler::Call callOperation(J_JITOperation_EJscC, int, GPRReg, JSCell*);
         MacroAssembler::Call callOperation(C_JITOperation_EJscZ, GPRReg, int32_t);
         MacroAssembler::Call callOperation(C_JITOperation_EJscZ, int, GPRReg, int32_t);
diff --git a/Source/JavaScriptCore/jit/JITCall.cpp b/Source/JavaScriptCore/jit/JITCall.cpp
index eb037ab..37f469d 100644
--- a/Source/JavaScriptCore/jit/JITCall.cpp
+++ b/Source/JavaScriptCore/jit/JITCall.cpp
@@ -29,7 +29,6 @@
 #if USE(JSVALUE64)
 #include "JIT.h"
 
-#include "Arguments.h"
 #include "CodeBlock.h"
 #include "JITInlines.h"
 #include "JSArray.h"
@@ -62,22 +61,6 @@
     int firstFreeRegister = instruction[5].u.operand;
     int firstVarArgOffset = instruction[6].u.operand;
 
-    JumpList slowCase;
-    JumpList end;
-    bool canOptimize = m_codeBlock->usesArguments()
-        && arguments == m_codeBlock->argumentsRegister().offset()
-        && !m_codeBlock->symbolTable()->slowArguments();
-
-    if (canOptimize) {
-        emitGetVirtualRegister(arguments, regT0);
-        slowCase.append(branch64(NotEqual, regT0, TrustedImm64(JSValue::encode(JSValue()))));
-        
-        move(TrustedImm32(-firstFreeRegister), regT1);
-        emitSetupVarargsFrameFastCase(*this, regT1, regT0, regT1, regT2, firstVarArgOffset, slowCase);
-        end.append(jump());
-        slowCase.link(this);
-    }
-
     emitGetVirtualRegister(arguments, regT1);
     callOperation(operationSizeFrameForVarargs, regT1, -firstFreeRegister, firstVarArgOffset);
     move(TrustedImm32(-firstFreeRegister), regT1);
@@ -87,9 +70,6 @@
     callOperation(operationSetupVarargsFrame, regT1, regT2, firstVarArgOffset, regT0);
     move(returnValueGPR, regT1);
 
-    if (canOptimize)
-        end.link(this);
-    
     // Profile the argument count.
     load32(Address(regT1, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + PayloadOffset), regT2);
     load8(&info->maxNumArguments, regT0);
diff --git a/Source/JavaScriptCore/jit/JITCall32_64.cpp b/Source/JavaScriptCore/jit/JITCall32_64.cpp
index 4c4fe7c..db4aa3e 100644
--- a/Source/JavaScriptCore/jit/JITCall32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITCall32_64.cpp
@@ -29,7 +29,6 @@
 #if USE(JSVALUE32_64)
 #include "JIT.h"
 
-#include "Arguments.h"
 #include "CodeBlock.h"
 #include "Interpreter.h"
 #include "JITInlines.h"
@@ -122,22 +121,6 @@
     int firstFreeRegister = instruction[5].u.operand;
     int firstVarArgOffset = instruction[6].u.operand;
 
-    JumpList slowCase;
-    JumpList end;
-    bool canOptimize = m_codeBlock->usesArguments()
-        && VirtualRegister(arguments) == m_codeBlock->argumentsRegister()
-        && !m_codeBlock->symbolTable()->slowArguments();
-
-    if (canOptimize) {
-        emitLoadTag(arguments, regT1);
-        slowCase.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::EmptyValueTag)));
-        
-        move(TrustedImm32(-firstFreeRegister), regT1);
-        emitSetupVarargsFrameFastCase(*this, regT1, regT0, regT1, regT2, firstVarArgOffset, slowCase);
-        end.append(jump());
-        slowCase.link(this);
-    }
-
     emitLoad(arguments, regT1, regT0);
     callOperation(operationSizeFrameForVarargs, regT1, regT0, -firstFreeRegister, firstVarArgOffset);
     move(TrustedImm32(-firstFreeRegister), regT1);
@@ -147,9 +130,6 @@
     callOperation(operationSetupVarargsFrame, regT1, regT2, regT4, firstVarArgOffset, regT0);
     move(returnValueGPR, regT1);
 
-    if (canOptimize)
-        end.link(this);
-
     // Profile the argument count.
     load32(Address(regT1, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + PayloadOffset), regT2);
     load8(&info->maxNumArguments, regT0);
diff --git a/Source/JavaScriptCore/jit/JITInlines.h b/Source/JavaScriptCore/jit/JITInlines.h
index a0f0b43..9ee24d0 100644
--- a/Source/JavaScriptCore/jit/JITInlines.h
+++ b/Source/JavaScriptCore/jit/JITInlines.h
@@ -193,6 +193,12 @@
     return appendCallWithExceptionCheck(operation);
 }
 
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(C_JITOperation_EJsc operation, GPRReg arg1)
+{
+    setupArgumentsWithExecState(arg1);
+    return appendCallWithExceptionCheck(operation);
+}
+
 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(C_JITOperation_EJscZ operation, GPRReg arg1, int32_t arg2)
 {
     setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp
index b09ee2b..d3d580e 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp
@@ -28,7 +28,6 @@
 #if ENABLE(JIT)
 #include "JIT.h"
 
-#include "Arguments.h"
 #include "BasicBlockLocation.h"
 #include "CopiedSpaceInlines.h"
 #include "Debugger.h"
@@ -245,18 +244,6 @@
     emitPutVirtualRegister(dst);
 }
 
-void JIT::emit_op_tear_off_arguments(Instruction* currentInstruction)
-{
-    int arguments = currentInstruction[1].u.operand;
-    int lexicalEnvironment = currentInstruction[2].u.operand;
-
-    Jump argsNotCreated = branchTest64(Zero, Address(callFrameRegister, sizeof(Register) * (VirtualRegister(arguments).offset())));
-    emitGetVirtualRegister(VirtualRegister(arguments).offset(), regT0);
-    emitGetVirtualRegister(lexicalEnvironment, regT1);
-    callOperation(operationTearOffArguments, regT0, regT1);
-    argsNotCreated.link(this);
-}
-
 void JIT::emit_op_ret(Instruction* currentInstruction)
 {
     ASSERT(callFrameRegister != regT1);
@@ -677,7 +664,7 @@
     int scope = currentInstruction[2].u.operand;
 
     emitGetVirtualRegister(scope, regT0);
-    callOperation(operationCreateActivation, regT0, 0);
+    callOperation(operationCreateActivation, regT0);
     emitStoreCell(dst, returnValueGPR);
     emitStoreCell(scope, returnValueGPR);
 }
@@ -690,31 +677,6 @@
     emitStoreCell(dst, regT0);
 }
 
-void JIT::emit_op_create_arguments(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-    int lexicalEnvironment = currentInstruction[2].u.operand;
-
-    Jump argsCreated = branchTest64(NonZero, Address(callFrameRegister, sizeof(Register) * dst));
-
-    if (VirtualRegister(lexicalEnvironment).isValid()) {
-        emitGetVirtualRegister(lexicalEnvironment, regT0);
-        callOperation(operationCreateArguments, regT0);
-    } else
-        callOperation(operationCreateArguments, TrustedImmPtr(nullptr));
-    emitStoreCell(dst, returnValueGPR);
-    emitStoreCell(unmodifiedArgumentsRegister(VirtualRegister(dst)), returnValueGPR);
-
-    argsCreated.link(this);
-}
-
-void JIT::emit_op_init_lazy_reg(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-
-    store64(TrustedImm64((int64_t)0), Address(callFrameRegister, sizeof(Register) * dst));
-}
-
 void JIT::emit_op_to_this(Instruction* currentInstruction)
 {
     WriteBarrierBase<Structure>* cachedStructure = &currentInstruction[2].u.structure;
@@ -915,69 +877,6 @@
     slowPathCall.call();
 }
 
-void JIT::emit_op_get_arguments_length(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-    int argumentsRegister = currentInstruction[2].u.operand;
-    addSlowCase(branchTest64(NonZero, addressFor(argumentsRegister)));
-    emitGetFromCallFrameHeader32(JSStack::ArgumentCount, regT0);
-    sub32(TrustedImm32(1), regT0);
-    emitFastArithReTagImmediate(regT0, regT0);
-    emitPutVirtualRegister(dst, regT0);
-}
-
-void JIT::emitSlow_op_get_arguments_length(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
-    linkSlowCase(iter);
-    int dst = currentInstruction[1].u.operand;
-    int base = currentInstruction[2].u.operand;
-    callOperation(operationGetArgumentsLength, dst, base);
-}
-
-void JIT::emit_op_get_argument_by_val(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-    int argumentsRegister = currentInstruction[2].u.operand;
-    int property = currentInstruction[3].u.operand;
-    addSlowCase(branchTest64(NonZero, addressFor(argumentsRegister)));
-    emitGetVirtualRegister(property, regT1);
-    addSlowCase(emitJumpIfNotImmediateInteger(regT1));
-    emitGetFromCallFrameHeader32(JSStack::ArgumentCount, regT2);
-    sub32(TrustedImm32(1), regT2);
-    addSlowCase(branch32(AboveOrEqual, regT1, regT2));
-
-    signExtend32ToPtr(regT1, regT1);
-    load64(BaseIndex(callFrameRegister, regT1, TimesEight, CallFrame::argumentOffset(0) * static_cast<int>(sizeof(Register))), regT0);
-    emitValueProfilingSite();
-    emitPutVirtualRegister(dst, regT0);
-}
-
-void JIT::emitSlow_op_get_argument_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
-    int dst = currentInstruction[1].u.operand;
-    int arguments = currentInstruction[2].u.operand;
-    int property = currentInstruction[3].u.operand;
-    int lexicalEnvironment = currentInstruction[4].u.operand;
-    
-    linkSlowCase(iter);
-    Jump skipArgumentsCreation = jump();
-    
-    linkSlowCase(iter);
-    linkSlowCase(iter);
-    if (VirtualRegister(lexicalEnvironment).isValid()) {
-        emitGetVirtualRegister(lexicalEnvironment, regT0);
-        callOperation(operationCreateArguments, regT0);
-    } else
-        callOperation(operationCreateArguments, TrustedImmPtr(nullptr));
-    emitStoreCell(arguments, returnValueGPR);
-    emitStoreCell(unmodifiedArgumentsRegister(VirtualRegister(arguments)), returnValueGPR);
-    
-    skipArgumentsCreation.link(this);
-    emitGetVirtualRegister(arguments, regT0);
-    emitGetVirtualRegister(property, regT1);
-    callOperation(WithProfile, operationGetByValGeneric, dst, regT0, regT1);
-}
-
 #endif // USE(JSVALUE64)
 
 void JIT::emit_op_touch_entry(Instruction* currentInstruction)
@@ -1042,13 +941,6 @@
 {
     Jump lazyJump;
     int dst = currentInstruction[1].u.operand;
-    if (currentInstruction[4].u.operand) {
-#if USE(JSVALUE32_64)
-        lazyJump = branch32(NotEqual, tagFor(dst), TrustedImm32(JSValue::EmptyValueTag));
-#else
-        lazyJump = branchTest64(NonZero, addressFor(dst));
-#endif
-    }
 
 #if USE(JSVALUE64)
     emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
@@ -1057,9 +949,6 @@
 #endif
     FunctionExecutable* funcExec = m_codeBlock->functionDecl(currentInstruction[3].u.operand);
     callOperation(operationNewFunction, dst, regT0, funcExec);
-
-    if (currentInstruction[4].u.operand)
-        lazyJump.link(this);
 }
 
 void JIT::emit_op_new_func_exp(Instruction* currentInstruction)
@@ -1434,6 +1323,24 @@
         basicBlockLocation->emitExecuteCode(*this, regT1);
 }
 
+void JIT::emit_op_create_direct_arguments(Instruction* currentInstruction)
+{
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_create_direct_arguments);
+    slowPathCall.call();
+}
+
+void JIT::emit_op_create_scoped_arguments(Instruction* currentInstruction)
+{
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_create_scoped_arguments);
+    slowPathCall.call();
+}
+
+void JIT::emit_op_create_out_of_band_arguments(Instruction* currentInstruction)
+{
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_create_out_of_band_arguments);
+    slowPathCall.call();
+}
+
 } // namespace JSC
 
 #endif // ENABLE(JIT)
diff --git a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
index 17abda9..6835eeb 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
@@ -349,18 +349,6 @@
     emitStoreBool(dst, regT0);
 }
 
-void JIT::emit_op_tear_off_arguments(Instruction* currentInstruction)
-{
-    VirtualRegister arguments = VirtualRegister(currentInstruction[1].u.operand);
-    int lexicalEnvironment = currentInstruction[2].u.operand;
-
-    Jump argsNotCreated = branch32(Equal, tagFor(arguments.offset()), TrustedImm32(JSValue::EmptyValueTag));
-    emitLoadPayload(arguments.offset(), regT0);
-    emitLoadPayload(lexicalEnvironment, regT1);
-    callOperation(operationTearOffArguments, regT0, regT1);
-    argsNotCreated.link(this);
-}
-
 void JIT::emit_op_to_primitive(Instruction* currentInstruction)
 {
     int dst = currentInstruction[1].u.operand;
@@ -909,7 +897,7 @@
     int scope = currentInstruction[2].u.operand;
 
     emitLoadPayload(currentInstruction[2].u.operand, regT0);
-    callOperation(operationCreateActivation, regT0, 0);
+    callOperation(operationCreateActivation, regT0);
     emitStoreCell(lexicalEnvironment, returnValueGPR);
     emitStoreCell(scope, returnValueGPR);
 }
@@ -922,31 +910,6 @@
     emitStoreCell(dst, regT0);
 }
 
-void JIT::emit_op_create_arguments(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-    int lexicalEnvironment = currentInstruction[2].u.operand;
-
-    Jump argsCreated = branch32(NotEqual, tagFor(dst), TrustedImm32(JSValue::EmptyValueTag));
-
-    if (VirtualRegister(lexicalEnvironment).isValid()) {
-        emitLoadPayload(lexicalEnvironment, regT0);
-        callOperation(operationCreateArguments, regT0);
-    } else
-        callOperation(operationCreateArguments, TrustedImmPtr(nullptr));
-    emitStoreCell(dst, returnValueGPR);
-    emitStoreCell(unmodifiedArgumentsRegister(VirtualRegister(dst)).offset(), returnValueGPR);
-
-    argsCreated.link(this);
-}
-
-void JIT::emit_op_init_lazy_reg(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-
-    emitStore(dst, JSValue());
-}
-
 void JIT::emit_op_create_this(Instruction* currentInstruction)
 {
     int callee = currentInstruction[2].u.operand;
@@ -1028,70 +991,6 @@
     profilerDone.link(this);
 }
 
-void JIT::emit_op_get_arguments_length(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-    int argumentsRegister = currentInstruction[2].u.operand;
-    addSlowCase(branch32(NotEqual, tagFor(argumentsRegister), TrustedImm32(JSValue::EmptyValueTag)));
-    load32(payloadFor(JSStack::ArgumentCount), regT0);
-    sub32(TrustedImm32(1), regT0);
-    emitStoreInt32(dst, regT0);
-}
-
-void JIT::emitSlow_op_get_arguments_length(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
-    linkSlowCase(iter);
-    int dst = currentInstruction[1].u.operand;
-    int base = currentInstruction[2].u.operand;
-    callOperation(operationGetArgumentsLength, dst, base);
-}
-
-void JIT::emit_op_get_argument_by_val(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-    int argumentsRegister = currentInstruction[2].u.operand;
-    int property = currentInstruction[3].u.operand;
-    addSlowCase(branch32(NotEqual, tagFor(argumentsRegister), TrustedImm32(JSValue::EmptyValueTag)));
-    emitLoad(property, regT1, regT2);
-    addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
-    // regT2 now contains the integer index of the argument we want, including this
-    load32(payloadFor(JSStack::ArgumentCount), regT3);
-    sub32(TrustedImm32(1), regT3);
-    addSlowCase(branch32(AboveOrEqual, regT2, regT3));
-    
-    loadPtr(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) + CallFrame::argumentOffset(0) * static_cast<int>(sizeof(Register))), regT0);
-    loadPtr(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) + CallFrame::argumentOffset(0) * static_cast<int>(sizeof(Register))), regT1);
-    emitValueProfilingSite();
-    emitStore(dst, regT1, regT0);
-}
-
-void JIT::emitSlow_op_get_argument_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
-    int dst = currentInstruction[1].u.operand;
-    int arguments = currentInstruction[2].u.operand;
-    int property = currentInstruction[3].u.operand;
-    int lexicalEnvironment = currentInstruction[4].u.operand;
-
-    linkSlowCase(iter);
-    Jump skipArgumentsCreation = jump();
-
-    linkSlowCase(iter);
-    linkSlowCase(iter);
-
-    if (VirtualRegister(lexicalEnvironment).isValid()) {
-        emitLoadPayload(lexicalEnvironment, regT0);
-        callOperation(operationCreateArguments, regT0);
-    } else
-        callOperation(operationCreateArguments, TrustedImmPtr(nullptr));
-    emitStoreCell(arguments, returnValueGPR);
-    emitStoreCell(unmodifiedArgumentsRegister(VirtualRegister(arguments)).offset(), returnValueGPR);
-    
-    skipArgumentsCreation.link(this);
-    emitLoad(arguments, regT1, regT0);
-    emitLoad(property, regT3, regT2);
-    callOperation(WithProfile, operationGetByValGeneric, dst, regT1, regT0, regT3, regT2);
-}
-
 void JIT::emit_op_has_structure_property(Instruction* currentInstruction)
 {
     int dst = currentInstruction[1].u.operand;
diff --git a/Source/JavaScriptCore/jit/JITOperations.cpp b/Source/JavaScriptCore/jit/JITOperations.cpp
index c77c6ae..c651eac 100644
--- a/Source/JavaScriptCore/jit/JITOperations.cpp
+++ b/Source/JavaScriptCore/jit/JITOperations.cpp
@@ -28,7 +28,6 @@
 
 #if ENABLE(JIT)
 
-#include "Arguments.h"
 #include "ArrayConstructor.h"
 #include "DFGCompilationMode.h"
 #include "DFGDriver.h"
@@ -47,6 +46,7 @@
 #include "JSCatchScope.h"
 #include "JSFunctionNameScope.h"
 #include "JSGlobalObjectFunctions.h"
+#include "JSLexicalEnvironment.h"
 #include "JSNameScope.h"
 #include "JSPropertyNameEnumerator.h"
 #include "JSStackInlines.h"
@@ -530,7 +530,7 @@
         if (hasOptimizableIndexing(object->structure(vm))) {
             // Attempt to optimize.
             JITArrayMode arrayMode = jitArrayModeForStructure(object->structure(vm));
-            if (arrayMode != byValInfo.arrayMode) {
+            if (jitArrayModePermitsPut(arrayMode) && arrayMode != byValInfo.arrayMode) {
                 JIT::compilePutByVal(&vm, exec->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
                 didOptimize = true;
             }
@@ -575,7 +575,7 @@
         if (hasOptimizableIndexing(object->structure(vm))) {
             // Attempt to optimize.
             JITArrayMode arrayMode = jitArrayModeForStructure(object->structure(vm));
-            if (arrayMode != byValInfo.arrayMode) {
+            if (jitArrayModePermitsPut(arrayMode) && arrayMode != byValInfo.arrayMode) {
                 JIT::compileDirectPutByVal(&vm, callFrame->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
                 didOptimize = true;
             }
@@ -732,6 +732,7 @@
         callLinkInfo->setSeen();
     else
         linkFor(execCallee, *callLinkInfo, codeBlock, callee, codePtr, kind, registers);
+    
     return reinterpret_cast<char*>(codePtr.executableAddress());
 }
 
@@ -1353,51 +1354,14 @@
     return JSValue::encode(JSValue());
 }
 
-JSCell* JIT_OPERATION operationCreateActivation(ExecState* exec, JSScope* currentScope, int32_t offset)
+JSCell* JIT_OPERATION operationCreateActivation(ExecState* exec, JSScope* currentScope)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
-    JSLexicalEnvironment* lexicalEnvironment = JSLexicalEnvironment::create(vm, exec, exec->registers() + offset, currentScope, exec->codeBlock());
+    JSLexicalEnvironment* lexicalEnvironment = JSLexicalEnvironment::create(vm, exec, currentScope, exec->codeBlock());
     return lexicalEnvironment;
 }
 
-// FIXME: This is a temporary thunk for the DFG until we add the lexicalEnvironment operand to the DFG CreateArguments node.
-JSCell* JIT_OPERATION operationCreateArgumentsForDFG(ExecState* exec)
-{
-    JSLexicalEnvironment* lexicalEnvironment = exec->lexicalEnvironmentOrNullptr();
-    return operationCreateArguments(exec, lexicalEnvironment);
-}
-    
-JSCell* JIT_OPERATION operationCreateArguments(ExecState* exec, JSLexicalEnvironment* lexicalEnvironment)
-{
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-    // NB: This needs to be exceedingly careful with top call frame tracking, since it
-    // may be called from OSR exit, while the state of the call stack is bizarre.
-    Arguments* result = Arguments::create(vm, exec, lexicalEnvironment);
-    ASSERT(!vm.exception());
-    return result;
-}
-
-JSCell* JIT_OPERATION operationCreateArgumentsDuringOSRExit(ExecState* exec)
-{
-    DeferGCForAWhile(exec->vm().heap);
-    JSLexicalEnvironment* lexicalEnvironment = exec->lexicalEnvironmentOrNullptr();
-    return operationCreateArguments(exec, lexicalEnvironment);
-}
-
-EncodedJSValue JIT_OPERATION operationGetArgumentsLength(ExecState* exec, int32_t argumentsRegister)
-{
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-    // Here we can assume that the argumernts were created. Because otherwise the JIT code would
-    // have not made this call.
-    Identifier ident(&vm, "length");
-    JSValue baseValue = exec->uncheckedR(argumentsRegister).jsValue();
-    PropertySlot slot(baseValue);
-    return JSValue::encode(baseValue.get(exec, ident, slot));
-}
-
 }
 
 static JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript, ReturnAddressPtr returnAddress)
@@ -1565,12 +1529,6 @@
     return JSValue::encode(result);
 }
 
-void JIT_OPERATION operationTearOffArguments(ExecState* exec, JSCell* argumentsCell, JSCell*)
-{
-    ASSERT(exec->codeBlock()->usesArguments());
-    jsCast<Arguments*>(argumentsCell)->tearOff(exec);
-}
-
 EncodedJSValue JIT_OPERATION operationDeleteById(ExecState* exec, EncodedJSValue encodedBase, const Identifier* identifier)
 {
     VM& vm = exec->vm();
@@ -1734,7 +1692,7 @@
     ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
     if (modeAndType.type() == LocalClosureVar) {
         JSLexicalEnvironment* environment = jsCast<JSLexicalEnvironment*>(scope);
-        environment->registerAt(pc[6].u.operand).set(vm, environment, value);
+        environment->variableAt(ScopeOffset(pc[6].u.operand)).set(vm, environment, value);
         if (VariableWatchpointSet* set = pc[5].u.watchpointSet)
             set->notifyWrite(vm, value, "Executed op_put_scope<LocalClosureVar>");
         return;
@@ -1795,7 +1753,7 @@
     NativeCallFrameTracer tracer(vm, exec);
 
     JSValue value = exec->r(pc[2].u.operand).jsValue();
-    pc[1].u.registerPointer->set(*vm, exec->codeBlock()->globalObject(), value);
+    pc[1].u.variablePointer->set(*vm, exec->codeBlock()->globalObject(), value);
 }
 
 void JIT_OPERATION lookupExceptionHandler(VM* vm, ExecState* exec)
diff --git a/Source/JavaScriptCore/jit/JITOperations.h b/Source/JavaScriptCore/jit/JITOperations.h
index e289979..4decef4 100644
--- a/Source/JavaScriptCore/jit/JITOperations.h
+++ b/Source/JavaScriptCore/jit/JITOperations.h
@@ -65,11 +65,12 @@
     E: ExecState*
     F: CallFrame*
     I: StringImpl*
-    Icf: InlineCalLFrame*
+    Icf: InlineCallFrame*
     Idc: const Identifier*
     J: EncodedJSValue
     Jcp: const JSValue*
     Jsc: JSScope*
+    Jsf: JSFunction*
     Jss: JSString*
     L: JSLexicalEnvironment*
     O: JSObject*
@@ -129,6 +130,7 @@
 typedef JSCell* JIT_OPERATION (*C_JITOperation_ECC)(ExecState*, JSCell*, JSCell*);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EIcf)(ExecState*, InlineCallFrame*);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EJ)(ExecState*, EncodedJSValue);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EJsc)(ExecState*, JSScope*);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EJscC)(ExecState*, JSScope*, JSCell*);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EJZ)(ExecState*, EncodedJSValue, int32_t);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EJZC)(ExecState*, EncodedJSValue, int32_t, JSCell*);
@@ -141,6 +143,11 @@
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EO)(ExecState*, JSObject*);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EOZ)(ExecState*, JSObject*, int32_t);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_ESt)(ExecState*, Structure*);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EStJscSymtab)(ExecState*, Structure*, JSScope*, SymbolTable*);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EStRZJsfL)(ExecState*, Structure*, Register*, int32_t, JSFunction*, JSLexicalEnvironment*);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EStRZJsf)(ExecState*, Structure*, Register*, int32_t, JSFunction*);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EStZ)(ExecState*, Structure*, int32_t);
+typedef JSCell* JIT_OPERATION (*C_JITOperation_EStZZ)(ExecState*, Structure*, int32_t, int32_t);
 typedef JSCell* JIT_OPERATION (*C_JITOperation_EZ)(ExecState*, int32_t);
 typedef double JIT_OPERATION (*D_JITOperation_D)(double);
 typedef double JIT_OPERATION (*D_JITOperation_DD)(double, double);
@@ -293,17 +300,12 @@
 void JIT_OPERATION operationProfileDidCall(ExecState*, EncodedJSValue) WTF_INTERNAL;
 void JIT_OPERATION operationProfileWillCall(ExecState*, EncodedJSValue) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationCheckHasInstance(ExecState*, EncodedJSValue, EncodedJSValue baseVal) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationCreateActivation(ExecState*, JSScope* currentScope, int32_t offset) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationCreateArgumentsForDFG(ExecState*) WTF_INTERNAL; // FIXME: This is a temporary thunk for the DFG until we add the lexicalEnvironment operand to the DFG CreateArguments node.
-JSCell* JIT_OPERATION operationCreateArguments(ExecState*, JSLexicalEnvironment*) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationCreateArgumentsDuringOSRExit(ExecState*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationGetArgumentsLength(ExecState*, int32_t) WTF_INTERNAL;
+JSCell* JIT_OPERATION operationCreateActivation(ExecState*, JSScope* currentScope) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationGetByValDefault(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationGetByValGeneric(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationGetByValString(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyDefault(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyGeneric(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
-void JIT_OPERATION operationTearOffArguments(ExecState*, JSCell*, JSCell*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationDeleteById(ExecState*, EncodedJSValue base, const Identifier*) WTF_INTERNAL;
 JSCell* JIT_OPERATION operationGetPNames(ExecState*, JSObject*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationInstanceOf(ExecState*, EncodedJSValue, EncodedJSValue proto) WTF_INTERNAL;
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
index 8cdb070..260fa5e 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +29,7 @@
 #include "JIT.h"
 
 #include "CodeBlock.h"
+#include "DirectArguments.h"
 #include "GCAwareJITStubRoutine.h"
 #include "GetterSetter.h"
 #include "Interpreter.h"
@@ -40,6 +41,8 @@
 #include "RepatchBuffer.h"
 #include "ResultType.h"
 #include "SamplingTool.h"
+#include "ScopedArguments.h"
+#include "ScopedArgumentsTable.h"
 #include <wtf/StringPrintStream.h>
 
 
@@ -664,8 +667,7 @@
 void JIT::emitGetClosureVar(int scope, uintptr_t operand)
 {
     emitGetVirtualRegister(scope, regT0);
-    loadPtr(Address(regT0, JSEnvironmentRecord::offsetOfRegisters()), regT0);
-    loadPtr(Address(regT0, operand * sizeof(Register)), regT0);
+    loadPtr(Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register)), regT0);
 }
 
 void JIT::emit_op_get_from_scope(Instruction* currentInstruction)
@@ -748,9 +750,8 @@
 {
     emitGetVirtualRegister(value, regT1);
     emitGetVirtualRegister(scope, regT0);
-    loadPtr(Address(regT0, JSEnvironmentRecord::offsetOfRegisters()), regT0);
     emitNotifyWrite(regT1, regT2, set);
-    storePtr(regT1, Address(regT0, operand * sizeof(Register)));
+    storePtr(regT1, Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register)));
 }
 
 void JIT::emit_op_put_to_scope(Instruction* currentInstruction)
@@ -805,12 +806,37 @@
     callOperation(operationPutToScope, currentInstruction);
 }
 
+void JIT::emit_op_get_from_arguments(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int arguments = currentInstruction[2].u.operand;
+    int index = currentInstruction[3].u.operand;
+    
+    emitGetVirtualRegister(arguments, regT0);
+    load64(Address(regT0, DirectArguments::storageOffset() + index * sizeof(WriteBarrier<Unknown>)), regT0);
+    emitValueProfilingSite();
+    emitPutVirtualRegister(dst);
+}
+
+void JIT::emit_op_put_to_arguments(Instruction* currentInstruction)
+{
+    int arguments = currentInstruction[1].u.operand;
+    int index = currentInstruction[2].u.operand;
+    int value = currentInstruction[3].u.operand;
+    
+    emitWriteBarrier(arguments, value, ShouldFilterValue);
+    
+    emitGetVirtualRegister(arguments, regT0);
+    emitGetVirtualRegister(value, regT1);
+    store64(regT1, Address(regT0, DirectArguments::storageOffset() + index * sizeof(WriteBarrier<Unknown>)));
+}
+
 void JIT::emit_op_init_global_const(Instruction* currentInstruction)
 {
     JSGlobalObject* globalObject = m_codeBlock->globalObject();
     emitWriteBarrier(globalObject, currentInstruction[2].u.operand, ShouldFilterValue);
     emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
-    store64(regT0, currentInstruction[1].u.registerPointer);
+    store64(regT0, currentInstruction[1].u.variablePointer);
 }
 
 #endif // USE(JSVALUE64)
@@ -951,6 +977,12 @@
     case JITArrayStorage:
         slowCases = emitArrayStorageGetByVal(currentInstruction, badType);
         break;
+    case JITDirectArguments:
+        slowCases = emitDirectArgumentsGetByVal(currentInstruction, badType);
+        break;
+    case JITScopedArguments:
+        slowCases = emitScopedArgumentsGetByVal(currentInstruction, badType);
+        break;
     default:
         TypedArrayType type = typedArrayTypeForJITArrayMode(arrayMode);
         if (isInt(type))
@@ -1046,6 +1078,75 @@
     repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(isDirect ? operationDirectPutByValGeneric : operationPutByValGeneric));
 }
 
+JIT::JumpList JIT::emitDirectArgumentsGetByVal(Instruction*, PatchableJump& badType)
+{
+    JumpList slowCases;
+    
+#if USE(JSVALUE64)
+    RegisterID base = regT0;
+    RegisterID property = regT1;
+    JSValueRegs result = JSValueRegs(regT0);
+    RegisterID scratch = regT3;
+#else
+    RegisterID base = regT0;
+    RegisterID property = regT2;
+    JSValueRegs result = JSValueRegs(regT1, regT0);
+    RegisterID scratch = regT3;
+#endif
+
+    load8(Address(base, JSCell::typeInfoTypeOffset()), scratch);
+    badType = patchableBranch32(NotEqual, scratch, TrustedImm32(DirectArgumentsType));
+    
+    slowCases.append(branch32(AboveOrEqual, property, Address(base, DirectArguments::offsetOfLength())));
+    slowCases.append(branchTestPtr(NonZero, Address(base, DirectArguments::offsetOfOverrides())));
+    
+    zeroExtend32ToPtr(property, scratch);
+    loadValue(BaseIndex(base, scratch, TimesEight, DirectArguments::storageOffset()), result);
+    
+    return slowCases;
+}
+
+JIT::JumpList JIT::emitScopedArgumentsGetByVal(Instruction*, PatchableJump& badType)
+{
+    JumpList slowCases;
+    
+#if USE(JSVALUE64)
+    RegisterID base = regT0;
+    RegisterID property = regT1;
+    JSValueRegs result = JSValueRegs(regT0);
+    RegisterID scratch = regT3;
+    RegisterID scratch2 = regT4;
+#else
+    RegisterID base = regT0;
+    RegisterID property = regT2;
+    JSValueRegs result = JSValueRegs(regT1, regT0);
+    RegisterID scratch = regT3;
+    RegisterID scratch2 = regT4;
+#endif
+
+    load8(Address(base, JSCell::typeInfoTypeOffset()), scratch);
+    badType = patchableBranch32(NotEqual, scratch, TrustedImm32(DirectArgumentsType));
+    slowCases.append(branch32(AboveOrEqual, property, Address(base, ScopedArguments::offsetOfTotalLength())));
+    
+    loadPtr(Address(base, ScopedArguments::offsetOfTable()), scratch);
+    load32(Address(scratch, ScopedArgumentsTable::offsetOfLength()), scratch2);
+    Jump overflowCase = branch32(AboveOrEqual, property, scratch2);
+    loadPtr(Address(base, ScopedArguments::offsetOfScope()), scratch2);
+    loadPtr(Address(scratch, ScopedArgumentsTable::offsetOfArguments()), scratch);
+    load32(BaseIndex(scratch, property, TimesFour), scratch);
+    slowCases.append(branch32(Equal, scratch, TrustedImm32(ScopeOffset::invalidOffset)));
+    loadValue(BaseIndex(scratch2, scratch, TimesEight, JSEnvironmentRecord::offsetOfVariables()), result);
+    Jump done = jump();
+    overflowCase.link(this);
+    sub32(property, scratch2);
+    neg32(scratch2);
+    loadValue(BaseIndex(base, scratch2, TimesEight, ScopedArguments::overflowStorageOffset()), result);
+    slowCases.append(branchIsEmpty(result));
+    done.link(this);
+    
+    return slowCases;
+}
+
 JIT::JumpList JIT::emitIntTypedArrayGetByVal(Instruction*, PatchableJump& badType, TypedArrayType type)
 {
     ASSERT(isInt(type));
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
index 3171d74..567484d 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,6 +30,7 @@
 #include "JIT.h"
 
 #include "CodeBlock.h"
+#include "DirectArguments.h"
 #include "GCAwareJITStubRoutine.h"
 #include "Interpreter.h"
 #include "JITInlines.h"
@@ -688,9 +689,8 @@
 void JIT::emitGetClosureVar(int scope, uintptr_t operand)
 {
     emitLoad(scope, regT1, regT0);
-    loadPtr(Address(regT0, JSEnvironmentRecord::offsetOfRegisters()), regT0);
-    load32(Address(regT0, operand * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), regT1);
-    load32(Address(regT0, operand * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), regT0);
+    load32(Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register) + TagOffset), regT1);
+    load32(Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register) + PayloadOffset), regT0);
 }
 
 void JIT::emit_op_get_from_scope(Instruction* currentInstruction)
@@ -780,9 +780,8 @@
     emitLoad(value, regT3, regT2);
     emitLoad(scope, regT1, regT0);
     emitNotifyWrite(regT3, regT2, regT4, set);
-    loadPtr(Address(regT0, JSEnvironmentRecord::offsetOfRegisters()), regT0);
-    store32(regT3, Address(regT0, operand * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
-    store32(regT2, Address(regT0, operand * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
+    store32(regT3, Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register) + TagOffset));
+    store32(regT2, Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register) + PayloadOffset));
 }
 
 void JIT::emit_op_put_to_scope(Instruction* currentInstruction)
@@ -835,9 +834,36 @@
     callOperation(operationPutToScope, currentInstruction);
 }
 
+void JIT::emit_op_get_from_arguments(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int arguments = currentInstruction[2].u.operand;
+    int index = currentInstruction[3].u.operand;
+    
+    emitLoadPayload(arguments, regT0);
+    load32(Address(regT0, DirectArguments::storageOffset() + index * sizeof(WriteBarrier<Unknown>) + TagOffset), regT1);
+    load32(Address(regT0, DirectArguments::storageOffset() + index * sizeof(WriteBarrier<Unknown>) + PayloadOffset), regT0);
+    emitValueProfilingSite();
+    emitStore(dst, regT1, regT0);
+}
+
+void JIT::emit_op_put_to_arguments(Instruction* currentInstruction)
+{
+    int arguments = currentInstruction[1].u.operand;
+    int index = currentInstruction[2].u.operand;
+    int value = currentInstruction[3].u.operand;
+    
+    emitWriteBarrier(arguments, value, ShouldFilterValue);
+    
+    emitLoadPayload(arguments, regT0);
+    emitLoad(value, regT1, regT2);
+    store32(regT1, Address(regT0, DirectArguments::storageOffset() + index * sizeof(WriteBarrier<Unknown>) + TagOffset));
+    store32(regT2, Address(regT0, DirectArguments::storageOffset() + index * sizeof(WriteBarrier<Unknown>) + PayloadOffset));
+}
+
 void JIT::emit_op_init_global_const(Instruction* currentInstruction)
 {
-    WriteBarrier<Unknown>* registerPointer = currentInstruction[1].u.registerPointer;
+    WriteBarrier<Unknown>* variablePointer = currentInstruction[1].u.variablePointer;
     int value = currentInstruction[2].u.operand;
 
     JSGlobalObject* globalObject = m_codeBlock->globalObject();
@@ -846,8 +872,8 @@
 
     emitLoad(value, regT1, regT0);
     
-    store32(regT1, registerPointer->tagPointer());
-    store32(regT0, registerPointer->payloadPointer());
+    store32(regT1, variablePointer->tagPointer());
+    store32(regT0, variablePointer->payloadPointer());
 }
 
 } // namespace JSC
diff --git a/Source/JavaScriptCore/jit/SetupVarargsFrame.cpp b/Source/JavaScriptCore/jit/SetupVarargsFrame.cpp
index bb63596..9e133cc 100644
--- a/Source/JavaScriptCore/jit/SetupVarargsFrame.cpp
+++ b/Source/JavaScriptCore/jit/SetupVarargsFrame.cpp
@@ -28,7 +28,7 @@
 
 #if ENABLE(JIT)
 
-#include "Arguments.h"
+#include "Interpreter.h"
 #include "JSCInlines.h"
 #include "StackAlignment.h"
 
@@ -69,7 +69,7 @@
         jit.sub32(CCallHelpers::TrustedImm32(firstVarArgOffset), scratchGPR1);
         endVarArgs.link(&jit);
     }
-    slowCase.append(jit.branch32(CCallHelpers::Above, scratchGPR1, CCallHelpers::TrustedImm32(Arguments::MaxArguments + 1)));
+    slowCase.append(jit.branch32(CCallHelpers::Above, scratchGPR1, CCallHelpers::TrustedImm32(maxArguments + 1)));
     
     emitSetVarargsFrame(jit, scratchGPR1, true, numUsedSlotsGPR, scratchGPR2);
 
diff --git a/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp b/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
index 9391878..dea3782 100644
--- a/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
+++ b/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +29,7 @@
 #include "CodeBlock.h"
 #include "CommonSlowPaths.h"
 #include "Debugger.h"
+#include "DirectArguments.h"
 #include "Executable.h"
 #include "Heap.h"
 #include "Interpreter.h"
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
index 1c1ac1e..db4310e 100644
--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
@@ -26,11 +26,11 @@
 #include "config.h"
 #include "LLIntSlowPaths.h"
 
-#include "Arguments.h"
 #include "ArrayConstructor.h"
 #include "CallFrame.h"
 #include "CommonSlowPaths.h"
 #include "CommonSlowPathsExceptions.h"
+#include "Error.h"
 #include "ErrorHandlingScope.h"
 #include "ExceptionFuzz.h"
 #include "GetterSetter.h"
@@ -254,12 +254,11 @@
 
 LLINT_SLOW_PATH_DECL(trace)
 {
-    dataLogF("%p / %p: executing bc#%zu, %s, scope %p, pc = %p\n",
+    dataLogF("%p / %p: executing bc#%zu, %s, pc = %p\n",
             exec->codeBlock(),
             exec,
             static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
-            opcodeNames[exec->vm().interpreter->getOpcodeID(pc[0].u.opcode)],
-            exec->uncheckedR(exec->codeBlock()->scopeRegister().offset()).Register::scope(), pc);
+            opcodeNames[exec->vm().interpreter->getOpcodeID(pc[0].u.opcode)], pc);
     if (exec->vm().interpreter->getOpcodeID(pc[0].u.opcode) == op_enter) {
         dataLogF("Frame will eventually return to %p\n", exec->returnPC().value());
         *bitwise_cast<volatile char*>(exec->returnPC().value());
@@ -507,7 +506,6 @@
     int scopeReg = pc[2].u.operand;
     JSScope* scope = exec->uncheckedR(scopeReg).Register::scope();
     JSLexicalEnvironment* lexicalEnvironment = JSLexicalEnvironment::create(vm, exec, scope, exec->codeBlock());
-    exec->uncheckedR(pc[2].u.operand) = lexicalEnvironment;
     LLINT_RETURN(JSValue(lexicalEnvironment));
 }
 
@@ -755,24 +753,6 @@
     LLINT_RETURN_PROFILED(op_get_by_val, getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
 }
 
-LLINT_SLOW_PATH_DECL(slow_path_get_argument_by_val)
-{
-    LLINT_BEGIN();
-    JSValue arguments = LLINT_OP(2).jsValue();
-    if (!arguments) {
-        int lexicalEnvironmentReg = pc[4].u.operand;
-        JSLexicalEnvironment* lexicalEnvironment = VirtualRegister(lexicalEnvironmentReg).isValid() ?
-            exec->uncheckedR(lexicalEnvironmentReg).lexicalEnvironment() : nullptr;
-        arguments = JSValue(Arguments::create(vm, exec, lexicalEnvironment));
-
-        LLINT_CHECK_EXCEPTION();
-        LLINT_OP(2) = arguments;
-        exec->uncheckedR(unmodifiedArgumentsRegister(VirtualRegister(pc[2].u.operand)).offset()) = arguments;
-    }
-    
-    LLINT_RETURN_PROFILED(op_get_argument_by_val, getByVal(exec, arguments, LLINT_OP_C(3).jsValue()));
-}
-
 LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
 {
     LLINT_BEGIN();
@@ -1239,15 +1219,6 @@
     LLINT_CALL_RETURN(exec, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
 }
 
-LLINT_SLOW_PATH_DECL(slow_path_tear_off_arguments)
-{
-    LLINT_BEGIN();
-    ASSERT(exec->codeBlock()->usesArguments());
-    Arguments* arguments = jsCast<Arguments*>(exec->uncheckedR(VirtualRegister(pc[1].u.operand).offset()).jsValue());
-    arguments->tearOff(exec);
-    LLINT_END();
-}
-
 LLINT_SLOW_PATH_DECL(slow_path_strcat)
 {
     LLINT_BEGIN();
@@ -1407,7 +1378,7 @@
     ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
     if (modeAndType.type() == LocalClosureVar) {
         JSLexicalEnvironment* environment = jsCast<JSLexicalEnvironment*>(scope);
-        environment->registerAt(pc[6].u.operand).set(vm, environment, value);
+        environment->variableAt(ScopeOffset(pc[6].u.operand)).set(vm, environment, value);
         if (VariableWatchpointSet* set = pc[5].u.watchpointSet)
             set->notifyWrite(vm, value, "Executed op_put_scope<LocalClosureVar>");
         LLINT_END();
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
index 1991042..43ed7e8 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
@@ -42,6 +42,9 @@
 end
 const SlotSize = 8
 
+const JSEnvironmentRecord_variables = (sizeof JSEnvironmentRecord + SlotSize - 1) & ~(SlotSize - 1)
+const DirectArguments_storage = (sizeof DirectArguments + SlotSize - 1) & ~(SlotSize - 1)
+
 const StackAlignment = 16
 const StackAlignmentMask = StackAlignment - 1
 
@@ -923,6 +926,30 @@
     dispatch(1)
 
 
+_llint_op_create_direct_arguments:
+    traceExecution()
+    callSlowPath(_slow_path_create_direct_arguments)
+    dispatch(2)
+
+
+_llint_op_create_scoped_arguments:
+    traceExecution()
+    callSlowPath(_slow_path_create_scoped_arguments)
+    dispatch(3)
+
+
+_llint_op_create_out_of_band_arguments:
+    traceExecution()
+    callSlowPath(_slow_path_create_out_of_band_arguments)
+    dispatch(2)
+
+
+_llint_op_new_func:
+    traceExecution()
+    callSlowPath(_llint_slow_path_new_func)
+    dispatch(4)
+
+
 _llint_op_new_array:
     traceExecution()
     callSlowPath(_llint_slow_path_new_array)
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
index 5bcd89f..ca91e8d 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
@@ -722,7 +722,6 @@
 
 _llint_op_create_lexical_environment:
     traceExecution()
-    loadi 4[PC], t0
     callSlowPath(_llint_slow_path_create_lexical_environment)
     dispatch(3)
 
@@ -737,23 +736,6 @@
     dispatch(2)
 
 
-_llint_op_init_lazy_reg:
-    traceExecution()
-    loadi 4[PC], t0
-    storei EmptyValueTag, TagOffset[cfr, t0, 8]
-    storei 0, PayloadOffset[cfr, t0, 8]
-    dispatch(2)
-
-
-_llint_op_create_arguments:
-    traceExecution()
-    loadi 4[PC], t0
-    bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opCreateArgumentsDone
-    callSlowPath(_slow_path_create_arguments)
-.opCreateArgumentsDone:
-    dispatch(3)
-
-
 _llint_op_create_this:
     traceExecution()
     loadi 8[PC], t0
@@ -1450,22 +1432,6 @@
     dispatch(9)
 
 
-_llint_op_get_arguments_length:
-    traceExecution()
-    loadi 8[PC], t0
-    loadi 4[PC], t1
-    bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opGetArgumentsLengthSlow
-    loadi ArgumentCount + PayloadOffset[cfr], t2
-    subi 1, t2
-    storei Int32Tag, TagOffset[cfr, t1, 8]
-    storei t2, PayloadOffset[cfr, t1, 8]
-    dispatch(4)
-
-.opGetArgumentsLengthSlow:
-    callSlowPath(_llint_slow_path_get_arguments_length)
-    dispatch(4)
-
-
 macro putById(getPropertyStorage)
     traceExecution()
     writeBarrierOnOperands(1, 3)
@@ -1616,30 +1582,6 @@
     dispatch(6)
 
 
-_llint_op_get_argument_by_val:
-    # FIXME: At some point we should array profile this. Right now it isn't necessary
-    # since the DFG will never turn a get_argument_by_val into a GetByVal.
-    traceExecution()
-    loadi 8[PC], t0
-    loadi 12[PC], t1
-    bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opGetArgumentByValSlow
-    loadConstantOrVariablePayload(t1, Int32Tag, t2, .opGetArgumentByValSlow)
-    loadi ArgumentCount + PayloadOffset[cfr], t1
-    subi 1, t1
-    biaeq t2, t1, .opGetArgumentByValSlow
-    loadi 4[PC], t3
-    loadi FirstArgumentOffset + TagOffset[cfr, t2, 8], t0
-    loadi FirstArgumentOffset + PayloadOffset[cfr, t2, 8], t1
-    storei t0, TagOffset[cfr, t3, 8]
-    storei t1, PayloadOffset[cfr, t3, 8]
-    valueProfile(t0, t1, 24, t2)
-    dispatch(7)
-
-.opGetArgumentByValSlow:
-    callSlowPath(_llint_slow_path_get_argument_by_val)
-    dispatch(7)
-
-
 macro contiguousPutByVal(storeCallback)
     biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], .outOfBounds
 .storeResult:
@@ -1921,16 +1863,6 @@
     dispatch(0)
 
 
-_llint_op_new_func:
-    traceExecution()
-    btiz 16[PC], .opNewFuncUnchecked
-    loadi 4[PC], t1
-    bineq TagOffset[cfr, t1, 8], EmptyValueTag, .opNewFuncDone
-.opNewFuncUnchecked:
-    callSlowPath(_llint_slow_path_new_func)
-.opNewFuncDone:
-    dispatch(5)
-
 macro arrayProfileForCall()
     loadi 16[PC], t3
     negi t3
@@ -1964,14 +1896,6 @@
     slowPathForCall(slowPath)
 end
 
-_llint_op_tear_off_arguments:
-    traceExecution()
-    loadi 4[PC], t0
-    bieq TagOffset[cfr, t0, 8], EmptyValueTag, .opTearOffArgumentsNotCreated
-    callSlowPath(_llint_slow_path_tear_off_arguments)
-.opTearOffArgumentsNotCreated:
-    dispatch(3)
-
 
 _llint_op_ret:
     traceExecution()
@@ -2213,10 +2137,9 @@
 end
 
 macro getClosureVar()
-    loadp JSEnvironmentRecord::m_registers[t0], t0
     loadisFromInstruction(6, t3)
-    loadp TagOffset[t0, t3, 8], t1
-    loadp PayloadOffset[t0, t3, 8], t2
+    loadp JSEnvironmentRecord_variables + TagOffset[t0, t3, 8], t1
+    loadp JSEnvironmentRecord_variables + PayloadOffset[t0, t3, 8], t2
     valueProfile(t1, t2, 28, t0)
     loadisFromInstruction(1, t0)
     storei t1, TagOffset[cfr, t0, 8]
@@ -2290,10 +2213,9 @@
 macro putClosureVar()
     loadisFromInstruction(3, t1)
     loadConstantOrVariable(t1, t2, t3)
-    loadp JSEnvironmentRecord::m_registers[t0], t0
     loadisFromInstruction(6, t1)
-    storei t2, TagOffset[t0, t1, 8]
-    storei t3, PayloadOffset[t0, t1, 8]
+    storei t2, JSEnvironmentRecord_variables + TagOffset[t0, t1, 8]
+    storei t3, JSEnvironmentRecord_variables + PayloadOffset[t0, t1, 8]
 end
 
 macro putLocalClosureVar()
@@ -2303,10 +2225,9 @@
     btpz t4, .noVariableWatchpointSet
     notifyWrite(t4, t2, t3, t1, .pDynamic)
 .noVariableWatchpointSet:
-    loadp JSEnvironmentRecord::m_registers[t0], t0
     loadisFromInstruction(6, t1)
-    storei t2, TagOffset[t0, t1, 8]
-    storei t3, PayloadOffset[t0, t1, 8]
+    storei t2, JSEnvironmentRecord_variables + TagOffset[t0, t1, 8]
+    storei t3, JSEnvironmentRecord_variables + PayloadOffset[t0, t1, 8]
 end
 
 
@@ -2368,6 +2289,34 @@
     callSlowPath(_llint_slow_path_put_to_scope)
     dispatch(7)
 
+
+_llint_op_get_from_arguments:
+    traceExecution()
+    loadisFromInstruction(2, t0)
+    loadi PayloadOffset[cfr, t0, 8], t0
+    loadi 12[PC], t1
+    loadi DirectArguments_storage + TagOffset[t0, t1, 8], t2
+    loadi DirectArguments_storage + PayloadOffset[t0, t1, 8], t3
+    loadisFromInstruction(1, t1)
+    valueProfile(t2, t3, 16, t0)
+    storei t2, TagOffset[cfr, t1, 8]
+    storei t3, PayloadOffset[cfr, t1, 8]
+    dispatch(5)
+
+
+_llint_op_put_to_arguments:
+    traceExecution()
+    writeBarrierOnOperands(1, 3)
+    loadisFromInstruction(1, t0)
+    loadi PayloadOffset[cfr, t0, 8], t0
+    loadisFromInstruction(3, t1)
+    loadConstantOrVariable(t1, t2, t3)
+    loadi 8[PC], t1
+    storei t2, DirectArguments_storage + TagOffset[t0, t1, 8]
+    storei t3, DirectArguments_storage + PayloadOffset[t0, t1, 8]
+    dispatch(4)
+
+
 _llint_op_profile_type:
     traceExecution()
     loadp CodeBlock[cfr], t1
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
index dcb9883..de57062 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
@@ -609,7 +609,6 @@
 
 _llint_op_create_lexical_environment:
     traceExecution()
-    loadisFromInstruction(1, t0)
     callSlowPath(_llint_slow_path_create_lexical_environment)
     dispatch(3)
 
@@ -623,22 +622,6 @@
     dispatch(2)
 
 
-_llint_op_init_lazy_reg:
-    traceExecution()
-    loadisFromInstruction(1, t0)
-    storeq ValueEmpty, [cfr, t0, 8]
-    dispatch(2)
-
-
-_llint_op_create_arguments:
-    traceExecution()
-    loadisFromInstruction(1, t0)
-    bqneq [cfr, t0, 8], ValueEmpty, .opCreateArgumentsDone
-    callSlowPath(_slow_path_create_arguments)
-.opCreateArgumentsDone:
-    dispatch(3)
-
-
 _llint_op_create_this:
     traceExecution()
     loadisFromInstruction(2, t0)
@@ -1314,22 +1297,6 @@
     dispatch(9)
 
 
-_llint_op_get_arguments_length:
-    traceExecution()
-    loadisFromInstruction(2, t0)
-    loadisFromInstruction(1, t1)
-    btqnz [cfr, t0, 8], .opGetArgumentsLengthSlow
-    loadi ArgumentCount + PayloadOffset[cfr], t2
-    subi 1, t2
-    orq tagTypeNumber, t2
-    storeq t2, [cfr, t1, 8]
-    dispatch(4)
-
-.opGetArgumentsLengthSlow:
-    callSlowPath(_llint_slow_path_get_arguments_length)
-    dispatch(4)
-
-
 macro putById(getPropertyStorage)
     traceExecution()
     writeBarrierOnOperands(1, 3)
@@ -1476,30 +1443,6 @@
     dispatch(6)
 
 
-_llint_op_get_argument_by_val:
-    # FIXME: At some point we should array profile this. Right now it isn't necessary
-    # since the DFG will never turn a get_argument_by_val into a GetByVal.
-    traceExecution()
-    loadisFromInstruction(2, t0)
-    loadisFromInstruction(3, t1)
-    btqnz [cfr, t0, 8], .opGetArgumentByValSlow
-    loadConstantOrVariableInt32(t1, t2, .opGetArgumentByValSlow)
-    loadi ArgumentCount + PayloadOffset[cfr], t1
-    sxi2q t2, t2
-    subi 1, t1
-    biaeq t2, t1, .opGetArgumentByValSlow
-    loadisFromInstruction(1, t3)
-    loadpFromInstruction(6, t1)
-    loadq FirstArgumentOffset[cfr, t2, 8], t0
-    storeq t0, [cfr, t3, 8]
-    valueProfile(t0, 6, t1)
-    dispatch(7)
-
-.opGetArgumentByValSlow:
-    callSlowPath(_llint_slow_path_get_argument_by_val)
-    dispatch(7)
-
-
 macro contiguousPutByVal(storeCallback)
     biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], .outOfBounds
 .storeResult:
@@ -1781,17 +1724,6 @@
     dispatch(0)
 
 
-_llint_op_new_func:
-    traceExecution()
-    loadisFromInstruction(4, t2)
-    btiz t2, .opNewFuncUnchecked
-    loadisFromInstruction(1, t1)
-    btqnz [cfr, t1, 8], .opNewFuncDone
-.opNewFuncUnchecked:
-    callSlowPath(_llint_slow_path_new_func)
-.opNewFuncDone:
-    dispatch(5)
-
 macro arrayProfileForCall()
     loadisFromInstruction(4, t3)
     negp t3
@@ -1824,14 +1756,6 @@
     slowPathForCall(slowPath)
 end
 
-_llint_op_tear_off_arguments:
-    traceExecution()
-    loadisFromInstruction(1, t0)
-    btqz [cfr, t0, 8], .opTearOffArgumentsNotCreated
-    callSlowPath(_llint_slow_path_tear_off_arguments)
-.opTearOffArgumentsNotCreated:
-    dispatch(3)
-
 
 _llint_op_ret:
     traceExecution()
@@ -2080,9 +2004,8 @@
 end
 
 macro getClosureVar()
-    loadp JSEnvironmentRecord::m_registers[t0], t0
     loadisFromInstruction(6, t1)
-    loadq [t0, t1, 8], t0
+    loadq JSEnvironmentRecord_variables[t0, t1, 8], t0
     valueProfile(t0, 7, t1)
     loadisFromInstruction(1, t1)
     storeq t0, [cfr, t1, 8]
@@ -2154,9 +2077,8 @@
 macro putClosureVar()
     loadisFromInstruction(3, t1)
     loadConstantOrVariable(t1, t2)
-    loadp JSEnvironmentRecord::m_registers[t0], t0
     loadisFromInstruction(6, t1)
-    storeq t2, [t0, t1, 8]
+    storeq t2, JSEnvironmentRecord_variables[t0, t1, 8]
 end
 
 macro putLocalClosureVar()
@@ -2166,9 +2088,8 @@
     btpz t3, .noVariableWatchpointSet
     notifyWrite(t3, t2, t1, .pDynamic)
 .noVariableWatchpointSet:
-    loadp JSEnvironmentRecord::m_registers[t0], t0
     loadisFromInstruction(6, t1)
-    storeq t2, [t0, t1, 8]
+    storeq t2, JSEnvironmentRecord_variables[t0, t1, 8]
 end
 
 
@@ -2230,6 +2151,29 @@
     callSlowPath(_llint_slow_path_put_to_scope)
     dispatch(7)
 
+
+_llint_op_get_from_arguments:
+    traceExecution()
+    loadVariable(2, t0)
+    loadi 24[PB, PC, 8], t1
+    loadq DirectArguments_storage[t0, t1, 8], t0
+    valueProfile(t0, 4, t1)
+    loadisFromInstruction(1, t1)
+    storeq t0, [cfr, t1, 8]
+    dispatch(5)
+
+
+_llint_op_put_to_arguments:
+    traceExecution()
+    writeBarrierOnOperands(1, 3)
+    loadVariable(1, t0)
+    loadi 16[PB, PC, 8], t1
+    loadisFromInstruction(3, t3)
+    loadConstantOrVariable(t3, t2)
+    storeq t2, DirectArguments_storage[t0, t1, 8]
+    dispatch(4)
+
+
 _llint_op_profile_type:
     traceExecution()
     loadp CodeBlock[cfr], t1
diff --git a/Source/JavaScriptCore/parser/Nodes.h b/Source/JavaScriptCore/parser/Nodes.h
index 19bdbbf..3694120 100644
--- a/Source/JavaScriptCore/parser/Nodes.h
+++ b/Source/JavaScriptCore/parser/Nodes.h
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013, 2015 Apple Inc. All rights reserved.
  *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
  *  Copyright (C) 2007 Maks Orlovich
  *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
@@ -1470,7 +1470,8 @@
         bool hasCapturedVariables() const { return !!m_capturedVariables.size(); }
         size_t capturedVariableCount() const { return m_capturedVariables.size(); }
         const IdentifierSet& capturedVariables() const { return m_capturedVariables; }
-        bool captures(const Identifier& ident) { return m_capturedVariables.contains(ident.impl()); }
+        bool captures(StringImpl* uid) { return m_capturedVariables.contains(uid); }
+        bool captures(const Identifier& ident) { return captures(ident.impl()); }
 
         VarStack& varStack() { return m_varStack; }
         FunctionStack& functionStack() { return m_functionStack; }
diff --git a/Source/JavaScriptCore/runtime/Arguments.cpp b/Source/JavaScriptCore/runtime/Arguments.cpp
deleted file mode 100644
index 98548d2..0000000
--- a/Source/JavaScriptCore/runtime/Arguments.cpp
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
- *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2015 Apple Inc. All rights reserved.
- *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
- *  Copyright (C) 2007 Maks Orlovich
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Library General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Library General Public License for more details.
- *
- *  You should have received a copy of the GNU Library General Public License
- *  along with this library; see the file COPYING.LIB.  If not, write to
- *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- *  Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "Arguments.h"
-
-#include "CopyVisitorInlines.h"
-#include "JSArgumentsIterator.h"
-#include "JSFunction.h"
-#include "JSGlobalObject.h"
-#include "JSCInlines.h"
-#include "JSLexicalEnvironment.h"
-
-using namespace std;
-
-namespace JSC {
-
-STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(Arguments);
-
-const ClassInfo Arguments::s_info = { "Arguments", &Base::s_info, 0, CREATE_METHOD_TABLE(Arguments) };
-
-void Arguments::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    Arguments* thisObject = jsCast<Arguments*>(cell);
-
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    JSObject::visitChildren(thisObject, visitor);
-
-    if (thisObject->isTornOff())
-        visitor.appendValues(&thisObject->registerArray(), thisObject->m_numArguments);
-
-    if (thisObject->m_slowArgumentData) {
-        visitor.copyLater(thisObject, ArgumentsSlowArgumentDataCopyToken,
-            thisObject->m_slowArgumentData.get(), SlowArgumentData::sizeForNumArguments(thisObject->m_numArguments));
-    }
-    visitor.append(&thisObject->m_callee);
-    visitor.append(&thisObject->m_lexicalEnvironment);
-}
-
-void Arguments::copyBackingStore(JSCell* cell, CopyVisitor& visitor, CopyToken token)
-{
-    Arguments* thisObject = jsCast<Arguments*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    
-
-    switch (token) {
-    case ArgumentsSlowArgumentDataCopyToken: {
-        SlowArgumentData* slowArgumentData = thisObject->m_slowArgumentData.get();
-        if (!slowArgumentData)
-            return;
-
-        if (visitor.checkIfShouldCopy(slowArgumentData)) {
-            size_t bytes = SlowArgumentData::sizeForNumArguments(thisObject->m_numArguments);
-            SlowArgumentData* newSlowArgumentData = static_cast<SlowArgumentData*>(visitor.allocateNewSpace(bytes));
-            memcpy(newSlowArgumentData, slowArgumentData, bytes);
-            thisObject->m_slowArgumentData.setWithoutWriteBarrier(newSlowArgumentData);
-            visitor.didCopy(slowArgumentData, bytes);
-        }
-        return;
-    }
-
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
-    }
-}
-    
-static EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState*);
-
-void Arguments::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, unsigned offset, unsigned length)
-{
-    for (unsigned i = 0; i < length; ++i) {
-        if (JSValue value = tryGetArgument(i + offset))
-            exec->r(firstElementDest + i) = value;
-        else {
-            exec->r(firstElementDest + i) = get(exec, i + offset);
-            if (UNLIKELY(exec->vm().exception()))
-                return;
-        }
-    }
-}
-
-void Arguments::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
-{
-    if (UNLIKELY(m_overrodeLength)) {
-        unsigned length = get(exec, exec->propertyNames().length).toUInt32(exec); 
-        for (unsigned i = 0; i < length; i++) 
-            args.append(get(exec, i)); 
-        return;
-    }
-    uint32_t length = this->length(exec);
-    for (size_t i = 0; i < length; ++i) {
-        if (JSValue value = tryGetArgument(i))
-            args.append(value);
-        else
-            args.append(get(exec, i));
-    }
-}
-
-bool Arguments::getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned i, PropertySlot& slot)
-{
-    Arguments* thisObject = jsCast<Arguments*>(object);
-    if (JSValue value = thisObject->tryGetArgument(i)) {
-        slot.setValue(thisObject, None, value);
-        return true;
-    }
-
-    return JSObject::getOwnPropertySlot(thisObject, exec, Identifier::from(exec, i), slot);
-}
-    
-void Arguments::createStrictModeCallerIfNecessary(ExecState* exec)
-{
-    if (m_overrodeCaller)
-        return;
-
-    VM& vm = exec->vm();
-    m_overrodeCaller = true;
-    PropertyDescriptor descriptor;
-    descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(vm), DontEnum | DontDelete | Accessor);
-    methodTable(exec->vm())->defineOwnProperty(this, exec, vm.propertyNames->caller, descriptor, false);
-}
-
-void Arguments::createStrictModeCalleeIfNecessary(ExecState* exec)
-{
-    if (m_overrodeCallee)
-        return;
-
-    VM& vm = exec->vm();
-    m_overrodeCallee = true;
-    PropertyDescriptor descriptor;
-    descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(vm), DontEnum | DontDelete | Accessor);
-    methodTable(exec->vm())->defineOwnProperty(this, exec, vm.propertyNames->callee, descriptor, false);
-}
-
-bool Arguments::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
-{
-    Arguments* thisObject = jsCast<Arguments*>(object);
-    unsigned i = propertyName.asIndex();
-    if (JSValue value = thisObject->tryGetArgument(i)) {
-        RELEASE_ASSERT(i < PropertyName::NotAnIndex);
-        slot.setValue(thisObject, None, value);
-        return true;
-    }
-
-    if (propertyName == exec->propertyNames().length && LIKELY(!thisObject->m_overrodeLength)) {
-        slot.setValue(thisObject, DontEnum, jsNumber(thisObject->m_numArguments));
-        return true;
-    }
-
-    if (propertyName == exec->propertyNames().callee && LIKELY(!thisObject->m_overrodeCallee)) {
-        if (!thisObject->m_isStrictMode) {
-            slot.setValue(thisObject, DontEnum, thisObject->m_callee.get());
-            return true;
-        }
-        thisObject->createStrictModeCalleeIfNecessary(exec);
-    }
-
-    if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode)
-        thisObject->createStrictModeCallerIfNecessary(exec);
-
-    if (JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot))
-        return true;
-    if (propertyName == exec->propertyNames().iteratorPrivateName) {
-        VM& vm = exec->vm();
-        JSGlobalObject* globalObject = exec->lexicalGlobalObject();
-        thisObject->JSC_NATIVE_FUNCTION(exec->propertyNames().iteratorPrivateName, argumentsFuncIterator, DontEnum, 0);
-        if (JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot))
-            return true;
-    }
-    return false;
-}
-
-void Arguments::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
-{
-    Arguments* thisObject = jsCast<Arguments*>(object);
-    for (unsigned i = 0; i < thisObject->m_numArguments; ++i) {
-        if (!thisObject->isArgument(i))
-            continue;
-        propertyNames.add(Identifier::from(exec, i));
-    }
-    if (shouldIncludeDontEnumProperties(mode)) {
-        propertyNames.add(exec->propertyNames().callee);
-        propertyNames.add(exec->propertyNames().length);
-    }
-    JSObject::getOwnPropertyNames(thisObject, exec, propertyNames, mode);
-}
-
-void Arguments::putByIndex(JSCell* cell, ExecState* exec, unsigned i, JSValue value, bool shouldThrow)
-{
-    Arguments* thisObject = jsCast<Arguments*>(cell);
-    if (thisObject->trySetArgument(exec->vm(), i, value))
-        return;
-
-    PutPropertySlot slot(thisObject, shouldThrow);
-    JSObject::put(thisObject, exec, Identifier::from(exec, i), value, slot);
-}
-
-void Arguments::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
-{
-    Arguments* thisObject = jsCast<Arguments*>(cell);
-    unsigned i = propertyName.asIndex();
-    if (thisObject->trySetArgument(exec->vm(), i, value))
-        return;
-
-    if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) {
-        thisObject->m_overrodeLength = true;
-        thisObject->putDirect(exec->vm(), propertyName, value, DontEnum);
-        return;
-    }
-
-    if (propertyName == exec->propertyNames().callee && !thisObject->m_overrodeCallee) {
-        if (!thisObject->m_isStrictMode) {
-            thisObject->m_overrodeCallee = true;
-            thisObject->putDirect(exec->vm(), propertyName, value, DontEnum);
-            return;
-        }
-        thisObject->createStrictModeCalleeIfNecessary(exec);
-    }
-
-    if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode)
-        thisObject->createStrictModeCallerIfNecessary(exec);
-
-    JSObject::put(thisObject, exec, propertyName, value, slot);
-}
-
-bool Arguments::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i) 
-{
-    Arguments* thisObject = jsCast<Arguments*>(cell);
-    if (i < thisObject->m_numArguments) {
-        if (!Base::deletePropertyByIndex(cell, exec, i))
-            return false;
-        if (thisObject->tryDeleteArgument(exec->vm(), i))
-            return true;
-    }
-    return JSObject::deletePropertyByIndex(thisObject, exec, i);
-}
-
-bool Arguments::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName) 
-{
-    if (exec->vm().isInDefineOwnProperty())
-        return Base::deleteProperty(cell, exec, propertyName);
-
-    Arguments* thisObject = jsCast<Arguments*>(cell);
-    unsigned i = propertyName.asIndex();
-    if (i < thisObject->m_numArguments) {
-        RELEASE_ASSERT(i < PropertyName::NotAnIndex);
-        if (!Base::deleteProperty(cell, exec, propertyName))
-            return false;
-        if (thisObject->tryDeleteArgument(exec->vm(), i))
-            return true;
-    }
-
-    if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) {
-        thisObject->m_overrodeLength = true;
-        return true;
-    }
-
-    if (propertyName == exec->propertyNames().callee && !thisObject->m_overrodeCallee) {
-        if (!thisObject->m_isStrictMode) {
-            thisObject->m_overrodeCallee = true;
-            return true;
-        }
-        thisObject->createStrictModeCalleeIfNecessary(exec);
-    }
-    
-    if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode)
-        thisObject->createStrictModeCallerIfNecessary(exec);
-
-    return JSObject::deleteProperty(thisObject, exec, propertyName);
-}
-
-bool Arguments::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool shouldThrow)
-{
-    Arguments* thisObject = jsCast<Arguments*>(object);
-    unsigned i = propertyName.asIndex();
-    if (i < thisObject->m_numArguments) {
-        RELEASE_ASSERT(i < PropertyName::NotAnIndex);
-        
-        if (thisObject->isArgument(i)) {
-            if (!descriptor.isAccessorDescriptor()) {
-                // If the property is not deleted and we are using a non-accessor descriptor, then
-                // make sure that the aliased argument sees the value.
-                if (descriptor.value())
-                    thisObject->trySetArgument(exec->vm(), i, descriptor.value());
-            
-                // If the property is not deleted and we are using a non-accessor, writable
-                // descriptor, then we are done. The argument continues to be aliased. Note that we
-                // ignore the request to change enumerability. We appear to have always done so, in
-                // cases where the argument was still aliased.
-                // FIXME: https://bugs.webkit.org/show_bug.cgi?id=141952
-                if (descriptor.writable())
-                    return true;
-            }
-            
-            // If the property is a non-deleted argument, then move it into the base object and then
-            // delete it.
-            JSValue value = thisObject->tryGetArgument(i);
-            ASSERT(value);
-            object->putDirectMayBeIndex(exec, propertyName, value);
-            thisObject->tryDeleteArgument(exec->vm(), i);
-        }
-        
-        // Now just let the normal object machinery do its thing.
-        return Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow);
-    }
-
-    if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) {
-        thisObject->putDirect(exec->vm(), propertyName, jsNumber(thisObject->m_numArguments), DontEnum);
-        thisObject->m_overrodeLength = true;
-    } else if (propertyName == exec->propertyNames().callee && !thisObject->m_overrodeCallee) {
-        thisObject->putDirect(exec->vm(), propertyName, thisObject->m_callee.get(), DontEnum);
-        thisObject->m_overrodeCallee = true;
-    } else if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode)
-        thisObject->createStrictModeCallerIfNecessary(exec);
-
-    return Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow);
-}
-
-void Arguments::tearOff(CallFrame* callFrame)
-{
-    if (isTornOff())
-        return;
-
-    if (!m_numArguments)
-        return;
-
-    // Must be called for the same call frame from which it was created.
-    ASSERT(bitwise_cast<WriteBarrier<Unknown>*>(callFrame) == m_registers);
-
-    m_registers = &registerArray() - CallFrame::offsetFor(1) - 1;
-
-    for (size_t i = 0; i < m_numArguments; ++i) {
-        if (m_slowArgumentData && m_slowArgumentData->slowArguments()[i].status == SlowArgument::Captured) {
-            m_registers[CallFrame::argumentOffset(i)].setUndefined();
-            continue;
-        }
-        trySetArgument(callFrame->vm(), i, callFrame->argumentAfterCapture(i));
-    }
-}
-
-void Arguments::tearOff(CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
-{
-    RELEASE_ASSERT(!inlineCallFrame->baselineCodeBlock()->needsActivation());
-    if (isTornOff())
-        return;
-    
-    if (!m_numArguments)
-        return;
-
-    m_registers = &registerArray() - CallFrame::offsetFor(1) - 1;
-
-    for (size_t i = 0; i < m_numArguments; ++i) {
-        ValueRecovery& recovery = inlineCallFrame->arguments[i + 1];
-        trySetArgument(callFrame->vm(), i, recovery.recover(callFrame));
-    }
-}
-    
-void Arguments::tearOffForCloning(CallFrame* callFrame)
-{
-    ASSERT(!isTornOff());
-    
-    if (!m_numArguments)
-        return;
-    
-    // Must be called for the same call frame from which it was created.
-    ASSERT(bitwise_cast<WriteBarrier<Unknown>*>(callFrame) == m_registers);
-    
-    m_registers = &registerArray() - CallFrame::offsetFor(1) - 1;
-    
-    ASSERT(!m_slowArgumentData);
-    for (size_t i = 0; i < m_numArguments; ++i)
-        m_registers[CallFrame::argumentOffset(i)].set(callFrame->vm(), this, callFrame->argument(i));
-}
-    
-void Arguments::tearOffForCloning(CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
-{
-    RELEASE_ASSERT(!inlineCallFrame->baselineCodeBlock()->needsActivation());
-    ASSERT(!isTornOff());
-    
-    if (!m_numArguments)
-        return;
-    
-    m_registers = &registerArray() - CallFrame::offsetFor(1) - 1;
-    
-    ASSERT(!m_slowArgumentData);
-    for (size_t i = 0; i < m_numArguments; ++i) {
-        ValueRecovery& recovery = inlineCallFrame->arguments[i + 1];
-        m_registers[CallFrame::argumentOffset(i)].set(callFrame->vm(), this, recovery.recover(callFrame));
-    }
-}
-
-EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState* exec)
-{
-    JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
-    Arguments* arguments = jsDynamicCast<Arguments*>(thisObj);
-    if (!arguments)
-        return JSValue::encode(throwTypeError(exec, ASCIILiteral("Attempted to use Arguments iterator on non-Arguments object")));
-    return JSValue::encode(JSArgumentsIterator::create(exec->vm(), exec->callee()->globalObject()->argumentsIteratorStructure(), arguments));
-}
-
-
-} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/Arguments.h b/Source/JavaScriptCore/runtime/Arguments.h
deleted file mode 100644
index 87cf721..0000000
--- a/Source/JavaScriptCore/runtime/Arguments.h
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- *  Copyright (C) 2003, 2006, 2007, 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
- *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
- *  Copyright (C) 2007 Maks Orlovich
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Library General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Library General Public License for more details.
- *
- *  You should have received a copy of the GNU Library General Public License
- *  along with this library; see the file COPYING.LIB.  If not, write to
- *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- *  Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef Arguments_h
-#define Arguments_h
-
-#include "CodeOrigin.h"
-#include "JSFunction.h"
-#include "JSGlobalObject.h"
-#include "JSLexicalEnvironment.h"
-#include "Interpreter.h"
-#include "ObjectConstructor.h"
-#include "WriteBarrierInlines.h"
-#include <wtf/StdLibExtras.h>
-
-namespace JSC {
-
-enum ArgumentsMode {
-    NormalArgumentsCreationMode,
-    ClonedArgumentsCreationMode,
-    FakeArgumentValuesCreationMode
-};
-
-class Arguments : public JSNonFinalObject {
-    friend class JIT;
-    friend class JSArgumentsIterator;
-public:
-    typedef JSNonFinalObject Base;
-
-    static Arguments* create(VM& vm, CallFrame* callFrame, JSLexicalEnvironment* lexicalEnvironment, ArgumentsMode mode = NormalArgumentsCreationMode)
-    {
-        Arguments* arguments = new (NotNull, allocateCell<Arguments>(vm.heap, offsetOfInlineRegisterArray() + registerArraySizeInBytes(callFrame))) Arguments(callFrame);
-        arguments->finishCreation(callFrame, lexicalEnvironment, mode);
-        return arguments;
-    }
-        
-    static Arguments* create(VM& vm, CallFrame* callFrame, InlineCallFrame* inlineCallFrame, ArgumentsMode mode = NormalArgumentsCreationMode)
-    {
-        Arguments* arguments = new (NotNull, allocateCell<Arguments>(vm.heap, offsetOfInlineRegisterArray() + registerArraySizeInBytes(callFrame, inlineCallFrame))) Arguments(callFrame);
-        arguments->finishCreation(callFrame, inlineCallFrame, mode);
-        return arguments;
-    }
-
-    enum { MaxArguments = 0x10000 };
-
-private:
-    enum NoParametersType { NoParameters };
-        
-    Arguments(CallFrame*);
-    Arguments(CallFrame*, NoParametersType);
-        
-public:
-    DECLARE_INFO;
-
-    static void visitChildren(JSCell*, SlotVisitor&);
-    static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken);
-
-    void fillArgList(ExecState*, MarkedArgumentBuffer&);
-
-    uint32_t length(ExecState* exec) const 
-    {
-        if (UNLIKELY(m_overrodeLength))
-            return get(exec, exec->propertyNames().length).toUInt32(exec);
-        return m_numArguments; 
-    }
-        
-    void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
-    void tearOff(CallFrame*);
-    void tearOff(CallFrame*, InlineCallFrame*);
-    void tearOffForCloning(CallFrame*);
-    void tearOffForCloning(CallFrame*, InlineCallFrame*);
-    bool isTornOff() const { return m_registers == (&registerArray() - CallFrame::offsetFor(1) - 1); }
-
-    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 
-    { 
-        return Structure::create(vm, globalObject, prototype, TypeInfo(ArgumentsType, StructureFlags), info()); 
-    }
-    
-    static ptrdiff_t offsetOfActivation() { return OBJECT_OFFSETOF(Arguments, m_lexicalEnvironment); }
-    static ptrdiff_t offsetOfNumArguments() { return OBJECT_OFFSETOF(Arguments, m_numArguments); }
-    static ptrdiff_t offsetOfOverrodeLength() { return OBJECT_OFFSETOF(Arguments, m_overrodeLength); }
-    static ptrdiff_t offsetOfIsStrictMode() { return OBJECT_OFFSETOF(Arguments, m_isStrictMode); }
-    static ptrdiff_t offsetOfRegisters() { return OBJECT_OFFSETOF(Arguments, m_registers); }
-    static ptrdiff_t offsetOfInlineRegisterArray() { return WTF::roundUpToMultipleOf<8>(sizeof(Arguments)); }
-    static ptrdiff_t offsetOfSlowArgumentData() { return OBJECT_OFFSETOF(Arguments, m_slowArgumentData); }
-    static ptrdiff_t offsetOfCallee() { return OBJECT_OFFSETOF(Arguments, m_callee); }
-    
-protected:
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSObject::StructureFlags;
-
-    void finishCreation(CallFrame*, JSLexicalEnvironment*, ArgumentsMode);
-    void finishCreation(CallFrame*, InlineCallFrame*, ArgumentsMode);
-
-private:
-    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-    static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
-    static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
-    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
-    static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
-    static bool deleteProperty(JSCell*, ExecState*, PropertyName);
-    static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
-    static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
-    void createStrictModeCallerIfNecessary(ExecState*);
-    void createStrictModeCalleeIfNecessary(ExecState*);
-
-    static size_t registerArraySizeInBytes(CallFrame* callFrame) { return sizeof(WriteBarrier<Unknown>) * callFrame->argumentCount(); }
-    static size_t registerArraySizeInBytes(CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
-    {
-        unsigned argumentCountIncludingThis;
-        if (inlineCallFrame->argumentCountRegister.isValid())
-            argumentCountIncludingThis = callFrame->r(inlineCallFrame->argumentCountRegister.offset()).unboxedInt32();
-        else
-            argumentCountIncludingThis = inlineCallFrame->arguments.size();
-        return sizeof(WriteBarrier<Unknown>) * (argumentCountIncludingThis - 1);
-    }
-    bool isArgument(size_t);
-    bool trySetArgument(VM&, size_t argument, JSValue);
-    JSValue tryGetArgument(size_t argument);
-    bool isDeletedArgument(size_t);
-    bool tryDeleteArgument(VM&, size_t);
-    WriteBarrierBase<Unknown>& argument(size_t);
-    void allocateSlowArguments(VM&);
-
-    void init(CallFrame*);
-
-    WriteBarrier<JSLexicalEnvironment> m_lexicalEnvironment;
-
-    unsigned m_numArguments;
-
-    // We make these full byte booleans to make them easy to test from the JIT,
-    // and because even if they were single-bit booleans we still wouldn't save
-    // any space.
-    bool m_overrodeLength; 
-    bool m_overrodeCallee;
-    bool m_overrodeCaller;
-    bool m_isStrictMode;
-
-    WriteBarrierBase<Unknown>* m_registers;
-    WriteBarrier<Unknown>& registerArray() { return *reinterpret_cast<WriteBarrier<Unknown>*>(reinterpret_cast<char*>(this) + offsetOfInlineRegisterArray()); }
-    const WriteBarrier<Unknown>& registerArray() const { return *reinterpret_cast<const WriteBarrier<Unknown>*>(reinterpret_cast<const char*>(this) + offsetOfInlineRegisterArray()); }
-
-public:
-    struct SlowArgumentData {
-    public:
-        SlowArgumentData()
-            : m_bytecodeToMachineCaptureOffset(0)
-        {
-        }
-
-        SlowArgument* slowArguments()
-        {
-            return reinterpret_cast<SlowArgument*>(WTF::roundUpToMultipleOf<8>(reinterpret_cast<size_t>(this + 1)));
-        }
-
-        int bytecodeToMachineCaptureOffset() const { return m_bytecodeToMachineCaptureOffset; }
-        void setBytecodeToMachineCaptureOffset(int newOffset) { m_bytecodeToMachineCaptureOffset = newOffset; }
-
-        static size_t sizeForNumArguments(unsigned numArguments)
-        {
-            return WTF::roundUpToMultipleOf<8>(sizeof(SlowArgumentData)) + sizeof(SlowArgument) * numArguments;
-        }
-
-    private:
-        int m_bytecodeToMachineCaptureOffset; // Add this if you have a bytecode offset into captured registers and you want the machine offset instead. Subtract if you want to do the opposite. 
-    };
-    
-private:
-    CopyWriteBarrier<SlowArgumentData> m_slowArgumentData;
-
-    WriteBarrier<JSFunction> m_callee;
-};
-
-Arguments* asArguments(JSValue);
-
-inline Arguments* asArguments(JSValue value)
-{
-    ASSERT(asObject(value)->inherits(Arguments::info()));
-    return static_cast<Arguments*>(asObject(value));
-}
-
-inline Arguments::Arguments(CallFrame* callFrame)
-    : Base(callFrame->vm(), callFrame->lexicalGlobalObject()->argumentsStructure())
-{
-}
-
-inline Arguments::Arguments(CallFrame* callFrame, NoParametersType)
-    : Base(callFrame->vm(), callFrame->lexicalGlobalObject()->argumentsStructure())
-{
-}
-
-inline void Arguments::allocateSlowArguments(VM& vm)
-{
-    if (!!m_slowArgumentData)
-        return;
-
-    void* backingStore;
-    if (!vm.heap.tryAllocateStorage(this, SlowArgumentData::sizeForNumArguments(m_numArguments), &backingStore))
-        RELEASE_ASSERT_NOT_REACHED();
-    m_slowArgumentData.set(vm, this, static_cast<SlowArgumentData*>(backingStore));
-
-    for (size_t i = 0; i < m_numArguments; ++i) {
-        ASSERT(m_slowArgumentData->slowArguments()[i].status == SlowArgument::Normal);
-        m_slowArgumentData->slowArguments()[i].index = CallFrame::argumentOffset(i);
-    }
-}
-
-inline bool Arguments::tryDeleteArgument(VM& vm, size_t argument)
-{
-    if (!isArgument(argument))
-        return false;
-    allocateSlowArguments(vm);
-    m_slowArgumentData->slowArguments()[argument].status = SlowArgument::Deleted;
-    return true;
-}
-
-inline bool Arguments::trySetArgument(VM& vm, size_t argument, JSValue value)
-{
-    if (!isArgument(argument))
-        return false;
-    this->argument(argument).set(vm, this, value);
-    return true;
-}
-
-inline JSValue Arguments::tryGetArgument(size_t argument)
-{
-    if (!isArgument(argument))
-        return JSValue();
-    return this->argument(argument).get();
-}
-
-inline bool Arguments::isDeletedArgument(size_t argument)
-{
-    if (argument >= m_numArguments)
-        return false;
-    if (!m_slowArgumentData)
-        return false;
-    if (m_slowArgumentData->slowArguments()[argument].status != SlowArgument::Deleted)
-        return false;
-    return true;
-}
-
-inline bool Arguments::isArgument(size_t argument)
-{
-    if (argument >= m_numArguments)
-        return false;
-    if (m_slowArgumentData && m_slowArgumentData->slowArguments()[argument].status == SlowArgument::Deleted)
-        return false;
-    return true;
-}
-
-inline WriteBarrierBase<Unknown>& Arguments::argument(size_t argument)
-{
-    ASSERT(isArgument(argument));
-    if (!m_slowArgumentData)
-        return m_registers[CallFrame::argumentOffset(argument)];
-
-    int index = m_slowArgumentData->slowArguments()[argument].index;
-    if (m_slowArgumentData->slowArguments()[argument].status != SlowArgument::Captured)
-        return m_registers[index];
-
-    RELEASE_ASSERT(m_lexicalEnvironment);
-    return m_lexicalEnvironment->registerAt(index - m_slowArgumentData->bytecodeToMachineCaptureOffset());
-}
-
-inline void Arguments::finishCreation(CallFrame* callFrame, JSLexicalEnvironment* lexicalEnvironment, ArgumentsMode mode)
-{
-    Base::finishCreation(callFrame->vm());
-    ASSERT(inherits(info()));
-
-    JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
-    m_callee.set(callFrame->vm(), this, callee);
-    m_overrodeLength = false;
-    m_overrodeCallee = false;
-    m_overrodeCaller = false;
-    m_isStrictMode = callFrame->codeBlock()->isStrictMode();
-
-    switch (mode) {
-    case NormalArgumentsCreationMode: {
-        m_numArguments = callFrame->argumentCount();
-        m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers());
-
-        CodeBlock* codeBlock = callFrame->codeBlock();
-        if (codeBlock->hasSlowArguments()) {
-            SymbolTable* symbolTable = codeBlock->symbolTable();
-            const SlowArgument* slowArguments = codeBlock->machineSlowArguments();
-            allocateSlowArguments(callFrame->vm());
-            size_t count = std::min<unsigned>(m_numArguments, symbolTable->parameterCount());
-            for (size_t i = 0; i < count; ++i)
-                m_slowArgumentData->slowArguments()[i] = slowArguments[i];
-            m_slowArgumentData->setBytecodeToMachineCaptureOffset(
-                codeBlock->framePointerOffsetToGetActivationRegisters());
-        }
-        if (codeBlock->needsActivation()) {
-            RELEASE_ASSERT(lexicalEnvironment && lexicalEnvironment == callFrame->lexicalEnvironment());
-            m_lexicalEnvironment.set(callFrame->vm(), this, lexicalEnvironment);
-        }
-        // The bytecode generator omits op_tear_off_lexical_environment in cases of no
-        // declared parameters, so we need to tear off immediately.
-        if (m_isStrictMode || !callee->jsExecutable()->parameterCount())
-            tearOff(callFrame);
-        break;
-    }
-
-    case ClonedArgumentsCreationMode: {
-        m_numArguments = callFrame->argumentCount();
-        m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers());
-        tearOffForCloning(callFrame);
-        break;
-    }
-
-    case FakeArgumentValuesCreationMode: {
-        m_numArguments = 0;
-        m_registers = nullptr;
-        tearOff(callFrame);
-        break;
-    }
-    }
-}
-
-inline void Arguments::finishCreation(CallFrame* callFrame, InlineCallFrame* inlineCallFrame, ArgumentsMode mode)
-{
-    Base::finishCreation(callFrame->vm());
-    ASSERT(inherits(info()));
-
-    JSFunction* callee = inlineCallFrame->calleeForCallFrame(callFrame);
-    m_callee.set(callFrame->vm(), this, callee);
-    m_overrodeLength = false;
-    m_overrodeCallee = false;
-    m_overrodeCaller = false;
-    m_isStrictMode = jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->isStrictMode();
-    
-    if (inlineCallFrame->argumentCountRegister.isValid())
-        m_numArguments = callFrame->r(inlineCallFrame->argumentCountRegister.offset()).unboxedInt32();
-    else
-        m_numArguments = inlineCallFrame->arguments.size();
-    m_numArguments--;
-    
-    switch (mode) {
-    case NormalArgumentsCreationMode: {
-        if (m_numArguments) {
-            int offsetForArgumentOne = inlineCallFrame->arguments[1].virtualRegister().offset();
-            m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()) + offsetForArgumentOne - virtualRegisterForArgument(1).offset();
-        } else
-            m_registers = 0;
-        
-        ASSERT(!jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->symbolTable(inlineCallFrame->specializationKind())->slowArguments());
-        
-        // The bytecode generator omits op_tear_off_lexical_environment in cases of no
-        // declared parameters, so we need to tear off immediately.
-        if (m_isStrictMode || !callee->jsExecutable()->parameterCount())
-            tearOff(callFrame, inlineCallFrame);
-        break;
-    }
-        
-    case ClonedArgumentsCreationMode: {
-        if (m_numArguments) {
-            int offsetForArgumentOne = inlineCallFrame->arguments[1].virtualRegister().offset();
-            m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()) + offsetForArgumentOne - virtualRegisterForArgument(1).offset();
-        } else
-            m_registers = 0;
-        
-        ASSERT(!jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->symbolTable(inlineCallFrame->specializationKind())->slowArguments());
-        
-        tearOffForCloning(callFrame, inlineCallFrame);
-        break;
-    }
-        
-    case FakeArgumentValuesCreationMode: {
-        m_numArguments = 0;
-        m_registers = nullptr;
-        tearOff(callFrame);
-        break;
-    } }
-}
-
-} // namespace JSC
-
-#endif // Arguments_h
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h b/Source/JavaScriptCore/runtime/ArgumentsMode.h
similarity index 71%
copy from Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h
copy to Source/JavaScriptCore/runtime/ArgumentsMode.h
index 25098ca..67cd334 100644
--- a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h
+++ b/Source/JavaScriptCore/runtime/ArgumentsMode.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,25 +23,17 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#ifndef DFGArgumentsSimplificationPhase_h
-#define DFGArgumentsSimplificationPhase_h
+#ifndef ArgumentsMode_h
+#define ArgumentsMode_h
 
-#if ENABLE(DFG_JIT)
+namespace JSC {
 
-namespace JSC { namespace DFG {
+enum class ArgumentsMode {
+    Cloned,
+    FakeValues
+};
 
-class Graph;
+} // namespace JSC
 
-// Simplifies reflective uses of the Arguments object:
-//
-// Inlined arguments.length -> constant
-// Inlined arguments[constant] -> GetLocalUnlinked
-
-bool performArgumentsSimplification(Graph&);
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // DFGArgumentsSimplificationPhase_h
+#endif // ArgumentsMode_h
 
diff --git a/Source/JavaScriptCore/runtime/ClonedArguments.cpp b/Source/JavaScriptCore/runtime/ClonedArguments.cpp
new file mode 100644
index 0000000..17798a2
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/ClonedArguments.cpp
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "ClonedArguments.h"
+
+#include "GetterSetter.h"
+#include "JSArgumentsIterator.h"
+#include "JSCInlines.h"
+
+namespace JSC {
+
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ClonedArguments);
+
+const ClassInfo ClonedArguments::s_info = { "Arguments", &Base::s_info, 0, CREATE_METHOD_TABLE(ClonedArguments) };
+
+ClonedArguments::ClonedArguments(VM& vm, Structure* structure)
+    : Base(vm, structure, nullptr)
+{
+}
+
+ClonedArguments* ClonedArguments::createEmpty(
+    VM& vm, Structure* structure, JSFunction* callee)
+{
+    ClonedArguments* result =
+        new (NotNull, allocateCell<ClonedArguments>(vm.heap))
+        ClonedArguments(vm, structure);
+    result->finishCreation(vm);
+    result->m_callee.set(vm, result, callee);
+    return result;
+}
+
+ClonedArguments* ClonedArguments::createEmpty(ExecState* exec, JSFunction* callee)
+{
+    // NB. Some clients might expect that the global object of of this object is the global object
+    // of the callee. We don't do this for now, but maybe we should.
+    return createEmpty(
+        exec->vm(), exec->lexicalGlobalObject()->outOfBandArgumentsStructure(), callee);
+}
+
+ClonedArguments* ClonedArguments::createWithInlineFrame(ExecState* myFrame, ExecState* targetFrame, InlineCallFrame* inlineCallFrame, ArgumentsMode mode)
+{
+    VM& vm = myFrame->vm();
+    
+    JSFunction* callee;
+    
+    if (inlineCallFrame)
+        callee = jsCast<JSFunction*>(inlineCallFrame->calleeRecovery.recover(targetFrame));
+    else
+        callee = jsCast<JSFunction*>(targetFrame->callee());
+
+    ClonedArguments* result = createEmpty(myFrame, callee);
+    
+    unsigned length;
+    switch (mode) {
+    case ArgumentsMode::Cloned: {
+        if (inlineCallFrame) {
+            if (inlineCallFrame->argumentCountRegister.isValid())
+                length = targetFrame->r(inlineCallFrame->argumentCountRegister).unboxedInt32();
+            else
+                length = inlineCallFrame->arguments.size();
+            length--;
+            
+            for (unsigned i = length; i--;)
+                result->putDirectIndex(myFrame, i, inlineCallFrame->arguments[i + 1].recover(targetFrame));
+        } else {
+            length = targetFrame->argumentCount();
+            
+            for (unsigned i = length; i--;)
+                result->putDirectIndex(myFrame, i, targetFrame->uncheckedArgument(i));
+        }
+        break;
+    }
+        
+    case ArgumentsMode::FakeValues: {
+        length = 0;
+        break;
+    } }
+    
+    result->putDirect(vm, vm.propertyNames->length, jsNumber(length));
+    
+    return result;
+}
+
+ClonedArguments* ClonedArguments::createWithMachineFrame(ExecState* myFrame, ExecState* targetFrame, ArgumentsMode mode)
+{
+    return createWithInlineFrame(myFrame, targetFrame, nullptr, mode);
+}
+
+ClonedArguments* ClonedArguments::createByCopyingFrom(
+    ExecState* exec, Structure* structure, Register* argumentStart, unsigned length,
+    JSFunction* callee)
+{
+    VM& vm = exec->vm();
+    ClonedArguments* result = createEmpty(vm, structure, callee);
+    
+    for (unsigned i = length; i--;)
+        result->putDirectIndex(exec, i, argumentStart[i].jsValue());
+    
+    result->putDirect(vm, vm.propertyNames->length, jsNumber(length));
+    return result;
+}
+
+Structure* ClonedArguments::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+    return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+}
+
+bool ClonedArguments::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName ident, PropertySlot& slot)
+{
+    ClonedArguments* thisObject = jsCast<ClonedArguments*>(object);
+    VM& vm = exec->vm();
+    
+    if (ident == vm.propertyNames->caller
+        || ident == vm.propertyNames->callee)
+        thisObject->materializeSpecialsIfNecessary(exec);
+    
+    if (Base::getOwnPropertySlot(thisObject, exec, ident, slot))
+        return true;
+    
+    if (ident == vm.propertyNames->iteratorPrivateName) {
+        JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+        thisObject->JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, argumentsFuncIterator, DontEnum, 0);
+        if (JSObject::getOwnPropertySlot(thisObject, exec, ident, slot))
+            return true;
+    }
+    
+    return false;
+}
+
+void ClonedArguments::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& array, EnumerationMode mode)
+{
+    ClonedArguments* thisObject = jsCast<ClonedArguments*>(object);
+    thisObject->materializeSpecialsIfNecessary(exec);
+    Base::getOwnPropertyNames(thisObject, exec, array, mode);
+}
+
+void ClonedArguments::put(JSCell* cell, ExecState* exec, PropertyName ident, JSValue value, PutPropertySlot& slot)
+{
+    ClonedArguments* thisObject = jsCast<ClonedArguments*>(cell);
+    VM& vm = exec->vm();
+    
+    if (ident == vm.propertyNames->callee
+        || ident == vm.propertyNames->caller) {
+        thisObject->materializeSpecialsIfNecessary(exec);
+        PutPropertySlot dummy = slot; // Shadow the given PutPropertySlot to prevent caching.
+        Base::put(thisObject, exec, ident, value, dummy);
+        return;
+    }
+    
+    Base::put(thisObject, exec, ident, value, slot);
+}
+
+bool ClonedArguments::deleteProperty(JSCell* cell, ExecState* exec, PropertyName ident)
+{
+    ClonedArguments* thisObject = jsCast<ClonedArguments*>(cell);
+    VM& vm = exec->vm();
+    
+    if (ident == vm.propertyNames->callee
+        || ident == vm.propertyNames->caller)
+        thisObject->materializeSpecialsIfNecessary(exec);
+    
+    return Base::deleteProperty(thisObject, exec, ident);
+}
+
+bool ClonedArguments::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName ident, const PropertyDescriptor& descriptor, bool shouldThrow)
+{
+    ClonedArguments* thisObject = jsCast<ClonedArguments*>(object);
+    VM& vm = exec->vm();
+    
+    if (ident == vm.propertyNames->callee
+        || ident == vm.propertyNames->caller)
+        thisObject->materializeSpecialsIfNecessary(exec);
+    
+    return Base::defineOwnProperty(object, exec, ident, descriptor, shouldThrow);
+}
+
+void ClonedArguments::materializeSpecials(ExecState* exec)
+{
+    RELEASE_ASSERT(!specialsMaterialized());
+    VM& vm = exec->vm();
+    
+    FunctionExecutable* executable = jsCast<FunctionExecutable*>(m_callee->executable());
+    bool isStrictMode = executable->isStrictMode();
+    
+    if (isStrictMode) {
+        putDirectAccessor(exec, vm.propertyNames->callee, globalObject()->throwTypeErrorGetterSetter(vm), DontDelete | DontEnum | Accessor);
+        putDirectAccessor(exec, vm.propertyNames->caller, globalObject()->throwTypeErrorGetterSetter(vm), DontDelete | DontEnum | Accessor);
+    } else
+        putDirect(vm, vm.propertyNames->callee, JSValue(m_callee.get()));
+    
+    m_callee.clear();
+}
+
+void ClonedArguments::materializeSpecialsIfNecessary(ExecState* exec)
+{
+    if (!specialsMaterialized())
+        materializeSpecials(exec);
+}
+
+} // namespace JSC
+
diff --git a/Source/JavaScriptCore/runtime/ClonedArguments.h b/Source/JavaScriptCore/runtime/ClonedArguments.h
new file mode 100644
index 0000000..c506948
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/ClonedArguments.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef ClonedArguments_h
+#define ClonedArguments_h
+
+#include "ArgumentsMode.h"
+#include "JSObject.h"
+
+namespace JSC {
+
+// This is an Arguments-class object that we create when you do function.arguments, or you say
+// "arguments" inside a function in strict mode. It behaves almpst entirely like an ordinary
+// JavaScript object. All of the arguments values are simply copied from the stack (possibly via
+// some sophisticated ValueRecovery's if an optimizing compiler is in play) and the appropriate
+// properties of the object are populated. The only reason why we need a special class is to make
+// the object claim to be "Arguments" from a toString standpoint, and to avoid materializing the
+// caller/callee properties unless someone asks for them.
+class ClonedArguments : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
+    
+private:
+    ClonedArguments(VM&, Structure*);
+
+public:
+    static ClonedArguments* createEmpty(VM&, Structure*, JSFunction* callee);
+    static ClonedArguments* createEmpty(ExecState*, JSFunction* callee);
+    static ClonedArguments* createWithInlineFrame(ExecState* myFrame, ExecState* targetFrame, InlineCallFrame*, ArgumentsMode);
+    static ClonedArguments* createWithMachineFrame(ExecState* myFrame, ExecState* targetFrame, ArgumentsMode);
+    static ClonedArguments* createByCopyingFrom(ExecState*, Structure*, Register* argumentsStart, unsigned length, JSFunction* callee);
+    
+    static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
+
+    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSObject::StructureFlags;
+
+    DECLARE_INFO;
+
+private:
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+    static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
+    static bool deleteProperty(JSCell*, ExecState*, PropertyName);
+    static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
+    
+    bool specialsMaterialized() const { return !m_callee; }
+    void materializeSpecials(ExecState*);
+    void materializeSpecialsIfNecessary(ExecState*);
+    
+    WriteBarrier<JSFunction> m_callee; // Set to nullptr when we materialize all of our special properties.
+};
+
+} // namespace JSC
+
+#endif // ClonedArguments_h
+
diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
index 8abd816..a3addd2 100644
--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -25,12 +25,14 @@
 
 #include "config.h"
 #include "CommonSlowPaths.h"
-#include "Arguments.h"
 #include "ArityCheckFailReturnThunks.h"
 #include "ArrayConstructor.h"
 #include "CallFrame.h"
+#include "ClonedArguments.h"
 #include "CodeProfiling.h"
 #include "CommonSlowPathsExceptions.h"
+#include "DirectArguments.h"
+#include "Error.h"
 #include "ErrorHandlingScope.h"
 #include "ExceptionFuzz.h"
 #include "GetterSetter.h"
@@ -38,6 +40,7 @@
 #include "Interpreter.h"
 #include "JIT.h"
 #include "JITStubs.h"
+#include "JSCInlines.h"
 #include "JSCJSValue.h"
 #include "JSGlobalObjectFunctions.h"
 #include "JSLexicalEnvironment.h"
@@ -49,7 +52,7 @@
 #include "LLIntExceptions.h"
 #include "LowLevelInterpreter.h"
 #include "ObjectConstructor.h"
-#include "JSCInlines.h"
+#include "ScopedArguments.h"
 #include "StructureRareDataInlines.h"
 #include "TypeProfilerLog.h"
 #include "VariableWatchpointSetInlines.h"
@@ -210,17 +213,24 @@
     END();
 }
 
-SLOW_PATH_DECL(slow_path_create_arguments)
+SLOW_PATH_DECL(slow_path_create_direct_arguments)
 {
     BEGIN();
-    int lexicalEnvironmentReg = pc[2].u.operand;
-    JSLexicalEnvironment* lexicalEnvironment = VirtualRegister(lexicalEnvironmentReg).isValid() ?
-        exec->uncheckedR(lexicalEnvironmentReg).lexicalEnvironment() : nullptr;
-    JSValue arguments = JSValue(Arguments::create(vm, exec, lexicalEnvironment));
-    CHECK_EXCEPTION();
-    exec->uncheckedR(pc[1].u.operand) = arguments;
-    exec->uncheckedR(unmodifiedArgumentsRegister(VirtualRegister(pc[1].u.operand)).offset()) = arguments;
-    END();
+    RETURN(DirectArguments::createByCopying(exec));
+}
+
+SLOW_PATH_DECL(slow_path_create_scoped_arguments)
+{
+    BEGIN();
+    JSLexicalEnvironment* scope = jsCast<JSLexicalEnvironment*>(OP(2).jsValue());
+    ScopedArgumentsTable* table = exec->codeBlock()->symbolTable()->arguments();
+    RETURN(ScopedArguments::createByCopying(exec, table, scope));
+}
+
+SLOW_PATH_DECL(slow_path_create_out_of_band_arguments)
+{
+    BEGIN();
+    RETURN(ClonedArguments::createWithMachineFrame(exec, exec, ArgumentsMode::Cloned));
 }
 
 SLOW_PATH_DECL(slow_path_create_this)
diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.h b/Source/JavaScriptCore/runtime/CommonSlowPaths.h
index 94fadec..f60bbc8 100644
--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.h
+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -182,7 +182,9 @@
 SLOW_PATH_HIDDEN_DECL(slow_path_call_arityCheck);
 SLOW_PATH_HIDDEN_DECL(slow_path_construct_arityCheck);
 SLOW_PATH_HIDDEN_DECL(slow_path_touch_entry);
-SLOW_PATH_HIDDEN_DECL(slow_path_create_arguments);
+SLOW_PATH_HIDDEN_DECL(slow_path_create_direct_arguments);
+SLOW_PATH_HIDDEN_DECL(slow_path_create_scoped_arguments);
+SLOW_PATH_HIDDEN_DECL(slow_path_create_out_of_band_arguments);
 SLOW_PATH_HIDDEN_DECL(slow_path_create_this);
 SLOW_PATH_HIDDEN_DECL(slow_path_enter);
 SLOW_PATH_HIDDEN_DECL(slow_path_get_callee);
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h b/Source/JavaScriptCore/runtime/ConstantMode.cpp
similarity index 71%
copy from Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h
copy to Source/JavaScriptCore/runtime/ConstantMode.cpp
index 25098ca..58ba794 100644
--- a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h
+++ b/Source/JavaScriptCore/runtime/ConstantMode.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,25 +23,24 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#ifndef DFGArgumentsSimplificationPhase_h
-#define DFGArgumentsSimplificationPhase_h
+#include "config.h"
+#include "ConstantMode.h"
 
-#if ENABLE(DFG_JIT)
+namespace WTF {
 
-namespace JSC { namespace DFG {
+using namespace JSC;
 
-class Graph;
+void printInternal(PrintStream& out, ConstantMode mode)
+{
+    switch (mode) {
+    case IsConstant:
+        out.print("Constant");
+        return;
+    case IsVariable:
+        out.print("Variable");
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
 
-// Simplifies reflective uses of the Arguments object:
-//
-// Inlined arguments.length -> constant
-// Inlined arguments[constant] -> GetLocalUnlinked
-
-bool performArgumentsSimplification(Graph&);
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // DFGArgumentsSimplificationPhase_h
-
+} // namespace WTF
diff --git a/Source/JavaScriptCore/runtime/ConstantMode.h b/Source/JavaScriptCore/runtime/ConstantMode.h
index 389a074..a049627 100644
--- a/Source/JavaScriptCore/runtime/ConstantMode.h
+++ b/Source/JavaScriptCore/runtime/ConstantMode.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,11 +26,24 @@
 #ifndef ConstantMode_h
 #define ConstantMode_h
 
+#include <wtf/PrintStream.h>
+
 namespace JSC {
 
 enum ConstantMode { IsConstant, IsVariable };
 
+inline ConstantMode modeForIsConstant(bool isConstant)
+{
+    return isConstant ? IsConstant : IsVariable;
+}
+
 } // namespace JSC
 
+namespace WTF {
+
+void printInternal(PrintStream&, JSC::ConstantMode);
+
+} // namespace WTF
+
 #endif // ConstantMode_h
 
diff --git a/Source/JavaScriptCore/runtime/DirectArguments.cpp b/Source/JavaScriptCore/runtime/DirectArguments.cpp
new file mode 100644
index 0000000..d0333a7
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/DirectArguments.cpp
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DirectArguments.h"
+
+#include "CopyVisitorInlines.h"
+#include "GenericArgumentsInlines.h"
+#include "JSArgumentsIterator.h"
+#include "JSCInlines.h"
+
+namespace JSC {
+
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(DirectArguments);
+
+const ClassInfo DirectArguments::s_info = { "Arguments", &Base::s_info, 0, CREATE_METHOD_TABLE(DirectArguments) };
+
+DirectArguments::DirectArguments(VM& vm, Structure* structure, unsigned length, unsigned capacity)
+    : GenericArguments(vm, structure)
+    , m_length(length)
+    , m_minCapacity(capacity)
+{
+    // When we construct the object from C++ code, we expect the capacity to be at least as large as
+    // length. JIT-allocated DirectArguments objects play evil tricks, though.
+    ASSERT(capacity >= length);
+}
+
+DirectArguments* DirectArguments::createUninitialized(
+    VM& vm, Structure* structure, unsigned length, unsigned capacity)
+{
+    DirectArguments* result =
+        new (NotNull, allocateCell<DirectArguments>(vm.heap, allocationSize(capacity)))
+        DirectArguments(vm, structure, length, capacity);
+    result->finishCreation(vm);
+    return result;
+}
+
+DirectArguments* DirectArguments::create(VM& vm, Structure* structure, unsigned length, unsigned capacity)
+{
+    DirectArguments* result = createUninitialized(vm, structure, length, capacity);
+    
+    for (unsigned i = capacity; i--;)
+        result->storage()[i].clear();
+    
+    return result;
+}
+
+DirectArguments* DirectArguments::createByCopying(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    
+    unsigned length = exec->argumentCount();
+    unsigned capacity = std::max(length, static_cast<unsigned>(exec->codeBlock()->numParameters() - 1));
+    DirectArguments* result = createUninitialized(
+        vm, exec->lexicalGlobalObject()->directArgumentsStructure(), length, capacity);
+    
+    for (unsigned i = capacity; i--;)
+        result->storage()[i].set(vm, result, exec->getArgumentUnsafe(i));
+    
+    result->callee().set(vm, result, jsCast<JSFunction*>(exec->callee()));
+    
+    return result;
+}
+
+void DirectArguments::visitChildren(JSCell* thisCell, SlotVisitor& visitor)
+{
+    DirectArguments* thisObject = static_cast<DirectArguments*>(thisCell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    Base::visitChildren(thisObject, visitor);
+    
+    visitor.appendValues(thisObject->storage(), std::max(thisObject->m_length, thisObject->m_minCapacity));
+    visitor.append(&thisObject->m_callee);
+    
+    if (thisObject->m_overrides) {
+        visitor.copyLater(
+            thisObject, DirectArgumentsOverridesCopyToken,
+            thisObject->m_overrides.get(), thisObject->overridesSize());
+    }
+}
+
+void DirectArguments::copyBackingStore(JSCell* thisCell, CopyVisitor& visitor, CopyToken token)
+{
+    DirectArguments* thisObject = static_cast<DirectArguments*>(thisCell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    
+    RELEASE_ASSERT(token == DirectArgumentsOverridesCopyToken);
+    
+    bool* oldOverrides = thisObject->m_overrides.get();
+    if (!oldOverrides)
+        return;
+    
+    if (visitor.checkIfShouldCopy(oldOverrides)) {
+        bool* newOverrides = static_cast<bool*>(visitor.allocateNewSpace(thisObject->overridesSize()));
+        memcpy(newOverrides, oldOverrides, thisObject->m_length);
+        thisObject->m_overrides.setWithoutWriteBarrier(newOverrides);
+        visitor.didCopy(oldOverrides, thisObject->overridesSize());
+    }
+}
+
+Structure* DirectArguments::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+    return Structure::create(vm, globalObject, prototype, TypeInfo(DirectArgumentsType, StructureFlags), info());
+}
+
+void DirectArguments::overrideThings(VM& vm)
+{
+    RELEASE_ASSERT(!m_overrides);
+    
+    putDirect(vm, vm.propertyNames->length, jsNumber(m_length), DontEnum);
+    putDirect(vm, vm.propertyNames->callee, m_callee.get(), DontEnum);
+    
+    void* backingStore;
+    RELEASE_ASSERT(vm.heap.tryAllocateStorage(this, overridesSize(), &backingStore));
+    m_overrides.set(vm, this, static_cast<bool*>(backingStore));
+    for (unsigned i = m_length; i--;)
+        m_overrides.get()[i] = false;
+}
+
+void DirectArguments::overrideThingsIfNecessary(VM& vm)
+{
+    if (!m_overrides)
+        overrideThings(vm);
+}
+
+void DirectArguments::overrideArgument(VM& vm, unsigned index)
+{
+    overrideThingsIfNecessary(vm);
+    m_overrides.get()[index] = true;
+}
+
+void DirectArguments::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, unsigned offset, unsigned length)
+{
+    if (!m_overrides) {
+        unsigned limit = std::min(length + offset, m_length);
+        unsigned i;
+        VirtualRegister start = firstElementDest - offset;
+        for (i = offset; i < limit; ++i)
+            exec->r(start + i) = storage()[i].get();
+        for (; i < length; ++i)
+            exec->r(start + i) = get(exec, i);
+        return;
+    }
+
+    GenericArguments::copyToArguments(exec, firstElementDest, offset, length);
+}
+
+unsigned DirectArguments::overridesSize()
+{
+    // We always allocate something; in the relatively uncommon case of overriding an empty argument we
+    // still allocate so that m_overrides is non-null. We use that to indicate that the other properties
+    // (length, etc) are overridden.
+    return WTF::roundUpToMultipleOf<8>(m_length ? m_length : 1);
+}
+
+} // namespace JSC
+
diff --git a/Source/JavaScriptCore/runtime/DirectArguments.h b/Source/JavaScriptCore/runtime/DirectArguments.h
new file mode 100644
index 0000000..a29e80a
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/DirectArguments.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DirectArguments_h
+#define DirectArguments_h
+
+#include "DirectArgumentsOffset.h"
+#include "GenericArguments.h"
+
+namespace JSC {
+
+// This is an Arguments-class object that we create when you say "arguments" inside a function,
+// and none of the arguments are captured in the function's activation. The function will copy all
+// of its arguments into this object, and all subsequent accesses to the arguments will go through
+// this object thereafter. Special support is in place for mischevious events like the arguments
+// being deleted (something like "delete arguments[0]") or reconfigured (broadly, we say deletions
+// and reconfigurations mean that the respective argument was "overridden").
+//
+// To speed allocation, this object will hold all of the arguments in-place. The arguments as well
+// as a table of flags saying which arguments were overridden.
+class DirectArguments : public GenericArguments<DirectArguments> {
+private:
+    DirectArguments(VM&, Structure*, unsigned length, unsigned capacity);
+    
+public:
+    // Creates an arguments object but leaves it uninitialized. This is dangerous if we GC right
+    // after allocation.
+    static DirectArguments* createUninitialized(VM&, Structure*, unsigned length, unsigned capacity);
+    
+    // Creates an arguments object and initializes everything to the empty value. Use this if you
+    // cannot guarantee that you'll immediately initialize all of the elements.
+    static DirectArguments* create(VM&, Structure*, unsigned length, unsigned capacity);
+    
+    // Creates an arguments object by copying the argumnets from the stack.
+    static DirectArguments* createByCopying(ExecState*);
+    
+    static void visitChildren(JSCell*, SlotVisitor&);
+    static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken);
+    
+    uint32_t internalLength() const
+    {
+        return m_length;
+    }
+    
+    uint32_t length(ExecState* exec) const
+    {
+        if (UNLIKELY(m_overrides))
+            return get(exec, exec->propertyNames().length).toUInt32(exec);
+        return m_length;
+    }
+    
+    bool canAccessIndexQuickly(uint32_t i) const
+    {
+        return i < m_length && (!m_overrides || !m_overrides.get()[i]);
+    }
+    
+    JSValue getIndexQuickly(uint32_t i) const
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(canAccessIndexQuickly(i));
+        return const_cast<DirectArguments*>(this)->storage()[i].get();
+    }
+    
+    void setIndexQuickly(VM& vm, uint32_t i, JSValue value)
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(canAccessIndexQuickly(i));
+        storage()[i].set(vm, this, value);
+    }
+    
+    WriteBarrier<JSFunction>& callee()
+    {
+        return m_callee;
+    }
+    
+    WriteBarrier<Unknown>& argument(DirectArgumentsOffset offset)
+    {
+        ASSERT(offset);
+        ASSERT_WITH_SECURITY_IMPLICATION(offset.offset() < std::max(m_length, m_minCapacity));
+        return storage()[offset.offset()];
+    }
+    
+    // Methods intended for use by the GenericArguments mixin.
+    bool overrodeThings() const { return !!m_overrides; }
+    void overrideThings(VM&);
+    void overrideThingsIfNecessary(VM&);
+    void overrideArgument(VM&, unsigned index);
+    
+    void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
+
+    DECLARE_INFO;
+    
+    static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
+    
+    static ptrdiff_t offsetOfCallee() { return OBJECT_OFFSETOF(DirectArguments, m_callee); }
+    static ptrdiff_t offsetOfLength() { return OBJECT_OFFSETOF(DirectArguments, m_length); }
+    static ptrdiff_t offsetOfMinCapacity() { return OBJECT_OFFSETOF(DirectArguments, m_minCapacity); }
+    static ptrdiff_t offsetOfOverrides() { return OBJECT_OFFSETOF(DirectArguments, m_overrides); }
+    
+    static size_t storageOffset()
+    {
+        return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(DirectArguments));
+    }
+    
+    static size_t offsetOfSlot(uint32_t index)
+    {
+        return storageOffset() + sizeof(WriteBarrier<Unknown>) * index;
+    }
+    
+    static size_t allocationSize(uint32_t capacity)
+    {
+        return offsetOfSlot(capacity);
+    }
+    
+private:
+    WriteBarrier<Unknown>* storage()
+    {
+        return bitwise_cast<WriteBarrier<Unknown>*>(bitwise_cast<char*>(this) + storageOffset());
+    }
+    
+    unsigned overridesSize();
+    
+    WriteBarrier<JSFunction> m_callee;
+    uint32_t m_length; // Always the actual length of captured arguments and never what was stored into the length property.
+    uint32_t m_minCapacity; // The max of this and length determines the capacity of this object. It may be the actual capacity, or maybe something smaller. We arrange it this way to be kind to the JITs.
+    CopyWriteBarrier<bool> m_overrides; // If non-null, it means that length, callee, and caller are fully materialized properties.
+};
+
+} // namespace JSC
+
+#endif // DirectArguments_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h b/Source/JavaScriptCore/runtime/DirectArgumentsOffset.cpp
similarity index 71%
copy from Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h
copy to Source/JavaScriptCore/runtime/DirectArgumentsOffset.cpp
index 25098ca..9fc4c42 100644
--- a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h
+++ b/Source/JavaScriptCore/runtime/DirectArgumentsOffset.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,25 +23,20 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#ifndef DFGArgumentsSimplificationPhase_h
-#define DFGArgumentsSimplificationPhase_h
+#include "config.h"
+#include "DirectArgumentsOffset.h"
 
-#if ENABLE(DFG_JIT)
+namespace JSC {
 
-namespace JSC { namespace DFG {
+void DirectArgumentsOffset::dump(PrintStream& out) const
+{
+    if (!*this) {
+        out.print("capturedArgumentInvalid");
+        return;
+    }
 
-class Graph;
+    out.print("capturedArgument", offset());
+}
 
-// Simplifies reflective uses of the Arguments object:
-//
-// Inlined arguments.length -> constant
-// Inlined arguments[constant] -> GetLocalUnlinked
-
-bool performArgumentsSimplification(Graph&);
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // DFGArgumentsSimplificationPhase_h
+} // namespace JSC
 
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h b/Source/JavaScriptCore/runtime/DirectArgumentsOffset.h
similarity index 61%
copy from Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h
copy to Source/JavaScriptCore/runtime/DirectArgumentsOffset.h
index 25098ca..f60f4b7 100644
--- a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h
+++ b/Source/JavaScriptCore/runtime/DirectArgumentsOffset.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,25 +23,31 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#ifndef DFGArgumentsSimplificationPhase_h
-#define DFGArgumentsSimplificationPhase_h
+#ifndef DirectArgumentsOffset_h
+#define DirectArgumentsOffset_h
 
-#if ENABLE(DFG_JIT)
+#include "GenericOffset.h"
+#include <wtf/PrintStream.h>
 
-namespace JSC { namespace DFG {
+namespace JSC {
 
-class Graph;
+// This is an offset into the special arguments object, which captures the arguments to a
+// function. It only comes into play it the arguments aren't also lifted into the activation.
+// If they were then accesses to the arguments would resolve to a ScopeOffset and not a
+// DirectArgumentsOffset.
+class DirectArgumentsOffset : public GenericOffset<DirectArgumentsOffset> {
+public:
+    DirectArgumentsOffset() { }
+    
+    explicit DirectArgumentsOffset(unsigned offset)
+        : GenericOffset(offset)
+    {
+    }
+    
+    void dump(PrintStream&) const;
+};
 
-// Simplifies reflective uses of the Arguments object:
-//
-// Inlined arguments.length -> constant
-// Inlined arguments[constant] -> GetLocalUnlinked
+} // namespace JSC
 
-bool performArgumentsSimplification(Graph&);
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // DFGArgumentsSimplificationPhase_h
+#endif // DirectArgumentsOffset_h
 
diff --git a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
index 1e5666d..d082b12 100644
--- a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2015 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -21,9 +21,9 @@
 #include "config.h"
 #include "FunctionPrototype.h"
 
-#include "Arguments.h"
 #include "BuiltinExecutables.h"
 #include "BuiltinNames.h"
+#include "Error.h"
 #include "JSArray.h"
 #include "JSBoundFunction.h"
 #include "JSFunction.h"
diff --git a/Source/JavaScriptCore/runtime/GenericArguments.h b/Source/JavaScriptCore/runtime/GenericArguments.h
new file mode 100644
index 0000000..2e9373c
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/GenericArguments.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef GenericArguments_h
+#define GenericArguments_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+// This is a mixin for the two kinds of Arguments-class objects that arise when you say
+// "arguments" inside a function. This class doesn't show up in the JSCell inheritance hierarchy.
+template<typename Type>
+class GenericArguments : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
+
+    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSObject::StructureFlags;
+
+protected:
+    GenericArguments(VM& vm, Structure* structure)
+        : Base(vm, structure)
+    {
+    }
+
+    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
+    static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
+    static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
+    static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
+    static bool deleteProperty(JSCell*, ExecState*, PropertyName);
+    static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
+    static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
+    
+    void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
+};
+
+} // namespace JSC
+
+#endif // GenericArguments_h
+
diff --git a/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h b/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h
new file mode 100644
index 0000000..516b7aa
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef GenericArgumentsInlines_h
+#define GenericArgumentsInlines_h
+
+#include "GenericArguments.h"
+#include "JSArgumentsIterator.h"
+#include "JSCInlines.h"
+
+namespace JSC {
+
+template<typename Type>
+bool GenericArguments<Type>::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName ident, PropertySlot& slot)
+{
+    Type* thisObject = jsCast<Type*>(object);
+    VM& vm = exec->vm();
+    
+    if (!thisObject->overrodeThings()) {
+        if (ident == vm.propertyNames->length) {
+            slot.setValue(thisObject, DontEnum, jsNumber(thisObject->internalLength()));
+            return true;
+        }
+        if (ident == vm.propertyNames->callee) {
+            slot.setValue(thisObject, DontEnum, thisObject->callee().get());
+            return true;
+        }
+    }
+    
+    unsigned index = ident.asIndex();
+    if (thisObject->canAccessIndexQuickly(index)) {
+        slot.setValue(thisObject, None, thisObject->getIndexQuickly(index));
+        return true;
+    }
+    
+    if (Base::getOwnPropertySlot(thisObject, exec, ident, slot))
+        return true;
+    
+    if (ident == vm.propertyNames->iteratorPrivateName) {
+        JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+        thisObject->JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, argumentsFuncIterator, DontEnum, 0);
+        if (JSObject::getOwnPropertySlot(thisObject, exec, ident, slot))
+            return true;
+    }
+    
+    return false;
+}
+
+template<typename Type>
+bool GenericArguments<Type>::getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned index, PropertySlot& slot)
+{
+    Type* thisObject = jsCast<Type*>(object);
+    
+    if (thisObject->canAccessIndexQuickly(index)) {
+        slot.setValue(thisObject, None, thisObject->getIndexQuickly(index));
+        return true;
+    }
+    
+    return Base::getOwnPropertySlotByIndex(object, exec, index, slot);
+}
+
+template<typename Type>
+void GenericArguments<Type>::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& array, EnumerationMode mode)
+{
+    Type* thisObject = jsCast<Type*>(object);
+    
+    for (unsigned i = 0; i < thisObject->internalLength(); ++i) {
+        if (!thisObject->canAccessIndexQuickly(i))
+            continue;
+        array.add(Identifier::from(exec, i));
+    }
+    if (shouldIncludeDontEnumProperties(mode) && !thisObject->overrodeThings()) {
+        array.add(exec->propertyNames().callee);
+        array.add(exec->propertyNames().length);
+    }
+    Base::getOwnPropertyNames(thisObject, exec, array, mode);
+}
+
+template<typename Type>
+void GenericArguments<Type>::put(JSCell* cell, ExecState* exec, PropertyName ident, JSValue value, PutPropertySlot& slot)
+{
+    Type* thisObject = jsCast<Type*>(cell);
+    VM& vm = exec->vm();
+    
+    if (!thisObject->overrodeThings()
+        && (ident == vm.propertyNames->length
+            || ident == vm.propertyNames->callee)) {
+        thisObject->overrideThings(vm);
+        PutPropertySlot dummy = slot; // This put is not cacheable, so we shadow the slot that was given to us.
+        Base::put(thisObject, exec, ident, value, dummy);
+        return;
+    }
+    
+    unsigned index = ident.asIndex();
+    if (thisObject->canAccessIndexQuickly(index)) {
+        thisObject->setIndexQuickly(vm, index, value);
+        return;
+    }
+    
+    Base::put(thisObject, exec, ident, value, slot);
+}
+
+template<typename Type>
+void GenericArguments<Type>::putByIndex(JSCell* cell, ExecState* exec, unsigned index, JSValue value, bool shouldThrow)
+{
+    Type* thisObject = jsCast<Type*>(cell);
+    VM& vm = exec->vm();
+
+    if (thisObject->canAccessIndexQuickly(index)) {
+        thisObject->setIndexQuickly(vm, index, value);
+        return;
+    }
+    
+    return Base::putByIndex(cell, exec, index, value, shouldThrow);
+}
+
+template<typename Type>
+bool GenericArguments<Type>::deleteProperty(JSCell* cell, ExecState* exec, PropertyName ident)
+{
+    Type* thisObject = jsCast<Type*>(cell);
+    VM& vm = exec->vm();
+    
+    if (!thisObject->overrodeThings()
+        && (ident == vm.propertyNames->length
+            || ident == vm.propertyNames->callee))
+        thisObject->overrideThings(vm);
+    
+    unsigned index = ident.asIndex();
+    if (thisObject->canAccessIndexQuickly(index)) {
+        thisObject->overrideArgument(vm, index);
+        return true;
+    }
+    
+    return Base::deleteProperty(thisObject, exec, ident);
+}
+
+template<typename Type>
+bool GenericArguments<Type>::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned index)
+{
+    Type* thisObject = jsCast<Type*>(cell);
+    VM& vm = exec->vm();
+    
+    if (thisObject->canAccessIndexQuickly(index)) {
+        thisObject->overrideArgument(vm, index);
+        return true;
+    }
+    
+    return Base::deletePropertyByIndex(cell, exec, index);
+}
+
+template<typename Type>
+bool GenericArguments<Type>::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName ident, const PropertyDescriptor& descriptor, bool shouldThrow)
+{
+    Type* thisObject = jsCast<Type*>(object);
+    VM& vm = exec->vm();
+    
+    if (ident == vm.propertyNames->length
+        || ident == vm.propertyNames->callee)
+        thisObject->overrideThingsIfNecessary(vm);
+    else {
+        unsigned index = ident.asIndex();
+        if (thisObject->canAccessIndexQuickly(index)) {
+            if (!descriptor.isAccessorDescriptor()) {
+                // If the property is not deleted and we are using a non-accessor descriptor, then
+                // make sure that the aliased argument sees the value.
+                if (descriptor.value())
+                    thisObject->setIndexQuickly(vm, index, descriptor.value());
+            
+                // If the property is not deleted and we are using a non-accessor, writable
+                // descriptor, then we are done. The argument continues to be aliased. Note that we
+                // ignore the request to change enumerability. We appear to have always done so, in
+                // cases where the argument was still aliased.
+                // FIXME: https://bugs.webkit.org/show_bug.cgi?id=141952
+                if (descriptor.writable())
+                    return true;
+            }
+        
+            // If the property is a non-deleted argument, then move it into the base object and
+            // then delete it.
+            JSValue value = thisObject->getIndexQuickly(index);
+            ASSERT(value);
+            object->putDirectMayBeIndex(exec, ident, value);
+            thisObject->overrideArgument(vm, index);
+        }
+    }
+    
+    // Now just let the normal object machinery do its thing.
+    return Base::defineOwnProperty(object, exec, ident, descriptor, shouldThrow);
+}
+
+template<typename Type>
+void GenericArguments<Type>::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, unsigned offset, unsigned length)
+{
+    Type* thisObject = static_cast<Type*>(this);
+    for (unsigned i = 0; i < length; ++i) {
+        if (thisObject->canAccessIndexQuickly(i + offset))
+            exec->r(firstElementDest + i) = thisObject->getIndexQuickly(i + offset);
+        else {
+            exec->r(firstElementDest + i) = get(exec, i + offset);
+            if (UNLIKELY(exec->vm().exception()))
+                return;
+        }
+    }
+}
+
+} // namespace JSC
+
+#endif // GenericArgumentsInlines_h
+
diff --git a/Source/JavaScriptCore/runtime/GenericOffset.h b/Source/JavaScriptCore/runtime/GenericOffset.h
new file mode 100644
index 0000000..a6bfe56
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/GenericOffset.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef GenericOffset_h
+#define GenericOffset_h
+
+#include <limits.h>
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+// A mixin for creating the various kinds of variable offsets that our engine supports.
+template<typename T>
+class GenericOffset {
+public:
+    static const unsigned invalidOffset = UINT_MAX;
+    
+    GenericOffset()
+        : m_offset(invalidOffset)
+    {
+    }
+    
+    explicit GenericOffset(unsigned offset)
+        : m_offset(offset)
+    {
+    }
+    
+    bool operator!() const { return m_offset == invalidOffset; }
+    
+    unsigned offsetUnchecked() const
+    {
+        return m_offset;
+    }
+    
+    unsigned offset() const
+    {
+        ASSERT(m_offset != invalidOffset);
+        return m_offset;
+    }
+    
+    bool operator==(const T& other) const
+    {
+        return m_offset == other.offsetUnchecked();
+    }
+    bool operator!=(const T& other) const
+    {
+        return m_offset != other.offsetUnchecked();
+    }
+    bool operator<(const T& other) const
+    {
+        return m_offset < other.offsetUnchecked();
+    }
+    bool operator>(const T& other) const
+    {
+        return m_offset > other.offsetUnchecked();
+    }
+    bool operator<=(const T& other) const
+    {
+        return m_offset <= other.offsetUnchecked();
+    }
+    bool operator>=(const T& other) const
+    {
+        return m_offset >= other.offsetUnchecked();
+    }
+    
+    T operator+(int value) const
+    {
+        return T(offset() + value);
+    }
+    T operator-(int value) const
+    {
+        return T(offset() - value);
+    }
+    T& operator+=(int value)
+    {
+        return *this = *this + value;
+    }
+    T& operator-=(int value)
+    {
+        return *this = *this - value;
+    }
+    
+private:
+    unsigned m_offset;
+};
+
+} // namespace JSC
+
+#endif // GenericOffset_h
+
diff --git a/Source/JavaScriptCore/runtime/JSArgumentsIterator.cpp b/Source/JavaScriptCore/runtime/JSArgumentsIterator.cpp
index 4ccb622..7947dc9 100644
--- a/Source/JavaScriptCore/runtime/JSArgumentsIterator.cpp
+++ b/Source/JavaScriptCore/runtime/JSArgumentsIterator.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple, Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple, Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,14 +26,16 @@
 #include "config.h"
 #include "JSArgumentsIterator.h"
 
-#include "Arguments.h"
+#include "ClonedArguments.h"
+#include "DirectArguments.h"
 #include "JSCInlines.h"
+#include "ScopedArguments.h"
 
 namespace JSC {
 
 const ClassInfo JSArgumentsIterator::s_info = { "ArgumentsIterator", &Base::s_info, 0, CREATE_METHOD_TABLE(JSArgumentsIterator) };
 
-void JSArgumentsIterator::finishCreation(VM& vm, Arguments* arguments)
+void JSArgumentsIterator::finishCreation(VM& vm, JSObject* arguments)
 {
     Base::finishCreation(vm);
     m_arguments.set(vm, this, arguments);
@@ -46,4 +48,12 @@
     return clone;
 }
 
+EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState* exec)
+{
+    JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
+    if (!thisObj->inherits(DirectArguments::info()) && !thisObj->inherits(ScopedArguments::info()) && !thisObj->inherits(ClonedArguments::info()))
+        return JSValue::encode(throwTypeError(exec, ASCIILiteral("Attempted to use Arguments iterator on non-Arguments object")));
+    return JSValue::encode(JSArgumentsIterator::create(exec->vm(), exec->callee()->globalObject()->argumentsIteratorStructure(), thisObj));
+}
+
 }
diff --git a/Source/JavaScriptCore/runtime/JSArgumentsIterator.h b/Source/JavaScriptCore/runtime/JSArgumentsIterator.h
index 6bdce7d..efcf91e 100644
--- a/Source/JavaScriptCore/runtime/JSArgumentsIterator.h
+++ b/Source/JavaScriptCore/runtime/JSArgumentsIterator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple, Inc. All rights reserved.
+ * Copyright (C) 2013, 2015 Apple, Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,7 +26,7 @@
 #ifndef JSArgumentsIterator_h
 #define JSArgumentsIterator_h
 
-#include "Arguments.h"
+#include "JSObject.h"
 
 namespace JSC {
 
@@ -41,7 +41,7 @@
         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     }
 
-    static JSArgumentsIterator* create(VM& vm, Structure* structure, Arguments* arguments)
+    static JSArgumentsIterator* create(VM& vm, Structure* structure, JSObject* arguments)
     {
         JSArgumentsIterator* instance = new (NotNull, allocateCell<JSArgumentsIterator>(vm.heap)) JSArgumentsIterator(vm, structure);
         instance->finishCreation(vm, arguments);
@@ -50,11 +50,11 @@
 
     bool next(CallFrame* callFrame, JSValue& value)
     {
-        if (m_nextIndex >= m_arguments->length(callFrame))
+        unsigned length =
+            m_arguments->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
+        if (m_nextIndex >= length)
             return false;
-        value = m_arguments->tryGetArgument(m_nextIndex++);
-        if (!value)
-            value = jsUndefined();
+        value = m_arguments->getIndex(callFrame, m_nextIndex++);
         return true;
     }
 
@@ -71,12 +71,14 @@
     {
     }
 
-    void finishCreation(VM&, Arguments*);
+    void finishCreation(VM&, JSObject*);
     
-    WriteBarrier<Arguments> m_arguments;
+    WriteBarrier<JSObject> m_arguments;
     size_t m_nextIndex;
 };
 
+EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState*);
+
 }
 
 #endif // !defined(JSArgumentsIterator_h)
diff --git a/Source/JavaScriptCore/runtime/JSEnvironmentRecord.cpp b/Source/JavaScriptCore/runtime/JSEnvironmentRecord.cpp
index 670dee6..152b044 100644
--- a/Source/JavaScriptCore/runtime/JSEnvironmentRecord.cpp
+++ b/Source/JavaScriptCore/runtime/JSEnvironmentRecord.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2008, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2012, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,4 +35,12 @@
 
 const ClassInfo JSEnvironmentRecord::s_info = { "EnvironmentRecord", &Base::s_info, 0, CREATE_METHOD_TABLE(JSEnvironmentRecord) };
 
+void JSEnvironmentRecord::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    JSEnvironmentRecord* thisObject = jsCast<JSEnvironmentRecord*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    Base::visitChildren(thisObject, visitor);
+    visitor.appendValues(thisObject->variables(), thisObject->m_symbolTable->scopeSize());
+}
+
 } // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSEnvironmentRecord.h b/Source/JavaScriptCore/runtime/JSEnvironmentRecord.h
index 655db7f..811e4d1 100644
--- a/Source/JavaScriptCore/runtime/JSEnvironmentRecord.h
+++ b/Source/JavaScriptCore/runtime/JSEnvironmentRecord.h
@@ -46,29 +46,71 @@
 public:
     typedef JSSymbolTableObject Base;
 
-    WriteBarrierBase<Unknown>* registers() { return m_registers; }
-    WriteBarrierBase<Unknown>& registerAt(int index) const { return m_registers[index]; }
+    WriteBarrierBase<Unknown>* variables()
+    {
+        return bitwise_cast<WriteBarrierBase<Unknown>*>(bitwise_cast<char*>(this) + offsetOfVariables());
+    }
+    
+    bool isValid(ScopeOffset offset)
+    {
+        return !!offset && offset.offset() < m_symbolTable->scopeSize();
+    }
+    
+    WriteBarrierBase<Unknown>& variableAt(ScopeOffset offset)
+    {
+        ASSERT(isValid(offset));
+        return variables()[offset.offset()];
+    }
 
-    WriteBarrierBase<Unknown>* const * addressOfRegisters() const { return &m_registers; }
-    static size_t offsetOfRegisters() { return OBJECT_OFFSETOF(JSEnvironmentRecord, m_registers); }
+    static size_t offsetOfVariables()
+    {
+        return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSEnvironmentRecord));
+    }
+    
+    static ptrdiff_t offsetOfVariable(ScopeOffset offset)
+    {
+        return offsetOfVariables() + offset.offset() * sizeof(WriteBarrier<Unknown>);
+    }
 
     DECLARE_INFO;
 
+    static size_t allocationSizeForScopeSize(unsigned scopeSize)
+    {
+        return offsetOfVariables() + scopeSize * sizeof(WriteBarrier<Unknown>);
+    }
+    
+    static size_t allocationSize(SymbolTable* symbolTable)
+    {
+        return allocationSizeForScopeSize(symbolTable->scopeSize());
+    }
+    
 protected:
     static const unsigned StructureFlags = Base::StructureFlags;
 
     JSEnvironmentRecord(
         VM& vm,
         Structure* structure,
-        Register* registers,
         JSScope* scope,
         SymbolTable* symbolTable)
         : Base(vm, structure, scope, symbolTable)
-        , m_registers(reinterpret_cast<WriteBarrierBase<Unknown>*>(registers))
     {
     }
+    
+    void finishCreationUninitialized(VM& vm)
+    {
+        Base::finishCreation(vm);
+    }
+    
+    void finishCreation(VM& vm)
+    {
+        finishCreationUninitialized(vm);
+        for (unsigned i = m_symbolTable->scopeSize(); i--;) {
+            // Filling this with undefined is useful because that's what variables start out as.
+            variableAt(ScopeOffset(i)).setUndefined();
+        }
+    }
 
-    WriteBarrierBase<Unknown>* m_registers; // "r" in the stack.
+    static void visitChildren(JSCell*, SlotVisitor&);
 };
 
 } // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSFunction.cpp b/Source/JavaScriptCore/runtime/JSFunction.cpp
index 851b66f..1b985ae 100644
--- a/Source/JavaScriptCore/runtime/JSFunction.cpp
+++ b/Source/JavaScriptCore/runtime/JSFunction.cpp
@@ -25,7 +25,7 @@
 #include "config.h"
 #include "JSFunction.h"
 
-#include "Arguments.h"
+#include "ClonedArguments.h"
 #include "CodeBlock.h"
 #include "CommonIdentifiers.h"
 #include "CallFrame.h"
@@ -34,13 +34,13 @@
 #include "GetterSetter.h"
 #include "JSArray.h"
 #include "JSBoundFunction.h"
+#include "JSCInlines.h"
 #include "JSFunctionInlines.h"
 #include "JSGlobalObject.h"
 #include "JSNotAnObject.h"
 #include "Interpreter.h"
 #include "ObjectConstructor.h"
 #include "ObjectPrototype.h"
-#include "JSCInlines.h"
 #include "Parser.h"
 #include "PropertyNameArray.h"
 #include "StackVisitor.h"
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
index 77276d5..a5eaafb 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2008, 2009, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Cameron Zwarich (cwzwarich@uwaterloo.ca)
  *
  * Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,6 @@
 #include "config.h"
 #include "JSGlobalObject.h"
 
-#include "Arguments.h"
 #include "ArgumentsIteratorConstructor.h"
 #include "ArgumentsIteratorPrototype.h"
 #include "ArrayConstructor.h"
@@ -39,6 +38,7 @@
 #include "ArrayPrototype.h"
 #include "BooleanConstructor.h"
 #include "BooleanPrototype.h"
+#include "ClonedArguments.h"
 #include "CodeBlock.h"
 #include "CodeCache.h"
 #include "ConsolePrototype.h"
@@ -46,6 +46,7 @@
 #include "DatePrototype.h"
 #include "Debugger.h"
 #include "DebuggerScope.h"
+#include "DirectArguments.h"
 #include "Error.h"
 #include "ErrorConstructor.h"
 #include "ErrorPrototype.h"
@@ -110,6 +111,7 @@
 #include "RegExpMatchesArray.h"
 #include "RegExpObject.h"
 #include "RegExpPrototype.h"
+#include "ScopedArguments.h"
 #include "SetConstructor.h"
 #include "SetIteratorConstructor.h"
 #include "SetIteratorPrototype.h"
@@ -280,7 +282,9 @@
     m_nullPrototypeObjectStructure.set(vm, this, JSFinalObject::createStructure(vm, this, jsNull(), JSFinalObject::defaultInlineCapacity()));
     
     m_callbackFunctionStructure.set(vm, this, JSCallbackFunction::createStructure(vm, this, m_functionPrototype.get()));
-    m_argumentsStructure.set(vm, this, Arguments::createStructure(vm, this, m_objectPrototype.get()));
+    m_directArgumentsStructure.set(vm, this, DirectArguments::createStructure(vm, this, m_objectPrototype.get()));
+    m_scopedArgumentsStructure.set(vm, this, ScopedArguments::createStructure(vm, this, m_objectPrototype.get()));
+    m_outOfBandArgumentsStructure.set(vm, this, ClonedArguments::createStructure(vm, this, m_objectPrototype.get()));
     m_callbackConstructorStructure.set(vm, this, JSCallbackConstructor::createStructure(vm, this, m_objectPrototype.get()));
     m_callbackObjectStructure.set(vm, this, JSCallbackObject<JSDestructibleObject>::createStructure(vm, this, m_objectPrototype.get()));
 #if JSC_OBJC_API_ENABLED
@@ -474,18 +478,28 @@
 JSGlobalObject::NewGlobalVar JSGlobalObject::addGlobalVar(const Identifier& ident, ConstantMode constantMode)
 {
     ConcurrentJITLocker locker(symbolTable()->m_lock);
-    int index = symbolTable()->size(locker);
-    SymbolTableEntry newEntry(index, (constantMode == IsConstant) ? ReadOnly : 0);
+    SymbolTableEntry entry = symbolTable()->get(locker, ident.impl());
+    if (!entry.isNull()) {
+        NewGlobalVar result;
+        result.offset = entry.scopeOffset();
+        result.set = entry.watchpointSet();
+        return result;
+    }
+    
+    ScopeOffset offset = symbolTable()->takeNextScopeOffset(locker);
+    SymbolTableEntry newEntry(VarOffset(offset), (constantMode == IsConstant) ? ReadOnly : 0);
     if (constantMode == IsVariable)
         newEntry.prepareToWatch(symbolTable());
-    SymbolTable::Map::AddResult result = symbolTable()->add(locker, ident.impl(), newEntry);
-    if (result.isNewEntry)
-        addRegisters(1);
     else
-        index = result.iterator->value.getIndex();
+        newEntry.disableWatching();
+    symbolTable()->add(locker, ident.impl(), newEntry);
+    
+    ScopeOffset offsetForAssert = addVariables(1);
+    RELEASE_ASSERT(offsetForAssert == offset);
+
     NewGlobalVar var;
-    var.registerNumber = index;
-    var.set = result.iterator->value.watchpointSet();
+    var.offset = offset;
+    var.set = newEntry.watchpointSet();
     return var;
 }
 
@@ -494,7 +508,7 @@
     VM& vm = exec->vm();
     removeDirect(vm, propertyName); // Newly declared functions overwrite existing properties.
     NewGlobalVar var = addGlobalVar(propertyName, IsVariable);
-    registerAt(var.registerNumber).set(exec->vm(), this, value);
+    variableAt(var.offset).set(exec->vm(), this, value);
     if (var.set)
         var.set->notifyWrite(vm, value, VariableWriteFireDetail(this, propertyName));
 }
@@ -691,7 +705,9 @@
     visitor.append(&thisObject->m_lexicalEnvironmentStructure);
     visitor.append(&thisObject->m_catchScopeStructure);
     visitor.append(&thisObject->m_functionNameScopeStructure);
-    visitor.append(&thisObject->m_argumentsStructure);
+    visitor.append(&thisObject->m_directArgumentsStructure);
+    visitor.append(&thisObject->m_scopedArgumentsStructure);
+    visitor.append(&thisObject->m_outOfBandArgumentsStructure);
     for (unsigned i = 0; i < NumberOfIndexingShapes; ++i)
         visitor.append(&thisObject->m_originalArrayStructureForIndexingShape[i]);
     for (unsigned i = 0; i < NumberOfIndexingShapes; ++i)
@@ -748,16 +764,21 @@
 
 void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count)
 {
-    addRegisters(count);
+    ScopeOffset startOffset = addVariables(count);
 
     for (int i = 0; i < count; ++i) {
         GlobalPropertyInfo& global = globals[i];
         ASSERT(global.attributes & DontDelete);
         
-        int index = symbolTable()->size();
-        SymbolTableEntry newEntry(index, global.attributes);
-        symbolTable()->add(global.identifier.impl(), newEntry);
-        registerAt(index).set(vm(), this, global.value);
+        ScopeOffset offset;
+        {
+            ConcurrentJITLocker locker(symbolTable()->m_lock);
+            offset = symbolTable()->takeNextScopeOffset(locker);
+            RELEASE_ASSERT(offset = startOffset + i);
+            SymbolTableEntry newEntry(VarOffset(offset), global.attributes);
+            symbolTable()->add(locker, global.identifier.impl(), newEntry);
+        }
+        variableAt(offset).set(vm(), this, global.value);
     }
 }
 
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h
index 903546b..5f08fe4 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
- *  Copyright (C) 2007, 2008, 2009, 2014 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007, 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -204,7 +204,9 @@
     WriteBarrier<Structure> m_lexicalEnvironmentStructure;
     WriteBarrier<Structure> m_catchScopeStructure;
     WriteBarrier<Structure> m_functionNameScopeStructure;
-    WriteBarrier<Structure> m_argumentsStructure;
+    WriteBarrier<Structure> m_directArgumentsStructure;
+    WriteBarrier<Structure> m_scopedArgumentsStructure;
+    WriteBarrier<Structure> m_outOfBandArgumentsStructure;
         
     // Lists the actual structures used for having these particular indexing shapes.
     WriteBarrier<Structure> m_originalArrayStructureForIndexingShape[NumberOfIndexingShapes];
@@ -329,7 +331,7 @@
     }
 
     struct NewGlobalVar {
-        int registerNumber;
+        ScopeOffset offset;
         VariableWatchpointSet* set;
     };
     NewGlobalVar addGlobalVar(const Identifier&, ConstantMode);
@@ -416,7 +418,9 @@
     Structure* activationStructure() const { return m_lexicalEnvironmentStructure.get(); }
     Structure* catchScopeStructure() const { return m_catchScopeStructure.get(); }
     Structure* functionNameScopeStructure() const { return m_functionNameScopeStructure.get(); }
-    Structure* argumentsStructure() const { return m_argumentsStructure.get(); }
+    Structure* directArgumentsStructure() const { return m_directArgumentsStructure.get(); }
+    Structure* scopedArgumentsStructure() const { return m_scopedArgumentsStructure.get(); }
+    Structure* outOfBandArgumentsStructure() const { return m_outOfBandArgumentsStructure.get(); }
     Structure* originalArrayStructureForIndexingType(IndexingType indexingType) const
     {
         ASSERT(indexingType & IsArray);
diff --git a/Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp b/Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp
index 84037a3..5874f23 100644
--- a/Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp
+++ b/Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,7 +29,6 @@
 #include "config.h"
 #include "JSLexicalEnvironment.h"
 
-#include "Arguments.h"
 #include "Interpreter.h"
 #include "JSFunction.h"
 #include "JSCInlines.h"
@@ -40,27 +39,19 @@
 
 const ClassInfo JSLexicalEnvironment::s_info = { "JSLexicalEnvironment", &Base::s_info, 0, CREATE_METHOD_TABLE(JSLexicalEnvironment) };
 
-void JSLexicalEnvironment::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    JSLexicalEnvironment* thisObject = jsCast<JSLexicalEnvironment*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    Base::visitChildren(thisObject, visitor);
-
-    for (int i = 0; i < thisObject->symbolTable()->captureCount(); ++i)
-        visitor.append(&thisObject->storage()[i]);
-}
-
 inline bool JSLexicalEnvironment::symbolTableGet(PropertyName propertyName, PropertySlot& slot)
 {
     SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.uid());
     if (entry.isNull())
         return false;
 
+    ScopeOffset offset = entry.scopeOffset();
+
     // Defend against the inspector asking for a var after it has been optimized out.
-    if (!isValid(entry))
+    if (!isValid(offset))
         return false;
 
-    slot.setValue(this, DontEnum, registerAt(entry.getIndex()).get());
+    slot.setValue(this, DontEnum, variableAt(offset).get());
     return true;
 }
 
@@ -70,11 +61,13 @@
     if (entry.isNull())
         return false;
 
+    ScopeOffset offset = entry.scopeOffset();
+
     // Defend against the inspector asking for a var after it has been optimized out.
-    if (!isValid(entry))
+    if (!isValid(offset))
         return false;
 
-    descriptor.setDescriptor(registerAt(entry.getIndex()).get(), entry.getAttributes());
+    descriptor.setDescriptor(variableAt(offset).get(), entry.getAttributes());
     return true;
 }
 
@@ -95,12 +88,13 @@
                 throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
             return true;
         }
+        ScopeOffset offset = iter->value.scopeOffset();
         // Defend against the inspector asking for a var after it has been optimized out.
-        if (!isValid(iter->value))
+        if (!isValid(offset))
             return false;
         if (VariableWatchpointSet* set = iter->value.watchpointSet())
-            set->invalidate(VariableWriteFireDetail(this, propertyName)); // Don't mess around - if we had found this statically, we would have invcalidated it.
-        reg = &registerAt(iter->value.getIndex());
+            set->invalidate(VariableWriteFireDetail(this, propertyName)); // Don't mess around - if we had found this statically, we would have invalidated it.
+        reg = &variableAt(offset);
     }
     reg->set(vm, this, value);
     return true;
@@ -116,7 +110,7 @@
         for (SymbolTable::Map::iterator it = thisObject->symbolTable()->begin(locker); it != end; ++it) {
             if (it->value.getAttributes() & DontEnum && !shouldIncludeDontEnumProperties(mode))
                 continue;
-            if (!thisObject->isValid(it->value))
+            if (!thisObject->isValid(it->value.scopeOffset()))
                 continue;
             propertyNames.add(Identifier(exec, it->key.get()));
         }
@@ -137,11 +131,13 @@
             return false;
         SymbolTableEntry& entry = iter->value;
         ASSERT(!entry.isNull());
-        if (!isValid(entry))
+        
+        ScopeOffset offset = entry.scopeOffset();
+        if (!isValid(offset))
             return false;
         
         entry.setAttributes(attributes);
-        reg = &registerAt(entry.getIndex());
+        reg = &variableAt(offset);
     }
     reg->set(vm, this, value);
     return true;
diff --git a/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h b/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h
index ba2b808..9ec06c6 100644
--- a/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h
+++ b/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,7 +32,6 @@
 #include "CodeBlock.h"
 #include "CopiedSpaceInlines.h"
 #include "JSEnvironmentRecord.h"
-#include "Nodes.h"
 #include "SymbolTable.h"
 
 namespace JSC {
@@ -41,33 +40,31 @@
     
 class JSLexicalEnvironment : public JSEnvironmentRecord {
 private:
-    JSLexicalEnvironment(VM&, CallFrame*, Register*, JSScope*, CodeBlock*);
+    JSLexicalEnvironment(VM&, Structure*, JSScope*, SymbolTable*);
     
 public:
     typedef JSEnvironmentRecord Base;
 
-    static JSLexicalEnvironment* create(VM& vm, CallFrame* callFrame, Register* registers, JSScope* currentScope, CodeBlock* codeBlock)
+    static JSLexicalEnvironment* create(
+        VM& vm, Structure* structure, JSScope* currentScope, SymbolTable* symbolTable)
     {
-        SymbolTable* symbolTable = codeBlock->symbolTable();
-        ASSERT(codeBlock->codeType() == FunctionCode);
-        JSLexicalEnvironment* lexicalEnvironment = new (
-            NotNull,
-            allocateCell<JSLexicalEnvironment>(
-                vm.heap,
-                allocationSize(symbolTable)
-            )
-        ) JSLexicalEnvironment(vm, callFrame, registers, currentScope, codeBlock);
-        lexicalEnvironment->finishCreation(vm);
-        return lexicalEnvironment;
+        JSLexicalEnvironment* result = 
+            new (
+                NotNull,
+                allocateCell<JSLexicalEnvironment>(vm.heap, allocationSize(symbolTable)))
+            JSLexicalEnvironment(vm, structure, currentScope, symbolTable);
+        result->finishCreation(vm);
+        return result;
     }
-        
+    
     static JSLexicalEnvironment* create(VM& vm, CallFrame* callFrame, JSScope* currentScope, CodeBlock* codeBlock)
     {
-        return create(vm, callFrame, callFrame->registers() + codeBlock->framePointerOffsetToGetActivationRegisters(), currentScope, codeBlock);
+        JSGlobalObject* globalObject = callFrame->lexicalGlobalObject();
+        Structure* structure = globalObject->activationStructure();
+        SymbolTable* symbolTable = codeBlock->symbolTable();
+        return create(vm, structure, currentScope, symbolTable);
     }
-
-    static void visitChildren(JSCell*, SlotVisitor&);
-
+        
     static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
 
@@ -81,12 +78,6 @@
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject) { return Structure::create(vm, globalObject, jsNull(), TypeInfo(ActivationObjectType, StructureFlags), info()); }
 
-    WriteBarrierBase<Unknown>& registerAt(int) const;
-    bool isValidIndex(int) const;
-    bool isValid(const SymbolTableEntry&) const;
-    int registersOffset();
-    static int registersOffset(SymbolTable*);
-
 protected:
     static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags;
 
@@ -96,32 +87,13 @@
     bool symbolTableGet(PropertyName, PropertySlot&, bool& slotIsWriteable);
     bool symbolTablePut(ExecState*, PropertyName, JSValue, bool shouldThrow);
     bool symbolTablePutWithAttributes(VM&, PropertyName, JSValue, unsigned attributes);
-
-    static size_t allocationSize(SymbolTable*);
-    static size_t storageOffset();
-
-    WriteBarrier<Unknown>* storage(); // captureCount() number of registers.
 };
 
-inline JSLexicalEnvironment::JSLexicalEnvironment(VM& vm, CallFrame* callFrame, Register* registers, JSScope* currentScope, CodeBlock* codeBlock)
-    : Base(
-        vm,
-        callFrame->lexicalGlobalObject()->activationStructure(),
-        registers,
-        currentScope,
-        codeBlock->symbolTable())
+inline JSLexicalEnvironment::JSLexicalEnvironment(VM& vm, Structure* structure, JSScope* currentScope, SymbolTable* symbolTable)
+    : Base(vm, structure, currentScope, symbolTable)
 {
-    SymbolTable* symbolTable = codeBlock->symbolTable();
-    WriteBarrier<Unknown>* storage = this->storage();
-    size_t captureCount = symbolTable->captureCount();
-    for (size_t i = 0; i < captureCount; ++i)
-        new (NotNull, &storage[i]) WriteBarrier<Unknown>(UndefinedWriteBarrierTag);
-    m_registers = reinterpret_cast_ptr<WriteBarrierBase<Unknown>*>(
-        reinterpret_cast<char*>(this) + registersOffset(symbolTable));
 }
 
-JSLexicalEnvironment* asActivation(JSValue);
-
 inline JSLexicalEnvironment* asActivation(JSValue value)
 {
     ASSERT(asObject(value)->inherits(JSLexicalEnvironment::info()));
@@ -133,49 +105,6 @@
     return asActivation(jsValue());
 }
 
-inline int JSLexicalEnvironment::registersOffset(SymbolTable* symbolTable)
-{
-    return storageOffset() + ((symbolTable->captureCount() - symbolTable->captureStart()  - 1) * sizeof(WriteBarrier<Unknown>));
-}
-
-inline size_t JSLexicalEnvironment::storageOffset()
-{
-    return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSLexicalEnvironment));
-}
-
-inline WriteBarrier<Unknown>* JSLexicalEnvironment::storage()
-{
-    return reinterpret_cast_ptr<WriteBarrier<Unknown>*>(
-        reinterpret_cast<char*>(this) + storageOffset());
-}
-
-inline size_t JSLexicalEnvironment::allocationSize(SymbolTable* symbolTable)
-{
-    size_t objectSizeInBytes = WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSLexicalEnvironment));
-    size_t storageSizeInBytes = symbolTable->captureCount() * sizeof(WriteBarrier<Unknown>);
-    return objectSizeInBytes + storageSizeInBytes;
-}
-
-inline bool JSLexicalEnvironment::isValidIndex(int index) const
-{
-    if (index > symbolTable()->captureStart())
-        return false;
-    if (index <= symbolTable()->captureEnd())
-        return false;
-    return true;
-}
-
-inline bool JSLexicalEnvironment::isValid(const SymbolTableEntry& entry) const
-{
-    return isValidIndex(entry.getIndex());
-}
-
-inline WriteBarrierBase<Unknown>& JSLexicalEnvironment::registerAt(int index) const
-{
-    ASSERT(isValidIndex(index));
-    return Base::registerAt(index);
-}
-
 } // namespace JSC
 
 #endif // JSLexicalEnvironment_h
diff --git a/Source/JavaScriptCore/runtime/JSNameScope.cpp b/Source/JavaScriptCore/runtime/JSNameScope.cpp
index d092555..d159f69 100644
--- a/Source/JavaScriptCore/runtime/JSNameScope.cpp
+++ b/Source/JavaScriptCore/runtime/JSNameScope.cpp
@@ -47,14 +47,6 @@
     return nullptr;
 }
 
-void JSNameScope::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    JSNameScope* thisObject = jsCast<JSNameScope*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    Base::visitChildren(thisObject, visitor);
-    visitor.append(&thisObject->m_registerStore);
-}
-
 JSValue JSNameScope::toThis(JSCell*, ExecState* exec, ECMAMode ecmaMode)
 {
     if (ecmaMode == StrictMode)
diff --git a/Source/JavaScriptCore/runtime/JSNameScope.h b/Source/JavaScriptCore/runtime/JSNameScope.h
index e0bc16b..c2b6952 100644
--- a/Source/JavaScriptCore/runtime/JSNameScope.h
+++ b/Source/JavaScriptCore/runtime/JSNameScope.h
@@ -44,38 +44,37 @@
     template<typename T>
     static T* create(VM& vm, JSGlobalObject* globalObject, JSScope* currentScope, SymbolTable* symbolTable, JSValue value)
     {
-        T* scopeObject = new (NotNull, allocateCell<T>(vm.heap)) T(vm, globalObject, currentScope, symbolTable);
+        T* scopeObject = new (
+            NotNull, allocateCell<T>(vm.heap, allocationSizeForScopeSize(1)))
+            T(vm, globalObject, currentScope, symbolTable);
         scopeObject->finishCreation(vm, value);
         return scopeObject;
     }
     
     static JSNameScope* create(VM&, JSGlobalObject*, JSScope* currentScope, SymbolTable*, JSValue, Type);
 
-    static void visitChildren(JSCell*, SlotVisitor&);
     static JSValue toThis(JSCell*, ExecState*, ECMAMode);
     static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
 
     DECLARE_INFO;
 
-    JSValue value() const { return m_registerStore.get(); }
+    JSValue value() { return variableAt(ScopeOffset(0)).get(); }
 
 protected:
     void finishCreation(VM& vm, JSValue value)
     {
-        Base::finishCreation(vm);
-        m_registerStore.set(vm, this, value);
+        Base::finishCreationUninitialized(vm);
+        variableAt(ScopeOffset(0)).set(vm, this, value);
     }
 
     static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags;
 
     JSNameScope(VM& vm, Structure* structure, JSScope* next, SymbolTable* symbolTable)
-        : Base(vm, structure, reinterpret_cast<Register*>(&m_registerStore + 1), next, symbolTable)
+        : Base(vm, structure, next, symbolTable)
     {
+        ASSERT(symbolTable->scopeSize() == 1);
     }
-
-private:
-    WriteBarrier<Unknown> m_registerStore;
 };
 
 }
diff --git a/Source/JavaScriptCore/runtime/JSScope.cpp b/Source/JavaScriptCore/runtime/JSScope.cpp
index 300cbef..f3d4645 100644
--- a/Source/JavaScriptCore/runtime/JSScope.cpp
+++ b/Source/JavaScriptCore/runtime/JSScope.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -62,7 +62,7 @@
         }
 
         if (!entry.isNull()) {
-            op = ResolveOp(makeType(ClosureVar, needsVarInjectionChecks), depth, 0, lexicalEnvironment, entry.watchpointSet(), entry.getIndex());
+            op = ResolveOp(makeType(ClosureVar, needsVarInjectionChecks), depth, 0, lexicalEnvironment, entry.watchpointSet(), entry.scopeOffset().offset());
             return true;
         }
 
@@ -82,7 +82,7 @@
 
             op = ResolveOp(
                 makeType(GlobalVar, needsVarInjectionChecks), depth, 0, 0, entry.watchpointSet(),
-                reinterpret_cast<uintptr_t>(globalObject->registerAt(entry.getIndex()).slot()));
+                reinterpret_cast<uintptr_t>(globalObject->variableAt(entry.scopeOffset()).slot()));
             return true;
         }
 
diff --git a/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp b/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp
index 2cb3602..2502fa8 100644
--- a/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,32 +33,30 @@
 
 namespace JSC {
 
-int JSSegmentedVariableObject::findRegisterIndex(void* registerAddress)
+ScopeOffset JSSegmentedVariableObject::findVariableIndex(void* variableAddress)
 {
     ConcurrentJITLocker locker(m_lock);
     
-    for (int i = m_registers.size(); i--;) {
-        if (&m_registers[i] != registerAddress)
+    for (unsigned i = m_variables.size(); i--;) {
+        if (&m_variables[i] != variableAddress)
             continue;
-        return i;
+        return ScopeOffset(i);
     }
     CRASH();
-    return -1;
+    return ScopeOffset();
 }
 
-int JSSegmentedVariableObject::addRegisters(int numberOfRegistersToAdd)
+ScopeOffset JSSegmentedVariableObject::addVariables(unsigned numberOfVariablesToAdd)
 {
     ConcurrentJITLocker locker(m_lock);
     
-    ASSERT(numberOfRegistersToAdd >= 0);
+    size_t oldSize = m_variables.size();
+    m_variables.grow(oldSize + numberOfVariablesToAdd);
     
-    size_t oldSize = m_registers.size();
-    m_registers.grow(oldSize + numberOfRegistersToAdd);
+    for (size_t i = numberOfVariablesToAdd; i--;)
+        m_variables[oldSize + i].setWithoutWriteBarrier(jsUndefined());
     
-    for (size_t i = numberOfRegistersToAdd; i--;)
-        m_registers[oldSize + i].setWithoutWriteBarrier(jsUndefined());
-    
-    return static_cast<int>(oldSize);
+    return ScopeOffset(oldSize);
 }
 
 void JSSegmentedVariableObject::visitChildren(JSCell* cell, SlotVisitor& slotVisitor)
@@ -67,8 +65,8 @@
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
     JSSymbolTableObject::visitChildren(thisObject, slotVisitor);
     
-    for (unsigned i = thisObject->m_registers.size(); i--;)
-        slotVisitor.append(&thisObject->m_registers[i]);
+    for (unsigned i = thisObject->m_variables.size(); i--;)
+        slotVisitor.append(&thisObject->m_variables[i]);
 }
 
 } // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h b/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h
index 4408734..0f03745 100644
--- a/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h
+++ b/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h
@@ -57,24 +57,23 @@
 public:
     typedef JSSymbolTableObject Base;
 
-    WriteBarrier<Unknown>& registerAt(int index) { return m_registers[index]; }
+    WriteBarrier<Unknown>& variableAt(ScopeOffset offset) { return m_variables[offset.offset()]; }
     
     // This is a slow method call, which searches the register bank to find the index
     // given a pointer. It will CRASH() if it does not find the register. Only use this
     // in debug code (like bytecode dumping).
-    JS_EXPORT_PRIVATE int findRegisterIndex(void*);
+    JS_EXPORT_PRIVATE ScopeOffset findVariableIndex(void*);
     
-    WriteBarrier<Unknown>* assertRegisterIsInThisObject(WriteBarrier<Unknown>* registerPointer)
+    WriteBarrier<Unknown>* assertVariableIsInThisObject(WriteBarrier<Unknown>* variablePointer)
     {
-#if !ASSERT_DISABLED
-        findRegisterIndex(registerPointer);
-#endif
-        return registerPointer;
+        if (!ASSERT_DISABLED)
+            findVariableIndex(variablePointer);
+        return variablePointer;
     }
     
     // Adds numberOfRegistersToAdd registers, initializes them to Undefined, and returns
     // the index of the first one added.
-    JS_EXPORT_PRIVATE int addRegisters(int numberOfRegistersToAdd);
+    JS_EXPORT_PRIVATE ScopeOffset addVariables(unsigned numberOfVariablesToAdd);
     
     JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
 
@@ -90,7 +89,7 @@
         m_symbolTable.set(vm, this, SymbolTable::create(vm));
     }
     
-    SegmentedVector<WriteBarrier<Unknown>, 16> m_registers;
+    SegmentedVector<WriteBarrier<Unknown>, 16> m_variables;
     ConcurrentJITLock m_lock;
 };
 
diff --git a/Source/JavaScriptCore/runtime/JSSymbolTableObject.h b/Source/JavaScriptCore/runtime/JSSymbolTableObject.h
index af16176..2685346 100644
--- a/Source/JavaScriptCore/runtime/JSSymbolTableObject.h
+++ b/Source/JavaScriptCore/runtime/JSSymbolTableObject.h
@@ -47,6 +47,8 @@
     JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName);
     JS_EXPORT_PRIVATE static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
     
+    static ptrdiff_t offsetOfSymbolTable() { return OBJECT_OFFSETOF(JSSymbolTableObject, m_symbolTable); }
+    
 protected:
     static const unsigned StructureFlags = IsEnvironmentRecord | OverridesGetPropertyNames | Base::StructureFlags;
     
@@ -78,7 +80,7 @@
         return false;
     SymbolTableEntry::Fast entry = iter->value;
     ASSERT(!entry.isNull());
-    slot.setValue(object, entry.getAttributes() | DontDelete, object->registerAt(entry.getIndex()).get());
+    slot.setValue(object, entry.getAttributes() | DontDelete, object->variableAt(entry.scopeOffset()).get());
     return true;
 }
 
@@ -94,7 +96,7 @@
     SymbolTableEntry::Fast entry = iter->value;
     ASSERT(!entry.isNull());
     descriptor.setDescriptor(
-        object->registerAt(entry.getIndex()).get(), entry.getAttributes() | DontDelete);
+        object->variableAt(entry.scopeOffset()).get(), entry.getAttributes() | DontDelete);
     return true;
 }
 
@@ -110,7 +112,7 @@
         return false;
     SymbolTableEntry::Fast entry = iter->value;
     ASSERT(!entry.isNull());
-    slot.setValue(object, entry.getAttributes() | DontDelete, object->registerAt(entry.getIndex()).get());
+    slot.setValue(object, entry.getAttributes() | DontDelete, object->variableAt(entry.scopeOffset()).get());
     slotIsWriteable = !entry.isReadOnly();
     return true;
 }
@@ -145,7 +147,7 @@
             // https://bugs.webkit.org/show_bug.cgi?id=134601
             set->notifyWrite(vm, value, object, propertyName);
         }
-        reg = &object->registerAt(fastEntry.getIndex());
+        reg = &object->variableAt(fastEntry.scopeOffset());
     }
     // I'd prefer we not hold lock while executing barriers, since I prefer to reserve
     // the right for barriers to be able to trigger GC. And I don't want to hold VM
@@ -173,7 +175,7 @@
         if (VariableWatchpointSet* set = entry.watchpointSet())
             set->notifyWrite(vm, value, object, propertyName);
         entry.setAttributes(attributes);
-        reg = &object->registerAt(entry.getIndex());
+        reg = &object->variableAt(entry.scopeOffset());
     }
     reg->set(vm, object, value);
     return true;
diff --git a/Source/JavaScriptCore/runtime/JSType.h b/Source/JavaScriptCore/runtime/JSType.h
index f86b54c..40326ce 100644
--- a/Source/JavaScriptCore/runtime/JSType.h
+++ b/Source/JavaScriptCore/runtime/JSType.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ *  Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2015 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -58,7 +58,8 @@
     PureForwardingProxyType,
     ImpureProxyType,
     WithScopeType,
-    ArgumentsType,
+    DirectArgumentsType,
+    ScopedArgumentsType,
 
     Int8ArrayType,
     Int16ArrayType,
diff --git a/Source/JavaScriptCore/runtime/Options.h b/Source/JavaScriptCore/runtime/Options.h
index e72bbd9..39af0f8 100644
--- a/Source/JavaScriptCore/runtime/Options.h
+++ b/Source/JavaScriptCore/runtime/Options.h
@@ -125,6 +125,7 @@
     v(optionRange, bytecodeRangeToDFGCompile, 0) \
     v(optionString, dfgFunctionWhitelistFile, nullptr) \
     v(bool, dumpBytecodeAtDFGTime, false) \
+    v(bool, dumpGraphAfterParsing, false) \
     v(bool, dumpGraphAtEachPhase, false) \
     v(bool, verboseDFGByteCodeParsing, false) \
     v(bool, verboseCompilation, false) \
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h b/Source/JavaScriptCore/runtime/ScopeOffset.cpp
similarity index 71%
copy from Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h
copy to Source/JavaScriptCore/runtime/ScopeOffset.cpp
index 25098ca..1753165 100644
--- a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h
+++ b/Source/JavaScriptCore/runtime/ScopeOffset.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,25 +23,20 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#ifndef DFGArgumentsSimplificationPhase_h
-#define DFGArgumentsSimplificationPhase_h
+#include "config.h"
+#include "ScopeOffset.h"
 
-#if ENABLE(DFG_JIT)
+namespace JSC {
 
-namespace JSC { namespace DFG {
+void ScopeOffset::dump(PrintStream& out) const
+{
+    if (!*this) {
+        out.print("scopeInvalid");
+        return;
+    }
+    
+    out.print("scope", offset());
+}
 
-class Graph;
-
-// Simplifies reflective uses of the Arguments object:
-//
-// Inlined arguments.length -> constant
-// Inlined arguments[constant] -> GetLocalUnlinked
-
-bool performArgumentsSimplification(Graph&);
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // DFGArgumentsSimplificationPhase_h
+} // namespace JSC
 
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h b/Source/JavaScriptCore/runtime/ScopeOffset.h
similarity index 69%
copy from Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h
copy to Source/JavaScriptCore/runtime/ScopeOffset.h
index 25098ca..4dbd186 100644
--- a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h
+++ b/Source/JavaScriptCore/runtime/ScopeOffset.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,25 +23,29 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#ifndef DFGArgumentsSimplificationPhase_h
-#define DFGArgumentsSimplificationPhase_h
+#ifndef ScopeOffset_h
+#define ScopeOffset_h
 
-#if ENABLE(DFG_JIT)
+#include "GenericOffset.h"
+#include <wtf/PrintStream.h>
 
-namespace JSC { namespace DFG {
+namespace JSC {
 
-class Graph;
+// This is an offset into a scope of some kind. It could be an activation scope or it could be a
+// global object.
+class ScopeOffset : public GenericOffset<ScopeOffset> {
+public:
+    ScopeOffset() { }
+    
+    explicit ScopeOffset(unsigned offset)
+        : GenericOffset(offset)
+    {
+    }
+    
+    void dump(PrintStream&) const;
+};
 
-// Simplifies reflective uses of the Arguments object:
-//
-// Inlined arguments.length -> constant
-// Inlined arguments[constant] -> GetLocalUnlinked
+} // namespace JSC
 
-bool performArgumentsSimplification(Graph&);
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // DFGArgumentsSimplificationPhase_h
+#endif // ScopeOffset_h
 
diff --git a/Source/JavaScriptCore/runtime/ScopedArguments.cpp b/Source/JavaScriptCore/runtime/ScopedArguments.cpp
new file mode 100644
index 0000000..652048c
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/ScopedArguments.cpp
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "ScopedArguments.h"
+
+#include "GenericArgumentsInlines.h"
+#include "JSArgumentsIterator.h"
+#include "JSCInlines.h"
+
+namespace JSC {
+
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ScopedArguments);
+
+const ClassInfo ScopedArguments::s_info = { "Arguments", &Base::s_info, 0, CREATE_METHOD_TABLE(ScopedArguments) };
+
+ScopedArguments::ScopedArguments(VM& vm, Structure* structure, unsigned totalLength)
+    : GenericArguments(vm, structure)
+    , m_overrodeThings(false)
+    , m_totalLength(totalLength)
+{
+}
+
+void ScopedArguments::finishCreation(VM& vm, JSFunction* callee, ScopedArgumentsTable* table, JSLexicalEnvironment* scope)
+{
+    Base::finishCreation(vm);
+    m_callee.set(vm, this, callee);
+    m_table.set(vm, this, table);
+    m_scope.set(vm, this, scope);
+}
+
+ScopedArguments* ScopedArguments::createUninitialized(VM& vm, Structure* structure, JSFunction* callee, ScopedArgumentsTable* table, JSLexicalEnvironment* scope, unsigned totalLength)
+{
+    unsigned overflowLength;
+    if (totalLength > table->length())
+        overflowLength = totalLength - table->length();
+    else
+        overflowLength = 0;
+    ScopedArguments* result = new (
+        NotNull,
+        allocateCell<ScopedArguments>(vm.heap, allocationSize(overflowLength)))
+        ScopedArguments(vm, structure, totalLength);
+    result->finishCreation(vm, callee, table, scope);
+    return result;
+}
+
+ScopedArguments* ScopedArguments::create(VM& vm, Structure* structure, JSFunction* callee, ScopedArgumentsTable* table, JSLexicalEnvironment* scope, unsigned totalLength)
+{
+    ScopedArguments* result =
+        createUninitialized(vm, structure, callee, table, scope, totalLength);
+
+    unsigned namedLength = table->length();
+    for (unsigned i = namedLength; i < totalLength; ++i)
+        result->overflowStorage()[i - namedLength].clear();
+    
+    return result;
+}
+
+ScopedArguments* ScopedArguments::createByCopying(ExecState* exec, ScopedArgumentsTable* table, JSLexicalEnvironment* scope)
+{
+    return createByCopyingFrom(
+        exec->vm(), exec->lexicalGlobalObject()->scopedArgumentsStructure(),
+        exec->registers() + CallFrame::argumentOffset(0), exec->argumentCount(),
+        jsCast<JSFunction*>(exec->callee()), table, scope);
+}
+
+ScopedArguments* ScopedArguments::createByCopyingFrom(VM& vm, Structure* structure, Register* argumentsStart, unsigned totalLength, JSFunction* callee, ScopedArgumentsTable* table, JSLexicalEnvironment* scope)
+{
+    ScopedArguments* result =
+        createUninitialized(vm, structure, callee, table, scope, totalLength);
+    
+    unsigned namedLength = table->length();
+    for (unsigned i = namedLength; i < totalLength; ++i)
+        result->overflowStorage()[i - namedLength].set(vm, result, argumentsStart[i].jsValue());
+    
+    return result;
+}
+
+void ScopedArguments::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    ScopedArguments* thisObject = static_cast<ScopedArguments*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    Base::visitChildren(thisObject, visitor);
+
+    visitor.append(&thisObject->m_callee);
+    visitor.append(&thisObject->m_table);
+    visitor.append(&thisObject->m_scope);
+    
+    if (thisObject->m_totalLength > thisObject->m_table->length()) {
+        visitor.appendValues(
+            thisObject->overflowStorage(), thisObject->m_totalLength - thisObject->m_table->length());
+    }
+}
+
+Structure* ScopedArguments::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+    return Structure::create(vm, globalObject, prototype, TypeInfo(ScopedArgumentsType, StructureFlags), info());
+}
+
+void ScopedArguments::overrideThings(VM& vm)
+{
+    RELEASE_ASSERT(!m_overrodeThings);
+    
+    putDirect(vm, vm.propertyNames->length, jsNumber(m_table->length()), DontEnum);
+    putDirect(vm, vm.propertyNames->callee, m_callee.get(), DontEnum);
+    
+    m_overrodeThings = true;
+}
+
+void ScopedArguments::overrideThingsIfNecessary(VM& vm)
+{
+    if (!m_overrodeThings)
+        overrideThings(vm);
+}
+
+void ScopedArguments::overrideArgument(VM& vm, uint32_t i)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(i < m_totalLength);
+    unsigned namedLength = m_table->length();
+    if (i < namedLength)
+        m_table.set(vm, this, m_table->set(vm, i, ScopeOffset()));
+    else
+        overflowStorage()[i - namedLength].clear();
+}
+
+void ScopedArguments::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, unsigned offset, unsigned length)
+{
+    GenericArguments::copyToArguments(exec, firstElementDest, offset, length);
+}
+
+} // namespace JSC
+
diff --git a/Source/JavaScriptCore/runtime/ScopedArguments.h b/Source/JavaScriptCore/runtime/ScopedArguments.h
new file mode 100644
index 0000000..e448dc9
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/ScopedArguments.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef ScopedArguments_h
+#define ScopedArguments_h
+
+#include "GenericArguments.h"
+#include "JSLexicalEnvironment.h"
+
+namespace JSC {
+
+// This is an Arguments-class object that we create when you say "arguments" inside a function,
+// and one or more of the arguments may be captured in the function's activation. The function
+// will copy its formally declared arguments into the activation and then create this object. This
+// object will store the overflow arguments, if there are any. This object will use the symbol
+// table's ScopedArgumentsTable and the activation, or its overflow storage, to handle all indexed
+// lookups.
+class ScopedArguments : public GenericArguments<ScopedArguments> {
+private:
+    ScopedArguments(VM&, Structure*, unsigned totalLength);
+    void finishCreation(VM&, JSFunction* callee, ScopedArgumentsTable*, JSLexicalEnvironment*);
+
+public:
+    // Creates an arguments object but leaves it uninitialized. This is dangerous if we GC right
+    // after allocation.
+    static ScopedArguments* createUninitialized(VM&, Structure*, JSFunction* callee, ScopedArgumentsTable*, JSLexicalEnvironment*, unsigned totalLength);
+    
+    // Creates an arguments object and initializes everything to the empty value. Use this if you
+    // cannot guarantee that you'll immediately initialize all of the elements.
+    static ScopedArguments* create(VM&, Structure*, JSFunction* callee, ScopedArgumentsTable*, JSLexicalEnvironment*, unsigned totalLength);
+    
+    // Creates an arguments object by copying the arguments from the stack.
+    static ScopedArguments* createByCopying(ExecState*, ScopedArgumentsTable*, JSLexicalEnvironment*);
+    
+    // Creates an arguments object by copying the arguments from a well-defined stack location.
+    static ScopedArguments* createByCopyingFrom(VM&, Structure*, Register* argumentsStart, unsigned totalLength, JSFunction* callee, ScopedArgumentsTable*, JSLexicalEnvironment*);
+    
+    static void visitChildren(JSCell*, SlotVisitor&);
+    
+    uint32_t internalLength() const
+    {
+        return m_totalLength;
+    }
+    
+    uint32_t length(ExecState* exec) const
+    {
+        if (UNLIKELY(m_overrodeThings))
+            return get(exec, exec->propertyNames().length).toUInt32(exec);
+        return internalLength();
+    }
+    
+    bool canAccessIndexQuickly(uint32_t i) const
+    {
+        if (i >= m_totalLength)
+            return false;
+        unsigned namedLength = m_table->length();
+        if (i < namedLength)
+            return !!m_table->get(i);
+        return !!overflowStorage()[i - namedLength].get();
+    }
+    
+    JSValue getIndexQuickly(uint32_t i) const
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(canAccessIndexQuickly(i));
+        unsigned namedLength = m_table->length();
+        if (i < namedLength)
+            return m_scope->variableAt(m_table->get(i)).get();
+        return overflowStorage()[i - namedLength].get();
+    }
+
+    void setIndexQuickly(VM& vm, uint32_t i, JSValue value)
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(canAccessIndexQuickly(i));
+        unsigned namedLength = m_table->length();
+        if (i < namedLength)
+            m_scope->variableAt(m_table->get(i)).set(vm, this, value);
+        else
+            overflowStorage()[i - namedLength].set(vm, this, value);
+    }
+
+    WriteBarrier<JSFunction>& callee()
+    {
+        return m_callee;
+    }
+    
+    bool overrodeThings() const { return m_overrodeThings; }
+    void overrideThings(VM&);
+    void overrideThingsIfNecessary(VM&);
+    void overrideArgument(VM&, uint32_t index);
+    
+    void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
+
+    DECLARE_INFO;
+    
+    static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
+    
+    static ptrdiff_t offsetOfOverrodeThings() { return OBJECT_OFFSETOF(ScopedArguments, m_overrodeThings); }
+    static ptrdiff_t offsetOfTotalLength() { return OBJECT_OFFSETOF(ScopedArguments, m_totalLength); }
+    static ptrdiff_t offsetOfTable() { return OBJECT_OFFSETOF(ScopedArguments, m_table); }
+    static ptrdiff_t offsetOfScope() { return OBJECT_OFFSETOF(ScopedArguments, m_scope); }
+    
+    static size_t overflowStorageOffset()
+    {
+        return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(ScopedArguments));
+    }
+    
+    static size_t allocationSize(unsigned overflowArgumentsLength)
+    {
+        return overflowStorageOffset() + sizeof(WriteBarrier<Unknown>) * overflowArgumentsLength;
+    }
+
+private:
+    WriteBarrier<Unknown>* overflowStorage() const
+    {
+        return bitwise_cast<WriteBarrier<Unknown>*>(
+            bitwise_cast<char*>(this) + overflowStorageOffset());
+    }
+    
+    
+    bool m_overrodeThings; // True if length, callee, and caller are fully materialized in the object.
+    unsigned m_totalLength; // The length of declared plus overflow arguments.
+    WriteBarrier<JSFunction> m_callee;
+    WriteBarrier<ScopedArgumentsTable> m_table;
+    WriteBarrier<JSLexicalEnvironment> m_scope;
+};
+
+} // namespace JSC
+
+#endif // ScopedArguments_h
+
diff --git a/Source/JavaScriptCore/runtime/ScopedArgumentsTable.cpp b/Source/JavaScriptCore/runtime/ScopedArgumentsTable.cpp
new file mode 100644
index 0000000..9be4797
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/ScopedArgumentsTable.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "ScopedArgumentsTable.h"
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+const ClassInfo ScopedArgumentsTable::s_info = { "ScopedArgumentsTable", 0, 0, CREATE_METHOD_TABLE(ScopedArgumentsTable) };
+
+ScopedArgumentsTable::ScopedArgumentsTable(VM& vm)
+    : Base(vm, vm.scopedArgumentsTableStructure.get())
+    , m_length(0)
+    , m_locked(false)
+{
+}
+
+ScopedArgumentsTable::~ScopedArgumentsTable()
+{
+}
+
+void ScopedArgumentsTable::destroy(JSCell* cell)
+{
+    static_cast<ScopedArgumentsTable*>(cell)->ScopedArgumentsTable::~ScopedArgumentsTable();
+}
+
+ScopedArgumentsTable* ScopedArgumentsTable::create(VM& vm)
+{
+    ScopedArgumentsTable* result =
+        new (NotNull, allocateCell<ScopedArgumentsTable>(vm.heap)) ScopedArgumentsTable(vm);
+    result->finishCreation(vm);
+    return result;
+}
+
+ScopedArgumentsTable* ScopedArgumentsTable::create(VM& vm, uint32_t length)
+{
+    ScopedArgumentsTable* result = create(vm);
+    result->m_length = length;
+    result->m_arguments = std::make_unique<ScopeOffset[]>(length);
+    return result;
+}
+
+ScopedArgumentsTable* ScopedArgumentsTable::clone(VM& vm)
+{
+    ScopedArgumentsTable* result = create(vm, m_length);
+    for (unsigned i = m_length; i--;)
+        result->m_arguments[i] = m_arguments[i];
+    return result;
+}
+
+ScopedArgumentsTable* ScopedArgumentsTable::setLength(VM& vm, uint32_t newLength)
+{
+    if (LIKELY(!m_locked)) {
+        std::unique_ptr<ScopeOffset[]> newArguments = std::make_unique<ScopeOffset[]>(newLength);
+        for (unsigned i = std::min(m_length, newLength); i--;)
+            newArguments[i] = m_arguments[i];
+        m_length = newLength;
+        m_arguments = WTF::move(newArguments);
+        return this;
+    }
+    
+    ScopedArgumentsTable* result = create(vm, newLength);
+    for (unsigned i = std::min(m_length, newLength); i--;)
+        result->m_arguments[i] = m_arguments[i];
+    return result;
+}
+
+ScopedArgumentsTable* ScopedArgumentsTable::set(VM& vm, uint32_t i, ScopeOffset value)
+{
+    ScopedArgumentsTable* result;
+    if (UNLIKELY(m_locked))
+        result = clone(vm);
+    else
+        result = this;
+    result->at(i) = value;
+    return result;
+}
+
+Structure* ScopedArgumentsTable::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+    return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
+}
+
+} // namespace JSC
+
diff --git a/Source/JavaScriptCore/runtime/ScopedArgumentsTable.h b/Source/JavaScriptCore/runtime/ScopedArgumentsTable.h
new file mode 100644
index 0000000..8efd23d
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/ScopedArgumentsTable.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef ScopedArgumentsTable_h
+#define ScopedArgumentsTable_h
+
+#include "JSCell.h"
+#include "ScopeOffset.h"
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+// This class's only job is to hold onto the list of ScopeOffsets for each argument that a
+// function has. Most of the time, the BytecodeGenerator will create one of these and it will
+// never be modified subsequently. There is a rare case where a ScopedArguments object is created
+// and aliases one of these and then decides to modify it; in that case we do copy-on-write. This
+// makes sense because such modifications are so uncommon. You'd have to do something crazy like
+// "delete arguments[i]" or some variant of defineOwnProperty.
+class ScopedArgumentsTable : public JSCell {
+public:
+    typedef JSCell Base;
+    
+private:
+    ScopedArgumentsTable(VM&);
+    ~ScopedArgumentsTable();
+
+public:
+    static ScopedArgumentsTable* create(VM&);
+    static ScopedArgumentsTable* create(VM&, uint32_t length);
+    
+    static const bool needsDestruction = true;
+    static const bool hasImmortalStructure = true;
+    static void destroy(JSCell*);
+
+    ScopedArgumentsTable* clone(VM&);
+    
+    uint32_t length() const { return m_length; }
+    ScopedArgumentsTable* setLength(VM&, uint32_t newLength);
+    
+    ScopeOffset get(uint32_t i) const
+    {
+        return const_cast<ScopedArgumentsTable*>(this)->at(i);
+    }
+    
+    void lock()
+    {
+        m_locked = true;
+    }
+    
+    ScopedArgumentsTable* set(VM&, uint32_t index, ScopeOffset);
+    
+    DECLARE_INFO;
+    
+    static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
+
+    static ptrdiff_t offsetOfLength() { return OBJECT_OFFSETOF(ScopedArgumentsTable, m_length); }
+    static ptrdiff_t offsetOfArguments() { return OBJECT_OFFSETOF(ScopedArgumentsTable, m_arguments); }
+
+private:
+    static const unsigned StructureFlags = StructureIsImmortal | Base::StructureFlags;
+
+    ScopeOffset& at(uint32_t i)
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(i < m_length);
+        return m_arguments[i];
+    }
+    
+    uint32_t m_length;
+    bool m_locked; // Being locked means that there are multiple references to this object and none of them expect to see the others' modifications. This means that modifications need to make a copy first.
+    std::unique_ptr<ScopeOffset[]> m_arguments;
+};
+
+} // namespace JSC
+
+#endif // ScopedArgumentsTable_h
+
diff --git a/Source/JavaScriptCore/runtime/SymbolTable.cpp b/Source/JavaScriptCore/runtime/SymbolTable.cpp
index c40f0d5..3a7e7e8 100644
--- a/Source/JavaScriptCore/runtime/SymbolTable.cpp
+++ b/Source/JavaScriptCore/runtime/SymbolTable.cpp
@@ -69,6 +69,8 @@
 
 void SymbolTableEntry::prepareToWatch(SymbolTable* symbolTable)
 {
+    if (!isWatchable())
+        return;
     FatEntry* entry = inflate();
     if (entry->m_watchpoints)
         return;
@@ -98,10 +100,7 @@
 
 SymbolTable::SymbolTable(VM& vm)
     : JSCell(vm, vm.symbolTableStructure.get())
-    , m_parameterCountIncludingThis(0)
     , m_usesNonStrictEval(false)
-    , m_captureStart(0)
-    , m_captureEnd(0)
     , m_functionEnteredOnce(ClearWatchpoint)
 {
 }
@@ -111,6 +110,9 @@
 void SymbolTable::visitChildren(JSCell* thisCell, SlotVisitor& visitor)
 {
     SymbolTable* thisSymbolTable = jsCast<SymbolTable*>(thisCell);
+    
+    visitor.append(&thisSymbolTable->m_arguments);
+    
     if (!thisSymbolTable->m_watchpointCleanup) {
         thisSymbolTable->m_watchpointCleanup =
             std::make_unique<WatchpointCleanup>(thisSymbolTable);
@@ -146,52 +148,46 @@
     if (UNLIKELY(!m_localToEntry)) {
         unsigned size = 0;
         for (auto& entry : m_map) {
-            VirtualRegister reg(entry.value.getIndex());
-            if (reg.isLocal())
-                size = std::max(size, static_cast<unsigned>(reg.toLocal()) + 1);
+            VarOffset offset = entry.value.varOffset();
+            if (offset.isScope())
+                size = std::max(size, offset.scopeOffset().offset() + 1);
         }
     
         m_localToEntry = std::make_unique<LocalToEntryVec>(size, nullptr);
         for (auto& entry : m_map) {
-            VirtualRegister reg(entry.value.getIndex());
-            if (reg.isLocal())
-                m_localToEntry->at(reg.toLocal()) = &entry.value;
+            VarOffset offset = entry.value.varOffset();
+            if (offset.isScope())
+                m_localToEntry->at(offset.scopeOffset().offset()) = &entry.value;
         }
     }
     
     return *m_localToEntry;
 }
 
-SymbolTableEntry* SymbolTable::entryFor(const ConcurrentJITLocker& locker, VirtualRegister reg)
+SymbolTableEntry* SymbolTable::entryFor(const ConcurrentJITLocker& locker, ScopeOffset offset)
 {
-    if (!reg.isLocal())
-        return nullptr;
-    return localToEntry(locker)[reg.toLocal()];
+    return localToEntry(locker)[offset.offset()];
 }
 
-SymbolTable* SymbolTable::cloneCapturedNames(VM& vm)
+SymbolTable* SymbolTable::cloneScopePart(VM& vm)
 {
     SymbolTable* result = SymbolTable::create(vm);
     
-    result->m_parameterCountIncludingThis = m_parameterCountIncludingThis;
     result->m_usesNonStrictEval = m_usesNonStrictEval;
-    result->m_captureStart = m_captureStart;
-    result->m_captureEnd = m_captureEnd;
 
     for (auto iter = m_map.begin(), end = m_map.end(); iter != end; ++iter) {
-        if (!isCaptured(iter->value.getIndex()))
+        if (!iter->value.varOffset().isScope())
             continue;
         result->m_map.add(
             iter->key,
-            SymbolTableEntry(iter->value.getIndex(), iter->value.getAttributes()));
+            SymbolTableEntry(iter->value.varOffset(), iter->value.getAttributes()));
     }
     
-    if (m_slowArguments) {
-        result->m_slowArguments = std::make_unique<SlowArgument[]>(parameterCount());
-        for (unsigned i = parameterCount(); i--;)
-            result->m_slowArguments[i] = m_slowArguments[i];
-    }
-
+    result->m_maxScopeOffset = m_maxScopeOffset;
+    
+    if (ScopedArgumentsTable* arguments = this->arguments())
+        result->m_arguments.set(vm, result, arguments);
+    
     if (m_typeProfilingRareData) {
         result->m_typeProfilingRareData = std::make_unique<TypeProfilingRareData>();
 
@@ -203,10 +199,10 @@
         }
 
         {
-            auto iter = m_typeProfilingRareData->m_registerToVariableMap.begin();
-            auto end = m_typeProfilingRareData->m_registerToVariableMap.end();
+            auto iter = m_typeProfilingRareData->m_offsetToVariableMap.begin();
+            auto end = m_typeProfilingRareData->m_offsetToVariableMap.end();
             for (; iter != end; ++iter)
-                result->m_typeProfilingRareData->m_registerToVariableMap.set(iter->key, iter->value);
+                result->m_typeProfilingRareData->m_offsetToVariableMap.set(iter->key, iter->value);
         }
 
         {
@@ -229,7 +225,7 @@
 
     for (auto iter = m_map.begin(), end = m_map.end(); iter != end; ++iter) {
         m_typeProfilingRareData->m_uniqueIDMap.set(iter->key, TypeProfilerNeedsUniqueIDGeneration);
-        m_typeProfilingRareData->m_registerToVariableMap.set(iter->value.getIndex(), iter->key);
+        m_typeProfilingRareData->m_offsetToVariableMap.set(iter->value.varOffset(), iter->key);
     }
 }
 
@@ -252,26 +248,26 @@
     return id;
 }
 
-GlobalVariableID SymbolTable::uniqueIDForRegister(const ConcurrentJITLocker& locker, int registerIndex, VM& vm)
+GlobalVariableID SymbolTable::uniqueIDForOffset(const ConcurrentJITLocker& locker, VarOffset offset, VM& vm)
 {
     RELEASE_ASSERT(m_typeProfilingRareData);
 
-    auto iter = m_typeProfilingRareData->m_registerToVariableMap.find(registerIndex);
-    auto end = m_typeProfilingRareData->m_registerToVariableMap.end();
+    auto iter = m_typeProfilingRareData->m_offsetToVariableMap.find(offset);
+    auto end = m_typeProfilingRareData->m_offsetToVariableMap.end();
     if (iter == end)
         return TypeProfilerNoGlobalIDExists;
 
     return uniqueIDForVariable(locker, iter->value.get(), vm);
 }
 
-RefPtr<TypeSet> SymbolTable::globalTypeSetForRegister(const ConcurrentJITLocker& locker, int registerIndex, VM& vm)
+RefPtr<TypeSet> SymbolTable::globalTypeSetForOffset(const ConcurrentJITLocker& locker, VarOffset offset, VM& vm)
 {
     RELEASE_ASSERT(m_typeProfilingRareData);
 
-    uniqueIDForRegister(locker, registerIndex, vm); // Lazily create the TypeSet if necessary.
+    uniqueIDForOffset(locker, offset, vm); // Lazily create the TypeSet if necessary.
 
-    auto iter = m_typeProfilingRareData->m_registerToVariableMap.find(registerIndex);
-    auto end = m_typeProfilingRareData->m_registerToVariableMap.end();
+    auto iter = m_typeProfilingRareData->m_offsetToVariableMap.find(offset);
+    auto end = m_typeProfilingRareData->m_offsetToVariableMap.end();
     if (iter == end)
         return nullptr;
 
diff --git a/Source/JavaScriptCore/runtime/SymbolTable.h b/Source/JavaScriptCore/runtime/SymbolTable.h
index da3a59a..a6a21e7 100644
--- a/Source/JavaScriptCore/runtime/SymbolTable.h
+++ b/Source/JavaScriptCore/runtime/SymbolTable.h
@@ -30,8 +30,11 @@
 #define SymbolTable_h
 
 #include "ConcurrentJITLock.h"
+#include "ConstantMode.h"
 #include "JSObject.h"
+#include "ScopedArgumentsTable.h"
 #include "TypeLocation.h"
+#include "VarOffset.h"
 #include "VariableWatchpointSet.h"
 #include <memory>
 #include <wtf/HashTraits.h>
@@ -39,24 +42,6 @@
 
 namespace JSC {
 
-struct SlowArgument {
-public:
-    enum Status {
-        Normal = 0,
-        Captured = 1,
-        Deleted = 2
-    };
-
-    SlowArgument()
-        : status(Normal)
-        , index(0)
-    {
-    }
-
-    Status status;
-    int index; // If status is 'Deleted', index is bogus.
-};
-
 static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits<int>::max(); }
 
 // The bit twiddling in this class assumes that every register index is a
@@ -86,6 +71,28 @@
 // copy:     SymbolTableEntry --> FatEntry -----^
 
 struct SymbolTableEntry {
+private:
+    static VarOffset varOffsetFromBits(intptr_t bits)
+    {
+        VarKind kind;
+        intptr_t kindBits = bits & KindBitsMask;
+        if (kindBits <= UnwatchableScopeKindBits)
+            kind = VarKind::Scope;
+        else if (kindBits == StackKindBits)
+            kind = VarKind::Stack;
+        else
+            kind = VarKind::DirectArgument;
+        return VarOffset::assemble(kind, static_cast<int>(bits >> FlagBits));
+    }
+    
+    static ScopeOffset scopeOffsetFromBits(intptr_t bits)
+    {
+        ASSERT((bits & KindBitsMask) <= UnwatchableScopeKindBits);
+        return ScopeOffset(static_cast<int>(bits >> FlagBits));
+    }
+
+public:
+    
     // Use the SymbolTableEntry::Fast class, either via implicit cast or by calling
     // getFast(), when you (1) only care about isNull(), getIndex(), and isReadOnly(),
     // and (2) you are in a hot path where you need to minimize the number of times
@@ -107,22 +114,35 @@
             return !(m_bits & ~SlimFlag);
         }
 
-        int getIndex() const
+        VarOffset varOffset() const
         {
-            return static_cast<int>(m_bits >> FlagBits);
+            return varOffsetFromBits(m_bits);
         }
-    
+        
+        // Asserts if the offset is anything but a scope offset. This structures the assertions
+        // in a way that may result in better code, even in release, than doing
+        // varOffset().scopeOffset().
+        ScopeOffset scopeOffset() const
+        {
+            return scopeOffsetFromBits(m_bits);
+        }
+        
         bool isReadOnly() const
         {
             return m_bits & ReadOnlyFlag;
         }
         
+        bool isDontEnum() const
+        {
+            return m_bits & DontEnumFlag;
+        }
+        
         unsigned getAttributes() const
         {
             unsigned attributes = 0;
-            if (m_bits & ReadOnlyFlag)
+            if (isReadOnly())
                 attributes |= ReadOnly;
-            if (m_bits & DontEnumFlag)
+            if (isDontEnum())
                 attributes |= DontEnum;
             return attributes;
         }
@@ -142,18 +162,18 @@
     {
     }
 
-    SymbolTableEntry(int index)
+    SymbolTableEntry(VarOffset offset)
         : m_bits(SlimFlag)
     {
-        ASSERT(isValidIndex(index));
-        pack(index, false, false);
+        ASSERT(isValidVarOffset(offset));
+        pack(offset, true, false, false);
     }
 
-    SymbolTableEntry(int index, unsigned attributes)
+    SymbolTableEntry(VarOffset offset, unsigned attributes)
         : m_bits(SlimFlag)
     {
-        ASSERT(isValidIndex(index));
-        pack(index, attributes & ReadOnly, attributes & DontEnum);
+        ASSERT(isValidVarOffset(offset));
+        pack(offset, true, attributes & ReadOnly, attributes & DontEnum);
     }
     
     ~SymbolTableEntry()
@@ -181,9 +201,22 @@
         return !(bits() & ~SlimFlag);
     }
 
-    int getIndex() const
+    VarOffset varOffset() const
     {
-        return static_cast<int>(bits() >> FlagBits);
+        return varOffsetFromBits(bits());
+    }
+    
+    bool isWatchable() const
+    {
+        return (m_bits & KindBitsMask) == ScopeKindBits;
+    }
+    
+    // Asserts if the offset is anything but a scope offset. This structures the assertions
+    // in a way that may result in better code, even in release, than doing
+    // varOffset().scopeOffset().
+    ScopeOffset scopeOffset() const
+    {
+        return scopeOffsetFromBits(bits());
     }
     
     ALWAYS_INLINE Fast getFast() const
@@ -206,10 +239,10 @@
     {
         return getFast().getAttributes();
     }
-
+    
     void setAttributes(unsigned attributes)
     {
-        pack(getIndex(), attributes & ReadOnly, attributes & DontEnum);
+        pack(varOffset(), isWatchable(), attributes & ReadOnly, attributes & DontEnum);
     }
 
     bool isReadOnly() const
@@ -217,7 +250,23 @@
         return bits() & ReadOnlyFlag;
     }
     
+    ConstantMode constantMode() const
+    {
+        return modeForIsConstant(isReadOnly());
+    }
+    
+    bool isDontEnum() const
+    {
+        return bits() & DontEnumFlag;
+    }
+    
     JSValue inferredValue();
+
+    void disableWatching()
+    {
+        if (varOffset().isScope())
+            pack(varOffset(), false, isReadOnly(), isDontEnum());
+    }
     
     void prepareToWatch(SymbolTable*);
     
@@ -242,7 +291,12 @@
     static const intptr_t ReadOnlyFlag = 0x2;
     static const intptr_t DontEnumFlag = 0x4;
     static const intptr_t NotNullFlag = 0x8;
-    static const intptr_t FlagBits = 4;
+    static const intptr_t KindBitsMask = 0x30;
+    static const intptr_t ScopeKindBits = 0x00;
+    static const intptr_t UnwatchableScopeKindBits = 0x10;
+    static const intptr_t StackKindBits = 0x20;
+    static const intptr_t DirectArgumentKindBits = 0x30;
+    static const intptr_t FlagBits = 6;
     
     class FatEntry {
         WTF_MAKE_FAST_ALLOCATED;
@@ -309,20 +363,38 @@
 
     JS_EXPORT_PRIVATE void freeFatEntrySlow();
 
-    void pack(int index, bool readOnly, bool dontEnum)
+    void pack(VarOffset offset, bool isWatchable, bool readOnly, bool dontEnum)
     {
         ASSERT(!isFat());
         intptr_t& bitsRef = bits();
-        bitsRef = (static_cast<intptr_t>(index) << FlagBits) | NotNullFlag | SlimFlag;
+        bitsRef =
+            (static_cast<intptr_t>(offset.rawOffset()) << FlagBits) | NotNullFlag | SlimFlag;
         if (readOnly)
             bitsRef |= ReadOnlyFlag;
         if (dontEnum)
             bitsRef |= DontEnumFlag;
+        switch (offset.kind()) {
+        case VarKind::Scope:
+            if (isWatchable)
+                bitsRef |= ScopeKindBits;
+            else
+                bitsRef |= UnwatchableScopeKindBits;
+            break;
+        case VarKind::Stack:
+            bitsRef |= StackKindBits;
+            break;
+        case VarKind::DirectArgument:
+            bitsRef |= DirectArgumentKindBits;
+            break;
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+            break;
+        }
     }
     
-    bool isValidIndex(int index)
+    static bool isValidVarOffset(VarOffset offset)
     {
-        return ((static_cast<intptr_t>(index) << FlagBits) >> FlagBits) == static_cast<intptr_t>(index);
+        return ((static_cast<intptr_t>(offset.rawOffset()) << FlagBits) >> FlagBits) == static_cast<intptr_t>(offset.rawOffset());
     }
 
     intptr_t m_bits;
@@ -339,7 +411,7 @@
     typedef HashMap<RefPtr<StringImpl>, SymbolTableEntry, IdentifierRepHash, HashTraits<RefPtr<StringImpl>>, SymbolTableIndexHashTraits> Map;
     typedef HashMap<RefPtr<StringImpl>, GlobalVariableID> UniqueIDMap;
     typedef HashMap<RefPtr<StringImpl>, RefPtr<TypeSet>> UniqueTypeSetMap;
-    typedef HashMap<int, RefPtr<StringImpl>, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int>> RegisterToVariableMap;
+    typedef HashMap<VarOffset, RefPtr<StringImpl>> OffsetToVariableMap;
     typedef Vector<SymbolTableEntry*> LocalToEntryVec;
 
     static SymbolTable* create(VM& vm)
@@ -352,7 +424,7 @@
     static SymbolTable* createNameScopeTable(VM& vm, const Identifier& ident, unsigned attributes)
     {
         SymbolTable* result = create(vm);
-        result->add(ident.impl(), SymbolTableEntry(-1, attributes));
+        result->add(ident.impl(), SymbolTableEntry(VarOffset(ScopeOffset(0)), attributes));
         return result;
     }
     
@@ -424,10 +496,60 @@
         return size(locker);
     }
     
-    Map::AddResult add(const ConcurrentJITLocker&, StringImpl* key, const SymbolTableEntry& entry)
+    ScopeOffset maxScopeOffset() const
+    {
+        return m_maxScopeOffset;
+    }
+    
+    void didUseScopeOffset(ScopeOffset offset)
+    {
+        if (!m_maxScopeOffset || m_maxScopeOffset < offset)
+            m_maxScopeOffset = offset;
+    }
+    
+    void didUseVarOffset(VarOffset offset)
+    {
+        if (offset.isScope())
+            didUseScopeOffset(offset.scopeOffset());
+    }
+    
+    unsigned scopeSize() const
+    {
+        ScopeOffset maxScopeOffset = this->maxScopeOffset();
+        
+        // Do some calculation that relies on invalid scope offset plus one being zero.
+        unsigned fastResult = maxScopeOffset.offsetUnchecked() + 1;
+        
+        // Assert that this works.
+        ASSERT(fastResult == (!maxScopeOffset ? 0 : maxScopeOffset.offset() + 1));
+        
+        return fastResult;
+    }
+    
+    ScopeOffset nextScopeOffset() const
+    {
+        return ScopeOffset(scopeSize());
+    }
+    
+    ScopeOffset takeNextScopeOffset(const ConcurrentJITLocker&)
+    {
+        ScopeOffset result = nextScopeOffset();
+        m_maxScopeOffset = result;
+        return result;
+    }
+    
+    ScopeOffset takeNextScopeOffset()
+    {
+        ConcurrentJITLocker locker(m_lock);
+        return takeNextScopeOffset(locker);
+    }
+    
+    void add(const ConcurrentJITLocker&, StringImpl* key, const SymbolTableEntry& entry)
     {
         RELEASE_ASSERT(!m_localToEntry);
-        return m_map.add(key, entry);
+        didUseVarOffset(entry.varOffset());
+        Map::AddResult result = m_map.add(key, entry);
+        ASSERT_UNUSED(result, result.isNewEntry);
     }
     
     void add(StringImpl* key, const SymbolTableEntry& entry)
@@ -436,10 +558,11 @@
         add(locker, key, entry);
     }
     
-    Map::AddResult set(const ConcurrentJITLocker&, StringImpl* key, const SymbolTableEntry& entry)
+    void set(const ConcurrentJITLocker&, StringImpl* key, const SymbolTableEntry& entry)
     {
         RELEASE_ASSERT(!m_localToEntry);
-        return m_map.set(key, entry);
+        didUseVarOffset(entry.varOffset());
+        m_map.set(key, entry);
     }
     
     void set(StringImpl* key, const SymbolTableEntry& entry)
@@ -459,39 +582,59 @@
         return contains(locker, key);
     }
     
-    const LocalToEntryVec& localToEntry(const ConcurrentJITLocker&);
-    SymbolTableEntry* entryFor(const ConcurrentJITLocker&, VirtualRegister);
+    // The principle behind ScopedArgumentsTable modifications is that we will create one and
+    // leave it unlocked - thereby allowing in-place changes - until someone asks for a pointer to
+    // the table. Then, we will lock it. Then both our future changes and their future changes
+    // will first have to make a copy. This discipline means that usually when we create a
+    // ScopedArguments object, we don't have to make a copy of the ScopedArgumentsTable - instead
+    // we just take a reference to one that we already have.
     
-    GlobalVariableID uniqueIDForVariable(const ConcurrentJITLocker&, StringImpl* key, VM& vm);
-    GlobalVariableID uniqueIDForRegister(const ConcurrentJITLocker& locker, int registerIndex, VM& vm);
-    RefPtr<TypeSet> globalTypeSetForRegister(const ConcurrentJITLocker& locker, int registerIndex, VM& vm);
-    RefPtr<TypeSet> globalTypeSetForVariable(const ConcurrentJITLocker& locker, StringImpl* key, VM& vm);
+    uint32_t argumentsLength() const
+    {
+        if (!m_arguments)
+            return 0;
+        return m_arguments->length();
+    }
+    
+    void setArgumentsLength(VM& vm, uint32_t length)
+    {
+        if (UNLIKELY(!m_arguments))
+            m_arguments.set(vm, this, ScopedArgumentsTable::create(vm));
+        m_arguments.set(vm, this, m_arguments->setLength(vm, length));
+    }
+    
+    ScopeOffset argumentOffset(uint32_t i) const
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(m_arguments);
+        return m_arguments->get(i);
+    }
+    
+    void setArgumentOffset(VM& vm, uint32_t i, ScopeOffset offset)
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(m_arguments);
+        m_arguments.set(vm, this, m_arguments->set(vm, i, offset));
+    }
+    
+    ScopedArgumentsTable* arguments() const
+    {
+        if (!m_arguments)
+            return nullptr;
+        m_arguments->lock();
+        return m_arguments.get();
+    }
+    
+    const LocalToEntryVec& localToEntry(const ConcurrentJITLocker&);
+    SymbolTableEntry* entryFor(const ConcurrentJITLocker&, ScopeOffset);
+    
+    GlobalVariableID uniqueIDForVariable(const ConcurrentJITLocker&, StringImpl* key, VM&);
+    GlobalVariableID uniqueIDForOffset(const ConcurrentJITLocker&, VarOffset, VM&);
+    RefPtr<TypeSet> globalTypeSetForOffset(const ConcurrentJITLocker&, VarOffset, VM&);
+    RefPtr<TypeSet> globalTypeSetForVariable(const ConcurrentJITLocker&, StringImpl* key, VM&);
 
     bool usesNonStrictEval() { return m_usesNonStrictEval; }
     void setUsesNonStrictEval(bool usesNonStrictEval) { m_usesNonStrictEval = usesNonStrictEval; }
 
-    int captureStart() const { return m_captureStart; }
-    void setCaptureStart(int captureStart) { m_captureStart = captureStart; }
-
-    int captureEnd() const { return m_captureEnd; }
-    void setCaptureEnd(int captureEnd) { m_captureEnd = captureEnd; }
-
-    int captureCount() const { return -(m_captureEnd - m_captureStart); }
-    
-    bool isCaptured(int operand)
-    {
-        return operand <= captureStart() && operand > captureEnd();
-    }
-
-    int parameterCount() { return m_parameterCountIncludingThis - 1; }
-    int parameterCountIncludingThis() { return m_parameterCountIncludingThis; }
-    void setParameterCountIncludingThis(int parameterCountIncludingThis) { m_parameterCountIncludingThis = parameterCountIncludingThis; }
-
-    // 0 if we don't capture any arguments; parameterCount() in length if we do.
-    const SlowArgument* slowArguments() { return m_slowArguments.get(); }
-    void setSlowArguments(std::unique_ptr<SlowArgument[]> slowArguments) { m_slowArguments = WTF::move(slowArguments); }
-    
-    SymbolTable* cloneCapturedNames(VM&);
+    SymbolTable* cloneScopePart(VM&);
 
     void prepareForTypeProfiling(const ConcurrentJITLocker&);
 
@@ -519,20 +662,18 @@
     ~SymbolTable();
 
     Map m_map;
+    ScopeOffset m_maxScopeOffset;
+    
     struct TypeProfilingRareData {
         UniqueIDMap m_uniqueIDMap;
-        RegisterToVariableMap m_registerToVariableMap;
+        OffsetToVariableMap m_offsetToVariableMap;
         UniqueTypeSetMap m_uniqueTypeSetMap;
     };
     std::unique_ptr<TypeProfilingRareData> m_typeProfilingRareData;
 
-    int m_parameterCountIncludingThis;
     bool m_usesNonStrictEval;
-
-    int m_captureStart;
-    int m_captureEnd;
-
-    std::unique_ptr<SlowArgument[]> m_slowArguments;
+    
+    WriteBarrier<ScopedArgumentsTable> m_arguments;
     
     std::unique_ptr<WatchpointCleanup> m_watchpointCleanup;
     std::unique_ptr<LocalToEntryVec> m_localToEntry;
diff --git a/Source/JavaScriptCore/runtime/VM.cpp b/Source/JavaScriptCore/runtime/VM.cpp
index 07ea468..3af817d 100644
--- a/Source/JavaScriptCore/runtime/VM.cpp
+++ b/Source/JavaScriptCore/runtime/VM.cpp
@@ -217,6 +217,7 @@
     propertyNameEnumeratorStructure.set(*this, JSPropertyNameEnumerator::createStructure(*this, 0, jsNull()));
     getterSetterStructure.set(*this, GetterSetter::createStructure(*this, 0, jsNull()));
     customGetterSetterStructure.set(*this, CustomGetterSetter::createStructure(*this, 0, jsNull()));
+    scopedArgumentsTableStructure.set(*this, ScopedArgumentsTable::createStructure(*this, 0, jsNull()));
     apiWrapperStructure.set(*this, JSAPIValueWrapper::createStructure(*this, 0, jsNull()));
     JSScopeStructure.set(*this, JSScope::createStructure(*this, 0, jsNull()));
     executableStructure.set(*this, ExecutableBase::createStructure(*this, 0, jsNull()));
diff --git a/Source/JavaScriptCore/runtime/VM.h b/Source/JavaScriptCore/runtime/VM.h
index 7e71def..a46a376 100644
--- a/Source/JavaScriptCore/runtime/VM.h
+++ b/Source/JavaScriptCore/runtime/VM.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -250,6 +250,7 @@
     Strong<Structure> propertyNameEnumeratorStructure;
     Strong<Structure> getterSetterStructure;
     Strong<Structure> customGetterSetterStructure;
+    Strong<Structure> scopedArgumentsTableStructure;
     Strong<Structure> apiWrapperStructure;
     Strong<Structure> JSScopeStructure;
     Strong<Structure> executableStructure;
diff --git a/Source/JavaScriptCore/runtime/VarOffset.cpp b/Source/JavaScriptCore/runtime/VarOffset.cpp
new file mode 100644
index 0000000..e0d65e5
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/VarOffset.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "VarOffset.h"
+
+namespace JSC {
+
+void VarOffset::dump(PrintStream& out) const
+{
+    switch (m_kind) {
+    case VarKind::Invalid:
+        out.print("invalid");
+        return;
+    case VarKind::Scope:
+        out.print(scopeOffset());
+        return;
+    case VarKind::Stack:
+        out.print(stackOffset());
+        return;
+    case VarKind::DirectArgument:
+        out.print(capturedArgumentsOffset());
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace JSC
+
+namespace WTF {
+
+using namespace JSC;
+
+void printInternal(PrintStream& out, VarKind varKind)
+{
+    switch (varKind) {
+    case VarKind::Invalid:
+        out.print("Invalid");
+        return;
+    case VarKind::Scope:
+        out.print("Scope");
+        return;
+    case VarKind::Stack:
+        out.print("Stack");
+        return;
+    case VarKind::DirectArgument:
+        out.print("DirectArgument");
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
diff --git a/Source/JavaScriptCore/runtime/VarOffset.h b/Source/JavaScriptCore/runtime/VarOffset.h
new file mode 100644
index 0000000..b844f57
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/VarOffset.h
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef VarOffset_h
+#define VarOffset_h
+
+#include "DirectArgumentsOffset.h"
+#include "ScopeOffset.h"
+#include "VirtualRegister.h"
+#include <wtf/HashMap.h>
+
+namespace JSC {
+
+enum class VarKind : uint8_t {
+    Invalid,
+    Scope,
+    Stack,
+    DirectArgument
+};
+
+class VarOffset {
+public:
+    VarOffset()
+        : m_kind(VarKind::Invalid)
+        , m_offset(UINT_MAX)
+    {
+    }
+    
+    VarOffset(WTF::HashTableDeletedValueType)
+        : m_kind(VarKind::Invalid)
+        , m_offset(0)
+    {
+    }
+    
+    explicit VarOffset(VirtualRegister stackOffset)
+    {
+        if (!stackOffset.isValid()) {
+            m_kind = VarKind::Invalid;
+            m_offset = UINT_MAX;
+        } else {
+            m_kind = VarKind::Stack;
+            m_offset = stackOffset.offset();
+        }
+    }
+    
+    explicit VarOffset(ScopeOffset scopeOffset)
+    {
+        if (!scopeOffset) {
+            m_kind = VarKind::Invalid;
+            m_offset = UINT_MAX;
+        } else {
+            m_kind = VarKind::Scope;
+            m_offset = scopeOffset.offset();
+        }
+    }
+    
+    explicit VarOffset(DirectArgumentsOffset capturedArgumentsOffset)
+    {
+        if (!capturedArgumentsOffset) {
+            m_kind = VarKind::Invalid;
+            m_offset = UINT_MAX;
+        } else {
+            m_kind = VarKind::DirectArgument;
+            m_offset = capturedArgumentsOffset.offset();
+        }
+    }
+    
+    static VarOffset assemble(VarKind kind, unsigned offset)
+    {
+        VarOffset result;
+        result.m_kind = kind;
+        result.m_offset = offset;
+        result.checkSanity();
+        return result;
+    }
+    
+    bool isValid() const
+    {
+        return m_kind != VarKind::Invalid;
+    }
+    
+    bool operator!() const
+    {
+        return !isValid();
+    }
+    
+    VarKind kind() const { return m_kind; }
+    
+    bool isStack() const
+    {
+        return m_kind == VarKind::Stack;
+    }
+    
+    bool isScope() const
+    {
+        return m_kind == VarKind::Scope;
+    }
+    
+    bool isDirectArgument() const
+    {
+        return m_kind == VarKind::DirectArgument;
+    }
+    
+    VirtualRegister stackOffsetUnchecked() const
+    {
+        if (!isStack())
+            return VirtualRegister();
+        return VirtualRegister(m_offset);
+    }
+    
+    ScopeOffset scopeOffsetUnchecked() const
+    {
+        if (!isScope())
+            return ScopeOffset();
+        return ScopeOffset(m_offset);
+    }
+    
+    DirectArgumentsOffset capturedArgumentsOffsetUnchecked() const
+    {
+        if (!isDirectArgument())
+            return DirectArgumentsOffset();
+        return DirectArgumentsOffset(m_offset);
+    }
+    
+    VirtualRegister stackOffset() const
+    {
+        ASSERT(isStack());
+        return VirtualRegister(m_offset);
+    }
+    
+    ScopeOffset scopeOffset() const
+    {
+        ASSERT(isScope());
+        return ScopeOffset(m_offset);
+    }
+    
+    DirectArgumentsOffset capturedArgumentsOffset() const
+    {
+        ASSERT(isDirectArgument());
+        return DirectArgumentsOffset(m_offset);
+    }
+    
+    unsigned rawOffset() const
+    {
+        ASSERT(isValid());
+        return m_offset;
+    }
+    
+    void checkSanity() const
+    {
+        if (ASSERT_DISABLED)
+            return;
+        
+        switch (m_kind) {
+        case VarKind::Invalid:
+            ASSERT(m_offset == UINT_MAX);
+            return;
+        case VarKind::Scope:
+            ASSERT(scopeOffset());
+            return;
+        case VarKind::Stack:
+            ASSERT(stackOffset().isValid());
+            return;
+        case VarKind::DirectArgument:
+            ASSERT(capturedArgumentsOffset());
+            return;
+        }
+        
+        ASSERT_NOT_REACHED();
+    }
+    
+    bool operator==(const VarOffset& other) const
+    {
+        return m_kind == other.m_kind
+            && m_offset == other.m_offset;
+    }
+    
+    bool operator!=(const VarOffset& other) const
+    {
+        return !(*this == other);
+    }
+    
+    unsigned hash() const
+    {
+        return WTF::IntHash<unsigned>::hash((static_cast<unsigned>(m_kind) << 20) + m_offset);
+    }
+    
+    bool isHashTableDeletedValue() const
+    {
+        return m_kind == VarKind::Invalid && !m_offset;
+    }
+    
+    void dump(PrintStream&) const;
+    
+private:
+    VarKind m_kind;
+    unsigned m_offset;
+};
+
+struct VarOffsetHash {
+    static unsigned hash(const VarOffset& key) { return key.hash(); }
+    static bool equal(const VarOffset& a, const VarOffset& b) { return a == b; }
+    static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} // namespace JSC
+
+namespace WTF {
+
+void printInternal(PrintStream&, JSC::VarKind);
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<JSC::VarOffset> {
+    typedef JSC::VarOffsetHash Hash;
+};
+
+template<typename T> struct HashTraits;
+template<> struct HashTraits<JSC::VarOffset> : SimpleClassHashTraits<JSC::VarOffset> {
+    static const bool emptyValueIsZero = false;
+};
+
+} // namespace WTF
+
+#endif // VarOffset_h
+
diff --git a/Source/JavaScriptCore/tests/stress/arguments-exit-fixed.js b/Source/JavaScriptCore/tests/stress/arguments-exit-fixed.js
new file mode 100644
index 0000000..4d107a8
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/arguments-exit-fixed.js
@@ -0,0 +1,16 @@
+function foo(x) {
+    var tmp = x.f + 1;
+    return tmp + arguments[0].f;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo({f:i});
+    if (result != i + i + 1)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo({f:4.5});
+if (result != 4.5 + 4.5 + 1)
+    throw "Error: bad result at end: " + result;
diff --git a/Source/JavaScriptCore/tests/stress/arguments-exit-strict-mode-fixed.js b/Source/JavaScriptCore/tests/stress/arguments-exit-strict-mode-fixed.js
new file mode 100644
index 0000000..fa816f2
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/arguments-exit-strict-mode-fixed.js
@@ -0,0 +1,18 @@
+"use strict";
+
+function foo(x) {
+    var tmp = x.f + 1;
+    return tmp + arguments[0].f;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo({f:i});
+    if (result != i + i + 1)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo({f:4.5});
+if (result != 4.5 + 4.5 + 1)
+    throw "Error: bad result at end: " + result;
diff --git a/Source/JavaScriptCore/tests/stress/arguments-exit-strict-mode.js b/Source/JavaScriptCore/tests/stress/arguments-exit-strict-mode.js
new file mode 100644
index 0000000..04c714e
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/arguments-exit-strict-mode.js
@@ -0,0 +1,18 @@
+"use strict";
+
+function foo(x) {
+    var tmp = x + 1;
+    return tmp + arguments[0];
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(i);
+    if (result != i + i + 1)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo(4.5);
+if (result != 4.5 + 4.5 + 1)
+    throw "Error: bad result at end: " + result;
diff --git a/Source/JavaScriptCore/tests/stress/arguments-exit.js b/Source/JavaScriptCore/tests/stress/arguments-exit.js
new file mode 100644
index 0000000..8580820
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/arguments-exit.js
@@ -0,0 +1,16 @@
+function foo(x) {
+    var tmp = x + 1;
+    return tmp + arguments[0];
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(i);
+    if (result != i + i + 1)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo(4.5);
+if (result != 4.5 + 4.5 + 1)
+    throw "Error: bad result at end: " + result;
diff --git a/Source/JavaScriptCore/tests/stress/arguments-inlined-exit-strict-mode-fixed.js b/Source/JavaScriptCore/tests/stress/arguments-inlined-exit-strict-mode-fixed.js
new file mode 100644
index 0000000..d08251f
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/arguments-inlined-exit-strict-mode-fixed.js
@@ -0,0 +1,22 @@
+"use strict";
+
+function foo(x) {
+    var tmp = x.f + 1;
+    return tmp + arguments[0].f;
+}
+
+function bar(x) {
+    return foo(x);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = bar({f:i});
+    if (result != i + i + 1)
+        throw "Error: bad result: " + result;
+}
+
+var result = bar({f:4.5});
+if (result != 4.5 + 4.5 + 1)
+    throw "Error: bad result at end: " + result;
diff --git a/Source/JavaScriptCore/tests/stress/arguments-inlined-exit-strict-mode.js b/Source/JavaScriptCore/tests/stress/arguments-inlined-exit-strict-mode.js
new file mode 100644
index 0000000..748251d
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/arguments-inlined-exit-strict-mode.js
@@ -0,0 +1,22 @@
+"use strict";
+
+function foo(x) {
+    var tmp = x + 1;
+    return tmp + arguments[0];
+}
+
+function bar(x) {
+    return foo(x);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = bar(i);
+    if (result != i + i + 1)
+        throw "Error: bad result: " + result;
+}
+
+var result = bar(4.5);
+if (result != 4.5 + 4.5 + 1)
+    throw "Error: bad result at end: " + result;
diff --git a/Source/JavaScriptCore/tests/stress/arguments-inlined-exit.js b/Source/JavaScriptCore/tests/stress/arguments-inlined-exit.js
new file mode 100644
index 0000000..43470d9
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/arguments-inlined-exit.js
@@ -0,0 +1,20 @@
+function foo(x) {
+    var tmp = x + 1;
+    return tmp + arguments[0];
+}
+
+function bar(x) {
+    return foo(x);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = bar(i);
+    if (result != i + i + 1)
+        throw "Error: bad result: " + result;
+}
+
+var result = bar(4.5);
+if (result != 4.5 + 4.5 + 1)
+    throw "Error: bad result at end: " + result;
diff --git a/Source/JavaScriptCore/tests/stress/arguments-interference-cfg.js b/Source/JavaScriptCore/tests/stress/arguments-interference-cfg.js
new file mode 100644
index 0000000..6904160
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/arguments-interference-cfg.js
@@ -0,0 +1,24 @@
+function bar() {
+    return arguments;
+}
+
+function foo(p) {
+    var a = bar(1, 2, 3);
+    var b;
+    if (p)
+        b = bar(4, 5, 6);
+    else
+        b = [7, 8, 9];
+    return (a[0] << 0) + (a[1] << 1) + (a[2] << 2) + (b[0] << 3) + (b[1] << 4) + (b[2] << 5);
+}
+
+noInline(foo);
+
+for (var i = 0; i < 20000; ++i) {
+    var p = i & 1;
+    var q = (!p) * 3;
+    var result = foo(p);
+    if (result != (1 << 0) + (2 << 1) + (3 << 2) + ((4 + q) << 3) + ((5 + q) << 4) + ((6 + q) << 5))
+        throw "Error: bad result: " + result;
+}
+
diff --git a/Source/JavaScriptCore/tests/stress/arguments-interference.js b/Source/JavaScriptCore/tests/stress/arguments-interference.js
new file mode 100644
index 0000000..d66f365
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/arguments-interference.js
@@ -0,0 +1,18 @@
+function bar() {
+    return arguments;
+}
+
+function foo() {
+    var a = bar(1, 2, 3);
+    var b = bar(4, 5, 6);
+    return (a[0] << 0) + (a[1] << 1) + (a[2] << 2) + (b[0] << 3) + (b[1] << 4) + (b[2] << 5);
+}
+
+noInline(foo);
+
+for (var i = 0; i < 20000; ++i) {
+    var result = foo();
+    if (result != (1 << 0) + (2 << 1) + (3 << 2) + (4 << 3) + (5 << 4) + (6 << 5))
+        throw "Error: bad result: " + result;
+}
+
diff --git a/Source/JavaScriptCore/tests/stress/dead-get-closure-var.js b/Source/JavaScriptCore/tests/stress/dead-get-closure-var.js
new file mode 100644
index 0000000..7622fb0
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/dead-get-closure-var.js
@@ -0,0 +1,23 @@
+var global;
+
+function foo(a) {
+    var x = a.f;
+    var f = function() { global = x; };
+    noInline(f);
+    f();
+    var tmp1 = a.g + 1;
+    var tmp2 = x;
+    return global;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo({f:i, g:i + 1});
+    if (result != i)
+        throw "Error: bad result: " + result;
+}
+
+var result = foo({f:42, g:4.2});
+if (result != 42)
+    throw "Error: bad result at end: " + result;
diff --git a/Source/JavaScriptCore/tests/stress/get-declared-unpassed-argument-in-direct-arguments.js b/Source/JavaScriptCore/tests/stress/get-declared-unpassed-argument-in-direct-arguments.js
new file mode 100644
index 0000000..57d380a
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/get-declared-unpassed-argument-in-direct-arguments.js
@@ -0,0 +1,13 @@
+function foo(a) {
+    if (!effectful42())
+        return arguments;
+    return a;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo();
+    if (result !== void 0)
+        throw "Error: bad result: " + result;
+}
diff --git a/Source/JavaScriptCore/tests/stress/get-declared-unpassed-argument-in-scoped-arguments.js b/Source/JavaScriptCore/tests/stress/get-declared-unpassed-argument-in-scoped-arguments.js
new file mode 100644
index 0000000..a85cd95
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/get-declared-unpassed-argument-in-scoped-arguments.js
@@ -0,0 +1,15 @@
+function foo(a) {
+    if (!effectful42()) {
+        (function() { a = 43; })();
+        return arguments;
+    }
+    return a;
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo();
+    if (result !== void 0)
+        throw "Error: bad result: " + result;
+}
diff --git a/Source/JavaScriptCore/tests/stress/varargs-closure-inlined-exit-strict-mode.js b/Source/JavaScriptCore/tests/stress/varargs-closure-inlined-exit-strict-mode.js
new file mode 100644
index 0000000..12759c0
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/varargs-closure-inlined-exit-strict-mode.js
@@ -0,0 +1,26 @@
+"use strict";
+
+function foo(a, b) {
+    return a + b;
+}
+
+function baz(a, b) {
+    function bar() {
+        var a = arguments;
+        var tmp = arguments[0] + 1;
+        return tmp + foo.apply(null, a);
+    }
+    return bar(a, b);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = baz(1, 2);
+    if (result != 1 + 1 + 3)
+        throw "Error: bad result: " + result;
+}
+
+var result = baz(1.5, 2);
+if (result != 1.5 + 1 + 3.5)
+    throw "Error: bad result at end: " + result;
diff --git a/Source/JavaScriptCore/tests/stress/varargs-closure-inlined-exit.js b/Source/JavaScriptCore/tests/stress/varargs-closure-inlined-exit.js
new file mode 100644
index 0000000..2acb4d4
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/varargs-closure-inlined-exit.js
@@ -0,0 +1,24 @@
+function foo(a, b) {
+    return a + b;
+}
+
+function baz(a, b) {
+    function bar() {
+        var a = arguments;
+        var tmp = arguments[0] + 1;
+        return tmp + foo.apply(null, a);
+    }
+    return bar(a, b);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = baz(1, 2);
+    if (result != 1 + 1 + 3)
+        throw "Error: bad result: " + result;
+}
+
+var result = baz(1.5, 2);
+if (result != 1.5 + 1 + 3.5)
+    throw "Error: bad result at end: " + result;
diff --git a/Source/JavaScriptCore/tests/stress/varargs-exit.js b/Source/JavaScriptCore/tests/stress/varargs-exit.js
new file mode 100644
index 0000000..9c9cd09
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/varargs-exit.js
@@ -0,0 +1,21 @@
+function foo(a, b) {
+    return a + b;
+}
+
+function bar() {
+    var a = arguments;
+    var tmp = arguments[0] + 1;
+    return tmp + foo.apply(null, a);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = bar(1, 2);
+    if (result != 1 + 1 + 3)
+        throw "Error: bad result: " + result;
+}
+
+var result = bar(1.5, 2);
+if (result != 1.5 + 1 + 3.5)
+    throw "Error: bad result at end: " + result;
diff --git a/Source/JavaScriptCore/tests/stress/varargs-inlined-exit.js b/Source/JavaScriptCore/tests/stress/varargs-inlined-exit.js
new file mode 100644
index 0000000..de951e1
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/varargs-inlined-exit.js
@@ -0,0 +1,25 @@
+function foo(a, b) {
+    return a + b;
+}
+
+function bar() {
+    var a = arguments;
+    var tmp = arguments[0] + 1;
+    return tmp + foo.apply(null, a);
+}
+
+function baz(a, b) {
+    return bar(a, b);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = baz(1, 2);
+    if (result != 1 + 1 + 3)
+        throw "Error: bad result: " + result;
+}
+
+var result = baz(1.5, 2);
+if (result != 1.5 + 1 + 3.5)
+    throw "Error: bad result at end: " + result;
diff --git a/Source/JavaScriptCore/tests/stress/varargs-inlined-simple-exit-aliasing-weird-reversed-args.js b/Source/JavaScriptCore/tests/stress/varargs-inlined-simple-exit-aliasing-weird-reversed-args.js
new file mode 100644
index 0000000..f1fbee1
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/varargs-inlined-simple-exit-aliasing-weird-reversed-args.js
@@ -0,0 +1,42 @@
+function foo(a, b) {
+    return a + b;
+}
+
+function verify(a, b) {
+    if (a !== b)
+        throw "Error: the two arguments objects aren't identical.";
+}
+
+noInline(verify);
+
+function bar() {
+    var a = arguments;
+    this.verify(arguments, a);
+    return foo.apply(null, a);
+}
+
+function baz(a, b) {
+    return this.bar(a + 1, b + 1);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 20000; ++i) {
+    var o = {
+        baz: baz,
+        bar: bar,
+        verify: function() { }
+    };
+    var result = o.baz(1, 2);
+    if (result != 1 + 1 + 2 + 1)
+        throw "Error: bad result: " + result;
+}
+
+var o = {
+    baz: baz,
+    bar: bar,
+    verify: verify
+};
+var result = o.baz(1, 2);
+if (result != 1 + 1 + 2 + 1)
+    throw "Error: bad result at end: " + result;
diff --git a/Source/JavaScriptCore/tests/stress/varargs-inlined-simple-exit-aliasing-weird.js b/Source/JavaScriptCore/tests/stress/varargs-inlined-simple-exit-aliasing-weird.js
new file mode 100644
index 0000000..04a6d4b
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/varargs-inlined-simple-exit-aliasing-weird.js
@@ -0,0 +1,42 @@
+function foo(a, b) {
+    return a + b;
+}
+
+function verify(a, b) {
+    if (a !== b)
+        throw "Error: the two arguments objects aren't identical.";
+}
+
+noInline(verify);
+
+function bar() {
+    var a = arguments;
+    this.verify(arguments, a);
+    return foo.apply(null, a);
+}
+
+function baz(a, b) {
+    return this.bar(a, b);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 20000; ++i) {
+    var o = {
+        baz: baz,
+        bar: bar,
+        verify: function() { }
+    };
+    var result = o.baz(1, 2);
+    if (result != 1 + 2)
+        throw "Error: bad result: " + result;
+}
+
+var o = {
+    baz: baz,
+    bar: bar,
+    verify: verify
+};
+var result = o.baz(1, 2);
+if (result != 1 + 2)
+    throw "Error: bad result at end: " + result;
diff --git a/Source/JavaScriptCore/tests/stress/varargs-inlined-simple-exit-aliasing.js b/Source/JavaScriptCore/tests/stress/varargs-inlined-simple-exit-aliasing.js
new file mode 100644
index 0000000..23890d1
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/varargs-inlined-simple-exit-aliasing.js
@@ -0,0 +1,41 @@
+function foo(a, b) {
+    return a + b;
+}
+
+function verify(a, b) {
+    if (a !== b)
+        throw "Error: the two arguments objects aren't identical.";
+    if (a[0] !== 42)
+        throw "Error: the first argument isn't 42 (a).";
+    if (b[0] !== 42)
+        throw "Error: the first argument isn't 42 (b).";
+}
+
+noInline(verify);
+
+var global = false;
+function bar(x) {
+    var a = arguments;
+    if (global) {
+        x = 42;
+        verify(arguments, a);
+    }
+    return foo.apply(null, a);
+}
+
+function baz(a, b) {
+    return bar(a, b);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = baz(1, 2);
+    if (result != 1 + 2)
+        throw "Error: bad result: " + result;
+}
+
+global = true;
+var result = baz(1, 2);
+if (result != 42 + 2)
+    throw "Error: bad result at end: " + result;
diff --git a/Source/JavaScriptCore/tests/stress/varargs-inlined-simple-exit.js b/Source/JavaScriptCore/tests/stress/varargs-inlined-simple-exit.js
new file mode 100644
index 0000000..c841e9c
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/varargs-inlined-simple-exit.js
@@ -0,0 +1,28 @@
+function foo(a, b) {
+    return a + b;
+}
+
+var global;
+function bar() {
+    var a = arguments;
+    var tmp = global + 1;
+    return tmp + foo.apply(null, a);
+}
+
+function baz(a, b) {
+    return bar(a, b);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    global = i;
+    var result = baz(1, 2);
+    if (result != i + 1 + 1 + 2)
+        throw "Error: bad result: " + result;
+}
+
+global = 1.5;
+var result = baz(1, 2);
+if (result != 1.5 + 1 + 1 + 2)
+    throw "Error: bad result at end: " + result;
diff --git a/Source/JavaScriptCore/tests/stress/varargs-too-few-arguments.js b/Source/JavaScriptCore/tests/stress/varargs-too-few-arguments.js
new file mode 100644
index 0000000..36c062a
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/varargs-too-few-arguments.js
@@ -0,0 +1,16 @@
+function foo(a, b) {
+    return [a, b];
+}
+
+function bar() {
+    return foo.apply(null, arguments);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = bar(1);
+    if ("" + result != "1,")
+        throw "Error: bad result: " + result;
+}
+
diff --git a/Source/JavaScriptCore/tests/stress/varargs-varargs-closure-inlined-exit.js b/Source/JavaScriptCore/tests/stress/varargs-varargs-closure-inlined-exit.js
new file mode 100644
index 0000000..b7b2d4c
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/varargs-varargs-closure-inlined-exit.js
@@ -0,0 +1,24 @@
+function foo(a, b) {
+    return a + b;
+}
+
+function baz() {
+    function bar() {
+        var a = arguments;
+        var tmp = arguments[0] + 1;
+        return tmp + foo.apply(null, a);
+    }
+    return bar.apply(null, arguments);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = baz(1, 2);
+    if (result != 1 + 1 + 3)
+        throw "Error: bad result: " + result;
+}
+
+var result = baz(1.5, 2);
+if (result != 1.5 + 1 + 3.5)
+    throw "Error: bad result at end: " + result;
diff --git a/Source/JavaScriptCore/tests/stress/varargs-varargs-inlined-exit-strict-mode.js b/Source/JavaScriptCore/tests/stress/varargs-varargs-inlined-exit-strict-mode.js
new file mode 100644
index 0000000..139d75d
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/varargs-varargs-inlined-exit-strict-mode.js
@@ -0,0 +1,27 @@
+"use strict";
+
+function foo(a, b) {
+    return a + b;
+}
+
+function bar() {
+    var a = arguments;
+    var tmp = arguments[0] + 1;
+    return tmp + foo.apply(null, a);
+}
+
+function baz() {
+    return bar.apply(this, arguments);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = baz(1, 2);
+    if (result != 1 + 1 + 3)
+        throw "Error: bad result: " + result;
+}
+
+var result = baz(1.5, 2);
+if (result != 1.5 + 1 + 3.5)
+    throw "Error: bad result at end: " + result;
diff --git a/Source/JavaScriptCore/tests/stress/varargs-varargs-inlined-exit.js b/Source/JavaScriptCore/tests/stress/varargs-varargs-inlined-exit.js
new file mode 100644
index 0000000..7a243cb
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/varargs-varargs-inlined-exit.js
@@ -0,0 +1,25 @@
+function foo(a, b) {
+    return a + b;
+}
+
+function bar() {
+    var a = arguments;
+    var tmp = arguments[0] + 1;
+    return tmp + foo.apply(null, a);
+}
+
+function baz() {
+    return bar.apply(this, arguments);
+}
+
+noInline(baz);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = baz(1, 2);
+    if (result != 1 + 1 + 3)
+        throw "Error: bad result: " + result;
+}
+
+var result = baz(1.5, 2);
+if (result != 1.5 + 1 + 3.5)
+    throw "Error: bad result at end: " + result;
diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog
index f332bf9..63d09a1 100644
--- a/Source/WTF/ChangeLog
+++ b/Source/WTF/ChangeLog
@@ -1,5 +1,15 @@
 2015-03-25  Filip Pizlo  <fpizlo@apple.com>
 
+        Heap variables shouldn't end up in the stack frame
+        https://bugs.webkit.org/show_bug.cgi?id=141174
+
+        Reviewed by Geoffrey Garen.
+
+        * wtf/FastBitVector.h:
+        (WTF::FastBitVector::resize): Small change: don't resize if you don't have to resize.
+
+2015-03-25  Filip Pizlo  <fpizlo@apple.com>
+
         Change Atomic methods from using the_wrong_naming_conventions to using theRightNamingConventions. Also make seq_cst the default.
 
         Rubber stamped by Geoffrey Garen.
diff --git a/Source/WTF/wtf/FastBitVector.h b/Source/WTF/wtf/FastBitVector.h
index 15c0a55..9f188bc 100644
--- a/Source/WTF/wtf/FastBitVector.h
+++ b/Source/WTF/wtf/FastBitVector.h
@@ -71,6 +71,9 @@
     
     void resize(size_t numBits)
     {
+        if (numBits == m_numBits)
+            return;
+        
         // Use fastCalloc instead of fastRealloc because we expect the common
         // use case for this method to be initializing the size of the bitvector.