Changeset 181993 in webkit


Ignore:
Timestamp:
Mar 25, 2015, 9:28:43 PM (10 years ago)
Author:
fpizlo@apple.com
Message:

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:
Location:
trunk
Files:
88 added
4 deleted
181 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r181988 r181993  
     12015-03-25  Filip Pizlo  <fpizlo@apple.com>
     2
     3        Heap variables shouldn't end up in the stack frame
     4        https://bugs.webkit.org/show_bug.cgi?id=141174
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        * js/function-apply-aliased-expected.txt:
     9        * js/function-dot-arguments-expected.txt:
     10        * js/regress/arguments-expected.txt: Added.
     11        * js/regress/arguments-named-and-reflective-expected.txt: Added.
     12        * js/regress/arguments-named-and-reflective.html: Added.
     13        * js/regress/arguments-strict-mode-expected.txt: Added.
     14        * js/regress/arguments-strict-mode.html: Added.
     15        * js/regress/arguments.html: Added.
     16        * js/regress/script-tests/arguments-named-and-reflective.js: Added.
     17        * js/regress/script-tests/arguments-strict-mode.js: Added.
     18        * js/regress/script-tests/arguments.js: Added.
     19        * js/regress/script-tests/try-catch-get-by-val-cloned-arguments.js: Added.
     20        * js/regress/script-tests/try-catch-get-by-val-direct-arguments.js: Added.
     21        * js/regress/script-tests/try-catch-get-by-val-scoped-arguments.js: Added.
     22        * js/regress/script-tests/varargs-call.js: Added.
     23        * js/regress/script-tests/varargs-construct-inline.js: Added.
     24        * js/regress/script-tests/varargs-construct.js: Added.
     25        * js/regress/script-tests/varargs-inline.js: Added.
     26        * js/regress/script-tests/varargs-strict-mode.js: Added.
     27        * js/regress/script-tests/varargs.js: Added.
     28        * js/regress/try-catch-get-by-val-cloned-arguments-expected.txt: Added.
     29        * js/regress/try-catch-get-by-val-cloned-arguments.html: Added.
     30        * js/regress/try-catch-get-by-val-direct-arguments-expected.txt: Added.
     31        * js/regress/try-catch-get-by-val-direct-arguments.html: Added.
     32        * js/regress/try-catch-get-by-val-scoped-arguments-expected.txt: Added.
     33        * js/regress/try-catch-get-by-val-scoped-arguments.html: Added.
     34        * js/regress/varargs-call-expected.txt: Added.
     35        * js/regress/varargs-call.html: Added.
     36        * js/regress/varargs-construct-expected.txt: Added.
     37        * js/regress/varargs-construct-inline-expected.txt: Added.
     38        * js/regress/varargs-construct-inline.html: Added.
     39        * js/regress/varargs-construct.html: Added.
     40        * js/regress/varargs-expected.txt: Added.
     41        * js/regress/varargs-inline-expected.txt: Added.
     42        * js/regress/varargs-inline.html: Added.
     43        * js/regress/varargs-strict-mode-expected.txt: Added.
     44        * js/regress/varargs-strict-mode.html: Added.
     45        * js/regress/varargs.html: Added.
     46        * js/script-tests/function-apply-aliased.js:
     47        * js/script-tests/function-dot-arguments.js:
     48
    1492015-03-25  Chris Fleizach  <cfleizach@apple.com>
    250
  • trunk/LayoutTests/js/function-apply-aliased-expected.txt

    r42337 r181993  
    2323PASS forwarder(myFunctionWithApply, myObject, arg1Array) is [myFunctionWithApply, "myFunctionWithApply.apply", myObject]
    2424PASS myFunctionWithApply.aliasedApply(myObject, arg1Array) is [myObject, "myFunctionWithApply", "arg1"]
     25PASS throw 42 threw exception 42.
    2526PASS myFunction.apply(null, new Array(5000000)) threw exception RangeError: Maximum call stack size exceeded..
    2627PASS myFunction.apply(null, new Array(1 << 30)) threw exception RangeError: Maximum call stack size exceeded..
  • trunk/LayoutTests/js/function-dot-arguments-expected.txt

    r178517 r181993  
    3333PASS tearOffTest4b(1, 2, 3, false) is [1, 2, 3, false]
    3434PASS tearOffTest4c(1, 2, 3, false) is [1, 2, 3, false]
    35 PASS tearOffTest5(1, 2, 3, false) is [10, 2, 3, false]
    36 PASS tearOffTest5a(1, 2, 3, false) is [10, 2, 3, false]
     35PASS tearOffTest5(1, 2, 3, false) is [1, 2, 3, false]
     36PASS tearOffTest5a(1, 2, 3, false) is [1, 2, 3, false]
    3737PASS tearOffTest5b(1, 2, 3, false) is [1, 2, 3, false]
    3838PASS tearOffTest5c(1, 2, 3, false) is [1, 2, 3, false]
    39 PASS tearOffTest6(1, 2, 3, false) is [10, 2, 3, false]
    40 PASS tearOffTest6a(1, 2, 3, false) is [10, 2, 3, false]
     39PASS tearOffTest6(1, 2, 3, false) is [1, 2, 3, false]
     40PASS tearOffTest6a(1, 2, 3, false) is [1, 2, 3, false]
    4141PASS tearOffTest6b(1, 2, 3, false) is [1, 2, 3, false]
    4242PASS tearOffTest6c(1, 2, 3, false) is [1, 2, 3, false]
     
    5757PASS tearOffTest10b(1, 2, 3, false) is [undefined, 2, 3, false]
    5858PASS tearOffTest10c(1, 2, 3, false) is [undefined, 2, 3, false]
    59 PASS lexicalArgumentsLiveRead1(0, 2, 3) is 1
    60 PASS lexicalArgumentsLiveRead2(1, 0, 3) is 2
    61 PASS lexicalArgumentsLiveRead3(1, 2, 0) is 3
     59PASS lexicalArgumentsLiveRead1(0, 2, 3) is 0
     60PASS lexicalArgumentsLiveRead2(1, 0, 3) is 0
     61PASS lexicalArgumentsLiveRead3(1, 2, 0) is 0
    6262PASS lexicalArgumentsLiveWrite1(0, 2, 3) is 0
    6363PASS lexicalArgumentsLiveWrite2(1, 0, 3) is 0
  • trunk/LayoutTests/js/script-tests/function-apply-aliased.js

    r98407 r181993  
    4545shouldBe("myFunctionWithApply.aliasedApply(myObject, arg1Array)", '[myObject, "myFunctionWithApply", "arg1"]');
    4646
     47// Let's make sure that shouldThrow() is compiled before we do crazy.
     48shouldThrow("throw 42");
     49
    4750function stackOverflowTest() {
    4851    try {
  • trunk/LayoutTests/js/script-tests/function-dot-arguments.js

    r178517 r181993  
    363363    return arrayify(inner());
    364364}
    365 shouldBe("tearOffTest5(1, 2, 3, false)", "[10, 2, 3, false]");
     365shouldBe("tearOffTest5(1, 2, 3, false)", "[1, 2, 3, false]");
    366366
    367367
     
    383383    }
    384384}
    385 shouldBe("tearOffTest5a(1, 2, 3, false)", "[10, 2, 3, false]");
     385shouldBe("tearOffTest5a(1, 2, 3, false)", "[1, 2, 3, false]");
    386386
    387387
     
    427427    return arrayify(tearOffTest6External());
    428428}
    429 shouldBe("tearOffTest6(1, 2, 3, false)", "[10, 2, 3, false]");
     429shouldBe("tearOffTest6(1, 2, 3, false)", "[1, 2, 3, false]");
    430430
    431431
     
    447447    }
    448448}
    449 shouldBe("tearOffTest6a(1, 2, 3, false)", "[10, 2, 3, false]");
     449shouldBe("tearOffTest6a(1, 2, 3, false)", "[1, 2, 3, false]");
    450450
    451451
     
    740740    return lexicalArgumentsLiveRead1.arguments[0];
    741741}
    742 shouldBe("lexicalArgumentsLiveRead1(0, 2, 3)", "1");
     742shouldBe("lexicalArgumentsLiveRead1(0, 2, 3)", "0");
    743743
    744744function lexicalArgumentsLiveRead2(a, b, c)
     
    748748    return lexicalArgumentsLiveRead2.arguments[1];
    749749}
    750 shouldBe("lexicalArgumentsLiveRead2(1, 0, 3)", "2");
     750shouldBe("lexicalArgumentsLiveRead2(1, 0, 3)", "0");
    751751
    752752function lexicalArgumentsLiveRead3(a, b, c)
     
    756756    return lexicalArgumentsLiveRead3.arguments[2];
    757757}
    758 shouldBe("lexicalArgumentsLiveRead3(1, 2, 0)", "3");
     758shouldBe("lexicalArgumentsLiveRead3(1, 2, 0)", "0");
    759759
    760760function lexicalArgumentsLiveWrite1(a, b, c)
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r181990 r181993  
    119119    dfg/DFGAbstractHeap.cpp
    120120    dfg/DFGAbstractValue.cpp
    121     dfg/DFGArgumentsSimplificationPhase.cpp
    122121    dfg/DFGArithMode.cpp
     122    dfg/DFGArgumentsEliminationPhase.cpp
     123    dfg/DFGArgumentsUtilities.cpp
    123124    dfg/DFGArrayMode.cpp
    124125    dfg/DFGAtTailAbstractState.cpp
     
    233234    dfg/DFGValueSource.cpp
    234235    dfg/DFGValueStrength.cpp
     236    dfg/DFGVarargsForwardingPhase.cpp
    235237    dfg/DFGVariableAccessData.cpp
    236238    dfg/DFGVariableAccessDataDump.cpp
     
    399401set(JavaScriptCore_RUNTIME_SOURCES
    400402    runtime/ArgList.cpp
    401     runtime/Arguments.cpp
    402403    runtime/ArgumentsIteratorConstructor.cpp
    403404    runtime/ArgumentsIteratorPrototype.cpp
     
    415416    runtime/BundlePath.cpp
    416417    runtime/CallData.cpp
     418    runtime/ClonedArguments.cpp
    417419    runtime/CodeCache.cpp
    418420    runtime/CodeSpecializationKind.cpp
     
    424426    runtime/ConsoleClient.cpp
    425427    runtime/ConsolePrototype.cpp
     428    runtime/ConstantMode.cpp
    426429    runtime/ConstructData.cpp
    427430    runtime/ControlFlowProfiler.cpp
     
    432435    runtime/DateInstance.cpp
    433436    runtime/DatePrototype.cpp
     437    runtime/DirectArguments.cpp
     438    runtime/DirectArgumentsOffset.cpp
    434439    runtime/DumpContext.cpp
    435440    runtime/Error.cpp
     
    539544    runtime/RuntimeType.cpp
    540545    runtime/SamplingCounter.cpp
     546    runtime/ScopeOffset.cpp
     547    runtime/ScopedArguments.cpp
     548    runtime/ScopedArgumentsTable.cpp
    541549    runtime/SetConstructor.cpp
    542550    runtime/SetIteratorConstructor.cpp
     
    571579    runtime/VM.cpp
    572580    runtime/VMEntryScope.cpp
     581    runtime/VarOffset.cpp
    573582    runtime/Watchdog.cpp
    574583    runtime/WatchdogNone.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r181992 r181993  
     12015-03-25  Filip Pizlo  <fpizlo@apple.com>
     2
     3        Heap variables shouldn't end up in the stack frame
     4        https://bugs.webkit.org/show_bug.cgi?id=141174
     5
     6        Reviewed by Geoffrey Garen.
     7       
     8        This is a major change to how JavaScriptCore handles declared variables (i.e. "var"). It removes
     9        any ambiguity about whether a variable should be in the heap or on the stack. A variable will no
     10        longer move between heap and stack during its lifetime. This enables a bunch of optimizations and
     11        simplifications:
     12       
     13        - Accesses to variables no longer need checks or indirections to determine where the variable is
     14          at that moment in time. For example, loading a closure variable now takes just one load instead
     15          of two. Loading an argument by index now takes a bounds check and a load in the fastest case
     16          (when no arguments object allocation is required) while previously that same operation required
     17          a "did I allocate arguments yet" check, a bounds check, and then the load.
     18       
     19        - Reasoning about the allocation of an activation or arguments object now follows the same simple
     20          logic as the allocation of any other kind of object. Previously, those objects were lazily
     21          allocated - so an allocation instruction wasn't the actual allocation site, since it might not
     22          allocate anything at all. This made the implementation of traditional escape analyses really
     23          awkward, and ultimately it meant that we missed important cases. Now, we can reason about the
     24          arguments object using the usual SSA tricks which allows for more comprehensive removal.
     25       
     26        - The allocations of arguments objects, functions, and activations are now much faster. While
     27          this patch generally expands our ability to eliminate arguments object allocations, an earlier
     28          version of the patch - which lacked that functionality - was a progression on some arguments-
     29          and closure-happy benchmarks because although no allocations were eliminated, all allocations
     30          were faster.
     31       
     32        - There is no tear-off. The runtime no loner needs to know about where on the stack a frame keeps
     33          its arguments objects or activations. The runtime doesn't have to do things to the arguments
     34          objects and activations that a frame allocated, when the frame is unwound. We always had horrid
     35          bugs in that code, so it's good to see it go. This removes *a ton* of machinery from the DFG,
     36          FTL, CodeBlock, and other places. All of the things having to do with "captured variables" is
     37          now gone. This also enables implementing block-scoping. Without this change, block-scope
     38          support would require telling CodeBlock and all of the rest of the runtime about all of the
     39          variables that store currently-live scopes. That would have been so disastrously hard that it
     40          might as well be impossible. With this change, it's fair game for the bytecode generator to
     41          simply allocate whatever activations it wants, wherever it wants, and to keep them live for
     42          however long it wants. This all works, because after bytecode generation, an activation is just
     43          an object and variables that refer to it are just normal variables.
     44       
     45        - SymbolTable can now tell you explicitly where a variable lives. The answer is in the form of a
     46          VarOffset object, which has methods like isStack(), isScope(), etc. VirtualRegister is never
     47          used for offsets of non-stack variables anymore. We now have shiny new objects for other kinds
     48          of offsets - ScopeOffset for offsets into scopes, and DirectArgumentsOffset for offsets into
     49          an arguments object.
     50       
     51        - Functions that create activations can now tier-up into the FTL. Previously they couldn't. Also,
     52          using activations used to prevent inlining; now functions that use activations can be inlined
     53          just fine.
     54       
     55        This is a >1% speed-up on Octane. This is a >2% speed-up on CompressionBench. This is a tiny
     56        speed-up on AsmBench (~0.4% or something). This looks like it might be a speed-up on SunSpider.
     57        It's only a slow-down on very short-running microbenchmarks we had previously written for our old
     58        style of tear-off-based arguments optimization. Those benchmarks are not part of any major suite.
     59       
     60        The easiest way of understanding this change is to start by looking at the changes in runtime/,
     61        and then the changes in bytecompiler/, and then sort of work your way up the compiler tiers.
     62
     63        * CMakeLists.txt:
     64        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
     65        * JavaScriptCore.xcodeproj/project.pbxproj:
     66        * assembler/AbortReason.h:
     67        * assembler/AbstractMacroAssembler.h:
     68        (JSC::AbstractMacroAssembler::BaseIndex::withOffset):
     69        * bytecode/ByValInfo.h:
     70        (JSC::hasOptimizableIndexingForJSType):
     71        (JSC::hasOptimizableIndexing):
     72        (JSC::jitArrayModeForJSType):
     73        (JSC::jitArrayModePermitsPut):
     74        (JSC::jitArrayModeForStructure):
     75        * bytecode/BytecodeKills.h: Added.
     76        (JSC::BytecodeKills::BytecodeKills):
     77        (JSC::BytecodeKills::operandIsKilled):
     78        (JSC::BytecodeKills::forEachOperandKilledAt):
     79        (JSC::BytecodeKills::KillSet::KillSet):
     80        (JSC::BytecodeKills::KillSet::add):
     81        (JSC::BytecodeKills::KillSet::forEachLocal):
     82        (JSC::BytecodeKills::KillSet::contains):
     83        * bytecode/BytecodeList.json:
     84        * bytecode/BytecodeLivenessAnalysis.cpp:
     85        (JSC::isValidRegisterForLiveness):
     86        (JSC::stepOverInstruction):
     87        (JSC::BytecodeLivenessAnalysis::runLivenessFixpoint):
     88        (JSC::BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset):
     89        (JSC::BytecodeLivenessAnalysis::operandIsLiveAtBytecodeOffset):
     90        (JSC::BytecodeLivenessAnalysis::computeFullLiveness):
     91        (JSC::BytecodeLivenessAnalysis::computeKills):
     92        (JSC::indexForOperand): Deleted.
     93        (JSC::BytecodeLivenessAnalysis::getLivenessInfoForNonCapturedVarsAtBytecodeOffset): Deleted.
     94        (JSC::getLivenessInfo): Deleted.
     95        * bytecode/BytecodeLivenessAnalysis.h:
     96        * bytecode/BytecodeLivenessAnalysisInlines.h:
     97        (JSC::operandIsAlwaysLive):
     98        (JSC::operandThatIsNotAlwaysLiveIsLive):
     99        (JSC::operandIsLive):
     100        * bytecode/BytecodeUseDef.h:
     101        (JSC::computeUsesForBytecodeOffset):
     102        (JSC::computeDefsForBytecodeOffset):
     103        * bytecode/CodeBlock.cpp:
     104        (JSC::CodeBlock::dumpBytecode):
     105        (JSC::CodeBlock::CodeBlock):
     106        (JSC::CodeBlock::nameForRegister):
     107        (JSC::CodeBlock::validate):
     108        (JSC::CodeBlock::isCaptured): Deleted.
     109        (JSC::CodeBlock::framePointerOffsetToGetActivationRegisters): Deleted.
     110        (JSC::CodeBlock::machineSlowArguments): Deleted.
     111        * bytecode/CodeBlock.h:
     112        (JSC::unmodifiedArgumentsRegister): Deleted.
     113        (JSC::CodeBlock::setArgumentsRegister): Deleted.
     114        (JSC::CodeBlock::argumentsRegister): Deleted.
     115        (JSC::CodeBlock::uncheckedArgumentsRegister): Deleted.
     116        (JSC::CodeBlock::usesArguments): Deleted.
     117        (JSC::CodeBlock::captureCount): Deleted.
     118        (JSC::CodeBlock::captureStart): Deleted.
     119        (JSC::CodeBlock::captureEnd): Deleted.
     120        (JSC::CodeBlock::argumentIndexAfterCapture): Deleted.
     121        (JSC::CodeBlock::hasSlowArguments): Deleted.
     122        (JSC::ExecState::argumentAfterCapture): Deleted.
     123        * bytecode/CodeOrigin.h:
     124        * bytecode/DataFormat.h:
     125        (JSC::dataFormatToString):
     126        * bytecode/FullBytecodeLiveness.h:
     127        (JSC::FullBytecodeLiveness::getLiveness):
     128        (JSC::FullBytecodeLiveness::operandIsLive):
     129        (JSC::FullBytecodeLiveness::FullBytecodeLiveness): Deleted.
     130        (JSC::FullBytecodeLiveness::getOut): Deleted.
     131        * bytecode/Instruction.h:
     132        (JSC::Instruction::Instruction):
     133        * bytecode/Operands.h:
     134        (JSC::Operands::virtualRegisterForIndex):
     135        * bytecode/SpeculatedType.cpp:
     136        (JSC::dumpSpeculation):
     137        (JSC::speculationToAbbreviatedString):
     138        (JSC::speculationFromClassInfo):
     139        * bytecode/SpeculatedType.h:
     140        (JSC::isDirectArgumentsSpeculation):
     141        (JSC::isScopedArgumentsSpeculation):
     142        (JSC::isActionableMutableArraySpeculation):
     143        (JSC::isActionableArraySpeculation):
     144        (JSC::isArgumentsSpeculation): Deleted.
     145        * bytecode/UnlinkedCodeBlock.cpp:
     146        (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
     147        * bytecode/UnlinkedCodeBlock.h:
     148        (JSC::UnlinkedCodeBlock::setArgumentsRegister): Deleted.
     149        (JSC::UnlinkedCodeBlock::usesArguments): Deleted.
     150        (JSC::UnlinkedCodeBlock::argumentsRegister): Deleted.
     151        * bytecode/ValueRecovery.cpp:
     152        (JSC::ValueRecovery::dumpInContext):
     153        * bytecode/ValueRecovery.h:
     154        (JSC::ValueRecovery::directArgumentsThatWereNotCreated):
     155        (JSC::ValueRecovery::outOfBandArgumentsThatWereNotCreated):
     156        (JSC::ValueRecovery::nodeID):
     157        (JSC::ValueRecovery::argumentsThatWereNotCreated): Deleted.
     158        * bytecode/VirtualRegister.h:
     159        (JSC::VirtualRegister::operator==):
     160        (JSC::VirtualRegister::operator!=):
     161        (JSC::VirtualRegister::operator<):
     162        (JSC::VirtualRegister::operator>):
     163        (JSC::VirtualRegister::operator<=):
     164        (JSC::VirtualRegister::operator>=):
     165        * bytecompiler/BytecodeGenerator.cpp:
     166        (JSC::BytecodeGenerator::generate):
     167        (JSC::BytecodeGenerator::BytecodeGenerator):
     168        (JSC::BytecodeGenerator::initializeNextParameter):
     169        (JSC::BytecodeGenerator::visibleNameForParameter):
     170        (JSC::BytecodeGenerator::emitMove):
     171        (JSC::BytecodeGenerator::variable):
     172        (JSC::BytecodeGenerator::createVariable):
     173        (JSC::BytecodeGenerator::emitResolveScope):
     174        (JSC::BytecodeGenerator::emitGetFromScope):
     175        (JSC::BytecodeGenerator::emitPutToScope):
     176        (JSC::BytecodeGenerator::initializeVariable):
     177        (JSC::BytecodeGenerator::emitInstanceOf):
     178        (JSC::BytecodeGenerator::emitNewFunction):
     179        (JSC::BytecodeGenerator::emitNewFunctionInternal):
     180        (JSC::BytecodeGenerator::emitCall):
     181        (JSC::BytecodeGenerator::emitReturn):
     182        (JSC::BytecodeGenerator::emitConstruct):
     183        (JSC::BytecodeGenerator::isArgumentNumber):
     184        (JSC::BytecodeGenerator::emitEnumeration):
     185        (JSC::BytecodeGenerator::addVar): Deleted.
     186        (JSC::BytecodeGenerator::emitInitLazyRegister): Deleted.
     187        (JSC::BytecodeGenerator::initializeCapturedVariable): Deleted.
     188        (JSC::BytecodeGenerator::resolveCallee): Deleted.
     189        (JSC::BytecodeGenerator::addCallee): Deleted.
     190        (JSC::BytecodeGenerator::addParameter): Deleted.
     191        (JSC::BytecodeGenerator::willResolveToArgumentsRegister): Deleted.
     192        (JSC::BytecodeGenerator::uncheckedLocalArgumentsRegister): Deleted.
     193        (JSC::BytecodeGenerator::createLazyRegisterIfNecessary): Deleted.
     194        (JSC::BytecodeGenerator::isCaptured): Deleted.
     195        (JSC::BytecodeGenerator::local): Deleted.
     196        (JSC::BytecodeGenerator::constLocal): Deleted.
     197        (JSC::BytecodeGenerator::emitResolveConstantLocal): Deleted.
     198        (JSC::BytecodeGenerator::emitGetArgumentsLength): Deleted.
     199        (JSC::BytecodeGenerator::emitGetArgumentByVal): Deleted.
     200        (JSC::BytecodeGenerator::emitLazyNewFunction): Deleted.
     201        (JSC::BytecodeGenerator::createArgumentsIfNecessary): Deleted.
     202        * bytecompiler/BytecodeGenerator.h:
     203        (JSC::Variable::Variable):
     204        (JSC::Variable::isResolved):
     205        (JSC::Variable::ident):
     206        (JSC::Variable::offset):
     207        (JSC::Variable::isLocal):
     208        (JSC::Variable::local):
     209        (JSC::Variable::isSpecial):
     210        (JSC::BytecodeGenerator::argumentsRegister):
     211        (JSC::BytecodeGenerator::emitNode):
     212        (JSC::BytecodeGenerator::registerFor):
     213        (JSC::Local::Local): Deleted.
     214        (JSC::Local::operator bool): Deleted.
     215        (JSC::Local::get): Deleted.
     216        (JSC::Local::isSpecial): Deleted.
     217        (JSC::ResolveScopeInfo::ResolveScopeInfo): Deleted.
     218        (JSC::ResolveScopeInfo::isLocal): Deleted.
     219        (JSC::ResolveScopeInfo::localIndex): Deleted.
     220        (JSC::BytecodeGenerator::hasSafeLocalArgumentsRegister): Deleted.
     221        (JSC::BytecodeGenerator::captureMode): Deleted.
     222        (JSC::BytecodeGenerator::shouldTearOffArgumentsEagerly): Deleted.
     223        (JSC::BytecodeGenerator::shouldCreateArgumentsEagerly): Deleted.
     224        (JSC::BytecodeGenerator::hasWatchableVariable): Deleted.
     225        (JSC::BytecodeGenerator::watchableVariableIdentifier): Deleted.
     226        * bytecompiler/NodesCodegen.cpp:
     227        (JSC::ResolveNode::isPure):
     228        (JSC::ResolveNode::emitBytecode):
     229        (JSC::BracketAccessorNode::emitBytecode):
     230        (JSC::DotAccessorNode::emitBytecode):
     231        (JSC::EvalFunctionCallNode::emitBytecode):
     232        (JSC::FunctionCallResolveNode::emitBytecode):
     233        (JSC::CallFunctionCallDotNode::emitBytecode):
     234        (JSC::ApplyFunctionCallDotNode::emitBytecode):
     235        (JSC::PostfixNode::emitResolve):
     236        (JSC::DeleteResolveNode::emitBytecode):
     237        (JSC::TypeOfResolveNode::emitBytecode):
     238        (JSC::PrefixNode::emitResolve):
     239        (JSC::ReadModifyResolveNode::emitBytecode):
     240        (JSC::AssignResolveNode::emitBytecode):
     241        (JSC::ConstDeclNode::emitCodeSingle):
     242        (JSC::EmptyVarExpression::emitBytecode):
     243        (JSC::ForInNode::tryGetBoundLocal):
     244        (JSC::ForInNode::emitLoopHeader):
     245        (JSC::ForOfNode::emitBytecode):
     246        (JSC::ArrayPatternNode::emitDirectBinding):
     247        (JSC::BindingNode::bindValue):
     248        (JSC::getArgumentByVal): Deleted.
     249        * dfg/DFGAbstractHeap.h:
     250        * dfg/DFGAbstractInterpreter.h:
     251        * dfg/DFGAbstractInterpreterInlines.h:
     252        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     253        (JSC::DFG::AbstractInterpreter<AbstractStateType>::clobberWorld):
     254        (JSC::DFG::AbstractInterpreter<AbstractStateType>::clobberCapturedVars): Deleted.
     255        * dfg/DFGAbstractValue.h:
     256        * dfg/DFGArgumentPosition.h:
     257        (JSC::DFG::ArgumentPosition::addVariable):
     258        * dfg/DFGArgumentsEliminationPhase.cpp: Added.
     259        (JSC::DFG::performArgumentsElimination):
     260        * dfg/DFGArgumentsEliminationPhase.h: Added.
     261        * dfg/DFGArgumentsSimplificationPhase.cpp: Removed.
     262        * dfg/DFGArgumentsSimplificationPhase.h: Removed.
     263        * dfg/DFGArgumentsUtilities.cpp: Added.
     264        (JSC::DFG::argumentsInvolveStackSlot):
     265        (JSC::DFG::emitCodeToGetArgumentsArrayLength):
     266        * dfg/DFGArgumentsUtilities.h: Added.
     267        * dfg/DFGArrayMode.cpp:
     268        (JSC::DFG::ArrayMode::refine):
     269        (JSC::DFG::ArrayMode::alreadyChecked):
     270        (JSC::DFG::arrayTypeToString):
     271        * dfg/DFGArrayMode.h:
     272        (JSC::DFG::ArrayMode::canCSEStorage):
     273        (JSC::DFG::ArrayMode::modeForPut):
     274        * dfg/DFGAvailabilityMap.cpp:
     275        (JSC::DFG::AvailabilityMap::prune):
     276        * dfg/DFGAvailabilityMap.h:
     277        (JSC::DFG::AvailabilityMap::closeOverNodes):
     278        (JSC::DFG::AvailabilityMap::closeStartingWithLocal):
     279        * dfg/DFGBackwardsPropagationPhase.cpp:
     280        (JSC::DFG::BackwardsPropagationPhase::propagate):
     281        * dfg/DFGByteCodeParser.cpp:
     282        (JSC::DFG::ByteCodeParser::newVariableAccessData):
     283        (JSC::DFG::ByteCodeParser::getLocal):
     284        (JSC::DFG::ByteCodeParser::setLocal):
     285        (JSC::DFG::ByteCodeParser::getArgument):
     286        (JSC::DFG::ByteCodeParser::setArgument):
     287        (JSC::DFG::ByteCodeParser::flushDirect):
     288        (JSC::DFG::ByteCodeParser::flush):
     289        (JSC::DFG::ByteCodeParser::noticeArgumentsUse):
     290        (JSC::DFG::ByteCodeParser::handleVarargsCall):
     291        (JSC::DFG::ByteCodeParser::attemptToInlineCall):
     292        (JSC::DFG::ByteCodeParser::handleInlining):
     293        (JSC::DFG::ByteCodeParser::parseBlock):
     294        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
     295        (JSC::DFG::ByteCodeParser::parseCodeBlock):
     296        * dfg/DFGCPSRethreadingPhase.cpp:
     297        (JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
     298        (JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock):
     299        * dfg/DFGCSEPhase.cpp:
     300        * dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h: Added.
     301        (JSC::DFG::CallCreateDirectArgumentsSlowPathGenerator::CallCreateDirectArgumentsSlowPathGenerator):
     302        * dfg/DFGCapabilities.cpp:
     303        (JSC::DFG::isSupportedForInlining):
     304        (JSC::DFG::capabilityLevel):
     305        * dfg/DFGClobberize.h:
     306        (JSC::DFG::clobberize):
     307        * dfg/DFGCommon.h:
     308        * dfg/DFGCommonData.h:
     309        (JSC::DFG::CommonData::CommonData):
     310        * dfg/DFGConstantFoldingPhase.cpp:
     311        (JSC::DFG::ConstantFoldingPhase::foldConstants):
     312        * dfg/DFGDCEPhase.cpp:
     313        (JSC::DFG::DCEPhase::cleanVariables):
     314        * dfg/DFGDisassembler.h:
     315        * dfg/DFGDoesGC.cpp:
     316        (JSC::DFG::doesGC):
     317        * dfg/DFGFixupPhase.cpp:
     318        (JSC::DFG::FixupPhase::fixupNode):
     319        * dfg/DFGFlushFormat.cpp:
     320        (WTF::printInternal):
     321        * dfg/DFGFlushFormat.h:
     322        (JSC::DFG::resultFor):
     323        (JSC::DFG::useKindFor):
     324        (JSC::DFG::dataFormatFor):
     325        * dfg/DFGForAllKills.h: Added.
     326        (JSC::DFG::forAllLiveNodesAtTail):
     327        (JSC::DFG::forAllDirectlyKilledOperands):
     328        (JSC::DFG::forAllKilledOperands):
     329        (JSC::DFG::forAllKilledNodesAtNodeIndex):
     330        (JSC::DFG::forAllKillsInBlock):
     331        * dfg/DFGGraph.cpp:
     332        (JSC::DFG::Graph::Graph):
     333        (JSC::DFG::Graph::dump):
     334        (JSC::DFG::Graph::substituteGetLocal):
     335        (JSC::DFG::Graph::livenessFor):
     336        (JSC::DFG::Graph::killsFor):
     337        (JSC::DFG::Graph::tryGetConstantClosureVar):
     338        (JSC::DFG::Graph::tryGetRegisters): Deleted.
     339        * dfg/DFGGraph.h:
     340        (JSC::DFG::Graph::symbolTableFor):
     341        (JSC::DFG::Graph::uses):
     342        (JSC::DFG::Graph::bytecodeRegisterForArgument): Deleted.
     343        (JSC::DFG::Graph::capturedVarsFor): Deleted.
     344        (JSC::DFG::Graph::usesArguments): Deleted.
     345        (JSC::DFG::Graph::argumentsRegisterFor): Deleted.
     346        (JSC::DFG::Graph::machineArgumentsRegisterFor): Deleted.
     347        (JSC::DFG::Graph::uncheckedArgumentsRegisterFor): Deleted.
     348        * dfg/DFGHeapLocation.cpp:
     349        (WTF::printInternal):
     350        * dfg/DFGHeapLocation.h:
     351        * dfg/DFGInPlaceAbstractState.cpp:
     352        (JSC::DFG::InPlaceAbstractState::initialize):
     353        (JSC::DFG::InPlaceAbstractState::mergeStateAtTail):
     354        * dfg/DFGJITCompiler.cpp:
     355        (JSC::DFG::JITCompiler::link):
     356        * dfg/DFGMayExit.cpp:
     357        (JSC::DFG::mayExit):
     358        * dfg/DFGMinifiedID.h:
     359        * dfg/DFGMinifiedNode.cpp:
     360        (JSC::DFG::MinifiedNode::fromNode):
     361        * dfg/DFGMinifiedNode.h:
     362        (JSC::DFG::belongsInMinifiedGraph):
     363        (JSC::DFG::MinifiedNode::hasInlineCallFrame):
     364        (JSC::DFG::MinifiedNode::inlineCallFrame):
     365        * dfg/DFGNode.cpp:
     366        (JSC::DFG::Node::convertToIdentityOn):
     367        * dfg/DFGNode.h:
     368        (JSC::DFG::Node::hasConstant):
     369        (JSC::DFG::Node::constant):
     370        (JSC::DFG::Node::hasScopeOffset):
     371        (JSC::DFG::Node::scopeOffset):
     372        (JSC::DFG::Node::hasDirectArgumentsOffset):
     373        (JSC::DFG::Node::capturedArgumentsOffset):
     374        (JSC::DFG::Node::variablePointer):
     375        (JSC::DFG::Node::hasCallVarargsData):
     376        (JSC::DFG::Node::hasLoadVarargsData):
     377        (JSC::DFG::Node::hasHeapPrediction):
     378        (JSC::DFG::Node::hasCellOperand):
     379        (JSC::DFG::Node::objectMaterializationData):
     380        (JSC::DFG::Node::isPhantomAllocation):
     381        (JSC::DFG::Node::willHaveCodeGenOrOSR):
     382        (JSC::DFG::Node::shouldSpeculateDirectArguments):
     383        (JSC::DFG::Node::shouldSpeculateScopedArguments):
     384        (JSC::DFG::Node::isPhantomArguments): Deleted.
     385        (JSC::DFG::Node::hasVarNumber): Deleted.
     386        (JSC::DFG::Node::varNumber): Deleted.
     387        (JSC::DFG::Node::registerPointer): Deleted.
     388        (JSC::DFG::Node::shouldSpeculateArguments): Deleted.
     389        * dfg/DFGNodeType.h:
     390        * dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
     391        (JSC::DFG::OSRAvailabilityAnalysisPhase::run):
     392        (JSC::DFG::LocalOSRAvailabilityCalculator::executeNode):
     393        * dfg/DFGOSRExitCompiler.cpp:
     394        (JSC::DFG::OSRExitCompiler::emitRestoreArguments):
     395        * dfg/DFGOSRExitCompiler.h:
     396        (JSC::DFG::OSRExitCompiler::badIndex): Deleted.
     397        (JSC::DFG::OSRExitCompiler::initializePoisoned): Deleted.
     398        (JSC::DFG::OSRExitCompiler::poisonIndex): Deleted.
     399        * dfg/DFGOSRExitCompiler32_64.cpp:
     400        (JSC::DFG::OSRExitCompiler::compileExit):
     401        * dfg/DFGOSRExitCompiler64.cpp:
     402        (JSC::DFG::OSRExitCompiler::compileExit):
     403        * dfg/DFGOSRExitCompilerCommon.cpp:
     404        (JSC::DFG::reifyInlinedCallFrames):
     405        (JSC::DFG::ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator): Deleted.
     406        (JSC::DFG::ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator): Deleted.
     407        (JSC::DFG::ArgumentsRecoveryGenerator::generateFor): Deleted.
     408        * dfg/DFGOSRExitCompilerCommon.h:
     409        * dfg/DFGOperations.cpp:
     410        * dfg/DFGOperations.h:
     411        * dfg/DFGPlan.cpp:
     412        (JSC::DFG::Plan::compileInThreadImpl):
     413        * dfg/DFGPreciseLocalClobberize.h:
     414        (JSC::DFG::PreciseLocalClobberizeAdaptor::read):
     415        (JSC::DFG::PreciseLocalClobberizeAdaptor::write):
     416        (JSC::DFG::PreciseLocalClobberizeAdaptor::def):
     417        (JSC::DFG::PreciseLocalClobberizeAdaptor::readTop):
     418        (JSC::DFG::preciseLocalClobberize):
     419        (JSC::DFG::PreciseLocalClobberizeAdaptor::writeTop): Deleted.
     420        (JSC::DFG::forEachLocalReadByUnwind): Deleted.
     421        * dfg/DFGPredictionPropagationPhase.cpp:
     422        (JSC::DFG::PredictionPropagationPhase::run):
     423        (JSC::DFG::PredictionPropagationPhase::propagate):
     424        (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
     425        (JSC::DFG::PredictionPropagationPhase::propagateThroughArgumentPositions):
     426        * dfg/DFGPromoteHeapAccess.h:
     427        (JSC::DFG::promoteHeapAccess):
     428        * dfg/DFGPromotedHeapLocation.cpp:
     429        (WTF::printInternal):
     430        * dfg/DFGPromotedHeapLocation.h:
     431        * dfg/DFGSSAConversionPhase.cpp:
     432        (JSC::DFG::SSAConversionPhase::run):
     433        * dfg/DFGSafeToExecute.h:
     434        (JSC::DFG::safeToExecute):
     435        * dfg/DFGSpeculativeJIT.cpp:
     436        (JSC::DFG::SpeculativeJIT::emitAllocateJSArray):
     437        (JSC::DFG::SpeculativeJIT::emitGetLength):
     438        (JSC::DFG::SpeculativeJIT::emitGetCallee):
     439        (JSC::DFG::SpeculativeJIT::emitGetArgumentStart):
     440        (JSC::DFG::SpeculativeJIT::checkArray):
     441        (JSC::DFG::SpeculativeJIT::compileGetByValOnDirectArguments):
     442        (JSC::DFG::SpeculativeJIT::compileGetByValOnScopedArguments):
     443        (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
     444        (JSC::DFG::SpeculativeJIT::compileNewFunction):
     445        (JSC::DFG::SpeculativeJIT::compileForwardVarargs):
     446        (JSC::DFG::SpeculativeJIT::compileCreateActivation):
     447        (JSC::DFG::SpeculativeJIT::compileCreateDirectArguments):
     448        (JSC::DFG::SpeculativeJIT::compileGetFromArguments):
     449        (JSC::DFG::SpeculativeJIT::compilePutToArguments):
     450        (JSC::DFG::SpeculativeJIT::compileCreateScopedArguments):
     451        (JSC::DFG::SpeculativeJIT::compileCreateClonedArguments):
     452        (JSC::DFG::SpeculativeJIT::emitAllocateArguments): Deleted.
     453        (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments): Deleted.
     454        (JSC::DFG::SpeculativeJIT::compileGetArgumentsLength): Deleted.
     455        (JSC::DFG::SpeculativeJIT::compileNewFunctionNoCheck): Deleted.
     456        (JSC::DFG::SpeculativeJIT::compileNewFunctionExpression): Deleted.
     457        * dfg/DFGSpeculativeJIT.h:
     458        (JSC::DFG::SpeculativeJIT::callOperation):
     459        (JSC::DFG::SpeculativeJIT::emitAllocateJSObjectWithKnownSize):
     460        (JSC::DFG::SpeculativeJIT::emitAllocateJSObject):
     461        (JSC::DFG::SpeculativeJIT::framePointerOffsetToGetActivationRegisters): Deleted.
     462        * dfg/DFGSpeculativeJIT32_64.cpp:
     463        (JSC::DFG::SpeculativeJIT::emitCall):
     464        (JSC::DFG::SpeculativeJIT::compile):
     465        * dfg/DFGSpeculativeJIT64.cpp:
     466        (JSC::DFG::SpeculativeJIT::emitCall):
     467        (JSC::DFG::SpeculativeJIT::compile):
     468        * dfg/DFGStackLayoutPhase.cpp:
     469        (JSC::DFG::StackLayoutPhase::run):
     470        * dfg/DFGStrengthReductionPhase.cpp:
     471        (JSC::DFG::StrengthReductionPhase::handleNode):
     472        * dfg/DFGStructureRegistrationPhase.cpp:
     473        (JSC::DFG::StructureRegistrationPhase::run):
     474        * dfg/DFGUnificationPhase.cpp:
     475        (JSC::DFG::UnificationPhase::run):
     476        * dfg/DFGValidate.cpp:
     477        (JSC::DFG::Validate::validateCPS):
     478        * dfg/DFGValueSource.cpp:
     479        (JSC::DFG::ValueSource::dump):
     480        * dfg/DFGValueSource.h:
     481        (JSC::DFG::dataFormatToValueSourceKind):
     482        (JSC::DFG::valueSourceKindToDataFormat):
     483        (JSC::DFG::ValueSource::ValueSource):
     484        (JSC::DFG::ValueSource::forFlushFormat):
     485        (JSC::DFG::ValueSource::valueRecovery):
     486        * dfg/DFGVarargsForwardingPhase.cpp: Added.
     487        (JSC::DFG::performVarargsForwarding):
     488        * dfg/DFGVarargsForwardingPhase.h: Added.
     489        * dfg/DFGVariableAccessData.cpp:
     490        (JSC::DFG::VariableAccessData::VariableAccessData):
     491        (JSC::DFG::VariableAccessData::flushFormat):
     492        (JSC::DFG::VariableAccessData::mergeIsCaptured): Deleted.
     493        * dfg/DFGVariableAccessData.h:
     494        (JSC::DFG::VariableAccessData::shouldNeverUnbox):
     495        (JSC::DFG::VariableAccessData::shouldUseDoubleFormat):
     496        (JSC::DFG::VariableAccessData::isCaptured): Deleted.
     497        (JSC::DFG::VariableAccessData::mergeIsArgumentsAlias): Deleted.
     498        (JSC::DFG::VariableAccessData::isArgumentsAlias): Deleted.
     499        * dfg/DFGVariableAccessDataDump.cpp:
     500        (JSC::DFG::VariableAccessDataDump::dump):
     501        * dfg/DFGVariableAccessDataDump.h:
     502        * dfg/DFGVariableEventStream.cpp:
     503        (JSC::DFG::VariableEventStream::tryToSetConstantRecovery):
     504        * dfg/DFGVariableEventStream.h:
     505        * ftl/FTLAbstractHeap.cpp:
     506        (JSC::FTL::AbstractHeap::dump):
     507        (JSC::FTL::AbstractField::dump):
     508        (JSC::FTL::IndexedAbstractHeap::dump):
     509        (JSC::FTL::NumberedAbstractHeap::dump):
     510        (JSC::FTL::AbsoluteAbstractHeap::dump):
     511        * ftl/FTLAbstractHeap.h:
     512        * ftl/FTLAbstractHeapRepository.cpp:
     513        * ftl/FTLAbstractHeapRepository.h:
     514        * ftl/FTLCapabilities.cpp:
     515        (JSC::FTL::canCompile):
     516        * ftl/FTLCompile.cpp:
     517        (JSC::FTL::mmAllocateDataSection):
     518        * ftl/FTLExitArgument.cpp:
     519        (JSC::FTL::ExitArgument::dump):
     520        * ftl/FTLExitPropertyValue.cpp:
     521        (JSC::FTL::ExitPropertyValue::withLocalsOffset):
     522        * ftl/FTLExitPropertyValue.h:
     523        * ftl/FTLExitTimeObjectMaterialization.cpp:
     524        (JSC::FTL::ExitTimeObjectMaterialization::ExitTimeObjectMaterialization):
     525        (JSC::FTL::ExitTimeObjectMaterialization::accountForLocalsOffset):
     526        * ftl/FTLExitTimeObjectMaterialization.h:
     527        (JSC::FTL::ExitTimeObjectMaterialization::origin):
     528        * ftl/FTLExitValue.cpp:
     529        (JSC::FTL::ExitValue::withLocalsOffset):
     530        (JSC::FTL::ExitValue::valueFormat):
     531        (JSC::FTL::ExitValue::dumpInContext):
     532        * ftl/FTLExitValue.h:
     533        (JSC::FTL::ExitValue::isArgument):
     534        (JSC::FTL::ExitValue::argumentsObjectThatWasNotCreated): Deleted.
     535        (JSC::FTL::ExitValue::isArgumentsObjectThatWasNotCreated): Deleted.
     536        (JSC::FTL::ExitValue::valueFormat): Deleted.
     537        * ftl/FTLInlineCacheSize.cpp:
     538        (JSC::FTL::sizeOfCallForwardVarargs):
     539        (JSC::FTL::sizeOfConstructForwardVarargs):
     540        (JSC::FTL::sizeOfICFor):
     541        * ftl/FTLInlineCacheSize.h:
     542        * ftl/FTLIntrinsicRepository.h:
     543        * ftl/FTLJSCallVarargs.cpp:
     544        (JSC::FTL::JSCallVarargs::JSCallVarargs):
     545        (JSC::FTL::JSCallVarargs::emit):
     546        * ftl/FTLJSCallVarargs.h:
     547        * ftl/FTLLowerDFGToLLVM.cpp:
     548        (JSC::FTL::LowerDFGToLLVM::lower):
     549        (JSC::FTL::LowerDFGToLLVM::compileNode):
     550        (JSC::FTL::LowerDFGToLLVM::compilePutStack):
     551        (JSC::FTL::LowerDFGToLLVM::compileGetArrayLength):
     552        (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
     553        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentByVal):
     554        (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
     555        (JSC::FTL::LowerDFGToLLVM::compileArrayPush):
     556        (JSC::FTL::LowerDFGToLLVM::compileArrayPop):
     557        (JSC::FTL::LowerDFGToLLVM::compileCreateActivation):
     558        (JSC::FTL::LowerDFGToLLVM::compileNewFunction):
     559        (JSC::FTL::LowerDFGToLLVM::compileCreateDirectArguments):
     560        (JSC::FTL::LowerDFGToLLVM::compileCreateScopedArguments):
     561        (JSC::FTL::LowerDFGToLLVM::compileCreateClonedArguments):
     562        (JSC::FTL::LowerDFGToLLVM::compileStringCharAt):
     563        (JSC::FTL::LowerDFGToLLVM::compileStringCharCodeAt):
     564        (JSC::FTL::LowerDFGToLLVM::compileGetGlobalVar):
     565        (JSC::FTL::LowerDFGToLLVM::compilePutGlobalVar):
     566        (JSC::FTL::LowerDFGToLLVM::compileGetArgumentCount):
     567        (JSC::FTL::LowerDFGToLLVM::compileGetClosureVar):
     568        (JSC::FTL::LowerDFGToLLVM::compilePutClosureVar):
     569        (JSC::FTL::LowerDFGToLLVM::compileGetFromArguments):
     570        (JSC::FTL::LowerDFGToLLVM::compilePutToArguments):
     571        (JSC::FTL::LowerDFGToLLVM::compileCallOrConstructVarargs):
     572        (JSC::FTL::LowerDFGToLLVM::compileForwardVarargs):
     573        (JSC::FTL::LowerDFGToLLVM::compileGetEnumeratorPname):
     574        (JSC::FTL::LowerDFGToLLVM::ArgumentsLength::ArgumentsLength):
     575        (JSC::FTL::LowerDFGToLLVM::getArgumentsLength):
     576        (JSC::FTL::LowerDFGToLLVM::getCurrentCallee):
     577        (JSC::FTL::LowerDFGToLLVM::getArgumentsStart):
     578        (JSC::FTL::LowerDFGToLLVM::baseIndex):
     579        (JSC::FTL::LowerDFGToLLVM::allocateObject):
     580        (JSC::FTL::LowerDFGToLLVM::allocateVariableSizedObject):
     581        (JSC::FTL::LowerDFGToLLVM::isArrayType):
     582        (JSC::FTL::LowerDFGToLLVM::emitStoreBarrier):
     583        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
     584        (JSC::FTL::LowerDFGToLLVM::exitValueForAvailability):
     585        (JSC::FTL::LowerDFGToLLVM::exitValueForNode):
     586        (JSC::FTL::LowerDFGToLLVM::loadStructure):
     587        (JSC::FTL::LowerDFGToLLVM::compilePhantomArguments): Deleted.
     588        (JSC::FTL::LowerDFGToLLVM::compileGetMyArgumentsLength): Deleted.
     589        (JSC::FTL::LowerDFGToLLVM::compileGetClosureRegisters): Deleted.
     590        (JSC::FTL::LowerDFGToLLVM::compileCheckArgumentsNotCreated): Deleted.
     591        (JSC::FTL::LowerDFGToLLVM::checkArgumentsNotCreated): Deleted.
     592        * ftl/FTLOSRExitCompiler.cpp:
     593        (JSC::FTL::compileRecovery):
     594        (JSC::FTL::compileStub):
     595        * ftl/FTLOperations.cpp:
     596        (JSC::FTL::operationMaterializeObjectInOSR):
     597        * ftl/FTLOutput.h:
     598        (JSC::FTL::Output::aShr):
     599        (JSC::FTL::Output::lShr):
     600        (JSC::FTL::Output::zeroExtPtr):
     601        * heap/CopyToken.h:
     602        * interpreter/CallFrame.h:
     603        (JSC::ExecState::getArgumentUnsafe):
     604        * interpreter/Interpreter.cpp:
     605        (JSC::sizeOfVarargs):
     606        (JSC::sizeFrameForVarargs):
     607        (JSC::loadVarargs):
     608        (JSC::unwindCallFrame):
     609        * interpreter/Interpreter.h:
     610        * interpreter/StackVisitor.cpp:
     611        (JSC::StackVisitor::Frame::createArguments):
     612        (JSC::StackVisitor::Frame::existingArguments): Deleted.
     613        * interpreter/StackVisitor.h:
     614        * jit/AssemblyHelpers.h:
     615        (JSC::AssemblyHelpers::storeValue):
     616        (JSC::AssemblyHelpers::loadValue):
     617        (JSC::AssemblyHelpers::storeTrustedValue):
     618        (JSC::AssemblyHelpers::branchIfNotCell):
     619        (JSC::AssemblyHelpers::branchIsEmpty):
     620        (JSC::AssemblyHelpers::argumentsStart):
     621        (JSC::AssemblyHelpers::baselineArgumentsRegisterFor): Deleted.
     622        (JSC::AssemblyHelpers::offsetOfLocals): Deleted.
     623        (JSC::AssemblyHelpers::offsetOfArguments): Deleted.
     624        * jit/CCallHelpers.h:
     625        (JSC::CCallHelpers::setupArgument):
     626        * jit/GPRInfo.h:
     627        (JSC::JSValueRegs::withTwoAvailableRegs):
     628        * jit/JIT.cpp:
     629        (JSC::JIT::privateCompileMainPass):
     630        (JSC::JIT::privateCompileSlowCases):
     631        * jit/JIT.h:
     632        * jit/JITCall.cpp:
     633        (JSC::JIT::compileSetupVarargsFrame):
     634        * jit/JITCall32_64.cpp:
     635        (JSC::JIT::compileSetupVarargsFrame):
     636        * jit/JITInlines.h:
     637        (JSC::JIT::callOperation):
     638        * jit/JITOpcodes.cpp:
     639        (JSC::JIT::emit_op_create_lexical_environment):
     640        (JSC::JIT::emit_op_new_func):
     641        (JSC::JIT::emit_op_create_direct_arguments):
     642        (JSC::JIT::emit_op_create_scoped_arguments):
     643        (JSC::JIT::emit_op_create_out_of_band_arguments):
     644        (JSC::JIT::emit_op_tear_off_arguments): Deleted.
     645        (JSC::JIT::emit_op_create_arguments): Deleted.
     646        (JSC::JIT::emit_op_init_lazy_reg): Deleted.
     647        (JSC::JIT::emit_op_get_arguments_length): Deleted.
     648        (JSC::JIT::emitSlow_op_get_arguments_length): Deleted.
     649        (JSC::JIT::emit_op_get_argument_by_val): Deleted.
     650        (JSC::JIT::emitSlow_op_get_argument_by_val): Deleted.
     651        * jit/JITOpcodes32_64.cpp:
     652        (JSC::JIT::emit_op_create_lexical_environment):
     653        (JSC::JIT::emit_op_tear_off_arguments): Deleted.
     654        (JSC::JIT::emit_op_create_arguments): Deleted.
     655        (JSC::JIT::emit_op_init_lazy_reg): Deleted.
     656        (JSC::JIT::emit_op_get_arguments_length): Deleted.
     657        (JSC::JIT::emitSlow_op_get_arguments_length): Deleted.
     658        (JSC::JIT::emit_op_get_argument_by_val): Deleted.
     659        (JSC::JIT::emitSlow_op_get_argument_by_val): Deleted.
     660        * jit/JITOperations.cpp:
     661        * jit/JITOperations.h:
     662        * jit/JITPropertyAccess.cpp:
     663        (JSC::JIT::emitGetClosureVar):
     664        (JSC::JIT::emitPutClosureVar):
     665        (JSC::JIT::emit_op_get_from_arguments):
     666        (JSC::JIT::emit_op_put_to_arguments):
     667        (JSC::JIT::emit_op_init_global_const):
     668        (JSC::JIT::privateCompileGetByVal):
     669        (JSC::JIT::emitDirectArgumentsGetByVal):
     670        (JSC::JIT::emitScopedArgumentsGetByVal):
     671        * jit/JITPropertyAccess32_64.cpp:
     672        (JSC::JIT::emitGetClosureVar):
     673        (JSC::JIT::emitPutClosureVar):
     674        (JSC::JIT::emit_op_get_from_arguments):
     675        (JSC::JIT::emit_op_put_to_arguments):
     676        (JSC::JIT::emit_op_init_global_const):
     677        * jit/SetupVarargsFrame.cpp:
     678        (JSC::emitSetupVarargsFrameFastCase):
     679        * llint/LLIntOffsetsExtractor.cpp:
     680        * llint/LLIntSlowPaths.cpp:
     681        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
     682        * llint/LowLevelInterpreter.asm:
     683        * llint/LowLevelInterpreter32_64.asm:
     684        * llint/LowLevelInterpreter64.asm:
     685        * parser/Nodes.h:
     686        (JSC::ScopeNode::captures):
     687        * runtime/Arguments.cpp: Removed.
     688        * runtime/Arguments.h: Removed.
     689        * runtime/ArgumentsMode.h: Added.
     690        * runtime/DirectArgumentsOffset.cpp: Added.
     691        (JSC::DirectArgumentsOffset::dump):
     692        * runtime/DirectArgumentsOffset.h: Added.
     693        (JSC::DirectArgumentsOffset::DirectArgumentsOffset):
     694        * runtime/CommonSlowPaths.cpp:
     695        (JSC::SLOW_PATH_DECL):
     696        * runtime/CommonSlowPaths.h:
     697        * runtime/ConstantMode.cpp: Added.
     698        (WTF::printInternal):
     699        * runtime/ConstantMode.h:
     700        (JSC::modeForIsConstant):
     701        * runtime/DirectArguments.cpp: Added.
     702        (JSC::DirectArguments::DirectArguments):
     703        (JSC::DirectArguments::createUninitialized):
     704        (JSC::DirectArguments::create):
     705        (JSC::DirectArguments::createByCopying):
     706        (JSC::DirectArguments::visitChildren):
     707        (JSC::DirectArguments::copyBackingStore):
     708        (JSC::DirectArguments::createStructure):
     709        (JSC::DirectArguments::overrideThings):
     710        (JSC::DirectArguments::overrideThingsIfNecessary):
     711        (JSC::DirectArguments::overrideArgument):
     712        (JSC::DirectArguments::copyToArguments):
     713        (JSC::DirectArguments::overridesSize):
     714        * runtime/DirectArguments.h: Added.
     715        (JSC::DirectArguments::internalLength):
     716        (JSC::DirectArguments::length):
     717        (JSC::DirectArguments::canAccessIndexQuickly):
     718        (JSC::DirectArguments::getIndexQuickly):
     719        (JSC::DirectArguments::setIndexQuickly):
     720        (JSC::DirectArguments::callee):
     721        (JSC::DirectArguments::argument):
     722        (JSC::DirectArguments::overrodeThings):
     723        (JSC::DirectArguments::offsetOfCallee):
     724        (JSC::DirectArguments::offsetOfLength):
     725        (JSC::DirectArguments::offsetOfMinCapacity):
     726        (JSC::DirectArguments::offsetOfOverrides):
     727        (JSC::DirectArguments::storageOffset):
     728        (JSC::DirectArguments::offsetOfSlot):
     729        (JSC::DirectArguments::allocationSize):
     730        (JSC::DirectArguments::storage):
     731        * runtime/FunctionPrototype.cpp:
     732        * runtime/GenericArguments.h: Added.
     733        (JSC::GenericArguments::GenericArguments):
     734        * runtime/GenericArgumentsInlines.h: Added.
     735        (JSC::GenericArguments<Type>::getOwnPropertySlot):
     736        (JSC::GenericArguments<Type>::getOwnPropertySlotByIndex):
     737        (JSC::GenericArguments<Type>::getOwnPropertyNames):
     738        (JSC::GenericArguments<Type>::put):
     739        (JSC::GenericArguments<Type>::putByIndex):
     740        (JSC::GenericArguments<Type>::deleteProperty):
     741        (JSC::GenericArguments<Type>::deletePropertyByIndex):
     742        (JSC::GenericArguments<Type>::defineOwnProperty):
     743        (JSC::GenericArguments<Type>::copyToArguments):
     744        * runtime/GenericOffset.h: Added.
     745        (JSC::GenericOffset::GenericOffset):
     746        (JSC::GenericOffset::operator!):
     747        (JSC::GenericOffset::offsetUnchecked):
     748        (JSC::GenericOffset::offset):
     749        (JSC::GenericOffset::operator==):
     750        (JSC::GenericOffset::operator!=):
     751        (JSC::GenericOffset::operator<):
     752        (JSC::GenericOffset::operator>):
     753        (JSC::GenericOffset::operator<=):
     754        (JSC::GenericOffset::operator>=):
     755        (JSC::GenericOffset::operator+):
     756        (JSC::GenericOffset::operator-):
     757        (JSC::GenericOffset::operator+=):
     758        (JSC::GenericOffset::operator-=):
     759        * runtime/JSArgumentsIterator.cpp:
     760        (JSC::JSArgumentsIterator::finishCreation):
     761        (JSC::argumentsFuncIterator):
     762        * runtime/JSArgumentsIterator.h:
     763        (JSC::JSArgumentsIterator::create):
     764        (JSC::JSArgumentsIterator::next):
     765        * runtime/JSEnvironmentRecord.cpp:
     766        (JSC::JSEnvironmentRecord::visitChildren):
     767        * runtime/JSEnvironmentRecord.h:
     768        (JSC::JSEnvironmentRecord::variables):
     769        (JSC::JSEnvironmentRecord::isValid):
     770        (JSC::JSEnvironmentRecord::variableAt):
     771        (JSC::JSEnvironmentRecord::offsetOfVariables):
     772        (JSC::JSEnvironmentRecord::offsetOfVariable):
     773        (JSC::JSEnvironmentRecord::allocationSizeForScopeSize):
     774        (JSC::JSEnvironmentRecord::allocationSize):
     775        (JSC::JSEnvironmentRecord::JSEnvironmentRecord):
     776        (JSC::JSEnvironmentRecord::finishCreationUninitialized):
     777        (JSC::JSEnvironmentRecord::finishCreation):
     778        (JSC::JSEnvironmentRecord::registers): Deleted.
     779        (JSC::JSEnvironmentRecord::registerAt): Deleted.
     780        (JSC::JSEnvironmentRecord::addressOfRegisters): Deleted.
     781        (JSC::JSEnvironmentRecord::offsetOfRegisters): Deleted.
     782        * runtime/JSFunction.cpp:
     783        * runtime/JSGlobalObject.cpp:
     784        (JSC::JSGlobalObject::init):
     785        (JSC::JSGlobalObject::addGlobalVar):
     786        (JSC::JSGlobalObject::addFunction):
     787        (JSC::JSGlobalObject::visitChildren):
     788        (JSC::JSGlobalObject::addStaticGlobals):
     789        * runtime/JSGlobalObject.h:
     790        (JSC::JSGlobalObject::directArgumentsStructure):
     791        (JSC::JSGlobalObject::scopedArgumentsStructure):
     792        (JSC::JSGlobalObject::outOfBandArgumentsStructure):
     793        (JSC::JSGlobalObject::argumentsStructure): Deleted.
     794        * runtime/JSLexicalEnvironment.cpp:
     795        (JSC::JSLexicalEnvironment::symbolTableGet):
     796        (JSC::JSLexicalEnvironment::symbolTablePut):
     797        (JSC::JSLexicalEnvironment::getOwnNonIndexPropertyNames):
     798        (JSC::JSLexicalEnvironment::symbolTablePutWithAttributes):
     799        (JSC::JSLexicalEnvironment::visitChildren): Deleted.
     800        * runtime/JSLexicalEnvironment.h:
     801        (JSC::JSLexicalEnvironment::create):
     802        (JSC::JSLexicalEnvironment::JSLexicalEnvironment):
     803        (JSC::JSLexicalEnvironment::registersOffset): Deleted.
     804        (JSC::JSLexicalEnvironment::storageOffset): Deleted.
     805        (JSC::JSLexicalEnvironment::storage): Deleted.
     806        (JSC::JSLexicalEnvironment::allocationSize): Deleted.
     807        (JSC::JSLexicalEnvironment::isValidIndex): Deleted.
     808        (JSC::JSLexicalEnvironment::isValid): Deleted.
     809        (JSC::JSLexicalEnvironment::registerAt): Deleted.
     810        * runtime/JSNameScope.cpp:
     811        (JSC::JSNameScope::visitChildren): Deleted.
     812        * runtime/JSNameScope.h:
     813        (JSC::JSNameScope::create):
     814        (JSC::JSNameScope::value):
     815        (JSC::JSNameScope::finishCreation):
     816        (JSC::JSNameScope::JSNameScope):
     817        * runtime/JSScope.cpp:
     818        (JSC::abstractAccess):
     819        * runtime/JSSegmentedVariableObject.cpp:
     820        (JSC::JSSegmentedVariableObject::findVariableIndex):
     821        (JSC::JSSegmentedVariableObject::addVariables):
     822        (JSC::JSSegmentedVariableObject::visitChildren):
     823        (JSC::JSSegmentedVariableObject::findRegisterIndex): Deleted.
     824        (JSC::JSSegmentedVariableObject::addRegisters): Deleted.
     825        * runtime/JSSegmentedVariableObject.h:
     826        (JSC::JSSegmentedVariableObject::variableAt):
     827        (JSC::JSSegmentedVariableObject::assertVariableIsInThisObject):
     828        (JSC::JSSegmentedVariableObject::registerAt): Deleted.
     829        (JSC::JSSegmentedVariableObject::assertRegisterIsInThisObject): Deleted.
     830        * runtime/JSSymbolTableObject.h:
     831        (JSC::JSSymbolTableObject::offsetOfSymbolTable):
     832        (JSC::symbolTableGet):
     833        (JSC::symbolTablePut):
     834        (JSC::symbolTablePutWithAttributes):
     835        * runtime/JSType.h:
     836        * runtime/Options.h:
     837        * runtime/ClonedArguments.cpp: Added.
     838        (JSC::ClonedArguments::ClonedArguments):
     839        (JSC::ClonedArguments::createEmpty):
     840        (JSC::ClonedArguments::createWithInlineFrame):
     841        (JSC::ClonedArguments::createWithMachineFrame):
     842        (JSC::ClonedArguments::createByCopyingFrom):
     843        (JSC::ClonedArguments::createStructure):
     844        (JSC::ClonedArguments::getOwnPropertySlot):
     845        (JSC::ClonedArguments::getOwnPropertyNames):
     846        (JSC::ClonedArguments::put):
     847        (JSC::ClonedArguments::deleteProperty):
     848        (JSC::ClonedArguments::defineOwnProperty):
     849        (JSC::ClonedArguments::materializeSpecials):
     850        (JSC::ClonedArguments::materializeSpecialsIfNecessary):
     851        * runtime/ClonedArguments.h: Added.
     852        (JSC::ClonedArguments::specialsMaterialized):
     853        * runtime/ScopeOffset.cpp: Added.
     854        (JSC::ScopeOffset::dump):
     855        * runtime/ScopeOffset.h: Added.
     856        (JSC::ScopeOffset::ScopeOffset):
     857        * runtime/ScopedArguments.cpp: Added.
     858        (JSC::ScopedArguments::ScopedArguments):
     859        (JSC::ScopedArguments::finishCreation):
     860        (JSC::ScopedArguments::createUninitialized):
     861        (JSC::ScopedArguments::create):
     862        (JSC::ScopedArguments::createByCopying):
     863        (JSC::ScopedArguments::createByCopyingFrom):
     864        (JSC::ScopedArguments::visitChildren):
     865        (JSC::ScopedArguments::createStructure):
     866        (JSC::ScopedArguments::overrideThings):
     867        (JSC::ScopedArguments::overrideThingsIfNecessary):
     868        (JSC::ScopedArguments::overrideArgument):
     869        (JSC::ScopedArguments::copyToArguments):
     870        * runtime/ScopedArguments.h: Added.
     871        (JSC::ScopedArguments::internalLength):
     872        (JSC::ScopedArguments::length):
     873        (JSC::ScopedArguments::canAccessIndexQuickly):
     874        (JSC::ScopedArguments::getIndexQuickly):
     875        (JSC::ScopedArguments::setIndexQuickly):
     876        (JSC::ScopedArguments::callee):
     877        (JSC::ScopedArguments::overrodeThings):
     878        (JSC::ScopedArguments::offsetOfOverrodeThings):
     879        (JSC::ScopedArguments::offsetOfTotalLength):
     880        (JSC::ScopedArguments::offsetOfTable):
     881        (JSC::ScopedArguments::offsetOfScope):
     882        (JSC::ScopedArguments::overflowStorageOffset):
     883        (JSC::ScopedArguments::allocationSize):
     884        (JSC::ScopedArguments::overflowStorage):
     885        * runtime/ScopedArgumentsTable.cpp: Added.
     886        (JSC::ScopedArgumentsTable::ScopedArgumentsTable):
     887        (JSC::ScopedArgumentsTable::~ScopedArgumentsTable):
     888        (JSC::ScopedArgumentsTable::destroy):
     889        (JSC::ScopedArgumentsTable::create):
     890        (JSC::ScopedArgumentsTable::clone):
     891        (JSC::ScopedArgumentsTable::setLength):
     892        (JSC::ScopedArgumentsTable::set):
     893        (JSC::ScopedArgumentsTable::createStructure):
     894        * runtime/ScopedArgumentsTable.h: Added.
     895        (JSC::ScopedArgumentsTable::length):
     896        (JSC::ScopedArgumentsTable::get):
     897        (JSC::ScopedArgumentsTable::lock):
     898        (JSC::ScopedArgumentsTable::offsetOfLength):
     899        (JSC::ScopedArgumentsTable::offsetOfArguments):
     900        (JSC::ScopedArgumentsTable::at):
     901        * runtime/SymbolTable.cpp:
     902        (JSC::SymbolTableEntry::prepareToWatch):
     903        (JSC::SymbolTable::SymbolTable):
     904        (JSC::SymbolTable::visitChildren):
     905        (JSC::SymbolTable::localToEntry):
     906        (JSC::SymbolTable::entryFor):
     907        (JSC::SymbolTable::cloneScopePart):
     908        (JSC::SymbolTable::prepareForTypeProfiling):
     909        (JSC::SymbolTable::uniqueIDForOffset):
     910        (JSC::SymbolTable::globalTypeSetForOffset):
     911        (JSC::SymbolTable::cloneCapturedNames): Deleted.
     912        (JSC::SymbolTable::uniqueIDForRegister): Deleted.
     913        (JSC::SymbolTable::globalTypeSetForRegister): Deleted.
     914        * runtime/SymbolTable.h:
     915        (JSC::SymbolTableEntry::varOffsetFromBits):
     916        (JSC::SymbolTableEntry::scopeOffsetFromBits):
     917        (JSC::SymbolTableEntry::Fast::varOffset):
     918        (JSC::SymbolTableEntry::Fast::scopeOffset):
     919        (JSC::SymbolTableEntry::Fast::isDontEnum):
     920        (JSC::SymbolTableEntry::Fast::getAttributes):
     921        (JSC::SymbolTableEntry::SymbolTableEntry):
     922        (JSC::SymbolTableEntry::varOffset):
     923        (JSC::SymbolTableEntry::isWatchable):
     924        (JSC::SymbolTableEntry::scopeOffset):
     925        (JSC::SymbolTableEntry::setAttributes):
     926        (JSC::SymbolTableEntry::constantMode):
     927        (JSC::SymbolTableEntry::isDontEnum):
     928        (JSC::SymbolTableEntry::disableWatching):
     929        (JSC::SymbolTableEntry::pack):
     930        (JSC::SymbolTableEntry::isValidVarOffset):
     931        (JSC::SymbolTable::createNameScopeTable):
     932        (JSC::SymbolTable::maxScopeOffset):
     933        (JSC::SymbolTable::didUseScopeOffset):
     934        (JSC::SymbolTable::didUseVarOffset):
     935        (JSC::SymbolTable::scopeSize):
     936        (JSC::SymbolTable::nextScopeOffset):
     937        (JSC::SymbolTable::takeNextScopeOffset):
     938        (JSC::SymbolTable::add):
     939        (JSC::SymbolTable::set):
     940        (JSC::SymbolTable::argumentsLength):
     941        (JSC::SymbolTable::setArgumentsLength):
     942        (JSC::SymbolTable::argumentOffset):
     943        (JSC::SymbolTable::setArgumentOffset):
     944        (JSC::SymbolTable::arguments):
     945        (JSC::SlowArgument::SlowArgument): Deleted.
     946        (JSC::SymbolTableEntry::Fast::getIndex): Deleted.
     947        (JSC::SymbolTableEntry::getIndex): Deleted.
     948        (JSC::SymbolTableEntry::isValidIndex): Deleted.
     949        (JSC::SymbolTable::captureStart): Deleted.
     950        (JSC::SymbolTable::setCaptureStart): Deleted.
     951        (JSC::SymbolTable::captureEnd): Deleted.
     952        (JSC::SymbolTable::setCaptureEnd): Deleted.
     953        (JSC::SymbolTable::captureCount): Deleted.
     954        (JSC::SymbolTable::isCaptured): Deleted.
     955        (JSC::SymbolTable::parameterCount): Deleted.
     956        (JSC::SymbolTable::parameterCountIncludingThis): Deleted.
     957        (JSC::SymbolTable::setParameterCountIncludingThis): Deleted.
     958        (JSC::SymbolTable::slowArguments): Deleted.
     959        (JSC::SymbolTable::setSlowArguments): Deleted.
     960        * runtime/VM.cpp:
     961        (JSC::VM::VM):
     962        * runtime/VM.h:
     963        * runtime/VarOffset.cpp: Added.
     964        (JSC::VarOffset::dump):
     965        (WTF::printInternal):
     966        * runtime/VarOffset.h: Added.
     967        (JSC::VarOffset::VarOffset):
     968        (JSC::VarOffset::assemble):
     969        (JSC::VarOffset::isValid):
     970        (JSC::VarOffset::operator!):
     971        (JSC::VarOffset::kind):
     972        (JSC::VarOffset::isStack):
     973        (JSC::VarOffset::isScope):
     974        (JSC::VarOffset::isDirectArgument):
     975        (JSC::VarOffset::stackOffsetUnchecked):
     976        (JSC::VarOffset::scopeOffsetUnchecked):
     977        (JSC::VarOffset::capturedArgumentsOffsetUnchecked):
     978        (JSC::VarOffset::stackOffset):
     979        (JSC::VarOffset::scopeOffset):
     980        (JSC::VarOffset::capturedArgumentsOffset):
     981        (JSC::VarOffset::rawOffset):
     982        (JSC::VarOffset::checkSanity):
     983        (JSC::VarOffset::operator==):
     984        (JSC::VarOffset::operator!=):
     985        (JSC::VarOffset::hash):
     986        (JSC::VarOffset::isHashTableDeletedValue):
     987        (JSC::VarOffsetHash::hash):
     988        (JSC::VarOffsetHash::equal):
     989        * tests/stress/arguments-exit-strict-mode.js: Added.
     990        * tests/stress/arguments-exit.js: Added.
     991        * tests/stress/arguments-inlined-exit-strict-mode-fixed.js: Added.
     992        * tests/stress/arguments-inlined-exit-strict-mode.js: Added.
     993        * tests/stress/arguments-inlined-exit.js: Added.
     994        * tests/stress/arguments-interference.js: Added.
     995        * tests/stress/arguments-interference-cfg.js: Added.
     996        * tests/stress/dead-get-closure-var.js: Added.
     997        * tests/stress/get-declared-unpassed-argument-in-direct-arguments.js: Added.
     998        * tests/stress/get-declared-unpassed-argument-in-scoped-arguments.js: Added.
     999        * tests/stress/varargs-closure-inlined-exit-strict-mode.js: Added.
     1000        * tests/stress/varargs-closure-inlined-exit.js: Added.
     1001        * tests/stress/varargs-exit.js: Added.
     1002        * tests/stress/varargs-inlined-exit.js: Added.
     1003        * tests/stress/varargs-inlined-simple-exit-aliasing-weird-reversed-args.js: Added.
     1004        * tests/stress/varargs-inlined-simple-exit-aliasing-weird.js: Added.
     1005        * tests/stress/varargs-inlined-simple-exit-aliasing.js: Added.
     1006        * tests/stress/varargs-inlined-simple-exit.js: Added.
     1007        * tests/stress/varargs-too-few-arguments.js: Added.
     1008        * tests/stress/varargs-varargs-closure-inlined-exit.js: Added.
     1009        * tests/stress/varargs-varargs-inlined-exit-strict-mode.js: Added.
     1010        * tests/stress/varargs-varargs-inlined-exit.js: Added.
     1011
    110122015-03-25  Andy Estes  <aestes@apple.com>
    21013
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj

    r181990 r181993  
    363363    <ClCompile Include="..\dfg\DFGAbstractHeap.cpp" />
    364364    <ClCompile Include="..\dfg\DFGAbstractValue.cpp" />
    365     <ClCompile Include="..\dfg\DFGArgumentsSimplificationPhase.cpp" />
     365    <ClCompile Include="..\dfg\DFGArgumentsEliminationPhase.cpp" />
     366    <ClCompile Include="..\dfg\DFGArgumentsUtilities.cpp" />
    366367    <ClCompile Include="..\dfg\DFGArithMode.cpp" />
    367368    <ClCompile Include="..\dfg\DFGArrayMode.cpp" />
     
    479480    <ClCompile Include="..\dfg\DFGValueSource.cpp" />
    480481    <ClCompile Include="..\dfg\DFGValueStrength.cpp" />
     482    <ClCompile Include="..\dfg\DFGVarargsForwardingPhase.cpp" />
    481483    <ClCompile Include="..\dfg\DFGVariableAccessData.cpp" />
    482484    <ClCompile Include="..\dfg\DFGVariableAccessDataDump.cpp" />
     
    668670    <ClCompile Include="..\profiler\ProfilerProfiledBytecodes.cpp" />
    669671    <ClCompile Include="..\runtime\ArgList.cpp" />
    670     <ClCompile Include="..\runtime\Arguments.cpp" />
    671672    <ClCompile Include="..\runtime\ArgumentsIteratorConstructor.cpp" />
    672673    <ClCompile Include="..\runtime\ArgumentsIteratorPrototype.cpp" />
     
    683684    <ClCompile Include="..\runtime\BooleanPrototype.cpp" />
    684685    <ClCompile Include="..\runtime\CallData.cpp" />
     686    <ClCompile Include="..\runtime\ClonedArguments.cpp" />
    685687    <ClCompile Include="..\runtime\CodeCache.cpp" />
    686688    <ClCompile Include="..\runtime\CodeSpecializationKind.cpp" />
     
    692694    <ClCompile Include="..\runtime\ConsoleClient.cpp" />
    693695    <ClCompile Include="..\runtime\ConsolePrototype.cpp" />
     696    <ClCompile Include="..\runtime\ConstantMode.cpp" />
    694697    <ClCompile Include="..\runtime\ConstructData.cpp" />
    695698    <ClCompile Include="..\runtime\ControlFlowProfiler.cpp" />
     
    700703    <ClCompile Include="..\runtime\DateInstance.cpp" />
    701704    <ClCompile Include="..\runtime\DatePrototype.cpp" />
     705    <ClCompile Include="..\runtime\DirectArguments.cpp" />
     706    <ClCompile Include="..\runtime\DirectArgumentsOffset.cpp" />
    702707    <ClCompile Include="..\runtime\DumpContext.cpp" />
    703708    <ClCompile Include="..\runtime\Error.cpp" />
     
    810815    <ClCompile Include="..\runtime\SetIteratorPrototype.cpp" />
    811816    <ClCompile Include="..\runtime\SetPrototype.cpp" />
     817    <ClCompile Include="..\runtime\ScopeOffset.cpp" />
     818    <ClCompile Include="..\runtime\ScopedArguments.cpp" />
     819    <ClCompile Include="..\runtime\ScopedArgumentsTable.cpp" />
    812820    <ClCompile Include="..\runtime\SimpleTypedArrayController.cpp" />
    813821    <ClCompile Include="..\runtime\SmallStrings.cpp" />
     
    838846    <ClCompile Include="..\runtime\VM.cpp" />
    839847    <ClCompile Include="..\runtime\VMEntryScope.cpp" />
     848    <ClCompile Include="..\runtime\VarOffset.cpp" />
    840849    <ClCompile Include="..\runtime\Watchdog.cpp" />
    841850    <ClCompile Include="..\runtime\WatchdogNone.cpp" />
     
    942951    <ClInclude Include="..\bytecode\ByValInfo.h" />
    943952    <ClInclude Include="..\bytecode\BytecodeBasicBlock.h" />
     953    <ClInclude Include="..\bytecode\BytecodeKills.h" />
    944954    <ClInclude Include="..\bytecode\BytecodeLivenessAnalysis.h" />
    945955    <ClInclude Include="..\bytecode\BytecodeUseDef.h" />
     
    10171027    <ClInclude Include="..\dfg\DFGAnalysis.h" />
    10181028    <ClInclude Include="..\dfg\DFGArgumentPosition.h" />
    1019     <ClInclude Include="..\dfg\DFGArgumentsSimplificationPhase.h" />
     1029    <ClInclude Include="..\dfg\DFGArgumentsEliminationPhase.h" />
     1030    <ClInclude Include="..\dfg\DFGArgumentsUtilities.h" />
    10201031    <ClInclude Include="..\dfg\DFGArrayifySlowPathGenerator.h" />
    10211032    <ClInclude Include="..\dfg\DFGArithMode.h" />
     
    10361047    <ClInclude Include="..\dfg\DFGByteCodeParser.h" />
    10371048    <ClInclude Include="..\dfg\DFGCallArrayAllocatorSlowPathGenerator.h" />
     1049    <ClInclude Include="..\dfg\DFGCallCreateDirectArgumentsSlowPathGenerator.h" />
    10381050    <ClInclude Include="..\dfg\DFGCapabilities.h" />
    10391051    <ClInclude Include="..\dfg\DFGCCallHelpers.h" />
     
    10701082    <ClInclude Include="..\dfg\DFGFlushedAt.h" />
    10711083    <ClInclude Include="..\dfg\DFGFlushFormat.h" />
     1084    <ClInclude Include="..\dfg\DFGForAllKills.h" />
    10721085    <ClInclude Include="..\dfg\DFGFPRInfo.h" />
    10731086    <ClInclude Include="..\dfg\DFGFrozenValue.h" />
     
    11641177    <ClInclude Include="..\dfg\DFGValueSource.h" />
    11651178    <ClInclude Include="..\dfg\DFGValueStrength.h" />
     1179    <ClInclude Include="..\dfg\DFGVarargsForwardingPhase.h" />
    11661180    <ClInclude Include="..\dfg\DFGVariableAccessData.h" />
    11671181    <ClInclude Include="..\dfg\DFGVariableAccessDataDump.h" />
     
    14251439    <ClInclude Include="..\profiler\ProfilerProfiledBytecodes.h" />
    14261440    <ClInclude Include="..\runtime\ArgList.h" />
    1427     <ClInclude Include="..\runtime\Arguments.h" />
     1441    <ClInclude Include="..\runtime\ArgumentsMode.h" />
    14281442    <ClInclude Include="..\runtime\ArrayBuffer.h" />
    14291443    <ClInclude Include="..\runtime\ArrayBufferNeuteringWatchpoint.h" />
     
    14451459    <ClInclude Include="..\runtime\CallData.h" />
    14461460    <ClInclude Include="..\runtime\ClassInfo.h" />
     1461    <ClInclude Include="..\runtime\ClonedArguments.h" />
    14471462    <ClInclude Include="..\runtime\CodeCache.h" />
    14481463    <ClInclude Include="..\runtime\CodeSpecializationKind.h" />
     
    14651480    <ClInclude Include="..\runtime\DateInstanceCache.h" />
    14661481    <ClInclude Include="..\runtime\DatePrototype.h" />
     1482    <ClInclude Include="..\runtime\DirectArguments.h" />
     1483    <ClInclude Include="..\runtime\DirectArgumentsOffset.h" />
    14671484    <ClInclude Include="..\runtime\DumpContext.h" />
    14681485    <ClInclude Include="..\runtime\EnumerationMode.h" />
     
    14811498    <ClInclude Include="..\runtime\FunctionHasExecutedCache.h" />
    14821499    <ClInclude Include="..\runtime\FunctionPrototype.h" />
     1500    <ClInclude Include="..\runtime\GenericArguments.h" />
     1501    <ClInclude Include="..\runtime\GenericArgumentsInlines.h" />
     1502    <ClInclude Include="..\runtime\GenericOffset.h" />
    14831503    <ClInclude Include="..\runtime\GenericTypedArrayView.h" />
    14841504    <ClInclude Include="..\runtime\GenericTypedArrayViewInlines.h" />
     
    16201640    <ClInclude Include="..\runtime\RuntimeType.h" />
    16211641    <ClInclude Include="..\runtime\SamplingCounter.h" />
     1642    <ClInclude Include="..\runtime\ScopeOffset.h" />
     1643    <ClInclude Include="..\runtime\ScopedArguments.h" />
     1644    <ClInclude Include="..\runtime\ScopedArgumentsTable.h" />
    16221645    <ClInclude Include="..\runtime\SetConstructor.h" />
    16231646    <ClInclude Include="..\runtime\SetIteratorConstructor.h" />
     
    16651688    <ClInclude Include="..\runtime\VM.h" />
    16661689    <ClInclude Include="..\runtime\VMEntryScope.h" />
     1690    <ClInclude Include="..\runtime\VarOffset.h" />
    16671691    <ClInclude Include="..\runtime\Watchdog.h" />
    16681692    <ClInclude Include="..\runtime\WeakGCMap.h" />
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r181990 r181993  
    105105                0F13E04E16164A1F00DC8DE7 /* IndexingType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F13E04C16164A1B00DC8DE7 /* IndexingType.cpp */; };
    106106                0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */; settings = {ATTRIBUTES = (Private, ); }; };
    107                 0F16015D156198C900C2587C /* DFGArgumentsSimplificationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F16015A156198BF00C2587C /* DFGArgumentsSimplificationPhase.cpp */; };
    108                 0F16015E156198C900C2587C /* DFGArgumentsSimplificationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F16015B156198BF00C2587C /* DFGArgumentsSimplificationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
    109107                0F190CAC189D82F6000AE5F0 /* ProfilerJettisonReason.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F190CAA189D82F6000AE5F0 /* ProfilerJettisonReason.cpp */; };
    110108                0F190CAD189D82F6000AE5F0 /* ProfilerJettisonReason.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F190CAB189D82F6000AE5F0 /* ProfilerJettisonReason.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    252250                0F2D4DEF19832DD3007D4B19 /* TypeSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2D4DE319832D91007D4B19 /* TypeSet.cpp */; };
    253251                0F2D4DF019832DD6007D4B19 /* TypeSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2D4DE419832D91007D4B19 /* TypeSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
     252                0F2DD80B1AB3D85800BBB8E8 /* BytecodeKills.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2DD80A1AB3D85800BBB8E8 /* BytecodeKills.h */; settings = {ATTRIBUTES = (Private, ); }; };
     253                0F2DD8111AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2DD80C1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.cpp */; };
     254                0F2DD8121AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2DD80D1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
     255                0F2DD8131AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2DD80E1AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.cpp */; };
     256                0F2DD8141AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2DD80F1AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
     257                0F2DD8151AB3D8BE00BBB8E8 /* DFGForAllKills.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2DD8101AB3D8BE00BBB8E8 /* DFGForAllKills.h */; settings = {ATTRIBUTES = (Private, ); }; };
    254258                0F2E892C16D028AD009E4FD2 /* UnusedPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = 65987F2F16828A7E003C2F8D /* UnusedPointer.h */; settings = {ATTRIBUTES = (Private, ); }; };
    255259                0F2E892D16D02BAF009E4FD2 /* DFGMinifiedID.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB4B51016B3A964003F696B /* DFGMinifiedID.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    442446                0F96EBB316676EF6008BADE3 /* CodeBlockWithJITType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F96EBB116676EF4008BADE3 /* CodeBlockWithJITType.h */; settings = {ATTRIBUTES = (Private, ); }; };
    443447                0F9749711687ADE400A4FF6A /* JSCellInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F97496F1687ADE200A4FF6A /* JSCellInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
     448                0F978B3B1AAEA71D007C7369 /* ConstantMode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F978B3A1AAEA71D007C7369 /* ConstantMode.cpp */; };
    444449                0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F98205D16BFE37F00240D02 /* PreciseJumpTargets.cpp */; };
    445450                0F98206116BFE38300240D02 /* PreciseJumpTargets.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F98205E16BFE37F00240D02 /* PreciseJumpTargets.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    499504                0FBC0AE81496C7C700D4FBDD /* DFGExitProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
    500505                0FBD7E691447999600481315 /* CodeOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBD7E671447998F00481315 /* CodeOrigin.h */; settings = {ATTRIBUTES = (Private, ); }; };
     506                0FBDB9AD1AB0FBC6000B57E5 /* DFGCallCreateDirectArgumentsSlowPathGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBDB9AC1AB0FBC6000B57E5 /* DFGCallCreateDirectArgumentsSlowPathGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
    501507                0FBE0F7216C1DB030082C5E8 /* DFGCPSRethreadingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBE0F6B16C1DB010082C5E8 /* DFGCPSRethreadingPhase.cpp */; };
    502508                0FBE0F7316C1DB050082C5E8 /* DFGCPSRethreadingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBE0F6C16C1DB010082C5E8 /* DFGCPSRethreadingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    605611                0FDDBFB51666EED800C55FEF /* DFGVariableAccessDataDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDDBFB21666EED500C55FEF /* DFGVariableAccessDataDump.cpp */; };
    606612                0FDDBFB61666EEDA00C55FEF /* DFGVariableAccessDataDump.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDDBFB31666EED500C55FEF /* DFGVariableAccessDataDump.h */; settings = {ATTRIBUTES = (Private, ); }; };
     613                0FE050141AA9091100D33B33 /* ArgumentsMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE0500C1AA9091100D33B33 /* ArgumentsMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
     614                0FE050151AA9091100D33B33 /* DirectArgumentsOffset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE0500D1AA9091100D33B33 /* DirectArgumentsOffset.cpp */; };
     615                0FE050161AA9091100D33B33 /* DirectArgumentsOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE0500E1AA9091100D33B33 /* DirectArgumentsOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
     616                0FE050171AA9091100D33B33 /* DirectArguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE0500F1AA9091100D33B33 /* DirectArguments.cpp */; };
     617                0FE050181AA9091100D33B33 /* DirectArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050101AA9091100D33B33 /* DirectArguments.h */; settings = {ATTRIBUTES = (Private, ); }; };
     618                0FE050191AA9091100D33B33 /* GenericArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050111AA9091100D33B33 /* GenericArguments.h */; settings = {ATTRIBUTES = (Private, ); }; };
     619                0FE0501A1AA9091100D33B33 /* GenericArgumentsInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050121AA9091100D33B33 /* GenericArgumentsInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
     620                0FE0501B1AA9091100D33B33 /* GenericOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050131AA9091100D33B33 /* GenericOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
     621                0FE050251AA9095600D33B33 /* ClonedArguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE0501C1AA9095600D33B33 /* ClonedArguments.cpp */; };
     622                0FE050261AA9095600D33B33 /* ClonedArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE0501D1AA9095600D33B33 /* ClonedArguments.h */; settings = {ATTRIBUTES = (Private, ); }; };
     623                0FE050271AA9095600D33B33 /* ScopedArguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE0501E1AA9095600D33B33 /* ScopedArguments.cpp */; };
     624                0FE050281AA9095600D33B33 /* ScopedArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE0501F1AA9095600D33B33 /* ScopedArguments.h */; settings = {ATTRIBUTES = (Private, ); }; };
     625                0FE050291AA9095600D33B33 /* ScopedArgumentsTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050201AA9095600D33B33 /* ScopedArgumentsTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
     626                0FE0502A1AA9095600D33B33 /* ScopeOffset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE050211AA9095600D33B33 /* ScopeOffset.cpp */; };
     627                0FE0502B1AA9095600D33B33 /* ScopeOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050221AA9095600D33B33 /* ScopeOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
     628                0FE0502C1AA9095600D33B33 /* VarOffset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE050231AA9095600D33B33 /* VarOffset.cpp */; };
     629                0FE0502D1AA9095600D33B33 /* VarOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE050241AA9095600D33B33 /* VarOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
     630                0FE0502F1AAA806900D33B33 /* ScopedArgumentsTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE0502E1AAA806900D33B33 /* ScopedArgumentsTable.cpp */; };
    607631                0FE228ED1436AB2700196C48 /* Options.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE228EB1436AB2300196C48 /* Options.h */; settings = {ATTRIBUTES = (Private, ); }; };
    608632                0FE228EE1436AB2C00196C48 /* Options.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE228EA1436AB2300196C48 /* Options.cpp */; };
     633                0FE254F61ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE254F41ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.cpp */; };
     634                0FE254F71ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE254F51ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
    609635                0FE7211D193B9C590031F6ED /* DFGTransition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE7211B193B9C590031F6ED /* DFGTransition.cpp */; };
    610636                0FE7211E193B9C590031F6ED /* DFGTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE7211C193B9C590031F6ED /* DFGTransition.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    804830                147B84630E6DE6B1004775A4 /* PutPropertySlot.h in Headers */ = {isa = PBXBuildFile; fileRef = 147B84620E6DE6B1004775A4 /* PutPropertySlot.h */; settings = {ATTRIBUTES = (Private, ); }; };
    805831                147F39BD107EC37600427A48 /* ArgList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCF605110E203EF800B9A64D /* ArgList.cpp */; };
    806                 147F39BE107EC37600427A48 /* Arguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC257DE50E1F51C50016B6C9 /* Arguments.cpp */; };
    807832                147F39BF107EC37600427A48 /* ArrayConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7952060E15E8A800A898AB /* ArrayConstructor.cpp */; };
    808833                147F39C0107EC37600427A48 /* ArrayPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A84D0255597D01FF60F7 /* ArrayPrototype.cpp */; };
     
    15241549                BC18C52C0E16FCD200B34460 /* RegExpObject.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C52B0E16FCD200B34460 /* RegExpObject.lut.h */; };
    15251550                BC18C52E0E16FCE100B34460 /* Lexer.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C52D0E16FCE100B34460 /* Lexer.lut.h */; };
    1526                 BC257DE80E1F51C50016B6C9 /* Arguments.h in Headers */ = {isa = PBXBuildFile; fileRef = BC257DE60E1F51C50016B6C9 /* Arguments.h */; };
    15271551                BC3046070E1F497F003232CF /* Error.h in Headers */ = {isa = PBXBuildFile; fileRef = BC3046060E1F497F003232CF /* Error.h */; settings = {ATTRIBUTES = (Private, ); }; };
    15281552                BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    17981822                0F13E04C16164A1B00DC8DE7 /* IndexingType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IndexingType.cpp; sourceTree = "<group>"; };
    17991823                0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonSlowPaths.h; sourceTree = "<group>"; };
    1800                 0F16015A156198BF00C2587C /* DFGArgumentsSimplificationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGArgumentsSimplificationPhase.cpp; path = dfg/DFGArgumentsSimplificationPhase.cpp; sourceTree = "<group>"; };
    1801                 0F16015B156198BF00C2587C /* DFGArgumentsSimplificationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArgumentsSimplificationPhase.h; path = dfg/DFGArgumentsSimplificationPhase.h; sourceTree = "<group>"; };
    18021824                0F190CAA189D82F6000AE5F0 /* ProfilerJettisonReason.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerJettisonReason.cpp; path = profiler/ProfilerJettisonReason.cpp; sourceTree = "<group>"; };
    18031825                0F190CAB189D82F6000AE5F0 /* ProfilerJettisonReason.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerJettisonReason.h; path = profiler/ProfilerJettisonReason.h; sourceTree = "<group>"; };
     
    19461968                0F2D4DE619832DAC007D4B19 /* ToThisStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ToThisStatus.h; sourceTree = "<group>"; };
    19471969                0F2D4DE719832DAC007D4B19 /* TypeLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeLocation.h; sourceTree = "<group>"; };
     1970                0F2DD80A1AB3D85800BBB8E8 /* BytecodeKills.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeKills.h; sourceTree = "<group>"; };
     1971                0F2DD80C1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGArgumentsEliminationPhase.cpp; path = dfg/DFGArgumentsEliminationPhase.cpp; sourceTree = "<group>"; };
     1972                0F2DD80D1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArgumentsEliminationPhase.h; path = dfg/DFGArgumentsEliminationPhase.h; sourceTree = "<group>"; };
     1973                0F2DD80E1AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGArgumentsUtilities.cpp; path = dfg/DFGArgumentsUtilities.cpp; sourceTree = "<group>"; };
     1974                0F2DD80F1AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArgumentsUtilities.h; path = dfg/DFGArgumentsUtilities.h; sourceTree = "<group>"; };
     1975                0F2DD8101AB3D8BE00BBB8E8 /* DFGForAllKills.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGForAllKills.h; path = dfg/DFGForAllKills.h; sourceTree = "<group>"; };
    19481976                0F2FC77016E12F6F0038D976 /* DFGDCEPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDCEPhase.cpp; path = dfg/DFGDCEPhase.cpp; sourceTree = "<group>"; };
    19491977                0F2FC77116E12F6F0038D976 /* DFGDCEPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDCEPhase.h; path = dfg/DFGDCEPhase.h; sourceTree = "<group>"; };
     
    21332161                0F96EBB116676EF4008BADE3 /* CodeBlockWithJITType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeBlockWithJITType.h; sourceTree = "<group>"; };
    21342162                0F97496F1687ADE200A4FF6A /* JSCellInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCellInlines.h; sourceTree = "<group>"; };
     2163                0F978B3A1AAEA71D007C7369 /* ConstantMode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConstantMode.cpp; sourceTree = "<group>"; };
    21352164                0F98205D16BFE37F00240D02 /* PreciseJumpTargets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PreciseJumpTargets.cpp; sourceTree = "<group>"; };
    21362165                0F98205E16BFE37F00240D02 /* PreciseJumpTargets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PreciseJumpTargets.h; sourceTree = "<group>"; };
     
    22002229                0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DFGExitProfile.h; sourceTree = "<group>"; };
    22012230                0FBD7E671447998F00481315 /* CodeOrigin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeOrigin.h; sourceTree = "<group>"; };
     2231                0FBDB9AC1AB0FBC6000B57E5 /* DFGCallCreateDirectArgumentsSlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCallCreateDirectArgumentsSlowPathGenerator.h; path = dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h; sourceTree = "<group>"; };
    22022232                0FBE0F6B16C1DB010082C5E8 /* DFGCPSRethreadingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCPSRethreadingPhase.cpp; path = dfg/DFGCPSRethreadingPhase.cpp; sourceTree = "<group>"; };
    22032233                0FBE0F6C16C1DB010082C5E8 /* DFGCPSRethreadingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCPSRethreadingPhase.h; path = dfg/DFGCPSRethreadingPhase.h; sourceTree = "<group>"; };
     
    23102340                0FDDBFB21666EED500C55FEF /* DFGVariableAccessDataDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVariableAccessDataDump.cpp; path = dfg/DFGVariableAccessDataDump.cpp; sourceTree = "<group>"; };
    23112341                0FDDBFB31666EED500C55FEF /* DFGVariableAccessDataDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVariableAccessDataDump.h; path = dfg/DFGVariableAccessDataDump.h; sourceTree = "<group>"; };
     2342                0FE0500C1AA9091100D33B33 /* ArgumentsMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArgumentsMode.h; sourceTree = "<group>"; };
     2343                0FE0500D1AA9091100D33B33 /* DirectArgumentsOffset.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectArgumentsOffset.cpp; sourceTree = "<group>"; };
     2344                0FE0500E1AA9091100D33B33 /* DirectArgumentsOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectArgumentsOffset.h; sourceTree = "<group>"; };
     2345                0FE0500F1AA9091100D33B33 /* DirectArguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectArguments.cpp; sourceTree = "<group>"; };
     2346                0FE050101AA9091100D33B33 /* DirectArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectArguments.h; sourceTree = "<group>"; };
     2347                0FE050111AA9091100D33B33 /* GenericArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenericArguments.h; sourceTree = "<group>"; };
     2348                0FE050121AA9091100D33B33 /* GenericArgumentsInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenericArgumentsInlines.h; sourceTree = "<group>"; };
     2349                0FE050131AA9091100D33B33 /* GenericOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenericOffset.h; sourceTree = "<group>"; };
     2350                0FE0501C1AA9095600D33B33 /* ClonedArguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClonedArguments.cpp; sourceTree = "<group>"; };
     2351                0FE0501D1AA9095600D33B33 /* ClonedArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClonedArguments.h; sourceTree = "<group>"; };
     2352                0FE0501E1AA9095600D33B33 /* ScopedArguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScopedArguments.cpp; sourceTree = "<group>"; };
     2353                0FE0501F1AA9095600D33B33 /* ScopedArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopedArguments.h; sourceTree = "<group>"; };
     2354                0FE050201AA9095600D33B33 /* ScopedArgumentsTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopedArgumentsTable.h; sourceTree = "<group>"; };
     2355                0FE050211AA9095600D33B33 /* ScopeOffset.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScopeOffset.cpp; sourceTree = "<group>"; };
     2356                0FE050221AA9095600D33B33 /* ScopeOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopeOffset.h; sourceTree = "<group>"; };
     2357                0FE050231AA9095600D33B33 /* VarOffset.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VarOffset.cpp; sourceTree = "<group>"; };
     2358                0FE050241AA9095600D33B33 /* VarOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VarOffset.h; sourceTree = "<group>"; };
     2359                0FE0502E1AAA806900D33B33 /* ScopedArgumentsTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScopedArgumentsTable.cpp; sourceTree = "<group>"; };
    23122360                0FE228EA1436AB2300196C48 /* Options.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Options.cpp; sourceTree = "<group>"; };
    23132361                0FE228EB1436AB2300196C48 /* Options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Options.h; sourceTree = "<group>"; };
     2362                0FE254F41ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVarargsForwardingPhase.cpp; path = dfg/DFGVarargsForwardingPhase.cpp; sourceTree = "<group>"; };
     2363                0FE254F51ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVarargsForwardingPhase.h; path = dfg/DFGVarargsForwardingPhase.h; sourceTree = "<group>"; };
    23142364                0FE7211B193B9C590031F6ED /* DFGTransition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGTransition.cpp; path = dfg/DFGTransition.cpp; sourceTree = "<group>"; };
    23152365                0FE7211C193B9C590031F6ED /* DFGTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGTransition.h; path = dfg/DFGTransition.h; sourceTree = "<group>"; };
     
    31993249                BC22A3990E16E14800AF21C8 /* JSObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSObject.h; sourceTree = "<group>"; };
    32003250                BC22A39A0E16E14800AF21C8 /* JSEnvironmentRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSEnvironmentRecord.cpp; sourceTree = "<group>"; };
    3201                 BC257DE50E1F51C50016B6C9 /* Arguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Arguments.cpp; sourceTree = "<group>"; };
    3202                 BC257DE60E1F51C50016B6C9 /* Arguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Arguments.h; sourceTree = "<group>"; };
    32033251                BC2680C00E16D4E900A06E92 /* FunctionConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionConstructor.cpp; sourceTree = "<group>"; };
    32043252                BC2680C10E16D4E900A06E92 /* FunctionConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionConstructor.h; sourceTree = "<group>"; };
     
    42354283                                BCF605110E203EF800B9A64D /* ArgList.cpp */,
    42364284                                BCF605120E203EF800B9A64D /* ArgList.h */,
    4237                                 BC257DE50E1F51C50016B6C9 /* Arguments.cpp */,
    4238                                 BC257DE60E1F51C50016B6C9 /* Arguments.h */,
    42394285                                A76140C7182982CB00750624 /* ArgumentsIteratorConstructor.cpp */,
    42404286                                A76140C8182982CB00750624 /* ArgumentsIteratorConstructor.h */,
    42414287                                A76140C9182982CB00750624 /* ArgumentsIteratorPrototype.cpp */,
    42424288                                A76140CA182982CB00750624 /* ArgumentsIteratorPrototype.h */,
     4289                                0FE0500C1AA9091100D33B33 /* ArgumentsMode.h */,
    42434290                                0F6B1CB71861244C00845D97 /* ArityCheckMode.h */,
    42444291                                A7A8AF2517ADB5F2005AB174 /* ArrayBuffer.cpp */,
     
    42754322                                145C507F0D9DF63B0088F6B9 /* CallData.h */,
    42764323                                BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */,
     4324                                0FE0501C1AA9095600D33B33 /* ClonedArguments.cpp */,
     4325                                0FE0501D1AA9095600D33B33 /* ClonedArguments.h */,
    42774326                                A77F181F164088B200640A47 /* CodeCache.cpp */,
    42784327                                A77F1820164088B200640A47 /* CodeCache.h */,
     
    42954344                                A53CE08218BC1A5600BEDF76 /* ConsolePrototype.h */,
    42964345                                A5FD0071189B038C00633231 /* ConsoleTypes.h */,
     4346                                0F978B3A1AAEA71D007C7369 /* ConstantMode.cpp */,
    42974347                                0FFC99D0184EC8AD009C10AB /* ConstantMode.h */,
    42984348                                BCA62DFF0E2826310004F30D /* ConstructData.cpp */,
     
    43134363                                BCD203470E17135E002C7E82 /* DatePrototype.cpp */,
    43144364                                BCD203480E17135E002C7E82 /* DatePrototype.h */,
     4365                                0FE0500F1AA9091100D33B33 /* DirectArguments.cpp */,
     4366                                0FE050101AA9091100D33B33 /* DirectArguments.h */,
     4367                                0FE0500D1AA9091100D33B33 /* DirectArgumentsOffset.cpp */,
     4368                                0FE0500E1AA9091100D33B33 /* DirectArgumentsOffset.h */,
    43154369                                A70447EB17A0BD7000F5898E /* DumpContext.cpp */,
    43164370                                A70447EC17A0BD7000F5898E /* DumpContext.h */,
     
    43424396                                F692A85C0255597D01FF60F7 /* FunctionPrototype.cpp */,
    43434397                                F692A85D0255597D01FF60F7 /* FunctionPrototype.h */,
     4398                                0FE050111AA9091100D33B33 /* GenericArguments.h */,
     4399                                0FE050121AA9091100D33B33 /* GenericArgumentsInlines.h */,
     4400                                0FE050131AA9091100D33B33 /* GenericOffset.h */,
    43444401                                0F2B66B217B6B5AB00A7AE3F /* GenericTypedArrayView.h */,
    43454402                                0F2B66B317B6B5AB00A7AE3F /* GenericTypedArrayViewInlines.h */,
     
    45794636                                0F7700911402FF280078EB39 /* SamplingCounter.cpp */,
    45804637                                0F77008E1402FDD60078EB39 /* SamplingCounter.h */,
     4638                                0FE0501E1AA9095600D33B33 /* ScopedArguments.cpp */,
     4639                                0FE0501F1AA9095600D33B33 /* ScopedArguments.h */,
     4640                                0FE0502E1AAA806900D33B33 /* ScopedArgumentsTable.cpp */,
     4641                                0FE050201AA9095600D33B33 /* ScopedArgumentsTable.h */,
     4642                                0FE050211AA9095600D33B33 /* ScopeOffset.cpp */,
     4643                                0FE050221AA9095600D33B33 /* ScopeOffset.h */,
    45814644                                A7299DA317D12858005F5FF9 /* SetConstructor.cpp */,
    45824645                                A7299DA417D12858005F5FF9 /* SetConstructor.h */,
     
    46554718                                866739D113BFDE710023D87C /* Uint16WithFraction.h */,
    46564719                                A7A8AF3317ADB5F3005AB174 /* Uint32Array.h */,
     4720                                0FE050231AA9095600D33B33 /* VarOffset.cpp */,
     4721                                0FE050241AA9095600D33B33 /* VarOffset.h */,
    46574722                                E18E3A570DF9278C00D90B34 /* VM.cpp */,
    46584723                                E18E3A560DF9278C00D90B34 /* VM.h */,
     
    47254790                                A73781091799EA2E00817533 /* DFGAnalysis.h */,
    47264791                                0F1E3A431534CBAD000F9456 /* DFGArgumentPosition.h */,
    4727                                 0F16015A156198BF00C2587C /* DFGArgumentsSimplificationPhase.cpp */,
    4728                                 0F16015B156198BF00C2587C /* DFGArgumentsSimplificationPhase.h */,
     4792                                0F2DD80C1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.cpp */,
     4793                                0F2DD80D1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.h */,
     4794                                0F2DD80E1AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.cpp */,
     4795                                0F2DD80F1AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.h */,
    47294796                                0F48531F187750560083B687 /* DFGArithMode.cpp */,
    47304797                                0F485320187750560083B687 /* DFGArithMode.h */,
     
    47564823                                86EC9DB51328DF82002B2AD7 /* DFGByteCodeParser.h */,
    47574824                                0F256C341627B0AA007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h */,
     4825                                0FBDB9AC1AB0FBC6000B57E5 /* DFGCallCreateDirectArgumentsSlowPathGenerator.h */,
    47584826                                0FD82E1E14172C2F00179C94 /* DFGCapabilities.cpp */,
    47594827                                0FD82E1F14172C2F00179C94 /* DFGCapabilities.h */,
     
    48184886                                A7D89CE817A0B8CC00773AD8 /* DFGFlushFormat.cpp */,
    48194887                                A7D89CE917A0B8CC00773AD8 /* DFGFlushFormat.h */,
     4888                                0F2DD8101AB3D8BE00BBB8E8 /* DFGForAllKills.h */,
    48204889                                0F69CC86193AC60A0045759E /* DFGFrozenValue.cpp */,
    48214890                                0F69CC87193AC60A0045759E /* DFGFrozenValue.h */,
     
    49855054                                0F0123301944EA1B00843A0C /* DFGValueStrength.cpp */,
    49865055                                0F0123311944EA1B00843A0C /* DFGValueStrength.h */,
     5056                                0FE254F41ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.cpp */,
     5057                                0FE254F51ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.h */,
    49875058                                0F6E845919030BEF00562741 /* DFGVariableAccessData.cpp */,
    49885059                                0F620172143FCD2F0068B77C /* DFGVariableAccessData.h */,
     
    51065177                                C2FCAE0D17A9C24E0034C735 /* BytecodeBasicBlock.h */,
    51075178                                0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */,
     5179                                0F2DD80A1AB3D85800BBB8E8 /* BytecodeKills.h */,
    51085180                                6529FB3118B2D99900C61102 /* BytecodeList.json */,
    51095181                                C2FCAE0E17A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp */,
     
    54605532                                0FFA549816B8835300B3A982 /* A64DOpcode.h in Headers */,
    54615533                                860161E30F3A83C100F84710 /* AbstractMacroAssembler.h in Headers */,
     5534                                0FE050291AA9095600D33B33 /* ScopedArgumentsTable.h in Headers */,
    54625535                                0F55F0F514D1063C00AC7649 /* AbstractPC.h in Headers */,
    54635536                                2A48D1911772365B00C65A5F /* APICallbackFunction.h in Headers */,
     
    54655538                                BCF605140E203EF800B9A64D /* ArgList.h in Headers */,
    54665539                                2A88067919107D5500CB0BBB /* DFGFunctionWhitelist.h in Headers */,
    5467                                 BC257DE80E1F51C50016B6C9 /* Arguments.h in Headers */,
    54685540                                A76140CE182982CB00750624 /* ArgumentsIteratorConstructor.h in Headers */,
    54695541                                A76140D0182982CB00750624 /* ArgumentsIteratorPrototype.h in Headers */,
     
    54725544                                A1A009C11831A26E00CF8711 /* ARM64Assembler.h in Headers */,
    54735545                                86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */,
     5546                                0FE050281AA9095600D33B33 /* ScopedArguments.h in Headers */,
    54745547                                52C0611F1AA51E1C00B4ADBA /* RuntimeType.h in Headers */,
    54755548                                C442CB251A6CDB8C005D3D7C /* JSInputs.json in Headers */,
     
    56325705                                0F1E3A461534CBAF000F9456 /* DFGArgumentPosition.h in Headers */,
    56335706                                A5C3A1A618C0490200C9593A /* JSGlobalObjectConsoleClient.h in Headers */,
    5634                                 0F16015E156198C900C2587C /* DFGArgumentsSimplificationPhase.h in Headers */,
    56355707                                0F485322187750560083B687 /* DFGArithMode.h in Headers */,
    56365708                                0F05C3B41683CF9200BAF45B /* DFGArrayifySlowPathGenerator.h in Headers */,
     
    56475719                                0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */,
    56485720                                0FFFC95814EF90A200C72532 /* DFGCFAPhase.h in Headers */,
     5721                                0F2DD80B1AB3D85800BBB8E8 /* BytecodeKills.h in Headers */,
    56495722                                0F3B3A281544C997003ED0FF /* DFGCFGSimplificationPhase.h in Headers */,
    56505723                                A77A424017A0BBFD00A8DB81 /* DFGClobberize.h in Headers */,
     
    57365809                                A741017F179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h in Headers */,
    57375810                                0F2FCCFD18A60070001A27F8 /* DFGScannable.h in Headers */,
     5811                                0F2DD8141AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.h in Headers */,
    57385812                                86ECA3FA132DF25A002B2AD7 /* DFGScoreBoard.h in Headers */,
    57395813                                0F1E3A67153A21E2000F9456 /* DFGSilentRegisterSavePlan.h in Headers */,
     
    57905864                                0FEA0A08170513DB00BB722C /* FTLAbbreviations.h in Headers */,
    57915865                                A53CE08A18BC21C300BEDF76 /* ConsoleClient.h in Headers */,
     5866                                0FE050191AA9091100D33B33 /* GenericArguments.h in Headers */,
    57925867                                0FEA0A1D1708B00700BB722C /* FTLAbstractHeap.h in Headers */,
    57935868                                DC00039319D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h in Headers */,
     
    58745949                                2AD8932B17E3868F00668276 /* HeapIterationScope.h in Headers */,
    58755950                                2A6F462617E959CE00C45C98 /* HeapOperation.h in Headers */,
     5951                                0FE050141AA9091100D33B33 /* ArgumentsMode.h in Headers */,
    58765952                                14F97447138C853E00DA1C67 /* HeapRootVisitor.h in Headers */,
    58775953                                C24D31E3161CD695002AA4DB /* HeapStatistics.h in Headers */,
     
    59005976                                0F3E01AB19D353A500F61B7F /* DFGPrePostNumbering.h in Headers */,
    59015977                                A593CF87184038CA00BFCE27 /* InspectorAgentRegistry.h in Headers */,
     5978                                0FE050261AA9095600D33B33 /* ClonedArguments.h in Headers */,
    59025979                                A593CF7D1840360300BFCE27 /* InspectorBackendDispatcher.h in Headers */,
    59035980                                A5FD0082189B191A00633231 /* InspectorConsoleAgent.h in Headers */,
     
    59756052                                0F9749711687ADE400A4FF6A /* JSCellInlines.h in Headers */,
    59766053                                0F1DD84A18A945BE0026F3FA /* JSCInlines.h in Headers */,
     6054                                0FE0501A1AA9091100D33B33 /* GenericArgumentsInlines.h in Headers */,
    59776055                                BC18C42B0E16F5CD00B34460 /* JSCJSValue.h in Headers */,
    59786056                                0F64B2721A784BAF006E4E66 /* BinarySwitch.h in Headers */,
     
    60556133                                0F919D0D157EE0A2004A4E7D /* JSSymbolTableObject.h in Headers */,
    60566134                                BC18C42A0E16F5CD00B34460 /* JSType.h in Headers */,
     6135                                0FE050161AA9091100D33B33 /* DirectArgumentsOffset.h in Headers */,
    60576136                                0F2B66FB17B6B5AB00A7AE3F /* JSTypedArrayConstructors.h in Headers */,
    60586137                                0F2B66FD17B6B5AB00A7AE3F /* JSTypedArrayPrototypes.h in Headers */,
     
    60636142                                0F2D4DF019832DD6007D4B19 /* TypeSet.h in Headers */,
    60646143                                0F2B670017B6B5AB00A7AE3F /* JSUint8Array.h in Headers */,
     6144                                0FE0502D1AA9095600D33B33 /* VarOffset.h in Headers */,
    60656145                                0F2B670117B6B5AB00A7AE3F /* JSUint8ClampedArray.h in Headers */,
    60666146                                86E3C612167BABD7006D760A /* JSValue.h in Headers */,
     
    60916171                                0F0FC45A14BD15F500B81154 /* LLIntCallLinkInfo.h in Headers */,
    60926172                                0FC3CD0019ADA410006AC72A /* DFGBlockWorklist.h in Headers */,
     6173                                0FE050181AA9091100D33B33 /* DirectArguments.h in Headers */,
    60936174                                FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */,
    60946175                                0F4680CA14BBB16C00BFE272 /* LLIntCommon.h in Headers */,
     6176                                0FBDB9AD1AB0FBC6000B57E5 /* DFGCallCreateDirectArgumentsSlowPathGenerator.h in Headers */,
    60956177                                0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */,
    60966178                                0F38B01217CF078300B144D3 /* LLIntEntrypoint.h in Headers */,
     
    61656247                                0F2D4DDE19832D34007D4B19 /* DebuggerScope.h in Headers */,
    61666248                                BC18C4480E16F5CD00B34460 /* Operations.h in Headers */,
     6249                                0FE0501B1AA9091100D33B33 /* GenericOffset.h in Headers */,
    61676250                                0FE228ED1436AB2700196C48 /* Options.h in Headers */,
    61686251                                BC18C44B0E16F5CD00B34460 /* Parser.h in Headers */,
     
    61746257                                0F9FC8C414E1B60000D52AE0 /* PolymorphicPutByIdList.h in Headers */,
    61756258                                0F98206116BFE38300240D02 /* PreciseJumpTargets.h in Headers */,
     6259                                0F2DD8151AB3D8BE00BBB8E8 /* DFGForAllKills.h in Headers */,
    61766260                                868916B0155F286300CB2B9A /* PrivateName.h in Headers */,
    61776261                                A5EA70E719F5B1010098F5EC /* AugmentableInspectorController.h in Headers */,
     
    62466330                                C22B31B9140577D700DB475A /* SamplingCounter.h in Headers */,
    62476331                                1429D8860ED21C3D00B89619 /* SamplingTool.h in Headers */,
     6332                                0FE254F71ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.h in Headers */,
    62486333                                0F24E55217EE274900ABB217 /* ScratchRegisterAllocator.h in Headers */,
    62496334                                A5FD0068189AFE9C00633231 /* ScriptArguments.h in Headers */,
     
    63256410                                70B0A9D11A9B66460001306A /* RuntimeFlags.h in Headers */,
    63266411                                A7E5AB391799E4B200D2833D /* UDis86Disassembler.h in Headers */,
     6412                                0FE0502B1AA9095600D33B33 /* ScopeOffset.h in Headers */,
    63276413                                A7A8AF4117ADB5F3005AB174 /* Uint16Array.h in Headers */,
    63286414                                0FE834181A6EF97B00D04847 /* PolymorphicCallStubRoutine.h in Headers */,
     
    63496435                                14F7256614EE265E00B1652B /* WeakHandleOwner.h in Headers */,
    63506436                                14E84FA214EE1ACC00D6D5D4 /* WeakImpl.h in Headers */,
     6437                                0F2DD8121AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.h in Headers */,
    63516438                                14BE7D3317135CF400D1807A /* WeakInlines.h in Headers */,
    63526439                                A7CA3AE417DA41AE006538AF /* WeakMapConstructor.h in Headers */,
     
    68356922                                9E729407190F01A5001A91B5 /* InitializeThreading.cpp in Sources */,
    68366923                                0FFA549716B8835000B3A982 /* A64DOpcode.cpp in Sources */,
     6924                                0FE050151AA9091100D33B33 /* DirectArgumentsOffset.cpp in Sources */,
    68376925                                0F55F0F414D1063900AC7649 /* AbstractPC.cpp in Sources */,
    68386926                                147F39BD107EC37600427A48 /* ArgList.cpp in Sources */,
    6839                                 147F39BE107EC37600427A48 /* Arguments.cpp in Sources */,
    68406927                                A76140CD182982CB00750624 /* ArgumentsIteratorConstructor.cpp in Sources */,
    68416928                                A76140CF182982CB00750624 /* ArgumentsIteratorPrototype.cpp in Sources */,
     
    68856972                                6553A33117A1F1EE008CF6F3 /* CommonSlowPathsExceptions.cpp in Sources */,
    68866973                                0F64B2791A7957B2006E4E66 /* CallEdge.cpp in Sources */,
     6974                                0FE254F61ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.cpp in Sources */,
    68876975                                A7E5A3A71797432D00E893C0 /* CompilationResult.cpp in Sources */,
    68886976                                147F39C2107EC37600427A48 /* Completion.cpp in Sources */,
     
    69076995                                A77A423D17A0BBFD00A8DB81 /* DFGAbstractHeap.cpp in Sources */,
    69086996                                0F55C19417276E4600CEABFD /* DFGAbstractValue.cpp in Sources */,
    6909                                 0F16015D156198C900C2587C /* DFGArgumentsSimplificationPhase.cpp in Sources */,
    69106997                                0F485321187750560083B687 /* DFGArithMode.cpp in Sources */,
    69116998                                0F2D4DDD19832D34007D4B19 /* DebuggerScope.cpp in Sources */,
     
    69177004                                A7D89CF217A0B8CC00773AD8 /* DFGBasicBlock.cpp in Sources */,
    69187005                                2A88067819107D5500CB0BBB /* DFGFunctionWhitelist.cpp in Sources */,
     7006                                0F2DD8131AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.cpp in Sources */,
    69197007                                A7D89CF317A0B8CC00773AD8 /* DFGBlockInsertionSet.cpp in Sources */,
    69207008                                86EC9DC41328DF82002B2AD7 /* DFGByteCodeParser.cpp in Sources */,
     
    69637051                                0FEA0A33170D40BF00BB722C /* DFGJITCode.cpp in Sources */,
    69647052                                86EC9DCB1328DF82002B2AD7 /* DFGJITCompiler.cpp in Sources */,
     7053                                0FE0502A1AA9095600D33B33 /* ScopeOffset.cpp in Sources */,
    69657054                                A78A9778179738B8009DF744 /* DFGJITFinalizer.cpp in Sources */,
    69667055                                0FC97F3F18202119002C9B26 /* DFGJumpReplacement.cpp in Sources */,
     
    70417130                                A7B48F490EE8936F00DCBDB6 /* ExecutableAllocator.cpp in Sources */,
    70427131                                86DB64640F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp in Sources */,
     7132                                0F2DD8111AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.cpp in Sources */,
    70437133                                0F56A1D515001CF4002992B1 /* ExecutionCounter.cpp in Sources */,
    70447134                                52678F8E1A031009006A306D /* BasicBlockLocation.cpp in Sources */,
     
    70477137                                0FB105851675480F00F8AB6E /* ExitKind.cpp in Sources */,
    70487138                                0FEA0A1C1708B00700BB722C /* FTLAbstractHeap.cpp in Sources */,
     7139                                0F978B3B1AAEA71D007C7369 /* ConstantMode.cpp in Sources */,
     7140                                0FE050251AA9095600D33B33 /* ClonedArguments.cpp in Sources */,
    70497141                                0F79085519A290B200F6310C /* DFGStructureRegistrationPhase.cpp in Sources */,
    70507142                                0FEA0A1E1708B00700BB722C /* FTLAbstractHeapRepository.cpp in Sources */,
     
    71857277                                0F2D4DE819832DAC007D4B19 /* ToThisStatus.cpp in Sources */,
    71867278                                978801401471AD920041B016 /* JSDateMath.cpp in Sources */,
     7279                                0FE050171AA9091100D33B33 /* DirectArguments.cpp in Sources */,
    71877280                                140566D6107EC271005DBC8D /* JSFunction.cpp in Sources */,
    71887281                                147F39D2107EC37600427A48 /* JSGlobalObject.cpp in Sources */,
     
    73337426                                14280841107EC0930013E7B2 /* RegExp.cpp in Sources */,
    73347427                                A1712B3B11C7B212007A5315 /* RegExpCache.cpp in Sources */,
     7428                                0FE0502C1AA9095600D33B33 /* VarOffset.cpp in Sources */,
    73357429                                8642C510151C06A90046D4EF /* RegExpCachedResult.cpp in Sources */,
    73367430                                14280842107EC0930013E7B2 /* RegExpConstructor.cpp in Sources */,
     
    74267520                                2A4EC90B1860D6C20094F782 /* WriteBarrierBuffer.cpp in Sources */,
    74277521                                0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */,
     7522                                0FE050271AA9095600D33B33 /* ScopedArguments.cpp in Sources */,
    74287523                                0F3B7E2A19A11B8000D9BC56 /* CallVariant.cpp in Sources */,
    74297524                                A7E5AB3A1799E4B200D2833D /* X86Disassembler.cpp in Sources */,
    74307525                                863C6D9C1521111A00585E4E /* YarrCanonicalizeUCS2.cpp in Sources */,
     7526                                0FE0502F1AAA806900D33B33 /* ScopedArgumentsTable.cpp in Sources */,
    74317527                                86704B8412DBA33700A9FE7B /* YarrInterpreter.cpp in Sources */,
    74327528                                86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */,
  • trunk/Source/JavaScriptCore/assembler/AbortReason.h

    r169942 r181993  
    11/*
    2  * Copyright (C) 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5858    DFGUnreachableBasicBlock                          = 220,
    5959    DFGUnreasonableOSREntryJumpDestination            = 230,
     60    DFGVarargsThrowingPathDidNotThrow                 = 235,
    6061    JITDivOperandsAreNotNumbers                       = 240,
    6162    JITGetByValResultIsNotEmpty                       = 250,
  • trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h

    r181570 r181993  
    11/*
    2  * Copyright (C) 2008, 2012, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2012, 2014, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    206206        Scale scale;
    207207        int32_t offset;
     208       
     209        BaseIndex withOffset(int32_t additionalOffset)
     210        {
     211            return BaseIndex(base, index, scale, offset + additionalOffset);
     212        }
    208213    };
    209214
  • trunk/Source/JavaScriptCore/bytecode/ByValInfo.h

    r164424 r181993  
    11/*
    2  * Copyright (C) 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4242    JITContiguous,
    4343    JITArrayStorage,
     44    JITDirectArguments,
     45    JITScopedArguments,
    4446    JITInt8Array,
    4547    JITInt16Array,
     
    6668}
    6769
     70inline bool hasOptimizableIndexingForJSType(JSType type)
     71{
     72    switch (type) {
     73    case DirectArgumentsType:
     74    case ScopedArgumentsType:
     75        return true;
     76    default:
     77        return false;
     78    }
     79}
     80
    6881inline bool hasOptimizableIndexingForClassInfo(const ClassInfo* classInfo)
    6982{
     
    7487{
    7588    return isOptimizableIndexingType(structure->indexingType())
     89        || hasOptimizableIndexingForJSType(structure->typeInfo().type())
    7690        || hasOptimizableIndexingForClassInfo(structure->classInfo());
    7791}
     
    90104    default:
    91105        CRASH();
     106        return JITContiguous;
     107    }
     108}
     109
     110inline JITArrayMode jitArrayModeForJSType(JSType type)
     111{
     112    switch (type) {
     113    case DirectArgumentsType:
     114        return JITDirectArguments;
     115    case ScopedArgumentsType:
     116        return JITScopedArguments;
     117    default:
     118        RELEASE_ASSERT_NOT_REACHED();
    92119        return JITContiguous;
    93120    }
     
    121148}
    122149
     150inline bool jitArrayModePermitsPut(JITArrayMode mode)
     151{
     152    switch (mode) {
     153    case JITDirectArguments:
     154    case JITScopedArguments:
     155        // We could support put_by_val on these at some point, but it's just not that profitable
     156        // at the moment.
     157        return false;
     158    default:
     159        return true;
     160    }
     161}
     162
    123163inline TypedArrayType typedArrayTypeForJITArrayMode(JITArrayMode mode)
    124164{
     
    153193        return jitArrayModeForIndexingType(structure->indexingType());
    154194   
     195    if (hasOptimizableIndexingForJSType(structure->typeInfo().type()))
     196        return jitArrayModeForJSType(structure->typeInfo().type());
     197   
    155198    ASSERT(hasOptimizableIndexingForClassInfo(structure->classInfo()));
    156199    return jitArrayModeForClassInfo(structure->classInfo());
  • trunk/Source/JavaScriptCore/bytecode/BytecodeList.json

    r181891 r181993  
    88            { "name" : "op_get_scope", "length" : 2 },
    99            { "name" : "op_touch_entry", "length" : 1 },
    10             { "name" : "op_init_lazy_reg", "length" : 2 },
    11             { "name" : "op_create_arguments", "length" : 3 },
     10            { "name" : "op_create_direct_arguments", "length" : 2 },
     11            { "name" : "op_create_scoped_arguments", "length" : 3 },
     12            { "name" : "op_create_out_of_band_arguments", "length" : 2 },
    1213            { "name" : "op_create_this", "length" : 4 },
    1314            { "name" : "op_to_this", "length" : 4 },
     
    6263            { "name" : "op_get_by_id_out_of_line", "length" : 9  },
    6364            { "name" : "op_get_array_length", "length" : 9 },
    64             { "name" : "op_get_arguments_length", "length" : 4 },
    6565            { "name" : "op_put_by_id", "length" : 9 },
    6666            { "name" : "op_put_by_id_out_of_line", "length" : 9 },
     
    7171            { "name" : "op_del_by_id", "length" : 4 },
    7272            { "name" : "op_get_by_val", "length" : 6 },
    73             { "name" : "op_get_argument_by_val", "length" : 7 },
    7473            { "name" : "op_put_by_val", "length" : 5 },
    7574            { "name" : "op_put_by_val_direct", "length" : 5 },
     
    9594            { "name" : "op_switch_char", "length" : 4 },
    9695            { "name" : "op_switch_string", "length" : 4 },
    97             { "name" : "op_new_func", "length" : 5 },
     96            { "name" : "op_new_func", "length" : 4 },
    9897            { "name" : "op_new_func_exp", "length" : 4 },
    9998            { "name" : "op_call", "length" : 9 },
    10099            { "name" : "op_call_eval", "length" : 9 },
    101100            { "name" : "op_call_varargs", "length" : 9 },
    102             { "name" : "op_tear_off_arguments", "length" : 3 },
    103101            { "name" : "op_ret", "length" : 2 },
    104102            { "name" : "op_construct", "length" : 9 },
     
    109107            { "name" : "op_get_from_scope", "length" : 8 },
    110108            { "name" : "op_put_to_scope", "length" : 7 },
     109            { "name" : "op_get_from_arguments", "length" : 5 },
     110            { "name" : "op_put_to_arguments", "length" : 4 },
    111111            { "name" : "op_push_with_scope", "length" : 3 },
    112112            { "name" : "op_pop_scope", "length" : 2 },
  • trunk/Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.cpp

    r181467 r181993  
    2727#include "BytecodeLivenessAnalysis.h"
    2828
     29#include "BytecodeKills.h"
    2930#include "BytecodeLivenessAnalysisInlines.h"
    3031#include "BytecodeUseDef.h"
     
    4849   
    4950    VirtualRegister virtualReg(operand);
    50     if (!virtualReg.isLocal())
    51         return false;
    52    
    53     if (codeBlock->captureCount()
    54         && operand <= codeBlock->captureStart()
    55         && operand > codeBlock->captureEnd())
    56         return false;
    57    
    58     return true;
    59 }
    60 
    61 static unsigned indexForOperand(CodeBlock* codeBlock, int operand)
    62 {
    63     ASSERT(isValidRegisterForLiveness(codeBlock, operand));
    64     VirtualRegister virtualReg(operand);
    65     if (virtualReg.offset() > codeBlock->captureStart())
    66         return virtualReg.toLocal();
    67     return virtualReg.toLocal() - codeBlock->captureCount();
     51    return virtualReg.isLocal();
    6852}
    6953
     
    136120        [&] (CodeBlock* codeBlock, Instruction*, OpcodeID, int operand) {
    137121            if (isValidRegisterForLiveness(codeBlock, operand))
    138                 def(indexForOperand(codeBlock, operand));
     122                def(VirtualRegister(operand).toLocal());
    139123        });
    140    
     124
    141125    computeUsesForBytecodeOffset(
    142126        codeBlock, bytecodeOffset,
    143127        [&] (CodeBlock* codeBlock, Instruction*, OpcodeID, int operand) {
    144128            if (isValidRegisterForLiveness(codeBlock, operand))
    145                 use(indexForOperand(codeBlock, operand));
     129                use(VirtualRegister(operand).toLocal());
    146130        });
    147131       
     
    197181{
    198182    UnlinkedCodeBlock* unlinkedCodeBlock = m_codeBlock->unlinkedCodeBlock();
    199     unsigned numberOfVariables =
    200         unlinkedCodeBlock->m_numCalleeRegisters - m_codeBlock->captureCount();
     183    unsigned numberOfVariables = unlinkedCodeBlock->m_numCalleeRegisters;
    201184
    202185    for (unsigned i = 0; i < m_basicBlocks.size(); i++) {
     
    213196    do {
    214197        changed = false;
    215         for (int i = m_basicBlocks.size() - 2; i >= 0; i--) {
     198        for (unsigned i = m_basicBlocks.size() - 1; i--;) {
    216199            BytecodeBasicBlock* block = m_basicBlocks[i].get();
    217200            newOut.clearAll();
     
    225208}
    226209
    227 void BytecodeLivenessAnalysis::getLivenessInfoForNonCapturedVarsAtBytecodeOffset(unsigned bytecodeOffset, FastBitVector& result)
     210void BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset(unsigned bytecodeOffset, FastBitVector& result)
    228211{
    229212    BytecodeBasicBlock* block = findBasicBlockForBytecodeOffset(m_basicBlocks, bytecodeOffset);
     
    237220bool BytecodeLivenessAnalysis::operandIsLiveAtBytecodeOffset(int operand, unsigned bytecodeOffset)
    238221{
    239     if (operandIsAlwaysLive(m_codeBlock, operand))
     222    if (operandIsAlwaysLive(operand))
    240223        return true;
    241224    FastBitVector result;
    242     getLivenessInfoForNonCapturedVarsAtBytecodeOffset(bytecodeOffset, result);
    243     return operandThatIsNotAlwaysLiveIsLive(m_codeBlock, result, operand);
    244 }
    245 
    246 FastBitVector getLivenessInfo(CodeBlock* codeBlock, const FastBitVector& out)
    247 {
    248     FastBitVector result;
    249 
    250     unsigned numCapturedVars = codeBlock->captureCount();
    251     if (numCapturedVars) {
    252         int firstCapturedLocal = VirtualRegister(codeBlock->captureStart()).toLocal();
    253         result.resize(out.numBits() + numCapturedVars);
    254         for (unsigned i = 0; i < numCapturedVars; ++i)
    255             result.set(firstCapturedLocal + i);
    256     } else
    257         result.resize(out.numBits());
    258 
    259     int outLength = out.numBits();
    260     ASSERT(outLength >= 0);
    261     for (int i = 0; i < outLength; i++) {
    262         if (!out.get(i))
    263             continue;
    264 
    265         if (!numCapturedVars) {
    266             result.set(i);
    267             continue;
    268         }
    269 
    270         if (virtualRegisterForLocal(i).offset() > codeBlock->captureStart())
    271             result.set(i);
    272         else
    273             result.set(numCapturedVars + i);
    274     }
    275     return result;
     225    getLivenessInfoAtBytecodeOffset(bytecodeOffset, result);
     226    return operandThatIsNotAlwaysLiveIsLive(result, operand);
    276227}
    277228
     
    279230{
    280231    FastBitVector out;
    281     getLivenessInfoForNonCapturedVarsAtBytecodeOffset(bytecodeOffset, out);
    282     return getLivenessInfo(m_codeBlock, out);
     232    getLivenessInfoAtBytecodeOffset(bytecodeOffset, out);
     233    return out;
    283234}
    284235
     
    287238    FastBitVector out;
    288239   
    289     result.m_codeBlock = m_codeBlock;
    290240    result.m_map.clear();
    291241   
     
    301251            stepOverInstruction(m_codeBlock, m_basicBlocks, bytecodeOffset, out);
    302252            result.m_map.add(bytecodeOffset, out);
     253        }
     254    }
     255}
     256
     257void BytecodeLivenessAnalysis::computeKills(BytecodeKills& result)
     258{
     259    FastBitVector out;
     260   
     261    result.m_codeBlock = m_codeBlock;
     262    result.m_killSets = std::make_unique<BytecodeKills::KillSet[]>(m_codeBlock->instructions().size());
     263   
     264    for (unsigned i = m_basicBlocks.size(); i--;) {
     265        BytecodeBasicBlock* block = m_basicBlocks[i].get();
     266        if (block->isEntryBlock() || block->isExitBlock())
     267            continue;
     268       
     269        out = block->out();
     270       
     271        for (unsigned i = block->bytecodeOffsets().size(); i--;) {
     272            unsigned bytecodeOffset = block->bytecodeOffsets()[i];
     273            stepOverInstruction(
     274                m_codeBlock, m_basicBlocks, bytecodeOffset,
     275                [&] (unsigned index) {
     276                    // This is for uses.
     277                    if (out.get(index))
     278                        return;
     279                    result.m_killSets[bytecodeOffset].add(index);
     280                    out.set(index);
     281                },
     282                [&] (unsigned index) {
     283                    // This is for defs.
     284                    out.clear(index);
     285                });
    303286        }
    304287    }
  • trunk/Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.h

    r159394 r181993  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3434namespace JSC {
    3535
     36class BytecodeKills;
    3637class CodeBlock;
    3738class FullBytecodeLiveness;
     
    4546   
    4647    void computeFullLiveness(FullBytecodeLiveness& result);
     48    void computeKills(BytecodeKills& result);
    4749
    4850private:
     
    5153    void dumpResults();
    5254
    53     void getLivenessInfoForNonCapturedVarsAtBytecodeOffset(unsigned bytecodeOffset, FastBitVector&);
     55    void getLivenessInfoAtBytecodeOffset(unsigned bytecodeOffset, FastBitVector&);
    5456
    5557    CodeBlock* m_codeBlock;
     
    5759};
    5860
    59 inline bool operandIsAlwaysLive(CodeBlock*, int operand);
    60 inline bool operandThatIsNotAlwaysLiveIsLive(CodeBlock*, const FastBitVector& out, int operand);
    61 inline bool operandIsLive(CodeBlock*, const FastBitVector& out, int operand);
    62 
    63 FastBitVector getLivenessInfo(CodeBlock*, const FastBitVector& out);
     61inline bool operandIsAlwaysLive(int operand);
     62inline bool operandThatIsNotAlwaysLiveIsLive(const FastBitVector& out, int operand);
     63inline bool operandIsLive(const FastBitVector& out, int operand);
    6464
    6565} // namespace JSC
  • trunk/Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysisInlines.h

    r163760 r181993  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3333namespace JSC {
    3434
    35 inline bool operandIsAlwaysLive(CodeBlock* codeBlock, int operand)
     35inline bool operandIsAlwaysLive(int operand)
    3636{
    37     if (VirtualRegister(operand).isArgument())
    38         return true;
    39     return operand <= codeBlock->captureStart() && operand > codeBlock->captureEnd();
     37    return !VirtualRegister(operand).isLocal();
    4038}
    4139
    42 inline bool operandThatIsNotAlwaysLiveIsLive(CodeBlock* codeBlock, const FastBitVector& out, int operand)
     40inline bool operandThatIsNotAlwaysLiveIsLive(const FastBitVector& out, int operand)
    4341{
    44     VirtualRegister virtualReg(operand);
    45     if (virtualReg.offset() > codeBlock->captureStart())
    46         return out.get(virtualReg.toLocal());
    47     size_t index = virtualReg.toLocal() - codeBlock->captureCount();
    48     if (index >= out.numBits())
     42    unsigned local = VirtualRegister(operand).toLocal();
     43    if (local >= out.numBits())
    4944        return false;
    50     return out.get(index);
     45    return out.get(local);
    5146}
    5247
    53 inline bool operandIsLive(CodeBlock* codeBlock, const FastBitVector& out, int operand)
     48inline bool operandIsLive(const FastBitVector& out, int operand)
    5449{
    55     return operandIsAlwaysLive(codeBlock, operand) || operandThatIsNotAlwaysLiveIsLive(codeBlock, out, operand);
     50    return operandIsAlwaysLive(operand) || operandThatIsNotAlwaysLiveIsLive(out, operand);
    5651}
    5752
  • trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h

    r181891 r181993  
    4949    case op_jmp:
    5050    case op_new_object:
    51     case op_init_lazy_reg:
    5251    case op_enter:
    5352    case op_catch:
    5453    case op_touch_entry:
    5554    case op_profile_control_flow:
     55    case op_create_direct_arguments:
     56    case op_create_out_of_band_arguments:
    5657        return;
    5758    case op_get_scope:
     
    7475        return;
    7576    }
    76     case op_create_arguments:
    77     case op_new_func:
    7877    case op_jlesseq:
    7978    case op_jgreater:
     
    102101    case op_put_by_id_out_of_line:
    103102    case op_put_by_id:
    104     case op_put_to_scope: {
     103    case op_put_to_scope:
     104    case op_put_to_arguments: {
    105105        functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
    106106        functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
     
    128128    case op_get_by_id_out_of_line:
    129129    case op_get_array_length:
    130     case op_get_arguments_length:
    131130    case op_typeof:
    132131    case op_is_undefined:
     
    146145    case op_create_this:
    147146    case op_del_by_id:
    148     case op_unsigned: {
     147    case op_unsigned:
     148    case op_new_func:
     149    case op_create_scoped_arguments:
     150    case op_get_from_arguments: {
    149151        functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
    150152        return;
     
    183185    }
    184186    case op_has_structure_property:
    185     case op_get_argument_by_val:
    186187    case op_construct_varargs:
    187188    case op_call_varargs: {
     
    221222        for (int i = 0; i < argCount; i++)
    222223            functor(codeBlock, instruction, opcodeID, lastArg + i);
    223         return;
    224     }
    225     case op_tear_off_arguments: {
    226         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
    227         functor(codeBlock, instruction, opcodeID, unmodifiedArgumentsRegister(VirtualRegister(instruction[1].u.operand)).offset());
    228         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
    229224        return;
    230225    }
     
    282277    case op_put_by_val_direct:
    283278    case op_put_by_index:
    284     case op_tear_off_arguments:
    285279    case op_profile_type:
    286280    case op_profile_control_flow:
    287281    case op_touch_entry:
     282    case op_put_to_arguments:
    288283#define LLINT_HELPER_OPCODES(opcode, length) case opcode:
    289284        FOR_EACH_LLINT_OPCODE_EXTENSION(LLINT_HELPER_OPCODES);
     
    326321    case op_instanceof:
    327322    case op_get_by_val:
    328     case op_get_argument_by_val:
    329     case op_get_arguments_length:
    330323    case op_typeof:
    331324    case op_is_undefined:
     
    367360    case op_to_this:
    368361    case op_check_tdz:
    369     case op_init_lazy_reg:
    370362    case op_get_scope:
    371     case op_create_arguments:
     363    case op_create_direct_arguments:
     364    case op_create_scoped_arguments:
     365    case op_create_out_of_band_arguments:
    372366    case op_del_by_id:
    373367    case op_del_by_val:
    374     case op_unsigned: {
     368    case op_unsigned:
     369    case op_get_from_arguments: {
    375370        functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
    376371        return;
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r181979 r181993  
    570570        static_cast<unsigned long>(instructions().size() * sizeof(Instruction)),
    571571        m_numParameters, m_numCalleeRegisters, m_numVars);
    572     if (symbolTable() && symbolTable()->captureCount()) {
    573         out.printf(
    574             "; %d captured var(s) (from r%d to r%d, inclusive)",
    575             symbolTable()->captureCount(), symbolTable()->captureStart(), symbolTable()->captureEnd() + 1);
    576     }
    577     if (usesArguments()) {
    578         out.printf(
    579             "; uses arguments, in r%d, r%d",
    580             argumentsRegister().offset(),
    581             unmodifiedArgumentsRegister(argumentsRegister()).offset());
    582     }
    583572    if (needsActivation() && codeType() == FunctionCode)
    584573        out.printf("; lexical environment in r%d", activationRegister().offset());
     
    753742            int r1 = (++it)->u.operand;
    754743            printLocationAndOp(out, exec, location, it, "create_lexical_environment");
    755             out.printf("%s %s", registerName(r0).data(), registerName(r1).data());
     744            out.printf("%s, %s", registerName(r0).data(), registerName(r1).data());
    756745            break;
    757746        }
     
    761750            break;
    762751        }
    763         case op_create_arguments: {
     752        case op_create_direct_arguments: {
     753            int r0 = (++it)->u.operand;
     754            printLocationAndOp(out, exec, location, it, "create_direct_arguments");
     755            out.printf("%s", registerName(r0).data());
     756            break;
     757        }
     758        case op_create_scoped_arguments: {
    764759            int r0 = (++it)->u.operand;
    765760            int r1 = (++it)->u.operand;
    766             printLocationAndOp(out, exec, location, it, "create_arguments");
    767             out.printf("%s %s", registerName(r0).data(), registerName(r1).data());
    768             break;
    769         }
    770         case op_init_lazy_reg: {
    771             int r0 = (++it)->u.operand;
    772             printLocationOpAndRegisterOperand(out, exec, location, it, "init_lazy_reg", r0);
     761            printLocationAndOp(out, exec, location, it, "create_scoped_arguments");
     762            out.printf("%s, %s", registerName(r0).data(), registerName(r1).data());
     763            break;
     764        }
     765        case op_create_out_of_band_arguments: {
     766            int r0 = (++it)->u.operand;
     767            printLocationAndOp(out, exec, location, it, "create_out_of_band_arguments");
     768            out.printf("%s", registerName(r0).data());
    773769            break;
    774770        }
     
    786782            Structure* structure = (++it)->u.structure.get();
    787783            if (structure)
    788                 out.print(" cache(struct = ", RawPointer(structure), ")");
    789             out.print(" ", (++it)->u.toThisStatus);
     784                out.print(", cache(struct = ", RawPointer(structure), ")");
     785            out.print(", ", (++it)->u.toThisStatus);
    790786            break;
    791787        }
     
    10421038        }
    10431039        case op_init_global_const: {
    1044             WriteBarrier<Unknown>* registerPointer = (++it)->u.registerPointer;
     1040            WriteBarrier<Unknown>* variablePointer = (++it)->u.variablePointer;
    10451041            int r0 = (++it)->u.operand;
    10461042            printLocationAndOp(out, exec, location, it, "init_global_const");
    1047             out.printf("g%d(%p), %s", m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(r0).data());
     1043            out.printf("g%d(%p), %s", m_globalObject->findVariableIndex(variablePointer).offset(), variablePointer, registerName(r0).data());
    10481044            it++;
    10491045            it++;
     
    10581054            break;
    10591055        }
    1060         case op_get_arguments_length: {
    1061             printUnaryOp(out, exec, location, it, "get_arguments_length");
    1062             it++;
    1063             break;
    1064         }
    10651056        case op_put_by_id: {
    10661057            printPutByIdOp(out, exec, location, it, "put_by_id");
     
    11201111            break;
    11211112        }
    1122         case op_get_argument_by_val: {
    1123             int r0 = (++it)->u.operand;
    1124             int r1 = (++it)->u.operand;
    1125             int r2 = (++it)->u.operand;
    1126             int r3 = (++it)->u.operand;
    1127             printLocationAndOp(out, exec, location, it, "get_argument_by_val");
    1128             out.printf("%s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), registerName(r3).data());
    1129             ++it;
    1130             dumpValueProfiling(out, it, hasPrintedProfiling);
    1131             break;
    1132         }
    11331113        case op_put_by_val: {
    11341114            int r0 = (++it)->u.operand;
     
    12911271            int r1 = (++it)->u.operand;
    12921272            int f0 = (++it)->u.operand;
    1293             int shouldCheck = (++it)->u.operand;
    12941273            printLocationAndOp(out, exec, location, it, "new_func");
    1295             out.printf("%s, %s, f%d, %s", registerName(r0).data(), registerName(r1).data(), f0, shouldCheck ? "<Checked>" : "<Unchecked>");
     1274            out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0);
    12961275            break;
    12971276        }
     
    13281307        }
    13291308
    1330         case op_tear_off_arguments: {
    1331             int r0 = (++it)->u.operand;
    1332             int r1 = (++it)->u.operand;
    1333             printLocationAndOp(out, exec, location, it, "tear_off_arguments");
    1334             out.printf("%s, %s", registerName(r0).data(), registerName(r1).data());
    1335             break;
    1336         }
    13371309        case op_ret: {
    13381310            int r0 = (++it)->u.operand;
     
    15231495            ++it; // Structure
    15241496            int operand = (++it)->u.operand; // Operand
    1525             ++it; // Skip value profile.
    15261497            printLocationAndOp(out, exec, location, it, "get_from_scope");
    1527             out.printf("%s, %s, %s, %u<%s|%s>, <structure>, %d",
    1528                 registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data(),
    1529                 modeAndType.operand(), resolveModeName(modeAndType.mode()), resolveTypeName(modeAndType.type()),
    1530                 operand);
     1498            out.print(registerName(r0), ", ", registerName(r1));
     1499            if (static_cast<unsigned>(id0) == UINT_MAX)
     1500                out.print(", anonymous");
     1501            else
     1502                out.print(", ", idName(id0, identifier(id0)));
     1503            out.print(", ", modeAndType.operand(), "<", resolveModeName(modeAndType.mode()), "|", resolveTypeName(modeAndType.type()), ">, ", operand);
     1504            dumpValueProfiling(out, it, hasPrintedProfiling);
    15311505            break;
    15321506        }
     
    15391513            int operand = (++it)->u.operand; // Operand
    15401514            printLocationAndOp(out, exec, location, it, "put_to_scope");
    1541             out.printf("%s, %s, %s, %u<%s|%s>, <structure>, %d",
    1542                 registerName(r0).data(), idName(id0, identifier(id0)).data(), registerName(r1).data(),
    1543                 modeAndType.operand(), resolveModeName(modeAndType.mode()), resolveTypeName(modeAndType.type()),
    1544                 operand);
     1515            out.print(registerName(r0));
     1516            if (static_cast<unsigned>(id0) == UINT_MAX)
     1517                out.print(", anonymous");
     1518            else
     1519                out.print(", ", idName(id0, identifier(id0)));
     1520            out.print(", ", registerName(r1), ", ", modeAndType.operand(), "<", resolveModeName(modeAndType.mode()), "|", resolveTypeName(modeAndType.type()), ">, <structure>, ", operand);
     1521            break;
     1522        }
     1523        case op_get_from_arguments: {
     1524            int r0 = (++it)->u.operand;
     1525            int r1 = (++it)->u.operand;
     1526            int offset = (++it)->u.operand;
     1527            printLocationAndOp(out, exec, location, it, "get_from_arguments");
     1528            out.printf("%s, %s, %d", registerName(r0).data(), registerName(r1).data(), offset);
     1529            dumpValueProfiling(out, it, hasPrintedProfiling);
     1530            break;
     1531        }
     1532        case op_put_to_arguments: {
     1533            int r0 = (++it)->u.operand;
     1534            int offset = (++it)->u.operand;
     1535            int r1 = (++it)->u.operand;
     1536            printLocationAndOp(out, exec, location, it, "put_to_arguments");
     1537            out.printf("%s, %d, %s", registerName(r0).data(), offset, registerName(r1).data());
    15451538            break;
    15461539        }
     
    16401633    , m_thisRegister(other.m_thisRegister)
    16411634    , m_scopeRegister(other.m_scopeRegister)
    1642     , m_argumentsRegister(other.m_argumentsRegister)
    16431635    , m_lexicalEnvironmentRegister(other.m_lexicalEnvironmentRegister)
    16441636    , m_isStrictMode(other.m_isStrictMode)
     
    17031695    , m_thisRegister(unlinkedCodeBlock->thisRegister())
    17041696    , m_scopeRegister(unlinkedCodeBlock->scopeRegister())
    1705     , m_argumentsRegister(unlinkedCodeBlock->argumentsRegister())
    17061697    , m_lexicalEnvironmentRegister(unlinkedCodeBlock->activationRegister())
    17071698    , m_isStrictMode(unlinkedCodeBlock->isStrictMode())
     
    17321723        }
    17331724
    1734         if (codeType() == FunctionCode && symbolTable->captureCount()) {
    1735             m_symbolTable.set(*m_vm, m_ownerExecutable.get(), symbolTable->cloneCapturedNames(*m_vm));
     1725        if (codeType() == FunctionCode && symbolTable->scopeSize()) {
     1726            m_symbolTable.set(*m_vm, m_ownerExecutable.get(), symbolTable->cloneScopePart(*m_vm));
    17361727            didCloneSymbolTable = true;
    17371728        } else
     
    18501841        case op_call_varargs:
    18511842        case op_construct_varargs:
    1852         case op_get_by_val:
    1853         case op_get_argument_by_val: {
     1843        case op_get_by_val: {
    18541844            int arrayProfileIndex = pc[opLength - 2].u.operand;
    18551845            m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i);
     
    18591849        }
    18601850        case op_get_direct_pname:
    1861         case op_get_by_id: {
     1851        case op_get_by_id:
     1852        case op_get_from_arguments: {
    18621853            ValueProfile* profile = &m_valueProfiles[pc[opLength - 1].u.operand];
    18631854            ASSERT(profile->m_bytecodeOffset == -1);
     
    19291920
    19301921            instructions[i + 0] = vm()->interpreter->getOpcode(op_init_global_const);
    1931             instructions[i + 1] = &m_globalObject->registerAt(entry.getIndex());
     1922            instructions[i + 1] = &m_globalObject->variableAt(entry.varOffset().scopeOffset());
    19321923            break;
    19331924        }
     
    19541945            // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
    19551946
    1956             const Identifier& ident = identifier(pc[3].u.operand);
    19571947            ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
    19581948            if (modeAndType.type() == LocalClosureVar) {
     
    19601950                break;
    19611951            }
     1952
     1953            const Identifier& ident = identifier(pc[3].u.operand);
    19621954
    19631955            ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), needsActivation(), scope, ident, Get, modeAndType.type());
     
    19751967        case op_put_to_scope: {
    19761968            // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
    1977             const Identifier& ident = identifier(pc[2].u.operand);
    1978 
    19791969            ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
    19801970            if (modeAndType.type() == LocalClosureVar) {
    1981                 bool isWatchableVariable = pc[5].u.operand;
    1982                 if (!isWatchableVariable) {
    1983                     instructions[i + 5].u.watchpointSet = nullptr;
    1984                     break;
    1985                 }
    1986                 StringImpl* uid = ident.impl();
    1987                 RELEASE_ASSERT(didCloneSymbolTable);
    1988                 if (ident != m_vm->propertyNames->arguments) {
     1971                // Only do watching if the property we're putting to is not anonymous.
     1972                if (static_cast<unsigned>(pc[2].u.operand) != UINT_MAX) {
     1973                    RELEASE_ASSERT(didCloneSymbolTable);
     1974                    const Identifier& ident = identifier(pc[2].u.operand);
     1975                    StringImpl* uid = ident.impl();
    19891976                    ConcurrentJITLocker locker(m_symbolTable->m_lock);
    19901977                    SymbolTable::Map::iterator iter = m_symbolTable->find(locker, uid);
     
    19961983                break;
    19971984            }
     1985
     1986            const Identifier& ident = identifier(pc[2].u.operand);
    19981987
    19991988            ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), needsActivation(), scope, ident, Put, modeAndType.type());
     
    20652054                symbolTable = m_symbolTable.get();
    20662055                ConcurrentJITLocker locker(symbolTable->m_lock);
    2067                 globalVariableID = symbolTable->uniqueIDForRegister(locker, profileRegister.offset(), *vm());
    2068                 globalTypeSet = symbolTable->globalTypeSetForRegister(locker, profileRegister.offset(), *vm());
     2056                globalVariableID = symbolTable->uniqueIDForOffset(locker, VarOffset(profileRegister), *vm());
     2057                globalTypeSet = symbolTable->globalTypeSetForOffset(locker, VarOffset(profileRegister), *vm());
    20692058                break;
    20702059            }
     
    28222811#endif
    28232812
    2824 bool CodeBlock::isCaptured(VirtualRegister operand, InlineCallFrame* inlineCallFrame) const
    2825 {
    2826     if (operand.isArgument())
    2827         return operand.toArgument() && usesArguments();
    2828 
    2829     if (inlineCallFrame)
    2830         return inlineCallFrame->capturedVars.get(operand.toLocal());
    2831 
    2832     // The lexical environment object isn't in the captured region, but it's "captured"
    2833     // in the sense that stores to its location can be observed indirectly.
    2834     if (needsActivation() && operand == activationRegister())
    2835         return true;
    2836 
    2837     // Ditto for the arguments object.
    2838     if (usesArguments() && operand == argumentsRegister())
    2839         return true;
    2840     if (usesArguments() && operand == unmodifiedArgumentsRegister(argumentsRegister()))
    2841         return true;
    2842 
    2843     // We're in global code so there are no locals to capture
    2844     if (!symbolTable())
    2845         return false;
    2846 
    2847     return symbolTable()->isCaptured(operand.offset());
    2848 }
    2849 
    2850 int CodeBlock::framePointerOffsetToGetActivationRegisters(int machineCaptureStart)
    2851 {
    2852     // We'll be adding this to the stack pointer to get a registers pointer that looks
    2853     // like it would have looked in the baseline engine. For example, if bytecode would
    2854     // have put the first captured variable at offset -5 but we put it at offset -1, then
    2855     // we'll have an offset of 4.
    2856     int32_t offset = 0;
    2857    
    2858     // Compute where we put the captured variables. This offset will point the registers
    2859     // pointer directly at the first captured var.
    2860     offset += machineCaptureStart;
    2861    
    2862     // Now compute the offset needed to make the runtime see the captured variables at the
    2863     // same offset that the bytecode would have used.
    2864     offset -= symbolTable()->captureStart();
    2865    
    2866     return offset;
    2867 }
    2868 
    2869 int CodeBlock::framePointerOffsetToGetActivationRegisters()
    2870 {
    2871     if (!JITCode::isOptimizingJIT(jitType()))
    2872         return 0;
    2873 #if ENABLE(DFG_JIT)
    2874     return framePointerOffsetToGetActivationRegisters(jitCode()->dfgCommon()->machineCaptureStart);
    2875 #else
    2876     RELEASE_ASSERT_NOT_REACHED();
    2877     return 0;
    2878 #endif
    2879 }
    2880 
    28812813HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
    28822814{
     
    30612993{
    30622994    return ownerExecutable()->newReplacementCodeBlockFor(specializationKind());
    3063 }
    3064 
    3065 const SlowArgument* CodeBlock::machineSlowArguments()
    3066 {
    3067     if (!JITCode::isOptimizingJIT(jitType()))
    3068         return symbolTable()->slowArguments();
    3069    
    3070 #if ENABLE(DFG_JIT)
    3071     return jitCode()->dfgCommon()->slowArguments.get();
    3072 #else // ENABLE(DFG_JIT)
    3073     return 0;
    3074 #endif // ENABLE(DFG_JIT)
    30752995}
    30762996
     
    38573777    SymbolTable::Map::iterator end = symbolTable()->end(locker);
    38583778    for (SymbolTable::Map::iterator ptr = symbolTable()->begin(locker); ptr != end; ++ptr) {
    3859         if (ptr->value.getIndex() == virtualRegister.offset()) {
     3779        if (ptr->value.varOffset() == VarOffset(virtualRegister)) {
    38603780            // FIXME: This won't work from the compilation thread.
    38613781            // https://bugs.webkit.org/show_bug.cgi?id=115300
     
    38633783        }
    38643784    }
    3865     if (needsActivation() && virtualRegister == activationRegister())
    3866         return ASCIILiteral("lexical environment");
    38673785    if (virtualRegister == thisRegister())
    38683786        return ASCIILiteral("this");
    3869     if (usesArguments()) {
    3870         if (virtualRegister == argumentsRegister())
    3871             return ASCIILiteral("arguments");
    3872         if (unmodifiedArgumentsRegister(argumentsRegister()) == virtualRegister)
    3873             return ASCIILiteral("real arguments");
    3874     }
    38753787    if (virtualRegister.isArgument())
    38763788        return String::format("arguments[%3d]", virtualRegister.toArgument());
     
    38783790    return "";
    38793791}
    3880 
    3881 namespace {
    3882 
    3883 struct VerifyCapturedDef {
    3884     void operator()(CodeBlock* codeBlock, Instruction* instruction, OpcodeID opcodeID, int operand) const
    3885     {
    3886         unsigned bytecodeOffset = instruction - codeBlock->instructions().begin();
    3887        
    3888         if (codeBlock->isConstantRegisterIndex(operand)) {
    3889             codeBlock->beginValidationDidFail();
    3890             dataLog("    At bc#", bytecodeOffset, " encountered a definition of a constant.\n");
    3891             codeBlock->endValidationDidFail();
    3892             return;
    3893         }
    3894 
    3895         switch (opcodeID) {
    3896         case op_enter:
    3897         case op_init_lazy_reg:
    3898         case op_create_arguments:
    3899             return;
    3900         default:
    3901             break;
    3902         }
    3903 
    3904         VirtualRegister virtualReg(operand);
    3905         if (!virtualReg.isLocal())
    3906             return;
    3907 
    3908         if (codeBlock->usesArguments() && virtualReg == codeBlock->argumentsRegister())
    3909             return;
    3910         if (codeBlock->usesArguments() && virtualReg == unmodifiedArgumentsRegister(codeBlock->argumentsRegister()))
    3911             return;
    3912 
    3913         if (codeBlock->captureCount() && codeBlock->symbolTable()->isCaptured(operand)) {
    3914             codeBlock->beginValidationDidFail();
    3915             dataLog("    At bc#", bytecodeOffset, " encountered invalid assignment to captured variable ", virtualReg, ".\n");
    3916             codeBlock->endValidationDidFail();
    3917             return;
    3918         }
    3919        
    3920         return;
    3921     }
    3922 };
    3923 
    3924 } // anonymous namespace
    39253792
    39263793void CodeBlock::validate()
     
    39393806   
    39403807    for (unsigned i = m_numCalleeRegisters; i--;) {
    3941         bool isCaptured = false;
    39423808        VirtualRegister reg = virtualRegisterForLocal(i);
    39433809       
    3944         if (captureCount())
    3945             isCaptured = reg.offset() <= captureStart() && reg.offset() > captureEnd();
    3946        
    3947         if (isCaptured) {
    3948             if (!liveAtHead.get(i)) {
    3949                 beginValidationDidFail();
    3950                 dataLog("    Variable loc", i, " is expected to be live because it is captured, but it isn't live.\n");
    3951                 dataLog("    Result: ", liveAtHead, "\n");
    3952                 endValidationDidFail();
    3953             }
    3954         } else {
    3955             if (liveAtHead.get(i)) {
    3956                 beginValidationDidFail();
    3957                 dataLog("    Variable loc", i, " is expected to be dead.\n");
    3958                 dataLog("    Result: ", liveAtHead, "\n");
    3959                 endValidationDidFail();
    3960             }
    3961         }
    3962     }
    3963    
    3964     for (unsigned bytecodeOffset = 0; bytecodeOffset < instructions().size();) {
    3965         Instruction* currentInstruction = instructions().begin() + bytecodeOffset;
    3966         OpcodeID opcodeID = m_vm->interpreter->getOpcodeID(currentInstruction->u.opcode);
    3967        
    3968         VerifyCapturedDef verifyCapturedDef;
    3969         computeDefsForBytecodeOffset(this, bytecodeOffset, verifyCapturedDef);
    3970        
    3971         bytecodeOffset += opcodeLength(opcodeID);
     3810        if (liveAtHead.get(i)) {
     3811            beginValidationDidFail();
     3812            dataLog("    Variable ", reg, " is expected to be dead.\n");
     3813            dataLog("    Result: ", liveAtHead, "\n");
     3814            endValidationDidFail();
     3815        }
    39723816    }
    39733817}
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r181481 r181993  
    8484class TypeLocation;
    8585
    86 inline VirtualRegister unmodifiedArgumentsRegister(VirtualRegister argumentsRegister) { return VirtualRegister(argumentsRegister.offset() + 1); }
    87 
    8886enum ReoptimizationMode { DontCountReoptimization, CountReoptimization };
    8987
     
    260258    unsigned instructionCount() const { return m_instructions.size(); }
    261259
    262     int argumentIndexAfterCapture(size_t argument);
    263    
    264     bool hasSlowArguments();
    265     const SlowArgument* machineSlowArguments();
    266 
    267260    // Exactly equivalent to codeBlock->ownerExecutable()->installCode(codeBlock);
    268261    void install();
     
    328321    }
    329322
    330     void setArgumentsRegister(VirtualRegister argumentsRegister)
    331     {
    332         ASSERT(argumentsRegister.isValid());
    333         m_argumentsRegister = argumentsRegister;
    334         ASSERT(usesArguments());
    335     }
    336     VirtualRegister argumentsRegister() const
    337     {
    338         ASSERT(usesArguments());
    339         return m_argumentsRegister;
    340     }
    341     VirtualRegister uncheckedArgumentsRegister()
    342     {
    343         if (!usesArguments())
    344             return VirtualRegister();
    345         return argumentsRegister();
    346     }
    347 
    348323    void setActivationRegister(VirtualRegister activationRegister)
    349324    {
     
    362337    }
    363338
    364     bool usesArguments() const { return m_argumentsRegister.isValid(); }
    365 
    366339    bool needsActivation() const
    367340    {
     
    370343    }
    371344   
    372     unsigned captureCount() const
    373     {
    374         if (!symbolTable())
    375             return 0;
    376         return symbolTable()->captureCount();
    377     }
    378    
    379     int captureStart() const
    380     {
    381         if (!symbolTable())
    382             return 0;
    383         return symbolTable()->captureStart();
    384     }
    385    
    386     int captureEnd() const
    387     {
    388         if (!symbolTable())
    389             return 0;
    390         return symbolTable()->captureEnd();
    391     }
    392    
    393     bool isCaptured(VirtualRegister operand, InlineCallFrame* = 0) const;
    394    
    395     int framePointerOffsetToGetActivationRegisters(int machineCaptureStart);
    396     int framePointerOffsetToGetActivationRegisters();
    397 
    398345    CodeType codeType() const { return m_unlinkedCode->codeType(); }
    399346    PutPropertySlot::Context putByIdContext() const
     
    10601007    VirtualRegister m_thisRegister;
    10611008    VirtualRegister m_scopeRegister;
    1062     VirtualRegister m_argumentsRegister;
    10631009    VirtualRegister m_lexicalEnvironmentRegister;
    10641010
     
    12211167}
    12221168
    1223 inline int CodeBlock::argumentIndexAfterCapture(size_t argument)
    1224 {
    1225     if (argument >= static_cast<size_t>(symbolTable()->parameterCount()))
    1226         return CallFrame::argumentOffset(argument);
    1227    
    1228     const SlowArgument* slowArguments = symbolTable()->slowArguments();
    1229     if (!slowArguments || slowArguments[argument].status == SlowArgument::Normal)
    1230         return CallFrame::argumentOffset(argument);
    1231    
    1232     ASSERT(slowArguments[argument].status == SlowArgument::Captured);
    1233     return slowArguments[argument].index;
    1234 }
    1235 
    1236 inline bool CodeBlock::hasSlowArguments()
    1237 {
    1238     return !!symbolTable()->slowArguments();
    1239 }
    1240 
    12411169inline Register& ExecState::r(int index)
    12421170{
     
    12611189{
    12621190    return uncheckedR(reg.offset());
    1263 }
    1264 
    1265 inline JSValue ExecState::argumentAfterCapture(size_t argument)
    1266 {
    1267     if (argument >= argumentCount())
    1268         return jsUndefined();
    1269    
    1270     if (!codeBlock())
    1271         return this[argumentOffset(argument)].jsValue();
    1272    
    1273     return this[codeBlock()->argumentIndexAfterCapture(argument)].jsValue();
    12741191}
    12751192
  • trunk/Source/JavaScriptCore/bytecode/CodeOrigin.h

    r180279 r181993  
    190190    ValueRecovery calleeRecovery;
    191191    CodeOrigin caller;
    192     BitVector capturedVars; // Indexed by the machine call frame's variable numbering.
    193192
    194193    signed stackOffset : 28;
    195194    unsigned kind : 3; // real type is Kind
    196195    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.
    197     VirtualRegister argumentsRegister; // This is only set if the code uses arguments. The unmodified arguments register follows the unmodifiedArgumentsRegister() convention (see CodeBlock.h).
    198196    VirtualRegister argumentCountRegister; // Only set when we inline a varargs call.
    199197   
  • trunk/Source/JavaScriptCore/bytecode/DataFormat.h

    r156047 r181993  
    11/*
    2  * Copyright (C) 2011 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5757    // Special data formats used only for OSR.
    5858    DataFormatDead = 33, // Implies jsUndefined().
    59     DataFormatArguments = 34 // Implies that the arguments object must be reified.
    6059};
    6160
     
    9190    case DataFormatDead:
    9291        return "Dead";
    93     case DataFormatArguments:
    94         return "Arguments";
    9592    default:
    9693        RELEASE_ASSERT_NOT_REACHED();
  • trunk/Source/JavaScriptCore/bytecode/FullBytecodeLiveness.h

    r159394 r181993  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3737class FullBytecodeLiveness {
    3838public:
    39     FullBytecodeLiveness() : m_codeBlock(0) { }
    40    
    41     // We say "out" to refer to the bitvector that contains raw results for a bytecode
    42     // instruction.
    43     const FastBitVector& getOut(unsigned bytecodeIndex) const
     39    const FastBitVector& getLiveness(unsigned bytecodeIndex) const
    4440    {
    4541        BytecodeToBitmapMap::const_iterator iter = m_map.find(bytecodeIndex);
     
    5046    bool operandIsLive(int operand, unsigned bytecodeIndex) const
    5147    {
    52         return operandIsAlwaysLive(m_codeBlock, operand) || operandThatIsNotAlwaysLiveIsLive(m_codeBlock, getOut(bytecodeIndex), operand);
    53     }
    54    
    55     FastBitVector getLiveness(unsigned bytecodeIndex) const
    56     {
    57         return getLivenessInfo(m_codeBlock, getOut(bytecodeIndex));
     48        return operandIsAlwaysLive(operand) || operandThatIsNotAlwaysLiveIsLive(getLiveness(bytecodeIndex), operand);
    5849    }
    5950   
     
    6152    friend class BytecodeLivenessAnalysis;
    6253   
    63     CodeBlock* m_codeBlock;
    6454    BytecodeToBitmapMap m_map;
    6555};
  • trunk/Source/JavaScriptCore/bytecode/Instruction.h

    r176836 r181993  
    11/*
    2  * Copyright (C) 2008, 2012, 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2012-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    9898    Instruction(ArrayAllocationProfile* profile) { u.arrayAllocationProfile = profile; }
    9999    Instruction(ObjectAllocationProfile* profile) { u.objectAllocationProfile = profile; }
    100     Instruction(WriteBarrier<Unknown>* registerPointer) { u.registerPointer = registerPointer; }
     100    Instruction(WriteBarrier<Unknown>* variablePointer) { u.variablePointer = variablePointer; }
    101101    Instruction(Special::Pointer pointer) { u.specialPointer = pointer; }
    102102    Instruction(StringImpl* uid) { u.uid = uid; }
     
    109109        WriteBarrierBase<StructureChain> structureChain;
    110110        WriteBarrierBase<JSCell> jsCell;
    111         WriteBarrier<Unknown>* registerPointer;
     111        WriteBarrier<Unknown>* variablePointer;
    112112        Special::Pointer specialPointer;
    113113        PropertySlot::GetValueFunc getterFunc;
  • trunk/Source/JavaScriptCore/bytecode/Operands.h

    r174318 r181993  
    210210        return virtualRegisterForLocal(index - numberOfArguments()).offset();
    211211    }
     212    VirtualRegister virtualRegisterForIndex(size_t index) const
     213    {
     214        return VirtualRegister(operandForIndex(index));
     215    }
    212216    size_t indexForOperand(int operand) const
    213217    {
  • trunk/Source/JavaScriptCore/bytecode/SpeculatedType.cpp

    r180098 r181993  
    11/*
    2  * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011-2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3030#include "SpeculatedType.h"
    3131
    32 #include "Arguments.h"
     32#include "DirectArguments.h"
    3333#include "JSArray.h"
    3434#include "JSFunction.h"
    3535#include "JSCInlines.h"
     36#include "ScopedArguments.h"
    3637#include "StringObject.h"
    3738#include "ValueProfile.h"
     
    128129                isTop = false;
    129130   
    130             if (value & SpecArguments)
    131                 myOut.print("Arguments");
     131            if (value & SpecDirectArguments)
     132                myOut.print("Directarguments");
     133            else
     134                isTop = false;
     135   
     136            if (value & SpecScopedArguments)
     137                myOut.print("Scopedarguments");
    132138            else
    133139                isTop = false;
     
    233239    if (isFloat64ArraySpeculation(prediction))
    234240        return "<Float64array>";
    235     if (isArgumentsSpeculation(prediction))
    236         return "<Arguments>";
     241    if (isDirectArgumentsSpeculation(prediction))
     242        return "<DirectArguments>";
     243    if (isScopedArgumentsSpeculation(prediction))
     244        return "<ScopedArguments>";
    237245    if (isStringObjectSpeculation(prediction))
    238246        return "<StringObject>";
     
    306314        return SpecArray;
    307315   
    308     if (classInfo == Arguments::info())
    309         return SpecArguments;
     316    if (classInfo == DirectArguments::info())
     317        return SpecDirectArguments;
     318   
     319    if (classInfo == ScopedArguments::info())
     320        return SpecScopedArguments;
    310321   
    311322    if (classInfo == StringObject::info())
  • trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h

    r180098 r181993  
    11/*
    2  * Copyright (C) 2011-2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5353static const SpeculatedType SpecFloat64Array       = 0x00000800; // It's definitely an Uint16Array or one of its subclasses.
    5454static const SpeculatedType SpecTypedArrayView     = SpecInt8Array | SpecInt16Array | SpecInt32Array | SpecUint8Array | SpecUint8ClampedArray | SpecUint16Array | SpecUint32Array | SpecFloat32Array | SpecFloat64Array;
    55 static const SpeculatedType SpecArguments          = 0x00001000; // It's definitely an Arguments object.
    56 static const SpeculatedType SpecStringObject       = 0x00002000; // It's definitely a StringObject.
     55static const SpeculatedType SpecDirectArguments    = 0x00001000; // It's definitely a DirectArguments object.
     56static const SpeculatedType SpecScopedArguments    = 0x00002000; // It's definitely a ScopedArguments object.
     57static const SpeculatedType SpecStringObject       = 0x00004000; // It's definitely a StringObject.
    5758static const SpeculatedType SpecObjectOther        = 0x00008000; // It's definitely an object but not JSFinalObject, JSArray, or JSFunction.
    5859static const SpeculatedType SpecObject             = 0x0000ffff; // Bitmask used for testing for any kind of object prediction.
     
    194195}
    195196
    196 inline bool isArgumentsSpeculation(SpeculatedType value)
    197 {
    198     return !!value && (value & SpecArguments) == value;
     197inline bool isDirectArgumentsSpeculation(SpeculatedType value)
     198{
     199    return value == SpecDirectArguments;
     200}
     201
     202inline bool isScopedArgumentsSpeculation(SpeculatedType value)
     203{
     204    return value == SpecScopedArguments;
    199205}
    200206
     
    225231{
    226232    return isArraySpeculation(value)
    227         || isArgumentsSpeculation(value)
    228233        || isActionableTypedMutableArraySpeculation(value);
    229234}
     
    232237{
    233238    return isStringSpeculation(value)
     239        || isDirectArgumentsSpeculation(value)
     240        || isScopedArgumentsSpeculation(value)
    234241        || isActionableMutableArraySpeculation(value);
    235242}
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp

    r181901 r181993  
    11/*
    2  * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.
     2 * Copyright (C) 2012, 2013, 2015 Apple Inc. All Rights Reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    210210    , m_numParameters(0)
    211211    , m_vm(vm)
    212     , m_argumentsRegister(VirtualRegister())
    213212    , m_globalObjectRegister(VirtualRegister())
    214213    , m_needsFullScopeChain(info.needsActivation())
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h

    r181901 r181993  
    11/*
    2  * Copyright (C) 2012, 2013, 2014 Apple Inc. All Rights Reserved.
     2 * Copyright (C) 2012-2015 Apple Inc. All Rights Reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    288288    void setActivationRegister(VirtualRegister activationRegister) { m_lexicalEnvironmentRegister = activationRegister; }
    289289
    290     void setArgumentsRegister(VirtualRegister argumentsRegister) { m_argumentsRegister = argumentsRegister; }
    291     bool usesArguments() const { return m_argumentsRegister.isValid(); }
    292     VirtualRegister argumentsRegister() const { return m_argumentsRegister; }
    293 
    294 
    295290    bool usesGlobalObject() const { return m_globalObjectRegister.isValid(); }
    296291    void setGlobalObjectRegister(VirtualRegister globalObjectRegister) { m_globalObjectRegister = globalObjectRegister; }
     
    532527
    533528    VirtualRegister m_thisRegister;
    534     VirtualRegister m_argumentsRegister;
    535529    VirtualRegister m_scopeRegister;
    536530    VirtualRegister m_lexicalEnvironmentRegister;
  • trunk/Source/JavaScriptCore/bytecode/ValueRecovery.cpp

    r180279 r181993  
    113113        out.print("*bool(", virtualRegister(), ")");
    114114        return;
    115     case ArgumentsThatWereNotCreated:
    116         out.printf("arguments");
     115    case DirectArgumentsThatWereNotCreated:
     116        out.print("DirectArguments(", nodeID(), ")");
     117        return;
     118    case ClonedArgumentsThatWereNotCreated:
     119        out.print("ClonedArguments(", nodeID(), ")");
    117120        return;
    118121    case Constant:
  • trunk/Source/JavaScriptCore/bytecode/ValueRecovery.h

    r164424 r181993  
    11/*
    2  * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011, 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2727#define ValueRecovery_h
    2828
     29#include "DFGMinifiedID.h"
    2930#include "DataFormat.h"
    3031#if ENABLE(JIT)
     
    3940
    4041struct DumpContext;
     42struct InlineCallFrame;
    4143
    4244// Describes how to recover a given bytecode virtual register at a given
     
    6365    CellDisplacedInJSStack,
    6466    BooleanDisplacedInJSStack,
    65     // It's an Arguments object.
    66     ArgumentsThatWereNotCreated,
     67    // It's an Arguments object. This arises because of the simplified arguments simplification done by the DFG.
     68    DirectArgumentsThatWereNotCreated,
     69    ClonedArgumentsThatWereNotCreated,
    6770    // It's a constant.
    6871    Constant,
     
    168171    }
    169172   
    170     static ValueRecovery argumentsThatWereNotCreated()
    171     {
    172         ValueRecovery result;
    173         result.m_technique = ArgumentsThatWereNotCreated;
     173    static ValueRecovery directArgumentsThatWereNotCreated(DFG::MinifiedID id)
     174    {
     175        ValueRecovery result;
     176        result.m_technique = DirectArgumentsThatWereNotCreated;
     177        result.m_source.nodeID = id.bits();
     178        return result;
     179    }
     180   
     181    static ValueRecovery outOfBandArgumentsThatWereNotCreated(DFG::MinifiedID id)
     182    {
     183        ValueRecovery result;
     184        result.m_technique = ClonedArgumentsThatWereNotCreated;
     185        result.m_source.nodeID = id.bits();
    174186        return result;
    175187    }
     
    257269    }
    258270   
     271    DFG::MinifiedID nodeID() const
     272    {
     273        ASSERT(m_technique == DirectArgumentsThatWereNotCreated || m_technique == ClonedArgumentsThatWereNotCreated);
     274        return DFG::MinifiedID::fromBits(m_source.nodeID);
     275    }
     276   
    259277    JSValue recover(ExecState*) const;
    260278   
     
    277295        int virtualReg;
    278296        EncodedJSValue constant;
     297        uintptr_t nodeID;
    279298    } m_source;
    280299};
  • trunk/Source/JavaScriptCore/bytecode/VirtualRegister.h

    r179862 r181993  
    6868    int offsetInBytes() const { return m_virtualRegister * sizeof(Register); }
    6969
    70     bool operator==(const VirtualRegister other) const { return m_virtualRegister == other.m_virtualRegister; }
    71     bool operator!=(const VirtualRegister other) const { return m_virtualRegister != other.m_virtualRegister; }
     70    bool operator==(VirtualRegister other) const { return m_virtualRegister == other.m_virtualRegister; }
     71    bool operator!=(VirtualRegister other) const { return m_virtualRegister != other.m_virtualRegister; }
     72    bool operator<(VirtualRegister other) const { return m_virtualRegister < other.m_virtualRegister; }
     73    bool operator>(VirtualRegister other) const { return m_virtualRegister > other.m_virtualRegister; }
     74    bool operator<=(VirtualRegister other) const { return m_virtualRegister <= other.m_virtualRegister; }
     75    bool operator>=(VirtualRegister other) const { return m_virtualRegister >= other.m_virtualRegister; }
    7276   
    7377    VirtualRegister operator+(int value) const
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r181924 r181993  
    6565   
    6666    m_codeBlock->setThisRegister(m_thisRegister.virtualRegister());
     67   
     68    // If we have declared a variable named "arguments" and we are using arguments then we should
     69    // perform that assignment now.
     70    if (m_needToInitializeArguments)
     71        initializeVariable(variable(propertyNames().arguments), m_argumentsRegister);
     72   
     73    {
     74        RefPtr<RegisterID> temp = newTemporary();
     75        for (FunctionBodyNode* functionBody : m_functionsToInitialize) {
     76            emitNewFunction(temp.get(), functionBody);
     77            initializeVariable(variable(functionBody->ident()), temp.get());
     78        }
     79    }
     80   
    6781    for (size_t i = 0; i < m_deconstructedParameters.size(); i++) {
    6882        auto& entry = m_deconstructedParameters[i];
     
    120134
    121135    if (m_codeBlock->symbolTable() && !m_codeBlock->vm()->typeProfiler())
    122         m_codeBlock->setSymbolTable(m_codeBlock->symbolTable()->cloneCapturedNames(*m_codeBlock->vm()));
     136        m_codeBlock->setSymbolTable(m_codeBlock->symbolTable()->cloneScopePart(*m_codeBlock->vm()));
    123137
    124138    if (m_expressionTooDeep)
    125139        return ParserError(ParserError::OutOfMemory);
    126140    return ParserError(ParserError::ErrorNone);
    127 }
    128 
    129 RegisterID* BytecodeGenerator::addVar(
    130     const Identifier& ident, ConstantMode constantMode, WatchMode watchMode)
    131 {
    132     ASSERT(static_cast<size_t>(m_codeBlock->m_numVars) == m_calleeRegisters.size());
    133    
    134     ConcurrentJITLocker locker(symbolTable().m_lock);
    135     int index = virtualRegisterForLocal(m_calleeRegisters.size()).offset();
    136     SymbolTableEntry newEntry(index, constantMode == IsConstant ? ReadOnly : 0);
    137     SymbolTable::Map::AddResult result = symbolTable().add(locker, ident.impl(), newEntry);
    138 
    139     if (!result.isNewEntry)
    140         return &registerFor(result.iterator->value.getIndex());
    141    
    142     if (watchMode == IsWatchable) {
    143         while (m_watchableVariables.size() < static_cast<size_t>(m_codeBlock->m_numVars))
    144             m_watchableVariables.append(Identifier());
    145         m_watchableVariables.append(ident);
    146     }
    147    
    148     RegisterID* regID = addVar();
    149     ASSERT(watchMode == NotWatchable || static_cast<size_t>(m_codeBlock->m_numVars) == m_watchableVariables.size());
    150    
    151     return regID;
    152141}
    153142
     
    193182    if (m_isBuiltinFunction)
    194183        m_shouldEmitDebugHooks = false;
    195 
     184   
    196185    m_symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode());
    197186    Vector<Identifier> boundParameterProperties;
     
    204193        continue;
    205194    }
    206     m_symbolTable->setParameterCountIncludingThis(functionNode->parameters()->size() + 1);
     195
     196    bool shouldCaptureSomeOfTheThings = m_shouldEmitDebugHooks || m_codeBlock->needsFullScopeChain();
     197    bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
     198    bool needsArguments = functionNode->usesArguments() || codeBlock->usesEval();
     199   
     200    auto captures = [&] (StringImpl* uid) -> bool {
     201        if (shouldCaptureAllOfTheThings)
     202            return true;
     203        if (!shouldCaptureSomeOfTheThings)
     204            return false;
     205        if (needsArguments && uid == propertyNames().arguments.impl()) {
     206            // Actually, we only need to capture the arguments object when we "need full activation"
     207            // because of name scopes. But historically we did it this way, so for now we just preserve
     208            // the old behavior.
     209            // FIXME: https://bugs.webkit.org/show_bug.cgi?id=143072
     210            return true;
     211        }
     212        return functionNode->captures(uid);
     213    };
     214    auto varKind = [&] (StringImpl* uid) -> VarKind {
     215        return captures(uid) ? VarKind::Scope : VarKind::Stack;
     216    };
    207217
    208218    emitOpcode(op_enter);
    209219
    210220    allocateAndEmitScope();
     221   
     222    m_calleeRegister.setIndex(JSStack::Callee);
    211223   
    212224    if (functionNameIsInScope(functionNode->ident(), functionNode->functionMode())
     
    218230        // be any more correct, but it would be more performant.
    219231        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=141887
    220         RegisterID calleeRegister;
    221         calleeRegister.setIndex(JSStack::Callee);
    222         emitPushFunctionNameScope(m_scopeRegister, functionNode->ident(), &calleeRegister, ReadOnly | DontDelete);
    223     }
    224 
    225     if (m_codeBlock->needsFullScopeChain() || m_shouldEmitDebugHooks) {
     232        emitPushFunctionNameScope(m_scopeRegister, functionNode->ident(), &m_calleeRegister, ReadOnly | DontDelete);
     233    }
     234
     235    if (shouldCaptureSomeOfTheThings) {
    226236        m_lexicalEnvironmentRegister = addVar();
    227237        m_codeBlock->setActivationRegister(m_lexicalEnvironmentRegister->virtualRegister());
     
    229239        instructions().append(m_lexicalEnvironmentRegister->index());
    230240        instructions().append(scopeRegister()->index());
    231     }
    232     RegisterID* localArgumentsRegister = nullptr;
    233     RegisterID* scratch = addVar();
    234     m_symbolTable->setCaptureStart(virtualRegisterForLocal(m_codeBlock->m_numVars).offset());
    235 
    236     if (functionNode->usesArguments() || codeBlock->usesEval()) { // May reify arguments object.
    237         RegisterID* unmodifiedArgumentsRegister = addVar(); // Anonymous, so it can't be modified by user code.
    238         RegisterID* argumentsRegister = addVar(propertyNames().arguments, IsVariable, NotWatchable); // Can be changed by assigning to 'arguments'.
    239 
    240         localArgumentsRegister = argumentsRegister;
    241 
    242         // We can save a little space by hard-coding the knowledge that the two
    243         // 'arguments' values are stored in consecutive registers, and storing
    244         // only the index of the assignable one.
    245         codeBlock->setArgumentsRegister(argumentsRegister->virtualRegister());
    246         ASSERT_UNUSED(unmodifiedArgumentsRegister, unmodifiedArgumentsRegister->virtualRegister() == JSC::unmodifiedArgumentsRegister(codeBlock->argumentsRegister()));
    247 
    248         emitInitLazyRegister(argumentsRegister);
    249         emitInitLazyRegister(unmodifiedArgumentsRegister);
    250        
    251         if (shouldCreateArgumentsEagerly() || shouldTearOffArgumentsEagerly()) {
    252             emitOpcode(op_create_arguments);
    253             instructions().append(argumentsRegister->index());
    254             instructions().append(m_codeBlock->activationRegister().offset());
    255 
    256             if (m_codeBlock->hasActivationRegister()) {
    257                 RegisterID* argumentsRegister = &registerFor(m_codeBlock->argumentsRegister().offset());
    258                 initializeCapturedVariable(argumentsRegister, propertyNames().arguments, argumentsRegister);
    259                 RegisterID* uncheckedArgumentsRegister = &registerFor(JSC::unmodifiedArgumentsRegister(m_codeBlock->argumentsRegister()).offset());
    260                 initializeCapturedVariable(uncheckedArgumentsRegister, propertyNames().arguments, uncheckedArgumentsRegister);
    261                 if (functionNode->modifiesArguments()) {
    262                     emitOpcode(op_mov);
    263                     instructions().append(argumentsRegister->index());
    264                     instructions().append(addConstantValue(jsUndefined())->index());
    265                     emitOpcode(op_mov);
    266                     instructions().append(uncheckedArgumentsRegister->index());
    267                     instructions().append(addConstantValue(jsUndefined())->index());
    268                     localArgumentsRegister = nullptr;
    269                 }
    270             }
    271         }
    272     }
    273 
    274     bool shouldCaptureAllTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
    275 
     241        emitOpcode(op_mov);
     242        instructions().append(scopeRegister()->index());
     243        instructions().append(m_lexicalEnvironmentRegister->index());
     244    }
     245   
     246    // Make sure the code block knows about all of our parameters, and make sure that parameters
     247    // needing deconstruction are noted.
     248    m_parameters.grow(parameters.size() + 1); // reserve space for "this"
     249    m_thisRegister.setIndex(initializeNextParameter()->index()); // this
     250    for (unsigned i = 0; i < parameters.size(); ++i) {
     251        auto pattern = parameters.at(i);
     252        RegisterID* reg = initializeNextParameter();
     253        if (!pattern->isBindingNode())
     254            m_deconstructedParameters.append(std::make_pair(reg, pattern));
     255    }
     256   
     257    // Figure out some interesting facts about our arguments.
    276258    bool capturesAnyArgumentByName = false;
    277     Vector<RegisterID*, 0, UnsafeVectorOverflow> capturedArguments;
    278     if (functionNode->hasCapturedVariables() || shouldCaptureAllTheThings) {
     259    if (functionNode->hasCapturedVariables()) {
    279260        FunctionParameters& parameters = *functionNode->parameters();
    280         capturedArguments.resize(parameters.size());
    281261        for (size_t i = 0; i < parameters.size(); ++i) {
    282             capturedArguments[i] = 0;
    283262            auto pattern = parameters.at(i);
    284263            if (!pattern->isBindingNode())
    285264                continue;
    286265            const Identifier& ident = static_cast<const BindingNode*>(pattern)->boundProperty();
    287             if (!functionNode->captures(ident) && !shouldCaptureAllTheThings)
     266            capturesAnyArgumentByName |= captures(ident.impl());
     267        }
     268    }
     269
     270    if (capturesAnyArgumentByName)
     271        ASSERT(m_lexicalEnvironmentRegister);
     272   
     273    // Need to know what our functions are called. Parameters have some goofy behaviors when it
     274    // comes to functions of the same name.
     275    for (FunctionBodyNode* function : functionNode->functionStack())
     276        m_functions.add(function->ident().impl());
     277   
     278    if (needsArguments) {
     279        // Create the arguments object now. We may put the arguments object into the activation if
     280        // it is captured. Either way, we create two arguments object variables: one is our
     281        // private variable that is immutable, and another that is the user-visible variable. The
     282        // immutable one is only used here, or during formal parameter resolutions if we opt for
     283        // DirectArguments.
     284       
     285        m_argumentsRegister = addVar();
     286        m_argumentsRegister->ref();
     287    }
     288   
     289    if (needsArguments && !codeBlock->isStrictMode()) {
     290        // If we captured any formal parameter by name, then we use ScopedArguments. Otherwise we
     291        // use DirectArguments. With ScopedArguments, we lift all of our arguments into the
     292        // activation.
     293       
     294        if (capturesAnyArgumentByName) {
     295            m_symbolTable->setArgumentsLength(vm, parameters.size());
     296           
     297            // For each parameter, we have two possibilities:
     298            // Either it's a binding node with no function overlap, in which case it gets a name
     299            // in the symbol table - or it just gets space reserved in the symbol table. Either
     300            // way we lift the value into the scope.
     301            for (unsigned i = 0; i < parameters.size(); ++i) {
     302                ScopeOffset offset = m_symbolTable->takeNextScopeOffset();
     303                m_symbolTable->setArgumentOffset(vm, i, offset);
     304                if (StringImpl* name = visibleNameForParameter(parameters.at(i))) {
     305                    VarOffset varOffset(offset);
     306                    SymbolTableEntry entry(varOffset);
     307                    // Stores to these variables via the ScopedArguments object will not do
     308                    // notifyWrite(), since that would be cumbersome. Also, watching formal
     309                    // parameters when "arguments" is in play is unlikely to be super profitable.
     310                    // So, we just disable it.
     311                    entry.disableWatching();
     312                    m_symbolTable->set(name, entry);
     313                }
     314                emitOpcode(op_put_to_scope);
     315                instructions().append(m_lexicalEnvironmentRegister->index());
     316                instructions().append(UINT_MAX);
     317                instructions().append(virtualRegisterForArgument(1 + i).offset());
     318                instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
     319                instructions().append(0);
     320                instructions().append(offset.offset());
     321            }
     322           
     323            // This creates a scoped arguments object and copies the overflow arguments into the
     324            // scope. It's the equivalent of calling ScopedArguments::createByCopying().
     325            emitOpcode(op_create_scoped_arguments);
     326            instructions().append(m_argumentsRegister->index());
     327            instructions().append(m_lexicalEnvironmentRegister->index());
     328        } else {
     329            // We're going to put all parameters into the DirectArguments object. First ensure
     330            // that the symbol table knows that this is happening.
     331            for (unsigned i = 0; i < parameters.size(); ++i) {
     332                if (StringImpl* name = visibleNameForParameter(parameters.at(i)))
     333                    m_symbolTable->set(name, SymbolTableEntry(VarOffset(DirectArgumentsOffset(i))));
     334            }
     335           
     336            emitOpcode(op_create_direct_arguments);
     337            instructions().append(m_argumentsRegister->index());
     338        }
     339    } else {
     340        // Create the formal parameters the normal way. Any of them could be captured, or not. If
     341        // captured, lift them into the scope.
     342        for (unsigned i = 0; i < parameters.size(); ++i) {
     343            StringImpl* name = visibleNameForParameter(parameters.at(i));
     344            if (!name)
    288345                continue;
    289             capturesAnyArgumentByName = true;
    290             capturedArguments[i] = addVar(ident, IsVariable, IsWatchable);
    291         }
    292     }
    293 
    294     if (capturesAnyArgumentByName && !shouldTearOffArgumentsEagerly()) {
    295         size_t parameterCount = m_symbolTable->parameterCount();
    296         auto slowArguments = std::make_unique<SlowArgument[]>(parameterCount);
    297         for (size_t i = 0; i < parameterCount; ++i) {
    298             if (!capturedArguments[i]) {
    299                 ASSERT(slowArguments[i].status == SlowArgument::Normal);
    300                 slowArguments[i].index = CallFrame::argumentOffset(i);
     346           
     347            if (!captures(name)) {
     348                // This is the easy case - just tell the symbol table about the argument. It will
     349                // be accessed directly.
     350                m_symbolTable->set(name, SymbolTableEntry(VarOffset(virtualRegisterForArgument(1 + i))));
    301351                continue;
    302352            }
    303             slowArguments[i].status = SlowArgument::Captured;
    304             slowArguments[i].index = capturedArguments[i]->index();
    305         }
    306         m_symbolTable->setSlowArguments(WTF::move(slowArguments));
    307     }
    308 
    309     RegisterID* calleeRegister = resolveCallee(functionNode); // May push to the scope chain and/or add a captured var.
    310 
    311     const DeclarationStacks::FunctionStack& functionStack = functionNode->functionStack();
    312     const DeclarationStacks::VarStack& varStack = functionNode->varStack();
    313     IdentifierSet test;
    314 
    315     // Captured variables and functions go first so that activations don't have
    316     // to step over the non-captured locals to mark them.
    317     if (functionNode->hasCapturedVariables() || shouldCaptureAllTheThings) {
    318         for (size_t i = 0; i < boundParameterProperties.size(); i++) {
    319             const Identifier& ident = boundParameterProperties[i];
    320             if (functionNode->captures(ident) || shouldCaptureAllTheThings)
    321                 addVar(ident, IsVariable, IsWatchable);
    322         }
    323         for (size_t i = 0; i < functionStack.size(); ++i) {
    324             FunctionBodyNode* function = functionStack[i];
    325             const Identifier& ident = function->ident();
    326             if (functionNode->captures(ident) || shouldCaptureAllTheThings) {
    327                 m_functions.add(ident.impl());
    328                 emitNewFunction(scratch, function);
    329                 initializeCapturedVariable(addVar(ident, IsVariable, IsWatchable), ident, scratch);
     353           
     354            ScopeOffset offset = m_symbolTable->takeNextScopeOffset();
     355            const Identifier& ident =
     356                static_cast<const BindingNode*>(parameters.at(i))->boundProperty();
     357            m_symbolTable->set(name, SymbolTableEntry(VarOffset(offset)));
     358           
     359            emitOpcode(op_put_to_scope);
     360            instructions().append(m_lexicalEnvironmentRegister->index());
     361            instructions().append(addConstant(ident));
     362            instructions().append(virtualRegisterForArgument(1 + i).offset());
     363            instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
     364            instructions().append(0);
     365            instructions().append(offset.offset());
     366        }
     367    }
     368   
     369    if (needsArguments && codeBlock->isStrictMode()) {
     370        // Allocate an out-of-bands arguments object.
     371        emitOpcode(op_create_out_of_band_arguments);
     372        instructions().append(m_argumentsRegister->index());
     373    }
     374   
     375    // Now declare all variables.
     376    for (const Identifier& ident : boundParameterProperties)
     377        createVariable(ident, varKind(ident.impl()), IsVariable);
     378    for (FunctionBodyNode* function : functionNode->functionStack()) {
     379        const Identifier& ident = function->ident();
     380        createVariable(ident, varKind(ident.impl()), IsVariable);
     381        m_functionsToInitialize.append(function);
     382    }
     383    for (auto& entry : functionNode->varStack()) {
     384        ConstantMode constantMode = modeForIsConstant(entry.second & DeclarationStacks::IsConstant);
     385        // Variables named "arguments" are never const.
     386        if (entry.first == propertyNames().arguments)
     387            constantMode = IsVariable;
     388        createVariable(entry.first, varKind(entry.first.impl()), constantMode, IgnoreExisting);
     389    }
     390   
     391    // There are some variables that need to be preinitialized to something other than Undefined:
     392    //
     393    // - "arguments": unless it's used as a function or parameter, this should refer to the
     394    //   arguments object.
     395    //
     396    // - callee: unless it's used as a var, function, or parameter, this should refer to the
     397    //   callee (i.e. our function).
     398    //
     399    // - functions: these always override everything else.
     400    //
     401    // The most logical way to do all of this is to initialize none of the variables until now,
     402    // and then initialize them in BytecodeGenerator::generate() in such an order that the rules
     403    // for how these things override each other end up holding. We would initialize the callee
     404    // first, then "arguments", then all arguments, then the functions.
     405    //
     406    // But some arguments are already initialized by default, since if they aren't captured and we
     407    // don't have "arguments" then we just point the symbol table at the stack slot of those
     408    // arguments. We end up initializing the rest of the arguments that have an uncomplicated
     409    // binding (i.e. don't involve deconstruction) above when figuring out how to lay them out,
     410    // because that's just the simplest thing. This means that when we initialize them, we have to
     411    // watch out for the things that override arguments (namely, functions).
     412    //
     413    // We also initialize callee here as well, just because it's so weird. We know whether we want
     414    // to do this because we can just check if it's in the symbol table.
     415    if (functionNameIsInScope(functionNode->ident(), functionNode->functionMode())
     416        && !functionNameScopeIsDynamic(codeBlock->usesEval(), codeBlock->isStrictMode())
     417        && m_symbolTable->get(functionNode->ident().impl()).isNull()) {
     418        if (captures(functionNode->ident().impl())) {
     419            ScopeOffset offset;
     420            {
     421                ConcurrentJITLocker locker(m_symbolTable->m_lock);
     422                offset = m_symbolTable->takeNextScopeOffset(locker);
     423                m_symbolTable->add(
     424                    locker, functionNode->ident().impl(),
     425                    SymbolTableEntry(VarOffset(offset), ReadOnly));
    330426            }
    331         }
    332         for (size_t i = 0; i < varStack.size(); ++i) {
    333             const Identifier& ident = varStack[i].first;
    334             if (functionNode->captures(ident) || shouldCaptureAllTheThings)
    335                 addVar(ident, (varStack[i].second & DeclarationStacks::IsConstant) ? IsConstant : IsVariable, IsWatchable);
    336         }
    337     }
    338 
    339     m_symbolTable->setCaptureEnd(virtualRegisterForLocal(codeBlock->m_numVars).offset());
    340 
    341     bool canLazilyCreateFunctions = !functionNode->needsActivationForMoreThanVariables() && !m_shouldEmitDebugHooks && !m_vm->typeProfiler() && !m_vm->controlFlowProfiler();
    342     m_firstLazyFunction = codeBlock->m_numVars;
    343     if (!shouldCaptureAllTheThings) {
    344         for (size_t i = 0; i < functionStack.size(); ++i) {
    345             FunctionBodyNode* function = functionStack[i];
    346             const Identifier& ident = function->ident();
    347             if (!functionNode->captures(ident)) {
    348                 m_functions.add(ident.impl());
    349                 RefPtr<RegisterID> reg = addVar(ident, IsVariable, NotWatchable);
    350                 // Don't lazily create functions that override the name 'arguments'
    351                 // as this would complicate lazy instantiation of actual arguments.
    352                 if (!canLazilyCreateFunctions || ident == propertyNames().arguments)
    353                     emitNewFunction(reg.get(), function);
    354                 else {
    355                     emitInitLazyRegister(reg.get());
    356                     m_lazyFunctions.set(reg->virtualRegister().toLocal(), function);
    357                 }
     427           
     428            emitOpcode(op_put_to_scope);
     429            instructions().append(m_lexicalEnvironmentRegister->index());
     430            instructions().append(addConstant(functionNode->ident()));
     431            instructions().append(m_calleeRegister.index());
     432            instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
     433            instructions().append(0);
     434            instructions().append(offset.offset());
     435        } else {
     436            m_symbolTable->add(
     437                functionNode->ident().impl(),
     438                SymbolTableEntry(VarOffset(m_calleeRegister.virtualRegister()), ReadOnly));
     439        }
     440    }
     441   
     442    // This is our final act of weirdness. "arguments" is overridden by everything except the
     443    // callee. We add it to the symbol table if it's not already there and it's not an argument.
     444    if (needsArguments) {
     445        // If "arguments" is overridden by a function or deconstructed parameter name, then it's
     446        // OK for us to call createVariable() because it won't change anything. It's also OK for
     447        // us to them tell BytecodeGenerator::generate() to write to it because it will do so
     448        // before it initializes functions and deconstructed parameters. But if "arguments" is
     449        // overridden by a "simple" function parameter, then we have to bail: createVariable()
     450        // would assert and BytecodeGenerator::generate() would write the "arguments" after the
     451        // argument value had already been properly initialized.
     452       
     453        bool haveParameterNamedArguments = false;
     454        for (unsigned i = 0; i < parameters.size(); ++i) {
     455            StringImpl* name = visibleNameForParameter(parameters.at(i));
     456            if (name == propertyNames().arguments.impl()) {
     457                haveParameterNamedArguments = true;
     458                break;
    358459            }
    359460        }
    360         m_lastLazyFunction = canLazilyCreateFunctions ? codeBlock->m_numVars : m_firstLazyFunction;
    361         for (size_t i = 0; i < boundParameterProperties.size(); i++) {
    362             const Identifier& ident = boundParameterProperties[i];
    363             if (!functionNode->captures(ident))
    364                 addVar(ident, IsVariable, IsWatchable);
    365         }
    366         for (size_t i = 0; i < varStack.size(); ++i) {
    367             const Identifier& ident = varStack[i].first;
    368             if (!functionNode->captures(ident))
    369                 addVar(ident, (varStack[i].second & DeclarationStacks::IsConstant) ? IsConstant : IsVariable, NotWatchable);
    370         }
    371     }
    372 
    373     if (m_symbolTable->captureCount())
     461       
     462        if (!haveParameterNamedArguments) {
     463            createVariable(
     464                propertyNames().arguments, varKind(propertyNames().arguments.impl()), IsVariable);
     465            m_needToInitializeArguments = true;
     466        }
     467    }
     468   
     469    if (m_symbolTable->scopeSize())
    374470        emitOpcode(op_touch_entry);
    375    
    376     m_parameters.grow(parameters.size() + 1); // reserve space for "this"
    377 
    378     // Add "this" as a parameter
    379     int nextParameterIndex = CallFrame::thisArgumentOffset();
    380     m_thisRegister.setIndex(nextParameterIndex++);
    381     m_codeBlock->addParameter();
    382 
    383     for (size_t i = 0; i < parameters.size(); ++i, ++nextParameterIndex) {
    384         int index = nextParameterIndex;
    385         auto pattern = parameters.at(i);
    386         if (!pattern->isBindingNode()) {
    387             m_codeBlock->addParameter();
    388             RegisterID& parameter = registerFor(index);
    389             parameter.setIndex(index);
    390             m_deconstructedParameters.append(std::make_pair(&parameter, pattern));
    391             continue;
    392         }
    393         auto simpleParameter = static_cast<const BindingNode*>(pattern);
    394         if (capturedArguments.size() && capturedArguments[i] && !m_functions.contains(simpleParameter->boundProperty().impl())) {
    395             ASSERT((functionNode->hasCapturedVariables() && functionNode->captures(simpleParameter->boundProperty())) || shouldCaptureAllTheThings);
    396             index = capturedArguments[i]->index();
    397             RegisterID original(nextParameterIndex);
    398             initializeCapturedVariable(capturedArguments[i], simpleParameter->boundProperty(), &original);
    399         }
    400         addParameter(simpleParameter->boundProperty(), index);
    401     }
    402 
    403     // We declare the callee's name last because it should lose to a var, function, and/or parameter declaration.
    404     addCallee(functionNode, calleeRegister);
    405471
    406472    if (isConstructor()) {
     
    420486        instructions().append(0);
    421487    }
    422     m_localArgumentsRegister = localArgumentsRegister;
    423488}
    424489
     
    459524}
    460525
    461 RegisterID* BytecodeGenerator::emitInitLazyRegister(RegisterID* reg)
    462 {
    463     emitOpcode(op_init_lazy_reg);
    464     instructions().append(reg->index());
    465     ASSERT(!hasWatchableVariable(reg->index()));
    466     return reg;
    467 }
    468 
    469 RegisterID* BytecodeGenerator::initializeCapturedVariable(RegisterID* dst, const Identifier& propertyName, RegisterID* value)
    470 {
    471 
    472     m_codeBlock->addPropertyAccessInstruction(instructions().size());
    473     emitOpcode(op_put_to_scope);
    474     instructions().append(m_lexicalEnvironmentRegister->index());
    475     instructions().append(addConstant(propertyName));
    476     instructions().append(value->index());
    477     instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
    478     int operand = registerFor(dst->index()).index();
    479     bool isWatchableVariable = hasWatchableVariable(operand);
    480     ASSERT(!isWatchableVariable || watchableVariableIdentifier(operand) == propertyName);
    481     instructions().append(isWatchableVariable);
    482     instructions().append(dst->index());
    483     return dst;
    484 }
    485 
    486 RegisterID* BytecodeGenerator::resolveCallee(FunctionNode* functionNode)
    487 {
    488     if (!functionNameIsInScope(functionNode->ident(), functionNode->functionMode()))
    489         return 0;
    490 
    491     if (functionNameScopeIsDynamic(m_codeBlock->usesEval(), m_codeBlock->isStrictMode()))
    492         return 0;
    493 
    494     m_calleeRegister.setIndex(JSStack::Callee);
    495     if (functionNode->captures(functionNode->ident()))
    496         return initializeCapturedVariable(addVar(), functionNode->ident(), &m_calleeRegister);
    497 
    498     return &m_calleeRegister;
    499 }
    500 
    501 void BytecodeGenerator::addCallee(FunctionNode* functionNode, RegisterID* calleeRegister)
    502 {
    503     if (!calleeRegister)
    504         return;
    505 
    506     symbolTable().add(functionNode->ident().impl(), SymbolTableEntry(calleeRegister->index(), ReadOnly));
    507 }
    508 
    509 void BytecodeGenerator::addParameter(const Identifier& ident, int parameterIndex)
    510 {
    511     // Parameters overwrite var declarations, but not function declarations.
    512     StringImpl* rep = ident.impl();
    513     if (!m_functions.contains(rep)) {
    514         symbolTable().set(rep, parameterIndex);
    515         RegisterID& parameter = registerFor(parameterIndex);
    516         parameter.setIndex(parameterIndex);
    517     }
    518 
    519     // To maintain the calling convention, we have to allocate unique space for
    520     // each parameter, even if the parameter doesn't make it into the symbol table.
     526RegisterID* BytecodeGenerator::initializeNextParameter()
     527{
     528    VirtualRegister reg = virtualRegisterForArgument(m_codeBlock->numParameters());
     529    RegisterID& parameter = registerFor(reg);
     530    parameter.setIndex(reg.offset());
    521531    m_codeBlock->addParameter();
    522 }
    523 
    524 bool BytecodeGenerator::willResolveToArgumentsRegister(const Identifier& ident)
    525 {
    526     if (ident != propertyNames().arguments)
    527         return false;
    528    
    529     if (!shouldOptimizeLocals())
    530         return false;
    531    
    532     SymbolTableEntry entry = symbolTable().get(ident.impl());
    533     if (entry.isNull())
    534         return false;
    535 
    536     if (m_localArgumentsRegister && isCaptured(m_localArgumentsRegister->index()) && m_lexicalEnvironmentRegister)
    537         return false;
    538 
    539     if (m_codeBlock->usesArguments() && m_codeType == FunctionCode && m_localArgumentsRegister)
    540         return true;
    541    
    542     return false;
    543 }
    544 
    545 RegisterID* BytecodeGenerator::uncheckedLocalArgumentsRegister()
    546 {
    547     ASSERT(willResolveToArgumentsRegister(propertyNames().arguments));
    548     ASSERT(m_localArgumentsRegister);
    549     return m_localArgumentsRegister;
    550 }
    551 
    552 RegisterID* BytecodeGenerator::createLazyRegisterIfNecessary(RegisterID* reg)
    553 {
    554     if (!reg->virtualRegister().isLocal())
    555         return reg;
    556 
    557     int localVariableNumber = reg->virtualRegister().toLocal();
    558 
    559     if (m_lastLazyFunction <= localVariableNumber || localVariableNumber < m_firstLazyFunction)
    560         return reg;
    561     emitLazyNewFunction(reg, m_lazyFunctions.get(localVariableNumber));
    562     return reg;
     532    return &parameter;
     533}
     534
     535StringImpl* BytecodeGenerator::visibleNameForParameter(DeconstructionPatternNode* pattern)
     536{
     537    if (pattern->isBindingNode()) {
     538        const Identifier& ident = static_cast<const BindingNode*>(pattern)->boundProperty();
     539        if (!m_functions.contains(ident.impl()))
     540            return ident.impl();
     541    }
     542    return nullptr;
    563543}
    564544
     
    965945    return m_identifierMap.contains(rep);
    966946}
    967    
     947
    968948unsigned BytecodeGenerator::addConstant(const Identifier& ident)
    969949{
     
    1016996{
    1017997    m_staticPropertyAnalyzer.mov(dst->index(), src->index());
    1018     ASSERT(dst->virtualRegister() == m_codeBlock->argumentsRegister() || !isCaptured(dst->index()));
    1019998    emitOpcode(op_mov);
    1020999    instructions().append(dst->index());
     
    11981177}
    11991178
    1200 bool BytecodeGenerator::isCaptured(int operand)
    1201 {
    1202     return m_symbolTable && m_symbolTable->isCaptured(operand);
    1203 }
    1204 
    1205 Local BytecodeGenerator::local(const Identifier& property)
    1206 {
    1207     if (property == propertyNames().thisIdentifier)
    1208         return Local(thisRegister(), ReadOnly, Local::SpecialLocal);
    1209     bool isArguments = property == propertyNames().arguments;
    1210     if (isArguments)
    1211         createArgumentsIfNecessary();
    1212 
     1179Variable BytecodeGenerator::variable(const Identifier& property)
     1180{
     1181    if (property == propertyNames().thisIdentifier) {
     1182        return Variable(
     1183            property, VarOffset(thisRegister()->virtualRegister()), thisRegister(),
     1184            ReadOnly, Variable::SpecialVariable);
     1185    }
     1186   
    12131187    if (!shouldOptimizeLocals())
    1214         return Local();
    1215 
     1188        return Variable(property);
     1189   
    12161190    SymbolTableEntry entry = symbolTable().get(property.impl());
    12171191    if (entry.isNull())
    1218         return Local();
    1219 
    1220 
    1221     RegisterID* local = createLazyRegisterIfNecessary(&registerFor(entry.getIndex()));
    1222 
    1223     if (isCaptured(local->index()) && m_lexicalEnvironmentRegister)
    1224         return Local();
    1225 
    1226     return Local(local, entry.getAttributes(), isArguments ? Local::SpecialLocal : Local::NormalLocal);
    1227 }
    1228 
    1229 Local BytecodeGenerator::constLocal(const Identifier& property)
    1230 {
    1231     if (m_codeType != FunctionCode)
    1232         return Local();
    1233 
     1192        return Variable(property);
     1193   
     1194    if (entry.varOffset().isScope() && m_localScopeDepth) {
     1195        // FIXME: We should be able to statically resolve through our local scopes.
     1196        // https://bugs.webkit.org/show_bug.cgi?id=141885
     1197        return Variable(property);
     1198    }
     1199   
     1200    return variableForLocalEntry(property, entry);
     1201}
     1202
     1203Variable BytecodeGenerator::variablePerSymbolTable(const Identifier& property)
     1204{
    12341205    SymbolTableEntry entry = symbolTable().get(property.impl());
    12351206    if (entry.isNull())
    1236         return Local();
    1237 
    1238     RegisterID* local = createLazyRegisterIfNecessary(&registerFor(entry.getIndex()));
    1239 
    1240     bool isArguments = property == propertyNames().arguments;
    1241     if (isCaptured(local->index()) && m_lexicalEnvironmentRegister)
    1242         return Local();
    1243 
    1244     return Local(local, entry.getAttributes(), isArguments ? Local::SpecialLocal : Local::NormalLocal);
     1207        return Variable(property);
     1208   
     1209    return variableForLocalEntry(property, entry);
     1210}
     1211
     1212Variable BytecodeGenerator::variableForLocalEntry(
     1213    const Identifier& property, const SymbolTableEntry& entry)
     1214{
     1215    VarOffset offset = entry.varOffset();
     1216   
     1217    RegisterID* local;
     1218    if (offset.isStack())
     1219        local = &registerFor(offset.stackOffset());
     1220    else
     1221        local = nullptr;
     1222   
     1223    return Variable(property, offset, local, entry.getAttributes(), Variable::NormalVariable);
     1224}
     1225
     1226void BytecodeGenerator::createVariable(
     1227    const Identifier& property, VarKind varKind, ConstantMode constantMode,
     1228    ExistingVariableMode existingVariableMode)
     1229{
     1230    ASSERT(property != propertyNames().thisIdentifier);
     1231   
     1232    ConcurrentJITLocker locker(symbolTable().m_lock);
     1233    SymbolTableEntry entry = symbolTable().get(locker, property.impl());
     1234   
     1235    if (!entry.isNull()) {
     1236        if (existingVariableMode == IgnoreExisting)
     1237            return;
     1238       
     1239        // Do some checks to ensure that the variable we're being asked to create is sufficiently
     1240        // compatible with the one we have already created.
     1241
     1242        VarOffset offset = entry.varOffset();
     1243       
     1244        // We can't change our minds about whether it's captured.
     1245        if (offset.kind() != varKind || constantMode != entry.constantMode()) {
     1246            dataLog(
     1247                "Trying to add variable called ", property, " as ", varKind, "/", constantMode,
     1248                " but it was already added as ", offset, "/", entry.constantMode(), ".\n");
     1249            RELEASE_ASSERT_NOT_REACHED();
     1250        }
     1251
     1252        return;
     1253    }
     1254   
     1255    VarOffset varOffset;
     1256    if (varKind == VarKind::Scope)
     1257        varOffset = VarOffset(symbolTable().takeNextScopeOffset(locker));
     1258    else {
     1259        ASSERT(varKind == VarKind::Stack);
     1260        varOffset = VarOffset(virtualRegisterForLocal(m_calleeRegisters.size()));
     1261    }
     1262    SymbolTableEntry newEntry(varOffset, constantMode == IsConstant ? ReadOnly : 0);
     1263    symbolTable().add(locker, property.impl(), newEntry);
     1264   
     1265    if (varKind == VarKind::Stack) {
     1266        RegisterID* local = addVar();
     1267        RELEASE_ASSERT(local->index() == varOffset.stackOffset().offset());
     1268    }
    12451269}
    12461270
     
    12661290}
    12671291
    1268 RegisterID* BytecodeGenerator::emitResolveScope(RegisterID* dst, const Identifier& identifier, ResolveScopeInfo& info)
    1269 {
    1270     if (m_symbolTable && m_codeType == FunctionCode && !m_localScopeDepth) {
    1271         SymbolTableEntry entry = m_symbolTable->get(identifier.impl());
    1272         if (!entry.isNull()) {
    1273             info = ResolveScopeInfo(entry.getIndex());
    1274             return scopeRegister();
    1275         }
    1276     }
    1277 
    1278     ASSERT(!m_symbolTable || !m_symbolTable->contains(identifier.impl()) || resolveType() == Dynamic);
    1279 
    1280     m_codeBlock->addPropertyAccessInstruction(instructions().size());
    1281 
    1282     // resolve_scope dst, id, ResolveType, depth
    1283     emitOpcode(op_resolve_scope);
    1284     dst = tempDestination(dst);
    1285     instructions().append(kill(dst));
    1286     instructions().append(scopeRegister()->index());
    1287     instructions().append(addConstant(identifier));
    1288     instructions().append(resolveType());
    1289     instructions().append(0);
    1290     instructions().append(0);
    1291     return dst;
    1292 }
    1293 
    1294 
    1295 RegisterID* BytecodeGenerator::emitResolveConstantLocal(RegisterID* dst, const Identifier& identifier, ResolveScopeInfo& info)
    1296 {
    1297     if (!m_symbolTable || m_codeType != FunctionCode)
     1292RegisterID* BytecodeGenerator::emitResolveScope(RegisterID* dst, const Variable& variable)
     1293{
     1294    switch (variable.offset().kind()) {
     1295    case VarKind::Stack:
    12981296        return nullptr;
    1299 
    1300     SymbolTableEntry entry = m_symbolTable->get(identifier.impl());
    1301     if (entry.isNull())
    1302         return nullptr;
    1303     info = ResolveScopeInfo(entry.getIndex());
    1304     return emitMove(dst, m_lexicalEnvironmentRegister);
    1305 
    1306 }
    1307 
    1308 RegisterID* BytecodeGenerator::emitGetFromScope(RegisterID* dst, RegisterID* scope, const Identifier& identifier, ResolveMode resolveMode, const ResolveScopeInfo& info)
    1309 {
    1310     m_codeBlock->addPropertyAccessInstruction(instructions().size());
    1311 
    1312     // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
    1313     UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_scope);
    1314     instructions().append(kill(dst));
    1315     instructions().append(scope->index());
    1316     instructions().append(addConstant(identifier));
    1317     instructions().append(ResolveModeAndType(resolveMode, info.isLocal() ? LocalClosureVar : resolveType()).operand());
    1318     instructions().append(0);
    1319     instructions().append(info.localIndex());
    1320     instructions().append(profile);
    1321     return dst;
    1322 }
    1323 
    1324 RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Identifier& identifier, RegisterID* value, ResolveMode resolveMode, const ResolveScopeInfo& info)
    1325 {
    1326     m_codeBlock->addPropertyAccessInstruction(instructions().size());
    1327 
    1328     // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
    1329     emitOpcode(op_put_to_scope);
    1330     instructions().append(scope->index());
    1331     instructions().append(addConstant(identifier));
    1332     instructions().append(value->index());
    1333     if (info.isLocal()) {
    1334         instructions().append(ResolveModeAndType(resolveMode, LocalClosureVar).operand());
    1335         int operand = registerFor(info.localIndex()).index();
    1336         bool isWatchableVariable = hasWatchableVariable(operand);
    1337         ASSERT(!isWatchableVariable || watchableVariableIdentifier(operand) == identifier);
    1338         instructions().append(isWatchableVariable);
    1339     } else {
    1340         ASSERT(resolveType() != LocalClosureVar);
    1341         instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
    1342         instructions().append(false);
    1343     }
    1344     instructions().append(info.localIndex());
    1345     return value;
     1297       
     1298    case VarKind::DirectArgument:
     1299        return argumentsRegister();
     1300       
     1301    case VarKind::Scope:
     1302        // This always refers to the activation that *we* allocated, and not the current scope that code
     1303        // lives in. Note that this will change once we have proper support for block scoping. Once that
     1304        // changes, it will be correct for this code to return scopeRegister(). The only reason why we
     1305        // don't do that already is that m_lexicalEnvironment is required by ConstDeclNode. ConstDeclNode
     1306        // requires weird things because it is a shameful pile of nonsense, but block scoping would make
     1307        // that code sensible and obviate the need for us to do bad things.
     1308        return m_lexicalEnvironmentRegister;
     1309       
     1310    case VarKind::Invalid:
     1311        // Indicates non-local resolution.
     1312       
     1313        ASSERT(!m_symbolTable || !m_symbolTable->contains(variable.ident().impl()) || resolveType() == Dynamic);
     1314       
     1315        m_codeBlock->addPropertyAccessInstruction(instructions().size());
     1316       
     1317        // resolve_scope dst, id, ResolveType, depth
     1318        emitOpcode(op_resolve_scope);
     1319        dst = tempDestination(dst);
     1320        instructions().append(kill(dst));
     1321        instructions().append(scopeRegister()->index());
     1322        instructions().append(addConstant(variable.ident()));
     1323        instructions().append(resolveType());
     1324        instructions().append(0);
     1325        instructions().append(0);
     1326        return dst;
     1327    }
     1328   
     1329    RELEASE_ASSERT_NOT_REACHED();
     1330    return nullptr;
     1331}
     1332
     1333RegisterID* BytecodeGenerator::emitGetFromScope(RegisterID* dst, RegisterID* scope, const Variable& variable, ResolveMode resolveMode)
     1334{
     1335    switch (variable.offset().kind()) {
     1336    case VarKind::Stack:
     1337        return emitMove(dst, variable.local());
     1338       
     1339    case VarKind::DirectArgument: {
     1340        UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_arguments);
     1341        instructions().append(kill(dst));
     1342        instructions().append(scope->index());
     1343        instructions().append(variable.offset().capturedArgumentsOffset().offset());
     1344        instructions().append(profile);
     1345        return dst;
     1346    }
     1347       
     1348    case VarKind::Scope:
     1349    case VarKind::Invalid: {
     1350        m_codeBlock->addPropertyAccessInstruction(instructions().size());
     1351       
     1352        // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
     1353        UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_scope);
     1354        instructions().append(kill(dst));
     1355        instructions().append(scope->index());
     1356        instructions().append(addConstant(variable.ident()));
     1357        instructions().append(ResolveModeAndType(resolveMode, variable.offset().isScope() ? LocalClosureVar : resolveType()).operand());
     1358        instructions().append(0);
     1359        instructions().append(variable.offset().isScope() ? variable.offset().scopeOffset().offset() : 0);
     1360        instructions().append(profile);
     1361        return dst;
     1362    } }
     1363   
     1364    RELEASE_ASSERT_NOT_REACHED();
     1365}
     1366
     1367RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Variable& variable, RegisterID* value, ResolveMode resolveMode)
     1368{
     1369    switch (variable.offset().kind()) {
     1370    case VarKind::Stack:
     1371        emitMove(variable.local(), value);
     1372        return value;
     1373       
     1374    case VarKind::DirectArgument:
     1375        emitOpcode(op_put_to_arguments);
     1376        instructions().append(scope->index());
     1377        instructions().append(variable.offset().capturedArgumentsOffset().offset());
     1378        instructions().append(value->index());
     1379        return value;
     1380       
     1381    case VarKind::Scope:
     1382    case VarKind::Invalid: {
     1383        m_codeBlock->addPropertyAccessInstruction(instructions().size());
     1384       
     1385        // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
     1386        emitOpcode(op_put_to_scope);
     1387        instructions().append(scope->index());
     1388        instructions().append(addConstant(variable.ident()));
     1389        instructions().append(value->index());
     1390        ScopeOffset offset;
     1391        if (variable.offset().isScope()) {
     1392            offset = variable.offset().scopeOffset();
     1393            instructions().append(ResolveModeAndType(resolveMode, LocalClosureVar).operand());
     1394        } else {
     1395            ASSERT(resolveType() != LocalClosureVar);
     1396            instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
     1397        }
     1398        instructions().append(0);
     1399        instructions().append(!!offset ? offset.offset() : 0);
     1400        return value;
     1401    } }
     1402   
     1403    RELEASE_ASSERT_NOT_REACHED();
     1404}
     1405
     1406RegisterID* BytecodeGenerator::initializeVariable(const Variable& variable, RegisterID* value)
     1407{
     1408    RegisterID* scope;
     1409    switch (variable.offset().kind()) {
     1410    case VarKind::Stack:
     1411        scope = nullptr;
     1412        break;
     1413       
     1414    case VarKind::DirectArgument:
     1415        scope = argumentsRegister();
     1416        break;
     1417       
     1418    case VarKind::Scope:
     1419        scope = scopeRegister();
     1420        break;
     1421       
     1422    default:
     1423        RELEASE_ASSERT_NOT_REACHED();
     1424        scope = nullptr;
     1425        break;
     1426    }
     1427
     1428    return emitPutToScope(scope, variable, value, ThrowIfNotFound);
    13461429}
    13471430
    13481431RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype)
    1349 { 
     1432{
    13501433    emitOpcode(op_instanceof);
    13511434    instructions().append(dst->index());
     
    13791462    instructions().append(0);
    13801463    instructions().append(profile);
    1381     return dst;
    1382 }
    1383 
    1384 RegisterID* BytecodeGenerator::emitGetArgumentsLength(RegisterID* dst, RegisterID* base)
    1385 {
    1386     emitOpcode(op_get_arguments_length);
    1387     instructions().append(dst->index());
    1388     ASSERT(base->virtualRegister() == m_codeBlock->argumentsRegister());
    1389     instructions().append(base->index());
    1390     instructions().append(addConstant(propertyNames().length));
    13911464    return dst;
    13921465}
     
    14521525    instructions().append(base->index());
    14531526    instructions().append(addConstant(property));
    1454     return dst;
    1455 }
    1456 
    1457 RegisterID* BytecodeGenerator::emitGetArgumentByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
    1458 {
    1459     UnlinkedArrayProfile arrayProfile = newArrayProfile();
    1460     UnlinkedValueProfile profile = emitProfiledOpcode(op_get_argument_by_val);
    1461     instructions().append(kill(dst));
    1462     ASSERT(base->virtualRegister() == m_codeBlock->argumentsRegister());
    1463     instructions().append(base->index());
    1464     instructions().append(property->index());
    1465     instructions().append(m_codeBlock->activationRegister().offset());
    1466     instructions().append(arrayProfile);
    1467     instructions().append(profile);
    14681527    return dst;
    14691528}
     
    16531712RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode* function)
    16541713{
    1655     return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl(makeFunction(function)), false);
    1656 }
    1657 
    1658 RegisterID* BytecodeGenerator::emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* function)
    1659 {
    1660     FunctionOffsetMap::AddResult ptr = m_functionOffsets.add(function, 0);
    1661     if (ptr.isNewEntry)
    1662         ptr.iterator->value = m_codeBlock->addFunctionDecl(makeFunction(function));
    1663     return emitNewFunctionInternal(dst, ptr.iterator->value, true);
    1664 }
    1665 
    1666 RegisterID* BytecodeGenerator::emitNewFunctionInternal(RegisterID* dst, unsigned index, bool doNullCheck)
     1714    return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl(makeFunction(function)));
     1715}
     1716
     1717RegisterID* BytecodeGenerator::emitNewFunctionInternal(RegisterID* dst, unsigned index)
    16671718{
    16681719    emitOpcode(op_new_func);
     
    16701721    instructions().append(scopeRegister()->index());
    16711722    instructions().append(index);
    1672     instructions().append(doNullCheck);
    16731723    return dst;
    16741724}
     
    17101760{
    17111761    return emitCall(op_call, dst, func, expectedFunction, callArguments, divot, divotStart, divotEnd);
    1712 }
    1713 
    1714 void BytecodeGenerator::createArgumentsIfNecessary()
    1715 {
    1716     if (m_codeType != FunctionCode)
    1717         return;
    1718    
    1719     if (!m_codeBlock->usesArguments())
    1720         return;
    1721 
    1722     if (shouldTearOffArgumentsEagerly() || shouldCreateArgumentsEagerly())
    1723         return;
    1724 
    1725     emitOpcode(op_create_arguments);
    1726     instructions().append(m_codeBlock->argumentsRegister().offset());
    1727     ASSERT(!hasWatchableVariable(m_codeBlock->argumentsRegister().offset()));
    1728     instructions().append(m_codeBlock->activationRegister().offset());
    17291762}
    17301763
     
    18251858            auto expression = static_cast<SpreadExpressionNode*>(n->m_expr)->expression();
    18261859            RefPtr<RegisterID> argumentRegister;
    1827             if (expression->isResolveNode() && willResolveToArgumentsRegister(static_cast<ResolveNode*>(expression)->identifier()) && !symbolTable().slowArguments())
    1828                 argumentRegister = uncheckedLocalArgumentsRegister();
    1829             else
    1830                 argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
     1860            argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
    18311861            RefPtr<RegisterID> thisRegister = emitMove(newTemporary(), callArguments.thisRegister());
    18321862            return emitCallVarargs(dst, func, callArguments.thisRegister(), argumentRegister.get(), newTemporary(), 0, callArguments.profileHookRegister(), divot, divotStart, divotEnd);
     
    19171947RegisterID* BytecodeGenerator::emitReturn(RegisterID* src)
    19181948{
    1919     if (m_codeBlock->usesArguments() && m_codeBlock->numParameters() != 1 && !isStrictMode()) {
    1920         RefPtr<RegisterID> scratchRegister;
    1921         int argumentsIndex = unmodifiedArgumentsRegister(m_codeBlock->argumentsRegister()).offset();
    1922         if (m_lexicalEnvironmentRegister && m_codeType == FunctionCode) {
    1923             scratchRegister = newTemporary();
    1924             ResolveScopeInfo scopeInfo(unmodifiedArgumentsRegister(m_codeBlock->argumentsRegister()).offset());
    1925             emitGetFromScope(scratchRegister.get(), scopeRegister(), propertyNames().arguments, ThrowIfNotFound, scopeInfo);
    1926             argumentsIndex = scratchRegister->index();
    1927         }
    1928         emitOpcode(op_tear_off_arguments);
    1929         instructions().append(argumentsIndex);
    1930         instructions().append(m_lexicalEnvironmentRegister ? m_lexicalEnvironmentRegister->index() : emitLoad(0, JSValue())->index());
    1931     }
    1932 
    19331949    if (isConstructor()) {
    19341950        bool derived = constructorKind() == ConstructorKind::Derived;
     
    19791995            auto expression = static_cast<SpreadExpressionNode*>(n->m_expr)->expression();
    19801996            RefPtr<RegisterID> argumentRegister;
    1981             if (expression->isResolveNode() && willResolveToArgumentsRegister(static_cast<ResolveNode*>(expression)->identifier()) && !symbolTable().slowArguments())
    1982                 argumentRegister = uncheckedLocalArgumentsRegister();
    1983             else
    1984                 argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
     1997            argumentRegister = expression->emitBytecode(*this, callArguments.argumentRegister(0));
    19851998            return emitConstructVarargs(dst, func, callArguments.thisRegister(), argumentRegister.get(), newTemporary(), 0, callArguments.profileHookRegister(), divot, divotStart, divotEnd);
    19861999        }
     
    25442557bool BytecodeGenerator::isArgumentNumber(const Identifier& ident, int argumentNumber)
    25452558{
    2546     RegisterID* registerID = local(ident).get();
    2547     if (!registerID || registerID->index() >= 0)
    2548          return 0;
     2559    RegisterID* registerID = variable(ident).local();
     2560    if (!registerID)
     2561        return false;
    25492562    return registerID->index() == CallFrame::argumentOffset(argumentNumber);
    25502563}
     
    25612574void BytecodeGenerator::emitEnumeration(ThrowableExpressionData* node, ExpressionNode* subjectNode, const std::function<void(BytecodeGenerator&, RegisterID*)>& callBack)
    25622575{
    2563     if (subjectNode->isResolveNode()
    2564         && willResolveToArgumentsRegister(static_cast<ResolveNode*>(subjectNode)->identifier())
    2565         && !symbolTable().slowArguments()) {
    2566         RefPtr<RegisterID> index = emitLoad(newTemporary(), jsNumber(0));
    2567 
    2568         LabelScopePtr scope = newLabelScope(LabelScope::Loop);
    2569         RefPtr<RegisterID> value = emitLoad(newTemporary(), jsUndefined());
    2570        
    2571         RefPtr<Label> loopCondition = newLabel();
    2572         RefPtr<Label> loopStart = newLabel();
    2573         emitJump(loopCondition.get());
    2574         emitLabel(loopStart.get());
    2575         emitLoopHint();
    2576         emitGetArgumentByVal(value.get(), uncheckedLocalArgumentsRegister(), index.get());
    2577         callBack(*this, value.get());
    2578    
    2579         emitLabel(scope->continueTarget());
    2580         emitInc(index.get());
    2581         emitLabel(loopCondition.get());
    2582         RefPtr<RegisterID> length = emitGetArgumentsLength(newTemporary(), uncheckedLocalArgumentsRegister());
    2583         emitJumpIfTrue(emitEqualityOp(op_less, newTemporary(), index.get(), length.get()), loopStart.get());
    2584         emitLabel(scope->breakTarget());
    2585         return;
    2586     }
    2587 
    25882576    LabelScopePtr scope = newLabelScope(LabelScope::Loop);
    25892577    RefPtr<RegisterID> subject = newTemporary();
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r181891 r181993  
    11/*
    2  * Copyright (C) 2008, 2009, 2012, 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2009, 2012-2015 Apple Inc. All rights reserved.
    33 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
    44 * Copyright (C) 2012 Igalia, S.L.
     
    179179    };
    180180
    181     enum CaptureMode {
    182         NotCaptured,
    183         IsCaptured
    184     };
    185 
    186     class Local {
     181    class Variable {
    187182    public:
    188         Local()
    189             : m_local(0)
     183        enum VariableKind { NormalVariable, SpecialVariable };
     184
     185        Variable()
     186            : m_offset()
     187            , m_local(nullptr)
    190188            , m_attributes(0)
    191             , m_kind(NormalLocal)
    192         {
    193         }
    194 
    195         enum LocalKind { NormalLocal, SpecialLocal };
    196 
    197         Local(RegisterID* local, unsigned attributes, LocalKind kind)
    198             : m_local(local)
     189            , m_kind(NormalVariable)
     190        {
     191        }
     192       
     193        Variable(const Identifier& ident)
     194            : m_ident(ident)
     195            , m_local(nullptr)
     196            , m_attributes(0)
     197            , m_kind(NormalVariable) // This is somewhat meaningless here for this kind of Variable.
     198        {
     199        }
     200
     201        Variable(const Identifier& ident, VarOffset offset, RegisterID* local, unsigned attributes, VariableKind kind)
     202            : m_ident(ident)
     203            , m_offset(offset)
     204            , m_local(local)
    199205            , m_attributes(attributes)
    200206            , m_kind(kind)
     
    202208        }
    203209
    204         operator bool() const { return m_local; }
    205 
    206         RegisterID* get() const { return m_local; }
     210        // If it's unset, then it is a non-locally-scoped variable. If it is set, then it could be
     211        // a stack variable, a scoped variable in the local scope, or a variable captured in the
     212        // direct arguments object.
     213        bool isResolved() const { return !!m_offset; }
     214       
     215        const Identifier& ident() const { return m_ident; }
     216       
     217        VarOffset offset() const { return m_offset; }
     218        bool isLocal() const { return m_offset.isStack(); }
     219        RegisterID* local() const { return m_local; }
    207220
    208221        bool isReadOnly() const { return m_attributes & ReadOnly; }
    209         bool isSpecial() const { return m_kind != NormalLocal; }
     222        bool isSpecial() const { return m_kind != NormalVariable; }
    210223
    211224    private:
     225        Identifier m_ident;
     226        VarOffset m_offset;
    212227        RegisterID* m_local;
    213228        unsigned m_attributes;
    214         LocalKind m_kind;
    215     };
    216 
    217     struct ResolveScopeInfo {
    218         ResolveScopeInfo()
    219             : m_localIndex(0)
    220             , m_resolveScopeKind(NonLocalScope)
    221         {
    222         }
    223 
    224         ResolveScopeInfo(int index)
    225             : m_localIndex(index)
    226             , m_resolveScopeKind(LocalScope)
    227         {
    228         }
    229 
    230         bool isLocal() const { return m_resolveScopeKind == LocalScope; }
    231         int localIndex() const { return m_localIndex; }
    232 
    233     private:
    234         int m_localIndex;
    235         enum { LocalScope, NonLocalScope } m_resolveScopeKind;
     229        VariableKind m_kind;
    236230    };
    237231
     
    283277        void setIsNumericCompareFunction(bool isNumericCompareFunction);
    284278
    285         bool willResolveToArgumentsRegister(const Identifier&);
    286 
    287         bool hasSafeLocalArgumentsRegister() { return m_localArgumentsRegister; }
    288         RegisterID* uncheckedLocalArgumentsRegister();
    289 
    290         bool isCaptured(int operand);
    291         CaptureMode captureMode(int operand) { return isCaptured(operand) ? IsCaptured : NotCaptured; }
    292        
    293         Local local(const Identifier&);
    294         Local constLocal(const Identifier&);
    295 
     279        Variable variable(const Identifier&);
     280       
     281        // Ignores the possibility of intervening scopes.
     282        Variable variablePerSymbolTable(const Identifier&);
     283       
     284        enum ExistingVariableMode { VerifyExisting, IgnoreExisting };
     285        void createVariable(const Identifier&, VarKind, ConstantMode, ExistingVariableMode = VerifyExisting); // Creates the variable, or asserts that the already-created variable is sufficiently compatible.
     286       
    296287        // Returns the register storing "this"
    297288        RegisterID* thisRegister() { return &m_thisRegister; }
     289        RegisterID* argumentsRegister() { return m_argumentsRegister; }
    298290        RegisterID* newTarget() { return m_newTargetRegister; }
    299291
     
    354346            // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
    355347            ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
    356             // Should never store directly into a captured variable.
    357             ASSERT(!dst || dst == ignoredResult() || !isCaptured(dst->index()));
    358348            if (!m_vm->isSafeToRecurse()) {
    359349                emitThrowExpressionTooDeepException();
     
    372362            // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
    373363            ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
    374             // Should never store directly into a captured variable.
    375             ASSERT(!dst || dst == ignoredResult() || !isCaptured(dst->index()));
    376364            if (!m_vm->isSafeToRecurse())
    377365                return emitThrowExpressionTooDeepException();
     
    464452
    465453        RegisterID* emitNewFunction(RegisterID* dst, FunctionBodyNode*);
    466         RegisterID* emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* body);
    467         RegisterID* emitNewFunctionInternal(RegisterID* dst, unsigned index, bool shouldNullCheck);
     454        RegisterID* emitNewFunctionInternal(RegisterID* dst, unsigned index);
    468455        RegisterID* emitNewFunctionExpression(RegisterID* dst, FuncExprNode* func);
    469456        RegisterID* emitNewDefaultConstructor(RegisterID* dst, ConstructorKind, const Identifier& name);
     
    484471
    485472        RegisterID* emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property);
    486         RegisterID* emitGetArgumentsLength(RegisterID* dst, RegisterID* base);
    487473        RegisterID* emitPutById(RegisterID* base, const Identifier& property, RegisterID* value);
    488474        RegisterID* emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value, PropertyNode::PutType);
     
    511497
    512498        ResolveType resolveType();
    513         RegisterID* emitResolveConstantLocal(RegisterID* dst, const Identifier&, ResolveScopeInfo&);
    514         // Calls tempDestination(dst), so it's safe to pass nullptr. It's also redundant to call
    515         // tempDestination(dst) on the thing you pass as the destination. The reason why this
    516         // calls tempDestination() for you is that it may not need a spare register. It may return
    517         // scopeRegister() directly. So, you cannot rely on this storing to dst.
    518         RegisterID* emitResolveScope(RegisterID* dst, const Identifier&, ResolveScopeInfo&);
    519         RegisterID* emitGetFromScope(RegisterID* dst, RegisterID* scope, const Identifier&, ResolveMode, const ResolveScopeInfo&);
    520         RegisterID* emitPutToScope(RegisterID* scope, const Identifier&, RegisterID* value, ResolveMode, const ResolveScopeInfo&);
     499        RegisterID* emitResolveConstantLocal(RegisterID* dst, const Variable&);
     500        RegisterID* emitResolveScope(RegisterID* dst, const Variable&);
     501        RegisterID* emitGetFromScope(RegisterID* dst, RegisterID* scope, const Variable&, ResolveMode);
     502        RegisterID* emitPutToScope(RegisterID* scope, const Variable&, RegisterID* value, ResolveMode);
     503        RegisterID* initializeVariable(const Variable&, RegisterID* value);
    521504
    522505        PassRefPtr<Label> emitLabel(Label*);
     
    598581
    599582    private:
     583        Variable variableForLocalEntry(const Identifier&, const SymbolTableEntry&);
     584
    600585        void emitOpcode(OpcodeID);
    601586        UnlinkedArrayAllocationProfile newArrayAllocationProfile();
     
    630615        RegisterID* newRegister();
    631616
    632         // Adds a var slot and maps it to the name ident in symbolTable().
    633         enum WatchMode { IsWatchable, NotWatchable };
    634         RegisterID* addVar(const Identifier&, ConstantMode, WatchMode);
    635 
    636         // Adds an anonymous var slot. To give this slot a name, add it to symbolTable().
     617        // Adds an anonymous local var slot. To give this slot a name, add it to symbolTable().
    637618        RegisterID* addVar()
    638619        {
     
    644625        }
    645626
    646         // Returns the index of the added var.
    647         void addParameter(const Identifier&, int parameterIndex);
    648         RegisterID* resolveCallee(FunctionNode*);
    649         void addCallee(FunctionNode*, RegisterID*);
    650 
    651         void preserveLastVar();
    652 
    653         RegisterID& registerFor(int index)
    654         {
    655             if (operandIsLocal(index))
    656                 return m_calleeRegisters[VirtualRegister(index).toLocal()];
    657 
    658             if (index == JSStack::Callee)
     627        // Initializes the stack form the parameter; does nothing for the symbol table.
     628        RegisterID* initializeNextParameter();
     629        StringImpl* visibleNameForParameter(DeconstructionPatternNode*);
     630       
     631        RegisterID& registerFor(VirtualRegister reg)
     632        {
     633            if (reg.isLocal())
     634                return m_calleeRegisters[reg.toLocal()];
     635
     636            if (reg.offset() == JSStack::Callee)
    659637                return m_calleeRegister;
    660638
    661639            ASSERT(m_parameters.size());
    662             return m_parameters[VirtualRegister(index).toArgument()];
     640            return m_parameters[reg.toArgument()];
    663641        }
    664642
     
    676654        }
    677655
    678         RegisterID* emitInitLazyRegister(RegisterID*);
    679        
    680656        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);
    681657        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);
    682         RegisterID* initializeCapturedVariable(RegisterID* dst, const Identifier&, RegisterID*);
    683658
    684659    public:
     
    714689        }
    715690
    716         bool shouldTearOffArgumentsEagerly()
    717         {
    718             return m_codeType == FunctionCode && isStrictMode() && m_scopeNode->modifiesParameter();
    719         }
    720 
    721         bool shouldCreateArgumentsEagerly()
    722         {
    723             if (m_codeType != FunctionCode)
    724                 return false;
    725             return m_lexicalEnvironmentRegister && m_codeBlock->usesArguments();
    726         }
    727 
    728691        RegisterID* emitThrowExpressionTooDeepException();
    729 
    730         void createArgumentsIfNecessary();
    731         RegisterID* createLazyRegisterIfNecessary(RegisterID*);
    732        
    733         bool hasWatchableVariable(int operand) const
    734         {
    735             VirtualRegister reg(operand);
    736             if (!reg.isLocal())
    737                 return false;
    738             if (static_cast<size_t>(reg.toLocal()) >= m_watchableVariables.size())
    739                 return false;
    740             const Identifier& ident = m_watchableVariables[reg.toLocal()];
    741             if (ident.isNull())
    742                 return false;
    743             ASSERT(hasConstant(ident)); // Should have already been added.
    744             return true;
    745         }
    746        
    747         const Identifier& watchableVariableIdentifier(int operand) const
    748         {
    749             ASSERT(hasWatchableVariable(operand));
    750             VirtualRegister reg(operand);
    751             return m_watchableVariables[reg.toLocal()];
    752         }
    753692
    754693    private:
     
    770709        RegisterID m_calleeRegister;
    771710        RegisterID* m_scopeRegister { nullptr };
     711        RegisterID* m_argumentsRegister { nullptr };
    772712        RegisterID* m_lexicalEnvironmentRegister { nullptr };
    773713        RegisterID* m_emptyValueRegister { nullptr };
    774714        RegisterID* m_globalObjectRegister { nullptr };
    775         RegisterID* m_localArgumentsRegister { nullptr };
    776715        RegisterID* m_newTargetRegister { nullptr };
    777716
    778         Vector<Identifier, 16> m_watchableVariables;
    779717        SegmentedVector<RegisterID, 32> m_constantPoolRegisters;
    780718        SegmentedVector<RegisterID, 32> m_calleeRegisters;
     
    791729        Vector<TryContext> m_tryContextStack;
    792730        Vector<std::pair<RefPtr<RegisterID>, const DeconstructionPatternNode*>> m_deconstructedParameters;
     731        Vector<FunctionBodyNode*> m_functionsToInitialize;
     732        bool m_needToInitializeArguments { false };
    793733       
    794734        Vector<TryRange> m_tryRanges;
     
    797737        int m_nextConstantOffset { 0 };
    798738
    799         int m_firstLazyFunction { 0 };
    800         int m_lastLazyFunction { 0 };
    801         HashMap<unsigned int, FunctionBodyNode*, WTF::IntHash<unsigned int>, WTF::UnsignedWithZeroKeyHashTraits<unsigned int>> m_lazyFunctions;
    802739        typedef HashMap<FunctionBodyNode*, unsigned> FunctionOffsetMap;
    803740        FunctionOffsetMap m_functionOffsets;
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r181891 r181993  
    22*  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
    33*  Copyright (C) 2001 Peter Kelly (pmk@post.com)
    4 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
     4*  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012, 2013, 2015 Apple Inc. All rights reserved.
    55*  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
    66*  Copyright (C) 2007 Maks Orlovich
     
    188188bool ResolveNode::isPure(BytecodeGenerator& generator) const
    189189{
    190     return generator.local(m_ident).get();
     190    return generator.variable(m_ident).offset().isStack();
    191191}
    192192
    193193RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    194194{
    195     if (Local local = generator.local(m_ident)) {
     195    Variable var = generator.variable(m_ident);
     196    if (RegisterID* local = var.local()) {
    196197        if (dst == generator.ignoredResult())
    197             return 0;
     198            return nullptr;
    198199        if (generator.vm()->typeProfiler()) {
    199             generator.emitProfileType(local.get(), ProfileTypeBytecodeHasGlobalID, nullptr);
     200            generator.emitProfileType(local, ProfileTypeBytecodeHasGlobalID, nullptr);
    200201            generator.emitTypeProfilerExpressionInfo(m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
    201202        }
    202         return generator.moveToDestinationIfNeeded(dst, local.get());
     203        return generator.moveToDestinationIfNeeded(dst, local);
    203204    }
    204205   
    205206    JSTextPosition divot = m_start + m_ident.length();
    206207    generator.emitExpressionInfo(divot, m_start, divot);
    207     ResolveScopeInfo resolveScopeInfo;
    208     RefPtr<RegisterID> scope = generator.emitResolveScope(dst, m_ident, resolveScopeInfo);
     208    RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
    209209    RegisterID* finalDest = generator.finalDestination(dst);
    210     RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), m_ident, ThrowIfNotFound, resolveScopeInfo);
     210    RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), var, ThrowIfNotFound);
    211211    if (generator.vm()->typeProfiler()) {
    212         generator.emitProfileType(finalDest, resolveScopeInfo.isLocal() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
     212        generator.emitProfileType(finalDest, var.isResolved() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
    213213        generator.emitTypeProfilerExpressionInfo(m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
    214214    }
     
    440440    }
    441441
    442     if (m_base->isResolveNode()
    443         && generator.willResolveToArgumentsRegister(static_cast<ResolveNode*>(m_base)->identifier())
    444         && !generator.symbolTable().slowArguments()) {
    445         RefPtr<RegisterID> property = generator.emitNode(m_subscript);
    446         generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    447         return generator.emitGetArgumentByVal(generator.finalDestination(dst), generator.uncheckedLocalArgumentsRegister(), property.get());
    448     }
    449 
    450442    RegisterID* ret;
    451443    RegisterID* finalDest = generator.finalDestination(dst);
     
    473465RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    474466{
    475     if (m_ident == generator.propertyNames().length) {
    476         if (!m_base->isResolveNode())
    477             goto nonArgumentsPath;
    478         ResolveNode* resolveNode = static_cast<ResolveNode*>(m_base);
    479         if (!generator.willResolveToArgumentsRegister(resolveNode->identifier()))
    480             goto nonArgumentsPath;
    481         generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    482         return generator.emitGetArgumentsLength(generator.finalDestination(dst), generator.uncheckedLocalArgumentsRegister());
    483     }
    484 
    485 nonArgumentsPath:
    486467    RefPtr<RegisterID> base = m_base->isSuperNode() ? emitSuperBaseForCallee(generator) : generator.emitNode(m_base);
    487468    generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
     
    548529RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    549530{
    550     if (Local local = generator.local(generator.propertyNames().eval)) {
    551         RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local.get());
     531    Variable var = generator.variable(generator.propertyNames().eval);
     532    if (RegisterID* local = var.local()) {
     533        RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
    552534        CallArguments callArguments(generator, m_args);
    553535        generator.emitLoad(callArguments.thisRegister(), jsUndefined());
     
    559541    JSTextPosition newDivot = divotStart() + 4;
    560542    generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
    561     ResolveScopeInfo resolveScopeInfo;
    562543    generator.moveToDestinationIfNeeded(
    563544        callArguments.thisRegister(),
    564         generator.emitResolveScope(callArguments.thisRegister(), generator.propertyNames().eval, resolveScopeInfo));
    565     generator.emitGetFromScope(func.get(), callArguments.thisRegister(), generator.propertyNames().eval, ThrowIfNotFound, resolveScopeInfo);
     545        generator.emitResolveScope(callArguments.thisRegister(), var));
     546    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
    566547    return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd());
    567548}
     
    597578    ExpectedFunction expectedFunction = generator.expectedFunctionForIdentifier(m_ident);
    598579
    599     if (Local local = generator.local(m_ident)) {
    600         RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local.get());
     580    Variable var = generator.variable(m_ident);
     581    if (RegisterID* local = var.local()) {
     582        RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
    601583        RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
    602584        CallArguments callArguments(generator, m_args);
     
    618600    JSTextPosition newDivot = divotStart() + m_ident.length();
    619601    generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
    620     ResolveScopeInfo resolveScopeInfo;
    621602    generator.moveToDestinationIfNeeded(
    622603        callArguments.thisRegister(),
    623         generator.emitResolveScope(callArguments.thisRegister(), m_ident, resolveScopeInfo));
    624     generator.emitGetFromScope(func.get(), callArguments.thisRegister(), m_ident, ThrowIfNotFound, resolveScopeInfo);
     604        generator.emitResolveScope(callArguments.thisRegister(), var));
     605    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
    625606    RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
    626607    if (generator.vm()->typeProfiler()) {
     
    676657}
    677658
    678 static RegisterID* getArgumentByVal(BytecodeGenerator& generator, ExpressionNode* base, RegisterID* property, RegisterID* dst, JSTextPosition divot, JSTextPosition divotStart, JSTextPosition divotEnd)
    679 {
    680     if (base->isResolveNode()
    681         && generator.willResolveToArgumentsRegister(static_cast<ResolveNode*>(base)->identifier())
    682         && !generator.symbolTable().slowArguments()) {
    683         generator.emitExpressionInfo(divot, divotStart, divotEnd);
    684         return generator.emitGetArgumentByVal(generator.finalDestination(dst), generator.uncheckedLocalArgumentsRegister(), property);
    685     }
    686     return nullptr;
    687 }
    688 
    689659RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    690660{
     
    707677            SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(m_args->m_listNode->m_expr);
    708678            ExpressionNode* subject = spread->expression();
    709             RefPtr<RegisterID> thisRegister = getArgumentByVal(generator, subject, generator.emitLoad(0, jsNumber(0)), 0, spread->divot(), spread->divotStart(), spread->divotEnd());
    710679            RefPtr<RegisterID> argumentsRegister;
    711             if (thisRegister)
    712                 argumentsRegister = generator.uncheckedLocalArgumentsRegister();
    713             else {
    714                 argumentsRegister = generator.emitNode(subject);
    715                 generator.emitExpressionInfo(spread->divot(), spread->divotStart(), spread->divotEnd());
    716                 thisRegister = generator.emitGetByVal(generator.newTemporary(), argumentsRegister.get(), generator.emitLoad(0, jsNumber(0)));
    717             }
     680            argumentsRegister = generator.emitNode(subject);
     681            generator.emitExpressionInfo(spread->divot(), spread->divotStart(), spread->divotEnd());
     682            RefPtr<RegisterID> thisRegister = generator.emitGetByVal(generator.newTemporary(), argumentsRegister.get(), generator.emitLoad(0, jsNumber(0)));
    718683            generator.emitCallVarargs(returnValue.get(), base.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 1, profileHookRegister.get(), divot(), divotStart(), divotEnd());
    719684        } else if (m_args->m_listNode && m_args->m_listNode->m_expr) {
     
    837802        RefPtr<RegisterID> argsRegister;
    838803        ArgumentListNode* args = m_args->m_listNode->m_next;
    839         if (args->m_expr->isResolveNode() && generator.willResolveToArgumentsRegister(static_cast<ResolveNode*>(args->m_expr)->identifier()) && !generator.symbolTable().slowArguments())
    840             argsRegister = generator.uncheckedLocalArgumentsRegister();
    841         else
    842             argsRegister = generator.emitNode(args->m_expr);
     804        argsRegister = generator.emitNode(args->m_expr);
    843805
    844806        // Function.prototype.apply ignores extra arguments, but we still
     
    889851    const Identifier& ident = resolve->identifier();
    890852
    891     if (Local local = generator.local(ident)) {
    892         RefPtr<RegisterID> localReg = local.get();
    893         if (local.isReadOnly()) {
     853    Variable var = generator.variable(ident);
     854    if (RegisterID* local = var.local()) {
     855        RefPtr<RegisterID> localReg = local;
     856        if (var.isReadOnly()) {
    894857            generator.emitReadOnlyExceptionIfNeeded();
    895             localReg = generator.emitMove(generator.tempDestination(dst), localReg.get());
     858            localReg = generator.emitMove(generator.tempDestination(dst), local);
    896859        } else if (generator.vm()->typeProfiler()) {
    897860            RefPtr<RegisterID> tempDst = generator.finalDestination(dst);
     
    910873
    911874    generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    912     ResolveScopeInfo resolveScopeInfo;
    913     RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, ident, resolveScopeInfo);
    914     RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound, resolveScopeInfo);
     875    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
     876    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
    915877    RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
    916     generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound, resolveScopeInfo);
     878    generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound);
    917879    if (generator.vm()->typeProfiler()) {
    918         generator.emitProfileType(value.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
     880        generator.emitProfileType(value.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
    919881        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
    920882    }
     
    992954RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    993955{
    994     if (generator.local(m_ident).get())
     956    Variable var = generator.variable(m_ident);
     957    if (var.local())
    995958        return generator.emitLoad(generator.finalDestination(dst), false);
    996959
    997960    generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    998     ResolveScopeInfo resolveScopeInfo;
    999     RefPtr<RegisterID> base = generator.emitResolveScope(dst, m_ident, resolveScopeInfo);
     961    RefPtr<RegisterID> base = generator.emitResolveScope(dst, var);
    1000962    return generator.emitDeleteById(generator.finalDestination(dst, base.get()), base.get(), m_ident);
    1001963}
     
    10481010}
    10491011
    1050 // ------------------------------ TypeOfValueNode -----------------------------------
     1012// ------------------------------ TypeOfResolveNode -----------------------------------
    10511013
    10521014RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    10531015{
    1054     if (Local local = generator.local(m_ident)) {
     1016    Variable var = generator.variable(m_ident);
     1017    if (RegisterID* local = var.local()) {
    10551018        if (dst == generator.ignoredResult())
    10561019            return 0;
    1057         return generator.emitTypeOf(generator.finalDestination(dst), local.get());
    1058     }
    1059 
    1060     ResolveScopeInfo resolveScopeInfo;
    1061     RefPtr<RegisterID> scope = generator.emitResolveScope(dst, m_ident, resolveScopeInfo);
    1062     RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, DoNotThrowIfNotFound, resolveScopeInfo);
     1020        return generator.emitTypeOf(generator.finalDestination(dst), local);
     1021    }
     1022
     1023    RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
     1024    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
    10631025    if (dst == generator.ignoredResult())
    10641026        return 0;
     
    10861048    const Identifier& ident = resolve->identifier();
    10871049
    1088     if (Local local = generator.local(ident)) {
    1089         RefPtr<RegisterID> localReg = local.get();
    1090         if (local.isReadOnly()) {
     1050    Variable var = generator.variable(ident);
     1051    if (RegisterID* local = var.local()) {
     1052        RefPtr<RegisterID> localReg = local;
     1053        if (var.isReadOnly()) {
    10911054            generator.emitReadOnlyExceptionIfNeeded();
    10921055            localReg = generator.emitMove(generator.tempDestination(dst), localReg.get());
     
    11051068
    11061069    generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    1107     ResolveScopeInfo resolveScopeInfo;
    1108     RefPtr<RegisterID> scope = generator.emitResolveScope(dst, ident, resolveScopeInfo);
    1109     RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound, resolveScopeInfo);
     1070    RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
     1071    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
    11101072    emitIncOrDec(generator, value.get(), m_operator);
    1111     generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound, resolveScopeInfo);
     1073    generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound);
    11121074    if (generator.vm()->typeProfiler()) {
    1113         generator.emitProfileType(value.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
     1075        generator.emitProfileType(value.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
    11141076        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
    11151077    }
     
    16031565{
    16041566    JSTextPosition newDivot = divotStart() + m_ident.length();
    1605     if (Local local = generator.local(m_ident)) {
    1606         if (local.isReadOnly()) {
     1567    Variable var = generator.variable(m_ident);
     1568    if (RegisterID* local = var.local()) {
     1569        if (var.isReadOnly()) {
    16071570            generator.emitReadOnlyExceptionIfNeeded();
    1608             return emitReadModifyAssignment(generator, generator.finalDestination(dst), local.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
     1571            return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
    16091572        }
    16101573       
     
    16121575            || generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
    16131576            RefPtr<RegisterID> result = generator.newTemporary();
    1614             generator.emitMove(result.get(), local.get());
     1577            generator.emitMove(result.get(), local);
    16151578            emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
    1616             generator.emitMove(local.get(), result.get());
    1617             generator.invalidateForInContextForLocal(local.get());
     1579            generator.emitMove(local, result.get());
     1580            generator.invalidateForInContextForLocal(local);
    16181581            if (generator.vm()->typeProfiler())
    16191582                generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
     
    16211584        }
    16221585       
    1623         RegisterID* result = emitReadModifyAssignment(generator, local.get(), local.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
    1624         generator.invalidateForInContextForLocal(local.get());
     1586        RegisterID* result = emitReadModifyAssignment(generator, local, local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
     1587        generator.invalidateForInContextForLocal(local);
    16251588        return generator.moveToDestinationIfNeeded(dst, result);
    16261589    }
    16271590
    16281591    generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
    1629     ResolveScopeInfo resolveScopeInfo;
    1630     RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, m_ident, resolveScopeInfo);
    1631     RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, ThrowIfNotFound, resolveScopeInfo);
     1592    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
     1593    RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
    16321594    RefPtr<RegisterID> result = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this);
    1633     RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), ThrowIfNotFound, resolveScopeInfo);
     1595    RegisterID* returnResult = generator.emitPutToScope(scope.get(), var, result.get(), ThrowIfNotFound);
    16341596    if (generator.vm()->typeProfiler()) {
    1635         generator.emitProfileType(result.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
     1597        generator.emitProfileType(result.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
    16361598        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
    16371599    }
     
    16431605RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    16441606{
    1645     if (Local local = generator.local(m_ident)) {
    1646         if (local.isReadOnly()) {
     1607    Variable var = generator.variable(m_ident);
     1608    if (RegisterID* local = var.local()) {
     1609        if (var.isReadOnly()) {
    16471610            generator.emitReadOnlyExceptionIfNeeded();
    16481611            return generator.emitNode(dst, m_right);
    16491612        }
    1650         if (local.isSpecial() || generator.vm()->typeProfiler()) {
     1613        if (var.isSpecial() || generator.vm()->typeProfiler()) {
    16511614            RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
    16521615            generator.emitNode(tempDst.get(), m_right);
    1653             generator.emitMove(local.get(), tempDst.get());
    1654             generator.invalidateForInContextForLocal(local.get());
     1616            generator.emitMove(local, tempDst.get());
     1617            generator.invalidateForInContextForLocal(local);
    16551618            if (generator.vm()->typeProfiler())
    16561619                generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
    16571620            return generator.moveToDestinationIfNeeded(dst, tempDst.get());
    16581621        }
    1659         RegisterID* result = generator.emitNode(local.get(), m_right);
    1660         generator.invalidateForInContextForLocal(local.get());
     1622        RegisterID* result = generator.emitNode(local, m_right);
     1623        generator.invalidateForInContextForLocal(local);
    16611624        return generator.moveToDestinationIfNeeded(dst, result);
    16621625    }
     
    16641627    if (generator.isStrictMode())
    16651628        generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    1666     ResolveScopeInfo resolveScopeInfo;
    1667     RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, m_ident, resolveScopeInfo);
     1629    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
    16681630    if (dst == generator.ignoredResult())
    16691631        dst = 0;
    16701632    RefPtr<RegisterID> result = generator.emitNode(dst, m_right);
    16711633    generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    1672     RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
     1634    RegisterID* returnResult = generator.emitPutToScope(scope.get(), var, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
    16731635    if (generator.vm()->typeProfiler()) {
    1674         generator.emitProfileType(result.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
     1636        generator.emitProfileType(result.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
    16751637        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
    16761638    }
     
    17811743{
    17821744    // FIXME: This code does not match the behavior of const in Firefox.
    1783     if (Local local = generator.constLocal(m_ident)) {
     1745    Variable var = generator.variable(m_ident);
     1746    if (RegisterID* local = var.local()) {
    17841747        if (!m_init)
    1785             return local.get();
     1748            return local;
    17861749
    17871750        // FIXME: Maybe call emitExpressionInfo here.
    1788         if (local.isSpecial() || generator.vm()->typeProfiler()) {
     1751        if (var.isSpecial() || generator.vm()->typeProfiler()) {
    17891752            RefPtr<RegisterID> tempDst = generator.newTemporary();
    17901753            generator.emitNode(tempDst.get(), m_init);
    1791             return generator.emitMove(local.get(), tempDst.get());
     1754            return generator.emitMove(local, tempDst.get());
    17921755        }
    17931756       
    1794         return generator.emitNode(local.get(), m_init);
     1757        return generator.emitNode(local, m_init);
    17951758    }
    17961759
     
    18011764
    18021765    if (generator.codeType() != EvalCode) {
    1803 
    1804         ResolveScopeInfo resolveScopeInfo;
    1805         if (RefPtr<RegisterID> scope = generator.emitResolveConstantLocal(generator.newTemporary(), m_ident, resolveScopeInfo))
    1806             return generator.emitPutToScope(scope.get(), m_ident, value.get(), DoNotThrowIfNotFound, resolveScopeInfo);
    1807 
    1808         return value.get();
     1766        // Do a special kind of resolution. If anything fails, then don't perform the assignment. This is
     1767        // pretty shady - particularly how negligent it is with inteleaving scopes - but it's the
     1768        // behavior that JSC has had for a long time.
     1769       
     1770        ASSERT(generator.codeType() == FunctinCode);
     1771       
     1772        var = generator.variablePerSymbolTable(m_ident);
     1773        if (!var.isResolved())
     1774            return value.get();
     1775       
     1776        RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), var);
     1777        return generator.emitPutToScope(scope.get(), var, value.get(), DoNotThrowIfNotFound);
    18091778    }
    18101779
    18111780    // FIXME: This will result in incorrect assignment if m_ident exists in an intervening with scope.
    1812     ResolveScopeInfo resolveScopeInfo;
    1813     RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, m_ident, resolveScopeInfo);
    1814     return generator.emitPutToScope(scope.get(), m_ident, value.get(), DoNotThrowIfNotFound, resolveScopeInfo);
     1781    RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
     1782    return generator.emitPutToScope(scope.get(), var, value.get(), DoNotThrowIfNotFound);
    18151783}
    18161784
     
    19041872        return nullptr;
    19051873
    1906     if (Local local = generator.local(m_ident))
    1907         generator.emitProfileType(local.get(), ProfileTypeBytecodeHasGlobalID, nullptr);
     1874    Variable var = generator.variable(m_ident);
     1875    if (RegisterID* local = var.local())
     1876        generator.emitProfileType(local, ProfileTypeBytecodeHasGlobalID, nullptr);
    19081877    else {
    1909         ResolveScopeInfo resolveScopeInfo;
    1910         RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, m_ident, resolveScopeInfo);
    1911         RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, DoNotThrowIfNotFound, resolveScopeInfo);
    1912         generator.emitProfileType(value.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
     1878        RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
     1879        RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
     1880        generator.emitProfileType(value.get(), var.isResolved() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
    19131881    }
    19141882
     
    20802048    if (m_lexpr->isResolveNode()) {
    20812049        const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
    2082         Local local = generator.local(ident);
    2083         return local.get();
     2050        return generator.variable(ident).local();
    20842051    }
    20852052
     
    20922059        auto simpleBinding = static_cast<BindingNode*>(binding);
    20932060        const Identifier& ident = simpleBinding->boundProperty();
    2094         Local local = generator.local(ident);
    2095         if (local.isSpecial())
     2061        Variable var = generator.variable(ident);
     2062        if (var.isSpecial())
    20962063            return nullptr;
    2097         return local.get();
     2064        return var.local();
    20982065    }
    20992066
     
    21052072    if (m_lexpr->isResolveNode()) {
    21062073        const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
    2107         Local local = generator.local(ident);
    2108         if (local.get())
    2109             generator.emitMove(local.get(), propertyName);
     2074        Variable var = generator.variable(ident);
     2075        if (RegisterID* local = var.local())
     2076            generator.emitMove(local, propertyName);
    21102077        else {
    21112078            if (generator.isStrictMode())
    21122079                generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    2113             ResolveScopeInfo resolveScopeInfo;
    2114             RegisterID* scope = generator.emitResolveScope(nullptr, ident, resolveScopeInfo);
     2080            RegisterID* scope = generator.emitResolveScope(nullptr, var);
    21152081            generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    2116             generator.emitPutToScope(scope, ident, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
     2082            generator.emitPutToScope(scope, var, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
    21172083            if (generator.vm()->typeProfiler())
    2118                 generator.emitProfileType(propertyName, resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
     2084                generator.emitProfileType(propertyName, var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
    21192085        }
    21202086        if (generator.vm()->typeProfiler())
     
    21572123        auto simpleBinding = static_cast<BindingNode*>(binding);
    21582124        const Identifier& ident = simpleBinding->boundProperty();
    2159         Local local = generator.local(ident);
    2160         if (!local.get() || local.isSpecial()) {
     2125        Variable var = generator.variable(ident);
     2126        if (!var.local() || var.isSpecial()) {
    21612127            assignNode->bindings()->bindValue(generator, propertyName);
    21622128            return;
    21632129        }
    2164         generator.emitMove(local.get(), propertyName);
     2130        generator.emitMove(var.local(), propertyName);
    21652131        if (generator.vm()->typeProfiler())
    21662132            generator.emitTypeProfilerExpressionInfo(simpleBinding->divotStart(), simpleBinding->divotEnd());
     
    23302296        if (m_lexpr->isResolveNode()) {
    23312297            const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
    2332             if (Local local = generator.local(ident))
    2333                 generator.emitMove(local.get(), value);
     2298            Variable var = generator.variable(ident);
     2299            if (RegisterID* local = var.local())
     2300                generator.emitMove(local, value);
    23342301            else {
    23352302                if (generator.isStrictMode())
    23362303                    generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    2337                 ResolveScopeInfo resolveScopeInfo;
    2338                 RegisterID* scope = generator.emitResolveScope(nullptr, ident, resolveScopeInfo);
     2304                RegisterID* scope = generator.emitResolveScope(nullptr, var);
    23392305                generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    2340                 generator.emitPutToScope(scope, ident, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
     2306                generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
    23412307                if (generator.vm()->typeProfiler())
    2342                     generator.emitProfileType(value, resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
     2308                    generator.emitProfileType(value, var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
    23432309            }
    23442310            if (generator.vm()->typeProfiler())
     
    29652931RegisterID* ArrayPatternNode::emitDirectBinding(BytecodeGenerator& generator, RegisterID* dst, ExpressionNode* rhs)
    29662932{
    2967     if (rhs->isResolveNode()
    2968         && generator.willResolveToArgumentsRegister(static_cast<ResolveNode*>(rhs)->identifier())
    2969         && generator.hasSafeLocalArgumentsRegister()&& !generator.symbolTable().slowArguments()) {
    2970         for (size_t i = 0; i < m_targetPatterns.size(); i++) {
    2971             auto target = m_targetPatterns[i];
    2972             if (!target)
    2973                 continue;
    2974            
    2975             RefPtr<RegisterID> temp = generator.newTemporary();
    2976             generator.emitLoad(temp.get(), jsNumber(i));
    2977             generator.emitGetArgumentByVal(temp.get(), generator.uncheckedLocalArgumentsRegister(), temp.get());
    2978             target->bindValue(generator, temp.get());
    2979         }
    2980         if (dst == generator.ignoredResult() || !dst)
    2981             return generator.emitLoad(generator.finalDestination(dst), jsUndefined());
    2982         Local local = generator.local(generator.vm()->propertyNames->arguments);
    2983         return generator.moveToDestinationIfNeeded(dst, local.get());
    2984     }
    29852933    if (!rhs->isSimpleArray())
    29862934        return 0;
     
    30703018void BindingNode::bindValue(BytecodeGenerator& generator, RegisterID* value) const
    30713019{
    3072     if (Local local = generator.local(m_boundProperty)) {
    3073         if (local.isReadOnly()) {
     3020    Variable var = generator.variable(m_boundProperty);
     3021    if (RegisterID* local = var.local()) {
     3022        if (var.isReadOnly()) {
    30743023            generator.emitReadOnlyExceptionIfNeeded();
    30753024            return;
    30763025        }
    3077         generator.emitMove(local.get(), value);
     3026        generator.emitMove(local, value);
    30783027        if (generator.vm()->typeProfiler())
    30793028            generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
     
    30823031    if (generator.isStrictMode())
    30833032        generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
    3084     ResolveScopeInfo resolveScopeInfo;
    3085     RegisterID* scope = generator.emitResolveScope(nullptr, m_boundProperty, resolveScopeInfo);
     3033    RegisterID* scope = generator.emitResolveScope(nullptr, var);
    30863034    generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
    3087     generator.emitPutToScope(scope, m_boundProperty, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
     3035    generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
    30883036    if (generator.vm()->typeProfiler()) {
    3089         generator.emitProfileType(value, resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_boundProperty);
     3037        generator.emitProfileType(value, var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_boundProperty);
    30903038        generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
    30913039    }
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractHeap.h

    r180656 r181993  
    4848    macro(Stack) \
    4949    macro(Heap) \
    50     macro(Arguments_registers) \
    5150    macro(Butterfly_publicLength) \
    5251    macro(Butterfly_vectorLength) \
     
    5857    macro(JSCell_typeInfoType) \
    5958    macro(JSObject_butterfly) \
    60     macro(JSEnvironmentRecord_registers) \
    6159    macro(JSPropertyNameEnumerator_cachedPropertyNames) \
    6260    macro(NamedProperties) \
     
    6664    macro(IndexedArrayStorageProperties) \
    6765    macro(ArrayStorageProperties) \
    68     macro(Variables) \
     66    macro(DirectArgumentsProperties) \
     67    macro(ScopeProperties) \
    6968    macro(TypedArrayProperties) \
    7069    macro(HeapObjectCount) /* Used to reflect the fact that some allocations reveal object identity */\
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h

    r173993 r181993  
    11/*
    2  * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    149149private:
    150150    void clobberWorld(const CodeOrigin&, unsigned indexInBlock);
    151     void clobberCapturedVars(const CodeOrigin&);
    152151   
    153152    template<typename Functor>
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r181891 r181993  
    132132    case JSConstant:
    133133    case DoubleConstant:
    134     case Int52Constant:
    135     case PhantomArguments: {
     134    case Int52Constant: {
    136135        setBuiltInConstant(node, *node->constant());
    137136        break;
     
    140139    case Identity: {
    141140        forNode(node) = forNode(node->child1());
     141        if (forNode(node).value())
     142            m_state.setFoundConstants(true);
    142143        break;
    143144    }
     
    208209        break;
    209210       
    210     case LoadVarargs: {
     211    case LoadVarargs:
     212    case ForwardVarargs: {
     213        // FIXME: ForwardVarargs should check if the count becomes known, and if it does, it should turn
     214        // itself into a straight-line sequence of GetStack/PutStack.
     215        // https://bugs.webkit.org/show_bug.cgi?id=143071
    211216        clobberWorld(node->origin.semantic, clobberLimit);
    212217        LoadVarargsData* data = node->loadVarargsData();
     
    880885        }
    881886       
    882         if (isFinalObjectSpeculation(abstractChild.m_type) || isArraySpeculation(abstractChild.m_type) || isArgumentsSpeculation(abstractChild.m_type)) {
     887        if (isFinalObjectSpeculation(abstractChild.m_type) || isArraySpeculation(abstractChild.m_type) || isDirectArgumentsSpeculation(abstractChild.m_type) || isScopedArgumentsSpeculation(abstractChild.m_type)) {
    883888            setConstant(node, *m_graph.freeze(vm->smallStrings.objectString()));
    884889            break;
     
    10321037                forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
    10331038            break;
    1034         case Array::Arguments:
     1039        case Array::DirectArguments:
     1040        case Array::ScopedArguments:
    10351041            forNode(node).makeHeapTop();
    10361042            break;
     
    11391145        forNode(node).makeHeapTop();
    11401146        break;
     1147       
     1148    case GetMyArgumentByVal: {
     1149        JSValue index = forNode(node->child2()).m_value;
     1150        InlineCallFrame* inlineCallFrame = node->child1()->origin.semantic.inlineCallFrame;
     1151
     1152        if (index && index.isInt32()) {
     1153            // This pretends to return TOP for accesses that are actually proven out-of-bounds because
     1154            // that's the conservative thing to do. Otherwise we'd need to write more code to mark such
     1155            // paths as unreachable, and it's almost certainly not worth the effort.
     1156           
     1157            if (inlineCallFrame) {
     1158                if (index.asUInt32() < inlineCallFrame->arguments.size() - 1) {
     1159                    forNode(node) = m_state.variables().operand(
     1160                        virtualRegisterForArgument(index.asInt32() + 1) + inlineCallFrame->stackOffset);
     1161                    m_state.setFoundConstants(true);
     1162                    break;
     1163                }
     1164            } else {
     1165                if (index.asUInt32() < m_state.variables().numberOfArguments() - 1) {
     1166                    forNode(node) = m_state.variables().argument(index.asInt32() + 1);
     1167                    m_state.setFoundConstants(true);
     1168                    break;
     1169                }
     1170            }
     1171        }
     1172       
     1173        if (inlineCallFrame) {
     1174            // We have a bound on the types even though it's random access. Take advantage of this.
     1175           
     1176            AbstractValue result;
     1177            for (unsigned i = inlineCallFrame->arguments.size(); i-- > 1;) {
     1178                result.merge(
     1179                    m_state.variables().operand(
     1180                        virtualRegisterForArgument(i) + inlineCallFrame->stackOffset));
     1181            }
     1182           
     1183            if (result.value())
     1184                m_state.setFoundConstants(true);
     1185            forNode(node) = result;
     1186            break;
     1187        }
     1188       
     1189        forNode(node).makeHeapTop();
     1190        break;
     1191    }
    11411192           
    11421193    case RegExpExec:
     
    13041355       
    13051356    case PhantomNewObject:
     1357    case PhantomDirectArguments:
     1358    case PhantomClonedArguments:
    13061359    case BottomValue:
    13071360        m_state.setDidClobber(true); // Prevent constant folding.
     
    13331386        break;
    13341387   
    1335     case CreateArguments:
    1336         forNode(node) = forNode(node->child1());
    1337         forNode(node).filter(~SpecEmpty);
    1338         forNode(node).merge(SpecArguments);
    1339         break;
    1340        
    1341     case TearOffArguments:
    1342         // Does nothing that is user-visible.
    1343         break;
    1344 
    1345     case CheckArgumentsNotCreated:
    1346         if (isEmptySpeculation(
    1347                 m_state.variables().operand(
    1348                     m_graph.argumentsRegisterFor(node->origin.semantic).offset()).m_type))
    1349             m_state.setFoundConstants(true);
    1350         break;
    1351        
    1352     case GetMyArgumentsLength:
    1353         // We know that this executable does not escape its arguments, so we can optimize
    1354         // the arguments a bit. Note that this is not sufficient to force constant folding
    1355         // of GetMyArgumentsLength, because GetMyArgumentsLength is a clobbering operation.
    1356         // We perform further optimizations on this later on.
    1357         if (node->origin.semantic.inlineCallFrame
    1358             && !node->origin.semantic.inlineCallFrame->isVarargs()) {
    1359             setConstant(
    1360                 node, jsNumber(node->origin.semantic.inlineCallFrame->arguments.size() - 1));
    1361             m_state.setDidClobber(true); // Pretend that we clobbered to prevent constant folding.
    1362         } else
    1363             forNode(node).setType(SpecInt32);
    1364         break;
    1365        
    1366     case GetMyArgumentsLengthSafe:
    1367         // This potentially clobbers all structures if the arguments object had a getter
    1368         // installed on the length property.
    1369         clobberWorld(node->origin.semantic, clobberLimit);
    1370         // We currently make no guarantee about what this returns because it does not
    1371         // speculate that the length property is actually a length.
    1372         forNode(node).makeHeapTop();
    1373         break;
    1374        
    1375     case GetMyArgumentByVal: {
    1376         InlineCallFrame* inlineCallFrame = node->origin.semantic.inlineCallFrame;
    1377         JSValue value = forNode(node->child1()).m_value;
    1378         if (inlineCallFrame && value && value.isInt32()) {
    1379             int32_t index = value.asInt32();
    1380             if (index >= 0
    1381                 && static_cast<size_t>(index + 1) < inlineCallFrame->arguments.size()) {
    1382                 forNode(node) = m_state.variables().operand(
    1383                     inlineCallFrame->stackOffset +
    1384                     m_graph.baselineCodeBlockFor(inlineCallFrame)->argumentIndexAfterCapture(index));
    1385                 m_state.setFoundConstants(true);
    1386                 break;
    1387             }
    1388         }
    1389         forNode(node).makeHeapTop();
    1390         break;
    1391     }
    1392        
    1393     case GetMyArgumentByValSafe:
    1394         // This potentially clobbers all structures if the property we're accessing has
    1395         // a getter. We don't speculate against this.
    1396         clobberWorld(node->origin.semantic, clobberLimit);
    1397         // And the result is unknown.
    1398         forNode(node).makeHeapTop();
    1399         break;
    1400        
    1401     case NewFunction: {
    1402         AbstractValue& value = forNode(node);
    1403         value = forNode(node->child1());
    1404        
    1405         if (!(value.m_type & SpecEmpty)) {
    1406             m_state.setFoundConstants(true);
    1407             break;
    1408         }
    1409 
    1410         value.setType((value.m_type & ~SpecEmpty) | SpecFunction);
    1411         break;
    1412     }
    1413 
    1414     case NewFunctionExpression:
    1415     case NewFunctionNoCheck:
     1388    case CreateDirectArguments:
     1389        forNode(node).set(m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->directArgumentsStructure());
     1390        break;
     1391       
     1392    case CreateScopedArguments:
     1393        forNode(node).set(m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->scopedArgumentsStructure());
     1394        break;
     1395       
     1396    case CreateClonedArguments:
     1397        forNode(node).setType(SpecObjectOther);
     1398        break;
     1399       
     1400    case NewFunction:
    14161401        forNode(node).set(
    14171402            m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->functionStructure());
     
    14201405    case GetCallee:
    14211406        forNode(node).setType(SpecFunction);
     1407        break;
     1408       
     1409    case GetArgumentCount:
     1410        forNode(node).setType(SpecInt32);
    14221411        break;
    14231412       
     
    14701459    }
    14711460
    1472     case GetClosureRegisters:
    1473         forNode(node).clear(); // The result is not a JS value.
    1474         break;
    1475 
    14761461    case GetClosureVar:
    1477         if (JSValue value = m_graph.tryGetConstantClosureVar(forNode(node->child1()), VirtualRegister(node->varNumber()))) {
     1462        if (JSValue value = m_graph.tryGetConstantClosureVar(forNode(node->child1()), node->scopeOffset())) {
    14781463            setConstant(node, *m_graph.freeze(value));
    14791464            break;
     
    14831468           
    14841469    case PutClosureVar:
    1485         clobberCapturedVars(node->origin.semantic);
     1470        break;
     1471       
     1472    case GetFromArguments:
     1473        forNode(node).makeHeapTop();
     1474        break;
     1475       
     1476    case PutToArguments:
    14861477        break;
    14871478           
     
    16271618        case Array::SlowPutArrayStorage:
    16281619            break;
    1629         case Array::Arguments:
    1630             filter(node->child1(), SpecArguments);
     1620        case Array::DirectArguments:
     1621            filter(node->child1(), SpecDirectArguments);
     1622            break;
     1623        case Array::ScopedArguments:
     1624            filter(node->child1(), SpecScopedArguments);
    16311625            break;
    16321626        case Array::Int8Array:
     
    20272021    case CallForwardVarargs:
    20282022    case ConstructVarargs:
     2023    case ConstructForwardVarargs:
    20292024        clobberWorld(node->origin.semantic, clobberLimit);
    20302025        forNode(node).makeHeapTop();
     
    21212116template<typename AbstractStateType>
    21222117void AbstractInterpreter<AbstractStateType>::clobberWorld(
    2123     const CodeOrigin& codeOrigin, unsigned clobberLimit)
    2124 {
    2125     clobberCapturedVars(codeOrigin);
     2118    const CodeOrigin&, unsigned clobberLimit)
     2119{
    21262120    clobberStructures(clobberLimit);
    2127 }
    2128 
    2129 template<typename AbstractStateType>
    2130 void AbstractInterpreter<AbstractStateType>::clobberCapturedVars(const CodeOrigin& codeOrigin)
    2131 {
    2132     SamplingRegion samplingRegion("DFG AI Clobber Captured Vars");
    2133     if (codeOrigin.inlineCallFrame) {
    2134         const BitVector& capturedVars = codeOrigin.inlineCallFrame->capturedVars;
    2135         for (size_t i = capturedVars.size(); i--;) {
    2136             if (!capturedVars.quickGet(i))
    2137                 continue;
    2138             m_state.variables().local(i).makeHeapTop();
    2139         }
    2140     } else {
    2141         for (size_t i = m_codeBlock->m_numVars; i--;) {
    2142             if (m_codeBlock->isCaptured(virtualRegisterForLocal(i)))
    2143                 m_state.variables().local(i).makeHeapTop();
    2144         }
    2145     }
    2146 
    2147     for (size_t i = m_state.variables().numberOfArguments(); i--;) {
    2148         if (m_codeBlock->isCaptured(virtualRegisterForArgument(i)))
    2149             m_state.variables().argument(i).makeHeapTop();
    2150     }
    21512121}
    21522122
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h

    r172737 r181993  
    11/*
    2  * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    347347    // This is a proven constraint on the possible types that this value can have
    348348    // now or any time in the future, unless it is reassigned. This field is
    349     // impervious to side-effects unless the side-effect can reassign the value
    350     // (for example if we're talking about a captured variable). The relationship
    351     // between this field, and the structure fields above, is as follows. The
    352     // fields above constraint the structures that a cell may have, but they say
    353     // nothing about whether or not the value is known to be a cell. More formally,
    354     // the m_structure is itself an abstract value that consists of the
    355     // union of the set of all non-cell values and the set of cell values that have
    356     // the given structure. This abstract value is then the intersection of the
    357     // m_structure and the set of values whose type is m_type. So, for
    358     // example if m_type is SpecFinal|SpecInt32 and m_structure is
    359     // [0x12345] then this abstract value corresponds to the set of all integers
    360     // unified with the set of all objects with structure 0x12345.
     349    // impervious to side-effects. The relationship between this field, and the
     350    // structure fields above, is as follows. The fields above constraint the
     351    // structures that a cell may have, but they say nothing about whether or not
     352    // the value is known to be a cell. More formally, the m_structure is itself an
     353    // abstract value that consists of the union of the set of all non-cell values
     354    // and the set of cell values that have the given structure. This abstract
     355    // value is then the intersection of the m_structure and the set of values
     356    // whose type is m_type. So, for example if m_type is SpecFinal|SpecInt32 and
     357    // m_structure is [0x12345] then this abstract value corresponds to the set of
     358    // all integers unified with the set of all objects with structure 0x12345.
    361359    SpeculatedType m_type;
    362360   
  • trunk/Source/JavaScriptCore/dfg/DFGArgumentPosition.h

    r179503 r181993  
    4747    {
    4848        m_variables.append(variable);
     49       
     50        // We may set this early. Merging it here saves us time in prediction propagation.
     51        variable->mergeShouldNeverUnbox(m_shouldNeverUnbox);
    4952    }
    5053   
  • trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp

    r180703 r181993  
    198198            return withType(Array::String);
    199199       
    200         if (isArgumentsSpeculation(base))
    201             return withType(Array::Arguments);
     200        if (isDirectArgumentsSpeculation(base) || isScopedArgumentsSpeculation(base)) {
     201            // Handle out-of-bounds accesses as generic accesses.
     202            if (graph.hasExitSite(node->origin.semantic, OutOfBounds) || !isInBounds())
     203                return ArrayMode(Array::Generic);
     204           
     205            if (isDirectArgumentsSpeculation(base))
     206                return withType(Array::DirectArguments);
     207            return withType(Array::ScopedArguments);
     208        }
    202209       
    203210        ArrayMode result;
     
    397404        } }
    398405       
    399     case Array::Arguments:
    400         return speculationChecked(value.m_type, SpecArguments);
     406    case Array::DirectArguments:
     407        return speculationChecked(value.m_type, SpecDirectArguments);
     408       
     409    case Array::ScopedArguments:
     410        return speculationChecked(value.m_type, SpecScopedArguments);
    401411       
    402412    case Array::Int8Array:
     
    462472    case Array::SlowPutArrayStorage:
    463473        return "SlowPutArrayStorage";
    464     case Array::Arguments:
    465         return "Arguments";
     474    case Array::DirectArguments:
     475        return "DirectArguments";
     476    case Array::ScopedArguments:
     477        return "ScopedArguments";
    466478    case Array::Int8Array:
    467479        return "Int8Array";
  • trunk/Source/JavaScriptCore/dfg/DFGArrayMode.h

    r176972 r181993  
    11/*
    2  * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6666    SlowPutArrayStorage,
    6767   
    68     Arguments,
     68    DirectArguments,
     69    ScopedArguments,
     70   
    6971    Int8Array,
    7072    Int16Array,
     
    295297        case Array::ForceExit:
    296298        case Array::Generic:
    297         case Array::Arguments:
     299        case Array::DirectArguments:
     300        case Array::ScopedArguments:
    298301            return false;
    299302        default:
     
    321324        switch (type()) {
    322325        case Array::String:
     326        case Array::DirectArguments:
     327        case Array::ScopedArguments:
    323328            return ArrayMode(Array::Generic);
    324 #if USE(JSVALUE32_64)
    325         case Array::Arguments:
    326             return ArrayMode(Array::Generic);
    327 #endif
    328329        default:
    329330            return *this;
  • trunk/Source/JavaScriptCore/dfg/DFGAvailabilityMap.cpp

    r181348 r181993  
    4646    }
    4747
    48     unsigned oldPossibleNodesSize;
    49     do {
    50         oldPossibleNodesSize = possibleNodes.size();
    51         for (auto pair : m_heap) {
    52             if (pair.value.hasNode() && possibleNodes.contains(pair.key.base()))
    53                 possibleNodes.add(pair.value.node());
    54         }
    55     } while (oldPossibleNodesSize != possibleNodes.size());
     48    closeOverNodes(
     49        [&] (Node* node) -> bool {
     50            return possibleNodes.contains(node);
     51        },
     52        [&] (Node* node) -> bool {
     53            return possibleNodes.add(node).isNewEntry;
     54        });
    5655   
    5756    HashMap<PromotedHeapLocation, Availability> newHeap;
  • trunk/Source/JavaScriptCore/dfg/DFGAvailabilityMap.h

    r173993 r181993  
    5353    }
    5454   
     55    template<typename HasFunctor, typename AddFunctor>
     56    void closeOverNodes(const HasFunctor& has, const AddFunctor& add)
     57    {
     58        bool changed;
     59        do {
     60            changed = false;
     61            for (auto pair : m_heap) {
     62                if (pair.value.hasNode() && has(pair.key.base()))
     63                    changed |= add(pair.value.node());
     64            }
     65        } while (changed);
     66    }
     67   
     68    template<typename HasFunctor, typename AddFunctor>
     69    void closeStartingWithLocal(VirtualRegister reg, const HasFunctor& has, const AddFunctor& add)
     70    {
     71        Availability availability = m_locals.operand(reg);
     72        if (!availability.hasNode())
     73            return;
     74       
     75        if (!add(availability.node()))
     76            return;
     77       
     78        closeOverNodes(has, add);
     79    }
     80   
    5581    Operands<Availability> m_locals;
    5682    HashMap<PromotedHeapLocation, Availability> m_heap;
  • trunk/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp

    r180813 r181993  
    11/*
    2  * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    324324            node->child1()->mergeFlags(NodeBytecodeUsesAsValue);
    325325            node->child2()->mergeFlags(NodeBytecodeUsesAsNumber | NodeBytecodeUsesAsOther | NodeBytecodeUsesAsInt | NodeBytecodeUsesAsArrayIndex);
    326             break;
    327         }
    328            
    329         case GetMyArgumentByValSafe: {
    330             node->child1()->mergeFlags(NodeBytecodeUsesAsNumber | NodeBytecodeUsesAsOther | NodeBytecodeUsesAsInt | NodeBytecodeUsesAsArrayIndex);
    331326            break;
    332327        }
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r181891 r181993  
    226226    void linkBlocks(Vector<UnlinkedBlock>& unlinkedBlocks, Vector<BasicBlock*>& possibleTargets);
    227227   
    228     VariableAccessData* newVariableAccessData(VirtualRegister operand, bool isCaptured)
     228    VariableAccessData* newVariableAccessData(VirtualRegister operand)
    229229    {
    230230        ASSERT(!operand.isConstant());
    231231       
    232         m_graph.m_variableAccessData.append(VariableAccessData(operand, isCaptured));
     232        m_graph.m_variableAccessData.append(VariableAccessData(operand));
    233233        return &m_graph.m_variableAccessData.last();
    234234    }
     
    347347
    348348        Node* node = m_currentBlock->variablesAtTail.local(local);
    349         bool isCaptured = m_codeBlock->isCaptured(operand, inlineCallFrame());
    350349       
    351350        // This has two goals: 1) link together variable access datas, and 2)
     
    359358        if (node) {
    360359            variable = node->variableAccessData();
    361             variable->mergeIsCaptured(isCaptured);
    362            
    363             if (!isCaptured) {
    364                 switch (node->op()) {
    365                 case GetLocal:
    366                     return node;
    367                 case SetLocal:
    368                     return node->child1().node();
    369                 default:
    370                     break;
    371                 }
     360           
     361            switch (node->op()) {
     362            case GetLocal:
     363                return node;
     364            case SetLocal:
     365                return node->child1().node();
     366            default:
     367                break;
    372368            }
    373369        } else
    374             variable = newVariableAccessData(operand, isCaptured);
     370            variable = newVariableAccessData(operand);
    375371       
    376372        node = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(variable)));
     
    385381
    386382        unsigned local = operand.toLocal();
    387         bool isCaptured = m_codeBlock->isCaptured(operand, inlineCallFrame());
    388383       
    389384        if (setMode != ImmediateNakedSet) {
    390385            ArgumentPosition* argumentPosition = findArgumentPositionForLocal(operand);
    391             if (isCaptured || argumentPosition)
     386            if (argumentPosition)
    392387                flushDirect(operand, argumentPosition);
    393388        }
    394389
    395         VariableAccessData* variableAccessData = newVariableAccessData(operand, isCaptured);
     390        VariableAccessData* variableAccessData = newVariableAccessData(operand);
    396391        variableAccessData->mergeStructureCheckHoistingFailed(
    397392            m_inlineStackTop->m_exitProfile.hasExitSite(semanticOrigin.bytecodeIndex, BadCache));
     
    412407       
    413408        Node* node = m_currentBlock->variablesAtTail.argument(argument);
    414         bool isCaptured = m_codeBlock->isCaptured(operand);
    415409
    416410        VariableAccessData* variable;
     
    418412        if (node) {
    419413            variable = node->variableAccessData();
    420             variable->mergeIsCaptured(isCaptured);
    421            
    422             if (!isCaptured) {
    423                 switch (node->op()) {
    424                 case GetLocal:
    425                     return node;
    426                 case SetLocal:
    427                     return node->child1().node();
    428                 default:
    429                     break;
    430                 }
     414           
     415            switch (node->op()) {
     416            case GetLocal:
     417                return node;
     418            case SetLocal:
     419                return node->child1().node();
     420            default:
     421                break;
    431422            }
    432423        } else
    433             variable = newVariableAccessData(operand, isCaptured);
     424            variable = newVariableAccessData(operand);
    434425       
    435426        node = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(variable)));
     
    445436        ASSERT(argument < m_numArguments);
    446437       
    447         bool isCaptured = m_codeBlock->isCaptured(operand);
    448 
    449         VariableAccessData* variableAccessData = newVariableAccessData(operand, isCaptured);
     438        VariableAccessData* variableAccessData = newVariableAccessData(operand);
    450439
    451440        // Always flush arguments, except for 'this'. If 'this' is created by us,
     
    513502    void flushDirect(VirtualRegister operand, ArgumentPosition* argumentPosition)
    514503    {
    515         bool isCaptured = m_codeBlock->isCaptured(operand, inlineCallFrame());
    516        
    517504        ASSERT(!operand.isConstant());
    518505       
     
    521508        VariableAccessData* variable;
    522509       
    523         if (node) {
     510        if (node)
    524511            variable = node->variableAccessData();
    525             variable->mergeIsCaptured(isCaptured);
    526         } else
    527             variable = newVariableAccessData(operand, isCaptured);
     512        else
     513            variable = newVariableAccessData(operand);
    528514       
    529515        node = addToGraph(Flush, OpInfo(variable));
     
    546532        for (unsigned argument = numArguments; argument-- > 1;)
    547533            flushDirect(inlineStackEntry->remapOperand(virtualRegisterForArgument(argument)));
    548         for (int local = 0; local < inlineStackEntry->m_codeBlock->m_numVars; ++local) {
    549             if (!inlineStackEntry->m_codeBlock->isCaptured(virtualRegisterForLocal(local)))
    550                 continue;
    551             flushDirect(inlineStackEntry->remapOperand(virtualRegisterForLocal(local)));
    552         }
    553534    }
    554535
     
    843824       
    844825        return node;
     826    }
     827   
     828    void noticeArgumentsUse()
     829    {
     830        // All of the arguments in this function need to be formatted as JSValues because we will
     831        // load from them in a random-access fashion and we don't want to have to switch on
     832        // format.
     833       
     834        for (ArgumentPosition* argument : m_inlineStackTop->m_argumentPositions)
     835            argument->mergeShouldNeverUnbox(true);
    845836    }
    846837   
     
    11231114    if (callTarget->isCellConstant())
    11241115        callLinkStatus.setProvenConstantCallee(CallVariant(callTarget->asCell()));
     1116   
     1117    if (Options::verboseDFGByteCodeParsing())
     1118        dataLog("    Varargs call link status at ", currentCodeOrigin(), ": ", callLinkStatus, "\n");
    11251119   
    11261120    if (callLinkStatus.canOptimize()
     
    14321426        dataLog("    Considering callee ", callee, "\n");
    14331427   
    1434     if (InternalFunction* function = callee.internalFunction()) {
    1435         if (handleConstantInternalFunction(resultOperand, function, registerOffset, argumentCountIncludingThis, specializationKind, insertChecksWithAccounting)) {
    1436             RELEASE_ASSERT(didInsertChecks);
    1437             addToGraph(Phantom, callTargetNode);
    1438             emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
    1439             inliningBalance--;
    1440             return true;
    1441         }
    1442         RELEASE_ASSERT(!didInsertChecks);
    1443         return false;
    1444     }
    1445    
    1446     Intrinsic intrinsic = callee.intrinsicFor(specializationKind);
    1447     if (intrinsic != NoIntrinsic) {
    1448         if (handleIntrinsic(resultOperand, intrinsic, registerOffset, argumentCountIncludingThis, prediction, insertChecksWithAccounting)) {
    1449             RELEASE_ASSERT(didInsertChecks);
    1450             addToGraph(Phantom, callTargetNode);
    1451             emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
    1452             inliningBalance--;
    1453             return true;
    1454         }
    1455         RELEASE_ASSERT(!didInsertChecks);
    1456         return false;
     1428    // Intrinsics and internal functions can only be inlined if we're not doing varargs. This is because
     1429    // we currently don't have any way of getting profiling information for arguments to non-JS varargs
     1430    // calls. The prediction propagator won't be of any help because LoadVarargs obscures the data flow,
     1431    // and there are no callsite value profiles and native function won't have callee value profiles for
     1432    // those arguments. Even worse, if the intrinsic decides to exit, it won't really have anywhere to
     1433    // exit to: LoadVarargs is effectful and it's part of the op_call_varargs, so we can't exit without
     1434    // calling LoadVarargs twice.
     1435    if (!InlineCallFrame::isVarargs(kind)) {
     1436        if (InternalFunction* function = callee.internalFunction()) {
     1437            if (handleConstantInternalFunction(resultOperand, function, registerOffset, argumentCountIncludingThis, specializationKind, insertChecksWithAccounting)) {
     1438                RELEASE_ASSERT(didInsertChecks);
     1439                addToGraph(Phantom, callTargetNode);
     1440                emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
     1441                inliningBalance--;
     1442                return true;
     1443            }
     1444            RELEASE_ASSERT(!didInsertChecks);
     1445            return false;
     1446        }
     1447   
     1448        Intrinsic intrinsic = callee.intrinsicFor(specializationKind);
     1449        if (intrinsic != NoIntrinsic) {
     1450            if (handleIntrinsic(resultOperand, intrinsic, registerOffset, argumentCountIncludingThis, prediction, insertChecksWithAccounting)) {
     1451                RELEASE_ASSERT(didInsertChecks);
     1452                addToGraph(Phantom, callTargetNode);
     1453                emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
     1454                inliningBalance--;
     1455                return true;
     1456            }
     1457            RELEASE_ASSERT(!didInsertChecks);
     1458            return false;
     1459        }
    14571460    }
    14581461   
     
    15411544                        m_inlineStackTop->remapOperand(VirtualRegister(registerOffset)).offset();
    15421545                   
     1546                    ensureLocals(VirtualRegister(remappedRegisterOffset).toLocal());
     1547                   
    15431548                    int argumentStart = registerOffset + JSStack::CallFrameHeaderSize;
    15441549                    int remappedArgumentStart =
     
    15601565           
    15611566                    VariableAccessData* countVariable = newVariableAccessData(
    1562                         VirtualRegister(remappedRegisterOffset + JSStack::ArgumentCount), false);
     1567                        VirtualRegister(remappedRegisterOffset + JSStack::ArgumentCount));
    15631568                    // This is pretty lame, but it will force the count to be flushed as an int. This doesn't
    15641569                    // matter very much, since our use of a SetArgument and Flushes for this local slot is
     
    15721577                    for (unsigned argument = 1; argument < maxNumArguments; ++argument) {
    15731578                        VariableAccessData* variable = newVariableAccessData(
    1574                             VirtualRegister(remappedArgumentStart + argument), false);
     1579                            VirtualRegister(remappedArgumentStart + argument));
    15751580                        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.
    15761581                       
     
    25352540        for (unsigned argument = 0; argument < m_numArguments; ++argument) {
    25362541            VariableAccessData* variable = newVariableAccessData(
    2537                 virtualRegisterForArgument(argument), m_codeBlock->isCaptured(virtualRegisterForArgument(argument)));
     2542                virtualRegisterForArgument(argument));
    25382543            variable->mergeStructureCheckHoistingFailed(
    25392544                m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
     
    30853090            addToGraph(
    30863091                PutGlobalVar,
    3087                 OpInfo(m_inlineStackTop->m_codeBlock->globalObject()->assertRegisterIsInThisObject(currentInstruction[1].u.registerPointer)),
     3092                OpInfo(m_inlineStackTop->m_codeBlock->globalObject()->assertVariableIsInThisObject(currentInstruction[1].u.variablePointer)),
    30883093                value);
    30893094            NEXT_OPCODE(op_init_global_const);
     
    33283333           
    33293334        case op_call_varargs: {
    3330             int result = currentInstruction[1].u.operand;
    3331             int callee = currentInstruction[2].u.operand;
    3332             int thisReg = currentInstruction[3].u.operand;
    3333             int arguments = currentInstruction[4].u.operand;
    3334             int firstFreeReg = currentInstruction[5].u.operand;
    3335             int firstVarArgOffset = currentInstruction[6].u.operand;
    3336            
    3337             if (arguments == m_inlineStackTop->m_codeBlock->uncheckedArgumentsRegister().offset()
    3338                 && !m_inlineStackTop->m_codeBlock->symbolTable()->slowArguments()) {
    3339                 if (inlineCallFrame()
    3340                     && !inlineCallFrame()->isVarargs()
    3341                     && !firstVarArgOffset) {
    3342                     addToGraph(CheckArgumentsNotCreated);
    3343 
    3344                     unsigned argCount = inlineCallFrame()->arguments.size();
    3345            
    3346                     // Let's compute the register offset. We start with the last used register, and
    3347                     // then adjust for the things we want in the call frame.
    3348                     int registerOffset = firstFreeReg + 1;
    3349                     registerOffset -= argCount; // We will be passing some arguments.
    3350                     registerOffset -= JSStack::CallFrameHeaderSize; // We will pretend to have a call frame header.
    3351            
    3352                     // Get the alignment right.
    3353                     registerOffset = -WTF::roundUpToMultipleOf(
    3354                         stackAlignmentRegisters(),
    3355                         -registerOffset);
    3356 
    3357                     ensureLocals(
    3358                         m_inlineStackTop->remapOperand(
    3359                             VirtualRegister(registerOffset)).toLocal());
    3360            
    3361                     // The bytecode wouldn't have set up the arguments. But we'll do it and make it
    3362                     // look like the bytecode had done it.
    3363                     int nextRegister = registerOffset + JSStack::CallFrameHeaderSize;
    3364                     set(VirtualRegister(nextRegister++), get(VirtualRegister(thisReg)), ImmediateNakedSet);
    3365                     for (unsigned argument = 1; argument < argCount; ++argument)
    3366                         set(VirtualRegister(nextRegister++), get(virtualRegisterForArgument(argument)), ImmediateNakedSet);
    3367            
    3368                     handleCall(
    3369                         result, Call, CodeForCall, OPCODE_LENGTH(op_call_varargs),
    3370                         callee, argCount, registerOffset);
    3371                     NEXT_OPCODE(op_call_varargs);
    3372                 }
    3373                
    3374                 // Emit CallForwardVarargs
    3375                 // FIXME: This means we cannot inline forwarded varargs calls inside a varargs
    3376                 // call frame. We will probably fix that once we finally get rid of the
    3377                 // arguments object special-casing.
    3378                 CallVarargsData* data = m_graph.m_callVarargsData.add();
    3379                 data->firstVarArgOffset = firstVarArgOffset;
    3380                
    3381                 Node* call = addToGraph(
    3382                     CallForwardVarargs, OpInfo(data), OpInfo(getPrediction()),
    3383                     get(VirtualRegister(callee)), get(VirtualRegister(thisReg)));
    3384                 VirtualRegister resultReg(result);
    3385                 if (resultReg.isValid())
    3386                     set(resultReg, call);
    3387                 NEXT_OPCODE(op_call_varargs);
    3388             }
    3389            
    33903335            handleVarargsCall(currentInstruction, CallVarargs, CodeForCall);
    33913336            NEXT_OPCODE(op_call_varargs);
     
    35123457            case ClosureVarWithVarInjectionChecks: {
    35133458                Node* scopeNode = get(VirtualRegister(scope));
    3514                 if (JSValue value = m_graph.tryGetConstantClosureVar(scopeNode, VirtualRegister(operand))) {
    3515                     addToGraph(Phantom, scopeNode);
     3459               
     3460                // Ideally we wouldn't have to do this Phantom. But:
     3461                //
     3462                // For the constant case: we must do it because otherwise we would have no way of knowing
     3463                // that the scope is live at OSR here.
     3464                //
     3465                // For the non-constant case: GetClosureVar could be DCE'd, but baseline's implementation
     3466                // won't be able to handle an Undefined scope.
     3467                addToGraph(Phantom, scopeNode);
     3468               
     3469                if (JSValue value = m_graph.tryGetConstantClosureVar(scopeNode, ScopeOffset(operand))) {
    35163470                    set(VirtualRegister(dst), weakJSConstant(value));
    35173471                    break;
     
    35193473                SpeculatedType prediction = getPrediction();
    35203474                set(VirtualRegister(dst),
    3521                     addToGraph(
    3522                         GetClosureVar, OpInfo(operand), OpInfo(prediction),
    3523                         scopeNode, addToGraph(GetClosureRegisters, scopeNode)));
     3475                    addToGraph(GetClosureVar, OpInfo(operand), OpInfo(prediction), scopeNode));
    35243476                break;
    35253477            }
     
    35333485        case op_put_to_scope: {
    35343486            unsigned scope = currentInstruction[1].u.operand;
    3535             unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[2].u.operand];
     3487            unsigned identifierNumber = currentInstruction[2].u.operand;
     3488            if (identifierNumber != UINT_MAX)
     3489                identifierNumber = m_inlineStackTop->m_identifierRemap[identifierNumber];
    35363490            unsigned value = currentInstruction[3].u.operand;
    35373491            ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type();
    3538             AtomicStringImpl* uid = m_graph.identifiers()[identifierNumber];
    3539 
    3540             Structure* structure = 0;
    3541             VariableWatchpointSet* watchpoints = 0;
     3492            AtomicStringImpl* uid;
     3493            if (identifierNumber != UINT_MAX)
     3494                uid = m_graph.identifiers()[identifierNumber];
     3495            else
     3496                uid = nullptr;
     3497           
     3498            Structure* structure = nullptr;
     3499            VariableWatchpointSet* watchpoints = nullptr;
    35423500            uintptr_t operand;
    35433501            {
     
    35553513            case GlobalProperty:
    35563514            case GlobalPropertyWithVarInjectionChecks: {
    3557                 PutByIdStatus status = PutByIdStatus::computeFor(globalObject, structure, uid, false);
     3515                PutByIdStatus status;
     3516                if (uid)
     3517                    status = PutByIdStatus::computeFor(globalObject, structure, uid, false);
     3518                else
     3519                    status = PutByIdStatus(PutByIdStatus::TakesSlowPath);
    35583520                if (status.numVariants() != 1
    35593521                    || status[0].kind() != PutByIdVariant::Replace
     
    35723534            case GlobalVar:
    35733535            case GlobalVarWithVarInjectionChecks: {
    3574                 SymbolTableEntry entry = globalObject->symbolTable()->get(uid);
    3575                 ASSERT(watchpoints == entry.watchpointSet());
     3536                if (watchpoints) {
     3537                    SymbolTableEntry entry = globalObject->symbolTable()->get(uid);
     3538                    ASSERT_UNUSED(entry, watchpoints == entry.watchpointSet());
     3539                }
    35763540                Node* valueNode = get(VirtualRegister(value));
    35773541                addToGraph(PutGlobalVar, OpInfo(operand), valueNode);
    3578                 if (watchpoints->state() != IsInvalidated)
     3542                if (watchpoints && watchpoints->state() != IsInvalidated)
    35793543                    addToGraph(NotifyWrite, OpInfo(watchpoints), valueNode);
    35803544                // Keep scope alive until after put.
     
    35863550            case ClosureVarWithVarInjectionChecks: {
    35873551                Node* scopeNode = get(VirtualRegister(scope));
    3588                 Node* scopeRegisters = addToGraph(GetClosureRegisters, scopeNode);
    35893552                Node* valueNode = get(VirtualRegister(value));
    35903553
     
    35923555                    addToGraph(NotifyWrite, OpInfo(watchpoints), valueNode);
    35933556
    3594                 addToGraph(PutClosureVar, OpInfo(operand), scopeNode, scopeRegisters, valueNode);
     3557                addToGraph(PutClosureVar, OpInfo(operand), scopeNode, valueNode);
    35953558                break;
    35963559            }
     
    36223585        }
    36233586           
    3624         case op_init_lazy_reg: {
    3625             set(VirtualRegister(currentInstruction[1].u.operand), jsConstant(JSValue()));
    3626             ASSERT(operandIsLocal(currentInstruction[1].u.operand));
    3627             m_graph.m_lazyVars.set(VirtualRegister(currentInstruction[1].u.operand).toLocal());
    3628             NEXT_OPCODE(op_init_lazy_reg);
    3629         }
    3630            
    36313587        case op_create_lexical_environment: {
    3632             Node* lexicalEnvironment = addToGraph(CreateActivation, get(VirtualRegister(currentInstruction[1].u.operand)), get(VirtualRegister(currentInstruction[2].u.operand)));
     3588            Node* lexicalEnvironment = addToGraph(CreateActivation, get(VirtualRegister(currentInstruction[2].u.operand)));
    36333589            set(VirtualRegister(currentInstruction[1].u.operand), lexicalEnvironment);
    36343590            set(VirtualRegister(currentInstruction[2].u.operand), lexicalEnvironment);
     
    36513607        }
    36523608           
    3653         case op_create_arguments: {
    3654             m_graph.m_hasArguments = true;
    3655             Node* createArguments = addToGraph(CreateArguments, get(VirtualRegister(currentInstruction[1].u.operand)));
     3609        case op_create_direct_arguments: {
     3610            noticeArgumentsUse();
     3611            Node* createArguments = addToGraph(CreateDirectArguments);
    36563612            set(VirtualRegister(currentInstruction[1].u.operand), createArguments);
    3657             set(unmodifiedArgumentsRegister(VirtualRegister(currentInstruction[1].u.operand)), createArguments);
    3658             NEXT_OPCODE(op_create_arguments);
    3659         }
    3660 
    3661         case op_tear_off_arguments: {
    3662             m_graph.m_hasArguments = true;
    3663             addToGraph(TearOffArguments, get(VirtualRegister(currentInstruction[1].u.operand)), get(VirtualRegister(currentInstruction[2].u.operand)));
    3664             NEXT_OPCODE(op_tear_off_arguments);
    3665         }
    3666            
    3667         case op_get_arguments_length: {
    3668             m_graph.m_hasArguments = true;
    3669             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetMyArgumentsLengthSafe));
    3670             NEXT_OPCODE(op_get_arguments_length);
    3671         }
    3672            
    3673         case op_get_argument_by_val: {
    3674             m_graph.m_hasArguments = true;
     3613            NEXT_OPCODE(op_create_direct_arguments);
     3614        }
     3615           
     3616        case op_create_scoped_arguments: {
     3617            noticeArgumentsUse();
     3618            Node* createArguments = addToGraph(CreateScopedArguments, get(VirtualRegister(currentInstruction[2].u.operand)));
     3619            set(VirtualRegister(currentInstruction[1].u.operand), createArguments);
     3620            NEXT_OPCODE(op_create_scoped_arguments);
     3621        }
     3622
     3623        case op_create_out_of_band_arguments: {
     3624            noticeArgumentsUse();
     3625            Node* createArguments = addToGraph(CreateClonedArguments);
     3626            set(VirtualRegister(currentInstruction[1].u.operand), createArguments);
     3627            NEXT_OPCODE(op_create_out_of_band_arguments);
     3628        }
     3629           
     3630        case op_get_from_arguments: {
    36753631            set(VirtualRegister(currentInstruction[1].u.operand),
    36763632                addToGraph(
    3677                     GetMyArgumentByValSafe, OpInfo(0), OpInfo(getPrediction()),
    3678                     get(VirtualRegister(currentInstruction[3].u.operand))));
    3679             NEXT_OPCODE(op_get_argument_by_val);
     3633                    GetFromArguments,
     3634                    OpInfo(currentInstruction[3].u.operand),
     3635                    OpInfo(getPrediction()),
     3636                    get(VirtualRegister(currentInstruction[2].u.operand))));
     3637            NEXT_OPCODE(op_get_from_arguments);
     3638        }
     3639           
     3640        case op_put_to_arguments: {
     3641            addToGraph(
     3642                PutToArguments,
     3643                OpInfo(currentInstruction[2].u.operand),
     3644                get(VirtualRegister(currentInstruction[1].u.operand)),
     3645                get(VirtualRegister(currentInstruction[3].u.operand)));
     3646            NEXT_OPCODE(op_put_to_arguments);
    36803647        }
    36813648           
     
    36833650            FunctionExecutable* decl = m_inlineStackTop->m_profiledBlock->functionDecl(currentInstruction[3].u.operand);
    36843651            FrozenValue* frozen = m_graph.freezeStrong(decl);
    3685             if (!currentInstruction[4].u.operand) {
    3686                 set(VirtualRegister(currentInstruction[1].u.operand),
    3687                     addToGraph(NewFunctionNoCheck, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand))));
    3688             } else {
    3689                 set(VirtualRegister(currentInstruction[1].u.operand),
    3690                     addToGraph(
    3691                         NewFunction,
    3692                         OpInfo(frozen),
    3693                         get(VirtualRegister(currentInstruction[1].u.operand)), get(VirtualRegister(currentInstruction[2].u.operand))));
    3694             }
     3652            set(VirtualRegister(currentInstruction[1].u.operand),
     3653                addToGraph(NewFunction, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand))));
    36953654            NEXT_OPCODE(op_new_func);
    36963655        }
     
    37003659            FrozenValue* frozen = m_graph.freezeStrong(expr);
    37013660            set(VirtualRegister(currentInstruction[1].u.operand),
    3702                 addToGraph(NewFunctionExpression, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand))));
     3661                addToGraph(NewFunction, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand))));
    37033662            NEXT_OPCODE(op_new_func_exp);
    37043663        }
     
    39073866    }
    39083867   
    3909     // Track the code-block-global exit sites.
    3910     if (m_exitProfile.hasExitSite(ArgumentsEscaped)) {
    3911         byteCodeParser->m_graph.m_executablesWhoseArgumentsEscaped.add(
    3912             codeBlock->ownerExecutable());
    3913     }
    3914        
    39153868    if (m_caller) {
    39163869        // Inline case.
     
    39373890        m_inlineCallFrame->kind = kind;
    39383891       
    3939         if (m_inlineCallFrame->caller.inlineCallFrame)
    3940             m_inlineCallFrame->capturedVars = m_inlineCallFrame->caller.inlineCallFrame->capturedVars;
    3941         else
    3942             m_inlineCallFrame->capturedVars = byteCodeParser->m_graph.m_outermostCapturedVars;
    3943 
    3944         for (int i = argumentCountIncludingThis; i--;) {
    3945             VirtualRegister argument = virtualRegisterForArgument(i);
    3946             if (codeBlock->isCaptured(argument))
    3947                 m_inlineCallFrame->capturedVars.set(VirtualRegister(argument.offset() + m_inlineCallFrame->stackOffset).toLocal());
    3948         }
    3949         for (size_t i = codeBlock->m_numVars; i--;) {
    3950             VirtualRegister local = virtualRegisterForLocal(i);
    3951             if (codeBlock->isCaptured(local))
    3952                 m_inlineCallFrame->capturedVars.set(VirtualRegister(local.offset() + m_inlineCallFrame->stackOffset).toLocal());
    3953         }
    3954 
    39553892        byteCodeParser->buildOperandMapsIfNecessary();
    39563893       
     
    40303967        }
    40313968        dataLog(
    4032             ": captureCount = ", codeBlock->symbolTable() ? codeBlock->symbolTable()->captureCount() : 0,
    4033             ", needsActivation = ", codeBlock->needsActivation(),
     3969            ": needsActivation = ", codeBlock->needsActivation(),
    40343970            ", isStrictMode = ", codeBlock->ownerExecutable()->isStrictMode(), "\n");
    40353971        codeBlock->baselineVersion()->dumpBytecode();
  • trunk/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp

    r179756 r181993  
    193193            }
    194194           
    195             if (variable->isCaptured()) {
    196                 variable->setIsLoadedFrom(true);
    197                 if (otherNode->op() == GetLocal)
    198                     otherNode = otherNode->child1().node();
    199                 else
    200                     ASSERT(otherNode->op() == SetLocal || otherNode->op() == SetArgument);
    201                
    202                 ASSERT(otherNode->op() == Phi || otherNode->op() == SetLocal || otherNode->op() == SetArgument);
    203                
    204                 // Keep this GetLocal but link it to the prior ones.
    205                 node->children.setChild1(Edge(otherNode));
    206                 m_block->variablesAtTail.atFor<operandKind>(idx) = node;
    207                 return;
    208             }
    209            
    210195            if (otherNode->op() == GetLocal) {
    211196                // Replace all references to this GetLocal with otherNode.
     
    336321            // variable will be a SetLocal and not those subsequent Flushes.
    337322            //
    338             // Child of GetLocal: the operation that the GetLocal keeps alive. For
    339             // uncaptured locals, it may be a Phi from the current block. For arguments,
    340             // it may be a SetArgument. For captured locals and arguments it may also be
    341             // a SetLocal.
     323            // Child of GetLocal: the operation that the GetLocal keeps alive. It may be
     324            // a Phi from the current block. For arguments, it may be a SetArgument.
    342325            //
    343326            // Child of SetLocal: must be a value producing node.
  • trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp

    r173413 r181993  
    11/*
    2  * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    327327       
    328328            if (m_node->op() == GetLocal) {
    329                 // For uncaptured locals, usually the CPS rethreading phase does this. But it's OK
    330                 // for us to mess with locals - regardless of their capturedness - so long as:
     329                // Usually the CPS rethreading phase does this. But it's OK for us to mess with
     330                // locals so long as:
    331331                //
    332332                // - We dethread the graph. Any changes we make may invalidate the assumptions of
     
    467467        // computed. We pick one that is in a block that dominates ours. Note that this means that
    468468        // a PureValue will map to a list of nodes, since there may be many places in the control
    469         // flow graph that compute a value but only one of them that dominates us. we may build up
     469        // flow graph that compute a value but only one of them that dominates us. We may build up
    470470        // a large list of nodes that compute some value in the case of gnarly control flow. This
    471471        // is probably OK.
  • trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp

    r181891 r181993  
    4545bool isSupportedForInlining(CodeBlock* codeBlock)
    4646{
    47     return !codeBlock->ownerExecutable()->needsActivation()
    48         && codeBlock->ownerExecutable()->isInliningCandidate();
     47    return codeBlock->ownerExecutable()->isInliningCandidate();
    4948}
    5049
     
    185184    case op_call_varargs:
    186185    case op_construct_varargs:
    187     case op_init_lazy_reg:
    188     case op_create_arguments:
    189     case op_tear_off_arguments:
    190     case op_get_argument_by_val:
    191     case op_get_arguments_length:
     186    case op_create_direct_arguments:
     187    case op_create_scoped_arguments:
     188    case op_create_out_of_band_arguments:
     189    case op_get_from_arguments:
     190    case op_put_to_arguments:
    192191    case op_jneq_ptr:
    193192    case op_typeof:
     
    209208    case op_new_func:
    210209    case op_new_func_exp:
     210    case op_create_lexical_environment:
    211211        return CanCompileAndInline;
    212212
     
    228228    }
    229229
    230     case op_new_regexp:
    231     case op_create_lexical_environment:
     230    case op_new_regexp:
    232231    case op_switch_string: // Don't inline because we don't want to copy string tables in the concurrent JIT.
    233232        return CanCompile;
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r181891 r181993  
    271271    case PhantomLocal:
    272272    case SetArgument:
    273     case PhantomArguments:
    274273    case Jump:
    275274    case Branch:
     
    301300
    302301    case Flush:
    303         read(AbstractHeap(Variables, node->local()));
     302        read(AbstractHeap(Stack, node->local()));
    304303        write(SideState);
    305304        return;
     
    318317        read(HeapObjectCount);
    319318        write(HeapObjectCount);
    320         write(SideState);
    321         write(Watchpoint_fire);
    322         return;
    323        
    324     case CreateArguments:
    325         read(Variables);
     319        return;
     320       
     321    case CreateDirectArguments:
     322    case CreateScopedArguments:
     323    case CreateClonedArguments:
     324        read(Stack);
    326325        read(HeapObjectCount);
    327326        write(HeapObjectCount);
    328         write(SideState);
    329         write(Watchpoint_fire);
     327        return;
     328
     329    case PhantomDirectArguments:
     330    case PhantomClonedArguments:
     331        // DFG backend requires that the locals that this reads are flushed. FTL backend can handle those
     332        // locals being promoted.
     333        if (!isFTL(graph.m_plan.mode))
     334            read(Stack);
     335       
     336        // Even though it's phantom, it still has the property that one can't be replaced with another.
     337        read(HeapObjectCount);
     338        write(HeapObjectCount);
    330339        return;
    331340
     
    376385    case CallForwardVarargs:
    377386    case ConstructVarargs:
     387    case ConstructForwardVarargs:
    378388    case ToPrimitive:
    379389    case In:
    380     case GetMyArgumentsLengthSafe:
    381     case GetMyArgumentByValSafe:
    382390    case ValueAdd:
    383391        read(World);
     
    396404       
    397405    case GetCallee:
    398         read(AbstractHeap(Variables, JSStack::Callee));
    399         def(HeapLocation(VariableLoc, AbstractHeap(Variables, JSStack::Callee)), node);
     406        read(AbstractHeap(Stack, JSStack::Callee));
     407        def(HeapLocation(StackLoc, AbstractHeap(Stack, JSStack::Callee)), node);
     408        return;
     409       
     410    case GetArgumentCount:
     411        read(AbstractHeap(Stack, JSStack::ArgumentCount));
     412        def(HeapLocation(StackPayloadLoc, AbstractHeap(Stack, JSStack::ArgumentCount)), node);
    400413        return;
    401414       
    402415    case GetLocal:
    403         read(AbstractHeap(Variables, node->local()));
    404         def(HeapLocation(VariableLoc, AbstractHeap(Variables, node->local())), node);
     416        read(AbstractHeap(Stack, node->local()));
     417        def(HeapLocation(StackLoc, AbstractHeap(Stack, node->local())), node);
    405418        return;
    406419       
    407420    case SetLocal:
    408         write(AbstractHeap(Variables, node->local()));
    409         def(HeapLocation(VariableLoc, AbstractHeap(Variables, node->local())), node->child1().node());
     421        write(AbstractHeap(Stack, node->local()));
     422        def(HeapLocation(StackLoc, AbstractHeap(Stack, node->local())), node->child1().node());
    410423        return;
    411424       
    412425    case GetStack: {
    413         AbstractHeap heap(Variables, node->stackAccessData()->local);
     426        AbstractHeap heap(Stack, node->stackAccessData()->local);
    414427        read(heap);
    415         def(HeapLocation(VariableLoc, heap), node);
     428        def(HeapLocation(StackLoc, heap), node);
    416429        return;
    417430    }
    418431       
    419432    case PutStack: {
    420         AbstractHeap heap(Variables, node->stackAccessData()->local);
     433        AbstractHeap heap(Stack, node->stackAccessData()->local);
    421434        write(heap);
    422         def(HeapLocation(VariableLoc, heap), node->child1().node());
    423         return;
    424     }
    425        
    426     case LoadVarargs:
    427         // This actually writes to local variables as well. But when it reads the array, it does
    428         // so in a way that may trigger getters or various traps.
     435        def(HeapLocation(StackLoc, heap), node->child1().node());
     436        return;
     437    }
     438       
     439    case LoadVarargs: {
    429440        read(World);
    430         write(World);
    431         return;
     441        write(Heap);
     442        LoadVarargsData* data = node->loadVarargsData();
     443        write(AbstractHeap(Stack, data->count.offset()));
     444        for (unsigned i = data->limit; i--;)
     445            write(AbstractHeap(Stack, data->start.offset() + static_cast<int>(i)));
     446        return;
     447    }
     448       
     449    case ForwardVarargs: {
     450        // We could be way more precise here.
     451        read(Stack);
     452       
     453        LoadVarargsData* data = node->loadVarargsData();
     454        write(AbstractHeap(Stack, data->count.offset()));
     455        for (unsigned i = data->limit; i--;)
     456            write(AbstractHeap(Stack, data->start.offset() + static_cast<int>(i)));
     457        return;
     458    }
    432459       
    433460    case GetLocalUnlinked:
    434         read(AbstractHeap(Variables, node->unlinkedLocal()));
    435         def(HeapLocation(VariableLoc, AbstractHeap(Variables, node->unlinkedLocal())), node);
     461        read(AbstractHeap(Stack, node->unlinkedLocal()));
     462        def(HeapLocation(StackLoc, AbstractHeap(Stack, node->unlinkedLocal())), node);
    436463        return;
    437464       
     
    466493            return;
    467494           
    468         case Array::Arguments:
    469             read(Arguments_registers);
    470             read(Variables);
    471             def(HeapLocation(IndexedPropertyLoc, Variables, node->child1(), node->child2()), node);
     495        case Array::DirectArguments:
     496            read(DirectArgumentsProperties);
     497            def(HeapLocation(IndexedPropertyLoc, DirectArgumentsProperties, node->child1(), node->child2()), node);
     498            return;
     499           
     500        case Array::ScopedArguments:
     501            read(ScopeProperties);
     502            def(HeapLocation(IndexedPropertyLoc, ScopeProperties, node->child1(), node->child2()), node);
    472503            return;
    473504           
     
    533564        return;
    534565    }
     566       
     567    case GetMyArgumentByVal: {
     568        read(Stack);
     569        // FIXME: It would be trivial to have a def here.
     570        // https://bugs.webkit.org/show_bug.cgi?id=143077
     571        return;
     572    }
    535573
    536574    case PutByValDirect:
     
    545583        case Array::Unprofiled:
    546584        case Array::Undecided:
    547         case Array::String:
    548585            // Assume the worst since we don't have profiling yet.
    549586            read(World);
     
    558595            read(World);
    559596            write(Heap);
    560             return;
    561            
    562         case Array::Arguments:
    563             read(Arguments_registers);
    564             read(MiscFields);
    565             write(Variables);
    566             def(HeapLocation(IndexedPropertyLoc, Variables, base, index), value);
    567597            return;
    568598           
     
    633663            // https://bugs.webkit.org/show_bug.cgi?id=134737
    634664            return;
     665        case Array::String:
     666        case Array::DirectArguments:
     667        case Array::ScopedArguments:
     668            DFG_CRASH(graph, node, "impossible array mode for put");
     669            return;
    635670        }
    636671        RELEASE_ASSERT_NOT_REACHED();
     
    761796            return;
    762797           
    763         case Array::Arguments:
     798        case Array::DirectArguments:
     799        case Array::ScopedArguments:
    764800            read(MiscFields);
    765801            def(HeapLocation(ArrayLengthLoc, MiscFields, node->child1()), node);
     
    774810    }
    775811       
    776     case GetClosureRegisters:
    777         read(JSEnvironmentRecord_registers);
    778         def(HeapLocation(ClosureRegistersLoc, JSEnvironmentRecord_registers, node->child1()), node);
    779         return;
    780 
    781812    case GetClosureVar:
    782         read(AbstractHeap(Variables, node->varNumber()));
    783         def(HeapLocation(ClosureVariableLoc, AbstractHeap(Variables, node->varNumber()), node->child1()), node);
     813        read(AbstractHeap(ScopeProperties, node->scopeOffset().offset()));
     814        def(HeapLocation(ClosureVariableLoc, AbstractHeap(ScopeProperties, node->scopeOffset().offset()), node->child1()), node);
    784815        return;
    785816       
    786817    case PutClosureVar:
    787         write(AbstractHeap(Variables, node->varNumber()));
    788         def(HeapLocation(ClosureVariableLoc, AbstractHeap(Variables, node->varNumber()), node->child1()), node->child3().node());
    789         return;
     818        write(AbstractHeap(ScopeProperties, node->scopeOffset().offset()));
     819        def(HeapLocation(ClosureVariableLoc, AbstractHeap(ScopeProperties, node->scopeOffset().offset()), node->child2()), node->child2().node());
     820        return;
     821       
     822    case GetFromArguments: {
     823        AbstractHeap heap(DirectArgumentsProperties, node->capturedArgumentsOffset().offset());
     824        read(heap);
     825        def(HeapLocation(DirectArgumentsLoc, heap), node);
     826        return;
     827    }
     828       
     829    case PutToArguments: {
     830        AbstractHeap heap(DirectArgumentsProperties, node->capturedArgumentsOffset().offset());
     831        write(heap);
     832        def(HeapLocation(DirectArgumentsLoc, heap), node->child2().node());
     833        return;
     834    }
    790835       
    791836    case GetGlobalVar:
    792         read(AbstractHeap(Absolute, node->registerPointer()));
    793         def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node->registerPointer())), node);
     837        read(AbstractHeap(Absolute, node->variablePointer()));
     838        def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node->variablePointer())), node);
    794839        return;
    795840       
    796841    case PutGlobalVar:
    797         write(AbstractHeap(Absolute, node->registerPointer()));
    798         def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node->registerPointer())), node->child1().node());
     842        write(AbstractHeap(Absolute, node->variablePointer()));
     843        def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node->variablePointer())), node->child1().node());
    799844        return;
    800845
     
    816861    case PhantomNewObject:
    817862    case MaterializeNewObject:
    818     case NewFunctionNoCheck:
    819863    case NewFunction:
    820     case NewFunctionExpression:
    821864        read(HeapObjectCount);
    822865        write(HeapObjectCount);
     
    870913        }
    871914       
    872     case TearOffArguments:
    873         read(Variables);
    874         write(Arguments_registers);
    875         return;
    876        
    877     case GetMyArgumentsLength:
    878         read(AbstractHeap(Variables, graph.argumentsRegisterFor(node->origin.semantic)));
    879         read(AbstractHeap(Variables, JSStack::ArgumentCount));
    880         // FIXME: We could def() this by specifying the code origin as a kind of m_info, like we
    881         // have for PureValue.
    882         // https://bugs.webkit.org/show_bug.cgi?id=134797
    883         return;
    884        
    885     case GetMyArgumentByVal:
    886         read(Variables);
    887         // FIXME: We could def() this by specifying the code origin as a kind of m_info, like we
    888         // have for PureValue.
    889         // https://bugs.webkit.org/show_bug.cgi?id=134797
    890         return;
    891        
    892     case CheckArgumentsNotCreated:
    893         read(AbstractHeap(Variables, graph.argumentsRegisterFor(node->origin.semantic)));
    894         return;
    895 
    896915    case ThrowReferenceError:
    897916        write(SideState);
  • trunk/Source/JavaScriptCore/dfg/DFGCommon.h

    r180813 r181993  
    3131#if ENABLE(DFG_JIT)
    3232
    33 #include "CodeOrigin.h"
    3433#include "Options.h"
    3534#include "VirtualRegister.h"
     
    194193    // tail. ThreadedCPS form also implies that:
    195194    //
    196     // - GetLocals and SetLocals to uncaptured variables are not redundant within
    197     //   a basic block.
     195    // - GetLocals and SetLocals are not redundant within a basic block.
    198196    //
    199197    // - All GetLocals and Flushes are linked directly to the last access point
    200     //   of the variable, which must not be another GetLocal if the variable is
    201     //   uncaptured.
     198    //   of the variable, which must not be another GetLocal.
    202199    //
    203200    // - Phantom(Phi) is not legal, but PhantomLocal is.
  • trunk/Source/JavaScriptCore/dfg/DFGCommonData.h

    r172129 r181993  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7272    CommonData()
    7373        : isStillValid(true)
    74         , machineCaptureStart(std::numeric_limits<int>::max())
    7574        , frameRegisterCount(std::numeric_limits<unsigned>::max())
    7675        , requiredRegisterCountForExit(std::numeric_limits<unsigned>::max())
     
    104103    bool isStillValid;
    105104   
    106     int machineCaptureStart;
    107     std::unique_ptr<SlowArgument[]> slowArguments;
    108 
    109105#if USE(JSVALUE32_64)
    110106    std::unique_ptr<Bag<double>> doubleConstants;
  • trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp

    r181817 r181993  
    11/*
    2  * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3030
    3131#include "DFGAbstractInterpreterInlines.h"
     32#include "DFGArgumentsUtilities.h"
    3233#include "DFGBasicBlock.h"
    3334#include "DFGGraph.h"
     
    9899            }
    99100               
    100             case CheckArgumentsNotCreated: {
    101                 if (!isEmptySpeculation(
    102                         m_state.variables().operand(
    103                             m_graph.argumentsRegisterFor(node->origin.semantic)).m_type))
    104                     break;
    105                 node->convertToPhantom();
    106                 eliminated = true;
    107                 break;
    108             }
    109                    
    110101            case CheckStructure:
    111102            case ArrayifyToStructure: {
     
    205196                }
    206197               
     198                break;
     199            }
     200               
     201            case GetMyArgumentByVal: {
     202                JSValue index = m_state.forNode(node->child2()).value();
     203                if (!index || !index.isInt32())
     204                    break;
     205               
     206                Node* arguments = node->child1().node();
     207                InlineCallFrame* inlineCallFrame = arguments->origin.semantic.inlineCallFrame;
     208               
     209                // Don't try to do anything if the index is known to be outside our static bounds. Note
     210                // that our static bounds are usually strictly larger than the dynamic bounds. The
     211                // exception is something like this, assuming foo() is not inlined:
     212                //
     213                // function foo() { return arguments[5]; }
     214                //
     215                // Here the static bound on number of arguments is 0, and we're accessing index 5. We
     216                // will not strength-reduce this to GetStack because GetStack is otherwise assumed by the
     217                // compiler to access those variables that are statically accounted for; for example if
     218                // we emitted a GetStack on arg6 we would have out-of-bounds access crashes anywhere that
     219                // uses an Operands<> map. There is not much cost to continuing to use a
     220                // GetMyArgumentByVal in such statically-out-of-bounds accesses; we just lose CFA unless
     221                // GCSE removes the access entirely.
     222                if (inlineCallFrame) {
     223                    if (index.isUInt32() >= inlineCallFrame->arguments.size() - 1)
     224                        break;
     225                } else {
     226                    if (index.isUInt32() >= m_state.variables().numberOfArguments() - 1)
     227                        break;
     228                }
     229               
     230                m_interpreter.execute(indexInBlock); // Push CFA over this node after we get the state before.
     231               
     232                StackAccessData* data;
     233                if (inlineCallFrame) {
     234                    data = m_graph.m_stackAccessData.add(
     235                        inlineCallFrame->arguments[index.asInt32() + 1].virtualRegister(), FlushedJSValue);
     236                } else {
     237                    data = m_graph.m_stackAccessData.add(
     238                        virtualRegisterForArgument(index.asInt32() + 1), FlushedJSValue);
     239                }
     240               
     241                if (inlineCallFrame && !inlineCallFrame->isVarargs()
     242                    && index.asUInt32() < inlineCallFrame->arguments.size() - 1) {
     243                    node->convertToGetStack(data);
     244                    eliminated = true;
     245                    break;
     246                }
     247               
     248                Node* length = emitCodeToGetArgumentsArrayLength(
     249                    m_insertionSet, arguments, indexInBlock, node->origin);
     250                m_insertionSet.insertNode(
     251                    indexInBlock, SpecNone, CheckInBounds, node->origin,
     252                    node->child2(), Edge(length, Int32Use));
     253                node->convertToGetStack(data);
     254                eliminated = true;
    207255                break;
    208256            }
     
    386434            }
    387435               
    388             case GetMyArgumentByVal: {
    389                 InlineCallFrame* inlineCallFrame = node->origin.semantic.inlineCallFrame;
    390                 JSValue value = m_state.forNode(node->child1()).m_value;
    391                 if (inlineCallFrame && value && value.isInt32()) {
    392                     int32_t index = value.asInt32();
    393                     if (index >= 0
    394                         && static_cast<size_t>(index + 1) < inlineCallFrame->arguments.size()) {
    395                         // Roll the interpreter over this.
    396                         m_interpreter.execute(indexInBlock);
    397                         eliminated = true;
    398                        
    399                         int operand =
    400                             inlineCallFrame->stackOffset +
    401                             m_graph.baselineCodeBlockFor(inlineCallFrame)->argumentIndexAfterCapture(index);
    402                        
    403                         m_insertionSet.insertNode(
    404                             indexInBlock, SpecNone, CheckArgumentsNotCreated, node->origin);
    405                         m_insertionSet.insertNode(
    406                             indexInBlock, SpecNone, Phantom, node->origin, node->children);
    407                        
    408                         if (m_graph.m_form == SSA)
    409                             node->convertToGetStack(m_graph.m_stackAccessData.add(VirtualRegister(operand), FlushedJSValue));
    410                         else
    411                             node->convertToGetLocalUnlinked(VirtualRegister(operand));
    412                         break;
    413                     }
    414                 }
    415                
    416                 break;
    417             }
    418                
    419436            case Check: {
    420437                alreadyHandled = true;
  • trunk/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp

    r180160 r181993  
    11/*
    2  * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    206206                node = node->child1().node();
    207207               
    208                 // FIXME: In the case that the variable is captured, we really want to be able
    209                 // to replace the variable-at-tail with the last use of the variable in the same
    210                 // way that CPS rethreading would do. The child of the GetLocal isn't necessarily
    211                 // the same as what CPS rethreading would do. For example, we may have:
    212                 //
    213                 // a: SetLocal(...) // live
    214                 // b: GetLocal(@a) // live
    215                 // c: GetLocal(@a) // dead
    216                 //
    217                 // When killing @c, the code below will set the variable-at-tail to @a, while CPS
    218                 // rethreading would have set @b. This is a benign bug, since all clients of CPS
    219                 // only use the variable-at-tail of captured variables to get the
    220                 // VariableAccessData and observe that it is in fact captured. But, this feels
    221                 // like it could cause bugs in the future.
    222                 //
    223                 // It's tempting to just dethread and then invoke CPS rethreading, but CPS
    224                 // rethreading fails to preserve exact ref-counts. So we would need a fixpoint.
    225                 // It's probably the case that this fixpoint will be guaranteed to converge after
    226                 // the second iteration (i.e. the second run of DCE will not kill anything and so
    227                 // will not need to dethread), but for now the safest approach is probably just to
    228                 // allow for this tiny bit of sloppiness.
    229                 //
    230                 // Another possible solution would be to simply say that DCE dethreads but then
    231                 // we never rethread before going to the backend. That feels intuitively right
    232                 // because it's unlikely that any of the phases after DCE in the backend rely on
    233                 // ThreadedCPS.
    234                 //
    235                 // https://bugs.webkit.org/show_bug.cgi?id=130115
    236                 ASSERT(
    237                     node->op() == Phi || node->op() == SetArgument
    238                     || node->variableAccessData()->isCaptured());
     208                ASSERT(node->op() == Phi || node->op() == SetArgument);
    239209               
    240210                if (node->shouldGenerate()) {
  • trunk/Source/JavaScriptCore/dfg/DFGDisassembler.h

    r170876 r181993  
    2929#if ENABLE(DFG_JIT)
    3030
     31#include "CodeOrigin.h"
    3132#include "DFGCommon.h"
    3233#include "DumpContext.h"
  • trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp

    r181891 r181993  
    5050    case Identity:
    5151    case GetCallee:
     52    case GetArgumentCount:
    5253    case GetLocal:
    5354    case SetLocal:
     
    99100    case GetScope:
    100101    case SkipScope:
    101     case GetClosureRegisters:
    102102    case GetClosureVar:
    103103    case PutClosureVar:
     
    123123    case LoadVarargs:
    124124    case CallForwardVarargs:
     125    case ConstructForwardVarargs:
    125126    case NativeCall:
    126127    case NativeConstruct:
     
    144145    case ToString:
    145146    case In:
    146     case PhantomArguments:
    147     case TearOffArguments:
    148     case GetMyArgumentsLength:
    149     case GetMyArgumentByVal:
    150     case GetMyArgumentsLengthSafe:
    151     case GetMyArgumentByValSafe:
    152     case CheckArgumentsNotCreated:
    153147    case Jump:
    154148    case Branch:
     
    205199    case BottomValue:
    206200    case PhantomNewObject:
     201    case PhantomDirectArguments:
     202    case PhantomClonedArguments:
     203    case GetMyArgumentByVal:
     204    case ForwardVarargs:
    207205    case PutHint:
    208206    case CheckStructureImmediate:
     
    210208    case KillStack:
    211209    case GetStack:
     210    case GetFromArguments:
     211    case PutToArguments:
    212212        return false;
    213213
    214214    case CreateActivation:
    215     case CreateArguments:
     215    case CreateDirectArguments:
     216    case CreateScopedArguments:
     217    case CreateClonedArguments:
    216218    case ToThis:
    217219    case CreateThis:
     
    227229    case NewStringObject:
    228230    case MakeRope:
    229     case NewFunctionNoCheck:
    230231    case NewFunction:
    231     case NewFunctionExpression:
    232232    case NewTypedArray:
    233233    case ThrowReferenceError:
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r181891 r181993  
    659659            case Array::ArrayStorage:
    660660            case Array::SlowPutArrayStorage:
    661             case Array::Arguments:
    662661                fixEdge<KnownCellUse>(child1);
    663662                fixEdge<Int32Use>(child2);
     
    858857        }
    859858           
    860         case GetMyArgumentByVal:
    861         case GetMyArgumentByValSafe: {
    862             fixEdge<Int32Use>(node->child1());
    863             break;
    864         }
    865            
    866859        case PutStructure: {
    867860            fixEdge<KnownCellUse>(node->child1());
     
    869862            break;
    870863        }
    871 
    872         case GetClosureVar: {
     864           
     865        case GetClosureVar:
     866        case GetFromArguments: {
    873867            fixEdge<KnownCellUse>(node->child1());
    874868            break;
    875869        }
    876870
    877         case PutClosureVar: {
     871        case PutClosureVar:
     872        case PutToArguments: {
    878873            fixEdge<KnownCellUse>(node->child1());
    879             insertStoreBarrier(m_indexInBlock, node->child1(), node->child3());
    880             break;
    881         }
    882 
    883         case GetClosureRegisters:
     874            insertStoreBarrier(m_indexInBlock, node->child1(), node->child2());
     875            break;
     876        }
     877           
    884878        case SkipScope:
    885879        case GetScope:
     
    10421036        case BooleanToNumber:
    10431037        case PhantomNewObject:
     1038        case PhantomDirectArguments:
     1039        case PhantomClonedArguments:
     1040        case ForwardVarargs:
     1041        case GetMyArgumentByVal:
    10441042        case PutHint:
    10451043        case CheckStructureImmediate:
     
    11811179        }
    11821180
     1181        case CreateScopedArguments:
    11831182        case CreateActivation:
    11841183        case NewFunction: {
    1185             fixEdge<CellUse>(node->child2());
    1186             break;
    1187         }
    1188 
    1189         case NewFunctionNoCheck:
    1190         case NewFunctionExpression: {
    11911184            fixEdge<CellUse>(node->child1());
    11921185            break;
     
    12001193        case GetLocal:
    12011194        case GetCallee:
     1195        case GetArgumentCount:
    12021196        case Flush:
    12031197        case PhantomLocal:
     
    12121206        case ConstructVarargs:
    12131207        case CallForwardVarargs:
     1208        case ConstructForwardVarargs:
    12141209        case LoadVarargs:
    12151210        case ProfileControlFlow:
     
    12271222        case IsObjectOrNull:
    12281223        case IsFunction:
    1229         case CreateArguments:
    1230         case PhantomArguments:
    1231         case TearOffArguments:
    1232         case GetMyArgumentsLength:
    1233         case GetMyArgumentsLengthSafe:
    1234         case CheckArgumentsNotCreated:
     1224        case CreateDirectArguments:
     1225        case CreateClonedArguments:
    12351226        case Jump:
    12361227        case Return:
  • trunk/Source/JavaScriptCore/dfg/DFGFlushFormat.cpp

    r164229 r181993  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5959        out.print("FlushedJSValue");
    6060        return;
    61     case FlushedArguments:
    62         out.print("FlushedArguments");
    63         return;
    6461    case ConflictingFlush:
    6562        out.print("ConflictingFlush");
  • trunk/Source/JavaScriptCore/dfg/DFGFlushFormat.h

    r180691 r181993  
    11/*
    2  * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4545    FlushedBoolean,
    4646    FlushedJSValue,
    47     FlushedArguments,
    4847    ConflictingFlush
    4948};
     
    5655    case FlushedCell:
    5756    case ConflictingFlush:
    58     case FlushedArguments:
    5957        return NodeResultJS;
    6058    case FlushedInt32:
     
    7775    case FlushedJSValue:
    7876    case ConflictingFlush:
    79     case FlushedArguments:
    8077        return UntypedUse;
    8178    case FlushedCell:
     
    117114    case FlushedBoolean:
    118115        return DataFormatBoolean;
    119     case FlushedArguments:
    120         return DataFormatArguments;
    121116    }
    122117    RELEASE_ASSERT_NOT_REACHED();
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp

    r181650 r181993  
    2929#if ENABLE(DFG_JIT)
    3030
     31#include "BytecodeKills.h"
    3132#include "BytecodeLivenessAnalysisInlines.h"
    3233#include "CodeBlock.h"
     
    6364    , m_allocator(longLivedState.m_allocator)
    6465    , m_mustHandleValues(OperandsLike, plan.mustHandleValues)
    65     , m_hasArguments(false)
    6666    , m_nextMachineLocal(0)
    67     , m_machineCaptureStart(std::numeric_limits<int>::max())
    6867    , m_fixpointState(BeforeFixpoint)
    6968    , m_structureRegistrationState(HaveNotStartedRegistering)
     
    7675    for (unsigned i = m_mustHandleValues.size(); i--;)
    7776        m_mustHandleValues[i] = freezeFragile(plan.mustHandleValues[i]);
    78    
    79     for (unsigned i = m_codeBlock->m_numVars; i--;) {
    80         if (m_codeBlock->isCaptured(virtualRegisterForLocal(i)))
    81             m_outermostCapturedVars.set(i);
    82     }
    8377}
    8478
     
    217211    if (node->hasArithMode())
    218212        out.print(comma, node->arithMode());
    219     if (node->hasVarNumber())
    220         out.print(comma, node->varNumber());
     213    if (node->hasScopeOffset())
     214        out.print(comma, node->scopeOffset());
     215    if (node->hasDirectArgumentsOffset())
     216        out.print(comma, node->capturedArgumentsOffset());
    221217    if (node->hasRegisterPointer())
    222         out.print(comma, "global", globalObjectFor(node->origin.semantic)->findRegisterIndex(node->registerPointer()), "(", RawPointer(node->registerPointer()), ")");
     218        out.print(comma, "global", globalObjectFor(node->origin.semantic)->findVariableIndex(node->variablePointer()), "(", RawPointer(node->variablePointer()), ")");
    223219    if (node->hasIdentifier())
    224220        out.print(comma, "id", node->identifierNumber(), "{", identifiers()[node->identifierNumber()], "}");
     
    229225    if (node->hasStructure())
    230226        out.print(comma, inContext(*node->structure(), context));
    231     if (node->hasTransition())
     227    if (node->hasTransition()) {
    232228        out.print(comma, pointerDumpInContext(node->transition(), context));
     229#if USE(JSVALUE64)
     230        out.print(", ID:", node->transition()->next->id());
     231#else
     232        out.print(", ID:", RawPointer(node->transition()->next));
     233#endif
     234    }
    233235    if (node->hasCellOperand()) {
    234236        if (!node->cellOperand()->value() || !node->cellOperand()->value().isCell())
     
    749751void Graph::substituteGetLocal(BasicBlock& block, unsigned startIndexInBlock, VariableAccessData* variableAccessData, Node* newGetLocal)
    750752{
    751     if (variableAccessData->isCaptured()) {
    752         // Let CSE worry about this one.
    753         return;
    754     }
    755753    for (unsigned indexInBlock = startIndexInBlock; indexInBlock < block.size(); ++indexInBlock) {
    756754        Node* node = block[indexInBlock];
     
    870868{
    871869    return livenessFor(baselineCodeBlockFor(inlineCallFrame));
     870}
     871
     872BytecodeKills& Graph::killsFor(CodeBlock* codeBlock)
     873{
     874    HashMap<CodeBlock*, std::unique_ptr<BytecodeKills>>::iterator iter = m_bytecodeKills.find(codeBlock);
     875    if (iter != m_bytecodeKills.end())
     876        return *iter->value;
     877   
     878    std::unique_ptr<BytecodeKills> kills = std::make_unique<BytecodeKills>();
     879    codeBlock->livenessAnalysis().computeKills(*kills);
     880    BytecodeKills& result = *kills;
     881    m_bytecodeKills.add(codeBlock, WTF::move(kills));
     882    return result;
     883}
     884
     885BytecodeKills& Graph::killsFor(InlineCallFrame* inlineCallFrame)
     886{
     887    return killsFor(baselineCodeBlockFor(inlineCallFrame));
    872888}
    873889
     
    10081024}
    10091025
    1010 JSValue Graph::tryGetConstantClosureVar(JSValue base, VirtualRegister reg)
     1026JSValue Graph::tryGetConstantClosureVar(JSValue base, ScopeOffset offset)
    10111027{
    10121028    if (!base)
     
    10231039        return JSValue();
    10241040   
    1025     SymbolTableEntry* entry = symbolTable->entryFor(locker, reg);
     1041    SymbolTableEntry* entry = symbolTable->entryFor(locker, offset);
    10261042    if (!entry)
    10271043        return JSValue();
     
    10411057}
    10421058
    1043 JSValue Graph::tryGetConstantClosureVar(const AbstractValue& value, VirtualRegister reg)
    1044 {
    1045     return tryGetConstantClosureVar(value.m_value, reg);
    1046 }
    1047 
    1048 JSValue Graph::tryGetConstantClosureVar(Node* node, VirtualRegister reg)
     1059JSValue Graph::tryGetConstantClosureVar(const AbstractValue& value, ScopeOffset offset)
     1060{
     1061    return tryGetConstantClosureVar(value.m_value, offset);
     1062}
     1063
     1064JSValue Graph::tryGetConstantClosureVar(Node* node, ScopeOffset offset)
    10491065{
    10501066    if (!node->hasConstant())
    10511067        return JSValue();
    1052     return tryGetConstantClosureVar(node->asJSValue(), reg);
    1053 }
    1054 
    1055 WriteBarrierBase<Unknown>* Graph::tryGetRegisters(Node* node)
    1056 {
    1057     JSLexicalEnvironment* lexicalEnvironment = node->dynamicCastConstant<JSLexicalEnvironment*>();
    1058     if (!lexicalEnvironment)
    1059         return 0;
    1060     return lexicalEnvironment->registers();
     1068    return tryGetConstantClosureVar(node->asJSValue(), offset);
    10611069}
    10621070
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.h

    r180989 r181993  
    316316    }
    317317   
    318     VirtualRegister bytecodeRegisterForArgument(CodeOrigin codeOrigin, int argument)
    319     {
    320         return VirtualRegister(
    321             codeOrigin.inlineCallFrame->stackOffset +
    322             baselineCodeBlockFor(codeOrigin)->argumentIndexAfterCapture(argument));
    323     }
    324    
    325318    static const char *opName(NodeType);
    326319   
     
    368361    }
    369362   
    370     const BitVector& capturedVarsFor(InlineCallFrame* inlineCallFrame)
    371     {
    372         if (!inlineCallFrame)
    373             return m_outermostCapturedVars;
    374         return inlineCallFrame->capturedVars;
     363    SymbolTable* symbolTableFor(InlineCallFrame* inlineCallFrame)
     364    {
     365        return baselineCodeBlockFor(inlineCallFrame)->symbolTable();
     366    }
     367   
     368    SymbolTable* symbolTableFor(const CodeOrigin& codeOrigin)
     369    {
     370        return symbolTableFor(codeOrigin.inlineCallFrame);
    375371    }
    376372   
     
    407403    }
    408404   
    409     bool usesArguments(InlineCallFrame* inlineCallFrame)
    410     {
    411         if (!inlineCallFrame)
    412             return m_profiledBlock->usesArguments();
    413        
    414         return baselineCodeBlockForInlineCallFrame(inlineCallFrame)->usesArguments();
    415     }
    416    
    417     VirtualRegister argumentsRegisterFor(InlineCallFrame* inlineCallFrame)
    418     {
    419         if (!inlineCallFrame)
    420             return m_profiledBlock->argumentsRegister();
    421        
    422         return VirtualRegister(baselineCodeBlockForInlineCallFrame(
    423             inlineCallFrame)->argumentsRegister().offset() +
    424             inlineCallFrame->stackOffset);
    425     }
    426    
    427     VirtualRegister argumentsRegisterFor(const CodeOrigin& codeOrigin)
    428     {
    429         return argumentsRegisterFor(codeOrigin.inlineCallFrame);
    430     }
    431    
    432     VirtualRegister machineArgumentsRegisterFor(InlineCallFrame* inlineCallFrame)
    433     {
    434         if (!inlineCallFrame)
    435             return m_codeBlock->argumentsRegister();
    436        
    437         return inlineCallFrame->argumentsRegister;
    438     }
    439    
    440     VirtualRegister machineArgumentsRegisterFor(const CodeOrigin& codeOrigin)
    441     {
    442         return machineArgumentsRegisterFor(codeOrigin.inlineCallFrame);
    443     }
    444    
    445     VirtualRegister uncheckedArgumentsRegisterFor(InlineCallFrame* inlineCallFrame)
    446     {
    447         if (!inlineCallFrame)
    448             return m_profiledBlock->uncheckedArgumentsRegister();
    449        
    450         CodeBlock* codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
    451         if (!codeBlock->usesArguments())
    452             return VirtualRegister();
    453        
    454         return VirtualRegister(codeBlock->argumentsRegister().offset() +
    455             inlineCallFrame->stackOffset);
    456     }
    457    
    458     VirtualRegister uncheckedArgumentsRegisterFor(const CodeOrigin& codeOrigin)
    459     {
    460         return uncheckedArgumentsRegisterFor(codeOrigin.inlineCallFrame);
    461     }
    462    
    463405    VirtualRegister activationRegister()
    464406    {
     
    483425    ValueProfile* valueProfileFor(Node*);
    484426    MethodOfGettingAValueProfile methodOfGettingAValueProfileFor(Node*);
    485    
    486     bool usesArguments() const
    487     {
    488         return m_codeBlock->usesArguments();
    489     }
    490427   
    491428    BlockIndex numBlocks() const { return m_blocks.size(); }
     
    723660    }
    724661   
     662    bool uses(Node* node, Node* child)
     663    {
     664        bool result = false;
     665        doToChildren(node, [&] (Edge edge) { result |= edge == child; });
     666        return result;
     667    }
     668   
    725669    Profiler::Compilation* compilation() { return m_plan.compilation.get(); }
    726670   
     
    731675    FullBytecodeLiveness& livenessFor(InlineCallFrame*);
    732676    bool isLiveInBytecode(VirtualRegister, CodeOrigin);
     677   
     678    BytecodeKills& killsFor(CodeBlock*);
     679    BytecodeKills& killsFor(InlineCallFrame*);
    733680   
    734681    unsigned frameRegisterCount();
     
    742689    JSValue tryGetConstantProperty(const AbstractValue&, PropertyOffset);
    743690   
    744     JSValue tryGetConstantClosureVar(JSValue base, VirtualRegister);
    745     JSValue tryGetConstantClosureVar(const AbstractValue&, VirtualRegister);
    746     JSValue tryGetConstantClosureVar(Node*, VirtualRegister);
    747     WriteBarrierBase<Unknown>* tryGetRegisters(Node*);
     691    JSValue tryGetConstantClosureVar(JSValue base, ScopeOffset);
     692    JSValue tryGetConstantClosureVar(const AbstractValue&, ScopeOffset);
     693    JSValue tryGetConstantClosureVar(Node*, ScopeOffset);
    748694   
    749695    JSArrayBufferView* tryGetFoldableView(Node*);
     
    827773    Vector<InlineVariableData, 4> m_inlineVariableData;
    828774    HashMap<CodeBlock*, std::unique_ptr<FullBytecodeLiveness>> m_bytecodeLiveness;
    829     bool m_hasArguments;
    830     HashSet<ExecutableBase*> m_executablesWhoseArgumentsEscaped;
    831     BitVector m_lazyVars;
     775    HashMap<CodeBlock*, std::unique_ptr<BytecodeKills>> m_bytecodeKills;
    832776    Dominators m_dominators;
    833777    PrePostNumbering m_prePostNumbering;
     
    836780    unsigned m_nextMachineLocal;
    837781    unsigned m_parameterSlots;
    838     int m_machineCaptureStart;
    839     std::unique_ptr<SlowArgument[]> m_slowArguments;
    840     BitVector m_outermostCapturedVars;
    841782
    842783#if USE(JSVALUE32_64)
  • trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp

    r180587 r181993  
    11/*
    2  * Copyright (C) 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    8181        return;
    8282       
    83     case VariableLoc:
    84         out.print("VariableLoc");
     83    case StackLoc:
     84        out.print("StackLoc");
     85        return;
     86       
     87    case StackPayloadLoc:
     88        out.print("StackPayloadLoc");
    8589        return;
    8690       
     
    97101        return;
    98102       
    99     case ClosureRegistersLoc:
    100         out.print("ClosureRegistersLoc");
     103    case ClosureVariableLoc:
     104        out.print("ClosureVariableLoc");
    101105        return;
    102106       
    103     case ClosureVariableLoc:
    104         out.print("ClosureVariableLoc");
     107    case DirectArgumentsLoc:
     108        out.print("DirectArgumentsLoc");
    105109        return;
    106110       
     
    123127    case InstanceOfLoc:
    124128        out.print("InstanceOfLoc");
    125         return;
    126        
    127     case MyArgumentByValLoc:
    128         out.print("MyArgumentByValLoc");
    129         return;
    130        
    131     case MyArgumentsLengthLoc:
    132         out.print("MyArgumentsLengthLoc");
    133129        return;
    134130       
  • trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.h

    r180587 r181993  
    11/*
    2  * Copyright (C) 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4141    ButterflyLoc,
    4242    CheckHasInstanceLoc,
    43     ClosureRegistersLoc,
    4443    ClosureVariableLoc,
     44    DirectArgumentsLoc,
    4545    GetterLoc,
    4646    GlobalVariableLoc,
     
    5252    IsFunctionLoc,
    5353    IsObjectOrNullLoc,
    54     MyArgumentByValLoc,
    55     MyArgumentsLengthLoc,
    5654    NamedPropertyLoc,
    5755    SetterLoc,
     
    6058    TypedArrayByteOffsetLoc,
    6159    VarInjectionWatchpointLoc,
    62     VariableLoc
     60    StackLoc,
     61    StackPayloadLoc
    6362};
    6463
  • trunk/Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp

    r180160 r181993  
    11/*
    2  * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    130130    }
    131131    for (size_t i = 0; i < root->valuesAtHead.numberOfLocals(); ++i) {
    132         Node* node = root->variablesAtHead.local(i);
    133         if (node && node->variableAccessData()->isCaptured())
    134             root->valuesAtHead.local(i).makeHeapTop();
    135         else
    136             root->valuesAtHead.local(i).clear();
     132        root->valuesAtHead.local(i).clear();
    137133        root->valuesAtTail.local(i).clear();
    138134    }
     
    264260    AbstractValue source;
    265261   
    266     if (node->variableAccessData()->isCaptured()) {
    267         // If it's captured then we know that whatever value was stored into the variable last is the
    268         // one we care about. This is true even if the variable at tail is dead, which might happen if
    269         // the last thing we did to the variable was a GetLocal and then ended up not using the
    270         // GetLocal's result.
    271        
     262    switch (node->op()) {
     263    case Phi:
     264    case SetArgument:
     265    case PhantomLocal:
     266    case Flush:
     267        // The block transfers the value from head to tail.
    272268        source = inVariable;
    273     } else {
    274         switch (node->op()) {
    275         case Phi:
    276         case SetArgument:
    277         case PhantomLocal:
    278         case Flush:
    279             // The block transfers the value from head to tail.
    280             source = inVariable;
    281             break;
    282            
    283         case GetLocal:
    284             // The block refines the value with additional speculations.
    285             source = forNode(node);
    286             break;
    287            
    288         case SetLocal:
    289             // The block sets the variable, and potentially refines it, both
    290             // before and after setting it.
    291             source = forNode(node->child1());
    292             if (node->variableAccessData()->flushFormat() == FlushedDouble)
    293                 RELEASE_ASSERT(!(source.m_type & ~SpecFullDouble));
    294             break;
    295        
    296         default:
    297             RELEASE_ASSERT_NOT_REACHED();
    298             break;
    299         }
     269        break;
     270           
     271    case GetLocal:
     272        // The block refines the value with additional speculations.
     273        source = forNode(node);
     274        break;
     275           
     276    case SetLocal:
     277        // The block sets the variable, and potentially refines it, both
     278        // before and after setting it.
     279        source = forNode(node->child1());
     280        if (node->variableAccessData()->flushFormat() == FlushedDouble)
     281            RELEASE_ASSERT(!(source.m_type & ~SpecFullDouble));
     282        break;
     283       
     284    default:
     285        RELEASE_ASSERT_NOT_REACHED();
     286        break;
    300287    }
    301288   
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp

    r181990 r181993  
    162162        m_jitCode->common.inlineCallFrames = m_graph.m_plan.inlineCallFrames;
    163163   
    164     m_jitCode->common.machineCaptureStart = m_graph.m_machineCaptureStart;
    165     m_jitCode->common.slowArguments = WTF::move(m_graph.m_slowArguments);
    166 
    167164#if USE(JSVALUE32_64)
    168165    m_jitCode->common.doubleConstants = WTF::move(m_graph.m_doubleConstants);
  • trunk/Source/JavaScriptCore/dfg/DFGMayExit.cpp

    r181650 r181993  
    7272    case GetLocal:
    7373    case LoopHint:
    74     case PhantomArguments:
    7574    case Phi:
    7675    case Upsilon:
     
    8382    case GetStack:
    8483    case GetCallee:
     84    case GetArgumentCount:
    8585    case GetScope:
    8686    case PhantomLocal:
  • trunk/Source/JavaScriptCore/dfg/DFGMinifiedID.h

    r164424 r181993  
    3838class MinifiedNode;
    3939class ValueSource;
     40struct Node;
    4041
    4142class MinifiedID {
     
    99100
    100101template<typename T> struct HashTraits;
    101 template<> struct HashTraits<JSC::DFG::MinifiedID> : SimpleClassHashTraits<JSC::DFG::MinifiedID> { };
     102template<> struct HashTraits<JSC::DFG::MinifiedID> : SimpleClassHashTraits<JSC::DFG::MinifiedID> {
     103    static const bool emptyValueIsZero = false;
     104};
    102105
    103106} // namespace WTF
  • trunk/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp

    r171613 r181993  
    11/*
    2  * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4343        result.m_info = JSValue::encode(node->asJSValue());
    4444    else {
    45         ASSERT(node->op() == PhantomArguments);
    46         result.m_info = 0;
     45        ASSERT(node->op() == PhantomDirectArguments || node->op() == PhantomClonedArguments);
     46        result.m_info = bitwise_cast<uintptr_t>(node->origin.semantic.inlineCallFrame);
    4747    }
    4848    return result;
  • trunk/Source/JavaScriptCore/dfg/DFGMinifiedNode.h

    r171613 r181993  
    11/*
    2  * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4343    case Int52Constant:
    4444    case DoubleConstant:
    45     case PhantomArguments:
     45    case PhantomDirectArguments:
     46    case PhantomClonedArguments:
    4647        return true;
    4748    default:
     
    6667    }
    6768   
     69    bool hasInlineCallFrame() const { return hasInlineCallFrame(m_op); }
     70   
     71    InlineCallFrame* inlineCallFrame() const
     72    {
     73        return bitwise_cast<InlineCallFrame*>(static_cast<uintptr_t>(m_info));
     74    }
     75   
    6876    static MinifiedID getID(MinifiedNode* node) { return node->id(); }
    6977    static bool compareByNodeIndex(const MinifiedNode& a, const MinifiedNode& b)
     
    7684    {
    7785        return type == JSConstant || type == Int52Constant || type == DoubleConstant;
     86    }
     87   
     88    static bool hasInlineCallFrame(NodeType type)
     89    {
     90        return type == PhantomDirectArguments || type == PhantomClonedArguments;
    7891    }
    7992   
  • trunk/Source/JavaScriptCore/dfg/DFGNode.cpp

    r181650 r181993  
    9595}
    9696
     97void Node::convertToIdentityOn(Node* child)
     98{
     99    children.reset();
     100    child1() = child->defaultEdge();
     101    NodeFlags output = canonicalResultRepresentation(this->result());
     102    NodeFlags input = canonicalResultRepresentation(child->result());
     103    if (output == input) {
     104        setOpAndDefaultFlags(Identity);
     105        setResult(output);
     106        return;
     107    }
     108    switch (output) {
     109    case NodeResultDouble:
     110        RELEASE_ASSERT(input == NodeResultInt52 || input == NodeResultJS);
     111        setOpAndDefaultFlags(DoubleRep);
     112        return;
     113    case NodeResultInt52:
     114        RELEASE_ASSERT(input == NodeResultDouble || input == NodeResultJS);
     115        setOpAndDefaultFlags(Int52Rep);
     116        return;
     117    case NodeResultJS:
     118        RELEASE_ASSERT(input == NodeResultDouble || input == NodeResultInt52);
     119        setOpAndDefaultFlags(ValueRep);
     120        return;
     121    default:
     122        RELEASE_ASSERT_NOT_REACHED();
     123        return;
     124    }
     125}
     126
    97127void Node::convertToPutHint(const PromotedLocationDescriptor& descriptor, Node* base, Node* value)
    98128{
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r181650 r181993  
    430430
    431431    void convertToIdentity();
     432    void convertToIdentityOn(Node*);
    432433
    433434    bool mustGenerate()
     
    448449    }
    449450   
    450     bool isPhantomArguments()
    451     {
    452         return op() == PhantomArguments;
    453     }
    454    
    455451    bool hasConstant()
    456452    {
     
    459455        case DoubleConstant:
    460456        case Int52Constant:
    461         case PhantomArguments:
    462             return true;
     457            return true;
     458           
     459        case PhantomDirectArguments:
     460        case PhantomClonedArguments:
     461            // These pretend to be the empty value constant for the benefit of the DFG backend, which
     462            // otherwise wouldn't take kindly to a node that doesn't compute a value.
     463            return true;
     464           
    463465        default:
    464466            return false;
     
    469471    {
    470472        ASSERT(hasConstant());
    471         if (op() == PhantomArguments)
     473       
     474        if (op() == PhantomDirectArguments || op() == PhantomClonedArguments) {
     475            // These pretend to be the empty value constant for the benefit of the DFG backend, which
     476            // otherwise wouldn't take kindly to a node that doesn't compute a value.
    472477            return FrozenValue::emptySingleton();
     478        }
     479       
    473480        return bitwise_cast<FrozenValue*>(m_opInfo);
    474481    }
     
    935942    }
    936943   
    937     bool hasVarNumber()
     944    bool hasScopeOffset()
    938945    {
    939946        return op() == GetClosureVar || op() == PutClosureVar;
    940947    }
    941948
    942     int varNumber()
    943     {
    944         ASSERT(hasVarNumber());
    945         return m_opInfo;
     949    ScopeOffset scopeOffset()
     950    {
     951        ASSERT(hasScopeOffset());
     952        return ScopeOffset(m_opInfo);
     953    }
     954   
     955    bool hasDirectArgumentsOffset()
     956    {
     957        return op() == GetFromArguments || op() == PutToArguments;
     958    }
     959   
     960    DirectArgumentsOffset capturedArgumentsOffset()
     961    {
     962        ASSERT(hasDirectArgumentsOffset());
     963        return DirectArgumentsOffset(m_opInfo);
    946964    }
    947965   
     
    951969    }
    952970   
    953     WriteBarrier<Unknown>* registerPointer()
     971    WriteBarrier<Unknown>* variablePointer()
    954972    {
    955973        return bitwise_cast<WriteBarrier<Unknown>*>(m_opInfo);
     
    962980        case CallForwardVarargs:
    963981        case ConstructVarargs:
     982        case ConstructForwardVarargs:
    964983            return true;
    965984        default:
     
    976995    bool hasLoadVarargsData()
    977996    {
    978         return op() == LoadVarargs;
     997        return op() == LoadVarargs || op() == ForwardVarargs;
    979998    }
    980999   
     
    11351154        case GetByIdFlush:
    11361155        case GetByVal:
    1137         case GetMyArgumentByVal:
    1138         case GetMyArgumentByValSafe:
    11391156        case Call:
    11401157        case Construct:
     
    11471164        case MultiGetByOffset:
    11481165        case GetClosureVar:
     1166        case GetFromArguments:
    11491167        case ArrayPop:
    11501168        case ArrayPush:
     
    11771195        case NativeConstruct:
    11781196        case NativeCall:
    1179         case NewFunctionNoCheck:
    11801197        case NewFunction:
    1181         case NewFunctionExpression:
    11821198            return true;
    11831199        default:
     
    13311347    ObjectMaterializationData& objectMaterializationData()
    13321348    {
     1349        ASSERT(hasObjectMaterializationData());
    13331350        return *reinterpret_cast<ObjectMaterializationData*>(m_opInfo);
    13341351    }
     
    13381355        switch (op()) {
    13391356        case PhantomNewObject:
     1357            return true;
     1358        default:
     1359            return false;
     1360        }
     1361    }
     1362   
     1363    bool isPhantomAllocation()
     1364    {
     1365        switch (op()) {
     1366        case PhantomNewObject:
     1367        case PhantomDirectArguments:
     1368        case PhantomClonedArguments:
    13401369            return true;
    13411370        default:
     
    14521481        case MovHint:
    14531482        case ZombieHint:
    1454         case PhantomArguments:
    14551483            return true;
    14561484        case Phantom:
     
    16721700    }
    16731701   
    1674     bool shouldSpeculateArguments()
    1675     {
    1676         return isArgumentsSpeculation(prediction());
     1702    bool shouldSpeculateDirectArguments()
     1703    {
     1704        return isDirectArgumentsSpeculation(prediction());
     1705    }
     1706   
     1707    bool shouldSpeculateScopedArguments()
     1708    {
     1709        return isScopedArgumentsSpeculation(prediction());
    16771710    }
    16781711   
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r181891 r181993  
    5151    macro(CreateThis, NodeResultJS) /* Note this is not MustGenerate since we're returning it anyway. */ \
    5252    macro(GetCallee, NodeResultJS) \
     53    macro(GetArgumentCount, NodeResultInt32) \
    5354    \
    5455    /* Nodes for local variable access. These nodes are linked together using Phi nodes. */\
     
    152153    /* opcodes use VarArgs beause they may have up to 4 children. */\
    153154    macro(GetByVal, NodeResultJS | NodeMustGenerate) \
     155    macro(GetMyArgumentByVal, NodeResultJS | NodeMustGenerate) \
    154156    macro(LoadVarargs, NodeMustGenerate) \
     157    macro(ForwardVarargs, NodeMustGenerate) \
    155158    macro(PutByValDirect, NodeMustGenerate | NodeHasVarArgs) \
    156159    macro(PutByVal, NodeMustGenerate | NodeHasVarArgs) \
     
    184187    macro(GetScope, NodeResultJS) \
    185188    macro(SkipScope, NodeResultJS) \
    186     macro(GetClosureRegisters, NodeResultStorage) \
    187189    macro(GetClosureVar, NodeResultJS) \
    188190    macro(PutClosureVar, NodeMustGenerate) \
     
    225227    macro(CallForwardVarargs, NodeResultJS | NodeMustGenerate) \
    226228    macro(ConstructVarargs, NodeResultJS | NodeMustGenerate) \
     229    macro(ConstructForwardVarargs, NodeResultJS | NodeMustGenerate) \
    227230    macro(NativeCall, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
    228231    macro(NativeConstruct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
     
    265268    macro(ProfileControlFlow, NodeMustGenerate) \
    266269    \
    267     /* Nodes used for activations. Activation support works by having it anchored at */\
    268     /* epilgoues via TearOffActivation, and all CreateActivation nodes kept alive by */\
    269     /* being threaded with each other. */\
    270270    macro(CreateActivation, NodeResultJS) \
    271271    \
    272     /* Nodes used for arguments. Similar to lexical environment support, only it makes even less */\
    273     /* sense. */\
    274     macro(CreateArguments, NodeResultJS) \
    275     macro(PhantomArguments, NodeResultJS) \
    276     macro(TearOffArguments, NodeMustGenerate) \
    277     macro(GetMyArgumentsLength, NodeResultJS | NodeMustGenerate) \
    278     macro(GetMyArgumentByVal, NodeResultJS | NodeMustGenerate) \
    279     macro(GetMyArgumentsLengthSafe, NodeResultJS | NodeMustGenerate) \
    280     macro(GetMyArgumentByValSafe, NodeResultJS | NodeMustGenerate) \
    281     macro(CheckArgumentsNotCreated, NodeMustGenerate) \
    282     \
    283     /* Nodes for creating functions. */\
    284     macro(NewFunctionNoCheck, NodeResultJS) \
     272    macro(CreateDirectArguments, NodeResultJS) \
     273    macro(PhantomDirectArguments, NodeResultJS) \
     274    macro(CreateScopedArguments, NodeResultJS) \
     275    macro(CreateClonedArguments, NodeResultJS) \
     276    macro(PhantomClonedArguments, NodeResultJS) \
     277    macro(GetFromArguments, NodeResultJS) \
     278    macro(PutToArguments, NodeMustGenerate) \
     279    \
    285280    macro(NewFunction, NodeResultJS) \
    286     macro(NewFunctionExpression, NodeResultJS) \
    287281    \
    288282    /* These aren't terminals but always exit */ \
  • trunk/Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp

    r181650 r181993  
    8383                    calculator.executeNode(block->at(nodeIndex));
    8484               
     85                // FIXME: we should probably prune by liveness here.
     86                // https://bugs.webkit.org/show_bug.cgi?id=143078
    8587                calculator.m_availability.prune();
    86                
     88
    8789                if (calculator.m_availability == block->ssa->availabilityAtTail)
    8890                    continue;
     
    156158    }
    157159       
    158     case LoadVarargs: {
     160    case LoadVarargs:
     161    case ForwardVarargs: {
    159162        LoadVarargsData* data = node->loadVarargsData();
    160163        m_availability.m_locals.operand(data->count) =
     
    167170    }
    168171       
     172    case PhantomDirectArguments:
     173    case PhantomClonedArguments: {
     174        InlineCallFrame* inlineCallFrame = node->origin.semantic.inlineCallFrame;
     175        if (!inlineCallFrame) {
     176            // We don't need to record anything about how the arguments are to be recovered. It's just a
     177            // given that we can read them from the stack.
     178            break;
     179        }
     180       
     181        if (inlineCallFrame->isVarargs()) {
     182            // Record how to read each argument and the argument count.
     183            Availability argumentCount =
     184                m_availability.m_locals.operand(inlineCallFrame->stackOffset + JSStack::ArgumentCount);
     185           
     186            m_availability.m_heap.set(PromotedHeapLocation(ArgumentCountPLoc, node), argumentCount);
     187        }
     188       
     189        if (inlineCallFrame->isClosureCall) {
     190            Availability callee = m_availability.m_locals.operand(
     191                inlineCallFrame->stackOffset + JSStack::Callee);
     192            m_availability.m_heap.set(PromotedHeapLocation(ArgumentsCalleePLoc, node), callee);
     193        }
     194       
     195        for (unsigned i = 0; i < inlineCallFrame->arguments.size() - 1; ++i) {
     196            Availability argument = m_availability.m_locals.operand(
     197                inlineCallFrame->stackOffset + CallFrame::argumentOffset(i));
     198           
     199            m_availability.m_heap.set(PromotedHeapLocation(ArgumentPLoc, node, i), argument);
     200        }
     201        break;
     202    }
     203       
    169204    case PutHint: {
    170205        m_availability.m_heap.set(
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp

    r181841 r181993  
    11/*
    2  * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011-2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4040
    4141namespace JSC { namespace DFG {
     42
     43void OSRExitCompiler::emitRestoreArguments(const Operands<ValueRecovery>& operands)
     44{
     45    HashMap<MinifiedID, int> alreadyAllocatedArguments; // Maps phantom arguments node ID to operand.
     46    for (size_t index = 0; index < operands.size(); ++index) {
     47        const ValueRecovery& recovery = operands[index];
     48        int operand = operands.operandForIndex(index);
     49       
     50        if (recovery.technique() != DirectArgumentsThatWereNotCreated
     51            && recovery.technique() != ClonedArgumentsThatWereNotCreated)
     52            continue;
     53       
     54        MinifiedID id = recovery.nodeID();
     55        auto iter = alreadyAllocatedArguments.find(id);
     56        if (iter != alreadyAllocatedArguments.end()) {
     57            JSValueRegs regs = JSValueRegs::withTwoAvailableRegs(GPRInfo::regT0, GPRInfo::regT1);
     58            m_jit.loadValue(CCallHelpers::addressFor(iter->value), regs);
     59            m_jit.storeValue(regs, CCallHelpers::addressFor(operand));
     60            continue;
     61        }
     62       
     63        InlineCallFrame* inlineCallFrame =
     64            m_jit.codeBlock()->jitCode()->dfg()->minifiedDFG.at(id)->inlineCallFrame();
     65
     66        int stackOffset;
     67        if (inlineCallFrame)
     68            stackOffset = inlineCallFrame->stackOffset;
     69        else
     70            stackOffset = 0;
     71       
     72        if (!inlineCallFrame || inlineCallFrame->isClosureCall) {
     73            m_jit.loadPtr(
     74                AssemblyHelpers::addressFor(stackOffset + JSStack::Callee),
     75                GPRInfo::regT0);
     76        } else {
     77            m_jit.move(
     78                AssemblyHelpers::TrustedImmPtr(inlineCallFrame->calleeRecovery.constant().asCell()),
     79                GPRInfo::regT0);
     80        }
     81       
     82        if (!inlineCallFrame || inlineCallFrame->isVarargs()) {
     83            m_jit.load32(
     84                AssemblyHelpers::payloadFor(stackOffset + JSStack::ArgumentCount),
     85                GPRInfo::regT1);
     86        } else {
     87            m_jit.move(
     88                AssemblyHelpers::TrustedImm32(inlineCallFrame->arguments.size()),
     89                GPRInfo::regT1);
     90        }
     91       
     92        m_jit.setupArgumentsWithExecState(
     93            AssemblyHelpers::TrustedImmPtr(inlineCallFrame), GPRInfo::regT0, GPRInfo::regT1);
     94        switch (recovery.technique()) {
     95        case DirectArgumentsThatWereNotCreated:
     96            m_jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(operationCreateDirectArgumentsDuringExit)), GPRInfo::nonArgGPR0);
     97            break;
     98        case ClonedArgumentsThatWereNotCreated:
     99            m_jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(operationCreateClonedArgumentsDuringExit)), GPRInfo::nonArgGPR0);
     100            break;
     101        default:
     102            RELEASE_ASSERT_NOT_REACHED();
     103            break;
     104        }
     105        m_jit.call(GPRInfo::nonArgGPR0);
     106        m_jit.storeCell(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(operand));
     107       
     108        alreadyAllocatedArguments.add(id, operand);
     109    }
     110}
    42111
    43112extern "C" {
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.h

    r164424 r181993  
    11/*
    2  * Copyright (C) 2011 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5050
    5151private:
    52 #if !ASSERT_DISABLED
    53     static unsigned badIndex() { return static_cast<unsigned>(-1); };
    54 #endif
    55    
    56     void initializePoisoned(unsigned size)
    57     {
    58 #if ASSERT_DISABLED
    59         m_poisonScratchIndices.resize(size);
    60 #else
    61         m_poisonScratchIndices.fill(badIndex(), size);
    62 #endif
    63     }
    64    
    65     unsigned poisonIndex(unsigned index)
    66     {
    67         unsigned result = m_poisonScratchIndices[index];
    68         ASSERT(result != badIndex());
    69         return result;
    70     }
     52    void emitRestoreArguments(const Operands<ValueRecovery>&);
    7153   
    7254    CCallHelpers& m_jit;
    73     Vector<unsigned> m_poisonScratchIndices;
    7455};
    7556
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp

    r181835 r181993  
    11/*
    2  * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3939void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecovery>& operands, SpeculationRecovery* recovery)
    4040{
    41     // 1) Pro-forma stuff.
     41    // Pro-forma stuff.
    4242    if (Options::printEachOSRExit()) {
    4343        SpeculationFailureDebugInfo* debugInfo = new SpeculationFailureDebugInfo;
     
    4949    }
    5050   
    51     // 2) Perform speculation recovery. This only comes into play when an operation
    52     //    starts mutating state before verifying the speculation it has already made.
     51    // Perform speculation recovery. This only comes into play when an operation
     52    // starts mutating state before verifying the speculation it has already made.
    5353   
    5454    if (recovery) {
     
    6666    }
    6767
    68     // 3) Refine some value profile, if appropriate.
     68    // Refine some value profile, if appropriate.
    6969   
    7070    if (!!exit.m_jsValueSource) {
     
    103103                scratch2 = AssemblyHelpers::selectScratchGPR(usedRegister1, usedRegister2, scratch1);
    104104               
    105 #if CPU(ARM64)
    106                 m_jit.pushToSave(scratch1);
    107                 m_jit.pushToSave(scratch2);
    108 #else
    109105                m_jit.push(scratch1);
    110106                m_jit.push(scratch2);
    111 #endif
    112107               
    113108                GPRReg value;
     
    125120                m_jit.or32(scratch2, AssemblyHelpers::AbsoluteAddress(arrayProfile->addressOfArrayModes()));
    126121               
    127 #if CPU(ARM64)
    128                 m_jit.popToRestore(scratch2);
    129                 m_jit.popToRestore(scratch1);
    130 #else
    131122                m_jit.pop(scratch2);
    132123                m_jit.pop(scratch1);
    133 #endif
    134124            }
    135125        }
     
    142132                GPRReg scratch = AssemblyHelpers::selectScratchGPR(exit.m_jsValueSource.base());
    143133               
    144 #if CPU(ARM64)
    145                 m_jit.pushToSave(scratch);
    146 #else
    147134                m_jit.push(scratch);
    148 #endif
    149135
    150136                m_jit.load32(exit.m_jsValueSource.asAddress(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), scratch);
     
    153139                m_jit.store32(scratch, &bitwise_cast<EncodedValueDescriptor*>(bucket)->asBits.payload);
    154140               
    155 #if CPU(ARM64)
    156                 m_jit.popToRestore(scratch);
    157 #else
    158141                m_jit.pop(scratch);
    159 #endif
    160142            } else if (exit.m_jsValueSource.hasKnownTag()) {
    161143                m_jit.store32(AssemblyHelpers::TrustedImm32(exit.m_jsValueSource.tag()), &bitwise_cast<EncodedValueDescriptor*>(bucket)->asBits.tag);
     
    171153    // do this simple approach.
    172154
    173     // 4) Save all state from GPRs into the scratch buffer.
     155    // Save all state from GPRs into the scratch buffer.
    174156   
    175157    ScratchBuffer* scratchBuffer = m_jit.vm()->scratchBufferForSize(sizeof(EncodedJSValue) * operands.size());
     
    204186    // Now all GPRs are free to reuse.
    205187   
    206     // 5) Save all state from FPRs into the scratch buffer.
     188    // Save all state from FPRs into the scratch buffer.
    207189   
    208190    for (size_t index = 0; index < operands.size(); ++index) {
     
    222204    // Now all FPRs are free to reuse.
    223205   
    224     // 6) Save all state from the stack into the scratch buffer. For simplicity we
    225     //    do this even for state that's already in the right place on the stack.
    226     //    It makes things simpler later.
     206    // Save all state from the stack into the scratch buffer. For simplicity we
     207    // do this even for state that's already in the right place on the stack.
     208    // It makes things simpler later.
    227209   
    228210    for (size_t index = 0; index < operands.size(); ++index) {
     
    262244        CCallHelpers::framePointerRegister, CCallHelpers::stackPointerRegister);
    263245   
    264     // 7) Do all data format conversions and store the results into the stack.
    265    
    266     bool haveArguments = false;
     246    // Do all data format conversions and store the results into the stack.
    267247   
    268248    for (size_t index = 0; index < operands.size(); ++index) {
     
    343323            break;
    344324           
    345         case ArgumentsThatWereNotCreated:
    346             haveArguments = true;
    347             m_jit.store32(
    348                 AssemblyHelpers::TrustedImm32(JSValue().tag()),
    349                 AssemblyHelpers::tagFor(operand));
    350             m_jit.store32(
    351                 AssemblyHelpers::TrustedImm32(JSValue().payload()),
    352                 AssemblyHelpers::payloadFor(operand));
    353             break;
    354            
    355         default:
    356             break;
    357         }
    358     }
    359    
    360     // 8) Adjust the old JIT's execute counter. Since we are exiting OSR, we know
    361     //    that all new calls into this code will go to the new JIT, so the execute
    362     //    counter only affects call frames that performed OSR exit and call frames
    363     //    that were still executing the old JIT at the time of another call frame's
    364     //    OSR exit. We want to ensure that the following is true:
    365     //
    366     //    (a) Code the performs an OSR exit gets a chance to reenter optimized
    367     //        code eventually, since optimized code is faster. But we don't
    368     //        want to do such reentery too aggressively (see (c) below).
    369     //
    370     //    (b) If there is code on the call stack that is still running the old
    371     //        JIT's code and has never OSR'd, then it should get a chance to
    372     //        perform OSR entry despite the fact that we've exited.
    373     //
    374     //    (c) Code the performs an OSR exit should not immediately retry OSR
    375     //        entry, since both forms of OSR are expensive. OSR entry is
    376     //        particularly expensive.
    377     //
    378     //    (d) Frequent OSR failures, even those that do not result in the code
    379     //        running in a hot loop, result in recompilation getting triggered.
    380     //
    381     //    To ensure (c), we'd like to set the execute counter to
    382     //    counterValueForOptimizeAfterWarmUp(). This seems like it would endanger
    383     //    (a) and (b), since then every OSR exit would delay the opportunity for
    384     //    every call frame to perform OSR entry. Essentially, if OSR exit happens
    385     //    frequently and the function has few loops, then the counter will never
    386     //    become non-negative and OSR entry will never be triggered. OSR entry
    387     //    will only happen if a loop gets hot in the old JIT, which does a pretty
    388     //    good job of ensuring (a) and (b). But that doesn't take care of (d),
    389     //    since each speculation failure would reset the execute counter.
    390     //    So we check here if the number of speculation failures is significantly
    391     //    larger than the number of successes (we want 90% success rate), and if
    392     //    there have been a large enough number of failures. If so, we set the
    393     //    counter to 0; otherwise we set the counter to
    394     //    counterValueForOptimizeAfterWarmUp().
     325        case DirectArgumentsThatWereNotCreated:
     326        case ClonedArgumentsThatWereNotCreated:
     327            // Don't do this, yet.
     328            break;
     329           
     330        default:
     331            break;
     332        }
     333    }
     334   
     335    // Now that things on the stack are recovered, do the arguments recovery. We assume that arguments
     336    // recoveries don't recursively refer to each other. But, we don't try to assume that they only
     337    // refer to certain ranges of locals. Hence why we need to do this here, once the stack is sensible.
     338    // Note that we also roughly assume that the arguments might still be materialized outside of its
     339    // inline call frame scope - but for now the DFG wouldn't do that.
     340   
     341    emitRestoreArguments(operands);
     342
     343    // Adjust the old JIT's execute counter. Since we are exiting OSR, we know
     344    // that all new calls into this code will go to the new JIT, so the execute
     345    // counter only affects call frames that performed OSR exit and call frames
     346    // that were still executing the old JIT at the time of another call frame's
     347    // OSR exit. We want to ensure that the following is true:
     348    //
     349    // (a) Code the performs an OSR exit gets a chance to reenter optimized
     350    //     code eventually, since optimized code is faster. But we don't
     351    //     want to do such reentery too aggressively (see (c) below).
     352    //
     353    // (b) If there is code on the call stack that is still running the old
     354    //     JIT's code and has never OSR'd, then it should get a chance to
     355    //     perform OSR entry despite the fact that we've exited.
     356    //
     357    // (c) Code the performs an OSR exit should not immediately retry OSR
     358    //     entry, since both forms of OSR are expensive. OSR entry is
     359    //     particularly expensive.
     360    //
     361    // (d) Frequent OSR failures, even those that do not result in the code
     362    //     running in a hot loop, result in recompilation getting triggered.
     363    //
     364    // To ensure (c), we'd like to set the execute counter to
     365    // counterValueForOptimizeAfterWarmUp(). This seems like it would endanger
     366    // (a) and (b), since then every OSR exit would delay the opportunity for
     367    // every call frame to perform OSR entry. Essentially, if OSR exit happens
     368    // frequently and the function has few loops, then the counter will never
     369    // become non-negative and OSR entry will never be triggered. OSR entry
     370    // will only happen if a loop gets hot in the old JIT, which does a pretty
     371    // good job of ensuring (a) and (b). But that doesn't take care of (d),
     372    // since each speculation failure would reset the execute counter.
     373    // So we check here if the number of speculation failures is significantly
     374    // larger than the number of successes (we want 90% success rate), and if
     375    // there have been a large enough number of failures. If so, we set the
     376    // counter to 0; otherwise we set the counter to
     377    // counterValueForOptimizeAfterWarmUp().
    395378   
    396379    handleExitCounts(m_jit, exit);
    397380   
    398     // 9) Reify inlined call frames.
     381    // Reify inlined call frames.
    399382   
    400383    reifyInlinedCallFrames(m_jit, exit);
    401384   
    402     // 10) Create arguments if necessary and place them into the appropriate aliased
    403     //     registers.
    404    
    405     if (haveArguments) {
    406         ArgumentsRecoveryGenerator argumentsRecovery;
    407 
    408         for (size_t index = 0; index < operands.size(); ++index) {
    409             const ValueRecovery& recovery = operands[index];
    410             if (recovery.technique() != ArgumentsThatWereNotCreated)
    411                 continue;
    412             argumentsRecovery.generateFor(
    413                 operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
    414         }
    415     }
    416 
    417     // 12) And finish.
     385    // And finish.
    418386    adjustAndJumpToTarget(m_jit, exit);
    419387}
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp

    r181835 r181993  
    4343    m_jit.jitAssertTagsInPlace();
    4444
    45     // 1) Pro-forma stuff.
     45    // Pro-forma stuff.
    4646    if (Options::printEachOSRExit()) {
    4747        SpeculationFailureDebugInfo* debugInfo = new SpeculationFailureDebugInfo;
     
    5353    }
    5454   
    55     // 2) Perform speculation recovery. This only comes into play when an operation
    56     //    starts mutating state before verifying the speculation it has already made.
     55    // Perform speculation recovery. This only comes into play when an operation
     56    // starts mutating state before verifying the speculation it has already made.
    5757   
    5858    if (recovery) {
     
    7272    }
    7373
    74     // 3) Refine some array and/or value profile, if appropriate.
     74    // Refine some array and/or value profile, if appropriate.
    7575   
    7676    if (!!exit.m_jsValueSource) {
     
    9898                scratch2 = AssemblyHelpers::selectScratchGPR(usedRegister, scratch1);
    9999               
    100 #if CPU(ARM64)
    101                 m_jit.pushToSave(scratch1);
    102                 m_jit.pushToSave(scratch2);
    103 #else
    104                 m_jit.push(scratch1);
    105                 m_jit.push(scratch2);
    106 #endif
     100                if (isARM64()) {
     101                    m_jit.pushToSave(scratch1);
     102                    m_jit.pushToSave(scratch2);
     103                } else {
     104                    m_jit.push(scratch1);
     105                    m_jit.push(scratch2);
     106                }
    107107               
    108108                GPRReg value;
     
    120120                m_jit.or32(scratch2, AssemblyHelpers::AbsoluteAddress(arrayProfile->addressOfArrayModes()));
    121121               
    122 #if CPU(ARM64)
    123                 m_jit.popToRestore(scratch2);
    124                 m_jit.popToRestore(scratch1);
    125 #else
    126                 m_jit.pop(scratch2);
    127                 m_jit.pop(scratch1);
    128 #endif
     122                if (isARM64()) {
     123                    m_jit.popToRestore(scratch2);
     124                    m_jit.popToRestore(scratch1);
     125                } else {
     126                    m_jit.pop(scratch2);
     127                    m_jit.pop(scratch1);
     128                }
    129129            }
    130130        }
     
    180180    // features in the future and it will make it harder to reason about bugs.
    181181
    182     // 4) Save all state from GPRs into the scratch buffer.
     182    // Save all state from GPRs into the scratch buffer.
    183183   
    184184    ScratchBuffer* scratchBuffer = m_jit.vm()->scratchBufferForSize(sizeof(EncodedJSValue) * operands.size());
     
    204204    // And voila, all GPRs are free to reuse.
    205205   
    206     // 5) Save all state from FPRs into the scratch buffer.
     206    // Save all state from FPRs into the scratch buffer.
    207207   
    208208    for (size_t index = 0; index < operands.size(); ++index) {
     
    222222    // Now, all FPRs are also free.
    223223   
    224     // 6) Save all state from the stack into the scratch buffer. For simplicity we
    225     //    do this even for state that's already in the right place on the stack.
    226     //    It makes things simpler later.
     224    // Save all state from the stack into the scratch buffer. For simplicity we
     225    // do this even for state that's already in the right place on the stack.
     226    // It makes things simpler later.
    227227
    228228    for (size_t index = 0; index < operands.size(); ++index) {
     
    254254        CCallHelpers::framePointerRegister, CCallHelpers::stackPointerRegister);
    255255   
    256     // 7) Do all data format conversions and store the results into the stack.
    257    
    258     bool haveArguments = false;
     256    // Do all data format conversions and store the results into the stack.
    259257   
    260258    for (size_t index = 0; index < operands.size(); ++index) {
     
    311309            break;
    312310           
    313         case ArgumentsThatWereNotCreated:
    314             haveArguments = true;
    315             // We can't restore this yet but we can make sure that the stack appears
    316             // sane.
    317             m_jit.store64(
    318                 AssemblyHelpers::TrustedImm64(JSValue::encode(JSValue())),
    319                 AssemblyHelpers::addressFor(operand));
    320             break;
    321            
    322         default:
    323             break;
    324         }
    325     }
    326    
    327     // 8) Adjust the old JIT's execute counter. Since we are exiting OSR, we know
    328     //    that all new calls into this code will go to the new JIT, so the execute
    329     //    counter only affects call frames that performed OSR exit and call frames
    330     //    that were still executing the old JIT at the time of another call frame's
    331     //    OSR exit. We want to ensure that the following is true:
    332     //
    333     //    (a) Code the performs an OSR exit gets a chance to reenter optimized
    334     //        code eventually, since optimized code is faster. But we don't
    335     //        want to do such reentery too aggressively (see (c) below).
    336     //
    337     //    (b) If there is code on the call stack that is still running the old
    338     //        JIT's code and has never OSR'd, then it should get a chance to
    339     //        perform OSR entry despite the fact that we've exited.
    340     //
    341     //    (c) Code the performs an OSR exit should not immediately retry OSR
    342     //        entry, since both forms of OSR are expensive. OSR entry is
    343     //        particularly expensive.
    344     //
    345     //    (d) Frequent OSR failures, even those that do not result in the code
    346     //        running in a hot loop, result in recompilation getting triggered.
    347     //
    348     //    To ensure (c), we'd like to set the execute counter to
    349     //    counterValueForOptimizeAfterWarmUp(). This seems like it would endanger
    350     //    (a) and (b), since then every OSR exit would delay the opportunity for
    351     //    every call frame to perform OSR entry. Essentially, if OSR exit happens
    352     //    frequently and the function has few loops, then the counter will never
    353     //    become non-negative and OSR entry will never be triggered. OSR entry
    354     //    will only happen if a loop gets hot in the old JIT, which does a pretty
    355     //    good job of ensuring (a) and (b). But that doesn't take care of (d),
    356     //    since each speculation failure would reset the execute counter.
    357     //    So we check here if the number of speculation failures is significantly
    358     //    larger than the number of successes (we want 90% success rate), and if
    359     //    there have been a large enough number of failures. If so, we set the
    360     //    counter to 0; otherwise we set the counter to
    361     //    counterValueForOptimizeAfterWarmUp().
     311        case DirectArgumentsThatWereNotCreated:
     312        case ClonedArgumentsThatWereNotCreated:
     313            // Don't do this, yet.
     314            break;
     315           
     316        default:
     317            RELEASE_ASSERT_NOT_REACHED();
     318            break;
     319        }
     320    }
     321   
     322    // Now that things on the stack are recovered, do the arguments recovery. We assume that arguments
     323    // recoveries don't recursively refer to each other. But, we don't try to assume that they only
     324    // refer to certain ranges of locals. Hence why we need to do this here, once the stack is sensible.
     325    // Note that we also roughly assume that the arguments might still be materialized outside of its
     326    // inline call frame scope - but for now the DFG wouldn't do that.
     327   
     328    emitRestoreArguments(operands);
     329   
     330    // Adjust the old JIT's execute counter. Since we are exiting OSR, we know
     331    // that all new calls into this code will go to the new JIT, so the execute
     332    // counter only affects call frames that performed OSR exit and call frames
     333    // that were still executing the old JIT at the time of another call frame's
     334    // OSR exit. We want to ensure that the following is true:
     335    //
     336    // (a) Code the performs an OSR exit gets a chance to reenter optimized
     337    //     code eventually, since optimized code is faster. But we don't
     338    //     want to do such reentery too aggressively (see (c) below).
     339    //
     340    // (b) If there is code on the call stack that is still running the old
     341    //     JIT's code and has never OSR'd, then it should get a chance to
     342    //     perform OSR entry despite the fact that we've exited.
     343    //
     344    // (c) Code the performs an OSR exit should not immediately retry OSR
     345    //     entry, since both forms of OSR are expensive. OSR entry is
     346    //     particularly expensive.
     347    //
     348    // (d) Frequent OSR failures, even those that do not result in the code
     349    //     running in a hot loop, result in recompilation getting triggered.
     350    //
     351    // To ensure (c), we'd like to set the execute counter to
     352    // counterValueForOptimizeAfterWarmUp(). This seems like it would endanger
     353    // (a) and (b), since then every OSR exit would delay the opportunity for
     354    // every call frame to perform OSR entry. Essentially, if OSR exit happens
     355    // frequently and the function has few loops, then the counter will never
     356    // become non-negative and OSR entry will never be triggered. OSR entry
     357    // will only happen if a loop gets hot in the old JIT, which does a pretty
     358    // good job of ensuring (a) and (b). But that doesn't take care of (d),
     359    // since each speculation failure would reset the execute counter.
     360    // So we check here if the number of speculation failures is significantly
     361    // larger than the number of successes (we want 90% success rate), and if
     362    // there have been a large enough number of failures. If so, we set the
     363    // counter to 0; otherwise we set the counter to
     364    // counterValueForOptimizeAfterWarmUp().
    362365   
    363366    handleExitCounts(m_jit, exit);
    364367   
    365     // 9) Reify inlined call frames.
     368    // Reify inlined call frames.
    366369   
    367370    reifyInlinedCallFrames(m_jit, exit);
    368371   
    369     // 10) Create arguments if necessary and place them into the appropriate aliased
    370     //     registers.
    371    
    372     if (haveArguments) {
    373         ArgumentsRecoveryGenerator argumentsRecovery;
    374 
    375         for (size_t index = 0; index < operands.size(); ++index) {
    376             const ValueRecovery& recovery = operands[index];
    377             if (recovery.technique() != ArgumentsThatWereNotCreated)
    378                 continue;
    379             argumentsRecovery.generateFor(
    380                 operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
    381         }
    382     }
    383 
    384     // 12) And finish.
     372    // And finish.
    385373    adjustAndJumpToTarget(m_jit, exit);
    386374}
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp

    r181835 r181993  
    2929#if ENABLE(DFG_JIT)
    3030
    31 #include "Arguments.h"
    3231#include "DFGJITCode.h"
    3332#include "DFGOperations.h"
     
    207206        if (!inlineCallFrame->isClosureCall)
    208207            jit.store64(AssemblyHelpers::TrustedImm64(JSValue::encode(JSValue(inlineCallFrame->calleeConstant()))), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::Callee)));
    209        
    210         // Leave the captured arguments in regT3.
    211         if (baselineCodeBlock->usesArguments())
    212             jit.loadPtr(AssemblyHelpers::addressFor(VirtualRegister(inlineCallFrame->stackOffset + unmodifiedArgumentsRegister(baselineCodeBlock->argumentsRegister()).offset())), GPRInfo::regT3);
    213208#else // USE(JSVALUE64) // so this is the 32-bit part
    214209        jit.storePtr(callerFrameGPR, AssemblyHelpers::addressForByteOffset(inlineCallFrame->callerFrameOffset()));
     
    219214        if (!inlineCallFrame->isClosureCall)
    220215            jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->calleeConstant()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::Callee)));
    221 
    222         // Leave the captured arguments in regT3.
    223         if (baselineCodeBlock->usesArguments())
    224             jit.loadPtr(AssemblyHelpers::payloadFor(VirtualRegister(inlineCallFrame->stackOffset + unmodifiedArgumentsRegister(baselineCodeBlock->argumentsRegister()).offset())), GPRInfo::regT3);
    225216#endif // USE(JSVALUE64) // ending the #else part, so directly above is the 32-bit part
    226        
    227         if (baselineCodeBlock->usesArguments()) {
    228             AssemblyHelpers::Jump noArguments = jit.branchTestPtr(AssemblyHelpers::Zero, GPRInfo::regT3);
    229             jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
    230             jit.storePtr(GPRInfo::regT0, AssemblyHelpers::Address(GPRInfo::regT3, Arguments::offsetOfRegisters()));
    231             noArguments.link(&jit);
    232         }
    233217    }
    234218
     
    300284}
    301285
    302 ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator() { }
    303 ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator() { }
    304 
    305 void ArgumentsRecoveryGenerator::generateFor(
    306     int operand, CodeOrigin codeOrigin, CCallHelpers& jit)
    307 {
    308     // Find the right inline call frame.
    309     InlineCallFrame* inlineCallFrame = 0;
    310     for (InlineCallFrame* current = codeOrigin.inlineCallFrame;
    311          current;
    312          current = current->caller.inlineCallFrame) {
    313         if (current->stackOffset >= operand) {
    314             inlineCallFrame = current;
    315             break;
    316         }
    317     }
    318 
    319     if (!jit.baselineCodeBlockFor(inlineCallFrame)->usesArguments())
    320         return;
    321     VirtualRegister argumentsRegister = jit.baselineArgumentsRegisterFor(inlineCallFrame);
    322     if (m_didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
    323         // We know this call frame optimized out an arguments object that
    324         // the baseline JIT would have created. Do that creation now.
    325         if (inlineCallFrame) {
    326             jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
    327             jit.setupArguments(GPRInfo::regT0);
    328         } else
    329             jit.setupArgumentsExecState();
    330         jit.move(
    331             AssemblyHelpers::TrustedImmPtr(
    332                 bitwise_cast<void*>(operationCreateArgumentsDuringOSRExit)),
    333             GPRInfo::nonArgGPR0);
    334 #if USE(JSVALUE64)
    335         jit.call(GPRInfo::nonArgGPR0);
    336         jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
    337         jit.store64(
    338             GPRInfo::returnValueGPR,
    339             AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
    340         jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
    341 #else // USE(JSVALUE64) -> so the 32_64 part
    342         jit.call(GPRInfo::nonArgGPR0);
    343         jit.store32(
    344             AssemblyHelpers::TrustedImm32(JSValue::CellTag),
    345             AssemblyHelpers::tagFor(argumentsRegister));
    346         jit.store32(
    347             GPRInfo::returnValueGPR,
    348             AssemblyHelpers::payloadFor(argumentsRegister));
    349         jit.store32(
    350             AssemblyHelpers::TrustedImm32(JSValue::CellTag),
    351             AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
    352         jit.store32(
    353             GPRInfo::returnValueGPR,
    354             AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
    355         jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
    356 #endif // USE(JSVALUE64)
    357     }
    358 
    359 #if USE(JSVALUE64)
    360     jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
    361     jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
    362 #else // USE(JSVALUE64) -> so the 32_64 part
    363     jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
    364     jit.store32(
    365         AssemblyHelpers::TrustedImm32(JSValue::CellTag),
    366         AssemblyHelpers::tagFor(operand));
    367     jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
    368 #endif // USE(JSVALUE64)
    369 }
    370    
    371286} } // namespace JSC::DFG
    372287
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h

    r164923 r181993  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3838void adjustAndJumpToTarget(CCallHelpers&, const OSRExitBase&);
    3939
    40 class ArgumentsRecoveryGenerator {
    41 public:
    42     ArgumentsRecoveryGenerator();
    43     ~ArgumentsRecoveryGenerator();
    44    
    45     void generateFor(int operand, CodeOrigin, CCallHelpers&);
    46    
    47 private:
    48     HashSet<InlineCallFrame*, DefaultHash<InlineCallFrame*>::Hash,
    49         NullableHashTraits<InlineCallFrame*>> m_didCreateArgumentsObject;
    50 };
    51 
    5240} } // namespace JSC::DFG
    5341
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r181814 r181993  
    2727#include "DFGOperations.h"
    2828
    29 #include "Arguments.h"
    3029#include "ButterflyInlines.h"
     30#include "ClonedArguments.h"
    3131#include "CodeBlock.h"
    3232#include "CommonSlowPaths.h"
     
    3939#include "DFGToFTLForOSREntryDeferredCompilationCallback.h"
    4040#include "DFGWorklist.h"
     41#include "DirectArguments.h"
    4142#include "FTLForOSREntryJITCode.h"
    4243#include "FTLOSREntry.h"
     
    4647#include "JIT.h"
    4748#include "JITExceptions.h"
     49#include "JSCInlines.h"
    4850#include "JSLexicalEnvironment.h"
    49 #include "VM.h"
    5051#include "JSNameScope.h"
    5152#include "ObjectConstructor.h"
    52 #include "JSCInlines.h"
    5353#include "Repatch.h"
     54#include "ScopedArguments.h"
    5455#include "StringConstructor.h"
    5556#include "Symbol.h"
    5657#include "TypeProfilerLog.h"
    5758#include "TypedArrayInlines.h"
     59#include "VM.h"
    5860#include <wtf/InlineASM.h>
    5961
     
    747749}
    748750
    749 JSCell* JIT_OPERATION operationCreateInlinedArguments(
    750     ExecState* exec, InlineCallFrame* inlineCallFrame)
    751 {
    752     VM& vm = exec->vm();
    753     NativeCallFrameTracer tracer(&vm, exec);
    754     // NB: This needs to be exceedingly careful with top call frame tracking, since it
    755     // may be called from OSR exit, while the state of the call stack is bizarre.
    756     Arguments* result = Arguments::create(vm, exec, inlineCallFrame);
    757     ASSERT(!vm.exception());
     751JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState* exec, Structure* structure, JSScope* scope, SymbolTable* table)
     752{
     753    VM& vm = exec->vm();
     754    NativeCallFrameTracer tracer(&vm, exec);
     755    return JSLexicalEnvironment::create(vm, structure, scope, table);
     756}
     757
     758JSCell* JIT_OPERATION operationCreateDirectArguments(ExecState* exec, Structure* structure, int32_t length, int32_t minCapacity)
     759{
     760    VM& vm = exec->vm();
     761    NativeCallFrameTracer target(&vm, exec);
     762    DirectArguments* result = DirectArguments::create(
     763        vm, structure, length, std::max(length, minCapacity));
     764    // The caller will store to this object without barriers. Most likely, at this point, this is
     765    // still a young object and so no barriers are needed. But it's good to be careful anyway,
     766    // since the GC should be allowed to do crazy (like pretenuring, for example).
     767    vm.heap.writeBarrier(result);
    758768    return result;
    759769}
    760770
    761 void JIT_OPERATION operationTearOffInlinedArguments(
    762     ExecState* exec, JSCell* argumentsCell, JSCell* activationCell, InlineCallFrame* inlineCallFrame)
    763 {
    764     ASSERT_UNUSED(activationCell, !activationCell); // Currently, we don't inline functions with activations.
    765     jsCast<Arguments*>(argumentsCell)->tearOff(exec, inlineCallFrame);
    766 }
    767 
    768 EncodedJSValue JIT_OPERATION operationGetArgumentByVal(ExecState* exec, int32_t argumentsRegister, int32_t index)
    769 {
    770     VM& vm = exec->vm();
    771     NativeCallFrameTracer tracer(&vm, exec);
    772 
    773     JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue();
    774    
    775     // If there are no arguments, and we're accessing out of bounds, then we have to create the
    776     // arguments in case someone has installed a getter on a numeric property.
    777     if (!argumentsValue) {
    778         JSLexicalEnvironment* lexicalEnvironment = exec->lexicalEnvironmentOrNullptr();
    779         exec->uncheckedR(argumentsRegister) = argumentsValue = Arguments::create(exec->vm(), exec, lexicalEnvironment);
    780     }
    781    
    782     return JSValue::encode(argumentsValue.get(exec, index));
    783 }
    784 
    785 EncodedJSValue JIT_OPERATION operationGetInlinedArgumentByVal(
    786     ExecState* exec, int32_t argumentsRegister, InlineCallFrame* inlineCallFrame, int32_t index)
    787 {
    788     VM& vm = exec->vm();
    789     NativeCallFrameTracer tracer(&vm, exec);
    790 
    791     JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue();
    792    
    793     // If there are no arguments, and we're accessing out of bounds, then we have to create the
    794     // arguments in case someone has installed a getter on a numeric property.
    795     if (!argumentsValue) {
    796         exec->uncheckedR(argumentsRegister) = argumentsValue =
    797             Arguments::create(exec->vm(), exec, inlineCallFrame);
    798     }
    799    
    800     return JSValue::encode(argumentsValue.get(exec, index));
    801 }
    802 
    803 JSCell* JIT_OPERATION operationNewFunctionNoCheck(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
    804 {
    805     ASSERT(functionExecutable->inherits(FunctionExecutable::info()));
    806     VM& vm = exec->vm();
    807     NativeCallFrameTracer tracer(&vm, exec);
    808     return JSFunction::create(vm, static_cast<FunctionExecutable*>(functionExecutable), scope);
     771JSCell* JIT_OPERATION operationCreateScopedArguments(ExecState* exec, Structure* structure, Register* argumentStart, int32_t length, JSFunction* callee, JSLexicalEnvironment* scope)
     772{
     773    VM& vm = exec->vm();
     774    NativeCallFrameTracer target(&vm, exec);
     775   
     776    // We could pass the ScopedArgumentsTable* as an argument. We currently don't because I
     777    // didn't feel like changing the max number of arguments for a slow path call from 6 to 7.
     778    ScopedArgumentsTable* table = scope->symbolTable()->arguments();
     779   
     780    return ScopedArguments::createByCopyingFrom(
     781        vm, structure, argumentStart, length, callee, table, scope);
     782}
     783
     784JSCell* JIT_OPERATION operationCreateClonedArguments(ExecState* exec, Structure* structure, Register* argumentStart, int32_t length, JSFunction* callee)
     785{
     786    VM& vm = exec->vm();
     787    NativeCallFrameTracer target(&vm, exec);
     788    return ClonedArguments::createByCopyingFrom(
     789        exec, structure, argumentStart, length, callee);
     790}
     791
     792JSCell* JIT_OPERATION operationCreateDirectArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, int32_t argumentCount)
     793{
     794    VM& vm = exec->vm();
     795    NativeCallFrameTracer target(&vm, exec);
     796   
     797    DeferGCForAWhile deferGC(vm.heap);
     798   
     799    CodeBlock* codeBlock;
     800    if (inlineCallFrame)
     801        codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
     802    else
     803        codeBlock = exec->codeBlock();
     804   
     805    unsigned length = argumentCount - 1;
     806    unsigned capacity = std::max(length, static_cast<unsigned>(codeBlock->numParameters() - 1));
     807    DirectArguments* result = DirectArguments::create(
     808        vm, codeBlock->globalObject()->directArgumentsStructure(), length, capacity);
     809   
     810    result->callee().set(vm, result, callee);
     811   
     812    Register* arguments =
     813        exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
     814        CallFrame::argumentOffset(0);
     815    for (unsigned i = length; i--;)
     816        result->setIndexQuickly(vm, i, arguments[i].jsValue());
     817   
     818    return result;
     819}
     820
     821JSCell* JIT_OPERATION operationCreateClonedArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, int32_t argumentCount)
     822{
     823    VM& vm = exec->vm();
     824    NativeCallFrameTracer target(&vm, exec);
     825   
     826    DeferGCForAWhile deferGC(vm.heap);
     827   
     828    CodeBlock* codeBlock;
     829    if (inlineCallFrame)
     830        codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
     831    else
     832        codeBlock = exec->codeBlock();
     833   
     834    unsigned length = argumentCount - 1;
     835    ClonedArguments* result = ClonedArguments::createEmpty(
     836        vm, codeBlock->globalObject()->outOfBandArgumentsStructure(), callee);
     837   
     838    Register* arguments =
     839        exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
     840        CallFrame::argumentOffset(0);
     841    for (unsigned i = length; i--;)
     842        result->putDirectIndex(exec, i, arguments[i].jsValue());
     843   
     844    result->putDirect(vm, vm.propertyNames->length, jsNumber(length));
     845   
     846    return result;
    809847}
    810848
     
    10171055
    10181056    set->notifyWrite(vm, value, "Executed NotifyWrite");
     1057}
     1058
     1059void JIT_OPERATION operationThrowStackOverflowForVarargs(ExecState* exec)
     1060{
     1061    VM& vm = exec->vm();
     1062    NativeCallFrameTracer tracer(&vm, exec);
     1063    throwStackOverflowError(exec);
    10191064}
    10201065
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r180587 r181993  
    9797size_t JIT_OPERATION operationCompareStrictEqCell(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
    9898size_t JIT_OPERATION operationCompareStrictEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
    99 JSCell* JIT_OPERATION operationCreateInlinedArguments(ExecState*, InlineCallFrame*) WTF_INTERNAL;
    100 void JIT_OPERATION operationTearOffInlinedArguments(ExecState*, JSCell*, JSCell*, InlineCallFrame*) WTF_INTERNAL;
    101 EncodedJSValue JIT_OPERATION operationGetInlinedArgumentByVal(ExecState*, int32_t, InlineCallFrame*, int32_t) WTF_INTERNAL;
    102 EncodedJSValue JIT_OPERATION operationGetArgumentByVal(ExecState*, int32_t, int32_t) WTF_INTERNAL;
    103 JSCell* JIT_OPERATION operationNewFunctionNoCheck(ExecState*, JSScope*, JSCell*) WTF_INTERNAL;
     99JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState*, Structure*, JSScope*, SymbolTable*);
     100JSCell* JIT_OPERATION operationCreateDirectArguments(ExecState*, Structure*, int32_t length, int32_t minCapacity);
     101JSCell* JIT_OPERATION operationCreateDirectArgumentsDuringExit(ExecState*, InlineCallFrame*, JSFunction*, int32_t argumentCount);
     102JSCell* JIT_OPERATION operationCreateScopedArguments(ExecState*, Structure*, Register* argumentStart, int32_t length, JSFunction* callee, JSLexicalEnvironment*);
     103JSCell* JIT_OPERATION operationCreateClonedArgumentsDuringExit(ExecState*, InlineCallFrame*, JSFunction*, int32_t argumentCount);
     104JSCell* JIT_OPERATION operationCreateClonedArguments(ExecState*, Structure*, Register* argumentStart, int32_t length, JSFunction* callee);
    104105double JIT_OPERATION operationFModOnInts(int32_t, int32_t) WTF_INTERNAL;
    105106size_t JIT_OPERATION operationIsObjectOrNull(ExecState*, EncodedJSValue) WTF_INTERNAL;
     
    126127char* JIT_OPERATION operationSwitchString(ExecState*, size_t tableIndex, JSString*);
    127128void JIT_OPERATION operationNotifyWrite(ExecState*, VariableWatchpointSet*, EncodedJSValue);
     129void JIT_OPERATION operationThrowStackOverflowForVarargs(ExecState*) WTF_INTERNAL;
    128130int32_t JIT_OPERATION operationSizeOfVarargs(ExecState*, EncodedJSValue arguments, int32_t firstVarArgOffset);
    129131void JIT_OPERATION operationLoadVarargs(ExecState*, int32_t firstElementDest, EncodedJSValue arguments, int32_t offset, int32_t length, int32_t mandatoryMinimum);
  • trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp

    r181990 r181993  
    2929#if ENABLE(DFG_JIT)
    3030
    31 #include "DFGArgumentsSimplificationPhase.h"
     31#include "DFGArgumentsEliminationPhase.h"
    3232#include "DFGBackwardsPropagationPhase.h"
    3333#include "DFGByteCodeParser.h"
     
    6868#include "DFGUnificationPhase.h"
    6969#include "DFGValidate.h"
     70#include "DFGVarargsForwardingPhase.h"
    7071#include "DFGVirtualRegisterAllocationPhase.h"
    7172#include "DFGWatchpointCollectionPhase.h"
     
    221222        validate(dfg);
    222223   
     224    if (Options::dumpGraphAfterParsing()) {
     225        dataLog("Graph after parsing:\n");
     226        dfg.dump();
     227    }
     228   
    223229    performCPSRethreading(dfg);
    224230    performUnification(dfg);
     
    258264    performStrengthReduction(dfg);
    259265    performLocalCSE(dfg);
    260     performCPSRethreading(dfg); // Canonicalize PhantomLocal to Phantom
    261     performArgumentsSimplification(dfg);
    262     performCPSRethreading(dfg); // This should do nothing, if arguments simplification did nothing.
     266    performCPSRethreading(dfg);
    263267    performCFA(dfg);
    264268    performConstantFolding(dfg);
     
    271275   
    272276    performCPSRethreading(dfg);
     277    if (!isFTL(mode)) {
     278        // Only run this if we're not FTLing, because currently for a LoadVarargs that is forwardable and
     279        // in a non-varargs inlined call frame, this will generate ForwardVarargs while the FTL
     280        // ArgumentsEliminationPhase will create a sequence of GetStack+PutStacks. The GetStack+PutStack
     281        // sequence then gets sunk, eliminating anything that looks like an escape for subsequent phases,
     282        // while the ForwardVarargs doesn't get simplified until later (or not at all) and looks like an
     283        // escape for all of the arguments. This then disables object allocation sinking.
     284        //
     285        // So, for now, we just disable this phase for the FTL.
     286        //
     287        // If we wanted to enable it, we'd have to do any of the following:
     288        // - Enable ForwardVarargs->GetStack+PutStack strength reduction, and have that run before
     289        //   PutStack sinking and object allocation sinking.
     290        // - Make VarargsForwarding emit a GetLocal+SetLocal sequence, that we can later turn into
     291        //   GetStack+PutStack.
     292        //
     293        // But, it's not super valuable to enable those optimizations, since the FTL
     294        // ArgumentsEliminationPhase does everything that this phase does, and it doesn't introduce this
     295        // pathology.
     296       
     297        changed |= performVarargsForwarding(dfg); // Do this after CFG simplification and CPS rethreading.
     298    }
    273299    if (changed) {
    274300        performCFA(dfg);
     
    322348        performSSAConversion(dfg);
    323349        performSSALowering(dfg);
     350       
     351        // Ideally, these would be run to fixpoint with the object allocation sinking phase.
     352        performArgumentsElimination(dfg);
    324353        performPutStackSinking(dfg);
     354       
    325355        performGlobalCSE(dfg);
    326356        performLivenessAnalysis(dfg);
     
    341371            performConstantFolding(dfg);
    342372        }
     373       
     374        // Currently, this relies on pre-headers still being valid. That precludes running CFG
     375        // simplification before it, unless we re-created the pre-headers. There wouldn't be anything
     376        // wrong with running LICM earlier, if we wanted to put other CFG transforms above this point.
     377        // Alternatively, we could run loop pre-header creation after SSA conversion - but if we did that
     378        // then we'd need to do some simple SSA fix-up.
    343379        performLICM(dfg);
     380       
    344381        performPhantomCanonicalization(dfg);
    345382        performIntegerCheckCombining(dfg);
  • trunk/Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h

    r180279 r181993  
    5050    void read(AbstractHeap heap)
    5151    {
    52         if (heap.kind() == Variables) {
     52        if (heap.kind() == Stack) {
    5353            if (heap.payload().isTop()) {
    5454                readTop();
     
    6060        }
    6161       
    62         if (heap.overlaps(Variables)) {
     62        if (heap.overlaps(Stack)) {
    6363            readTop();
    6464            return;
     
    6868    void write(AbstractHeap heap)
    6969    {
    70         if (heap.kind() == Variables) {
    71             if (heap.payload().isTop()) {
    72                 writeTop();
    73                 return;
    74             }
    75            
     70        // We expect stack writes to already be precisely characterized by DFG::clobberize().
     71        if (heap.kind() == Stack) {
     72            RELEASE_ASSERT(!heap.payload().isTop());
    7673            callIfAppropriate(m_write, VirtualRegister(heap.payload().value32()));
    7774            return;
    7875        }
    7976       
    80         if (heap.overlaps(Variables)) {
    81             writeTop();
    82             return;
    83         }
     77        RELEASE_ASSERT(!heap.overlaps(Stack));
    8478    }
    8579   
     
    9185    void def(HeapLocation location, Node* node)
    9286    {
    93         if (location.kind() != VariableLoc)
     87        if (location.kind() != StackLoc)
    9488            return;
    9589       
    96         RELEASE_ASSERT(location.heap().kind() == Variables);
     90        RELEASE_ASSERT(location.heap().kind() == Stack);
    9791       
    9892        m_def(VirtualRegister(location.heap().payload().value32()), node);
     
    122116            m_read(VirtualRegister(i));
    123117       
    124         // Read all of the captured variables.
    125         const BitVector& capturedVars =
    126             m_graph.capturedVarsFor(m_node->origin.semantic.inlineCallFrame);
    127         for (unsigned i : capturedVars.setBits())
    128             m_read(virtualRegisterForLocal(i));
    129        
    130118        // Read all of the inline arguments and call frame headers that we didn't already capture.
    131119        for (InlineCallFrame* inlineCallFrame = m_node->origin.semantic.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->caller.inlineCallFrame) {
     
    137125                m_read(VirtualRegister(inlineCallFrame->stackOffset + JSStack::ArgumentCount));
    138126        }
    139     }
    140    
    141     void writeTop()
    142     {
    143         if (m_node->op() == LoadVarargs) {
    144             // Make sure we note the writes to the locals that will store the array elements and
    145             // count.
    146             LoadVarargsData* data = m_node->loadVarargsData();
    147             m_write(data->count);
    148             for (unsigned i = data->limit; i--;)
    149                 m_write(VirtualRegister(data->start.offset() + i));
    150         }
    151        
     127
    152128        // Note that we don't need to do anything special for CallForwardVarargs, since it reads
    153129        // our arguments the same way that any effectful thing might.
    154        
    155         if (m_graph.m_codeBlock->usesArguments()) {
    156             for (unsigned i = m_graph.m_codeBlock->numParameters(); i-- > 1;)
    157                 m_write(virtualRegisterForArgument(i));
    158         }
    159 
    160         const BitVector& capturedVars =
    161             m_graph.capturedVarsFor(m_node->origin.semantic.inlineCallFrame);
    162         for (unsigned i : capturedVars.setBits())
    163             m_write(virtualRegisterForLocal(i));
    164130    }
    165131   
     
    171137};
    172138
    173 template<typename ReadFunctor>
    174 void forEachLocalReadByUnwind(Graph& graph, CodeOrigin codeOrigin, const ReadFunctor& read)
    175 {
    176     if (graph.uncheckedActivationRegister().isValid())
    177         read(graph.activationRegister());
    178     if (graph.m_codeBlock->usesArguments())
    179         read(unmodifiedArgumentsRegister(graph.argumentsRegisterFor(nullptr)));
    180    
    181     for (InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->caller.inlineCallFrame) {
    182         if (inlineCallFrame->executable->usesArguments())
    183             read(unmodifiedArgumentsRegister(graph.argumentsRegisterFor(inlineCallFrame)));
    184     }
    185 }
    186 
    187139template<typename ReadFunctor, typename WriteFunctor, typename DefFunctor>
    188140void preciseLocalClobberize(
     
    193145        adaptor(graph, node, read, write, def);
    194146    clobberize(graph, node, adaptor);
    195     if (mayExit(graph, node))
    196         forEachLocalReadByUnwind(graph, node->origin.forExit, read);
    197147}
    198148
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r181891 r181993  
    5858        ASSERT(m_graph.m_unificationState == GloballyUnified);
    5959
     60        propagateThroughArgumentPositions();
     61
    6062        m_pass = PrimaryPass;
    6163        propagateToFixpoint();
     
    188190        case GetById:
    189191        case GetByIdFlush:
    190         case GetMyArgumentByValSafe:
    191192        case GetByOffset:
    192193        case MultiGetByOffset:
     
    197198        case ConstructVarargs:
    198199        case CallForwardVarargs:
     200        case ConstructForwardVarargs:
    199201        case NativeCall:
    200202        case NativeConstruct:
    201203        case GetGlobalVar:
    202         case GetClosureVar: {
     204        case GetClosureVar:
     205        case GetFromArguments: {
    203206            changed |= setPrediction(node->getHeapPrediction());
    204207            break;
     
    214217        case GetSetter:
    215218        case GetCallee:
    216         case NewFunctionNoCheck:
    217         case NewFunctionExpression: {
     219        case NewFunction: {
    218220            changed |= setPrediction(SpecFunction);
     221            break;
     222        }
     223           
     224        case GetArgumentCount: {
     225            changed |= setPrediction(SpecInt32);
    219226            break;
    220227        }
     
    419426        }
    420427           
    421         case GetMyArgumentsLengthSafe: {
    422             changed |= setPrediction(SpecInt32);
    423             break;
    424         }
    425 
    426         case GetClosureRegisters:           
    427428        case GetButterfly:
    428429        case GetIndexedPropertyStorage:
     
    498499        }
    499500           
    500         case CreateArguments: {
    501             changed |= setPrediction(SpecArguments);
    502             break;
    503         }
    504            
    505         case NewFunction: {
    506             SpeculatedType child = node->child1()->prediction();
    507             if (child & SpecEmpty)
    508                 changed |= mergePrediction((child & ~SpecEmpty) | SpecFunction);
    509             else
    510                 changed |= mergePrediction(child);
     501        case CreateDirectArguments: {
     502            changed |= setPrediction(SpecDirectArguments);
     503            break;
     504        }
     505           
     506        case CreateScopedArguments: {
     507            changed |= setPrediction(SpecScopedArguments);
     508            break;
     509        }
     510           
     511        case CreateClonedArguments: {
     512            changed |= setPrediction(SpecObjectOther);
    511513            break;
    512514        }
     
    523525        case DoubleAsInt32:
    524526        case GetLocalUnlinked:
    525         case GetMyArgumentsLength:
    526         case GetMyArgumentByVal:
    527         case PhantomArguments:
    528527        case CheckArray:
    529528        case Arrayify:
     
    543542        case BooleanToNumber:
    544543        case PhantomNewObject:
     544        case PhantomDirectArguments:
     545        case PhantomClonedArguments:
     546        case GetMyArgumentByVal:
     547        case ForwardVarargs:
    545548        case PutHint:
    546549        case CheckStructureImmediate:
     
    608611        case PutByVal:
    609612        case PutClosureVar:
     613        case PutToArguments:
    610614        case Return:
    611615        case Throw:
     
    632636        case CheckBadCell:
    633637        case PutStructure:
    634         case TearOffArguments:
    635         case CheckArgumentsNotCreated:
    636638        case VarInjectionWatchpoint:
    637639        case AllocationProfileWatchpoint:
     
    855857            m_changed |= variableAccessData->tallyVotesForShouldUseDoubleFormat();
    856858        }
    857         for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i)
    858             m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness();
     859        propagateThroughArgumentPositions();
    859860        for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
    860861            VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
     
    865866    }
    866867   
     868    void propagateThroughArgumentPositions()
     869    {
     870        for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i)
     871            m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness();
     872    }
     873   
    867874    Node* m_currentNode;
    868875    bool m_changed;
  • trunk/Source/JavaScriptCore/dfg/DFGPromoteHeapAccess.h

    r181650 r181993  
    6262       
    6363    case PutHint: {
    64         ASSERT(node->child1()->isPhantomObjectAllocation());
     64        ASSERT(node->child1()->isPhantomAllocation());
    6565        write(
    6666            PromotedHeapLocation(node->child1().node(), node->promotedLocationDescriptor()),
  • trunk/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.cpp

    r181650 r181993  
    11/*
    2  * Copyright (C) 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7171        out.print("NamedPropertyPLoc");
    7272        return;
     73       
     74    case ArgumentPLoc:
     75        out.print("ArgumentPLoc");
     76        return;
     77       
     78    case ArgumentCountPLoc:
     79        out.print("ArgumentCountPLoc");
     80        return;
     81       
     82    case ArgumentsCalleePLoc:
     83        out.print("ArgumentsCalleePLoc");
     84        return;
    7385    }
    7486   
  • trunk/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h

    r181650 r181993  
    11/*
    2  * Copyright (C) 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3838   
    3939    StructurePLoc,
    40     NamedPropertyPLoc
     40    NamedPropertyPLoc,
     41    ArgumentPLoc,
     42    ArgumentCountPLoc,
     43    ArgumentsCalleePLoc
    4144};
    4245
  • trunk/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp

    r180691 r181993  
    6464        // Create a SSACalculator::Variable for every root VariableAccessData.
    6565        for (VariableAccessData& variable : m_graph.m_variableAccessData) {
    66             if (!variable.isRoot() || variable.isCaptured())
     66            if (!variable.isRoot())
    6767                continue;
    6868           
     
    8888               
    8989                VariableAccessData* variable = node->variableAccessData();
    90                 if (variable->isCaptured())
    91                     continue;
    9290               
    9391                Node* childNode;
     
    191189        //   - MovHint has KillLocal prepended to it.
    192190        //
    193         //   - GetLocal over captured variables lose their phis and become GetStack.
    194         //
    195         //   - GetLocal over uncaptured variables die and get replaced with references to the node
    196         //     specified by valueForOperand.
     191        //   - GetLocal die and get replaced with references to the node specified by
     192        //     valueForOperand.
    197193        //
    198194        //   - SetLocal turns into PutStack if it's flushed, or turns into a Check otherwise.
     
    219215                   
    220216                    VariableAccessData* variable = nodeAtHead->variableAccessData();
    221                     if (variable->isCaptured())
    222                         continue;
    223217                   
    224218                    if (verbose)
     
    284278                    VariableAccessData* variable = node->variableAccessData();
    285279                   
    286                     if (variable->isCaptured() || !!(node->flags() & NodeIsFlushed)) {
     280                    if (!!(node->flags() & NodeIsFlushed)) {
    287281                        node->convertToPutStack(
    288282                            m_graph.m_stackAccessData.add(
     
    291285                        node->setOpAndDefaultFlags(Check);
    292286                   
    293                     if (!variable->isCaptured()) {
    294                         if (verbose)
    295                             dataLog("Mapping: ", variable->local(), " -> ", node->child1().node(), "\n");
    296                         valueForOperand.operand(variable->local()) = node->child1().node();
    297                     }
     287                    if (verbose)
     288                        dataLog("Mapping: ", variable->local(), " -> ", node->child1().node(), "\n");
     289                    valueForOperand.operand(variable->local()) = node->child1().node();
    298290                    break;
    299291                }
     
    308300                    VariableAccessData* variable = node->variableAccessData();
    309301                    node->children.reset();
    310                    
    311                     if (variable->isCaptured()) {
    312                         node->convertToGetStack(m_graph.m_stackAccessData.add(variable->local(), variable->flushFormat()));
    313                         break;
    314                     }
    315302                   
    316303                    node->convertToPhantom();
     
    330317                    ASSERT(node->child1().useKind() == UntypedUse);
    331318                    VariableAccessData* variable = node->variableAccessData();
    332                     if (variable->isCaptured()) {
    333                         // This is a fun case. We could have a captured variable that had some
    334                         // or all of its uses strength reduced to phantoms rather than flushes.
    335                         // SSA conversion will currently still treat it as flushed, in the sense
    336                         // that it will just keep the SetLocal. Therefore, there is nothing that
    337                         // needs to be done here: we don't need to also keep the source value
    338                         // alive. And even if we did want to keep the source value alive, we
    339                         // wouldn't be able to, because the variablesAtHead value for a captured
    340                         // local wouldn't have been computed by the Phi reduction algorithm
    341                         // above.
    342                         node->children.reset();
    343                     } else
    344                         node->child1() = valueForOperand.operand(variable->local())->defaultEdge();
     319                    node->child1() = valueForOperand.operand(variable->local())->defaultEdge();
    345320                    node->convertToPhantom();
    346321                    break;
     
    403378
    404379            Node* node = m_argumentMapping.get(m_graph.m_arguments[i]);
    405 
    406             // m_argumentMapping.get could return null for a captured local. That's fine. We only
    407             // track the argument loads of those arguments for which we speculate type. We don't
    408             // speculate type for captured arguments.
    409             if (node)
    410                 format = node->stackAccessData()->format;
     380           
     381            RELEASE_ASSERT(node);
     382            format = node->stackAccessData()->format;
    411383           
    412384            m_graph.m_argumentFormats[i] = format;
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r181891 r181993  
    117117    case CreateThis:
    118118    case GetCallee:
     119    case GetArgumentCount:
    119120    case GetLocal:
    120121    case SetLocal:
     
    171172    case GetScope:
    172173    case SkipScope:
    173     case GetClosureRegisters:
    174174    case GetClosureVar:
    175175    case PutClosureVar:
     
    196196    case LoadVarargs:
    197197    case CallForwardVarargs:
     198    case ConstructForwardVarargs:
    198199    case NewObject:
    199200    case NewArray:
     
    223224    case In:
    224225    case CreateActivation:
    225     case CreateArguments:
    226     case PhantomArguments:
    227     case TearOffArguments:
    228     case GetMyArgumentsLength:
    229     case GetMyArgumentByVal:
    230     case GetMyArgumentsLengthSafe:
    231     case GetMyArgumentByValSafe:
    232     case CheckArgumentsNotCreated:
    233     case NewFunctionNoCheck:
     226    case CreateDirectArguments:
     227    case CreateScopedArguments:
     228    case CreateClonedArguments:
     229    case GetFromArguments:
     230    case PutToArguments:
    234231    case NewFunction:
    235     case NewFunctionExpression:
    236232    case Jump:
    237233    case Branch:
     
    281277    case CheckStructureImmediate:
    282278    case MaterializeNewObject:
     279    case PhantomDirectArguments:
     280    case PhantomClonedArguments:
     281    case GetMyArgumentByVal:
     282    case ForwardVarargs:
    283283        return true;
    284284
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r181570 r181993  
    11/*
    2  * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2929#if ENABLE(DFG_JIT)
    3030
    31 #include "Arguments.h"
    3231#include "BinarySwitch.h"
    3332#include "DFGAbstractInterpreterInlines.h"
    3433#include "DFGArrayifySlowPathGenerator.h"
    3534#include "DFGCallArrayAllocatorSlowPathGenerator.h"
     35#include "DFGCallCreateDirectArgumentsSlowPathGenerator.h"
    3636#include "DFGMayExit.h"
    3737#include "DFGSaneStringGetByValSlowPathGenerator.h"
    3838#include "DFGSlowPathGenerator.h"
     39#include "DirectArguments.h"
     40#include "JSCInlines.h"
     41#include "JSEnvironmentRecord.h"
     42#include "JSLexicalEnvironment.h"
    3943#include "LinkBuffer.h"
    40 #include "JSCInlines.h"
     44#include "ScopedArguments.h"
    4145#include "ScratchRegisterAllocator.h"
    4246#include "WriteBarrierBuffer.h"
     
    104108    // of work for a very small piece of functionality. :-/
    105109    addSlowPathGenerator(std::make_unique<CallArrayAllocatorSlowPathGenerator>(
    106             slowCases, this, operationNewArrayWithSize, resultGPR, storageGPR,
    107             structure, numElements));
    108 }
    109 
    110 void SpeculativeJIT::emitAllocateArguments(GPRReg resultGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
    111 {
    112     Structure* structure = m_jit.graph().globalObjectFor(m_currentNode->origin.semantic)->argumentsStructure();
    113 
    114     m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), scratchGPR1);
    115     m_jit.lshift32(TrustedImm32(3), scratchGPR1);
    116     m_jit.add32(TrustedImm32(Arguments::offsetOfInlineRegisterArray()), scratchGPR1);
    117     emitAllocateVariableSizedJSObject<Arguments>(resultGPR, TrustedImmPtr(structure), scratchGPR1, scratchGPR1, scratchGPR2, slowPath);
    118 
    119     m_jit.storePtr(TrustedImmPtr(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfActivation()));
    120 
    121     m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), scratchGPR1);
    122     m_jit.sub32(TrustedImm32(1), scratchGPR1);
    123     m_jit.store32(scratchGPR1, MacroAssembler::Address(resultGPR, Arguments::offsetOfNumArguments()));
    124 
    125     m_jit.store32(TrustedImm32(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfOverrodeLength()));
    126     if (m_jit.isStrictModeFor(m_currentNode->origin.semantic))
    127         m_jit.store8(TrustedImm32(1), MacroAssembler::Address(resultGPR, Arguments::offsetOfIsStrictMode()));
    128 
    129     m_jit.storePtr(GPRInfo::callFrameRegister, MacroAssembler::Address(resultGPR, Arguments::offsetOfRegisters()));
    130     m_jit.storePtr(TrustedImmPtr(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfSlowArgumentData()));
    131 
    132     m_jit.loadPtr(JITCompiler::addressFor(JSStack::Callee), scratchGPR1);
    133     m_jit.storePtr(scratchGPR1, MacroAssembler::Address(resultGPR, Arguments::offsetOfCallee()));
    134 
     110        slowCases, this, operationNewArrayWithSize, resultGPR, storageGPR,
     111        structure, numElements));
     112}
     113
     114void SpeculativeJIT::emitGetLength(InlineCallFrame* inlineCallFrame, GPRReg lengthGPR, bool includeThis)
     115{
     116    if (inlineCallFrame && !inlineCallFrame->isVarargs())
     117        m_jit.move(TrustedImm32(inlineCallFrame->arguments.size() - !includeThis), lengthGPR);
     118    else {
     119        VirtualRegister argumentCountRegister;
     120        if (!inlineCallFrame)
     121            argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
     122        else
     123            argumentCountRegister = inlineCallFrame->argumentCountRegister;
     124        m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), lengthGPR);
     125        if (!includeThis)
     126            m_jit.sub32(TrustedImm32(1), lengthGPR);
     127    }
     128}
     129
     130void SpeculativeJIT::emitGetLength(CodeOrigin origin, GPRReg lengthGPR, bool includeThis)
     131{
     132    emitGetLength(origin.inlineCallFrame, lengthGPR, includeThis);
     133}
     134
     135void SpeculativeJIT::emitGetCallee(CodeOrigin origin, GPRReg calleeGPR)
     136{
     137    if (origin.inlineCallFrame) {
     138        if (origin.inlineCallFrame->isClosureCall) {
     139            m_jit.loadPtr(
     140                JITCompiler::addressFor(origin.inlineCallFrame->calleeRecovery.virtualRegister()),
     141                calleeGPR);
     142        } else {
     143            m_jit.move(
     144                TrustedImmPtr(origin.inlineCallFrame->calleeRecovery.constant().asCell()),
     145                calleeGPR);
     146        }
     147    } else
     148        m_jit.loadPtr(JITCompiler::addressFor(JSStack::Callee), calleeGPR);
     149}
     150
     151void SpeculativeJIT::emitGetArgumentStart(CodeOrigin origin, GPRReg startGPR)
     152{
     153    m_jit.addPtr(
     154        TrustedImm32(
     155            JITCompiler::argumentsStart(origin).offset() * static_cast<int>(sizeof(Register))),
     156        GPRInfo::callFrameRegister, startGPR);
    135157}
    136158
     
    723745        return;
    724746    }
    725     case Array::Arguments:
    726         speculateCellTypeWithoutTypeFiltering(node->child1(), baseReg, ArgumentsType);
    727 
     747    case Array::DirectArguments:
     748        speculateCellTypeWithoutTypeFiltering(node->child1(), baseReg, DirectArgumentsType);
     749        noResult(m_currentNode);
     750        return;
     751    case Array::ScopedArguments:
     752        speculateCellTypeWithoutTypeFiltering(node->child1(), baseReg, ScopedArgumentsType);
    728753        noResult(m_currentNode);
    729754        return;
     
    40994124}
    41004125
    4101 void SpeculativeJIT::compileGetByValOnArguments(Node* node)
     4126void SpeculativeJIT::compileGetByValOnDirectArguments(Node* node)
     4127{
     4128    SpeculateCellOperand base(this, node->child1());
     4129    SpeculateStrictInt32Operand property(this, node->child2());
     4130    GPRTemporary result(this);
     4131#if USE(JSVALUE32_64)
     4132    GPRTemporary resultTag(this);
     4133#endif
     4134   
     4135    GPRReg baseReg = base.gpr();
     4136    GPRReg propertyReg = property.gpr();
     4137    GPRReg resultReg = result.gpr();
     4138#if USE(JSVALUE32_64)
     4139    GPRReg resultTagReg = resultTag.gpr();
     4140    JSValueRegs resultRegs = JSValueRegs(resultTagReg, resultReg);
     4141#else
     4142    JSValueRegs resultRegs = JSValueRegs(resultReg);
     4143#endif
     4144   
     4145    if (!m_compileOkay)
     4146        return;
     4147   
     4148    ASSERT(ArrayMode(Array::DirectArguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
     4149   
     4150    speculationCheck(
     4151        ExoticObjectMode, JSValueSource(), 0,
     4152        m_jit.branchTestPtr(
     4153            MacroAssembler::NonZero,
     4154            MacroAssembler::Address(baseReg, DirectArguments::offsetOfOverrides())));
     4155    speculationCheck(
     4156        ExoticObjectMode, JSValueSource(), 0,
     4157        m_jit.branch32(
     4158            MacroAssembler::AboveOrEqual, propertyReg,
     4159            MacroAssembler::Address(baseReg, DirectArguments::offsetOfLength())));
     4160   
     4161    m_jit.loadValue(
     4162        MacroAssembler::BaseIndex(
     4163            baseReg, propertyReg, MacroAssembler::TimesEight, DirectArguments::storageOffset()),
     4164        resultRegs);
     4165   
     4166    jsValueResult(resultRegs, node);
     4167}
     4168
     4169void SpeculativeJIT::compileGetByValOnScopedArguments(Node* node)
    41024170{
    41034171    SpeculateCellOperand base(this, node->child1());
     
    41084176#endif
    41094177    GPRTemporary scratch(this);
     4178    GPRTemporary scratch2(this);
    41104179   
    41114180    GPRReg baseReg = base.gpr();
     
    41144183#if USE(JSVALUE32_64)
    41154184    GPRReg resultTagReg = resultTag.gpr();
     4185    JSValueRegs resultRegs = JSValueRegs(resultTagReg, resultReg);
     4186#else
     4187    JSValueRegs resultRegs = JSValueRegs(resultReg);
    41164188#endif
    41174189    GPRReg scratchReg = scratch.gpr();
     4190    GPRReg scratch2Reg = scratch2.gpr();
    41184191   
    41194192    if (!m_compileOkay)
    41204193        return;
    4121  
    4122     ASSERT(ArrayMode(Array::Arguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
    4123    
    4124     // Two really lame checks.
     4194   
     4195    ASSERT(ArrayMode(Array::ScopedArguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
     4196   
    41254197    speculationCheck(
    4126         ExoticObjectMode, JSValueSource(), 0,
     4198        ExoticObjectMode, JSValueSource(), nullptr,
    41274199        m_jit.branch32(
    41284200            MacroAssembler::AboveOrEqual, propertyReg,
    4129             MacroAssembler::Address(baseReg, Arguments::offsetOfNumArguments())));
     4201            MacroAssembler::Address(baseReg, ScopedArguments::offsetOfTotalLength())));
     4202   
     4203    m_jit.loadPtr(MacroAssembler::Address(baseReg, ScopedArguments::offsetOfTable()), scratchReg);
     4204    m_jit.load32(
     4205        MacroAssembler::Address(scratchReg, ScopedArgumentsTable::offsetOfLength()), scratch2Reg);
     4206   
     4207    MacroAssembler::Jump overflowArgument = m_jit.branch32(
     4208        MacroAssembler::AboveOrEqual, propertyReg, scratch2Reg);
     4209   
     4210    m_jit.loadPtr(MacroAssembler::Address(baseReg, ScopedArguments::offsetOfScope()), scratch2Reg);
     4211
     4212    m_jit.loadPtr(
     4213        MacroAssembler::Address(scratchReg, ScopedArgumentsTable::offsetOfArguments()),
     4214        scratchReg);
     4215    m_jit.load32(
     4216        MacroAssembler::BaseIndex(scratchReg, propertyReg, MacroAssembler::TimesFour),
     4217        scratchReg);
     4218   
    41304219    speculationCheck(
    4131         ExoticObjectMode, JSValueSource(), 0,
    4132         m_jit.branchTestPtr(
    4133             MacroAssembler::NonZero,
    4134             MacroAssembler::Address(
    4135                 baseReg, Arguments::offsetOfSlowArgumentData())));
    4136    
    4137     m_jit.move(propertyReg, resultReg);
    4138     m_jit.signExtend32ToPtr(resultReg, resultReg);
    4139     m_jit.loadPtr(
    4140         MacroAssembler::Address(baseReg, Arguments::offsetOfRegisters()),
    4141         scratchReg);
    4142    
    4143 #if USE(JSVALUE32_64)
    4144     m_jit.load32(
     4220        ExoticObjectMode, JSValueSource(), nullptr,
     4221        m_jit.branch32(
     4222            MacroAssembler::Equal, scratchReg, TrustedImm32(ScopeOffset::invalidOffset)));
     4223   
     4224    m_jit.loadValue(
    41454225        MacroAssembler::BaseIndex(
    4146             scratchReg, resultReg, MacroAssembler::TimesEight,
    4147             CallFrame::thisArgumentOffset() * sizeof(Register) + sizeof(Register) +
    4148             OBJECT_OFFSETOF(JSValue, u.asBits.tag)),
    4149         resultTagReg);
    4150     m_jit.load32(
     4226            scratch2Reg, propertyReg, MacroAssembler::TimesEight,
     4227            JSEnvironmentRecord::offsetOfVariables()),
     4228        resultRegs);
     4229   
     4230    MacroAssembler::Jump done = m_jit.jump();
     4231    overflowArgument.link(&m_jit);
     4232   
     4233    m_jit.sub32(propertyReg, scratch2Reg);
     4234    m_jit.neg32(scratch2Reg);
     4235   
     4236    m_jit.loadValue(
    41514237        MacroAssembler::BaseIndex(
    4152             scratchReg, resultReg, MacroAssembler::TimesEight,
    4153             CallFrame::thisArgumentOffset() * sizeof(Register) + sizeof(Register) +
    4154             OBJECT_OFFSETOF(JSValue, u.asBits.payload)),
    4155         resultReg);
    4156     jsValueResult(resultTagReg, resultReg, node);
    4157 #else
    4158     m_jit.load64(
    4159         MacroAssembler::BaseIndex(
    4160             scratchReg, resultReg, MacroAssembler::TimesEight,
    4161             CallFrame::thisArgumentOffset() * sizeof(Register) + sizeof(Register)),
    4162         resultReg);
    4163     jsValueResult(resultReg, node);
    4164 #endif
    4165 }
    4166 
    4167 void SpeculativeJIT::compileGetArgumentsLength(Node* node)
    4168 {
    4169     SpeculateCellOperand base(this, node->child1());
    4170     GPRTemporary result(this, Reuse, base);
    4171    
    4172     GPRReg baseReg = base.gpr();
    4173     GPRReg resultReg = result.gpr();
    4174    
    4175     if (!m_compileOkay)
    4176         return;
    4177    
    4178     ASSERT(ArrayMode(Array::Arguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
    4179    
    4180     speculationCheck(
    4181         ExoticObjectMode, JSValueSource(), 0,
    4182         m_jit.branchTest8(
    4183             MacroAssembler::NonZero,
    4184             MacroAssembler::Address(baseReg, Arguments::offsetOfOverrodeLength())));
    4185    
    4186     m_jit.load32(
    4187         MacroAssembler::Address(baseReg, Arguments::offsetOfNumArguments()),
    4188         resultReg);
    4189     int32Result(resultReg, node);
     4238            baseReg, scratch2Reg, MacroAssembler::TimesEight,
     4239            ScopedArguments::overflowStorageOffset()),
     4240        resultRegs);
     4241    speculationCheck(ExoticObjectMode, JSValueSource(), nullptr, m_jit.branchIsEmpty(resultRegs));
     4242   
     4243    done.link(&m_jit);
     4244   
     4245    jsValueResult(resultRegs, node);
    41904246}
    41914247
     
    42434299        break;
    42444300    }
    4245     case Array::Arguments: {
    4246         compileGetArgumentsLength(node);
     4301    case Array::DirectArguments: {
     4302        SpeculateCellOperand base(this, node->child1());
     4303        GPRTemporary result(this, Reuse, base);
     4304       
     4305        GPRReg baseReg = base.gpr();
     4306        GPRReg resultReg = result.gpr();
     4307       
     4308        if (!m_compileOkay)
     4309            return;
     4310       
     4311        ASSERT(ArrayMode(Array::DirectArguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
     4312       
     4313        speculationCheck(
     4314            ExoticObjectMode, JSValueSource(), 0,
     4315            m_jit.branchTestPtr(
     4316                MacroAssembler::NonZero,
     4317                MacroAssembler::Address(baseReg, DirectArguments::offsetOfOverrides())));
     4318       
     4319        m_jit.load32(
     4320            MacroAssembler::Address(baseReg, DirectArguments::offsetOfLength()), resultReg);
     4321       
     4322        int32Result(resultReg, node);
     4323        break;
     4324    }
     4325    case Array::ScopedArguments: {
     4326        SpeculateCellOperand base(this, node->child1());
     4327        GPRTemporary result(this, Reuse, base);
     4328       
     4329        GPRReg baseReg = base.gpr();
     4330        GPRReg resultReg = result.gpr();
     4331       
     4332        if (!m_compileOkay)
     4333            return;
     4334       
     4335        ASSERT(ArrayMode(Array::ScopedArguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
     4336       
     4337        speculationCheck(
     4338            ExoticObjectMode, JSValueSource(), 0,
     4339            m_jit.branchTest8(
     4340                MacroAssembler::NonZero,
     4341                MacroAssembler::Address(baseReg, ScopedArguments::offsetOfOverrodeThings())));
     4342       
     4343        m_jit.load32(
     4344            MacroAssembler::Address(baseReg, ScopedArguments::offsetOfTotalLength()), resultReg);
     4345       
     4346        int32Result(resultReg, node);
    42474347        break;
    42484348    }
     
    42594359}
    42604360
    4261 void SpeculativeJIT::compileNewFunctionNoCheck(Node* node)
     4361void SpeculativeJIT::compileNewFunction(Node* node)
    42624362{
    42634363    GPRFlushedCallResult result(this);
     
    42674367    flushRegisters();
    42684368    callOperation(
    4269         operationNewFunctionNoCheck, resultGPR, scopeGPR,
    4270         node->castOperand<FunctionExecutable*>());
     4369        operationNewFunction, resultGPR, scopeGPR, node->castOperand<FunctionExecutable*>());
    42714370    cellResult(resultGPR, node);
    42724371}
    42734372
    4274 void SpeculativeJIT::compileNewFunctionExpression(Node* node)
    4275 {
     4373void SpeculativeJIT::compileForwardVarargs(Node* node)
     4374{
     4375    LoadVarargsData* data = node->loadVarargsData();
     4376    InlineCallFrame* inlineCallFrame = node->child1()->origin.semantic.inlineCallFrame;
     4377       
     4378    GPRTemporary length(this);
     4379    JSValueRegsTemporary temp(this);
     4380    GPRReg lengthGPR = length.gpr();
     4381    JSValueRegs tempRegs = temp.regs();
     4382       
     4383    emitGetLength(inlineCallFrame, lengthGPR, /* includeThis = */ true);
     4384    if (data->offset)
     4385        m_jit.sub32(TrustedImm32(data->offset), lengthGPR);
     4386       
     4387    speculationCheck(
     4388        VarargsOverflow, JSValueSource(), Edge(), m_jit.branch32(
     4389            MacroAssembler::Above,
     4390            lengthGPR, TrustedImm32(data->limit)));
     4391       
     4392    m_jit.store32(lengthGPR, JITCompiler::payloadFor(data->machineCount));
     4393       
     4394    VirtualRegister sourceStart = JITCompiler::argumentsStart(inlineCallFrame) + data->offset;
     4395    VirtualRegister targetStart = data->machineStart;
     4396
     4397    m_jit.sub32(TrustedImm32(1), lengthGPR);
     4398       
     4399    // First have a loop that fills in the undefined slots in case of an arity check failure.
     4400    m_jit.move(TrustedImm32(data->mandatoryMinimum), tempRegs.payloadGPR());
     4401    JITCompiler::Jump done = m_jit.branch32(JITCompiler::BelowOrEqual, tempRegs.payloadGPR(), lengthGPR);
     4402       
     4403    JITCompiler::Label loop = m_jit.label();
     4404    m_jit.sub32(TrustedImm32(1), tempRegs.payloadGPR());
     4405    m_jit.storeTrustedValue(
     4406        jsUndefined(),
     4407        JITCompiler::BaseIndex(
     4408            GPRInfo::callFrameRegister, tempRegs.payloadGPR(), JITCompiler::TimesEight,
     4409            targetStart.offset() * sizeof(EncodedJSValue)));
     4410    m_jit.branch32(JITCompiler::Above, tempRegs.payloadGPR(), lengthGPR).linkTo(loop, &m_jit);
     4411    done.link(&m_jit);
     4412       
     4413    // And then fill in the actual argument values.
     4414    done = m_jit.branchTest32(JITCompiler::Zero, lengthGPR);
     4415       
     4416    loop = m_jit.label();
     4417    m_jit.sub32(TrustedImm32(1), lengthGPR);
     4418    m_jit.loadValue(
     4419        JITCompiler::BaseIndex(
     4420            GPRInfo::callFrameRegister, lengthGPR, JITCompiler::TimesEight,
     4421            sourceStart.offset() * sizeof(EncodedJSValue)),
     4422        tempRegs);
     4423    m_jit.storeValue(
     4424        tempRegs,
     4425        JITCompiler::BaseIndex(
     4426            GPRInfo::callFrameRegister, lengthGPR, JITCompiler::TimesEight,
     4427            targetStart.offset() * sizeof(EncodedJSValue)));
     4428    m_jit.branchTest32(JITCompiler::NonZero, lengthGPR).linkTo(loop, &m_jit);
     4429       
     4430    done.link(&m_jit);
     4431       
     4432    noResult(node);
     4433}
     4434
     4435void SpeculativeJIT::compileCreateActivation(Node* node)
     4436{
     4437    SpeculateCellOperand scope(this, node->child1());
     4438    GPRTemporary result(this);
     4439    GPRTemporary scratch1(this);
     4440    GPRTemporary scratch2(this);
     4441    GPRReg scopeGPR = scope.gpr();
     4442    GPRReg resultGPR = result.gpr();
     4443    GPRReg scratch1GPR = scratch1.gpr();
     4444    GPRReg scratch2GPR = scratch2.gpr();
     4445       
     4446    SymbolTable* table = m_jit.graph().symbolTableFor(node->origin.semantic);
     4447    Structure* structure = m_jit.graph().globalObjectFor(
     4448        node->origin.semantic)->activationStructure();
     4449       
     4450    JITCompiler::JumpList slowPath;
     4451    emitAllocateJSObjectWithKnownSize<JSLexicalEnvironment>(
     4452        resultGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratch1GPR, scratch2GPR,
     4453        slowPath, JSLexicalEnvironment::allocationSize(table));
     4454       
     4455    // Don't need a memory barriers since we just fast-created the activation, so the
     4456    // activation must be young.
     4457    m_jit.storePtr(scopeGPR, JITCompiler::Address(resultGPR, JSScope::offsetOfNext()));
     4458    m_jit.storePtr(
     4459        TrustedImmPtr(table),
     4460        JITCompiler::Address(resultGPR, JSLexicalEnvironment::offsetOfSymbolTable()));
     4461       
     4462    // Must initialize all members to undefined.
     4463    for (unsigned i = 0; i < table->scopeSize(); ++i) {
     4464        m_jit.storeTrustedValue(
     4465            jsUndefined(),
     4466            JITCompiler::Address(
     4467                resultGPR, JSLexicalEnvironment::offsetOfVariable(ScopeOffset(i))));
     4468    }
     4469
     4470    addSlowPathGenerator(
     4471        slowPathCall(
     4472            slowPath, this, operationCreateActivationDirect, resultGPR, structure, scopeGPR, table));
     4473
     4474    cellResult(resultGPR, node);
     4475}
     4476
     4477void SpeculativeJIT::compileCreateDirectArguments(Node* node)
     4478{
     4479    // FIXME: A more effective way of dealing with the argument count and callee is to have
     4480    // them be explicit arguments to this node.
     4481    // https://bugs.webkit.org/show_bug.cgi?id=142207
     4482   
     4483    GPRTemporary result(this);
     4484    GPRTemporary scratch1(this);
     4485    GPRTemporary scratch2(this);
     4486    GPRTemporary length;
     4487    GPRReg resultGPR = result.gpr();
     4488    GPRReg scratch1GPR = scratch1.gpr();
     4489    GPRReg scratch2GPR = scratch2.gpr();
     4490    GPRReg lengthGPR = InvalidGPRReg;
     4491    JSValueRegs valueRegs = JSValueRegs::withTwoAvailableRegs(scratch1GPR, scratch2GPR);
     4492       
     4493    unsigned minCapacity = m_jit.graph().baselineCodeBlockFor(node->origin.semantic)->numParameters() - 1;
     4494       
     4495    unsigned knownLength;
     4496    bool lengthIsKnown; // if false, lengthGPR will have the length.
     4497    if (node->origin.semantic.inlineCallFrame
     4498        && !node->origin.semantic.inlineCallFrame->isVarargs()) {
     4499        knownLength = node->origin.semantic.inlineCallFrame->arguments.size() - 1;
     4500        lengthIsKnown = true;
     4501    } else {
     4502        knownLength = UINT_MAX;
     4503        lengthIsKnown = false;
     4504           
     4505        GPRTemporary realLength(this);
     4506        length.adopt(realLength);
     4507        lengthGPR = length.gpr();
     4508
     4509        VirtualRegister argumentCountRegister;
     4510        if (!node->origin.semantic.inlineCallFrame)
     4511            argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
     4512        else
     4513            argumentCountRegister = node->origin.semantic.inlineCallFrame->argumentCountRegister;
     4514        m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), lengthGPR);
     4515        m_jit.sub32(TrustedImm32(1), lengthGPR);
     4516    }
     4517       
     4518    Structure* structure =
     4519        m_jit.graph().globalObjectFor(node->origin.semantic)->directArgumentsStructure();
     4520       
     4521    // Use a different strategy for allocating the object depending on whether we know its
     4522    // size statically.
     4523    JITCompiler::JumpList slowPath;
     4524    if (lengthIsKnown) {
     4525        emitAllocateJSObjectWithKnownSize<DirectArguments>(
     4526            resultGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratch1GPR, scratch2GPR,
     4527            slowPath, DirectArguments::allocationSize(std::max(knownLength, minCapacity)));
     4528           
     4529        m_jit.store32(
     4530            TrustedImm32(knownLength),
     4531            JITCompiler::Address(resultGPR, DirectArguments::offsetOfLength()));
     4532    } else {
     4533        JITCompiler::Jump tooFewArguments;
     4534        if (minCapacity) {
     4535            tooFewArguments =
     4536                m_jit.branch32(JITCompiler::Below, lengthGPR, TrustedImm32(minCapacity));
     4537        }
     4538        m_jit.lshift32(lengthGPR, TrustedImm32(3), scratch1GPR);
     4539        m_jit.add32(TrustedImm32(DirectArguments::storageOffset()), scratch1GPR);
     4540        if (minCapacity) {
     4541            JITCompiler::Jump done = m_jit.jump();
     4542            tooFewArguments.link(&m_jit);
     4543            m_jit.move(TrustedImm32(DirectArguments::allocationSize(minCapacity)), scratch1GPR);
     4544            done.link(&m_jit);
     4545        }
     4546           
     4547        emitAllocateVariableSizedJSObject<DirectArguments>(
     4548            resultGPR, TrustedImmPtr(structure), scratch1GPR, scratch1GPR, scratch2GPR,
     4549            slowPath);
     4550           
     4551        m_jit.store32(
     4552            lengthGPR, JITCompiler::Address(resultGPR, DirectArguments::offsetOfLength()));
     4553    }
     4554       
     4555    m_jit.store32(
     4556        TrustedImm32(minCapacity),
     4557        JITCompiler::Address(resultGPR, DirectArguments::offsetOfMinCapacity()));
     4558       
     4559    m_jit.storePtr(
     4560        TrustedImmPtr(0), JITCompiler::Address(resultGPR, DirectArguments::offsetOfOverrides()));
     4561       
     4562    if (lengthIsKnown) {
     4563        addSlowPathGenerator(
     4564            slowPathCall(
     4565                slowPath, this, operationCreateDirectArguments, resultGPR, structure,
     4566                knownLength, minCapacity));
     4567    } else {
     4568        auto generator = std::make_unique<CallCreateDirectArgumentsSlowPathGenerator>(
     4569            slowPath, this, resultGPR, structure, lengthGPR, minCapacity);
     4570        addSlowPathGenerator(WTF::move(generator));
     4571    }
     4572       
     4573    if (node->origin.semantic.inlineCallFrame) {
     4574        if (node->origin.semantic.inlineCallFrame->isClosureCall) {
     4575            m_jit.loadPtr(
     4576                JITCompiler::addressFor(
     4577                    node->origin.semantic.inlineCallFrame->calleeRecovery.virtualRegister()),
     4578                scratch1GPR);
     4579        } else {
     4580            m_jit.move(
     4581                TrustedImmPtr(
     4582                    node->origin.semantic.inlineCallFrame->calleeRecovery.constant().asCell()),
     4583                scratch1GPR);
     4584        }
     4585    } else
     4586        m_jit.loadPtr(JITCompiler::addressFor(JSStack::Callee), scratch1GPR);
     4587
     4588    // Don't need a memory barriers since we just fast-created the activation, so the
     4589    // activation must be young.
     4590    m_jit.storePtr(
     4591        scratch1GPR, JITCompiler::Address(resultGPR, DirectArguments::offsetOfCallee()));
     4592       
     4593    VirtualRegister start = m_jit.argumentsStart(node->origin.semantic);
     4594    if (lengthIsKnown) {
     4595        for (unsigned i = 0; i < std::max(knownLength, minCapacity); ++i) {
     4596            m_jit.loadValue(JITCompiler::addressFor(start + i), valueRegs);
     4597            m_jit.storeValue(
     4598                valueRegs, JITCompiler::Address(resultGPR, DirectArguments::offsetOfSlot(i)));
     4599        }
     4600    } else {
     4601        JITCompiler::Jump done;
     4602        if (minCapacity) {
     4603            JITCompiler::Jump startLoop = m_jit.branch32(
     4604                JITCompiler::AboveOrEqual, lengthGPR, TrustedImm32(minCapacity));
     4605            m_jit.move(TrustedImm32(minCapacity), lengthGPR);
     4606            startLoop.link(&m_jit);
     4607        } else
     4608            done = m_jit.branchTest32(MacroAssembler::Zero, lengthGPR);
     4609        JITCompiler::Label loop = m_jit.label();
     4610        m_jit.sub32(TrustedImm32(1), lengthGPR);
     4611        m_jit.loadValue(
     4612            JITCompiler::BaseIndex(
     4613                GPRInfo::callFrameRegister, lengthGPR, JITCompiler::TimesEight,
     4614                start.offset() * static_cast<int>(sizeof(Register))),
     4615            valueRegs);
     4616        m_jit.storeValue(
     4617            valueRegs,
     4618            JITCompiler::BaseIndex(
     4619                resultGPR, lengthGPR, JITCompiler::TimesEight,
     4620                DirectArguments::storageOffset()));
     4621        m_jit.branchTest32(MacroAssembler::NonZero, lengthGPR).linkTo(loop, &m_jit);
     4622        if (done.isSet())
     4623            done.link(&m_jit);
     4624    }
     4625       
     4626    cellResult(resultGPR, node);
     4627}
     4628
     4629void SpeculativeJIT::compileGetFromArguments(Node* node)
     4630{
     4631    SpeculateCellOperand arguments(this, node->child1());
     4632    JSValueRegsTemporary result(this);
     4633   
     4634    GPRReg argumentsGPR = arguments.gpr();
     4635    JSValueRegs resultRegs = result.regs();
     4636   
     4637    m_jit.loadValue(JITCompiler::Address(argumentsGPR, DirectArguments::offsetOfSlot(node->capturedArgumentsOffset().offset())), resultRegs);
     4638    jsValueResult(resultRegs, node);
     4639}
     4640
     4641void SpeculativeJIT::compilePutToArguments(Node* node)
     4642{
     4643    SpeculateCellOperand arguments(this, node->child1());
     4644    JSValueOperand value(this, node->child2());
     4645   
     4646    GPRReg argumentsGPR = arguments.gpr();
     4647    JSValueRegs valueRegs = value.jsValueRegs();
     4648   
     4649    m_jit.storeValue(valueRegs, JITCompiler::Address(argumentsGPR, DirectArguments::offsetOfSlot(node->capturedArgumentsOffset().offset())));
     4650    noResult(node);
     4651}
     4652
     4653void SpeculativeJIT::compileCreateScopedArguments(Node* node)
     4654{
     4655    SpeculateCellOperand scope(this, node->child1());
     4656    GPRReg scopeGPR = scope.gpr();
     4657   
    42764658    GPRFlushedCallResult result(this);
    42774659    GPRReg resultGPR = result.gpr();
    4278     SpeculateCellOperand scope(this, node->child1());
    4279     GPRReg scopeGPR = scope.gpr();
    42804660    flushRegisters();
    4281     callOperation(
    4282         operationNewFunctionNoCheck,
    4283         resultGPR, scopeGPR,  node->castOperand<FunctionExecutable*>());
     4661   
     4662    // We set up the arguments ourselves, because we have the whole register file and we can
     4663    // set them up directly into the argument registers. This also means that we don't have to
     4664    // invent a four-argument-register shuffle.
     4665   
     4666    // Arguments: 0:exec, 1:structure, 2:start, 3:length, 4:callee, 5:scope
     4667   
     4668    // Do the scopeGPR first, since it might alias an argument register.
     4669    m_jit.setupArgument(5, [&] (GPRReg destGPR) { m_jit.move(scopeGPR, destGPR); });
     4670   
     4671    // These other things could be done in any order.
     4672    m_jit.setupArgument(4, [&] (GPRReg destGPR) { emitGetCallee(node->origin.semantic, destGPR); });
     4673    m_jit.setupArgument(3, [&] (GPRReg destGPR) { emitGetLength(node->origin.semantic, destGPR); });
     4674    m_jit.setupArgument(2, [&] (GPRReg destGPR) { emitGetArgumentStart(node->origin.semantic, destGPR); });
     4675    m_jit.setupArgument(
     4676        1, [&] (GPRReg destGPR) {
     4677            m_jit.move(
     4678                TrustedImmPtr(m_jit.globalObjectFor(node->origin.semantic)->scopedArgumentsStructure()),
     4679                destGPR);
     4680        });
     4681    m_jit.setupArgument(0, [&] (GPRReg destGPR) { m_jit.move(GPRInfo::callFrameRegister, destGPR); });
     4682   
     4683    appendCallWithExceptionCheckSetResult(operationCreateScopedArguments, resultGPR);
     4684   
     4685    cellResult(resultGPR, node);
     4686}
     4687
     4688void SpeculativeJIT::compileCreateClonedArguments(Node* node)
     4689{
     4690    GPRFlushedCallResult result(this);
     4691    GPRReg resultGPR = result.gpr();
     4692    flushRegisters();
     4693   
     4694    // We set up the arguments ourselves, because we have the whole register file and we can
     4695    // set them up directly into the argument registers.
     4696   
     4697    // Arguments: 0:exec, 1:structure, 2:start, 3:length, 4:callee
     4698    m_jit.setupArgument(4, [&] (GPRReg destGPR) { emitGetCallee(node->origin.semantic, destGPR); });
     4699    m_jit.setupArgument(3, [&] (GPRReg destGPR) { emitGetLength(node->origin.semantic, destGPR); });
     4700    m_jit.setupArgument(2, [&] (GPRReg destGPR) { emitGetArgumentStart(node->origin.semantic, destGPR); });
     4701    m_jit.setupArgument(
     4702        1, [&] (GPRReg destGPR) {
     4703            m_jit.move(
     4704                TrustedImmPtr(
     4705                    m_jit.globalObjectFor(node->origin.semantic)->outOfBandArgumentsStructure()),
     4706                destGPR);
     4707        });
     4708    m_jit.setupArgument(0, [&] (GPRReg destGPR) { m_jit.move(GPRInfo::callFrameRegister, destGPR); });
     4709   
     4710    appendCallWithExceptionCheckSetResult(operationCreateClonedArguments, resultGPR);
     4711   
    42844712    cellResult(resultGPR, node);
    42854713}
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r181035 r181993  
    718718    void emitCall(Node*);
    719719   
    720     int32_t framePointerOffsetToGetActivationRegisters()
    721     {
    722         return m_jit.codeBlock()->framePointerOffsetToGetActivationRegisters(
    723             m_jit.graph().m_machineCaptureStart);
    724     }
    725    
    726720    // Called once a node has completed code generation but prior to setting
    727721    // its result, to free up its children. (This must happen prior to setting
     
    903897    {
    904898        m_jit.setupArgumentsExecState();
    905         return appendCall(operation);
     899        return appendCallWithExceptionCheck(operation);
    906900    }
    907901    JITCompiler::Call callOperation(P_JITOperation_E operation, GPRReg result)
     
    10181012    {
    10191013        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
     1014        return appendCallWithExceptionCheckSetResult(operation, result);
     1015    }
     1016    JITCompiler::Call callOperation(C_JITOperation_EStJscSymtab operation, GPRReg result, Structure* structure, GPRReg scope, SymbolTable* table)
     1017    {
     1018        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), scope, TrustedImmPtr(table));
     1019        return appendCallWithExceptionCheckSetResult(operation, result);
     1020    }
     1021    JITCompiler::Call callOperation(C_JITOperation_EStZ operation, GPRReg result, Structure* structure, unsigned knownLength)
     1022    {
     1023        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(knownLength));
     1024        return appendCallWithExceptionCheckSetResult(operation, result);
     1025    }
     1026    JITCompiler::Call callOperation(C_JITOperation_EStZZ operation, GPRReg result, Structure* structure, unsigned knownLength, unsigned minCapacity)
     1027    {
     1028        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(knownLength), TrustedImm32(minCapacity));
     1029        return appendCallWithExceptionCheckSetResult(operation, result);
     1030    }
     1031    JITCompiler::Call callOperation(C_JITOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg length)
     1032    {
     1033        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), length);
     1034        return appendCallWithExceptionCheckSetResult(operation, result);
     1035    }
     1036    JITCompiler::Call callOperation(C_JITOperation_EStZZ operation, GPRReg result, Structure* structure, GPRReg length, unsigned minCapacity)
     1037    {
     1038        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), length, TrustedImm32(minCapacity));
    10201039        return appendCallWithExceptionCheckSetResult(operation, result);
    10211040    }
     
    11731192    {
    11741193        m_jit.setupArgumentsWithExecState(TrustedImm32(arg1));
     1194        return appendCallWithExceptionCheckSetResult(operation, result);
     1195    }
     1196
     1197    JITCompiler::Call callOperation(J_JITOperation_EJscC operation, GPRReg result, GPRReg arg1, JSCell* cell)
     1198    {
     1199        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
    11751200        return appendCallWithExceptionCheckSetResult(operation, result);
    11761201    }
     
    12471272    {
    12481273        m_jit.setupArgumentsWithExecState(arg1, arg2);
    1249         return appendCallWithExceptionCheckSetResult(operation, result);
    1250     }
    1251     JITCompiler::Call callOperation(J_JITOperation_EJscC operation, GPRReg result, GPRReg arg1, JSCell* cell)
    1252     {
    1253         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
    12541274        return appendCallWithExceptionCheckSetResult(operation, result);
    12551275    }
     
    21532173    void compileFromCharCode(Node*);
    21542174
    2155     void compileGetByValOnArguments(Node*);
    2156     void compileGetArgumentsLength(Node*);
     2175    void compileGetByValOnDirectArguments(Node*);
     2176    void compileGetByValOnScopedArguments(Node*);
     2177   
    21572178    void compileGetScope(Node*);
    21582179    void compileSkipScope(Node*);
     
    21852206    void compileGetByValOnFloatTypedArray(Node*, TypedArrayType);
    21862207    void compilePutByValForFloatTypedArray(GPRReg base, GPRReg property, Node*, TypedArrayType);
    2187     void compileNewFunctionNoCheck(Node*);
    2188     void compileNewFunctionExpression(Node*);
     2208    void compileNewFunction(Node*);
     2209    void compileForwardVarargs(Node*);
     2210    void compileCreateActivation(Node*);
     2211    void compileCreateDirectArguments(Node*);
     2212    void compileGetFromArguments(Node*);
     2213    void compilePutToArguments(Node*);
     2214    void compileCreateScopedArguments(Node*);
     2215    void compileCreateClonedArguments(Node*);
    21892216    bool compileRegExpExec(Node*);
    21902217   
     
    22552282    }
    22562283
     2284    template <typename ClassType, typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
     2285    void emitAllocateJSObjectWithKnownSize(
     2286        GPRReg resultGPR, StructureType structure, StorageType storage, GPRReg scratchGPR1,
     2287        GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath, size_t size)
     2288    {
     2289        MarkedAllocator* allocator = &m_jit.vm()->heap.allocatorForObjectOfType<ClassType>(size);
     2290        m_jit.move(TrustedImmPtr(allocator), scratchGPR1);
     2291        emitAllocateJSObject(resultGPR, scratchGPR1, structure, storage, scratchGPR2, slowPath);
     2292    }
     2293
    22572294    // Convenience allocator for a built-in object.
    22582295    template <typename ClassType, typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
     
    22602297        GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
    22612298    {
    2262         size_t size = ClassType::allocationSize(0);
    2263         MarkedAllocator* allocator = &m_jit.vm()->heap.allocatorForObjectOfType<ClassType>(size);
    2264         m_jit.move(TrustedImmPtr(allocator), scratchGPR1);
    2265         emitAllocateJSObject(resultGPR, scratchGPR1, structure, storage, scratchGPR2, slowPath);
     2299        emitAllocateJSObjectWithKnownSize<ClassType>(
     2300            resultGPR, structure, storage, scratchGPR1, scratchGPR2, slowPath,
     2301            ClassType::allocationSize(0));
    22662302    }
    22672303
     
    23002336
    23012337    void emitAllocateJSArray(GPRReg resultGPR, Structure*, GPRReg storageGPR, unsigned numElements);
    2302     void emitAllocateArguments(GPRReg resultGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath);
    2303 
     2338   
     2339    void emitGetLength(InlineCallFrame*, GPRReg lengthGPR, bool includeThis = false);
     2340    void emitGetLength(CodeOrigin, GPRReg lengthGPR, bool includeThis = false);
     2341    void emitGetCallee(CodeOrigin, GPRReg calleeGPR);
     2342    void emitGetArgumentStart(CodeOrigin, GPRReg startGPR);
     2343   
    23042344    // Add a speculation check.
    23052345    void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r181891 r181993  
    3636#include "DFGSlowPathGenerator.h"
    3737#include "Debugger.h"
     38#include "DirectArguments.h"
    3839#include "GetterSetter.h"
     40#include "JSEnvironmentRecord.h"
    3941#include "JSLexicalEnvironment.h"
    4042#include "JSPropertyNameEnumerator.h"
     
    641643{
    642644    CallLinkInfo::CallType callType;
    643     bool isVarargs;
     645    bool isVarargs = false;
     646    bool isForwardVarargs = false;
    644647    switch (node->op()) {
    645648    case Call:
    646649        callType = CallLinkInfo::Call;
    647         isVarargs = false;
    648650        break;
    649651    case Construct:
    650652        callType = CallLinkInfo::Construct;
    651         isVarargs = false;
    652653        break;
    653654    case CallVarargs:
    654     case CallForwardVarargs:
    655655        callType = CallLinkInfo::CallVarargs;
    656656        isVarargs = true;
     
    660660        isVarargs = true;
    661661        break;
     662    case CallForwardVarargs:
     663        callType = CallLinkInfo::CallVarargs;
     664        isForwardVarargs = true;
     665        break;
     666    case ConstructForwardVarargs:
     667        callType = CallLinkInfo::ConstructVarargs;
     668        isForwardVarargs = true;
     669        break;
    662670    default:
    663671        DFG_CRASH(m_jit.graph(), node, "bad node type");
     
    668676   
    669677    // Gotta load the arguments somehow. Varargs is trickier.
    670     if (isVarargs) {
     678    if (isVarargs || isForwardVarargs) {
    671679        CallVarargsData* data = node->callVarargsData();
    672680
    673         GPRReg argumentsPayloadGPR;
    674         GPRReg argumentsTagGPR;
    675         GPRReg scratchGPR1;
    676         GPRReg scratchGPR2;
    677         GPRReg scratchGPR3;
    678        
    679         if (node->op() == CallForwardVarargs) {
    680             // We avoid calling flushRegisters() inside the control flow of CallForwardVarargs.
     681        GPRReg resultGPR;
     682        unsigned numUsedStackSlots = m_jit.graph().m_nextMachineLocal;
     683       
     684        if (isForwardVarargs) {
    681685            flushRegisters();
    682         }
    683        
    684         auto loadArgumentsGPR = [&] (GPRReg reservedGPR) {
    685             if (node->op() == CallForwardVarargs) {
    686                 argumentsTagGPR = JITCompiler::selectScratchGPR(reservedGPR);
    687                 argumentsPayloadGPR = JITCompiler::selectScratchGPR(reservedGPR, argumentsTagGPR);
    688                 m_jit.load32(
    689                     JITCompiler::tagFor(
    690                         m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
    691                     argumentsTagGPR);
    692                 m_jit.load32(
    693                     JITCompiler::payloadFor(
    694                         m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
    695                     argumentsPayloadGPR);
    696             } else {
     686            use(node->child2());
     687           
     688            GPRReg scratchGPR1;
     689            GPRReg scratchGPR2;
     690            GPRReg scratchGPR3;
     691           
     692            scratchGPR1 = JITCompiler::selectScratchGPR();
     693            scratchGPR2 = JITCompiler::selectScratchGPR(scratchGPR1);
     694            scratchGPR3 = JITCompiler::selectScratchGPR(scratchGPR1, scratchGPR2);
     695           
     696            m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR2);
     697            JITCompiler::JumpList slowCase;
     698            emitSetupVarargsFrameFastCase(m_jit, scratchGPR2, scratchGPR1, scratchGPR2, scratchGPR3, node->child2()->origin.semantic.inlineCallFrame, data->firstVarArgOffset, slowCase);
     699            JITCompiler::Jump done = m_jit.jump();
     700            slowCase.link(&m_jit);
     701            callOperation(operationThrowStackOverflowForVarargs);
     702            m_jit.abortWithReason(DFGVarargsThrowingPathDidNotThrow);
     703            done.link(&m_jit);
     704            resultGPR = scratchGPR2;
     705        } else {
     706            GPRReg argumentsPayloadGPR;
     707            GPRReg argumentsTagGPR;
     708            GPRReg scratchGPR1;
     709            GPRReg scratchGPR2;
     710            GPRReg scratchGPR3;
     711       
     712            auto loadArgumentsGPR = [&] (GPRReg reservedGPR) {
    697713                if (reservedGPR != InvalidGPRReg)
    698714                    lock(reservedGPR);
     
    703719                    unlock(reservedGPR);
    704720                flushRegisters();
    705             }
    706            
    707             scratchGPR1 = JITCompiler::selectScratchGPR(argumentsPayloadGPR, argumentsTagGPR, reservedGPR);
    708             scratchGPR2 = JITCompiler::selectScratchGPR(argumentsPayloadGPR, argumentsTagGPR, scratchGPR1, reservedGPR);
    709             scratchGPR3 = JITCompiler::selectScratchGPR(argumentsPayloadGPR, argumentsTagGPR, scratchGPR1, scratchGPR2, reservedGPR);
    710         };
    711        
    712         loadArgumentsGPR(InvalidGPRReg);
    713        
    714         // At this point we have the whole register file to ourselves, and argumentsGPR has the
    715         // arguments register. Select some scratch registers.
    716        
    717         // We will use scratchGPR2 to point to our stack frame.
    718        
    719         unsigned numUsedStackSlots = m_jit.graph().m_nextMachineLocal;
    720        
    721         JITCompiler::Jump haveArguments;
    722         GPRReg resultGPR = GPRInfo::regT0;
    723         if (node->op() == CallForwardVarargs) {
    724             // Do the horrific foo.apply(this, arguments) optimization.
    725             // FIXME: do this optimization at the IR level instead of dynamically by testing the
    726             // arguments register. This will happen once we get rid of the arguments lazy creation and
    727             // lazy tear-off.
    728            
    729             JITCompiler::JumpList slowCase;
    730             slowCase.append(
    731                 m_jit.branch32(
    732                     JITCompiler::NotEqual,
    733                     argumentsTagGPR, TrustedImm32(JSValue::EmptyValueTag)));
    734            
    735             m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR2);
    736             emitSetupVarargsFrameFastCase(m_jit, scratchGPR2, scratchGPR1, scratchGPR2, scratchGPR3, node->origin.semantic.inlineCallFrame, data->firstVarArgOffset, slowCase);
    737             resultGPR = scratchGPR2;
    738            
    739             haveArguments = m_jit.jump();
    740             slowCase.link(&m_jit);
    741         }
    742 
     721               
     722                scratchGPR1 = JITCompiler::selectScratchGPR(argumentsPayloadGPR, argumentsTagGPR, reservedGPR);
     723                scratchGPR2 = JITCompiler::selectScratchGPR(argumentsPayloadGPR, argumentsTagGPR, scratchGPR1, reservedGPR);
     724                scratchGPR3 = JITCompiler::selectScratchGPR(argumentsPayloadGPR, argumentsTagGPR, scratchGPR1, scratchGPR2, reservedGPR);
     725            };
     726           
     727            loadArgumentsGPR(InvalidGPRReg);
     728       
     729            DFG_ASSERT(m_jit.graph(), node, isFlushed());
     730
     731            // Right now, arguments is in argumentsTagGPR/argumentsPayloadGPR and the register file is
     732            // flushed.
     733            callOperation(operationSizeFrameForVarargs, GPRInfo::returnValueGPR, argumentsTagGPR, argumentsPayloadGPR, numUsedStackSlots, data->firstVarArgOffset);
     734           
     735            // Now we have the argument count of the callee frame, but we've lost the arguments operand.
     736            // Reconstruct the arguments operand while preserving the callee frame.
     737            loadArgumentsGPR(GPRInfo::returnValueGPR);
     738            m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR1);
     739            emitSetVarargsFrame(m_jit, GPRInfo::returnValueGPR, false, scratchGPR1, scratchGPR1);
     740            m_jit.addPtr(TrustedImm32(-(sizeof(CallerFrameAndPC) + WTF::roundUpToMultipleOf(stackAlignmentBytes(), 6 * sizeof(void*)))), scratchGPR1, JITCompiler::stackPointerRegister);
     741           
     742            callOperation(operationSetupVarargsFrame, GPRInfo::returnValueGPR, scratchGPR1, argumentsTagGPR, argumentsPayloadGPR, data->firstVarArgOffset, GPRInfo::returnValueGPR);
     743            resultGPR = GPRInfo::returnValueGPR;
     744        }
     745           
     746        m_jit.addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), resultGPR, JITCompiler::stackPointerRegister);
     747       
    743748        DFG_ASSERT(m_jit.graph(), node, isFlushed());
    744749       
    745         // Right now, arguments is in argumentsTagGPR/argumentsPayloadGPR and the register file is
    746         // flushed.
    747         callOperation(operationSizeFrameForVarargs, GPRInfo::returnValueGPR, argumentsTagGPR, argumentsPayloadGPR, numUsedStackSlots, data->firstVarArgOffset);
    748        
    749         // Now we have the argument count of the callee frame, but we've lost the arguments operand.
    750         // Reconstruct the arguments operand while preserving the callee frame.
    751         loadArgumentsGPR(GPRInfo::returnValueGPR);
    752         m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR1);
    753         emitSetVarargsFrame(m_jit, GPRInfo::returnValueGPR, false, scratchGPR1, scratchGPR1);
    754         m_jit.addPtr(TrustedImm32(-(sizeof(CallerFrameAndPC) + WTF::roundUpToMultipleOf(stackAlignmentBytes(), 6 * sizeof(void*)))), scratchGPR1, JITCompiler::stackPointerRegister);
    755        
    756         callOperation(operationSetupVarargsFrame, GPRInfo::returnValueGPR, scratchGPR1, argumentsTagGPR, argumentsPayloadGPR, data->firstVarArgOffset, GPRInfo::returnValueGPR);
    757         m_jit.move(GPRInfo::returnValueGPR, resultGPR);
    758        
    759         if (node->op() == CallForwardVarargs)
    760             haveArguments.link(&m_jit);
    761        
    762         m_jit.addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), resultGPR, JITCompiler::stackPointerRegister);
    763        
    764         DFG_ASSERT(m_jit.graph(), node, isFlushed());
    765        
    766         if (node->op() != CallForwardVarargs)
    767             use(node->child2());
    768 
    769750        // Now set up the "this" argument.
    770         JSValueOperand thisArgument(this, node->op() == CallForwardVarargs ? node->child2() : node->child3());
     751        JSValueOperand thisArgument(this, node->child3());
    771752        GPRReg thisArgumentTagGPR = thisArgument.tagGPR();
    772753        GPRReg thisArgumentPayloadGPR = thisArgument.payloadGPR();
     
    17541735    case JSConstant:
    17551736    case DoubleConstant:
    1756         initConstantInfo(node);
    1757         break;
    1758 
    1759     case PhantomArguments:
     1737    case PhantomDirectArguments:
     1738    case PhantomClonedArguments:
    17601739        initConstantInfo(node);
    17611740        break;
     
    18411820        }
    18421821           
    1843         case FlushedJSValue:
    1844         case FlushedArguments: {
     1822        case FlushedJSValue: {
    18451823            GPRTemporary result(this);
    18461824            GPRTemporary tag(this);
     
    19171895        }
    19181896           
    1919         case FlushedJSValue:
    1920         case FlushedArguments: {
     1897        case FlushedJSValue: {
    19211898            JSValueOperand value(this, node->child1());
    19221899            m_jit.store32(value.payloadGPR(), JITCompiler::payloadFor(node->machineLocal()));
     
    25012478            compileGetByValOnString(node);
    25022479            break;
    2503         case Array::Arguments:
    2504             compileGetByValOnArguments(node);
     2480        case Array::DirectArguments:
     2481            compileGetByValOnDirectArguments(node);
     2482            break;
     2483        case Array::ScopedArguments:
     2484            compileGetByValOnScopedArguments(node);
    25052485            break;
    25062486        default: {
     
    26802660            break;
    26812661        }
    2682            
    2683         case Array::Arguments:
    2684             // FIXME: we could at some point make this work. Right now we're assuming that the register
    2685             // pressure would be too great.
    2686             RELEASE_ASSERT_NOT_REACHED();
    2687             break;
    26882662           
    26892663        default: {
     
    35873561    }
    35883562       
     3563    case GetArgumentCount: {
     3564        GPRTemporary result(this);
     3565        m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), result.gpr());
     3566        int32Result(result.gpr(), node);
     3567        break;
     3568    }
     3569       
    35893570    case GetScope:
    35903571        compileGetScope(node);
     
    35953576        break;
    35963577       
    3597     case GetClosureRegisters: {
    3598         if (WriteBarrierBase<Unknown>* registers = m_jit.graph().tryGetRegisters(node->child1().node())) {
    3599             GPRTemporary result(this);
    3600             GPRReg resultGPR = result.gpr();
    3601             m_jit.move(TrustedImmPtr(registers), resultGPR);
    3602             storageResult(resultGPR, node);
    3603             break;
    3604         }
    3605        
    3606         SpeculateCellOperand scope(this, node->child1());
    3607         GPRTemporary result(this);
    3608         GPRReg scopeGPR = scope.gpr();
    3609         GPRReg resultGPR = result.gpr();
    3610 
    3611         m_jit.loadPtr(JITCompiler::Address(scopeGPR, JSEnvironmentRecord::offsetOfRegisters()), resultGPR);
    3612         storageResult(resultGPR, node);
    3613         break;
    3614     }
    36153578    case GetClosureVar: {
    3616         speculate(node, node->child1());
    3617 
    3618         StorageOperand registers(this, node->child2());
     3579        SpeculateCellOperand base(this, node->child1());
    36193580        GPRTemporary resultTag(this);
    36203581        GPRTemporary resultPayload(this);
    3621         GPRReg registersGPR = registers.gpr();
     3582        GPRReg baseGPR = base.gpr();
    36223583        GPRReg resultTagGPR = resultTag.gpr();
    36233584        GPRReg resultPayloadGPR = resultPayload.gpr();
    3624         m_jit.load32(JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
    3625         m_jit.load32(JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayloadGPR);
     3585        m_jit.load32(JITCompiler::Address(baseGPR, JSEnvironmentRecord::offsetOfVariable(node->scopeOffset()) + TagOffset), resultTagGPR);
     3586        m_jit.load32(JITCompiler::Address(baseGPR, JSEnvironmentRecord::offsetOfVariable(node->scopeOffset()) + PayloadOffset), resultPayloadGPR);
    36263587        jsValueResult(resultTagGPR, resultPayloadGPR, node);
    36273588        break;
    36283589    }
     3590   
    36293591    case PutClosureVar: {
    3630         speculate(node, node->child1());
    3631 
    3632         StorageOperand registers(this, node->child2());
    3633         JSValueOperand value(this, node->child3());
    3634         GPRTemporary scratchRegister(this);
    3635 
    3636         GPRReg registersGPR = registers.gpr();
     3592        SpeculateCellOperand base(this, node->child1());
     3593        JSValueOperand value(this, node->child2());
     3594
     3595        GPRReg baseGPR = base.gpr();
    36373596        GPRReg valueTagGPR = value.tagGPR();
    36383597        GPRReg valuePayloadGPR = value.payloadGPR();
    36393598
    3640         m_jit.store32(valueTagGPR, JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
    3641         m_jit.store32(valuePayloadGPR, JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
     3599        m_jit.store32(valueTagGPR, JITCompiler::Address(baseGPR, JSEnvironmentRecord::offsetOfVariable(node->scopeOffset()) + TagOffset));
     3600        m_jit.store32(valuePayloadGPR, JITCompiler::Address(baseGPR, JSEnvironmentRecord::offsetOfVariable(node->scopeOffset()) + PayloadOffset));
    36423601        noResult(node);
    36433602        break;
     
    39973956        GPRTemporary resultTag(this);
    39983957
    3999         m_jit.move(TrustedImmPtr(node->registerPointer()), resultPayload.gpr());
     3958        m_jit.move(TrustedImmPtr(node->variablePointer()), resultPayload.gpr());
    40003959        m_jit.load32(JITCompiler::Address(resultPayload.gpr(), OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTag.gpr());
    40013960        m_jit.load32(JITCompiler::Address(resultPayload.gpr(), OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayload.gpr());
     
    40123971        // a register and then do a zero offset store followed by a four-offset store (or
    40133972        // vice-versa depending on endianness).
    4014         m_jit.store32(value.tagGPR(), node->registerPointer()->tagPointer());
    4015         m_jit.store32(value.payloadGPR(), node->registerPointer()->payloadPointer());
     3973        m_jit.store32(value.tagGPR(), node->variablePointer()->tagPointer());
     3974        m_jit.store32(value.payloadGPR(), node->variablePointer()->payloadPointer());
    40163975
    40173976        noResult(node);
     
    42634222    case CallForwardVarargs:
    42644223    case ConstructVarargs:
     4224    case ConstructForwardVarargs:
    42654225        emitCall(node);
    42664226        break;
     
    43134273    }
    43144274       
     4275    case ForwardVarargs: {
     4276        compileForwardVarargs(node);
     4277        break;
     4278    }
     4279       
    43154280    case CreateActivation: {
    4316         GPRTemporary result(this);
    4317         GPRReg resultGPR = result.gpr();
    4318         SpeculateCellOperand scope(this, node->child2());
    4319         GPRReg scopeGPR = scope.gpr();
    4320 
    4321         flushRegisters();
    4322         callOperation(operationCreateActivation, resultGPR, scopeGPR, framePointerOffsetToGetActivationRegisters());
    4323        
    4324         cellResult(resultGPR, node);
    4325         break;
    4326     }
    4327        
    4328     case CreateArguments: {
    4329         JSValueOperand value(this, node->child1());
    4330         GPRTemporary scratch1(this);
    4331         GPRTemporary scratch2(this);
    4332         GPRTemporary result(this, Reuse, value, PayloadWord);
    4333        
    4334         GPRReg valueTagGPR = value.tagGPR();
    4335         GPRReg valuePayloadGPR = value.payloadGPR();
    4336         GPRReg scratch1GPR = scratch1.gpr();
    4337         GPRReg scratch2GPR = scratch2.gpr();
    4338         GPRReg resultGPR = result.gpr();
    4339        
    4340         m_jit.move(valuePayloadGPR, resultGPR);
    4341        
    4342         if (node->origin.semantic.inlineCallFrame) {
    4343             JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
    4344             addSlowPathGenerator(
    4345                 slowPathCall(
    4346                     notCreated, this, operationCreateInlinedArguments, resultGPR,
    4347                     node->origin.semantic.inlineCallFrame));
    4348             cellResult(resultGPR, node);
    4349             break;
    4350         }
    4351 
    4352         FunctionExecutable* executable = jsCast<FunctionExecutable*>(m_jit.graph().executableFor(node->origin.semantic));
    4353         if (m_jit.codeBlock()->hasSlowArguments()
    4354             || executable->isStrictMode()
    4355             || !executable->parameterCount()) {
    4356             JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
    4357             addSlowPathGenerator(
    4358                 slowPathCall(notCreated, this, operationCreateArgumentsForDFG, resultGPR));
    4359             cellResult(resultGPR, node);
    4360             break;
    4361         }
    4362 
    4363         JITCompiler::Jump alreadyCreated = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
    4364 
    4365         MacroAssembler::JumpList slowPaths;
    4366         emitAllocateArguments(resultGPR, scratch1GPR, scratch2GPR, slowPaths);
    4367             addSlowPathGenerator(
    4368                 slowPathCall(slowPaths, this, operationCreateArgumentsForDFG, resultGPR));
    4369 
    4370         alreadyCreated.link(&m_jit);
    4371         cellResult(resultGPR, node);
    4372         break;
    4373     }
    4374        
    4375     case TearOffArguments: {
    4376         JSValueOperand unmodifiedArgumentsValue(this, node->child1());
    4377         JSValueOperand activationValue(this, node->child2());
    4378         GPRReg unmodifiedArgumentsValuePayloadGPR = unmodifiedArgumentsValue.payloadGPR();
    4379         GPRReg activationValuePayloadGPR = activationValue.payloadGPR();
    4380        
    4381         JITCompiler::Jump created = m_jit.branchTest32(
    4382             JITCompiler::NonZero, unmodifiedArgumentsValuePayloadGPR);
    4383        
    4384         if (node->origin.semantic.inlineCallFrame) {
    4385             addSlowPathGenerator(
    4386                 slowPathCall(
    4387                     created, this, operationTearOffInlinedArguments, NoResult,
    4388                     unmodifiedArgumentsValuePayloadGPR, activationValuePayloadGPR, node->origin.semantic.inlineCallFrame));
    4389         } else {
    4390             addSlowPathGenerator(
    4391                 slowPathCall(
    4392                     created, this, operationTearOffArguments, NoResult,
    4393                     unmodifiedArgumentsValuePayloadGPR, activationValuePayloadGPR));
    4394         }
    4395        
    4396         noResult(node);
    4397         break;
    4398     }
    4399        
    4400     case CheckArgumentsNotCreated: {
    4401         ASSERT(!isEmptySpeculation(
    4402             m_state.variables().operand(
    4403                 m_jit.graph().argumentsRegisterFor(node->origin.semantic)).m_type));
    4404         speculationCheck(
    4405             Uncountable, JSValueRegs(), 0,
    4406             m_jit.branch32(
    4407                 JITCompiler::NotEqual,
    4408                 JITCompiler::tagFor(m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
    4409                 TrustedImm32(JSValue::EmptyValueTag)));
    4410         noResult(node);
    4411         break;
    4412     }
    4413        
    4414     case GetMyArgumentsLength: {
    4415         GPRTemporary result(this);
    4416         GPRReg resultGPR = result.gpr();
    4417        
    4418         if (!isEmptySpeculation(
    4419                 m_state.variables().operand(
    4420                     m_jit.graph().argumentsRegisterFor(node->origin.semantic)).m_type)) {
    4421             speculationCheck(
    4422                 ArgumentsEscaped, JSValueRegs(), 0,
    4423                 m_jit.branch32(
    4424                     JITCompiler::NotEqual,
    4425                     JITCompiler::tagFor(m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
    4426                     TrustedImm32(JSValue::EmptyValueTag)));
    4427         }
    4428        
    4429         if (node->origin.semantic.inlineCallFrame
    4430             && !node->origin.semantic.inlineCallFrame->isVarargs()) {
    4431             m_jit.move(
    4432                 TrustedImm32(node->origin.semantic.inlineCallFrame->arguments.size() - 1),
    4433                 resultGPR);
    4434         } else {
    4435             VirtualRegister argumentCountRegister;
    4436             if (!node->origin.semantic.inlineCallFrame)
    4437                 argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
    4438             else
    4439                 argumentCountRegister = node->origin.semantic.inlineCallFrame->argumentCountRegister;
    4440             m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), resultGPR);
    4441             m_jit.sub32(TrustedImm32(1), resultGPR);
    4442         }
    4443         int32Result(resultGPR, node);
    4444         break;
    4445     }
    4446        
    4447     case GetMyArgumentsLengthSafe: {
    4448         GPRTemporary resultPayload(this);
    4449         GPRTemporary resultTag(this);
    4450         GPRReg resultPayloadGPR = resultPayload.gpr();
    4451         GPRReg resultTagGPR = resultTag.gpr();
    4452        
    4453         JITCompiler::Jump created = m_jit.branch32(
    4454             JITCompiler::NotEqual,
    4455             JITCompiler::tagFor(m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
    4456             TrustedImm32(JSValue::EmptyValueTag));
    4457        
    4458         if (node->origin.semantic.inlineCallFrame
    4459             && !node->origin.semantic.inlineCallFrame->isVarargs()) {
    4460             m_jit.move(
    4461                 TrustedImm32(node->origin.semantic.inlineCallFrame->arguments.size() - 1),
    4462                 resultPayloadGPR);
    4463         } else {
    4464             VirtualRegister argumentCountRegister;
    4465             if (!node->origin.semantic.inlineCallFrame)
    4466                 argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
    4467             else
    4468                 argumentCountRegister = node->origin.semantic.inlineCallFrame->argumentCountRegister;
    4469             m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), resultPayloadGPR);
    4470             m_jit.sub32(TrustedImm32(1), resultPayloadGPR);
    4471         }
    4472        
    4473         m_jit.move(TrustedImm32(JSValue::Int32Tag), resultTagGPR);
    4474        
    4475         // FIXME: the slow path generator should perform a forward speculation that the
    4476         // result is an integer. For now we postpone the speculation by having this return
    4477         // a JSValue.
    4478        
    4479         addSlowPathGenerator(
    4480             slowPathCall(
    4481                 created, this, operationGetArgumentsLength,
    4482                 JSValueRegs(resultTagGPR, resultPayloadGPR),
    4483                 m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic).offset()));
    4484        
    4485         jsValueResult(resultTagGPR, resultPayloadGPR, node);
    4486         break;
    4487     }
    4488        
    4489     case GetMyArgumentByVal: {
    4490         SpeculateStrictInt32Operand index(this, node->child1());
    4491         GPRTemporary resultPayload(this);
    4492         GPRTemporary resultTag(this);
    4493         GPRReg indexGPR = index.gpr();
    4494         GPRReg resultPayloadGPR = resultPayload.gpr();
    4495         GPRReg resultTagGPR = resultTag.gpr();
    4496        
    4497         if (!isEmptySpeculation(
    4498                 m_state.variables().operand(
    4499                     m_jit.graph().argumentsRegisterFor(node->origin.semantic)).m_type)) {
    4500             speculationCheck(
    4501                 ArgumentsEscaped, JSValueRegs(), 0,
    4502                 m_jit.branch32(
    4503                     JITCompiler::NotEqual,
    4504                     JITCompiler::tagFor(m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
    4505                     TrustedImm32(JSValue::EmptyValueTag)));
    4506         }
    4507            
    4508         if (node->origin.semantic.inlineCallFrame
    4509             && !node->origin.semantic.inlineCallFrame->isVarargs()) {
    4510             speculationCheck(
    4511                 Uncountable, JSValueRegs(), 0,
    4512                 m_jit.branch32(
    4513                     JITCompiler::AboveOrEqual,
    4514                     indexGPR,
    4515                     Imm32(node->origin.semantic.inlineCallFrame->arguments.size() - 1)));
    4516         } else {
    4517             VirtualRegister argumentCountRegister;
    4518             if (!node->origin.semantic.inlineCallFrame)
    4519                 argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
    4520             else
    4521                 argumentCountRegister = node->origin.semantic.inlineCallFrame->argumentCountRegister;
    4522             m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), resultPayloadGPR);
    4523             m_jit.sub32(TrustedImm32(1), resultPayloadGPR);
    4524             speculationCheck(
    4525                 Uncountable, JSValueRegs(), 0,
    4526                 m_jit.branch32(JITCompiler::AboveOrEqual, indexGPR, resultPayloadGPR));
    4527         }
    4528        
    4529         JITCompiler::JumpList slowArgument;
    4530         JITCompiler::JumpList slowArgumentOutOfBounds;
    4531         if (m_jit.symbolTableFor(node->origin.semantic)->slowArguments()) {
    4532             RELEASE_ASSERT(!node->origin.semantic.inlineCallFrame);
    4533             const SlowArgument* slowArguments = m_jit.graph().m_slowArguments.get();
    4534             slowArgumentOutOfBounds.append(
    4535                 m_jit.branch32(
    4536                     JITCompiler::AboveOrEqual, indexGPR,
    4537                     Imm32(m_jit.symbolTableFor(node->origin.semantic)->parameterCount())));
    4538 
    4539             COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
    4540             m_jit.move(ImmPtr(slowArguments), resultPayloadGPR);
    4541             m_jit.load32(
    4542                 JITCompiler::BaseIndex(
    4543                     resultPayloadGPR, indexGPR, JITCompiler::TimesEight,
    4544                     OBJECT_OFFSETOF(SlowArgument, index)),
    4545                 resultPayloadGPR);
    4546 
    4547             m_jit.load32(
    4548                 JITCompiler::BaseIndex(
    4549                     GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
    4550                     OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
    4551                 resultTagGPR);
    4552             m_jit.load32(
    4553                 JITCompiler::BaseIndex(
    4554                     GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
    4555                     OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
    4556                 resultPayloadGPR);
    4557             slowArgument.append(m_jit.jump());
    4558         }
    4559         slowArgumentOutOfBounds.link(&m_jit);
    4560 
    4561         m_jit.load32(
    4562             JITCompiler::BaseIndex(
    4563                 GPRInfo::callFrameRegister, indexGPR, JITCompiler::TimesEight,
    4564                 m_jit.offsetOfArguments(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
    4565             resultTagGPR);
    4566         m_jit.load32(
    4567             JITCompiler::BaseIndex(
    4568                 GPRInfo::callFrameRegister, indexGPR, JITCompiler::TimesEight,
    4569                 m_jit.offsetOfArguments(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
    4570             resultPayloadGPR);
    4571            
    4572         slowArgument.link(&m_jit);
    4573         jsValueResult(resultTagGPR, resultPayloadGPR, node);
    4574         break;
    4575     }
    4576     case GetMyArgumentByValSafe: {
    4577         SpeculateStrictInt32Operand index(this, node->child1());
    4578         GPRTemporary resultPayload(this);
    4579         GPRTemporary resultTag(this);
    4580         GPRReg indexGPR = index.gpr();
    4581         GPRReg resultPayloadGPR = resultPayload.gpr();
    4582         GPRReg resultTagGPR = resultTag.gpr();
    4583        
    4584         JITCompiler::JumpList slowPath;
    4585         slowPath.append(
    4586             m_jit.branch32(
    4587                 JITCompiler::NotEqual,
    4588                 JITCompiler::tagFor(m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
    4589                 TrustedImm32(JSValue::EmptyValueTag)));
    4590        
    4591         if (node->origin.semantic.inlineCallFrame
    4592             && !node->origin.semantic.inlineCallFrame->isVarargs()) {
    4593             slowPath.append(
    4594                 m_jit.branch32(
    4595                     JITCompiler::AboveOrEqual,
    4596                     indexGPR,
    4597                     Imm32(node->origin.semantic.inlineCallFrame->arguments.size() - 1)));
    4598         } else {
    4599             VirtualRegister argumentCountRegister;
    4600             if (!node->origin.semantic.inlineCallFrame)
    4601                 argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
    4602             else
    4603                 argumentCountRegister = node->origin.semantic.inlineCallFrame->argumentCountRegister;
    4604             m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), resultPayloadGPR);
    4605             m_jit.sub32(TrustedImm32(1), resultPayloadGPR);
    4606             slowPath.append(
    4607                 m_jit.branch32(JITCompiler::AboveOrEqual, indexGPR, resultPayloadGPR));
    4608         }
    4609        
    4610         JITCompiler::JumpList slowArgument;
    4611         JITCompiler::JumpList slowArgumentOutOfBounds;
    4612         if (m_jit.symbolTableFor(node->origin.semantic)->slowArguments()) {
    4613             RELEASE_ASSERT(!node->origin.semantic.inlineCallFrame);
    4614             const SlowArgument* slowArguments = m_jit.graph().m_slowArguments.get();
    4615             slowArgumentOutOfBounds.append(
    4616                 m_jit.branch32(
    4617                     JITCompiler::AboveOrEqual, indexGPR,
    4618                     Imm32(m_jit.symbolTableFor(node->origin.semantic)->parameterCount())));
    4619 
    4620             COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
    4621             m_jit.move(ImmPtr(slowArguments), resultPayloadGPR);
    4622             m_jit.load32(
    4623                 JITCompiler::BaseIndex(
    4624                     resultPayloadGPR, indexGPR, JITCompiler::TimesEight,
    4625                     OBJECT_OFFSETOF(SlowArgument, index)),
    4626                 resultPayloadGPR);
    4627             m_jit.load32(
    4628                 JITCompiler::BaseIndex(
    4629                     GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
    4630                     OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
    4631                 resultTagGPR);
    4632             m_jit.load32(
    4633                 JITCompiler::BaseIndex(
    4634                     GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
    4635                     OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
    4636                 resultPayloadGPR);
    4637             slowArgument.append(m_jit.jump());
    4638         }
    4639         slowArgumentOutOfBounds.link(&m_jit);
    4640 
    4641         m_jit.load32(
    4642             JITCompiler::BaseIndex(
    4643                 GPRInfo::callFrameRegister, indexGPR, JITCompiler::TimesEight,
    4644                 m_jit.offsetOfArguments(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
    4645             resultTagGPR);
    4646         m_jit.load32(
    4647             JITCompiler::BaseIndex(
    4648                 GPRInfo::callFrameRegister, indexGPR, JITCompiler::TimesEight,
    4649                 m_jit.offsetOfArguments(node->origin.semantic) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
    4650             resultPayloadGPR);
    4651        
    4652         if (node->origin.semantic.inlineCallFrame) {
    4653             addSlowPathGenerator(
    4654                 slowPathCall(
    4655                     slowPath, this, operationGetInlinedArgumentByVal,
    4656                     JSValueRegs(resultTagGPR, resultPayloadGPR),
    4657                     m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic).offset(),
    4658                     node->origin.semantic.inlineCallFrame, indexGPR));
    4659         } else {
    4660             addSlowPathGenerator(
    4661                 slowPathCall(
    4662                     slowPath, this, operationGetArgumentByVal,
    4663                     JSValueRegs(resultTagGPR, resultPayloadGPR),
    4664                     m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic).offset(),
    4665                     indexGPR));
    4666         }
    4667        
    4668         slowArgument.link(&m_jit);
    4669         jsValueResult(resultTagGPR, resultPayloadGPR, node);
    4670         break;
    4671     }
    4672        
    4673     case NewFunctionNoCheck:
    4674         compileNewFunctionNoCheck(node);
    4675         break;
    4676        
    4677     case NewFunction: {
    4678         JSValueOperand value(this, node->child1());
    4679         GPRTemporary resultTag(this, Reuse, value, TagWord);
    4680         GPRTemporary resultPayload(this, Reuse, value, PayloadWord);
    4681        
    4682         GPRReg valueTagGPR = value.tagGPR();
    4683         GPRReg valuePayloadGPR = value.payloadGPR();
    4684         GPRReg resultTagGPR = resultTag.gpr();
    4685         GPRReg resultPayloadGPR = resultPayload.gpr();
    4686         SpeculateCellOperand scope(this, node->child2());
    4687         GPRReg scopeGPR = scope.gpr();
    4688 
    4689         m_jit.move(valuePayloadGPR, resultPayloadGPR);
    4690         m_jit.move(valueTagGPR, resultTagGPR);
    4691        
    4692         JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
    4693        
    4694         addSlowPathGenerator(
    4695             slowPathCall(
    4696                 notCreated, this, operationNewFunction, JSValueRegs(resultTagGPR, resultPayloadGPR), scopeGPR,
    4697                 node->castOperand<FunctionExecutable*>()));
    4698        
    4699         jsValueResult(resultTagGPR, resultPayloadGPR, node);
    4700         break;
    4701     }
    4702        
    4703     case NewFunctionExpression:
    4704         compileNewFunctionExpression(node);
     4281        compileCreateActivation(node);
     4282        break;
     4283    }
     4284       
     4285    case CreateDirectArguments: {
     4286        compileCreateDirectArguments(node);
     4287        break;
     4288    }
     4289       
     4290    case GetFromArguments: {
     4291        compileGetFromArguments(node);
     4292        break;
     4293    }
     4294       
     4295    case PutToArguments: {
     4296        compilePutToArguments(node);
     4297        break;
     4298    }
     4299       
     4300    case CreateScopedArguments: {
     4301        compileCreateScopedArguments(node);
     4302        break;
     4303    }
     4304       
     4305    case CreateClonedArguments: {
     4306        compileCreateClonedArguments(node);
     4307        break;
     4308    }
     4309       
     4310    case NewFunction:
     4311        compileNewFunction(node);
    47054312        break;
    47064313       
     
    50884695    case KillStack:
    50894696    case GetStack:
    5090         RELEASE_ASSERT_NOT_REACHED();
     4697    case GetMyArgumentByVal:
     4698        DFG_CRASH(m_jit.graph(), node, "unexpected node in DFG backend");
    50914699        break;
    50924700    }
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r181891 r181993  
    2929#if ENABLE(DFG_JIT)
    3030
    31 #include "Arguments.h"
    3231#include "ArrayPrototype.h"
    3332#include "DFGAbstractInterpreterInlines.h"
     
    3635#include "DFGSlowPathGenerator.h"
    3736#include "Debugger.h"
     37#include "DirectArguments.h"
    3838#include "GetterSetter.h"
    3939#include "JSCInlines.h"
     40#include "JSEnvironmentRecord.h"
     41#include "JSLexicalEnvironment.h"
    4042#include "JSPropertyNameEnumerator.h"
    4143#include "ObjectPrototype.h"
     
    627629{
    628630    CallLinkInfo::CallType callType;
    629     bool isVarargs;
     631    bool isVarargs = false;
     632    bool isForwardVarargs = false;
    630633    switch (node->op()) {
    631634    case Call:
    632635        callType = CallLinkInfo::Call;
    633         isVarargs = false;
    634636        break;
    635637    case Construct:
    636638        callType = CallLinkInfo::Construct;
    637         isVarargs = false;
    638639        break;
    639640    case CallVarargs:
    640     case CallForwardVarargs:
    641641        callType = CallLinkInfo::CallVarargs;
    642642        isVarargs = true;
     
    646646        isVarargs = true;
    647647        break;
     648    case CallForwardVarargs:
     649        callType = CallLinkInfo::CallVarargs;
     650        isForwardVarargs = true;
     651        break;
     652    case ConstructForwardVarargs:
     653        callType = CallLinkInfo::ConstructVarargs;
     654        isForwardVarargs = true;
     655        break;
    648656    default:
    649657        DFG_CRASH(m_jit.graph(), node, "bad node type");
     
    654662   
    655663    // Gotta load the arguments somehow. Varargs is trickier.
    656     if (isVarargs) {
     664    if (isVarargs || isForwardVarargs) {
    657665        CallVarargsData* data = node->callVarargsData();
    658666
    659         GPRReg argumentsGPR;
    660         GPRReg scratchGPR1;
    661         GPRReg scratchGPR2;
    662         GPRReg scratchGPR3;
    663        
    664         if (node->op() == CallForwardVarargs) {
    665             // We avoid calling flushRegisters() inside the control flow of CallForwardVarargs.
     667        GPRReg resultGPR;
     668        unsigned numUsedStackSlots = m_jit.graph().m_nextMachineLocal;
     669       
     670        if (isForwardVarargs) {
    666671            flushRegisters();
    667         }
    668        
    669         auto loadArgumentsGPR = [&] (GPRReg reservedGPR) {
    670             if (node->op() == CallForwardVarargs) {
    671                 argumentsGPR = JITCompiler::selectScratchGPR(reservedGPR);
    672                 m_jit.load64(
    673                     JITCompiler::addressFor(
    674                         m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)),
    675                     argumentsGPR);
    676             } else {
     672            use(node->child2());
     673           
     674            GPRReg scratchGPR1;
     675            GPRReg scratchGPR2;
     676            GPRReg scratchGPR3;
     677           
     678            scratchGPR1 = JITCompiler::selectScratchGPR();
     679            scratchGPR2 = JITCompiler::selectScratchGPR(scratchGPR1);
     680            scratchGPR3 = JITCompiler::selectScratchGPR(scratchGPR1, scratchGPR2);
     681           
     682            m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR2);
     683            JITCompiler::JumpList slowCase;
     684            emitSetupVarargsFrameFastCase(m_jit, scratchGPR2, scratchGPR1, scratchGPR2, scratchGPR3, node->child2()->origin.semantic.inlineCallFrame, data->firstVarArgOffset, slowCase);
     685            JITCompiler::Jump done = m_jit.jump();
     686            slowCase.link(&m_jit);
     687            callOperation(operationThrowStackOverflowForVarargs);
     688            m_jit.abortWithReason(DFGVarargsThrowingPathDidNotThrow);
     689            done.link(&m_jit);
     690            resultGPR = scratchGPR2;
     691        } else {
     692            GPRReg argumentsGPR;
     693            GPRReg scratchGPR1;
     694            GPRReg scratchGPR2;
     695            GPRReg scratchGPR3;
     696           
     697            auto loadArgumentsGPR = [&] (GPRReg reservedGPR) {
    677698                if (reservedGPR != InvalidGPRReg)
    678699                    lock(reservedGPR);
     
    682703                    unlock(reservedGPR);
    683704                flushRegisters();
    684             }
    685            
    686             scratchGPR1 = JITCompiler::selectScratchGPR(argumentsGPR, reservedGPR);
    687             scratchGPR2 = JITCompiler::selectScratchGPR(argumentsGPR, scratchGPR1, reservedGPR);
    688             scratchGPR3 = JITCompiler::selectScratchGPR(argumentsGPR, scratchGPR1, scratchGPR2, reservedGPR);
    689         };
    690        
    691         loadArgumentsGPR(InvalidGPRReg);
    692        
    693         // At this point we have the whole register file to ourselves, and argumentsGPR has the
    694         // arguments register. Select some scratch registers.
    695        
    696         // We will use scratchGPR2 to point to our stack frame.
    697 
    698         unsigned numUsedStackSlots = m_jit.graph().m_nextMachineLocal;
    699        
    700         JITCompiler::Jump haveArguments;
    701         GPRReg resultGPR = GPRInfo::regT0;
    702         if (node->op() == CallForwardVarargs) {
    703             // Do the horrific foo.apply(this, arguments) optimization.
    704             // FIXME: do this optimization at the IR level instead of dynamically by testing the
    705             // arguments register. This will happen once we get rid of the arguments lazy creation and
    706             // lazy tear-off.
    707            
    708             JITCompiler::JumpList slowCase;
    709             slowCase.append(m_jit.branchTest64(JITCompiler::NonZero, argumentsGPR));
    710            
    711             m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR2);
    712             emitSetupVarargsFrameFastCase(m_jit, scratchGPR2, scratchGPR1, scratchGPR2, scratchGPR3, node->origin.semantic.inlineCallFrame, data->firstVarArgOffset, slowCase);
    713             resultGPR = scratchGPR2;
    714            
    715             haveArguments = m_jit.jump();
    716             slowCase.link(&m_jit);
    717         }
    718 
     705               
     706                scratchGPR1 = JITCompiler::selectScratchGPR(argumentsGPR, reservedGPR);
     707                scratchGPR2 = JITCompiler::selectScratchGPR(argumentsGPR, scratchGPR1, reservedGPR);
     708                scratchGPR3 = JITCompiler::selectScratchGPR(argumentsGPR, scratchGPR1, scratchGPR2, reservedGPR);
     709            };
     710           
     711            loadArgumentsGPR(InvalidGPRReg);
     712           
     713            DFG_ASSERT(m_jit.graph(), node, isFlushed());
     714           
     715            // Right now, arguments is in argumentsGPR and the register file is flushed.
     716            callOperation(operationSizeFrameForVarargs, GPRInfo::returnValueGPR, argumentsGPR, numUsedStackSlots, data->firstVarArgOffset);
     717           
     718            // Now we have the argument count of the callee frame, but we've lost the arguments operand.
     719            // Reconstruct the arguments operand while preserving the callee frame.
     720            loadArgumentsGPR(GPRInfo::returnValueGPR);
     721            m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR1);
     722            emitSetVarargsFrame(m_jit, GPRInfo::returnValueGPR, false, scratchGPR1, scratchGPR1);
     723            m_jit.addPtr(TrustedImm32(-(sizeof(CallerFrameAndPC) + WTF::roundUpToMultipleOf(stackAlignmentBytes(), 5 * sizeof(void*)))), scratchGPR1, JITCompiler::stackPointerRegister);
     724           
     725            callOperation(operationSetupVarargsFrame, GPRInfo::returnValueGPR, scratchGPR1, argumentsGPR, data->firstVarArgOffset, GPRInfo::returnValueGPR);
     726            resultGPR = GPRInfo::returnValueGPR;
     727        }
     728       
     729        m_jit.addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), resultGPR, JITCompiler::stackPointerRegister);
     730       
    719731        DFG_ASSERT(m_jit.graph(), node, isFlushed());
    720732       
    721         // Right now, arguments is in argumentsGPR and the register file is flushed.
    722         callOperation(operationSizeFrameForVarargs, GPRInfo::returnValueGPR, argumentsGPR, numUsedStackSlots, data->firstVarArgOffset);
    723        
    724         // Now we have the argument count of the callee frame, but we've lost the arguments operand.
    725         // Reconstruct the arguments operand while preserving the callee frame.
    726         loadArgumentsGPR(GPRInfo::returnValueGPR);
    727         m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR1);
    728         emitSetVarargsFrame(m_jit, GPRInfo::returnValueGPR, false, scratchGPR1, scratchGPR1);
    729         m_jit.addPtr(TrustedImm32(-(sizeof(CallerFrameAndPC) + WTF::roundUpToMultipleOf(stackAlignmentBytes(), 5 * sizeof(void*)))), scratchGPR1, JITCompiler::stackPointerRegister);
    730        
    731         callOperation(operationSetupVarargsFrame, GPRInfo::returnValueGPR, scratchGPR1, argumentsGPR, data->firstVarArgOffset, GPRInfo::returnValueGPR);
    732         m_jit.move(GPRInfo::returnValueGPR, resultGPR);
    733        
    734         if (node->op() == CallForwardVarargs)
    735             haveArguments.link(&m_jit);
    736        
    737         m_jit.addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), resultGPR, JITCompiler::stackPointerRegister);
    738        
    739         DFG_ASSERT(m_jit.graph(), node, isFlushed());
    740        
    741733        // We don't need the arguments array anymore.
    742         if (node->op() != CallForwardVarargs)
     734        if (isVarargs)
    743735            use(node->child2());
    744736
    745737        // Now set up the "this" argument.
    746         JSValueOperand thisArgument(this, node->op() == CallForwardVarargs ? node->child2() : node->child3());
     738        JSValueOperand thisArgument(this, node->child3());
    747739        GPRReg thisArgumentGPR = thisArgument.gpr();
    748740        thisArgument.use();
     
    18471839    case DoubleConstant:
    18481840    case Int52Constant:
    1849         initConstantInfo(node);
    1850         break;
    1851 
    1852     case PhantomArguments:
     1841    case PhantomDirectArguments:
     1842    case PhantomClonedArguments:
    18531843        initConstantInfo(node);
    18541844        break;
     
    20102000        }
    20112001           
    2012         case FlushedJSValue:
    2013         case FlushedArguments: {
     2002        case FlushedJSValue: {
    20142003            JSValueOperand value(this, node->child1());
    20152004            m_jit.store64(value.gpr(), JITCompiler::addressFor(node->machineLocal()));
     
    26032592            compileGetByValOnString(node);
    26042593            break;
    2605         case Array::Arguments:
    2606             compileGetByValOnArguments(node);
     2594        case Array::DirectArguments:
     2595            compileGetByValOnDirectArguments(node);
     2596            break;
     2597        case Array::ScopedArguments:
     2598            compileGetByValOnScopedArguments(node);
    26072599            break;
    26082600        default: {
     
    28312823
    28322824            noResult(node, UseChildrenCalledExplicitly);
    2833             break;
    2834         }
    2835            
    2836         case Array::Arguments: {
    2837             JSValueOperand value(this, child3);
    2838             GPRTemporary scratch(this);
    2839             GPRTemporary scratch2(this);
    2840            
    2841             GPRReg valueReg = value.gpr();
    2842             GPRReg scratchReg = scratch.gpr();
    2843             GPRReg scratch2Reg = scratch2.gpr();
    2844            
    2845             if (!m_compileOkay)
    2846                 return;
    2847 
    2848             // Two really lame checks.
    2849             speculationCheck(
    2850                 Uncountable, JSValueSource(), 0,
    2851                 m_jit.branch32(
    2852                     MacroAssembler::AboveOrEqual, propertyReg,
    2853                     MacroAssembler::Address(baseReg, Arguments::offsetOfNumArguments())));
    2854             speculationCheck(
    2855                 Uncountable, JSValueSource(), 0,
    2856                 m_jit.branchTestPtr(
    2857                     MacroAssembler::NonZero,
    2858                     MacroAssembler::Address(
    2859                         baseReg, Arguments::offsetOfSlowArgumentData())));
    2860 
    2861             m_jit.move(propertyReg, scratch2Reg);
    2862             m_jit.signExtend32ToPtr(scratch2Reg, scratch2Reg);
    2863             m_jit.loadPtr(
    2864                 MacroAssembler::Address(baseReg, Arguments::offsetOfRegisters()),
    2865                 scratchReg);
    2866            
    2867             m_jit.store64(
    2868                 valueReg,
    2869                 MacroAssembler::BaseIndex(
    2870                     scratchReg, scratch2Reg, MacroAssembler::TimesEight,
    2871                     CallFrame::thisArgumentOffset() * sizeof(Register) + sizeof(Register)));
    2872            
    2873             noResult(node);
    28742825            break;
    28752826        }
     
    36403591
    36413592        MacroAssembler::JumpList slowPath;
    3642 
     3593       
    36433594        m_jit.loadPtr(JITCompiler::Address(calleeGPR, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()), allocatorGPR);
    36443595        m_jit.loadPtr(JITCompiler::Address(calleeGPR, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()), structureGPR);
     
    36893640    }
    36903641       
     3642    case GetArgumentCount: {
     3643        GPRTemporary result(this);
     3644        m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), result.gpr());
     3645        int32Result(result.gpr(), node);
     3646        break;
     3647    }
     3648       
    36913649    case GetScope:
    36923650        compileGetScope(node);
     
    36973655        break;
    36983656       
    3699     case GetClosureRegisters: {
    3700         if (WriteBarrierBase<Unknown>* registers = m_jit.graph().tryGetRegisters(node->child1().node())) {
    3701             GPRTemporary result(this);
    3702             GPRReg resultGPR = result.gpr();
    3703             m_jit.move(TrustedImmPtr(registers), resultGPR);
    3704             storageResult(resultGPR, node);
    3705             break;
    3706         }
    3707        
    3708         SpeculateCellOperand scope(this, node->child1());
     3657    case GetClosureVar: {
     3658        SpeculateCellOperand base(this, node->child1());
    37093659        GPRTemporary result(this);
    3710         GPRReg scopeGPR = scope.gpr();
     3660        GPRReg baseGPR = base.gpr();
    37113661        GPRReg resultGPR = result.gpr();
    37123662
    3713         m_jit.loadPtr(JITCompiler::Address(scopeGPR, JSEnvironmentRecord::offsetOfRegisters()), resultGPR);
    3714         storageResult(resultGPR, node);
    3715         break;
    3716     }
    3717     case GetClosureVar: {
    3718         speculate(node, node->child1());
    3719 
    3720         StorageOperand registers(this, node->child2());
    3721         GPRTemporary result(this);
    3722         GPRReg registersGPR = registers.gpr();
    3723         GPRReg resultGPR = result.gpr();
    3724 
    3725         m_jit.load64(JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register)), resultGPR);
     3663        m_jit.load64(JITCompiler::Address(baseGPR, JSEnvironmentRecord::offsetOfVariable(node->scopeOffset())), resultGPR);
    37263664        jsValueResult(resultGPR, node);
    37273665        break;
    37283666    }
    37293667    case PutClosureVar: {
    3730         speculate(node, node->child1());
    3731 
    3732         StorageOperand registers(this, node->child2());
    3733         JSValueOperand value(this, node->child3());
    3734 
    3735         GPRReg registersGPR = registers.gpr();
     3668        SpeculateCellOperand base(this, node->child1());
     3669        JSValueOperand value(this, node->child2());
     3670
     3671        GPRReg baseGPR = base.gpr();
    37363672        GPRReg valueGPR = value.gpr();
    37373673
    3738         m_jit.store64(valueGPR, JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register)));
     3674        m_jit.store64(valueGPR, JITCompiler::Address(baseGPR, JSEnvironmentRecord::offsetOfVariable(node->scopeOffset())));
    37393675        noResult(node);
    37403676        break;
     
    40633999        GPRTemporary result(this);
    40644000
    4065         m_jit.load64(node->registerPointer(), result.gpr());
     4001        m_jit.load64(node->variablePointer(), result.gpr());
    40664002
    40674003        jsValueResult(result.gpr(), node);
     
    40724008        JSValueOperand value(this, node->child1());
    40734009
    4074         m_jit.store64(value.gpr(), node->registerPointer());
     4010        m_jit.store64(value.gpr(), node->variablePointer());
    40754011
    40764012        noResult(node);
     
    43194255    case CallForwardVarargs:
    43204256    case ConstructVarargs:
     4257    case ConstructForwardVarargs:
    43214258        emitCall(node);
    43224259        break;
     
    43664303    }
    43674304       
     4305    case ForwardVarargs: {
     4306        compileForwardVarargs(node);
     4307        break;
     4308    }
     4309       
    43684310    case CreateActivation: {
    4369         DFG_ASSERT(m_jit.graph(), node, !node->origin.semantic.inlineCallFrame);
    4370        
    4371         GPRTemporary result(this);
    4372         GPRReg resultGPR = result.gpr();
    4373         SpeculateCellOperand scope(this, node->child2());
    4374         GPRReg scopeGPR = scope.gpr();
    4375 
    4376         flushRegisters();
    4377         callOperation(operationCreateActivation, resultGPR, scopeGPR, framePointerOffsetToGetActivationRegisters());
    4378 
    4379         cellResult(resultGPR, node);
    4380         break;
    4381     }
    4382        
    4383     case CreateArguments: {
    4384         JSValueOperand value(this, node->child1());
    4385         GPRTemporary scratch1(this);
    4386         GPRTemporary scratch2(this);
    4387         GPRTemporary result(this, Reuse, value);
    4388        
    4389         GPRReg valueGPR = value.gpr();
    4390         GPRReg scratchGPR1 = scratch1.gpr();
    4391         GPRReg scratchGPR2 = scratch2.gpr();
    4392         GPRReg resultGPR = result.gpr();
    4393        
    4394         m_jit.move(valueGPR, resultGPR);
    4395        
    4396         if (node->origin.semantic.inlineCallFrame) {
    4397             JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR);
    4398             addSlowPathGenerator(
    4399                 slowPathCall(
    4400                     notCreated, this, operationCreateInlinedArguments, resultGPR,
    4401                     node->origin.semantic.inlineCallFrame));
    4402             cellResult(resultGPR, node);
    4403             break;
    4404         }
    4405 
    4406         FunctionExecutable* executable = jsCast<FunctionExecutable*>(m_jit.graph().executableFor(node->origin.semantic));
    4407         if (m_jit.codeBlock()->hasSlowArguments()
    4408             || executable->isStrictMode()
    4409             || !executable->parameterCount()) {
    4410             JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR);
    4411             addSlowPathGenerator(
    4412                 slowPathCall(notCreated, this, operationCreateArgumentsForDFG, resultGPR));
    4413             cellResult(resultGPR, node);
    4414             break;
    4415         }
    4416 
    4417         JITCompiler::Jump alreadyCreated = m_jit.branchTest64(JITCompiler::NonZero, resultGPR);
    4418 
    4419         MacroAssembler::JumpList slowPaths;
    4420         emitAllocateArguments(resultGPR, scratchGPR1, scratchGPR2, slowPaths);
    4421         addSlowPathGenerator(
    4422             slowPathCall(slowPaths, this, operationCreateArgumentsForDFG, resultGPR));
    4423 
    4424         alreadyCreated.link(&m_jit);
    4425         cellResult(resultGPR, node);
    4426         break;
    4427     }
    4428 
    4429     case TearOffArguments: {
    4430         JSValueOperand unmodifiedArgumentsValue(this, node->child1());
    4431         JSValueOperand activationValue(this, node->child2());
    4432         GPRReg unmodifiedArgumentsValueGPR = unmodifiedArgumentsValue.gpr();
    4433         GPRReg activationValueGPR = activationValue.gpr();
    4434 
    4435         JITCompiler::Jump created = m_jit.branchTest64(JITCompiler::NonZero, unmodifiedArgumentsValueGPR);
    4436 
    4437         if (node->origin.semantic.inlineCallFrame) {
    4438             addSlowPathGenerator(
    4439                 slowPathCall(
    4440                     created, this, operationTearOffInlinedArguments, NoResult,
    4441                     unmodifiedArgumentsValueGPR, activationValueGPR, node->origin.semantic.inlineCallFrame));
    4442         } else {
    4443             addSlowPathGenerator(
    4444                 slowPathCall(
    4445                     created, this, operationTearOffArguments, NoResult, unmodifiedArgumentsValueGPR, activationValueGPR));
    4446         }
    4447        
    4448         noResult(node);
    4449         break;
    4450     }
    4451        
    4452     case GetMyArgumentsLength: {
    4453         GPRTemporary result(this);
    4454         GPRReg resultGPR = result.gpr();
    4455        
    4456         if (!isEmptySpeculation(
    4457                 m_state.variables().operand(
    4458                     m_jit.graph().argumentsRegisterFor(node->origin.semantic)).m_type)) {
    4459             speculationCheck(
    4460                 ArgumentsEscaped, JSValueRegs(), 0,
    4461                 m_jit.branchTest64(
    4462                     JITCompiler::NonZero,
    4463                     JITCompiler::addressFor(
    4464                         m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic))));
    4465         }
    4466        
    4467         if (node->origin.semantic.inlineCallFrame
    4468             && !node->origin.semantic.inlineCallFrame->isVarargs()) {
    4469             m_jit.move(
    4470                 TrustedImm32(node->origin.semantic.inlineCallFrame->arguments.size() - 1),
    4471                 resultGPR);
    4472         } else {
    4473             VirtualRegister argumentCountRegister;
    4474             if (!node->origin.semantic.inlineCallFrame)
    4475                 argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
    4476             else
    4477                 argumentCountRegister = node->origin.semantic.inlineCallFrame->argumentCountRegister;
    4478             m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), resultGPR);
    4479             m_jit.sub32(TrustedImm32(1), resultGPR);
    4480         }
    4481         int32Result(resultGPR, node);
    4482         break;
    4483     }
    4484        
    4485     case GetMyArgumentsLengthSafe: {
    4486         GPRTemporary result(this);
    4487         GPRReg resultGPR = result.gpr();
    4488        
    4489         JITCompiler::Jump created = m_jit.branchTest64(
    4490             JITCompiler::NonZero,
    4491             JITCompiler::addressFor(
    4492                 m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic)));
    4493        
    4494         if (node->origin.semantic.inlineCallFrame
    4495             && !node->origin.semantic.inlineCallFrame->isVarargs()) {
    4496             m_jit.move(
    4497                 Imm64(JSValue::encode(jsNumber(node->origin.semantic.inlineCallFrame->arguments.size() - 1))),
    4498                 resultGPR);
    4499         } else {
    4500             VirtualRegister argumentCountRegister;
    4501             if (!node->origin.semantic.inlineCallFrame)
    4502                 argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
    4503             else
    4504                 argumentCountRegister = node->origin.semantic.inlineCallFrame->argumentCountRegister;
    4505             m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), resultGPR);
    4506             m_jit.sub32(TrustedImm32(1), resultGPR);
    4507             m_jit.or64(GPRInfo::tagTypeNumberRegister, resultGPR);
    4508         }
    4509        
    4510         addSlowPathGenerator(
    4511             slowPathCall(
    4512                 created, this, operationGetArgumentsLength, resultGPR,
    4513                 m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic).offset()));
    4514        
    4515         jsValueResult(resultGPR, node);
    4516         break;
    4517     }
    4518        
    4519     case GetMyArgumentByVal: {
    4520         SpeculateStrictInt32Operand index(this, node->child1());
    4521         GPRTemporary result(this);
    4522         GPRReg indexGPR = index.gpr();
    4523         GPRReg resultGPR = result.gpr();
    4524 
    4525         if (!isEmptySpeculation(
    4526                 m_state.variables().operand(
    4527                     m_jit.graph().argumentsRegisterFor(node->origin.semantic)).m_type)) {
    4528             speculationCheck(
    4529                 ArgumentsEscaped, JSValueRegs(), 0,
    4530                 m_jit.branchTest64(
    4531                     JITCompiler::NonZero,
    4532                     JITCompiler::addressFor(
    4533                         m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic))));
    4534         }
    4535 
    4536         if (node->origin.semantic.inlineCallFrame
    4537             && !node->origin.semantic.inlineCallFrame->isVarargs()) {
    4538             speculationCheck(
    4539                 Uncountable, JSValueRegs(), 0,
    4540                 m_jit.branch32(
    4541                     JITCompiler::AboveOrEqual,
    4542                     indexGPR,
    4543                     Imm32(node->origin.semantic.inlineCallFrame->arguments.size() - 1)));
    4544         } else {
    4545             VirtualRegister argumentCountRegister;
    4546             if (!node->origin.semantic.inlineCallFrame)
    4547                 argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
    4548             else
    4549                 argumentCountRegister = node->origin.semantic.inlineCallFrame->argumentCountRegister;
    4550             m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), resultGPR);
    4551             m_jit.sub32(TrustedImm32(1), resultGPR);
    4552             speculationCheck(
    4553                 Uncountable, JSValueRegs(), 0,
    4554                 m_jit.branch32(JITCompiler::AboveOrEqual, indexGPR, resultGPR));
    4555         }
    4556 
    4557         JITCompiler::JumpList slowArgument;
    4558         JITCompiler::JumpList slowArgumentOutOfBounds;
    4559         if (m_jit.symbolTableFor(node->origin.semantic)->slowArguments()) {
    4560             DFG_ASSERT(m_jit.graph(), node, !node->origin.semantic.inlineCallFrame);
    4561             const SlowArgument* slowArguments = m_jit.graph().m_slowArguments.get();
    4562            
    4563             slowArgumentOutOfBounds.append(
    4564                 m_jit.branch32(
    4565                     JITCompiler::AboveOrEqual, indexGPR,
    4566                     Imm32(m_jit.symbolTableFor(node->origin.semantic)->parameterCount())));
    4567 
    4568             COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
    4569             m_jit.move(ImmPtr(slowArguments), resultGPR);
    4570             m_jit.load32(
    4571                 JITCompiler::BaseIndex(
    4572                     resultGPR, indexGPR, JITCompiler::TimesEight,
    4573                     OBJECT_OFFSETOF(SlowArgument, index)),
    4574                 resultGPR);
    4575             m_jit.signExtend32ToPtr(resultGPR, resultGPR);
    4576             m_jit.load64(
    4577                 JITCompiler::BaseIndex(
    4578                     GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight),
    4579                 resultGPR);
    4580             slowArgument.append(m_jit.jump());
    4581         }
    4582         slowArgumentOutOfBounds.link(&m_jit);
    4583 
    4584         m_jit.load64(
    4585             JITCompiler::BaseIndex(
    4586                 GPRInfo::callFrameRegister, indexGPR, JITCompiler::TimesEight, m_jit.offsetOfArguments(node->origin.semantic)),
    4587             resultGPR);
    4588 
    4589         slowArgument.link(&m_jit);
    4590         jsValueResult(resultGPR, node);
    4591         break;
    4592     }
    4593        
    4594     case GetMyArgumentByValSafe: {
    4595         SpeculateStrictInt32Operand index(this, node->child1());
    4596         GPRTemporary result(this);
    4597         GPRReg indexGPR = index.gpr();
    4598         GPRReg resultGPR = result.gpr();
    4599        
    4600         JITCompiler::JumpList slowPath;
    4601         slowPath.append(
    4602             m_jit.branchTest64(
    4603                 JITCompiler::NonZero,
    4604                 JITCompiler::addressFor(
    4605                     m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic))));
    4606        
    4607         if (node->origin.semantic.inlineCallFrame
    4608             && !node->origin.semantic.inlineCallFrame->isVarargs()) {
    4609             slowPath.append(
    4610                 m_jit.branch32(
    4611                     JITCompiler::AboveOrEqual,
    4612                     resultGPR,
    4613                     Imm32(node->origin.semantic.inlineCallFrame->arguments.size() - 1)));
    4614         } else {
    4615             VirtualRegister argumentCountRegister;
    4616             if (!node->origin.semantic.inlineCallFrame)
    4617                 argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
    4618             else
    4619                 argumentCountRegister = node->origin.semantic.inlineCallFrame->argumentCountRegister;
    4620             m_jit.load32(JITCompiler::payloadFor(argumentCountRegister), resultGPR);
    4621             m_jit.sub32(TrustedImm32(1), resultGPR);
    4622             slowPath.append(
    4623                 m_jit.branch32(JITCompiler::AboveOrEqual, indexGPR, resultGPR));
    4624         }
    4625        
    4626         JITCompiler::JumpList slowArgument;
    4627         JITCompiler::JumpList slowArgumentOutOfBounds;
    4628         if (m_jit.symbolTableFor(node->origin.semantic)->slowArguments()) {
    4629             DFG_ASSERT(m_jit.graph(), node, !node->origin.semantic.inlineCallFrame);
    4630             const SlowArgument* slowArguments = m_jit.graph().m_slowArguments.get();
    4631 
    4632             slowArgumentOutOfBounds.append(
    4633                 m_jit.branch32(
    4634                     JITCompiler::AboveOrEqual, indexGPR,
    4635                     Imm32(m_jit.symbolTableFor(node->origin.semantic)->parameterCount())));
    4636 
    4637             COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
    4638             m_jit.move(ImmPtr(slowArguments), resultGPR);
    4639             m_jit.load32(
    4640                 JITCompiler::BaseIndex(
    4641                     resultGPR, indexGPR, JITCompiler::TimesEight,
    4642                     OBJECT_OFFSETOF(SlowArgument, index)),
    4643                 resultGPR);
    4644             m_jit.signExtend32ToPtr(resultGPR, resultGPR);
    4645             m_jit.load64(
    4646                 JITCompiler::BaseIndex(
    4647                     GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight),
    4648                 resultGPR);
    4649             slowArgument.append(m_jit.jump());
    4650         }
    4651         slowArgumentOutOfBounds.link(&m_jit);
    4652 
    4653         m_jit.load64(
    4654             JITCompiler::BaseIndex(
    4655                 GPRInfo::callFrameRegister, indexGPR, JITCompiler::TimesEight, m_jit.offsetOfArguments(node->origin.semantic)),
    4656             resultGPR);
    4657        
    4658         if (node->origin.semantic.inlineCallFrame) {
    4659             addSlowPathGenerator(
    4660                 slowPathCall(
    4661                     slowPath, this, operationGetInlinedArgumentByVal, resultGPR,
    4662                     m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic).offset(),
    4663                     node->origin.semantic.inlineCallFrame,
    4664                     indexGPR));
    4665         } else {
    4666             addSlowPathGenerator(
    4667                 slowPathCall(
    4668                     slowPath, this, operationGetArgumentByVal, resultGPR,
    4669                     m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic).offset(),
    4670                     indexGPR));
    4671         }
    4672        
    4673         slowArgument.link(&m_jit);
    4674         jsValueResult(resultGPR, node);
    4675         break;
    4676     }
    4677        
    4678     case CheckArgumentsNotCreated: {
    4679         ASSERT(!isEmptySpeculation(
    4680             m_state.variables().operand(
    4681                 m_jit.graph().argumentsRegisterFor(node->origin.semantic)).m_type));
    4682         speculationCheck(
    4683             ArgumentsEscaped, JSValueRegs(), 0,
    4684             m_jit.branchTest64(
    4685                 JITCompiler::NonZero,
    4686                 JITCompiler::addressFor(
    4687                     m_jit.graph().machineArgumentsRegisterFor(node->origin.semantic))));
    4688         noResult(node);
    4689         break;
    4690     }
    4691        
    4692     case NewFunctionNoCheck:
    4693         compileNewFunctionNoCheck(node);
    4694         break;
    4695        
    4696     case NewFunction: {
    4697         JSValueOperand value(this, node->child1());
    4698         GPRTemporary result(this, Reuse, value);
    4699         SpeculateCellOperand scope(this, node->child2());
    4700         GPRReg scopeGPR = scope.gpr();
    4701        
    4702         GPRReg valueGPR = value.gpr();
    4703         GPRReg resultGPR = result.gpr();
    4704        
    4705         m_jit.move(valueGPR, resultGPR);
    4706        
    4707         JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR);
    4708        
    4709         addSlowPathGenerator(
    4710             slowPathCall(
    4711                 notCreated, this, operationNewFunction,
    4712                 resultGPR, scopeGPR, node->castOperand<FunctionExecutable*>()));
    4713        
    4714         jsValueResult(resultGPR, node);
    4715         break;
    4716     }
    4717        
    4718     case NewFunctionExpression:
    4719         compileNewFunctionExpression(node);
     4311        compileCreateActivation(node);
     4312        break;
     4313    }
     4314       
     4315    case CreateDirectArguments: {
     4316        compileCreateDirectArguments(node);
     4317        break;
     4318    }
     4319       
     4320    case GetFromArguments: {
     4321        compileGetFromArguments(node);
     4322        break;
     4323    }
     4324       
     4325    case PutToArguments: {
     4326        compilePutToArguments(node);
     4327        break;
     4328    }
     4329       
     4330    case CreateScopedArguments: {
     4331        compileCreateScopedArguments(node);
     4332        break;
     4333    }
     4334       
     4335    case CreateClonedArguments: {
     4336        compileCreateClonedArguments(node);
     4337        break;
     4338    }
     4339       
     4340    case NewFunction:
     4341        compileNewFunction(node);
    47204342        break;
    47214343       
     
    51534775    case BottomValue:
    51544776    case PhantomNewObject:
     4777    case GetMyArgumentByVal:
    51554778    case PutHint:
    51564779    case CheckStructureImmediate:
  • trunk/Source/JavaScriptCore/dfg/DFGStackLayoutPhase.cpp

    r180691 r181993  
    4747    bool run()
    4848    {
    49         SymbolTable* symbolTable = codeBlock()->symbolTable();
    50 
    5149        // This enumerates the locals that we actually care about and packs them. So for example
    5250        // if we use local 1, 3, 4, 5, 7, then we remap them: 1->0, 3->1, 4->2, 5->3, 7->4. We
     
    8583                }
    8684                   
    87                 case LoadVarargs: {
     85                case LoadVarargs:
     86                case ForwardVarargs: {
    8887                    LoadVarargsData* data = node->loadVarargsData();
    8988                    if (data->count.isLocal())
     
    115114        }
    116115       
    117         // Ensure that captured variables and captured inline arguments are pinned down.
    118         // They should have been because of flushes, except that the flushes can be optimized
    119         // away.
    120         if (symbolTable) {
    121             for (int i = symbolTable->captureStart(); i > symbolTable->captureEnd(); i--)
    122                 usedLocals.set(VirtualRegister(i).toLocal());
    123         }
    124         if (codeBlock()->usesArguments()) {
    125             usedLocals.set(codeBlock()->argumentsRegister().toLocal());
    126             usedLocals.set(unmodifiedArgumentsRegister(codeBlock()->argumentsRegister()).toLocal());
    127         }
    128         if (codeBlock()->uncheckedActivationRegister().isValid())
    129             usedLocals.set(codeBlock()->activationRegister().toLocal());
    130116        for (InlineCallFrameSet::iterator iter = m_graph.m_plan.inlineCallFrames->begin(); !!iter; ++iter) {
    131117            InlineCallFrame* inlineCallFrame = *iter;
    132             if (!m_graph.usesArguments(inlineCallFrame))
    133                 continue;
    134            
    135             VirtualRegister argumentsRegister = m_graph.argumentsRegisterFor(inlineCallFrame);
    136             usedLocals.set(argumentsRegister.toLocal());
    137             usedLocals.set(unmodifiedArgumentsRegister(argumentsRegister).toLocal());
    138118           
    139119            if (inlineCallFrame->isVarargs()) {
     
    194174        }
    195175       
    196         if (codeBlock()->usesArguments()) {
    197             VirtualRegister argumentsRegister =
    198                 assign(allocation, codeBlock()->argumentsRegister());
    199             RELEASE_ASSERT(
    200                 assign(allocation, unmodifiedArgumentsRegister(codeBlock()->argumentsRegister()))
    201                 == unmodifiedArgumentsRegister(argumentsRegister));
    202             codeBlock()->setArgumentsRegister(argumentsRegister);
    203         }
    204        
    205         if (codeBlock()->uncheckedActivationRegister().isValid()) {
    206             codeBlock()->setActivationRegister(
    207                 assign(allocation, codeBlock()->activationRegister()));
    208         }
    209        
    210176        // This register is never valid for DFG code blocks.
     177        codeBlock()->setActivationRegister(VirtualRegister());
    211178        codeBlock()->setScopeRegister(VirtualRegister());
    212179
     
    214181            InlineVariableData data = m_graph.m_inlineVariableData[i];
    215182            InlineCallFrame* inlineCallFrame = data.inlineCallFrame;
    216            
    217             if (m_graph.usesArguments(inlineCallFrame)) {
    218                 inlineCallFrame->argumentsRegister = assign(
    219                     allocation, m_graph.argumentsRegisterFor(inlineCallFrame));
    220 
    221                 RELEASE_ASSERT(
    222                     assign(allocation, unmodifiedArgumentsRegister(m_graph.argumentsRegisterFor(inlineCallFrame)))
    223                     == unmodifiedArgumentsRegister(inlineCallFrame->argumentsRegister));
    224             }
    225183           
    226184            if (inlineCallFrame->isVarargs()) {
     
    252210            } else
    253211                RELEASE_ASSERT(inlineCallFrame->calleeRecovery.isConstant());
    254         }
    255        
    256         if (symbolTable) {
    257             if (symbolTable->captureCount()) {
    258                 unsigned captureStartLocal = allocation[
    259                     VirtualRegister(codeBlock()->symbolTable()->captureStart()).toLocal()];
    260                 ASSERT(captureStartLocal != UINT_MAX);
    261                 m_graph.m_machineCaptureStart = virtualRegisterForLocal(captureStartLocal).offset();
    262             } else
    263                 m_graph.m_machineCaptureStart = virtualRegisterForLocal(0).offset();
    264        
    265             // This is an abomination. If we had captured an argument then the argument ends
    266             // up being "slow", meaning that loads of the argument go through an extra lookup
    267             // table.
    268             if (const SlowArgument* slowArguments = symbolTable->slowArguments()) {
    269                 auto newSlowArguments = std::make_unique<SlowArgument[]>(
    270                     symbolTable->parameterCount());
    271                 for (size_t i = symbolTable->parameterCount(); i--;) {
    272                     newSlowArguments[i] = slowArguments[i];
    273                     newSlowArguments[i].index = assign(allocation, VirtualRegister(slowArguments[i].index)).offset();
    274                 }
    275            
    276                 m_graph.m_slowArguments = WTF::move(newSlowArguments);
    277             }
    278212        }
    279213       
     
    292226                    }
    293227                       
    294                     case LoadVarargs: {
     228                    case LoadVarargs:
     229                    case ForwardVarargs: {
    295230                        LoadVarargsData* data = node->loadVarargsData();
    296231                        data->machineCount = assign(allocation, data->count);
  • trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp

    r180279 r181993  
    238238            VirtualRegister local = m_node->local();
    239239           
    240             if (m_node->variableAccessData()->isCaptured()) {
    241                 for (unsigned i = m_nodeIndex; i--;) {
    242                     Node* node = m_block->at(i);
    243                     bool done = false;
    244                     switch (node->op()) {
    245                     case GetLocal:
    246                     case Flush:
    247                         if (node->local() == local)
    248                             done = true;
    249                         break;
    250                
    251                     case GetLocalUnlinked:
    252                         if (node->unlinkedLocal() == local)
    253                             done = true;
    254                         break;
    255                
    256                     case SetLocal: {
    257                         if (node->local() != local)
    258                             break;
    259                         setLocal = node;
    260                         done = true;
    261                         break;
    262                     }
    263                
    264                     case Phantom:
    265                     case Check:
    266                     case HardPhantom:
    267                     case MovHint:
    268                     case JSConstant:
    269                     case DoubleConstant:
    270                     case Int52Constant:
    271                     case GetScope:
    272                     case PhantomLocal:
    273                     case GetCallee:
    274                     case CountExecution:
    275                         break;
    276                
    277                     default:
    278                         done = true;
    279                         break;
    280                     }
    281                     if (done)
    282                         break;
    283                 }
    284             } else {
    285                 for (unsigned i = m_nodeIndex; i--;) {
    286                     Node* node = m_block->at(i);
    287                     if (node->op() == SetLocal && node->local() == local) {
    288                         setLocal = node;
    289                         break;
    290                     }
    291                     if (accessesOverlap(m_graph, node, AbstractHeap(Variables, local)))
    292                         break;
    293                 }
     240            for (unsigned i = m_nodeIndex; i--;) {
     241                Node* node = m_block->at(i);
     242                if (node->op() == SetLocal && node->local() == local) {
     243                    setLocal = node;
     244                    break;
     245                }
     246                if (accessesOverlap(m_graph, node, AbstractHeap(Stack, local)))
     247                    break;
    294248            }
    295249           
  • trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp

    r173993 r181993  
    11/*
    2  * Copyright (C) 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    119119                    break;
    120120                   
     121                case CreateDirectArguments:
     122                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->directArgumentsStructure());
     123                    break;
     124                   
     125                case CreateScopedArguments:
     126                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->scopedArgumentsStructure());
     127                    break;
     128                   
    121129                case NewRegexp:
    122130                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->regExpStructure());
    123131                    break;
    124132                   
    125                 case NewFunctionExpression:
    126                 case NewFunctionNoCheck:
     133                case NewFunction:
    127134                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->functionStructure());
    128135                    break;
  • trunk/Source/JavaScriptCore/dfg/DFGUnificationPhase.cpp

    r164229 r181993  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7171            VariableAccessData* data = &m_graph.m_variableAccessData[i];
    7272            data->find()->predict(data->nonUnifiedPrediction());
    73             data->find()->mergeIsCaptured(data->isCaptured());
    7473            data->find()->mergeStructureCheckHoistingFailed(data->structureCheckHoistingFailed());
    7574            data->find()->mergeCheckArrayHoistingFailed(data->checkArrayHoistingFailed());
  • trunk/Source/JavaScriptCore/dfg/DFGValidate.cpp

    r181650 r181993  
    439439                case CheckInBounds:
    440440                case PhantomNewObject:
     441                case GetMyArgumentByVal:
    441442                case PutHint:
    442443                case CheckStructureImmediate:
     
    455456                switch (node->op()) {
    456457                case GetLocal:
    457                     if (node->variableAccessData()->isCaptured())
    458                         break;
    459458                    // Ignore GetLocal's that we know to be dead, but that the graph
    460459                    // doesn't yet know to be dead.
     
    466465                    break;
    467466                case SetLocal:
    468                     if (node->variableAccessData()->isCaptured())
    469                         break;
    470467                    // Only record the first SetLocal. There may be multiple SetLocals
    471468                    // because of flushing.
     
    475472                    break;
    476473                case SetArgument:
    477                     if (node->variableAccessData()->isCaptured())
    478                         break;
    479474                    // This acts like a reset. It's ok to have a second GetLocal for a local in the same
    480475                    // block if we had a SetArgument for that local.
  • trunk/Source/JavaScriptCore/dfg/DFGValueSource.cpp

    r179503 r181993  
    11/*
    2  * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6060        out.print("Double:", virtualRegister());
    6161        break;
    62     case ArgumentsSource:
    63         out.print("Arguments");
    64         break;
    6562    case HaveNode:
    6663        out.print("Node(", m_value, ")");
  • trunk/Source/JavaScriptCore/dfg/DFGValueSource.h

    r168051 r181993  
    11/*
    2  * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4646    BooleanInJSStack,
    4747    DoubleInJSStack,
    48     ArgumentsSource,
    4948    SourceIsDead,
    5049    HaveNode
     
    6665    case DataFormatDead:
    6766        return SourceIsDead;
    68     case DataFormatArguments:
    69         return ArgumentsSource;
    7067    default:
    7168        RELEASE_ASSERT(dataFormat & DataFormatJS);
     
    8986    case DoubleInJSStack:
    9087        return DataFormatDouble;
    91     case ArgumentsSource:
    92         return DataFormatArguments;
    9388    case SourceIsDead:
    9489        return DataFormatDead;
     
    121116        : m_kind(valueSourceKind)
    122117    {
    123         ASSERT(kind() == ArgumentsSource || kind() == SourceIsDead || kind() == ArgumentsSource);
     118        ASSERT(kind() == SourceIsDead);
    124119    }
    125120   
     
    158153        case FlushedBoolean:
    159154            return ValueSource(BooleanInJSStack, where);
    160         case FlushedArguments:
    161             return ValueSource(ArgumentsSource);
    162155        }
    163156        RELEASE_ASSERT_NOT_REACHED();
     
    197190            return ValueRecovery::constant(jsUndefined());
    198191           
    199         case ArgumentsSource:
    200             return ValueRecovery::argumentsThatWereNotCreated();
    201            
    202192        default:
    203193            return ValueRecovery::displacedInJSStack(virtualRegister(), dataFormat());
  • trunk/Source/JavaScriptCore/dfg/DFGVariableAccessData.cpp

    r174371 r181993  
    11/*
    2  * Copyright (C) 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3636    , m_argumentAwarePrediction(SpecNone)
    3737    , m_flags(0)
    38     , m_isCaptured(false)
    3938    , m_shouldNeverUnbox(false)
    40     , m_isArgumentsAlias(false)
    4139    , m_structureCheckHoistingFailed(false)
    4240    , m_checkArrayHoistingFailed(false)
     
    4846}
    4947
    50 VariableAccessData::VariableAccessData(VirtualRegister local, bool isCaptured)
     48VariableAccessData::VariableAccessData(VirtualRegister local)
    5149    : m_local(local)
    5250    , m_prediction(SpecNone)
    5351    , m_argumentAwarePrediction(SpecNone)
    5452    , m_flags(0)
    55     , m_isCaptured(isCaptured)
    56     , m_shouldNeverUnbox(isCaptured)
    57     , m_isArgumentsAlias(false)
     53    , m_shouldNeverUnbox(false)
    5854    , m_structureCheckHoistingFailed(false)
    5955    , m_checkArrayHoistingFailed(false)
     
    6359{
    6460    clearVotes();
    65 }
    66 
    67 bool VariableAccessData::mergeIsCaptured(bool isCaptured)
    68 {
    69     return checkAndSet(m_shouldNeverUnbox, m_shouldNeverUnbox || isCaptured)
    70         | checkAndSet(m_isCaptured, m_isCaptured || isCaptured);
    7161}
    7262
     
    199189    ASSERT(find() == this);
    200190   
    201     if (isArgumentsAlias())
    202         return FlushedArguments;
    203    
    204191    if (!shouldUnboxIfPossible())
    205192        return FlushedJSValue;
  • trunk/Source/JavaScriptCore/dfg/DFGVariableAccessData.h

    r174371 r181993  
    11/*
    2  * Copyright (C) 2011-2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4949public:
    5050    VariableAccessData();
    51     VariableAccessData(VirtualRegister local, bool isCaptured);
     51    VariableAccessData(VirtualRegister local);
    5252   
    5353    VirtualRegister local()
     
    6363    }
    6464
    65     bool mergeIsCaptured(bool isCaptured);
    66    
    67     bool isCaptured()
    68     {
    69         return m_isCaptured;
    70     }
    71    
    7265    bool mergeIsProfitableToUnbox(bool isProfitableToUnbox)
    7366    {
     
    8780    bool shouldNeverUnbox()
    8881    {
    89         ASSERT(!(m_isCaptured && !m_shouldNeverUnbox));
    9082        return m_shouldNeverUnbox;
    9183    }
     
    119111    }
    120112   
    121     bool mergeIsArgumentsAlias(bool isArgumentsAlias)
    122     {
    123         return checkAndSet(m_isArgumentsAlias, m_isArgumentsAlias || isArgumentsAlias);
    124     }
    125    
    126     bool isArgumentsAlias()
    127     {
    128         return m_isArgumentsAlias;
    129     }
    130    
    131113    bool mergeIsLoadedFrom(bool isLoadedFrom)
    132114    {
     
    194176        bool doubleState = m_doubleFormatState == UsingDoubleFormat;
    195177        ASSERT(!(doubleState && shouldNeverUnbox()));
    196         ASSERT(!(doubleState && isCaptured()));
    197178        return doubleState && isProfitableToUnbox();
    198179    }
     
    234215    NodeFlags m_flags;
    235216
    236     bool m_isCaptured;
    237217    bool m_shouldNeverUnbox;
    238     bool m_isArgumentsAlias;
    239218    bool m_structureCheckHoistingFailed;
    240219    bool m_checkArrayHoistingFailed;
  • trunk/Source/JavaScriptCore/dfg/DFGVariableAccessDataDump.cpp

    r164229 r181993  
    11/*
    2  * Copyright (C) 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6363    }
    6464   
    65     if (m_data->isCaptured())
    66         out.print("*");
    67     else if (m_data->shouldNeverUnbox())
     65    if (m_data->shouldNeverUnbox())
    6866        out.print("!");
    6967    else if (!m_data->shouldUnboxIfPossible())
  • trunk/Source/JavaScriptCore/dfg/DFGVariableAccessDataDump.h

    r164424 r181993  
    11/*
    2  * Copyright (C) 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
  • trunk/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp

    r171613 r181993  
    11/*
    2  * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    9292    }
    9393   
    94     if (node->op() == PhantomArguments) {
    95         recovery = ValueRecovery::argumentsThatWereNotCreated();
     94    if (node->op() == PhantomDirectArguments) {
     95        recovery = ValueRecovery::directArgumentsThatWereNotCreated(node->id());
     96        return true;
     97    }
     98   
     99    if (node->op() == PhantomClonedArguments) {
     100        recovery = ValueRecovery::outOfBandArgumentsThatWereNotCreated(node->id());
    96101        return true;
    97102    }
  • trunk/Source/JavaScriptCore/dfg/DFGVariableEventStream.h

    r171613 r181993  
    3333#include "DFGVariableEvent.h"
    3434#include "Operands.h"
     35#include "ValueRecovery.h"
    3536#include <wtf/Vector.h>
    3637
  • trunk/Source/JavaScriptCore/ftl/FTLAbstractHeap.cpp

    r177222 r181993  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5454}
    5555
     56void AbstractHeap::dump(PrintStream& out) const
     57{
     58    out.print(heapName());
     59    if (m_parent)
     60        out.print("->", *m_parent);
     61}
     62
     63void AbstractField::dump(PrintStream& out) const
     64{
     65    out.print(heapName(), "(", m_offset, ")");
     66    if (parent())
     67        out.print("->", *parent());
     68}
     69
    5670IndexedAbstractHeap::IndexedAbstractHeap(LContext context, AbstractHeap* parent, const char* heapName, ptrdiff_t offset, size_t elementSize)
    5771    : m_heapForAnyIndex(parent, heapName)
     
    177191}
    178192
     193void IndexedAbstractHeap::dump(PrintStream& out) const
     194{
     195    out.print("Indexed:", atAnyIndex());
     196}
     197
    179198NumberedAbstractHeap::NumberedAbstractHeap(LContext context, AbstractHeap* heap, const char* heapName)
    180199    : m_indexedHeap(context, heap, heapName, 0, 1)
     
    186205}
    187206
     207void NumberedAbstractHeap::dump(PrintStream& out) const
     208{
     209    out.print("Numbered: ", atAnyNumber());
     210}
     211
    188212AbsoluteAbstractHeap::AbsoluteAbstractHeap(LContext context, AbstractHeap* heap, const char* heapName)
    189213    : m_indexedHeap(context, heap, heapName, 0, 1)
     
    195219}
    196220
     221void AbsoluteAbstractHeap::dump(PrintStream& out) const
     222{
     223    out.print("Absolute:", atAnyAddress());
     224}
     225
    197226} } // namespace JSC::FTL
    198227
  • trunk/Source/JavaScriptCore/ftl/FTLAbstractHeap.h

    r177222 r181993  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    100100    void decorateInstruction(LValue instruction, const AbstractHeapRepository&) const;
    101101
     102    void dump(PrintStream&) const;
     103
    102104private:
    103105    friend class AbstractHeapRepository;
     
    136138    }
    137139   
     140    void dump(PrintStream&) const;
     141
    138142private:
    139143    ptrdiff_t m_offset;
     
    158162    TypedPointer baseIndex(Output& out, LValue base, LValue index, JSValue indexAsConstant = JSValue(), ptrdiff_t offset = 0);
    159163   
     164    void dump(PrintStream&) const;
     165
    160166private:
    161167    const AbstractField& returnInitialized(AbstractField& field, ptrdiff_t index)
     
    202208    const AbstractHeap& operator[](unsigned number) { return at(number); }
    203209
     210    void dump(PrintStream&) const;
     211
    204212private:
    205213   
     
    222230   
    223231    const AbstractHeap& operator[](void* address) { return at(address); }
     232
     233    void dump(PrintStream&) const;
    224234
    225235private:
  • trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.cpp

    r173837 r181993  
    11/*
    2  * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2929#if ENABLE(FTL_JIT)
    3030
     31#include "DirectArguments.h"
    3132#include "GetterSetter.h"
    3233#include "JSEnvironmentRecord.h"
     
    3435#include "JSScope.h"
    3536#include "JSCInlines.h"
     37#include "ScopedArguments.h"
     38#include "ScopedArgumentsTable.h"
    3639
    3740namespace JSC { namespace FTL {
  • trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h

    r181891 r181993  
    11/*
    2  * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3636
    3737#define FOR_EACH_ABSTRACT_HEAP(macro) \
    38     macro(length) \
    39     macro(structureTable) \
    40     macro(typedArrayProperties) \
    41     macro(WriteBarrierBuffer_bufferContents)
     38    macro(typedArrayProperties)
    4239
    4340#define FOR_EACH_ABSTRACT_FIELD(macro) \
     
    4744    macro(Butterfly_vectorLength, Butterfly::offsetOfVectorLength()) \
    4845    macro(CallFrame_callerFrame, CallFrame::callerFrameOffset()) \
     46    macro(DirectArguments_callee, DirectArguments::offsetOfCallee()) \
     47    macro(DirectArguments_length, DirectArguments::offsetOfLength()) \
     48    macro(DirectArguments_minCapacity, DirectArguments::offsetOfMinCapacity()) \
     49    macro(DirectArguments_overrides, DirectArguments::offsetOfOverrides()) \
    4950    macro(GetterSetter_getter, GetterSetter::offsetOfGetter()) \
    5051    macro(GetterSetter_setter, GetterSetter::offsetOfSetter()) \
     
    7172    macro(JSString_length, JSString::offsetOfLength()) \
    7273    macro(JSString_value, JSString::offsetOfValue()) \
    73     macro(JSEnvironmentRecord_registers, JSEnvironmentRecord::offsetOfRegisters()) \
     74    macro(JSSymbolTableObject_symbolTable, JSSymbolTableObject::offsetOfSymbolTable()) \
    7475    macro(JSWrapperObject_internalValue, JSWrapperObject::internalValueOffset()) \
    7576    macro(MarkedAllocator_freeListHead, MarkedAllocator::offsetOfFreeListHead()) \
    7677    macro(MarkedBlock_markBits, MarkedBlock::offsetOfMarks()) \
     78    macro(ScopedArguments_overrodeThings, ScopedArguments::offsetOfOverrodeThings()) \
     79    macro(ScopedArguments_scope, ScopedArguments::offsetOfScope()) \
     80    macro(ScopedArguments_table, ScopedArguments::offsetOfTable()) \
     81    macro(ScopedArguments_totalLength, ScopedArguments::offsetOfTotalLength()) \
     82    macro(ScopedArgumentsTable_arguments, ScopedArgumentsTable::offsetOfArguments()) \
     83    macro(ScopedArgumentsTable_length, ScopedArgumentsTable::offsetOfLength()) \
    7784    macro(StringImpl_data, StringImpl::dataOffset()) \
    7885    macro(StringImpl_hashAndFlags, StringImpl::flagsOffset()) \
     
    8390
    8491#define FOR_EACH_INDEXED_ABSTRACT_HEAP(macro) \
     92    macro(DirectArguments_storage, DirectArguments::storageOffset(), sizeof(EncodedJSValue)) \
     93    macro(JSEnvironmentRecord_variables, JSEnvironmentRecord::offsetOfVariables(), sizeof(EncodedJSValue)) \
     94    macro(JSPropertyNameEnumerator_cachedPropertyNamesVectorContents, 0, sizeof(WriteBarrier<JSString>)) \
    8595    macro(JSRopeString_fibers, JSRopeString::offsetOfFibers(), sizeof(WriteBarrier<JSString>)) \
     96    macro(MarkedSpace_Subspace_impreciseAllocators, OBJECT_OFFSETOF(MarkedSpace::Subspace, impreciseAllocators), sizeof(MarkedAllocator)) \
     97    macro(MarkedSpace_Subspace_preciseAllocators, OBJECT_OFFSETOF(MarkedSpace::Subspace, preciseAllocators), sizeof(MarkedAllocator)) \
     98    macro(ScopedArguments_overflowStorage, ScopedArguments::overflowStorageOffset(), sizeof(EncodedJSValue)) \
     99    macro(WriteBarrierBuffer_bufferContents, 0, sizeof(JSCell*)) \
    86100    macro(characters8, 0, sizeof(LChar)) \
    87101    macro(characters16, 0, sizeof(UChar)) \
     
    90104    macro(indexedContiguousProperties, 0, sizeof(EncodedJSValue)) \
    91105    macro(indexedArrayStorageProperties, 0, sizeof(EncodedJSValue)) \
     106    macro(scopedArgumentsTableArguments, 0, sizeof(int32_t)) \
    92107    macro(singleCharacterStrings, 0, sizeof(JSString*)) \
     108    macro(structureTable, 0, sizeof(Structure*)) \
    93109    macro(variables, 0, sizeof(Register))
    94110   
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r181891 r181993  
    4545    switch (node->op()) {
    4646    case JSConstant:
    47     case GetMyArgumentsLength:
    4847    case GetLocal:
    4948    case SetLocal:
     
    104103    case LoopHint:
    105104    case SkipScope:
    106     case GetClosureRegisters:
     105    case CreateActivation:
     106    case NewFunction:
    107107    case GetClosureVar:
    108108    case PutClosureVar:
     109    case CreateDirectArguments:
     110    case CreateScopedArguments:
     111    case CreateClonedArguments:
     112    case GetFromArguments:
     113    case PutToArguments:
    109114    case InvalidationPoint:
    110115    case StringCharAt:
     
    125130    case CallForwardVarargs:
    126131    case ConstructVarargs:
     132    case ConstructForwardVarargs:
    127133    case LoadVarargs:
    128134    case NativeCall:
     
    138144    case GetScope:
    139145    case AllocationProfileWatchpoint:
    140     case CheckArgumentsNotCreated:
    141146    case GetCallee:
     147    case GetArgumentCount:
    142148    case ToString:
    143149    case MakeRope:
     
    148154    case MultiPutByOffset:
    149155    case ToPrimitive:
    150     case PhantomArguments:
    151156    case Throw:
    152157    case ThrowReferenceError:
    153158    case Unreachable:
    154     case GetMyArgumentByVal:
    155159    case IsUndefined:
    156160    case IsBoolean:
     
    181185    case CheckStructureImmediate:
    182186    case MaterializeNewObject:
     187    case PhantomDirectArguments:
     188    case PhantomClonedArguments:
     189    case GetMyArgumentByVal:
     190    case ForwardVarargs:
    183191        // These are OK.
    184192        break;
     
    209217        case Array::Double:
    210218        case Array::Contiguous:
     219        case Array::DirectArguments:
     220        case Array::ScopedArguments:
    211221            break;
    212222        default:
     
    222232        case Array::Contiguous:
    223233        case Array::String:
     234        case Array::DirectArguments:
     235        case Array::ScopedArguments:
    224236            break;
    225237        default:
     
    248260        case Array::Double:
    249261        case Array::Contiguous:
     262        case Array::DirectArguments:
     263        case Array::ScopedArguments:
    250264            break;
    251265        default:
     
    365379        if (verboseCapabilities())
    366380            dataLog("FTL rejecting ", *graph.m_codeBlock, " because it doesn't belong to a function.\n");
    367         return CannotCompile;
    368     }
    369    
    370     if (graph.m_codeBlock->needsActivation()) {
    371         // Need this because although we also don't support
    372         // CreateActivation, we might not see those nodes in case of
    373         // OSR entry.
    374         // FIXME: Support activations.
    375         // https://bugs.webkit.org/show_bug.cgi?id=129576
    376         if (verboseCapabilities())
    377             dataLog("FTL rejecting ", *graph.m_codeBlock, " because it uses activations.\n");
    378381        return CannotCompile;
    379382    }
  • trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp

    r181990 r181993  
    141141static int offsetOfStackRegion(StackMaps::RecordMap& recordMap, uint32_t stackmapID)
    142142{
     143    if (stackmapID == UINT_MAX)
     144        return 0;
     145   
    143146    StackMaps::RecordMap::iterator iter = recordMap.find(stackmapID);
    144147    RELEASE_ASSERT(iter != recordMap.end());
     
    302305    StackMaps stackmaps = jitCode->stackmaps;
    303306   
    304     int localsOffset =
    305         offsetOfStackRegion(recordMap, state.capturedStackmapID) + graph.m_nextMachineLocal;
    306    
    307     int varargsSpillSlotsOffset;
    308     if (state.varargsSpillSlotsStackmapID != UINT_MAX)
    309         varargsSpillSlotsOffset = offsetOfStackRegion(recordMap, state.varargsSpillSlotsStackmapID);
    310     else
    311         varargsSpillSlotsOffset = 0;
     307    int localsOffset = offsetOfStackRegion(recordMap, state.capturedStackmapID) + graph.m_nextMachineLocal;
     308    int varargsSpillSlotsOffset = offsetOfStackRegion(recordMap, state.varargsSpillSlotsStackmapID);
    312309   
    313310    for (unsigned i = graph.m_inlineVariableData.size(); i--;) {
    314311        InlineCallFrame* inlineCallFrame = graph.m_inlineVariableData[i].inlineCallFrame;
    315        
    316         if (inlineCallFrame->argumentsRegister.isValid())
    317             inlineCallFrame->argumentsRegister += localsOffset;
    318312       
    319313        if (inlineCallFrame->argumentCountRegister.isValid())
     
    331325    }
    332326   
    333     if (codeBlock->usesArguments()) {
    334         codeBlock->setArgumentsRegister(
    335             VirtualRegister(codeBlock->argumentsRegister().offset() + localsOffset));
    336     }
    337 
    338327    MacroAssembler::Label stackOverflowException;
    339328
     
    397386            exit.m_patchableCodeOffset = linkBuffer->offsetOf(info.m_thunkJump);
    398387           
    399             for (unsigned j = exit.m_values.size(); j--;) {
    400                 ExitValue value = exit.m_values[j];
    401                 if (!value.isInJSStackSomehow())
    402                     continue;
    403                 if (!value.virtualRegister().isLocal())
    404                     continue;
    405                 exit.m_values[j] = value.withVirtualRegister(
    406                     VirtualRegister(value.virtualRegister().offset() + localsOffset));
    407             }
     388            for (unsigned j = exit.m_values.size(); j--;)
     389                exit.m_values[j] = exit.m_values[j].withLocalsOffset(localsOffset);
     390            for (ExitTimeObjectMaterialization* materialization : exit.m_materializations)
     391                materialization->accountForLocalsOffset(localsOffset);
    408392           
    409393            if (verboseCompilationEnabled()) {
     
    589573       
    590574        CCallHelpers fastPathJIT(&vm, codeBlock);
    591         call.emit(fastPathJIT, graph, varargsSpillSlotsOffset);
     575        call.emit(fastPathJIT, varargsSpillSlotsOffset);
    592576       
    593577        char* startOfIC = bitwise_cast<char*>(generatedFunction) + call.m_instructionOffset;
  • trunk/Source/JavaScriptCore/ftl/FTLExitArgument.cpp

    r153121 r181993  
    3333void ExitArgument::dump(PrintStream& out) const
    3434{
    35     out.print("arg", argument(), " as ", format());
     35    out.print("#", argument(), " as ", format());
    3636}
    3737
  • trunk/Source/JavaScriptCore/ftl/FTLExitPropertyValue.cpp

    r173993 r181993  
    11/*
    2  * Copyright (C) 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3131namespace JSC { namespace FTL {
    3232
     33ExitPropertyValue ExitPropertyValue::withLocalsOffset(int offset) const
     34{
     35    return ExitPropertyValue(m_location, m_value.withLocalsOffset(offset));
     36}
     37
    3338void ExitPropertyValue::dump(PrintStream& out) const
    3439{
  • trunk/Source/JavaScriptCore/ftl/FTLExitPropertyValue.h

    r173993 r181993  
    11/*
    2  * Copyright (C) 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5252    const ExitValue& value() const { return m_value; }
    5353   
     54    ExitPropertyValue withLocalsOffset(int offset) const;
     55   
    5456    void dump(PrintStream& out) const;
    5557
  • trunk/Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.cpp

    r173993 r181993  
    11/*
    2  * Copyright (C) 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3535using namespace JSC::DFG;
    3636
    37 ExitTimeObjectMaterialization::ExitTimeObjectMaterialization(NodeType type)
     37ExitTimeObjectMaterialization::ExitTimeObjectMaterialization(NodeType type, CodeOrigin codeOrigin)
    3838    : m_type(type)
     39    , m_origin(codeOrigin)
    3940{
    4041}
     
    5960}
    6061
     62void ExitTimeObjectMaterialization::accountForLocalsOffset(int offset)
     63{
     64    for (ExitPropertyValue& property : m_properties)
     65        property = property.withLocalsOffset(offset);
     66}
     67
    6168void ExitTimeObjectMaterialization::dump(PrintStream& out) const
    6269{
  • trunk/Source/JavaScriptCore/ftl/FTLExitTimeObjectMaterialization.h

    r173993 r181993  
    11/*
    2  * Copyright (C) 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3939    WTF_MAKE_NONCOPYABLE(ExitTimeObjectMaterialization)
    4040public:
    41     ExitTimeObjectMaterialization(DFG::NodeType);
     41    ExitTimeObjectMaterialization(DFG::NodeType, CodeOrigin);
    4242    ~ExitTimeObjectMaterialization();
    4343   
     
    4545   
    4646    DFG::NodeType type() const { return m_type; }
     47    CodeOrigin origin() const { return m_origin; }
    4748   
    4849    ExitValue get(DFG::PromotedLocationDescriptor) const;
    4950    const Vector<ExitPropertyValue>& properties() const { return m_properties; }
     51   
     52    void accountForLocalsOffset(int offset);
    5053   
    5154    void dump(PrintStream& out) const;
     
    5356private:
    5457    DFG::NodeType m_type;
     58    CodeOrigin m_origin;
    5559    Vector<ExitPropertyValue> m_properties;
    5660};
  • trunk/Source/JavaScriptCore/ftl/FTLExitValue.cpp

    r179503 r181993  
    11/*
    2  * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4242}
    4343
     44ExitValue ExitValue::withLocalsOffset(int offset) const
     45{
     46    if (!isInJSStackSomehow())
     47        return *this;
     48    if (!virtualRegister().isLocal())
     49        return *this;
     50    return withVirtualRegister(virtualRegister() + offset);
     51}
     52
     53ValueFormat ExitValue::valueFormat() const
     54{
     55    switch (kind()) {
     56    case InvalidExitValue:
     57        RELEASE_ASSERT_NOT_REACHED();
     58        return InvalidValueFormat;
     59           
     60    case ExitValueDead:
     61    case ExitValueConstant:
     62    case ExitValueInJSStack:
     63    case ExitValueMaterializeNewObject:
     64        return ValueFormatJSValue;
     65           
     66    case ExitValueArgument:
     67        return exitArgument().format();
     68           
     69    case ExitValueInJSStackAsInt32:
     70        return ValueFormatInt32;
     71           
     72    case ExitValueInJSStackAsInt52:
     73        return ValueFormatInt52;
     74           
     75    case ExitValueInJSStackAsDouble:
     76        return ValueFormatDouble;
     77           
     78    case ExitValueRecovery:
     79        return recoveryFormat();
     80    }
     81       
     82    RELEASE_ASSERT_NOT_REACHED();
     83    return InvalidValueFormat;
     84}
     85
    4486void ExitValue::dumpInContext(PrintStream& out, DumpContext* context) const
    4587{
     
    69111        out.print("InJSStackAsDouble:", virtualRegister());
    70112        return;
    71     case ExitValueArgumentsObjectThatWasNotCreated:
    72         out.print("ArgumentsObjectThatWasNotCreated");
    73         return;
    74113    case ExitValueRecovery:
    75114        out.print("Recovery(", recoveryOpcode(), ", arg", leftRecoveryArgument(), ", arg", rightRecoveryArgument(), ", ", recoveryFormat(), ")");
  • trunk/Source/JavaScriptCore/ftl/FTLExitValue.h

    r173993 r181993  
    11/*
    2  * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5252    ExitValueInJSStackAsInt52,
    5353    ExitValueInJSStackAsDouble,
    54     ExitValueArgumentsObjectThatWasNotCreated,
    5554    ExitValueRecovery,
    5655    ExitValueMaterializeNewObject
     
    120119        result.m_kind = ExitValueArgument;
    121120        result.u.argument = argument.representation();
    122         return result;
    123     }
    124    
    125     static ExitValue argumentsObjectThatWasNotCreated()
    126     {
    127         ExitValue result;
    128         result.m_kind = ExitValueArgumentsObjectThatWasNotCreated;
    129121        return result;
    130122    }
     
    160152    bool isConstant() const { return kind() == ExitValueConstant; }
    161153    bool isArgument() const { return kind() == ExitValueArgument; }
    162     bool isArgumentsObjectThatWasNotCreated() const { return kind() == ExitValueArgumentsObjectThatWasNotCreated; }
    163154    bool isRecovery() const { return kind() == ExitValueRecovery; }
    164155    bool isObjectMaterialization() const { return kind() == ExitValueMaterializeNewObject; }
     
    220211        return result;
    221212    }
     213   
     214    ExitValue withLocalsOffset(int offset) const;
    222215   
    223216    // If it's in the JSStack somehow, this will tell you what format it's in, in a manner
     
    225218    // will claim to be a JSValue. If it's an argument then it will tell you the argument's
    226219    // format.
    227     ValueFormat valueFormat() const
    228     {
    229         switch (kind()) {
    230         case InvalidExitValue:
    231             RELEASE_ASSERT_NOT_REACHED();
    232             return InvalidValueFormat;
    233            
    234         case ExitValueDead:
    235         case ExitValueConstant:
    236         case ExitValueInJSStack:
    237         case ExitValueArgumentsObjectThatWasNotCreated:
    238         case ExitValueMaterializeNewObject:
    239             return ValueFormatJSValue;
    240            
    241         case ExitValueArgument:
    242             return exitArgument().format();
    243            
    244         case ExitValueInJSStackAsInt32:
    245             return ValueFormatInt32;
    246            
    247         case ExitValueInJSStackAsInt52:
    248             return ValueFormatInt52;
    249            
    250         case ExitValueInJSStackAsDouble:
    251             return ValueFormatDouble;
    252            
    253         case ExitValueRecovery:
    254             return recoveryFormat();
    255         }
    256        
    257         RELEASE_ASSERT_NOT_REACHED();
    258         return InvalidValueFormat;
    259     }
     220    ValueFormat valueFormat() const;
    260221
    261222    void dump(PrintStream&) const;
  • trunk/Source/JavaScriptCore/ftl/FTLInlineCacheSize.cpp

    r181195 r181993  
    8686{
    8787#if CPU(ARM64)
    88     return 460;
     88    return 312;
    8989#else
    90     return 372;
     90    return 250;
    9191#endif
    9292}
     
    9595{
    9696#if CPU(ARM64)
    97     return 300;
     97    return 332;
    9898#else
    9999    return 275;
     100#endif
     101}
     102
     103size_t sizeOfConstructForwardVarargs()
     104{
     105#if CPU(ARM64)
     106    return 312;
     107#else
     108    return 250;
    100109#endif
    101110}
     
    126135    case ConstructVarargs:
    127136        return sizeOfConstructVarargs();
     137    case ConstructForwardVarargs:
     138        return sizeOfConstructForwardVarargs();
    128139    case In:
    129140        return sizeOfIn();
  • trunk/Source/JavaScriptCore/ftl/FTLInlineCacheSize.h

    r180279 r181993  
    4343size_t sizeOfCallForwardVarargs();
    4444size_t sizeOfConstructVarargs();
     45size_t sizeOfConstructForwardVarargs();
    4546size_t sizeOfIn();
    4647
  • trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h

    r181035 r181993  
    6464    macro(C_JITOperation_EJssJssJss, functionType(intPtr, intPtr, intPtr, intPtr, intPtr)) \
    6565    macro(C_JITOperation_ESt, functionType(intPtr, intPtr, intPtr)) \
     66    macro(C_JITOperation_EStJscSymtab, functionType(intPtr, intPtr, intPtr, intPtr, intPtr)) \
     67    macro(C_JITOperation_EStRZJsf, functionType(intPtr, intPtr, intPtr, intPtr, int32, intPtr)) \
     68    macro(C_JITOperation_EStRZJsfL, functionType(intPtr, intPtr, intPtr, intPtr, int32, intPtr, intPtr)) \
     69    macro(C_JITOperation_EStZ, functionType(intPtr, intPtr, intPtr, int32)) \
     70    macro(C_JITOperation_EStZZ, functionType(intPtr, intPtr, intPtr, int32, int32)) \
    6671    macro(C_JITOperation_EZ, functionType(intPtr, intPtr, int32)) \
    6772    macro(D_JITOperation_D, functionType(doubleType, doubleType)) \
     
    7782    macro(J_JITOperation_EJC, functionType(int64, intPtr, int64, intPtr)) \
    7883    macro(J_JITOperation_EJJ, functionType(int64, intPtr, int64, int64)) \
     84    macro(J_JITOperation_EJscC, functionType(intPtr, intPtr, intPtr, intPtr)) \
    7985    macro(J_JITOperation_EJssZ, functionType(int64, intPtr, intPtr, int32)) \
    8086    macro(J_JITOperation_ESsiJI, functionType(int64, intPtr, intPtr, int64, intPtr)) \
  • trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.cpp

    r180595 r181993  
    2929#if ENABLE(FTL_JIT)
    3030
    31 #include "DFGGraph.h"
    3231#include "DFGNode.h"
    3332#include "DFGOperations.h"
     
    5251    , m_node(node)
    5352    , m_callBase(
    54         node->op() == ConstructVarargs ? CallLinkInfo::ConstructVarargs : CallLinkInfo::CallVarargs,
     53        (node->op() == ConstructVarargs || node->op() == ConstructForwardVarargs)
     54        ? CallLinkInfo::ConstructVarargs : CallLinkInfo::CallVarargs,
    5555        node->origin.semantic)
    5656    , m_instructionOffset(0)
    5757{
    58     ASSERT(node->op() == CallVarargs || node->op() == CallForwardVarargs || node->op() == ConstructVarargs);
     58    ASSERT(
     59        node->op() == CallVarargs || node->op() == CallForwardVarargs
     60        || node->op() == ConstructVarargs || node->op() == ConstructForwardVarargs);
    5961}
    6062
     
    6466}
    6567
    66 void JSCallVarargs::emit(CCallHelpers& jit, Graph& graph, int32_t spillSlotsOffset)
     68void JSCallVarargs::emit(CCallHelpers& jit, int32_t spillSlotsOffset)
    6769{
    6870    // We are passed three pieces of information:
    6971    // - The callee.
    70     // - The arguments object.
     72    // - The arguments object, if it's not a forwarding call.
    7173    // - The "this" value, if it's a constructor call.
    7274
     
    7779    GPRReg argumentsGPR = InvalidGPRReg;
    7880    GPRReg thisGPR = InvalidGPRReg;
    79     bool argumentsOnStack = false;
     81   
     82    bool forwarding = false;
    8083   
    8184    switch (m_node->op()) {
    8285    case CallVarargs:
     86    case ConstructVarargs:
    8387        argumentsGPR = GPRInfo::argumentGPR1;
    8488        thisGPR = GPRInfo::argumentGPR2;
    8589        break;
    8690    case CallForwardVarargs:
     91    case ConstructForwardVarargs:
    8792        thisGPR = GPRInfo::argumentGPR1;
    88         argumentsOnStack = true;
    89         break;
    90     case ConstructVarargs:
    91         argumentsGPR = GPRInfo::argumentGPR1;
    92         thisGPR = GPRInfo::argumentGPR2;
     93        forwarding = true;
    9394        break;
    9495    default:
     
    116117    GPRReg scratchGPR2 = allocator.allocateScratchGPR();
    117118    GPRReg scratchGPR3 = allocator.allocateScratchGPR();
    118     if (argumentsOnStack)
    119         argumentsGPR = allocator.allocateScratchGPR();
     119
    120120    RELEASE_ASSERT(!allocator.numberOfReusedRegisters());
    121    
    122     auto loadArguments = [&] (bool clobbered) {
    123         if (argumentsOnStack) {
    124             jit.load64(
    125                 CCallHelpers::addressFor(graph.machineArgumentsRegisterFor(m_node->origin.semantic)),
    126                 argumentsGPR);
    127         } else if (clobbered) {
    128             jit.load64(
    129                 CCallHelpers::addressFor(spillSlotsOffset + argumentsSpillSlot), argumentsGPR);
    130         }
    131     };
    132121   
    133122    auto computeUsedStack = [&] (GPRReg targetGPR, unsigned extra) {
     
    152141    };
    153142   
    154     loadArguments(false);
    155 
    156143    if (isARM64()) {
    157144        jit.move(CCallHelpers::stackPointerRegister, scratchGPR1);
     
    159146    } else
    160147        jit.storePtr(CCallHelpers::stackPointerRegister, CCallHelpers::addressFor(spillSlotsOffset + stackPointerSpillSlot));
    161    
    162     // Attempt the forwarding fast path, if it's been requested.
    163     CCallHelpers::Jump haveArguments;
    164     if (m_node->op() == CallForwardVarargs) {
    165         // Do the horrific foo.apply(this, arguments) optimization.
    166         // FIXME: do this optimization at the IR level.
    167        
    168         CCallHelpers::JumpList slowCase;
    169         slowCase.append(jit.branchTest64(CCallHelpers::NonZero, argumentsGPR));
    170        
    171         computeUsedStack(scratchGPR2, 0);
    172         emitSetupVarargsFrameFastCase(jit, scratchGPR2, scratchGPR1, scratchGPR2, scratchGPR3, m_node->origin.semantic.inlineCallFrame, data->firstVarArgOffset, slowCase);
    173        
    174         jit.move(calleeGPR, GPRInfo::regT0);
    175         haveArguments = jit.jump();
    176         slowCase.link(&jit);
    177     }
    178    
    179     // Gotta spill the callee, arguments, and this because we will need them later and we will have some
    180     // calls that clobber them.
    181     jit.store64(calleeGPR, CCallHelpers::addressFor(spillSlotsOffset + calleeSpillSlot));
    182     if (!argumentsOnStack)
    183         jit.store64(argumentsGPR, CCallHelpers::addressFor(spillSlotsOffset + argumentsSpillSlot));
    184     jit.store64(thisGPR, CCallHelpers::addressFor(spillSlotsOffset + thisSpillSlot));
    185    
     148
    186149    unsigned extraStack = sizeof(CallerFrameAndPC) +
    187150        WTF::roundUpToMultipleOf(stackAlignmentBytes(), 5 * sizeof(void*));
    188     computeUsedStack(scratchGPR1, 0);
    189     jit.subPtr(CCallHelpers::TrustedImm32(extraStack), CCallHelpers::stackPointerRegister);
    190     jit.setupArgumentsWithExecState(argumentsGPR, scratchGPR1, CCallHelpers::TrustedImm32(data->firstVarArgOffset));
    191     callWithExceptionCheck(bitwise_cast<void*>(operationSizeFrameForVarargs));
    192    
    193     jit.move(GPRInfo::returnValueGPR, scratchGPR1);
    194     computeUsedStack(scratchGPR2, extraStack);
    195     loadArguments(true);
    196     emitSetVarargsFrame(jit, scratchGPR1, false, scratchGPR2, scratchGPR2);
    197     jit.addPtr(CCallHelpers::TrustedImm32(-extraStack), scratchGPR2, CCallHelpers::stackPointerRegister);
    198     jit.setupArgumentsWithExecState(scratchGPR2, argumentsGPR, CCallHelpers::TrustedImm32(data->firstVarArgOffset), scratchGPR1);
    199     callWithExceptionCheck(bitwise_cast<void*>(operationSetupVarargsFrame));
    200    
    201     jit.move(GPRInfo::returnValueGPR, scratchGPR2);
    202 
    203     jit.load64(CCallHelpers::addressFor(spillSlotsOffset + thisSpillSlot), thisGPR);
    204     jit.load64(CCallHelpers::addressFor(spillSlotsOffset + calleeSpillSlot), GPRInfo::regT0);
    205    
    206     if (m_node->op() == CallForwardVarargs)
    207         haveArguments.link(&jit);
     151
     152    if (forwarding) {
     153        CCallHelpers::JumpList slowCase;
     154        computeUsedStack(scratchGPR2, 0);
     155        emitSetupVarargsFrameFastCase(jit, scratchGPR2, scratchGPR1, scratchGPR2, scratchGPR3, m_node->child2()->origin.semantic.inlineCallFrame, data->firstVarArgOffset, slowCase);
     156       
     157        CCallHelpers::Jump done = jit.jump();
     158        slowCase.link(&jit);
     159        jit.subPtr(CCallHelpers::TrustedImm32(extraStack), CCallHelpers::stackPointerRegister);
     160        jit.setupArgumentsExecState();
     161        callWithExceptionCheck(bitwise_cast<void*>(operationThrowStackOverflowForVarargs));
     162        jit.abortWithReason(DFGVarargsThrowingPathDidNotThrow);
     163       
     164        done.link(&jit);
     165        jit.move(calleeGPR, GPRInfo::regT0);
     166    } else {
     167        // Gotta spill the callee, arguments, and this because we will need them later and we will have some
     168        // calls that clobber them.
     169        jit.store64(calleeGPR, CCallHelpers::addressFor(spillSlotsOffset + calleeSpillSlot));
     170        jit.store64(argumentsGPR, CCallHelpers::addressFor(spillSlotsOffset + argumentsSpillSlot));
     171        jit.store64(thisGPR, CCallHelpers::addressFor(spillSlotsOffset + thisSpillSlot));
     172   
     173        computeUsedStack(scratchGPR1, 0);
     174        jit.subPtr(CCallHelpers::TrustedImm32(extraStack), CCallHelpers::stackPointerRegister);
     175        jit.setupArgumentsWithExecState(argumentsGPR, scratchGPR1, CCallHelpers::TrustedImm32(data->firstVarArgOffset));
     176        callWithExceptionCheck(bitwise_cast<void*>(operationSizeFrameForVarargs));
     177   
     178        jit.move(GPRInfo::returnValueGPR, scratchGPR1);
     179        computeUsedStack(scratchGPR2, extraStack);
     180        jit.load64(CCallHelpers::addressFor(spillSlotsOffset + argumentsSpillSlot), argumentsGPR);
     181        emitSetVarargsFrame(jit, scratchGPR1, false, scratchGPR2, scratchGPR2);
     182        jit.addPtr(CCallHelpers::TrustedImm32(-extraStack), scratchGPR2, CCallHelpers::stackPointerRegister);
     183        jit.setupArgumentsWithExecState(scratchGPR2, argumentsGPR, CCallHelpers::TrustedImm32(data->firstVarArgOffset), scratchGPR1);
     184        callWithExceptionCheck(bitwise_cast<void*>(operationSetupVarargsFrame));
     185   
     186        jit.move(GPRInfo::returnValueGPR, scratchGPR2);
     187
     188        jit.load64(CCallHelpers::addressFor(spillSlotsOffset + thisSpillSlot), thisGPR);
     189        jit.load64(CCallHelpers::addressFor(spillSlotsOffset + calleeSpillSlot), GPRInfo::regT0);
     190    }
    208191   
    209192    jit.addPtr(CCallHelpers::TrustedImm32(sizeof(CallerFrameAndPC)), scratchGPR2, CCallHelpers::stackPointerRegister);
  • trunk/Source/JavaScriptCore/ftl/FTLJSCallVarargs.h

    r180279 r181993  
    3636
    3737namespace DFG {
    38 class Graph;
    3938struct Node;
    4039}
     
    5150    static unsigned numSpillSlotsNeeded();
    5251   
    53     void emit(CCallHelpers&, DFG::Graph&, int32_t spillSlotsOffset);
     52    void emit(CCallHelpers&, int32_t spillSlotsOffset);
    5453    void link(VM&, LinkBuffer&, CodeLocationLabel exceptionHandler);
    5554   
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r181891 r181993  
    3333#include "DFGInPlaceAbstractState.h"
    3434#include "DFGOSRAvailabilityAnalysisPhase.h"
     35#include "DirectArguments.h"
    3536#include "FTLAbstractHeapRepository.h"
    3637#include "FTLAvailableRecovery.h"
     
    4445#include "FTLWeightedTarget.h"
    4546#include "JSCInlines.h"
     47#include "JSLexicalEnvironment.h"
    4648#include "OperandsInlines.h"
     49#include "ScopedArguments.h"
     50#include "ScopedArgumentsTable.h"
    4751#include "VirtualRegister.h"
    4852#include <atomic>
     
    168172            }
    169173        }
    170 
    171         LValue capturedAlloca = m_out.alloca(arrayType(m_out.int64, m_graph.m_nextMachineLocal));
    172 
     174       
    173175        if (maxNumberOfArguments >= 0) {
    174176            m_execState = m_out.alloca(arrayType(m_out.int64, JSStack::CallFrameHeaderSize + maxNumberOfArguments));
     
    176178        }
    177179
     180        LValue capturedAlloca = m_out.alloca(arrayType(m_out.int64, m_graph.m_nextMachineLocal));
     181       
    178182        m_captured = m_out.add(
    179183            m_out.ptrToInt(capturedAlloca, m_out.intPtr),
    180184            m_out.constIntPtr(m_graph.m_nextMachineLocal * sizeof(Register)));
    181        
    182         // We should not create any alloca's after this point, since they will cease to
    183         // be mem2reg candidates.
    184185       
    185186        m_ftlState.capturedStackmapID = m_stackmapIDs++;
     
    196197                case CallForwardVarargs:
    197198                case ConstructVarargs:
     199                case ConstructForwardVarargs:
    198200                    hasVarargs = true;
    199201                    break;
     
    211213                m_out.int32Zero, varargsSpillSlots);
    212214        }
     215       
     216        // We should not create any alloca's after this point, since they will cease to
     217        // be mem2reg candidates.
    213218       
    214219        m_callFrame = m_out.ptrToInt(
     
    435440            compileInt52Constant();
    436441            break;
    437         case PhantomArguments:
    438             compilePhantomArguments();
    439             break;
    440442        case DoubleRep:
    441443            compileDoubleRep();
     
    461463        case PutStack:
    462464            compilePutStack();
    463             break;
    464         case GetMyArgumentsLength:
    465             compileGetMyArgumentsLength();
    466             break;
    467         case GetMyArgumentByVal:
    468             compileGetMyArgumentByVal();
    469465            break;
    470466        case Phantom:
     
    593589            compileGetByVal();
    594590            break;
     591        case GetMyArgumentByVal:
     592            compileGetMyArgumentByVal();
     593            break;
    595594        case PutByVal:
    596595        case PutByValAlias:
     
    604603            compileArrayPop();
    605604            break;
     605        case CreateActivation:
     606            compileCreateActivation();
     607            break;
     608        case NewFunction:
     609            compileNewFunction();
     610            break;
     611        case CreateDirectArguments:
     612            compileCreateDirectArguments();
     613            break;
     614        case CreateScopedArguments:
     615            compileCreateScopedArguments();
     616            break;
     617        case CreateClonedArguments:
     618            compileCreateClonedArguments();
     619            break;
    606620        case NewObject:
    607621            compileNewObject();
     
    671685            compileGetCallee();
    672686            break;
     687        case GetArgumentCount:
     688            compileGetArgumentCount();
     689            break;
    673690        case GetScope:
    674691            compileGetScope();
     
    677694            compileSkipScope();
    678695            break;
    679         case GetClosureRegisters:
    680             compileGetClosureRegisters();
    681             break;
    682696        case GetClosureVar:
    683697            compileGetClosureVar();
     
    685699        case PutClosureVar:
    686700            compilePutClosureVar();
     701            break;
     702        case GetFromArguments:
     703            compileGetFromArguments();
     704            break;
     705        case PutToArguments:
     706            compilePutToArguments();
    687707            break;
    688708        case CompareEq:
     
    717737        case CallForwardVarargs:
    718738        case ConstructVarargs:
     739        case ConstructForwardVarargs:
    719740            compileCallOrConstructVarargs();
    720741            break;
    721742        case LoadVarargs:
    722743            compileLoadVarargs();
     744            break;
     745        case ForwardVarargs:
     746            compileForwardVarargs();
    723747            break;
    724748#if ENABLE(FTL_NATIVE_CALL_INLINING)
     
    749773        case InvalidationPoint:
    750774            compileInvalidationPoint();
    751             break;
    752         case CheckArgumentsNotCreated:
    753             compileCheckArgumentsNotCreated();
    754775            break;
    755776        case IsUndefined:
     
    830851        case ZombieHint:
    831852        case PhantomNewObject:
     853        case PhantomDirectArguments:
     854        case PhantomClonedArguments:
    832855        case PutHint:
    833856        case BottomValue:
     
    839862        }
    840863
    841         if (!m_state.isValid()) {
     864        if (!m_state.isValid() && !m_node->isTerminal()) {
    842865            safelyInvalidateAfterTermination();
    843866            return false;
     
    918941    }
    919942
    920     void compilePhantomArguments()
    921     {
    922         setJSValue(m_out.constInt64(JSValue::encode(JSValue())));
    923     }
    924    
    925943    void compileDoubleRep()
    926944    {
     
    10961114        StackAccessData* data = m_node->stackAccessData();
    10971115        switch (data->format) {
    1098         case FlushedJSValue:
    1099         case FlushedArguments: {
     1116        case FlushedJSValue: {
    11001117            LValue value = lowJSValue(m_node->child1());
    11011118            m_out.store64(value, addressFor(data->machineLocal));
     
    21172134    }
    21182135   
    2119     void compileGetMyArgumentsLength()
    2120     {
    2121         checkArgumentsNotCreated();
    2122 
    2123         if (m_node->origin.semantic.inlineCallFrame
    2124             && !m_node->origin.semantic.inlineCallFrame->isVarargs()) {
    2125             setInt32(
    2126                 m_out.constInt32(
    2127                     m_node->origin.semantic.inlineCallFrame->arguments.size() - 1));
    2128         } else {
    2129             VirtualRegister argumentCountRegister;
    2130             if (!m_node->origin.semantic.inlineCallFrame)
    2131                 argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
    2132             else
    2133                 argumentCountRegister = m_node->origin.semantic.inlineCallFrame->argumentCountRegister;
    2134             setInt32(
    2135                 m_out.add(
    2136                     m_out.load32NonNegative(payloadFor(argumentCountRegister)),
    2137                     m_out.constInt32(-1)));
    2138         }
    2139     }
    2140    
    2141     void compileGetMyArgumentByVal()
    2142     {
    2143         checkArgumentsNotCreated();
    2144        
    2145         CodeOrigin codeOrigin = m_node->origin.semantic;
    2146        
    2147         LValue index = lowInt32(m_node->child1());
    2148        
    2149         LValue limit;
    2150         if (codeOrigin.inlineCallFrame
    2151             && !codeOrigin.inlineCallFrame->isVarargs())
    2152             limit = m_out.constInt32(codeOrigin.inlineCallFrame->arguments.size() - 1);
    2153         else {
    2154             VirtualRegister argumentCountRegister;
    2155             if (!codeOrigin.inlineCallFrame)
    2156                 argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
    2157             else
    2158                 argumentCountRegister = codeOrigin.inlineCallFrame->argumentCountRegister;
    2159             limit = m_out.sub(m_out.load32(payloadFor(argumentCountRegister)), m_out.int32One);
    2160         }
    2161        
    2162         speculate(Uncountable, noValue(), 0, m_out.aboveOrEqual(index, limit));
    2163        
    2164         SymbolTable* symbolTable = m_graph.baselineCodeBlockFor(codeOrigin)->symbolTable();
    2165         if (symbolTable->slowArguments()) {
    2166             // FIXME: FTL should support activations.
    2167             // https://bugs.webkit.org/show_bug.cgi?id=129576
    2168            
    2169             DFG_CRASH(m_graph, m_node, "Unimplemented");
    2170         }
    2171        
    2172         TypedPointer base;
    2173         if (codeOrigin.inlineCallFrame) {
    2174             if (codeOrigin.inlineCallFrame->arguments.size() <= 1) {
    2175                 // We should have already exited due to the bounds check, above. Just tell the
    2176                 // compiler that anything dominated by this instruction is not reachable, so
    2177                 // that we don't waste time generating such code. This will also plant some
    2178                 // kind of crashing instruction so that if by some fluke the bounds check didn't
    2179                 // work, we'll crash in an easy-to-see way.
    2180                 didAlreadyTerminate();
    2181                 return;
    2182             }
    2183             base = addressFor(codeOrigin.inlineCallFrame->arguments[1].virtualRegister());
    2184         } else
    2185             base = addressFor(virtualRegisterForArgument(1));
    2186        
    2187         LValue pointer = m_out.baseIndex(
    2188             base.value(), m_out.zeroExt(index, m_out.intPtr), ScaleEight);
    2189         setJSValue(m_out.load64(TypedPointer(m_heaps.variables.atAnyIndex(), pointer)));
    2190     }
    2191 
    21922136    void compileGetArrayLength()
    21932137    {
     
    22032147            LValue string = lowCell(m_node->child1());
    22042148            setInt32(m_out.load32NonNegative(string, m_heaps.JSString_length));
     2149            return;
     2150        }
     2151           
     2152        case Array::DirectArguments: {
     2153            LValue arguments = lowCell(m_node->child1());
     2154            speculate(
     2155                ExoticObjectMode, noValue(), nullptr,
     2156                m_out.notNull(m_out.loadPtr(arguments, m_heaps.DirectArguments_overrides)));
     2157            setInt32(m_out.load32NonNegative(arguments, m_heaps.DirectArguments_length));
     2158            return;
     2159        }
     2160           
     2161        case Array::ScopedArguments: {
     2162            LValue arguments = lowCell(m_node->child1());
     2163            speculate(
     2164                ExoticObjectMode, noValue(), nullptr,
     2165                m_out.notZero8(m_out.loadPtr(arguments, m_heaps.ScopedArguments_overrodeThings)));
     2166            setInt32(m_out.load32NonNegative(arguments, m_heaps.ScopedArguments_totalLength));
    22052167            return;
    22062168        }
     
    23232285        }
    23242286           
     2287        case Array::DirectArguments: {
     2288            LValue base = lowCell(m_node->child1());
     2289            LValue index = lowInt32(m_node->child2());
     2290           
     2291            speculate(
     2292                ExoticObjectMode, noValue(), nullptr,
     2293                m_out.notNull(m_out.loadPtr(base, m_heaps.DirectArguments_overrides)));
     2294            speculate(
     2295                ExoticObjectMode, noValue(), nullptr,
     2296                m_out.aboveOrEqual(
     2297                    index,
     2298                    m_out.load32NonNegative(base, m_heaps.DirectArguments_length)));
     2299
     2300            TypedPointer address = m_out.baseIndex(
     2301                m_heaps.DirectArguments_storage, base, m_out.zeroExtPtr(index));
     2302            setJSValue(m_out.load64(address));
     2303            return;
     2304        }
     2305           
     2306        case Array::ScopedArguments: {
     2307            LValue base = lowCell(m_node->child1());
     2308            LValue index = lowInt32(m_node->child2());
     2309           
     2310            speculate(
     2311                ExoticObjectMode, noValue(), nullptr,
     2312                m_out.aboveOrEqual(
     2313                    index,
     2314                    m_out.load32NonNegative(base, m_heaps.ScopedArguments_totalLength)));
     2315           
     2316            LValue table = m_out.loadPtr(base, m_heaps.ScopedArguments_table);
     2317            LValue namedLength = m_out.load32(table, m_heaps.ScopedArgumentsTable_length);
     2318           
     2319            LBasicBlock namedCase = FTL_NEW_BLOCK(m_out, ("GetByVal ScopedArguments named case"));
     2320            LBasicBlock overflowCase = FTL_NEW_BLOCK(m_out, ("GetByVal ScopedArguments overflow case"));
     2321            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetByVal ScopedArguments continuation"));
     2322           
     2323            m_out.branch(
     2324                m_out.aboveOrEqual(index, namedLength), unsure(overflowCase), unsure(namedCase));
     2325           
     2326            LBasicBlock lastNext = m_out.appendTo(namedCase, overflowCase);
     2327           
     2328            LValue scope = m_out.loadPtr(base, m_heaps.ScopedArguments_scope);
     2329            LValue arguments = m_out.loadPtr(table, m_heaps.ScopedArgumentsTable_arguments);
     2330           
     2331            TypedPointer address = m_out.baseIndex(
     2332                m_heaps.scopedArgumentsTableArguments, arguments, m_out.zeroExtPtr(index));
     2333            LValue scopeOffset = m_out.load32(address);
     2334           
     2335            speculate(
     2336                ExoticObjectMode, noValue(), nullptr,
     2337                m_out.equal(scopeOffset, m_out.constInt32(ScopeOffset::invalidOffset)));
     2338           
     2339            address = m_out.baseIndex(
     2340                m_heaps.JSEnvironmentRecord_variables, scope, m_out.zeroExtPtr(scopeOffset));
     2341            ValueFromBlock namedResult = m_out.anchor(m_out.load64(address));
     2342            m_out.jump(continuation);
     2343           
     2344            m_out.appendTo(overflowCase, continuation);
     2345           
     2346            address = m_out.baseIndex(
     2347                m_heaps.ScopedArguments_overflowStorage, base,
     2348                m_out.zeroExtPtr(m_out.sub(index, namedLength)));
     2349            LValue overflowValue = m_out.load64(address);
     2350            speculate(ExoticObjectMode, noValue(), nullptr, m_out.isZero64(overflowValue));
     2351            ValueFromBlock overflowResult = m_out.anchor(overflowValue);
     2352            m_out.jump(continuation);
     2353           
     2354            m_out.appendTo(continuation, lastNext);
     2355            setJSValue(m_out.phi(m_out.int64, namedResult, overflowResult));
     2356            return;
     2357        }
     2358           
    23252359        case Array::Generic: {
    23262360            setJSValue(vmCall(
     
    23472381                        storage,
    23482382                        m_out.shl(
    2349                             m_out.zeroExt(index, m_out.intPtr),
     2383                            m_out.zeroExtPtr(index),
    23502384                            m_out.constIntPtr(logElementSize(type)))));
    23512385               
     
    24192453    }
    24202454   
     2455    void compileGetMyArgumentByVal()
     2456    {
     2457        InlineCallFrame* inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
     2458       
     2459        LValue index = lowInt32(m_node->child2());
     2460       
     2461        LValue limit;
     2462        if (inlineCallFrame && !inlineCallFrame->isVarargs())
     2463            limit = m_out.constInt32(inlineCallFrame->arguments.size() - 1);
     2464        else {
     2465            VirtualRegister argumentCountRegister;
     2466            if (!inlineCallFrame)
     2467                argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
     2468            else
     2469                argumentCountRegister = inlineCallFrame->argumentCountRegister;
     2470            limit = m_out.sub(m_out.load32(payloadFor(argumentCountRegister)), m_out.int32One);
     2471        }
     2472       
     2473        speculate(ExoticObjectMode, noValue(), 0, m_out.aboveOrEqual(index, limit));
     2474       
     2475        TypedPointer base;
     2476        if (inlineCallFrame) {
     2477            if (inlineCallFrame->arguments.size() <= 1) {
     2478                // We should have already exited due to the bounds check, above. Just tell the
     2479                // compiler that anything dominated by this instruction is not reachable, so
     2480                // that we don't waste time generating such code. This will also plant some
     2481                // kind of crashing instruction so that if by some fluke the bounds check didn't
     2482                // work, we'll crash in an easy-to-see way.
     2483                didAlreadyTerminate();
     2484                return;
     2485            }
     2486            base = addressFor(inlineCallFrame->arguments[1].virtualRegister());
     2487        } else
     2488            base = addressFor(virtualRegisterForArgument(1));
     2489       
     2490        LValue pointer = m_out.baseIndex(
     2491            base.value(), m_out.zeroExt(index, m_out.intPtr), ScaleEight);
     2492        setJSValue(m_out.load64(TypedPointer(m_heaps.variables.atAnyIndex(), pointer)));
     2493    }
     2494   
    24212495    void compilePutByVal()
    24222496    {
     
    24742548                    m_node->arrayMode().type() == Array::Int32 ?
    24752549                    m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties,
    2476                     storage, m_out.zeroExt(index, m_out.intPtr),
    2477                     m_state.forNode(child2).m_value);
     2550                    storage, m_out.zeroExtPtr(index), m_state.forNode(child2).m_value);
    24782551               
    24792552                if (m_node->op() == PutByValAlias) {
     
    25002573               
    25012574                TypedPointer elementPointer = m_out.baseIndex(
    2502                     m_heaps.indexedDoubleProperties,
    2503                     storage, m_out.zeroExt(index, m_out.intPtr),
     2575                    m_heaps.indexedDoubleProperties, storage, m_out.zeroExtPtr(index),
    25042576                    m_state.forNode(child2).m_value);
    25052577               
     
    27152787            LBasicBlock lastNext = m_out.appendTo(fastPath, slowPath);
    27162788            m_out.store(
    2717                 value,
    2718                 m_out.baseIndex(heap, storage, m_out.zeroExt(prevLength, m_out.intPtr)),
    2719                 refType);
     2789                value, m_out.baseIndex(heap, storage, m_out.zeroExtPtr(prevLength)), refType);
    27202790            LValue newLength = m_out.add(prevLength, m_out.int32One);
    27212791            m_out.store32(newLength, storage, m_heaps.Butterfly_publicLength);
     
    27702840            LValue newLength = m_out.sub(prevLength, m_out.int32One);
    27712841            m_out.store32(newLength, storage, m_heaps.Butterfly_publicLength);
    2772             TypedPointer pointer = m_out.baseIndex(
    2773                 heap, storage, m_out.zeroExt(newLength, m_out.intPtr));
     2842            TypedPointer pointer = m_out.baseIndex(heap, storage, m_out.zeroExtPtr(newLength));
    27742843            if (m_node->arrayMode().type() != Array::Double) {
    27752844                LValue result = m_out.load64(pointer);
     
    28012870            return;
    28022871        }
     2872    }
     2873   
     2874    void compileCreateActivation()
     2875    {
     2876        LValue scope = lowCell(m_node->child1());
     2877        SymbolTable* table = m_graph.symbolTableFor(m_node->origin.semantic);
     2878        Structure* structure = m_graph.globalObjectFor(m_node->origin.semantic)->activationStructure();
     2879       
     2880        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("CreateActivation slow path"));
     2881        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("CreateActivation continuation"));
     2882       
     2883        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
     2884       
     2885        LValue fastObject = allocateObject<JSLexicalEnvironment>(
     2886            JSLexicalEnvironment::allocationSize(table), structure, m_out.intPtrZero, slowPath);
     2887       
     2888        // We don't need memory barriers since we just fast-created the activation, so the
     2889        // activation must be young.
     2890        m_out.storePtr(scope, fastObject, m_heaps.JSScope_next);
     2891        m_out.storePtr(weakPointer(table), fastObject, m_heaps.JSSymbolTableObject_symbolTable);
     2892       
     2893        for (unsigned i = 0; i < table->scopeSize(); ++i) {
     2894            m_out.store64(
     2895                m_out.constInt64(JSValue::encode(jsUndefined())),
     2896                fastObject, m_heaps.JSEnvironmentRecord_variables[i]);
     2897        }
     2898       
     2899        ValueFromBlock fastResult = m_out.anchor(fastObject);
     2900        m_out.jump(continuation);
     2901       
     2902        m_out.appendTo(slowPath, continuation);
     2903        LValue callResult = vmCall(
     2904            m_out.operation(operationCreateActivationDirect), m_callFrame, weakPointer(structure),
     2905            scope, weakPointer(table));
     2906        ValueFromBlock slowResult = m_out.anchor(callResult);
     2907        m_out.jump(continuation);
     2908       
     2909        m_out.appendTo(continuation, lastNext);
     2910        setJSValue(m_out.phi(m_out.intPtr, fastResult, slowResult));
     2911    }
     2912   
     2913    void compileNewFunction()
     2914    {
     2915        LValue result = vmCall(
     2916            m_out.operation(operationNewFunction), m_callFrame,
     2917            lowCell(m_node->child1()), weakPointer(m_node->castOperand<FunctionExecutable*>()));
     2918        setJSValue(result);
     2919    }
     2920   
     2921    void compileCreateDirectArguments()
     2922    {
     2923        // FIXME: A more effective way of dealing with the argument count and callee is to have
     2924        // them be explicit arguments to this node.
     2925        // https://bugs.webkit.org/show_bug.cgi?id=142207
     2926       
     2927        Structure* structure =
     2928            m_graph.globalObjectFor(m_node->origin.semantic)->directArgumentsStructure();
     2929       
     2930        unsigned minCapacity = m_graph.baselineCodeBlockFor(m_node->origin.semantic)->numParameters() - 1;
     2931       
     2932        LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("CreateDirectArguments slow path"));
     2933        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("CreateDirectArguments continuation"));
     2934       
     2935        LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
     2936       
     2937        ArgumentsLength length = getArgumentsLength();
     2938       
     2939        LValue fastObject;
     2940        if (length.isKnown) {
     2941            fastObject = allocateObject<DirectArguments>(
     2942                DirectArguments::allocationSize(std::max(length.known, minCapacity)), structure,
     2943                m_out.intPtrZero, slowPath);
     2944        } else {
     2945            LValue size = m_out.add(
     2946                m_out.shl(length.value, m_out.constInt32(3)),
     2947                m_out.constInt32(DirectArguments::storageOffset()));
     2948           
     2949            size = m_out.select(
     2950                m_out.aboveOrEqual(length.value, m_out.constInt32(minCapacity)),
     2951                size, m_out.constInt32(DirectArguments::allocationSize(minCapacity)));
     2952           
     2953            fastObject = allocateVariableSizedObject<DirectArguments>(
     2954                size, structure, m_out.intPtrZero, slowPath);
     2955        }
     2956       
     2957        m_out.store32(length.value, fastObject, m_heaps.DirectArguments_length);
     2958        m_out.store32(m_out.constInt32(minCapacity), fastObject, m_heaps.DirectArguments_minCapacity);
     2959        m_out.storePtr(m_out.intPtrZero, fastObject, m_heaps.DirectArguments_overrides);
     2960        m_out.storePtr(getCurrentCallee(), fastObject, m_heaps.DirectArguments_callee);
     2961       
     2962        ValueFromBlock fastResult = m_out.anchor(fastObject);
     2963        m_out.jump(continuation);
     2964       
     2965        m_out.appendTo(slowPath, continuation);
     2966        LValue callResult = vmCall(
     2967            m_out.operation(operationCreateDirectArguments), m_callFrame, weakPointer(structure),
     2968            length.value, m_out.constInt32(minCapacity));
     2969        ValueFromBlock slowResult = m_out.anchor(callResult);
     2970        m_out.jump(continuation);
     2971       
     2972        m_out.appendTo(continuation, lastNext);
     2973        LValue result = m_out.phi(m_out.intPtr, fastResult, slowResult);
     2974       
     2975        if (length.isKnown) {
     2976            VirtualRegister start = AssemblyHelpers::argumentsStart(m_node->origin.semantic);
     2977            for (unsigned i = 0; i < std::max(length.known, minCapacity); ++i) {
     2978                m_out.store64(
     2979                    m_out.load64(addressFor(start + i)),
     2980                    result, m_heaps.DirectArguments_storage[i]);
     2981            }
     2982        } else {
     2983            LValue stackBase = getArgumentsStart();
     2984           
     2985            LBasicBlock loop = FTL_NEW_BLOCK(m_out, ("CreateDirectArguments loop body"));
     2986            LBasicBlock end = FTL_NEW_BLOCK(m_out, ("CreateDirectArguments loop end"));
     2987           
     2988            ValueFromBlock originalLength;
     2989            if (minCapacity) {
     2990                LValue capacity = m_out.select(
     2991                    m_out.aboveOrEqual(length.value, m_out.constInt32(minCapacity)),
     2992                    length.value,
     2993                    m_out.constInt32(minCapacity));
     2994                originalLength = m_out.anchor(m_out.zeroExtPtr(capacity));
     2995                m_out.jump(loop);
     2996            } else {
     2997                originalLength = m_out.anchor(m_out.zeroExtPtr(length.value));
     2998                m_out.branch(m_out.isNull(originalLength.value()), unsure(end), unsure(loop));
     2999            }
     3000           
     3001            lastNext = m_out.appendTo(loop, end);
     3002            LValue previousIndex = m_out.phi(m_out.intPtr, originalLength);
     3003            LValue index = m_out.sub(previousIndex, m_out.intPtrOne);
     3004            m_out.store64(
     3005                m_out.load64(m_out.baseIndex(m_heaps.variables, stackBase, index)),
     3006                m_out.baseIndex(m_heaps.DirectArguments_storage, result, index));
     3007            ValueFromBlock nextIndex = m_out.anchor(index);
     3008            addIncoming(previousIndex, nextIndex);
     3009            m_out.branch(m_out.isNull(index), unsure(end), unsure(loop));
     3010           
     3011            m_out.appendTo(end, lastNext);
     3012        }
     3013       
     3014        setJSValue(result);
     3015    }
     3016   
     3017    void compileCreateScopedArguments()
     3018    {
     3019        LValue scope = lowCell(m_node->child1());
     3020       
     3021        LValue result = vmCall(
     3022            m_out.operation(operationCreateScopedArguments), m_callFrame,
     3023            weakPointer(
     3024                m_graph.globalObjectFor(m_node->origin.semantic)->scopedArgumentsStructure()),
     3025            getArgumentsStart(), getArgumentsLength().value, getCurrentCallee(), scope);
     3026       
     3027        setJSValue(result);
     3028    }
     3029   
     3030    void compileCreateClonedArguments()
     3031    {
     3032        LValue result = vmCall(
     3033            m_out.operation(operationCreateClonedArguments), m_callFrame,
     3034            weakPointer(
     3035                m_graph.globalObjectFor(m_node->origin.semantic)->outOfBandArgumentsStructure()),
     3036            getArgumentsStart(), getArgumentsLength().value, getCurrentCallee());
     3037       
     3038        setJSValue(result);
    28033039    }
    28043040   
     
    32683504        ValueFromBlock char8Bit = m_out.anchor(m_out.zeroExt(
    32693505            m_out.load8(m_out.baseIndex(
    3270                 m_heaps.characters8,
    3271                 storage, m_out.zeroExt(index, m_out.intPtr),
     3506                m_heaps.characters8, storage, m_out.zeroExtPtr(index),
    32723507                m_state.forNode(m_node->child2()).m_value)),
    32733508            m_out.int32));
     
    32783513        ValueFromBlock char16Bit = m_out.anchor(m_out.zeroExt(
    32793514            m_out.load16(m_out.baseIndex(
    3280                 m_heaps.characters16,
    3281                 storage, m_out.zeroExt(index, m_out.intPtr),
     3515                m_heaps.characters16, storage, m_out.zeroExtPtr(index),
    32823516                m_state.forNode(m_node->child2()).m_value)),
    32833517            m_out.int32));
     
    33013535           
    33023536        results.append(m_out.anchor(m_out.loadPtr(m_out.baseIndex(
    3303             m_heaps.singleCharacterStrings, smallStrings,
    3304             m_out.zeroExt(character, m_out.intPtr)))));
     3537            m_heaps.singleCharacterStrings, smallStrings, m_out.zeroExtPtr(character)))));
    33053538        m_out.jump(continuation);
    33063539           
     
    33613594        ValueFromBlock char8Bit = m_out.anchor(m_out.zeroExt(
    33623595            m_out.load8(m_out.baseIndex(
    3363                 m_heaps.characters8,
    3364                 storage, m_out.zeroExt(index, m_out.intPtr),
     3596                m_heaps.characters8, storage, m_out.zeroExtPtr(index),
    33653597                m_state.forNode(m_node->child2()).m_value)),
    33663598            m_out.int32));
     
    33713603        ValueFromBlock char16Bit = m_out.anchor(m_out.zeroExt(
    33723604            m_out.load16(m_out.baseIndex(
    3373                 m_heaps.characters16,
    3374                 storage, m_out.zeroExt(index, m_out.intPtr),
     3605                m_heaps.characters16, storage, m_out.zeroExtPtr(index),
    33753606                m_state.forNode(m_node->child2()).m_value)),
    33763607            m_out.int32));
     
    35423773    void compileGetGlobalVar()
    35433774    {
    3544         setJSValue(m_out.load64(m_out.absolute(m_node->registerPointer())));
     3775        setJSValue(m_out.load64(m_out.absolute(m_node->variablePointer())));
    35453776    }
    35463777   
     
    35483779    {
    35493780        m_out.store64(
    3550             lowJSValue(m_node->child1()), m_out.absolute(m_node->registerPointer()));
     3781            lowJSValue(m_node->child1()), m_out.absolute(m_node->variablePointer()));
    35513782    }
    35523783   
     
    35863817    }
    35873818   
     3819    void compileGetArgumentCount()
     3820    {
     3821        setInt32(m_out.load32(payloadFor(JSStack::ArgumentCount)));
     3822    }
     3823   
    35883824    void compileGetScope()
    35893825    {
     
    35963832    }
    35973833   
    3598     void compileGetClosureRegisters()
    3599     {
    3600         if (WriteBarrierBase<Unknown>* registers = m_graph.tryGetRegisters(m_node->child1().node())) {
    3601             setStorage(m_out.constIntPtr(registers));
    3602             return;
    3603         }
    3604        
    3605         setStorage(m_out.loadPtr(
    3606             lowCell(m_node->child1()), m_heaps.JSEnvironmentRecord_registers));
    3607     }
    3608    
    36093834    void compileGetClosureVar()
    36103835    {
    3611         setJSValue(m_out.load64(
    3612             addressFor(lowStorage(m_node->child2()), m_node->varNumber())));
     3836        setJSValue(
     3837            m_out.load64(
     3838                lowCell(m_node->child1()),
     3839                m_heaps.JSEnvironmentRecord_variables[m_node->scopeOffset().offset()]));
    36133840    }
    36143841   
     
    36163843    {
    36173844        m_out.store64(
    3618             lowJSValue(m_node->child3()),
    3619             addressFor(lowStorage(m_node->child2()), m_node->varNumber()));
     3845            lowJSValue(m_node->child2()),
     3846            lowCell(m_node->child1()),
     3847            m_heaps.JSEnvironmentRecord_variables[m_node->scopeOffset().offset()]);
     3848    }
     3849   
     3850    void compileGetFromArguments()
     3851    {
     3852        setJSValue(
     3853            m_out.load64(
     3854                lowCell(m_node->child1()),
     3855                m_heaps.DirectArguments_storage[m_node->capturedArgumentsOffset().offset()]));
     3856    }
     3857   
     3858    void compilePutToArguments()
     3859    {
     3860        m_out.store64(
     3861            lowJSValue(m_node->child2()),
     3862            lowCell(m_node->child1()),
     3863            m_heaps.DirectArguments_storage[m_node->capturedArgumentsOffset().offset()]);
    36203864    }
    36213865   
     
    38594103    {
    38604104        LValue jsCallee = lowJSValue(m_node->child1());
     4105        LValue thisArg = lowJSValue(m_node->child3());
    38614106       
    38624107        LValue jsArguments = nullptr;
    3863         LValue thisArg = nullptr;
    38644108       
    38654109        switch (m_node->op()) {
    38664110        case CallVarargs:
    3867             jsArguments = lowJSValue(m_node->child2());
    3868             thisArg = lowJSValue(m_node->child3());
    3869             break;
    3870         case CallForwardVarargs:
    3871             thisArg = lowJSValue(m_node->child2());
    3872             break;
    38734111        case ConstructVarargs:
    38744112            jsArguments = lowJSValue(m_node->child2());
    3875             thisArg = lowJSValue(m_node->child3());
     4113            break;
     4114        case CallForwardVarargs:
     4115        case ConstructForwardVarargs:
    38764116            break;
    38774117        default:
     
    39374177            length, m_out.constInt32(data->mandatoryMinimum));
    39384178    }
     4179   
     4180    void compileForwardVarargs()
     4181    {
     4182        LoadVarargsData* data = m_node->loadVarargsData();
     4183        InlineCallFrame* inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
     4184       
     4185        LValue length = getArgumentsLength(inlineCallFrame).value;
     4186        LValue lengthIncludingThis = m_out.add(length, m_out.constInt32(1 - data->offset));
     4187       
     4188        speculate(
     4189            VarargsOverflow, noValue(), nullptr,
     4190            m_out.above(lengthIncludingThis, m_out.constInt32(data->limit)));
     4191       
     4192        m_out.store32(lengthIncludingThis, payloadFor(data->machineCount));
     4193       
     4194        LValue sourceStart = getArgumentsStart(inlineCallFrame);
     4195        LValue targetStart = addressFor(data->machineStart).value();
     4196
     4197        LBasicBlock undefinedLoop = FTL_NEW_BLOCK(m_out, ("ForwardVarargs undefined loop body"));
     4198        LBasicBlock mainLoopEntry = FTL_NEW_BLOCK(m_out, ("ForwardVarargs main loop entry"));
     4199        LBasicBlock mainLoop = FTL_NEW_BLOCK(m_out, ("ForwardVarargs main loop body"));
     4200        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ForwardVarargs continuation"));
     4201       
     4202        LValue lengthAsPtr = m_out.zeroExtPtr(length);
     4203        ValueFromBlock loopBound = m_out.anchor(m_out.constIntPtr(data->mandatoryMinimum));
     4204        m_out.branch(
     4205            m_out.above(loopBound.value(), lengthAsPtr), unsure(undefinedLoop), unsure(mainLoopEntry));
     4206       
     4207        LBasicBlock lastNext = m_out.appendTo(undefinedLoop, mainLoopEntry);
     4208        LValue previousIndex = m_out.phi(m_out.intPtr, loopBound);
     4209        LValue currentIndex = m_out.sub(previousIndex, m_out.intPtrOne);
     4210        m_out.store64(
     4211            m_out.constInt64(JSValue::encode(jsUndefined())),
     4212            m_out.baseIndex(m_heaps.variables, targetStart, currentIndex));
     4213        ValueFromBlock nextIndex = m_out.anchor(currentIndex);
     4214        addIncoming(previousIndex, nextIndex);
     4215        m_out.branch(
     4216            m_out.above(currentIndex, lengthAsPtr), unsure(undefinedLoop), unsure(mainLoopEntry));
     4217       
     4218        m_out.appendTo(mainLoopEntry, mainLoop);
     4219        loopBound = m_out.anchor(lengthAsPtr);
     4220        m_out.branch(m_out.notNull(loopBound.value()), unsure(mainLoop), unsure(continuation));
     4221       
     4222        m_out.appendTo(mainLoop, continuation);
     4223        previousIndex = m_out.phi(m_out.intPtr, loopBound);
     4224        currentIndex = m_out.sub(previousIndex, m_out.intPtrOne);
     4225        LValue value = m_out.load64(
     4226            m_out.baseIndex(
     4227                m_heaps.variables, sourceStart,
     4228                m_out.add(currentIndex, m_out.constIntPtr(data->offset))));
     4229        m_out.store64(value, m_out.baseIndex(m_heaps.variables, targetStart, currentIndex));
     4230        nextIndex = m_out.anchor(currentIndex);
     4231        addIncoming(previousIndex, nextIndex);
     4232        m_out.branch(m_out.isNull(currentIndex), unsure(continuation), unsure(mainLoop));
     4233       
     4234        m_out.appendTo(continuation, lastNext);
     4235    }
    39394236
    39404237    void compileJump()
     
    41724469    }
    41734470   
    4174     void compileCheckArgumentsNotCreated()
    4175     {
    4176         ASSERT(!isEmptySpeculation(
    4177             m_state.variables().operand(
    4178                 m_graph.argumentsRegisterFor(m_node->origin.semantic)).m_type));
    4179        
    4180         checkArgumentsNotCreated();
    4181     }
    4182    
    41834471    void compileIsUndefined()
    41844472    {
     
    45524840        LValue storage = m_out.loadPtr(enumerator, m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVector);
    45534841        ValueFromBlock inBoundsResult = m_out.anchor(
    4554             m_out.load64(m_out.baseIndex(m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVector,
    4555                 storage, m_out.signExt(index, m_out.int64), ScaleEight)));
     4842            m_out.loadPtr(m_out.baseIndex(m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVectorContents, storage, m_out.zeroExtPtr(index))));
    45564843        m_out.jump(continuation);
    45574844
     
    45794866        LValue storage = m_out.loadPtr(enumerator, m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVector);
    45804867        ValueFromBlock inBoundsResult = m_out.anchor(
    4581             m_out.load64(m_out.baseIndex(m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVector,
    4582                 storage, m_out.signExt(index, m_out.int64), ScaleEight)));
     4868            m_out.loadPtr(m_out.baseIndex(m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVectorContents, storage, m_out.zeroExtPtr(index))));
    45834869        m_out.jump(continuation);
    45844870
     
    48795165    }
    48805166   
     5167    struct ArgumentsLength {
     5168        ArgumentsLength()
     5169            : isKnown(false)
     5170            , known(UINT_MAX)
     5171            , value(nullptr)
     5172        {
     5173        }
     5174       
     5175        bool isKnown;
     5176        unsigned known;
     5177        LValue value;
     5178    };
     5179    ArgumentsLength getArgumentsLength(InlineCallFrame* inlineCallFrame)
     5180    {
     5181        ArgumentsLength length;
     5182
     5183        if (inlineCallFrame && !inlineCallFrame->isVarargs()) {
     5184            length.known = inlineCallFrame->arguments.size() - 1;
     5185            length.isKnown = true;
     5186            length.value = m_out.constInt32(length.known);
     5187        } else {
     5188            length.known = UINT_MAX;
     5189            length.isKnown = false;
     5190           
     5191            VirtualRegister argumentCountRegister;
     5192            if (!inlineCallFrame)
     5193                argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
     5194            else
     5195                argumentCountRegister = inlineCallFrame->argumentCountRegister;
     5196            length.value = m_out.sub(m_out.load32(payloadFor(argumentCountRegister)), m_out.int32One);
     5197        }
     5198       
     5199        return length;
     5200    }
     5201   
     5202    ArgumentsLength getArgumentsLength()
     5203    {
     5204        return getArgumentsLength(m_node->origin.semantic.inlineCallFrame);
     5205    }
     5206   
     5207    LValue getCurrentCallee()
     5208    {
     5209        if (InlineCallFrame* frame = m_node->origin.semantic.inlineCallFrame) {
     5210            if (frame->isClosureCall)
     5211                return m_out.loadPtr(addressFor(frame->calleeRecovery.virtualRegister()));
     5212            return weakPointer(frame->calleeRecovery.constant().asCell());
     5213        }
     5214        return m_out.loadPtr(addressFor(JSStack::Callee));
     5215    }
     5216   
     5217    LValue getArgumentsStart(InlineCallFrame* inlineCallFrame)
     5218    {
     5219        VirtualRegister start = AssemblyHelpers::argumentsStart(inlineCallFrame);
     5220        return addressFor(start).value();
     5221    }
     5222   
     5223    LValue getArgumentsStart()
     5224    {
     5225        return getArgumentsStart(m_node->origin.semantic.inlineCallFrame);
     5226    }
     5227   
    48815228    void checkStructure(
    48825229        LValue structureID, const FormattedValue& formattedValue, ExitKind exitKind,
     
    50995446    }
    51005447   
    5101     TypedPointer baseIndex(IndexedAbstractHeap& heap, LValue storage, LValue index, Edge edge)
     5448    TypedPointer baseIndex(IndexedAbstractHeap& heap, LValue storage, LValue index, Edge edge, ptrdiff_t offset = 0)
    51025449    {
    51035450        return m_out.baseIndex(
    5104             heap, storage, m_out.zeroExt(index, m_out.intPtr),
    5105             m_state.forNode(edge).m_value);
     5451            heap, storage, m_out.zeroExtPtr(index), m_state.forNode(edge).m_value, offset);
    51065452    }
    51075453   
     
    52545600   
    52555601    template<typename ClassType>
    5256     LValue allocateObject(Structure* structure, LValue butterfly, LBasicBlock slowPath)
    5257     {
    5258         size_t size = ClassType::allocationSize(0);
     5602    LValue allocateObject(
     5603        size_t size, Structure* structure, LValue butterfly, LBasicBlock slowPath)
     5604    {
    52595605        MarkedAllocator* allocator = &vm().heap.allocatorForObjectOfType<ClassType>(size);
    52605606        return allocateObject(m_out.constIntPtr(allocator), structure, butterfly, slowPath);
     5607    }
     5608   
     5609    template<typename ClassType>
     5610    LValue allocateObject(Structure* structure, LValue butterfly, LBasicBlock slowPath)
     5611    {
     5612        return allocateObject<ClassType>(
     5613            ClassType::allocationSize(0), structure, butterfly, slowPath);
     5614    }
     5615   
     5616    template<typename ClassType>
     5617    LValue allocateVariableSizedObject(
     5618        LValue size, Structure* structure, LValue butterfly, LBasicBlock slowPath)
     5619    {
     5620        static_assert(!(MarkedSpace::preciseStep & (MarkedSpace::preciseStep - 1)), "MarkedSpace::preciseStep must be a power of two.");
     5621        static_assert(!(MarkedSpace::impreciseStep & (MarkedSpace::impreciseStep - 1)), "MarkedSpace::impreciseStep must be a power of two.");
     5622
     5623        LValue subspace = m_out.constIntPtr(&vm().heap.subspaceForObjectOfType<ClassType>());
     5624       
     5625        LBasicBlock smallCaseBlock = FTL_NEW_BLOCK(m_out, ("allocateVariableSizedObject small case"));
     5626        LBasicBlock largeOrOversizeCaseBlock = FTL_NEW_BLOCK(m_out, ("allocateVariableSizedObject large or oversize case"));
     5627        LBasicBlock largeCaseBlock = FTL_NEW_BLOCK(m_out, ("allocateVariableSizedObject large case"));
     5628        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("allocateVariableSizedObject continuation"));
     5629       
     5630        LValue uproundedSize = m_out.add(size, m_out.constInt32(MarkedSpace::preciseStep - 1));
     5631        LValue isSmall = m_out.below(uproundedSize, m_out.constInt32(MarkedSpace::preciseCutoff));
     5632        m_out.branch(isSmall, unsure(smallCaseBlock), unsure(largeOrOversizeCaseBlock));
     5633       
     5634        LBasicBlock lastNext = m_out.appendTo(smallCaseBlock, largeOrOversizeCaseBlock);
     5635        TypedPointer address = m_out.baseIndex(
     5636            m_heaps.MarkedSpace_Subspace_preciseAllocators, subspace,
     5637            m_out.zeroExtPtr(m_out.lShr(uproundedSize, m_out.constInt32(getLSBSet(MarkedSpace::preciseStep)))));
     5638        ValueFromBlock smallAllocator = m_out.anchor(address.value());
     5639        m_out.jump(continuation);
     5640       
     5641        m_out.appendTo(largeOrOversizeCaseBlock, largeCaseBlock);
     5642        m_out.branch(
     5643            m_out.below(uproundedSize, m_out.constInt32(MarkedSpace::impreciseCutoff)),
     5644            usually(largeCaseBlock), rarely(slowPath));
     5645       
     5646        m_out.appendTo(largeCaseBlock, continuation);
     5647        address = m_out.baseIndex(
     5648            m_heaps.MarkedSpace_Subspace_impreciseAllocators, subspace,
     5649            m_out.zeroExtPtr(m_out.lShr(uproundedSize, m_out.constInt32(getLSBSet(MarkedSpace::impreciseStep)))));
     5650        ValueFromBlock largeAllocator = m_out.anchor(address.value());
     5651        m_out.jump(continuation);
     5652       
     5653        m_out.appendTo(continuation, lastNext);
     5654        LValue allocator = m_out.phi(m_out.intPtr, smallAllocator, largeAllocator);
     5655       
     5656        return allocateObject(allocator, structure, butterfly, slowPath);
    52615657    }
    52625658   
     
    56646060    }
    56656061   
    5666     void checkArgumentsNotCreated()
    5667     {
    5668         CodeOrigin codeOrigin = m_node->origin.semantic;
    5669         VirtualRegister argumentsRegister = m_graph.argumentsRegisterFor(codeOrigin);
    5670         if (isEmptySpeculation(m_state.variables().operand(argumentsRegister).m_type))
    5671             return;
    5672        
    5673         VirtualRegister argsReg = m_graph.machineArgumentsRegisterFor(codeOrigin);
    5674         speculate(
    5675             ArgumentsEscaped, noValue(), 0,
    5676             m_out.notZero64(m_out.load64(addressFor(argsReg))));
    5677     }
    5678    
    56796062    void speculate(
    56806063        ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition)
     
    63646747        }
    63656748           
     6749        case Array::DirectArguments:
     6750            return m_out.equal(
     6751                m_out.load8(cell, m_heaps.JSCell_typeInfoType),
     6752                m_out.constInt8(DirectArgumentsType));
     6753           
     6754        case Array::ScopedArguments:
     6755            return m_out.equal(
     6756                m_out.load8(cell, m_heaps.JSCell_typeInfoType),
     6757                m_out.constInt8(ScopedArgumentsType));
     6758           
    63666759        default:
    63676760            return m_out.equal(
     
    66527045        m_out.appendTo(bufferHasSpace, bufferIsFull);
    66537046        LValue writeBarrierBufferBase = m_out.loadPtr(m_out.absolute(&vm().heap.writeBarrierBuffer().m_buffer));
    6654         m_out.storePtr(base, m_out.baseIndex(m_heaps.WriteBarrierBuffer_bufferContents, writeBarrierBufferBase, m_out.zeroExt(currentBufferIndex, m_out.intPtr), ScalePtr));
     7047        m_out.storePtr(base, m_out.baseIndex(m_heaps.WriteBarrierBuffer_bufferContents, writeBarrierBufferBase, m_out.zeroExtPtr(currentBufferIndex)));
    66557048        m_out.store32(m_out.add(currentBufferIndex, m_out.constInt32(1)), m_out.absolute(&vm().heap.writeBarrierBuffer().m_currentIndex));
    66567049        m_out.jump(continuation);
     
    67907183               
    67917184                Node* node = availability.node();
    6792                 if (!node->isPhantomObjectAllocation())
     7185                if (!node->isPhantomAllocation())
    67937186                    return;
    67947187               
    67957188                auto result = map.add(node, nullptr);
    6796                 if (result.isNewEntry)
    6797                     result.iterator->value = exit.m_materializations.add(node->op());
     7189                if (result.isNewEntry) {
     7190                    result.iterator->value =
     7191                        exit.m_materializations.add(node->op(), node->origin.semantic);
     7192                }
    67987193            });
    67997194       
     
    68627257        case FlushedDouble:
    68637258            return ExitValue::inJSStackAsDouble(flush.virtualRegister());
    6864                
    6865         case FlushedArguments:
    6866             return ExitValue::argumentsObjectThatWasNotCreated();
    68677259        }
    68687260       
     
    68907282                return ExitValue::constant(node->asJSValue());
    68917283               
    6892             case PhantomArguments:
    6893                 return ExitValue::argumentsObjectThatWasNotCreated();
    6894                
    6895             case PhantomNewObject:
    6896                 return ExitValue::materializeNewObject(map.get(node));
    6897                
    68987284            default:
     7285                if (node->isPhantomAllocation())
     7286                    return ExitValue::materializeNewObject(map.get(node));
    68997287                break;
    69007288            }
     
    70697457        LValue tableBase = m_out.loadPtr(
    70707458            m_out.absolute(vm().heap.structureIDTable().base()));
    7071         LValue pointerIntoTable = m_out.baseIndex(
    7072             tableBase, m_out.zeroExt(tableIndex, m_out.intPtr), ScaleEight);
    7073         return m_out.loadPtr(TypedPointer(m_heaps.structureTable, pointerIntoTable));
     7459        TypedPointer address = m_out.baseIndex(
     7460            m_heaps.structureTable, tableBase, m_out.zeroExtPtr(tableIndex));
     7461        return m_out.loadPtr(address);
    70747462    }
    70757463
  • trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp

    r181348 r181993  
    11/*
    2  * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7474        break;
    7575           
    76     case ExitValueArgumentsObjectThatWasNotCreated:
    77         jit.move(MacroAssembler::TrustedImm64(JSValue::encode(JSValue())), GPRInfo::regT0);
    78         break;
    79            
    8076    case ExitValueRecovery:
    8177        record->locations[value.rightRecoveryArgument()].restoreInto(
     
    231227   
    232228    // Materialize all objects. Don't materialize an object until all of the objects it needs
    233     // have been materialized.
     229    // have been materialized. Curiously, this is the only place that we have an algorithm that prevents
     230    // OSR exit from handling cyclic object materializations. Of course, object allocation sinking
     231    // currently wouldn't recognize a cycle as being sinkable - but if it did then the only thing that
     232    // would ahve to change is this fixpoint. Instead we would allocate the objects first and populate
     233    // them with data later.
    234234    HashSet<ExitTimeObjectMaterialization*> toMaterialize;
    235235    for (ExitTimeObjectMaterialization* materialization : exit.m_materializations)
     
    444444    handleExitCounts(jit, exit);
    445445    reifyInlinedCallFrames(jit, exit);
    446    
    447     ArgumentsRecoveryGenerator argumentsRecovery;
    448     for (unsigned index = exit.m_values.size(); index--;) {
    449         if (!exit.m_values[index].isArgumentsObjectThatWasNotCreated())
    450             continue;
    451         int operand = exit.m_values.operandForIndex(index);
    452         argumentsRecovery.generateFor(operand, exit.m_codeOrigin, jit);
    453     }
    454    
    455446    adjustAndJumpToTarget(jit, exit);
    456447   
  • trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp

    r173993 r181993  
    11/*
    2  * Copyright (C) 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2929#if ENABLE(FTL_JIT)
    3030
     31#include "ClonedArguments.h"
     32#include "DirectArguments.h"
    3133#include "JSCInlines.h"
    3234
     
    5557    DeferGCForAWhile deferGC(vm.heap);
    5658   
    57     // In the future, we may have many different kinds of materializations. For now we just
    58     // materialize NewObject.
    59     RELEASE_ASSERT(materialization->type() == PhantomNewObject);
    60    
    61     // First figure out what the structure is.
    62     Structure* structure = nullptr;
    63     for (unsigned i = materialization->properties().size(); i--;) {
    64         const ExitPropertyValue& property = materialization->properties()[i];
    65         if (property.location() != PromotedLocationDescriptor(StructurePLoc))
    66             continue;
    67        
    68         structure = jsCast<Structure*>(JSValue::decode(values[i]));
    69     }
    70     RELEASE_ASSERT(structure);
    71    
    72     // Let's create that object!
    73     JSFinalObject* result = JSFinalObject::create(vm, structure);
    74    
    75     // Now figure out what the heck to populate the object with. Use getPropertiesConcurrently()
    76     // because that happens to be lower-level and more convenient. It doesn't change the
    77     // materialization of the property table. We want to have minimal visible effects on the
    78     // system. Also, don't mind that this is O(n^2). It doesn't matter. We only get here from OSR
    79     // exit.
    80     for (PropertyMapEntry entry : structure->getPropertiesConcurrently()) {
     59    switch (materialization->type()) {
     60    case PhantomNewObject: {
     61        // First figure out what the structure is.
     62        Structure* structure = nullptr;
    8163        for (unsigned i = materialization->properties().size(); i--;) {
    8264            const ExitPropertyValue& property = materialization->properties()[i];
    83             if (property.location().kind() != NamedPropertyPLoc)
     65            if (property.location() != PromotedLocationDescriptor(StructurePLoc))
    8466                continue;
    85             if (codeBlock->identifier(property.location().info()).impl() != entry.key)
    86                 continue;
     67       
     68            structure = jsCast<Structure*>(JSValue::decode(values[i]));
     69            break;
     70        }
     71        RELEASE_ASSERT(structure);
     72   
     73        // Let's create that object!
     74        JSFinalObject* result = JSFinalObject::create(vm, structure);
     75   
     76        // Now figure out what the heck to populate the object with. Use getPropertiesConcurrently()
     77        // because that happens to be lower-level and more convenient. It doesn't change the
     78        // materialization of the property table. We want to have minimal visible effects on the
     79        // system. Also, don't mind that this is O(n^2). It doesn't matter. We only get here from OSR
     80        // exit.
     81        for (PropertyMapEntry entry : structure->getPropertiesConcurrently()) {
     82            for (unsigned i = materialization->properties().size(); i--;) {
     83                const ExitPropertyValue& property = materialization->properties()[i];
     84                if (property.location().kind() != NamedPropertyPLoc)
     85                    continue;
     86                if (codeBlock->identifier(property.location().info()).impl() != entry.key)
     87                    continue;
    8788           
    88             result->putDirect(vm, entry.offset, JSValue::decode(values[i]));
     89                result->putDirect(vm, entry.offset, JSValue::decode(values[i]));
     90            }
     91        }
     92   
     93        return result;
     94    }
     95       
     96    case PhantomDirectArguments:
     97    case PhantomClonedArguments: {
     98        if (!materialization->origin().inlineCallFrame) {
     99            switch (materialization->type()) {
     100            case PhantomDirectArguments:
     101                return DirectArguments::createByCopying(exec);
     102            case PhantomClonedArguments:
     103                return ClonedArguments::createWithMachineFrame(exec, exec, ArgumentsMode::Cloned);
     104            default:
     105                RELEASE_ASSERT_NOT_REACHED();
     106                return nullptr;
     107            }
     108        }
     109
     110        // First figure out the argument count. If there isn't one then we represent the machine frame.
     111        unsigned argumentCount = 0;
     112        if (materialization->origin().inlineCallFrame->isVarargs()) {
     113            for (unsigned i = materialization->properties().size(); i--;) {
     114                const ExitPropertyValue& property = materialization->properties()[i];
     115                if (property.location() != PromotedLocationDescriptor(ArgumentCountPLoc))
     116                    continue;
     117               
     118                argumentCount = JSValue::decode(values[i]).asUInt32();
     119                RELEASE_ASSERT(argumentCount);
     120                break;
     121            }
     122            RELEASE_ASSERT(argumentCount);
     123        } else
     124            argumentCount = materialization->origin().inlineCallFrame->arguments.size();
     125       
     126        JSFunction* callee = nullptr;
     127        if (materialization->origin().inlineCallFrame->isClosureCall) {
     128            for (unsigned i = materialization->properties().size(); i--;) {
     129                const ExitPropertyValue& property = materialization->properties()[i];
     130                if (property.location() != PromotedLocationDescriptor(ArgumentsCalleePLoc))
     131                    continue;
     132               
     133                callee = jsCast<JSFunction*>(JSValue::decode(values[i]));
     134                break;
     135            }
     136        } else
     137            callee = materialization->origin().inlineCallFrame->calleeConstant();
     138        RELEASE_ASSERT(callee);
     139       
     140        CodeBlock* codeBlock = baselineCodeBlockForOriginAndBaselineCodeBlock(
     141            materialization->origin(), exec->codeBlock());
     142       
     143        // We have an inline frame and we have all of the data we need to recreate it.
     144        switch (materialization->type()) {
     145        case PhantomDirectArguments: {
     146            unsigned length = argumentCount - 1;
     147            unsigned capacity = std::max(length, static_cast<unsigned>(codeBlock->numParameters() - 1));
     148            DirectArguments* result = DirectArguments::create(
     149                vm, codeBlock->globalObject()->directArgumentsStructure(), length, capacity);
     150            result->callee().set(vm, result, callee);
     151            for (unsigned i = materialization->properties().size(); i--;) {
     152                const ExitPropertyValue& property = materialization->properties()[i];
     153                if (property.location().kind() != ArgumentPLoc)
     154                    continue;
     155               
     156                unsigned index = property.location().info();
     157                if (index >= capacity)
     158                    continue;
     159                result->setIndexQuickly(vm, index, JSValue::decode(values[i]));
     160            }
     161            return result;
     162        }
     163        case PhantomClonedArguments: {
     164            unsigned length = argumentCount - 1;
     165            ClonedArguments* result = ClonedArguments::createEmpty(
     166                vm, codeBlock->globalObject()->outOfBandArgumentsStructure(), callee);
     167           
     168            for (unsigned i = materialization->properties().size(); i--;) {
     169                const ExitPropertyValue& property = materialization->properties()[i];
     170                if (property.location().kind() != ArgumentPLoc)
     171                    continue;
     172               
     173                unsigned index = property.location().info();
     174                if (index >= length)
     175                    continue;
     176                result->putDirectIndex(exec, index, JSValue::decode(values[i]));
     177            }
     178           
     179            result->putDirect(vm, vm.propertyNames->length, jsNumber(length));
     180            return result;
     181        }
     182        default:
     183            RELEASE_ASSERT_NOT_REACHED();
     184            return nullptr;
    89185        }
    90186    }
    91    
    92     return result;
     187       
     188    default:
     189        RELEASE_ASSERT_NOT_REACHED();
     190        return nullptr;
     191    }
    93192}
    94193
  • trunk/Source/JavaScriptCore/ftl/FTLOutput.h

    r181035 r181993  
    134134    LValue bitXor(LValue left, LValue right) { return buildXor(m_builder, left, right); }
    135135    LValue shl(LValue left, LValue right) { return buildShl(m_builder, left, right); }
    136     LValue aShr(LValue left, LValue right) { return buildAShr(m_builder, left, right); }
    137     LValue lShr(LValue left, LValue right) { return buildLShr(m_builder, left, right); }
     136    LValue aShr(LValue left, LValue right) { return buildAShr(m_builder, left, right); } // arithmetic = signed
     137    LValue lShr(LValue left, LValue right) { return buildLShr(m_builder, left, right); } // logical = unsigned
    138138    LValue bitNot(LValue value) { return buildNot(m_builder, value); }
    139139   
     
    203203    LValue signExt(LValue value, LType type) { return buildSExt(m_builder, value, type); }
    204204    LValue zeroExt(LValue value, LType type) { return buildZExt(m_builder, value, type); }
     205    LValue zeroExtPtr(LValue value) { return zeroExt(value, intPtr); }
    205206    LValue fpToInt(LValue value, LType type) { return buildFPToSI(m_builder, value, type); }
    206207    LValue fpToUInt(LValue value, LType type) { return buildFPToUI(m_builder, value, type); }
     
    218219    LValue bitCast(LValue value, LType type) { return buildBitCast(m_builder, value, type); }
    219220   
     221    // Hilariously, the #define machinery in the stdlib means that this method is actually called
     222    // __builtin_alloca. So far this appears benign. :-|
    220223    LValue alloca(LType type) { return buildAlloca(m_builder, type); }
    221224   
  • trunk/Source/JavaScriptCore/heap/CopyToken.h

    r174795 r181993  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3333    TypedArrayVectorCopyToken,
    3434    MapBackingStoreCopyToken,
    35     ArgumentsSlowArgumentDataCopyToken
     35    DirectArgumentsOverridesCopyToken
    3636};
    3737
  • trunk/Source/JavaScriptCore/interpreter/CallFrame.h

    r179862 r181993  
    240240        }
    241241
     242        JSValue getArgumentUnsafe(size_t argIndex)
     243        {
     244            // User beware! This method does not verify that there is a valid
     245            // argument at the specified argIndex. This is used for debugging
     246            // and verification code only. The caller is expected to know what
     247            // he/she is doing when calling this method.
     248            return this[argumentOffset(argIndex)].jsValue();
     249        }
     250
    242251        static int thisArgumentOffset() { return argumentOffsetIncludingThis(0); }
    243252        JSValue thisValue() { return this[thisArgumentOffset()].jsValue(); }
     
    296305        }
    297306
    298         JSValue getArgumentUnsafe(size_t argIndex)
    299         {
    300             // User beware! This method does not verify that there is a valid
    301             // argument at the specified argIndex. This is used for debugging
    302             // and verification code only. The caller is expected to know what
    303             // he/she is doing when calling this method.
    304             return this[argumentOffset(argIndex)].jsValue();
    305         }
    306 
    307307        void* callerFrameOrVMEntryFrame() const { return callerFrameAndPC().callerFrame; }
    308308
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r181889 r181993  
    3131#include "Interpreter.h"
    3232
    33 #include "Arguments.h"
    3433#include "BatchedTransitionOptimizer.h"
    3534#include "CallFrameClosure.h"
    3635#include "CallFrameInlines.h"
     36#include "ClonedArguments.h"
    3737#include "CodeBlock.h"
     38#include "DirectArguments.h"
    3839#include "Heap.h"
    3940#include "Debugger.h"
     
    4546#include "JSArray.h"
    4647#include "JSBoundFunction.h"
     48#include "JSCInlines.h"
    4749#include "JSLexicalEnvironment.h"
    4850#include "JSNameScope.h"
     
    5658#include "LiteralParser.h"
    5759#include "ObjectPrototype.h"
    58 #include "JSCInlines.h"
    5960#include "Parser.h"
    6061#include "ProtoCallFrame.h"
     
    6364#include "Register.h"
    6465#include "SamplingTool.h"
     66#include "ScopedArguments.h"
    6567#include "StackAlignment.h"
    6668#include "StackVisitor.h"
     
    137139unsigned sizeOfVarargs(CallFrame* callFrame, JSValue arguments, uint32_t firstVarArgOffset)
    138140{
     141    if (UNLIKELY(!arguments.isCell())) {
     142        if (arguments.isUndefinedOrNull())
     143            return 0;
     144       
     145        callFrame->vm().throwException(callFrame, createInvalidFunctionApplyParameterError(callFrame, arguments));
     146        return 0;
     147    }
     148   
     149    JSCell* cell = arguments.asCell();
    139150    unsigned length;
    140     if (!arguments)
    141         length = callFrame->argumentCount();
    142     else if (arguments.isUndefinedOrNull())
    143         length = 0;
    144     else if (!arguments.isObject()) {
     151    switch (cell->type()) {
     152    case DirectArgumentsType:
     153        length = jsCast<DirectArguments*>(cell)->length(callFrame);
     154        break;
     155    case ScopedArgumentsType:
     156        length =jsCast<ScopedArguments*>(cell)->length(callFrame);
     157        break;
     158    case StringType:
    145159        callFrame->vm().throwException(callFrame, createInvalidFunctionApplyParameterError(callFrame,  arguments));
    146160        return 0;
    147     } else if (asObject(arguments)->classInfo() == Arguments::info())
    148         length = asArguments(arguments)->length(callFrame);
    149     else if (isJSArray(arguments))
    150         length = asArray(arguments)->length();
    151     else
    152         length = asObject(arguments)->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
     161    default:
     162        ASSERT(arguments.isObject());
     163        if (isJSArray(cell))
     164            length = jsCast<JSArray*>(cell)->length();
     165        else
     166            length = jsCast<JSObject*>(cell)->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
     167        break;
     168    }
    153169   
    154170    if (length >= firstVarArgOffset)
     
    165181   
    166182    CallFrame* calleeFrame = calleeFrameForVarargs(callFrame, numUsedStackSlots, length + 1);
    167     if (length > Arguments::MaxArguments || !stack->ensureCapacityFor(calleeFrame->registers())) {
     183    if (length > maxArguments || !stack->ensureCapacityFor(calleeFrame->registers())) {
    168184        throwStackOverflowError(callFrame);
    169185        return 0;
     
    175191void loadVarargs(CallFrame* callFrame, VirtualRegister firstElementDest, JSValue arguments, uint32_t offset, uint32_t length)
    176192{
    177     if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
    178         for (size_t i = 0; i < length; ++i)
    179             callFrame->r(firstElementDest + i) = callFrame->argumentAfterCapture(i + offset);
     193    if (UNLIKELY(!arguments.isCell()))
    180194        return;
    181     }
    182    
    183     if (arguments.isUndefinedOrNull())
     195   
     196    JSCell* cell = arguments.asCell();
     197    switch (cell->type()) {
     198    case DirectArgumentsType:
     199        jsCast<DirectArguments*>(cell)->copyToArguments(callFrame, firstElementDest, offset, length);
    184200        return;
    185    
    186     if (asObject(arguments)->classInfo() == Arguments::info()) {
    187         asArguments(arguments)->copyToArguments(callFrame, firstElementDest, offset, length);
     201    case ScopedArgumentsType:
     202        jsCast<ScopedArguments*>(cell)->copyToArguments(callFrame, firstElementDest, offset, length);
    188203        return;
    189     }
    190    
    191     if (isJSArray(arguments)) {
    192         asArray(arguments)->copyToArguments(callFrame, firstElementDest, offset, length);
     204    default: {
     205        ASSERT(arguments.isObject());
     206        JSObject* object = jsCast<JSObject*>(cell);
     207        if (isJSArray(object)) {
     208            jsCast<JSArray*>(object)->copyToArguments(callFrame, firstElementDest, offset, length);
     209            return;
     210        }
     211        unsigned i;
     212        for (i = 0; i < length && object->canGetIndexQuickly(i + offset); ++i)
     213            callFrame->r(firstElementDest + i) = object->getIndexQuickly(i + offset);
     214        for (; i < length; ++i)
     215            callFrame->r(firstElementDest + i) = object->get(callFrame, i + offset);
    193216        return;
    194     }
    195    
    196     for (unsigned i = 0; i < length; ++i) {
    197         callFrame->r(firstElementDest + i) = asObject(arguments)->get(callFrame, i + offset);
    198         if (UNLIKELY(callFrame->vm().exception()))
    199             return;
    200     }
     217    } }
    201218}
    202219
     
    385402            debugger->didExecuteProgram(callFrame);
    386403        ASSERT(!callFrame->hadException());
    387     }
    388 
    389     if (CodeBlock* codeBlock = visitor->codeBlock()) {
    390         if (codeBlock->codeType() == FunctionCode && codeBlock->needsActivation()) {
    391 #if ENABLE(DFG_JIT)
    392             RELEASE_ASSERT(!visitor->isInlinedFrame());
    393 #endif
    394         }
    395 
    396         if (codeBlock->codeType() == FunctionCode && codeBlock->usesArguments()) {
    397             if (Arguments* arguments = visitor->existingArguments()) {
    398 #if ENABLE(DFG_JIT)
    399                 if (visitor->isInlinedFrame())
    400                     arguments->tearOff(callFrame, visitor->inlineCallFrame());
    401                 else
    402 #endif
    403                     arguments->tearOff(callFrame);
    404             }
    405         }
    406404    }
    407405
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.h

    r180279 r181993  
    310310
    311311    unsigned sizeOfVarargs(CallFrame* exec, JSValue arguments, uint32_t firstVarArgOffset);
     312    static const unsigned maxArguments = 0x10000;
    312313    unsigned sizeFrameForVarargs(CallFrame* exec, JSStack*, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset);
    313314    void loadVarargs(CallFrame* execCaller, VirtualRegister firstElementDest, JSValue source, uint32_t offset, uint32_t length);
  • trunk/Source/JavaScriptCore/interpreter/StackVisitor.cpp

    r180279 r181993  
    2727#include "StackVisitor.h"
    2828
    29 #include "Arguments.h"
    3029#include "CallFrameInlines.h"
     30#include "ClonedArguments.h"
    3131#include "Executable.h"
    3232#include "Interpreter.h"
     
    256256}
    257257
    258 Arguments* StackVisitor::Frame::createArguments()
     258ClonedArguments* StackVisitor::Frame::createArguments()
    259259{
    260260    ASSERT(m_callFrame);
    261261    CallFrame* physicalFrame = m_callFrame;
    262     VM& vm = physicalFrame->vm();
    263     Arguments* arguments;
     262    ClonedArguments* arguments;
    264263    ArgumentsMode mode;
    265264    if (Options::enableFunctionDotArguments())
    266         mode = ClonedArgumentsCreationMode;
     265        mode = ArgumentsMode::Cloned;
    267266    else
    268         mode = FakeArgumentValuesCreationMode;
     267        mode = ArgumentsMode::FakeValues;
    269268#if ENABLE(DFG_JIT)
    270269    if (isInlinedFrame()) {
    271270        ASSERT(m_inlineCallFrame);
    272         arguments = Arguments::create(vm, physicalFrame, m_inlineCallFrame, mode);
    273         arguments->tearOff(physicalFrame, m_inlineCallFrame);
    274         jsCast<Arguments*>((JSCell*)arguments);
     271        arguments = ClonedArguments::createWithInlineFrame(physicalFrame, physicalFrame, m_inlineCallFrame, mode);
    275272    } else
    276273#endif
    277     {
    278         JSLexicalEnvironment* lexicalEnvironment = nullptr;
    279         arguments = Arguments::create(vm, physicalFrame, lexicalEnvironment, mode);
    280         arguments->tearOff(physicalFrame);
    281     }
     274        arguments = ClonedArguments::createWithMachineFrame(physicalFrame, physicalFrame, mode);
    282275    return arguments;
    283 }
    284 
    285 Arguments* StackVisitor::Frame::existingArguments()
    286 {
    287     if (codeBlock()->codeType() != FunctionCode)
    288         return 0;
    289     if (!codeBlock()->usesArguments())
    290         return 0;
    291    
    292     VirtualRegister reg;
    293        
    294 #if ENABLE(DFG_JIT)
    295     if (isInlinedFrame())
    296         reg = inlineCallFrame()->argumentsRegister;
    297     else
    298 #endif // ENABLE(DFG_JIT)
    299         reg = codeBlock()->argumentsRegister();
    300 
    301     // Care should be taken here since exception fuzzing may raise exceptions in
    302     // places where they would be otherwise impossible. Therefore, callFrame may
    303     // lack activation even if the codeBlock signals need of activation. Also,
    304     // even if codeBlock signals the use of arguments, the
    305     // unmodifiedArgumentsRegister may not be initialized yet (neither locally
    306     // nor in lexicalEnvironment).
    307     JSValue result = jsUndefined();
    308     if (codeBlock()->needsActivation() && callFrame()->hasActivation())
    309         result = callFrame()->lexicalEnvironment()->registerAt(unmodifiedArgumentsRegister(reg).offset()).get();
    310     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).
    311         result = callFrame()->r(unmodifiedArgumentsRegister(reg).offset()).jsValue();
    312     if (!result || !result.isCell()) // Protect against the case when exception fuzzing throws when unmodifiedArgumentsRegister is not set up yet (e.g., in op_enter).
    313         return 0;
    314     return jsCast<Arguments*>(result);
    315276}
    316277
  • trunk/Source/JavaScriptCore/interpreter/StackVisitor.h

    r176479 r181993  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3535struct InlineCallFrame;
    3636
    37 class Arguments;
    3837class CodeBlock;
    3938class ExecState;
     
    4140class JSObject;
    4241class JSScope;
     42class ClonedArguments;
    4343class Register;
    4444
     
    7979        JS_EXPORT_PRIVATE void computeLineAndColumn(unsigned& line, unsigned& column);
    8080
    81         Arguments* createArguments();
    82         Arguments* existingArguments();
     81        ClonedArguments* createArguments();
    8382        VMEntryFrame* vmEntryFrame() const { return m_VMEntryFrame; }
    8483        CallFrame* callFrame() const { return m_callFrame; }
  • trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h

    r180279 r181993  
    8989    }
    9090   
     91    void storeValue(JSValueRegs regs, BaseIndex address)
     92    {
     93#if USE(JSVALUE64)
     94        store64(regs.gpr(), address);
     95#else
     96        store32(regs.payloadGPR(), address.withOffset(PayloadOffset));
     97        store32(regs.tagGPR(), address.withOffset(TagOffset));
     98#endif
     99    }
     100   
    91101    void storeValue(JSValueRegs regs, void* address)
    92102    {
     
    114124    }
    115125   
     126    void loadValue(BaseIndex address, JSValueRegs regs)
     127    {
     128#if USE(JSVALUE64)
     129        load64(address, regs.gpr());
     130#else
     131        if (address.base == regs.payloadGPR() || address.index == regs.payloadGPR()) {
     132            // We actually could handle the case where the registers are aliased to both
     133            // tag and payload, but we don't for now.
     134            RELEASE_ASSERT(address.base != regs.tagGPR());
     135            RELEASE_ASSERT(address.index != regs.tagGPR());
     136           
     137            load32(address.withOffset(TagOffset), regs.tagGPR());
     138            load32(address.withOffset(PayloadOffset), regs.payloadGPR());
     139        } else {
     140            load32(address.withOffset(PayloadOffset), regs.payloadGPR());
     141            load32(address.withOffset(TagOffset), regs.tagGPR());
     142        }
     143#endif
     144    }
     145   
    116146    void moveTrustedValue(JSValue value, JSValueRegs regs)
    117147    {
     
    121151        move(TrustedImm32(value.tag()), regs.tagGPR());
    122152        move(TrustedImm32(value.payload()), regs.payloadGPR());
     153#endif
     154    }
     155   
     156    void storeTrustedValue(JSValue value, Address address)
     157    {
     158#if USE(JSVALUE64)
     159        store64(TrustedImm64(JSValue::encode(value)), address);
     160#else
     161        store32(TrustedImm32(value.tag()), address.withOffset(TagOffset));
     162        store32(TrustedImm32(value.payload()), address.withOffset(PayloadOffset));
     163#endif
     164    }
     165
     166    void storeTrustedValue(JSValue value, BaseIndex address)
     167    {
     168#if USE(JSVALUE64)
     169        store64(TrustedImm64(JSValue::encode(value)), address);
     170#else
     171        store32(TrustedImm32(value.tag()), address.withOffset(TagOffset));
     172        store32(TrustedImm32(value.payload()), address.withOffset(PayloadOffset));
    123173#endif
    124174    }
     
    325375#else
    326376        return branch32(MacroAssembler::NotEqual, reg, TrustedImm32(JSValue::CellTag));
     377#endif
     378    }
     379    Jump branchIfNotCell(JSValueRegs regs)
     380    {
     381#if USE(JSVALUE64)
     382        return branchIfNotCell(regs.gpr());
     383#else
     384        return branchIfNotCell(regs.tagGPR());
     385#endif
     386    }
     387   
     388    Jump branchIsEmpty(JSValueRegs regs)
     389    {
     390#if USE(JSVALUE64)
     391        return branchTest64(Zero, regs.gpr());
     392#else
     393        return branch32(Equal, regs.tagGPR(), TrustedImm32(JSValue::EmptyValueTag));
    327394#endif
    328395    }
     
    635702    }
    636703   
    637     VirtualRegister baselineArgumentsRegisterFor(InlineCallFrame* inlineCallFrame)
     704    SymbolTable* symbolTableFor(const CodeOrigin& codeOrigin)
     705    {
     706        return baselineCodeBlockFor(codeOrigin)->symbolTable();
     707    }
     708
     709    static VirtualRegister argumentsStart(InlineCallFrame* inlineCallFrame)
    638710    {
    639711        if (!inlineCallFrame)
    640             return baselineCodeBlock()->argumentsRegister();
    641        
    642         return VirtualRegister(baselineCodeBlockForInlineCallFrame(
    643             inlineCallFrame)->argumentsRegister().offset() + inlineCallFrame->stackOffset);
    644     }
    645    
    646     VirtualRegister baselineArgumentsRegisterFor(const CodeOrigin& codeOrigin)
    647     {
    648         return baselineArgumentsRegisterFor(codeOrigin.inlineCallFrame);
    649     }
    650    
    651     SymbolTable* symbolTableFor(const CodeOrigin& codeOrigin)
    652     {
    653         return baselineCodeBlockFor(codeOrigin)->symbolTable();
    654     }
    655 
    656     int offsetOfLocals(const CodeOrigin& codeOrigin)
    657     {
    658         if (!codeOrigin.inlineCallFrame)
    659             return 0;
    660         return codeOrigin.inlineCallFrame->stackOffset * sizeof(Register);
    661     }
    662 
    663     int offsetOfArguments(InlineCallFrame* inlineCallFrame)
    664     {
    665         if (!inlineCallFrame)
    666             return CallFrame::argumentOffset(0) * sizeof(Register);
     712            return VirtualRegister(CallFrame::argumentOffset(0));
    667713        if (inlineCallFrame->arguments.size() <= 1)
    668             return 0;
     714            return virtualRegisterForLocal(0);
    669715        ValueRecovery recovery = inlineCallFrame->arguments[1];
    670716        RELEASE_ASSERT(recovery.technique() == DisplacedInJSStack);
    671         return recovery.virtualRegister().offset() * sizeof(Register);
    672     }
    673    
    674     int offsetOfArguments(const CodeOrigin& codeOrigin)
    675     {
    676         return offsetOfArguments(codeOrigin.inlineCallFrame);
     717        return recovery.virtualRegister();
     718    }
     719   
     720    static VirtualRegister argumentsStart(const CodeOrigin& codeOrigin)
     721    {
     722        return argumentsStart(codeOrigin.inlineCallFrame);
    677723    }
    678724   
  • trunk/Source/JavaScriptCore/jit/CCallHelpers.h

    r180938 r181993  
    3434namespace JSC {
    3535
     36#if CPU(MIPS) || (OS(WINDOWS) && CPU(X86_64))
     37#define POKE_ARGUMENT_OFFSET 4
     38#else
     39#define POKE_ARGUMENT_OFFSET 0
     40#endif
     41
    3642class CCallHelpers : public AssemblyHelpers {
    3743public:
     
    3945        : AssemblyHelpers(vm, codeBlock)
    4046    {
     47    }
     48   
     49    // The most general helper for setting arguments that fit in a GPR, if you can compute each
     50    // argument without using any argument registers. You usually want one of the setupArguments*()
     51    // methods below instead of this. This thing is most useful if you have *a lot* of arguments.
     52    template<typename Functor>
     53    void setupArgument(unsigned argumentIndex, const Functor& functor)
     54    {
     55        unsigned numberOfRegs = GPRInfo::numberOfArgumentRegisters; // Disguise the constant from clang's tautological compare warning.
     56        if (argumentIndex < numberOfRegs) {
     57            functor(GPRInfo::toArgumentRegister(argumentIndex));
     58            return;
     59        }
     60       
     61        functor(GPRInfo::nonArgGPR0);
     62        poke(GPRInfo::nonArgGPR0, POKE_ARGUMENT_OFFSET + argumentIndex - GPRInfo::numberOfArgumentRegisters);
    4163    }
    4264
     
    864886    }
    865887
    866 #if CPU(MIPS) || (OS(WINDOWS) && CPU(X86_64))
    867 #define POKE_ARGUMENT_OFFSET 4
    868 #else
    869 #define POKE_ARGUMENT_OFFSET 0
    870 #endif
    871 
    872888#if CPU(X86_64) || CPU(ARM64)
    873889    ALWAYS_INLINE void setupArguments(FPRReg arg1)
  • trunk/Source/JavaScriptCore/jit/GPRInfo.h

    r180279 r181993  
    11/*
    2  * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5555    }
    5656   
     57    static JSValueRegs withTwoAvailableRegs(GPRReg gpr, GPRReg)
     58    {
     59        return JSValueRegs(gpr);
     60    }
     61   
    5762    bool operator!() const { return m_gpr == InvalidGPRReg; }
    5863   
     
    145150        , m_payloadGPR(payloadGPR)
    146151    {
     152    }
     153   
     154    static JSValueRegs withTwoAvailableRegs(GPRReg gpr1, GPRReg gpr2)
     155    {
     156        return JSValueRegs(gpr1, gpr2);
    147157    }
    148158   
     
    324334        static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5 };
    325335        return registerForIndex[index];
     336    }
     337
     338    static GPRReg toArgumentRegister(unsigned)
     339    {
     340        UNREACHABLE_FOR_PLATFORM();
     341        return InvalidGPRReg;
    326342    }
    327343
     
    495511        ASSERT(index < numberOfRegisters);
    496512        static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7, regT8 };
     513        return registerForIndex[index];
     514    }
     515
     516    static GPRReg toArgumentRegister(unsigned index)
     517    {
     518        ASSERT(index < numberOfArgumentRegisters);
     519        static const GPRReg registerForIndex[numberOfArgumentRegisters] = { argumentGPR0, argumentGPR1, argumentGPR2, argumentGPR3 };
    497520        return registerForIndex[index];
    498521    }
  • trunk/Source/JavaScriptCore/jit/JIT.cpp

    r181990 r181993  
    203203        DEFINE_OP(op_create_this)
    204204        DEFINE_OP(op_to_this)
     205        DEFINE_OP(op_create_direct_arguments)
     206        DEFINE_OP(op_create_scoped_arguments)
     207        DEFINE_OP(op_create_out_of_band_arguments)
    205208        DEFINE_OP(op_check_tdz)
    206         DEFINE_OP(op_init_lazy_reg)
    207         DEFINE_OP(op_create_arguments)
    208209        DEFINE_OP(op_debug)
    209210        DEFINE_OP(op_del_by_id)
     
    218219        case op_get_array_length:
    219220        DEFINE_OP(op_get_by_id)
    220         DEFINE_OP(op_get_arguments_length)
    221221        DEFINE_OP(op_get_by_val)
    222         DEFINE_OP(op_get_argument_by_val)
    223222        DEFINE_OP(op_check_has_instance)
    224223        DEFINE_OP(op_instanceof)
     
    292291        DEFINE_OP(op_switch_imm)
    293292        DEFINE_OP(op_switch_string)
    294         DEFINE_OP(op_tear_off_arguments)
    295293        DEFINE_OP(op_throw)
    296294        DEFINE_OP(op_throw_static_error)
     
    301299        DEFINE_OP(op_get_from_scope)
    302300        DEFINE_OP(op_put_to_scope)
     301        DEFINE_OP(op_get_from_arguments)
     302        DEFINE_OP(op_put_to_arguments)
    303303
    304304        DEFINE_OP(op_get_enumerable_length)
     
    385385        case op_get_array_length:
    386386        DEFINE_SLOWCASE_OP(op_get_by_id)
    387         DEFINE_SLOWCASE_OP(op_get_arguments_length)
    388387        DEFINE_SLOWCASE_OP(op_get_by_val)
    389         DEFINE_SLOWCASE_OP(op_get_argument_by_val)
    390388        DEFINE_SLOWCASE_OP(op_check_has_instance)
    391389        DEFINE_SLOWCASE_OP(op_instanceof)
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r181891 r181993  
    347347        JumpList emitContiguousGetByVal(Instruction*, PatchableJump& badType, IndexingType expectedShape = ContiguousShape);
    348348        JumpList emitArrayStorageGetByVal(Instruction*, PatchableJump& badType);
     349        JumpList emitDirectArgumentsGetByVal(Instruction*, PatchableJump& badType);
     350        JumpList emitScopedArgumentsGetByVal(Instruction*, PatchableJump& badType);
    349351        JumpList emitIntTypedArrayGetByVal(Instruction*, PatchableJump& badType, TypedArrayType);
    350352        JumpList emitFloatTypedArrayGetByVal(Instruction*, PatchableJump& badType, TypedArrayType);
     
    469471        void emit_op_create_this(Instruction*);
    470472        void emit_op_to_this(Instruction*);
     473        void emit_op_create_direct_arguments(Instruction*);
     474        void emit_op_create_scoped_arguments(Instruction*);
     475        void emit_op_create_out_of_band_arguments(Instruction*);
    471476        void emit_op_check_tdz(Instruction*);
    472         void emit_op_create_arguments(Instruction*);
    473477        void emit_op_debug(Instruction*);
    474478        void emit_op_del_by_id(Instruction*);
     
    621625        void emit_op_get_from_scope(Instruction*);
    622626        void emit_op_put_to_scope(Instruction*);
     627        void emit_op_get_from_arguments(Instruction*);
     628        void emit_op_put_to_arguments(Instruction*);
    623629        void emitSlow_op_resolve_scope(Instruction*, Vector<SlowCaseEntry>::iterator&);
    624630        void emitSlow_op_get_from_scope(Instruction*, Vector<SlowCaseEntry>::iterator&);
     
    698704        MacroAssembler::Call callOperation(J_JITOperation_EJIdc, int, GPRReg, const Identifier*);
    699705        MacroAssembler::Call callOperation(J_JITOperation_EJJ, int, GPRReg, GPRReg);
     706        MacroAssembler::Call callOperation(C_JITOperation_EJsc, GPRReg);
    700707        MacroAssembler::Call callOperation(J_JITOperation_EJscC, int, GPRReg, JSCell*);
    701708        MacroAssembler::Call callOperation(C_JITOperation_EJscZ, GPRReg, int32_t);
  • trunk/Source/JavaScriptCore/jit/JITCall.cpp

    r180279 r181993  
    3030#include "JIT.h"
    3131
    32 #include "Arguments.h"
    3332#include "CodeBlock.h"
    3433#include "JITInlines.h"
     
    6362    int firstVarArgOffset = instruction[6].u.operand;
    6463
    65     JumpList slowCase;
    66     JumpList end;
    67     bool canOptimize = m_codeBlock->usesArguments()
    68         && arguments == m_codeBlock->argumentsRegister().offset()
    69         && !m_codeBlock->symbolTable()->slowArguments();
    70 
    71     if (canOptimize) {
    72         emitGetVirtualRegister(arguments, regT0);
    73         slowCase.append(branch64(NotEqual, regT0, TrustedImm64(JSValue::encode(JSValue()))));
    74        
    75         move(TrustedImm32(-firstFreeRegister), regT1);
    76         emitSetupVarargsFrameFastCase(*this, regT1, regT0, regT1, regT2, firstVarArgOffset, slowCase);
    77         end.append(jump());
    78         slowCase.link(this);
    79     }
    80 
    8164    emitGetVirtualRegister(arguments, regT1);
    8265    callOperation(operationSizeFrameForVarargs, regT1, -firstFreeRegister, firstVarArgOffset);
     
    8871    move(returnValueGPR, regT1);
    8972
    90     if (canOptimize)
    91         end.link(this);
    92    
    9373    // Profile the argument count.
    9474    load32(Address(regT1, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + PayloadOffset), regT2);
  • trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp

    r180279 r181993  
    3030#include "JIT.h"
    3131
    32 #include "Arguments.h"
    3332#include "CodeBlock.h"
    3433#include "Interpreter.h"
     
    123122    int firstVarArgOffset = instruction[6].u.operand;
    124123
    125     JumpList slowCase;
    126     JumpList end;
    127     bool canOptimize = m_codeBlock->usesArguments()
    128         && VirtualRegister(arguments) == m_codeBlock->argumentsRegister()
    129         && !m_codeBlock->symbolTable()->slowArguments();
    130 
    131     if (canOptimize) {
    132         emitLoadTag(arguments, regT1);
    133         slowCase.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::EmptyValueTag)));
    134        
    135         move(TrustedImm32(-firstFreeRegister), regT1);
    136         emitSetupVarargsFrameFastCase(*this, regT1, regT0, regT1, regT2, firstVarArgOffset, slowCase);
    137         end.append(jump());
    138         slowCase.link(this);
    139     }
    140 
    141124    emitLoad(arguments, regT1, regT0);
    142125    callOperation(operationSizeFrameForVarargs, regT1, regT0, -firstFreeRegister, firstVarArgOffset);
     
    147130    callOperation(operationSetupVarargsFrame, regT1, regT2, regT4, firstVarArgOffset, regT0);
    148131    move(returnValueGPR, regT1);
    149 
    150     if (canOptimize)
    151         end.link(this);
    152132
    153133    // Profile the argument count.
  • trunk/Source/JavaScriptCore/jit/JITInlines.h

    r181343 r181993  
    194194}
    195195
     196ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(C_JITOperation_EJsc operation, GPRReg arg1)
     197{
     198    setupArgumentsWithExecState(arg1);
     199    return appendCallWithExceptionCheck(operation);
     200}
     201
    196202ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(C_JITOperation_EJscZ operation, GPRReg arg1, int32_t arg2)
    197203{
  • trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp

    r181891 r181993  
    2929#include "JIT.h"
    3030
    31 #include "Arguments.h"
    3231#include "BasicBlockLocation.h"
    3332#include "CopiedSpaceInlines.h"
     
    246245}
    247246
    248 void JIT::emit_op_tear_off_arguments(Instruction* currentInstruction)
    249 {
    250     int arguments = currentInstruction[1].u.operand;
    251     int lexicalEnvironment = currentInstruction[2].u.operand;
    252 
    253     Jump argsNotCreated = branchTest64(Zero, Address(callFrameRegister, sizeof(Register) * (VirtualRegister(arguments).offset())));
    254     emitGetVirtualRegister(VirtualRegister(arguments).offset(), regT0);
    255     emitGetVirtualRegister(lexicalEnvironment, regT1);
    256     callOperation(operationTearOffArguments, regT0, regT1);
    257     argsNotCreated.link(this);
    258 }
    259 
    260247void JIT::emit_op_ret(Instruction* currentInstruction)
    261248{
     
    678665
    679666    emitGetVirtualRegister(scope, regT0);
    680     callOperation(operationCreateActivation, regT0, 0);
     667    callOperation(operationCreateActivation, regT0);
    681668    emitStoreCell(dst, returnValueGPR);
    682669    emitStoreCell(scope, returnValueGPR);
     
    689676    loadPtr(Address(regT0, JSFunction::offsetOfScopeChain()), regT0);
    690677    emitStoreCell(dst, regT0);
    691 }
    692 
    693 void JIT::emit_op_create_arguments(Instruction* currentInstruction)
    694 {
    695     int dst = currentInstruction[1].u.operand;
    696     int lexicalEnvironment = currentInstruction[2].u.operand;
    697 
    698     Jump argsCreated = branchTest64(NonZero, Address(callFrameRegister, sizeof(Register) * dst));
    699 
    700     if (VirtualRegister(lexicalEnvironment).isValid()) {
    701         emitGetVirtualRegister(lexicalEnvironment, regT0);
    702         callOperation(operationCreateArguments, regT0);
    703     } else
    704         callOperation(operationCreateArguments, TrustedImmPtr(nullptr));
    705     emitStoreCell(dst, returnValueGPR);
    706     emitStoreCell(unmodifiedArgumentsRegister(VirtualRegister(dst)), returnValueGPR);
    707 
    708     argsCreated.link(this);
    709 }
    710 
    711 void JIT::emit_op_init_lazy_reg(Instruction* currentInstruction)
    712 {
    713     int dst = currentInstruction[1].u.operand;
    714 
    715     store64(TrustedImm64((int64_t)0), Address(callFrameRegister, sizeof(Register) * dst));
    716678}
    717679
     
    914876    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_to_number);
    915877    slowPathCall.call();
    916 }
    917 
    918 void JIT::emit_op_get_arguments_length(Instruction* currentInstruction)
    919 {
    920     int dst = currentInstruction[1].u.operand;
    921     int argumentsRegister = currentInstruction[2].u.operand;
    922     addSlowCase(branchTest64(NonZero, addressFor(argumentsRegister)));
    923     emitGetFromCallFrameHeader32(JSStack::ArgumentCount, regT0);
    924     sub32(TrustedImm32(1), regT0);
    925     emitFastArithReTagImmediate(regT0, regT0);
    926     emitPutVirtualRegister(dst, regT0);
    927 }
    928 
    929 void JIT::emitSlow_op_get_arguments_length(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    930 {
    931     linkSlowCase(iter);
    932     int dst = currentInstruction[1].u.operand;
    933     int base = currentInstruction[2].u.operand;
    934     callOperation(operationGetArgumentsLength, dst, base);
    935 }
    936 
    937 void JIT::emit_op_get_argument_by_val(Instruction* currentInstruction)
    938 {
    939     int dst = currentInstruction[1].u.operand;
    940     int argumentsRegister = currentInstruction[2].u.operand;
    941     int property = currentInstruction[3].u.operand;
    942     addSlowCase(branchTest64(NonZero, addressFor(argumentsRegister)));
    943     emitGetVirtualRegister(property, regT1);
    944     addSlowCase(emitJumpIfNotImmediateInteger(regT1));
    945     emitGetFromCallFrameHeader32(JSStack::ArgumentCount, regT2);
    946     sub32(TrustedImm32(1), regT2);
    947     addSlowCase(branch32(AboveOrEqual, regT1, regT2));
    948 
    949     signExtend32ToPtr(regT1, regT1);
    950     load64(BaseIndex(callFrameRegister, regT1, TimesEight, CallFrame::argumentOffset(0) * static_cast<int>(sizeof(Register))), regT0);
    951     emitValueProfilingSite();
    952     emitPutVirtualRegister(dst, regT0);
    953 }
    954 
    955 void JIT::emitSlow_op_get_argument_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    956 {
    957     int dst = currentInstruction[1].u.operand;
    958     int arguments = currentInstruction[2].u.operand;
    959     int property = currentInstruction[3].u.operand;
    960     int lexicalEnvironment = currentInstruction[4].u.operand;
    961    
    962     linkSlowCase(iter);
    963     Jump skipArgumentsCreation = jump();
    964    
    965     linkSlowCase(iter);
    966     linkSlowCase(iter);
    967     if (VirtualRegister(lexicalEnvironment).isValid()) {
    968         emitGetVirtualRegister(lexicalEnvironment, regT0);
    969         callOperation(operationCreateArguments, regT0);
    970     } else
    971         callOperation(operationCreateArguments, TrustedImmPtr(nullptr));
    972     emitStoreCell(arguments, returnValueGPR);
    973     emitStoreCell(unmodifiedArgumentsRegister(VirtualRegister(arguments)), returnValueGPR);
    974    
    975     skipArgumentsCreation.link(this);
    976     emitGetVirtualRegister(arguments, regT0);
    977     emitGetVirtualRegister(property, regT1);
    978     callOperation(WithProfile, operationGetByValGeneric, dst, regT0, regT1);
    979878}
    980879
     
    1043942    Jump lazyJump;
    1044943    int dst = currentInstruction[1].u.operand;
    1045     if (currentInstruction[4].u.operand) {
    1046 #if USE(JSVALUE32_64)
    1047         lazyJump = branch32(NotEqual, tagFor(dst), TrustedImm32(JSValue::EmptyValueTag));
    1048 #else
    1049         lazyJump = branchTest64(NonZero, addressFor(dst));
    1050 #endif
    1051     }
    1052944
    1053945#if USE(JSVALUE64)
     
    1058950    FunctionExecutable* funcExec = m_codeBlock->functionDecl(currentInstruction[3].u.operand);
    1059951    callOperation(operationNewFunction, dst, regT0, funcExec);
    1060 
    1061     if (currentInstruction[4].u.operand)
    1062         lazyJump.link(this);
    1063952}
    1064953
     
    14351324}
    14361325
     1326void JIT::emit_op_create_direct_arguments(Instruction* currentInstruction)
     1327{
     1328    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_create_direct_arguments);
     1329    slowPathCall.call();
     1330}
     1331
     1332void JIT::emit_op_create_scoped_arguments(Instruction* currentInstruction)
     1333{
     1334    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_create_scoped_arguments);
     1335    slowPathCall.call();
     1336}
     1337
     1338void JIT::emit_op_create_out_of_band_arguments(Instruction* currentInstruction)
     1339{
     1340    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_create_out_of_band_arguments);
     1341    slowPathCall.call();
     1342}
     1343
    14371344} // namespace JSC
    14381345
  • trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp

    r181891 r181993  
    350350}
    351351
    352 void JIT::emit_op_tear_off_arguments(Instruction* currentInstruction)
    353 {
    354     VirtualRegister arguments = VirtualRegister(currentInstruction[1].u.operand);
    355     int lexicalEnvironment = currentInstruction[2].u.operand;
    356 
    357     Jump argsNotCreated = branch32(Equal, tagFor(arguments.offset()), TrustedImm32(JSValue::EmptyValueTag));
    358     emitLoadPayload(arguments.offset(), regT0);
    359     emitLoadPayload(lexicalEnvironment, regT1);
    360     callOperation(operationTearOffArguments, regT0, regT1);
    361     argsNotCreated.link(this);
    362 }
    363 
    364352void JIT::emit_op_to_primitive(Instruction* currentInstruction)
    365353{
     
    910898
    911899    emitLoadPayload(currentInstruction[2].u.operand, regT0);
    912     callOperation(operationCreateActivation, regT0, 0);
     900    callOperation(operationCreateActivation, regT0);
    913901    emitStoreCell(lexicalEnvironment, returnValueGPR);
    914902    emitStoreCell(scope, returnValueGPR);
     
    921909    loadPtr(Address(regT0, JSFunction::offsetOfScopeChain()), regT0);
    922910    emitStoreCell(dst, regT0);
    923 }
    924 
    925 void JIT::emit_op_create_arguments(Instruction* currentInstruction)
    926 {
    927     int dst = currentInstruction[1].u.operand;
    928     int lexicalEnvironment = currentInstruction[2].u.operand;
    929 
    930     Jump argsCreated = branch32(NotEqual, tagFor(dst), TrustedImm32(JSValue::EmptyValueTag));
    931 
    932     if (VirtualRegister(lexicalEnvironment).isValid()) {
    933         emitLoadPayload(lexicalEnvironment, regT0);
    934         callOperation(operationCreateArguments, regT0);
    935     } else
    936         callOperation(operationCreateArguments, TrustedImmPtr(nullptr));
    937     emitStoreCell(dst, returnValueGPR);
    938     emitStoreCell(unmodifiedArgumentsRegister(VirtualRegister(dst)).offset(), returnValueGPR);
    939 
    940     argsCreated.link(this);
    941 }
    942 
    943 void JIT::emit_op_init_lazy_reg(Instruction* currentInstruction)
    944 {
    945     int dst = currentInstruction[1].u.operand;
    946 
    947     emitStore(dst, JSValue());
    948911}
    949912
     
    1027990    callOperation(operationProfileDidCall, regT1, regT0);
    1028991    profilerDone.link(this);
    1029 }
    1030 
    1031 void JIT::emit_op_get_arguments_length(Instruction* currentInstruction)
    1032 {
    1033     int dst = currentInstruction[1].u.operand;
    1034     int argumentsRegister = currentInstruction[2].u.operand;
    1035     addSlowCase(branch32(NotEqual, tagFor(argumentsRegister), TrustedImm32(JSValue::EmptyValueTag)));
    1036     load32(payloadFor(JSStack::ArgumentCount), regT0);
    1037     sub32(TrustedImm32(1), regT0);
    1038     emitStoreInt32(dst, regT0);
    1039 }
    1040 
    1041 void JIT::emitSlow_op_get_arguments_length(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    1042 {
    1043     linkSlowCase(iter);
    1044     int dst = currentInstruction[1].u.operand;
    1045     int base = currentInstruction[2].u.operand;
    1046     callOperation(operationGetArgumentsLength, dst, base);
    1047 }
    1048 
    1049 void JIT::emit_op_get_argument_by_val(Instruction* currentInstruction)
    1050 {
    1051     int dst = currentInstruction[1].u.operand;
    1052     int argumentsRegister = currentInstruction[2].u.operand;
    1053     int property = currentInstruction[3].u.operand;
    1054     addSlowCase(branch32(NotEqual, tagFor(argumentsRegister), TrustedImm32(JSValue::EmptyValueTag)));
    1055     emitLoad(property, regT1, regT2);
    1056     addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
    1057     // regT2 now contains the integer index of the argument we want, including this
    1058     load32(payloadFor(JSStack::ArgumentCount), regT3);
    1059     sub32(TrustedImm32(1), regT3);
    1060     addSlowCase(branch32(AboveOrEqual, regT2, regT3));
    1061    
    1062     loadPtr(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) + CallFrame::argumentOffset(0) * static_cast<int>(sizeof(Register))), regT0);
    1063     loadPtr(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) + CallFrame::argumentOffset(0) * static_cast<int>(sizeof(Register))), regT1);
    1064     emitValueProfilingSite();
    1065     emitStore(dst, regT1, regT0);
    1066 }
    1067 
    1068 void JIT::emitSlow_op_get_argument_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    1069 {
    1070     int dst = currentInstruction[1].u.operand;
    1071     int arguments = currentInstruction[2].u.operand;
    1072     int property = currentInstruction[3].u.operand;
    1073     int lexicalEnvironment = currentInstruction[4].u.operand;
    1074 
    1075     linkSlowCase(iter);
    1076     Jump skipArgumentsCreation = jump();
    1077 
    1078     linkSlowCase(iter);
    1079     linkSlowCase(iter);
    1080 
    1081     if (VirtualRegister(lexicalEnvironment).isValid()) {
    1082         emitLoadPayload(lexicalEnvironment, regT0);
    1083         callOperation(operationCreateArguments, regT0);
    1084     } else
    1085         callOperation(operationCreateArguments, TrustedImmPtr(nullptr));
    1086     emitStoreCell(arguments, returnValueGPR);
    1087     emitStoreCell(unmodifiedArgumentsRegister(VirtualRegister(arguments)).offset(), returnValueGPR);
    1088    
    1089     skipArgumentsCreation.link(this);
    1090     emitLoad(arguments, regT1, regT0);
    1091     emitLoad(property, regT3, regT2);
    1092     callOperation(WithProfile, operationGetByValGeneric, dst, regT1, regT0, regT3, regT2);
    1093992}
    1094993
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r181891 r181993  
    2929#if ENABLE(JIT)
    3030
    31 #include "Arguments.h"
    3231#include "ArrayConstructor.h"
    3332#include "DFGCompilationMode.h"
     
    4847#include "JSFunctionNameScope.h"
    4948#include "JSGlobalObjectFunctions.h"
     49#include "JSLexicalEnvironment.h"
    5050#include "JSNameScope.h"
    5151#include "JSPropertyNameEnumerator.h"
     
    531531            // Attempt to optimize.
    532532            JITArrayMode arrayMode = jitArrayModeForStructure(object->structure(vm));
    533             if (arrayMode != byValInfo.arrayMode) {
     533            if (jitArrayModePermitsPut(arrayMode) && arrayMode != byValInfo.arrayMode) {
    534534                JIT::compilePutByVal(&vm, exec->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
    535535                didOptimize = true;
     
    576576            // Attempt to optimize.
    577577            JITArrayMode arrayMode = jitArrayModeForStructure(object->structure(vm));
    578             if (arrayMode != byValInfo.arrayMode) {
     578            if (jitArrayModePermitsPut(arrayMode) && arrayMode != byValInfo.arrayMode) {
    579579                JIT::compileDirectPutByVal(&vm, callFrame->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
    580580                didOptimize = true;
     
    733733    else
    734734        linkFor(execCallee, *callLinkInfo, codeBlock, callee, codePtr, kind, registers);
     735   
    735736    return reinterpret_cast<char*>(codePtr.executableAddress());
    736737}
     
    13541355}
    13551356
    1356 JSCell* JIT_OPERATION operationCreateActivation(ExecState* exec, JSScope* currentScope, int32_t offset)
    1357 {
    1358     VM& vm = exec->vm();
    1359     NativeCallFrameTracer tracer(&vm, exec);
    1360     JSLexicalEnvironment* lexicalEnvironment = JSLexicalEnvironment::create(vm, exec, exec->registers() + offset, currentScope, exec->codeBlock());
     1357JSCell* JIT_OPERATION operationCreateActivation(ExecState* exec, JSScope* currentScope)
     1358{
     1359    VM& vm = exec->vm();
     1360    NativeCallFrameTracer tracer(&vm, exec);
     1361    JSLexicalEnvironment* lexicalEnvironment = JSLexicalEnvironment::create(vm, exec, currentScope, exec->codeBlock());
    13611362    return lexicalEnvironment;
    1362 }
    1363 
    1364 // FIXME: This is a temporary thunk for the DFG until we add the lexicalEnvironment operand to the DFG CreateArguments node.
    1365 JSCell* JIT_OPERATION operationCreateArgumentsForDFG(ExecState* exec)
    1366 {
    1367     JSLexicalEnvironment* lexicalEnvironment = exec->lexicalEnvironmentOrNullptr();
    1368     return operationCreateArguments(exec, lexicalEnvironment);
    1369 }
    1370    
    1371 JSCell* JIT_OPERATION operationCreateArguments(ExecState* exec, JSLexicalEnvironment* lexicalEnvironment)
    1372 {
    1373     VM& vm = exec->vm();
    1374     NativeCallFrameTracer tracer(&vm, exec);
    1375     // NB: This needs to be exceedingly careful with top call frame tracking, since it
    1376     // may be called from OSR exit, while the state of the call stack is bizarre.
    1377     Arguments* result = Arguments::create(vm, exec, lexicalEnvironment);
    1378     ASSERT(!vm.exception());
    1379     return result;
    1380 }
    1381 
    1382 JSCell* JIT_OPERATION operationCreateArgumentsDuringOSRExit(ExecState* exec)
    1383 {
    1384     DeferGCForAWhile(exec->vm().heap);
    1385     JSLexicalEnvironment* lexicalEnvironment = exec->lexicalEnvironmentOrNullptr();
    1386     return operationCreateArguments(exec, lexicalEnvironment);
    1387 }
    1388 
    1389 EncodedJSValue JIT_OPERATION operationGetArgumentsLength(ExecState* exec, int32_t argumentsRegister)
    1390 {
    1391     VM& vm = exec->vm();
    1392     NativeCallFrameTracer tracer(&vm, exec);
    1393     // Here we can assume that the argumernts were created. Because otherwise the JIT code would
    1394     // have not made this call.
    1395     Identifier ident(&vm, "length");
    1396     JSValue baseValue = exec->uncheckedR(argumentsRegister).jsValue();
    1397     PropertySlot slot(baseValue);
    1398     return JSValue::encode(baseValue.get(exec, ident, slot));
    13991363}
    14001364
     
    15661530}
    15671531
    1568 void JIT_OPERATION operationTearOffArguments(ExecState* exec, JSCell* argumentsCell, JSCell*)
    1569 {
    1570     ASSERT(exec->codeBlock()->usesArguments());
    1571     jsCast<Arguments*>(argumentsCell)->tearOff(exec);
    1572 }
    1573 
    15741532EncodedJSValue JIT_OPERATION operationDeleteById(ExecState* exec, EncodedJSValue encodedBase, const Identifier* identifier)
    15751533{
     
    17351693    if (modeAndType.type() == LocalClosureVar) {
    17361694        JSLexicalEnvironment* environment = jsCast<JSLexicalEnvironment*>(scope);
    1737         environment->registerAt(pc[6].u.operand).set(vm, environment, value);
     1695        environment->variableAt(ScopeOffset(pc[6].u.operand)).set(vm, environment, value);
    17381696        if (VariableWatchpointSet* set = pc[5].u.watchpointSet)
    17391697            set->notifyWrite(vm, value, "Executed op_put_scope<LocalClosureVar>");
     
    17961754
    17971755    JSValue value = exec->r(pc[2].u.operand).jsValue();
    1798     pc[1].u.registerPointer->set(*vm, exec->codeBlock()->globalObject(), value);
     1756    pc[1].u.variablePointer->set(*vm, exec->codeBlock()->globalObject(), value);
    17991757}
    18001758
  • trunk/Source/JavaScriptCore/jit/JITOperations.h

    r181891 r181993  
    6666    F: CallFrame*
    6767    I: StringImpl*
    68     Icf: InlineCalLFrame*
     68    Icf: InlineCallFrame*
    6969    Idc: const Identifier*
    7070    J: EncodedJSValue
    7171    Jcp: const JSValue*
    7272    Jsc: JSScope*
     73    Jsf: JSFunction*
    7374    Jss: JSString*
    7475    L: JSLexicalEnvironment*
     
    130131typedef JSCell* JIT_OPERATION (*C_JITOperation_EIcf)(ExecState*, InlineCallFrame*);
    131132typedef JSCell* JIT_OPERATION (*C_JITOperation_EJ)(ExecState*, EncodedJSValue);
     133typedef JSCell* JIT_OPERATION (*C_JITOperation_EJsc)(ExecState*, JSScope*);
    132134typedef JSCell* JIT_OPERATION (*C_JITOperation_EJscC)(ExecState*, JSScope*, JSCell*);
    133135typedef JSCell* JIT_OPERATION (*C_JITOperation_EJZ)(ExecState*, EncodedJSValue, int32_t);
     
    142144typedef JSCell* JIT_OPERATION (*C_JITOperation_EOZ)(ExecState*, JSObject*, int32_t);
    143145typedef JSCell* JIT_OPERATION (*C_JITOperation_ESt)(ExecState*, Structure*);
     146typedef JSCell* JIT_OPERATION (*C_JITOperation_EStJscSymtab)(ExecState*, Structure*, JSScope*, SymbolTable*);
     147typedef JSCell* JIT_OPERATION (*C_JITOperation_EStRZJsfL)(ExecState*, Structure*, Register*, int32_t, JSFunction*, JSLexicalEnvironment*);
     148typedef JSCell* JIT_OPERATION (*C_JITOperation_EStRZJsf)(ExecState*, Structure*, Register*, int32_t, JSFunction*);
     149typedef JSCell* JIT_OPERATION (*C_JITOperation_EStZ)(ExecState*, Structure*, int32_t);
     150typedef JSCell* JIT_OPERATION (*C_JITOperation_EStZZ)(ExecState*, Structure*, int32_t, int32_t);
    144151typedef JSCell* JIT_OPERATION (*C_JITOperation_EZ)(ExecState*, int32_t);
    145152typedef double JIT_OPERATION (*D_JITOperation_D)(double);
     
    294301void JIT_OPERATION operationProfileWillCall(ExecState*, EncodedJSValue) WTF_INTERNAL;
    295302EncodedJSValue JIT_OPERATION operationCheckHasInstance(ExecState*, EncodedJSValue, EncodedJSValue baseVal) WTF_INTERNAL;
    296 JSCell* JIT_OPERATION operationCreateActivation(ExecState*, JSScope* currentScope, int32_t offset) WTF_INTERNAL;
    297 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.
    298 JSCell* JIT_OPERATION operationCreateArguments(ExecState*, JSLexicalEnvironment*) WTF_INTERNAL;
    299 JSCell* JIT_OPERATION operationCreateArgumentsDuringOSRExit(ExecState*) WTF_INTERNAL;
    300 EncodedJSValue JIT_OPERATION operationGetArgumentsLength(ExecState*, int32_t) WTF_INTERNAL;
     303JSCell* JIT_OPERATION operationCreateActivation(ExecState*, JSScope* currentScope) WTF_INTERNAL;
    301304EncodedJSValue JIT_OPERATION operationGetByValDefault(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
    302305EncodedJSValue JIT_OPERATION operationGetByValGeneric(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
     
    304307EncodedJSValue JIT_OPERATION operationHasIndexedPropertyDefault(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
    305308EncodedJSValue JIT_OPERATION operationHasIndexedPropertyGeneric(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
    306 void JIT_OPERATION operationTearOffArguments(ExecState*, JSCell*, JSCell*) WTF_INTERNAL;
    307309EncodedJSValue JIT_OPERATION operationDeleteById(ExecState*, EncodedJSValue base, const Identifier*) WTF_INTERNAL;
    308310JSCell* JIT_OPERATION operationGetPNames(ExecState*, JSObject*) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp

    r181831 r181993  
    11/*
    2  * Copyright (C) 2008, 2009, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3030
    3131#include "CodeBlock.h"
     32#include "DirectArguments.h"
    3233#include "GCAwareJITStubRoutine.h"
    3334#include "GetterSetter.h"
     
    4142#include "ResultType.h"
    4243#include "SamplingTool.h"
     44#include "ScopedArguments.h"
     45#include "ScopedArgumentsTable.h"
    4346#include <wtf/StringPrintStream.h>
    4447
     
    665668{
    666669    emitGetVirtualRegister(scope, regT0);
    667     loadPtr(Address(regT0, JSEnvironmentRecord::offsetOfRegisters()), regT0);
    668     loadPtr(Address(regT0, operand * sizeof(Register)), regT0);
     670    loadPtr(Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register)), regT0);
    669671}
    670672
     
    749751    emitGetVirtualRegister(value, regT1);
    750752    emitGetVirtualRegister(scope, regT0);
    751     loadPtr(Address(regT0, JSEnvironmentRecord::offsetOfRegisters()), regT0);
    752753    emitNotifyWrite(regT1, regT2, set);
    753     storePtr(regT1, Address(regT0, operand * sizeof(Register)));
     754    storePtr(regT1, Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register)));
    754755}
    755756
     
    806807}
    807808
     809void JIT::emit_op_get_from_arguments(Instruction* currentInstruction)
     810{
     811    int dst = currentInstruction[1].u.operand;
     812    int arguments = currentInstruction[2].u.operand;
     813    int index = currentInstruction[3].u.operand;
     814   
     815    emitGetVirtualRegister(arguments, regT0);
     816    load64(Address(regT0, DirectArguments::storageOffset() + index * sizeof(WriteBarrier<Unknown>)), regT0);
     817    emitValueProfilingSite();
     818    emitPutVirtualRegister(dst);
     819}
     820
     821void JIT::emit_op_put_to_arguments(Instruction* currentInstruction)
     822{
     823    int arguments = currentInstruction[1].u.operand;
     824    int index = currentInstruction[2].u.operand;
     825    int value = currentInstruction[3].u.operand;
     826   
     827    emitWriteBarrier(arguments, value, ShouldFilterValue);
     828   
     829    emitGetVirtualRegister(arguments, regT0);
     830    emitGetVirtualRegister(value, regT1);
     831    store64(regT1, Address(regT0, DirectArguments::storageOffset() + index * sizeof(WriteBarrier<Unknown>)));
     832}
     833
    808834void JIT::emit_op_init_global_const(Instruction* currentInstruction)
    809835{
     
    811837    emitWriteBarrier(globalObject, currentInstruction[2].u.operand, ShouldFilterValue);
    812838    emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
    813     store64(regT0, currentInstruction[1].u.registerPointer);
     839    store64(regT0, currentInstruction[1].u.variablePointer);
    814840}
    815841
     
    951977    case JITArrayStorage:
    952978        slowCases = emitArrayStorageGetByVal(currentInstruction, badType);
     979        break;
     980    case JITDirectArguments:
     981        slowCases = emitDirectArgumentsGetByVal(currentInstruction, badType);
     982        break;
     983    case JITScopedArguments:
     984        slowCases = emitScopedArgumentsGetByVal(currentInstruction, badType);
    953985        break;
    954986    default:
     
    10451077    repatchBuffer.relink(byValInfo->badTypeJump, CodeLocationLabel(byValInfo->stubRoutine->code().code()));
    10461078    repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(isDirect ? operationDirectPutByValGeneric : operationPutByValGeneric));
     1079}
     1080
     1081JIT::JumpList JIT::emitDirectArgumentsGetByVal(Instruction*, PatchableJump& badType)
     1082{
     1083    JumpList slowCases;
     1084   
     1085#if USE(JSVALUE64)
     1086    RegisterID base = regT0;
     1087    RegisterID property = regT1;
     1088    JSValueRegs result = JSValueRegs(regT0);
     1089    RegisterID scratch = regT3;
     1090#else
     1091    RegisterID base = regT0;
     1092    RegisterID property = regT2;
     1093    JSValueRegs result = JSValueRegs(regT1, regT0);
     1094    RegisterID scratch = regT3;
     1095#endif
     1096
     1097    load8(Address(base, JSCell::typeInfoTypeOffset()), scratch);
     1098    badType = patchableBranch32(NotEqual, scratch, TrustedImm32(DirectArgumentsType));
     1099   
     1100    slowCases.append(branch32(AboveOrEqual, property, Address(base, DirectArguments::offsetOfLength())));
     1101    slowCases.append(branchTestPtr(NonZero, Address(base, DirectArguments::offsetOfOverrides())));
     1102   
     1103    zeroExtend32ToPtr(property, scratch);
     1104    loadValue(BaseIndex(base, scratch, TimesEight, DirectArguments::storageOffset()), result);
     1105   
     1106    return slowCases;
     1107}
     1108
     1109JIT::JumpList JIT::emitScopedArgumentsGetByVal(Instruction*, PatchableJump& badType)
     1110{
     1111    JumpList slowCases;
     1112   
     1113#if USE(JSVALUE64)
     1114    RegisterID base = regT0;
     1115    RegisterID property = regT1;
     1116    JSValueRegs result = JSValueRegs(regT0);
     1117    RegisterID scratch = regT3;
     1118    RegisterID scratch2 = regT4;
     1119#else
     1120    RegisterID base = regT0;
     1121    RegisterID property = regT2;
     1122    JSValueRegs result = JSValueRegs(regT1, regT0);
     1123    RegisterID scratch = regT3;
     1124    RegisterID scratch2 = regT4;
     1125#endif
     1126
     1127    load8(Address(base, JSCell::typeInfoTypeOffset()), scratch);
     1128    badType = patchableBranch32(NotEqual, scratch, TrustedImm32(DirectArgumentsType));
     1129    slowCases.append(branch32(AboveOrEqual, property, Address(base, ScopedArguments::offsetOfTotalLength())));
     1130   
     1131    loadPtr(Address(base, ScopedArguments::offsetOfTable()), scratch);
     1132    load32(Address(scratch, ScopedArgumentsTable::offsetOfLength()), scratch2);
     1133    Jump overflowCase = branch32(AboveOrEqual, property, scratch2);
     1134    loadPtr(Address(base, ScopedArguments::offsetOfScope()), scratch2);
     1135    loadPtr(Address(scratch, ScopedArgumentsTable::offsetOfArguments()), scratch);
     1136    load32(BaseIndex(scratch, property, TimesFour), scratch);
     1137    slowCases.append(branch32(Equal, scratch, TrustedImm32(ScopeOffset::invalidOffset)));
     1138    loadValue(BaseIndex(scratch2, scratch, TimesEight, JSEnvironmentRecord::offsetOfVariables()), result);
     1139    Jump done = jump();
     1140    overflowCase.link(this);
     1141    sub32(property, scratch2);
     1142    neg32(scratch2);
     1143    loadValue(BaseIndex(base, scratch2, TimesEight, ScopedArguments::overflowStorageOffset()), result);
     1144    slowCases.append(branchIsEmpty(result));
     1145    done.link(this);
     1146   
     1147    return slowCases;
    10471148}
    10481149
  • trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp

    r181831 r181993  
    11/*
    2  * Copyright (C) 2008, 2009, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3131
    3232#include "CodeBlock.h"
     33#include "DirectArguments.h"
    3334#include "GCAwareJITStubRoutine.h"
    3435#include "Interpreter.h"
     
    689690{
    690691    emitLoad(scope, regT1, regT0);
    691     loadPtr(Address(regT0, JSEnvironmentRecord::offsetOfRegisters()), regT0);
    692     load32(Address(regT0, operand * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), regT1);
    693     load32(Address(regT0, operand * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), regT0);
     692    load32(Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register) + TagOffset), regT1);
     693    load32(Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register) + PayloadOffset), regT0);
    694694}
    695695
     
    781781    emitLoad(scope, regT1, regT0);
    782782    emitNotifyWrite(regT3, regT2, regT4, set);
    783     loadPtr(Address(regT0, JSEnvironmentRecord::offsetOfRegisters()), regT0);
    784     store32(regT3, Address(regT0, operand * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
    785     store32(regT2, Address(regT0, operand * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
     783    store32(regT3, Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register) + TagOffset));
     784    store32(regT2, Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register) + PayloadOffset));
    786785}
    787786
     
    836835}
    837836
     837void JIT::emit_op_get_from_arguments(Instruction* currentInstruction)
     838{
     839    int dst = currentInstruction[1].u.operand;
     840    int arguments = currentInstruction[2].u.operand;
     841    int index = currentInstruction[3].u.operand;
     842   
     843    emitLoadPayload(arguments, regT0);
     844    load32(Address(regT0, DirectArguments::storageOffset() + index * sizeof(WriteBarrier<Unknown>) + TagOffset), regT1);
     845    load32(Address(regT0, DirectArguments::storageOffset() + index * sizeof(WriteBarrier<Unknown>) + PayloadOffset), regT0);
     846    emitValueProfilingSite();
     847    emitStore(dst, regT1, regT0);
     848}
     849
     850void JIT::emit_op_put_to_arguments(Instruction* currentInstruction)
     851{
     852    int arguments = currentInstruction[1].u.operand;
     853    int index = currentInstruction[2].u.operand;
     854    int value = currentInstruction[3].u.operand;
     855   
     856    emitWriteBarrier(arguments, value, ShouldFilterValue);
     857   
     858    emitLoadPayload(arguments, regT0);
     859    emitLoad(value, regT1, regT2);
     860    store32(regT1, Address(regT0, DirectArguments::storageOffset() + index * sizeof(WriteBarrier<Unknown>) + TagOffset));
     861    store32(regT2, Address(regT0, DirectArguments::storageOffset() + index * sizeof(WriteBarrier<Unknown>) + PayloadOffset));
     862}
     863
    838864void JIT::emit_op_init_global_const(Instruction* currentInstruction)
    839865{
    840     WriteBarrier<Unknown>* registerPointer = currentInstruction[1].u.registerPointer;
     866    WriteBarrier<Unknown>* variablePointer = currentInstruction[1].u.variablePointer;
    841867    int value = currentInstruction[2].u.operand;
    842868
     
    847873    emitLoad(value, regT1, regT0);
    848874   
    849     store32(regT1, registerPointer->tagPointer());
    850     store32(regT0, registerPointer->payloadPointer());
     875    store32(regT1, variablePointer->tagPointer());
     876    store32(regT0, variablePointer->payloadPointer());
    851877}
    852878
  • trunk/Source/JavaScriptCore/jit/SetupVarargsFrame.cpp

    r180279 r181993  
    2929#if ENABLE(JIT)
    3030
    31 #include "Arguments.h"
     31#include "Interpreter.h"
    3232#include "JSCInlines.h"
    3333#include "StackAlignment.h"
     
    7070        endVarArgs.link(&jit);
    7171    }
    72     slowCase.append(jit.branch32(CCallHelpers::Above, scratchGPR1, CCallHelpers::TrustedImm32(Arguments::MaxArguments + 1)));
     72    slowCase.append(jit.branch32(CCallHelpers::Above, scratchGPR1, CCallHelpers::TrustedImm32(maxArguments + 1)));
    7373   
    7474    emitSetVarargsFrame(jit, scratchGPR1, true, numUsedSlotsGPR, scratchGPR2);
  • trunk/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp

    r178073 r181993  
    11/*
    2  * Copyright (C) 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3030#include "CommonSlowPaths.h"
    3131#include "Debugger.h"
     32#include "DirectArguments.h"
    3233#include "Executable.h"
    3334#include "Heap.h"
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r181889 r181993  
    2727#include "LLIntSlowPaths.h"
    2828
    29 #include "Arguments.h"
    3029#include "ArrayConstructor.h"
    3130#include "CallFrame.h"
    3231#include "CommonSlowPaths.h"
    3332#include "CommonSlowPathsExceptions.h"
     33#include "Error.h"
    3434#include "ErrorHandlingScope.h"
    3535#include "ExceptionFuzz.h"
     
    255255LLINT_SLOW_PATH_DECL(trace)
    256256{
    257     dataLogF("%p / %p: executing bc#%zu, %s, scope %p, pc = %p\n",
     257    dataLogF("%p / %p: executing bc#%zu, %s, pc = %p\n",
    258258            exec->codeBlock(),
    259259            exec,
    260260            static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
    261             opcodeNames[exec->vm().interpreter->getOpcodeID(pc[0].u.opcode)],
    262             exec->uncheckedR(exec->codeBlock()->scopeRegister().offset()).Register::scope(), pc);
     261            opcodeNames[exec->vm().interpreter->getOpcodeID(pc[0].u.opcode)], pc);
    263262    if (exec->vm().interpreter->getOpcodeID(pc[0].u.opcode) == op_enter) {
    264263        dataLogF("Frame will eventually return to %p\n", exec->returnPC().value());
     
    508507    JSScope* scope = exec->uncheckedR(scopeReg).Register::scope();
    509508    JSLexicalEnvironment* lexicalEnvironment = JSLexicalEnvironment::create(vm, exec, scope, exec->codeBlock());
    510     exec->uncheckedR(pc[2].u.operand) = lexicalEnvironment;
    511509    LLINT_RETURN(JSValue(lexicalEnvironment));
    512510}
     
    756754}
    757755
    758 LLINT_SLOW_PATH_DECL(slow_path_get_argument_by_val)
    759 {
    760     LLINT_BEGIN();
    761     JSValue arguments = LLINT_OP(2).jsValue();
    762     if (!arguments) {
    763         int lexicalEnvironmentReg = pc[4].u.operand;
    764         JSLexicalEnvironment* lexicalEnvironment = VirtualRegister(lexicalEnvironmentReg).isValid() ?
    765             exec->uncheckedR(lexicalEnvironmentReg).lexicalEnvironment() : nullptr;
    766         arguments = JSValue(Arguments::create(vm, exec, lexicalEnvironment));
    767 
    768         LLINT_CHECK_EXCEPTION();
    769         LLINT_OP(2) = arguments;
    770         exec->uncheckedR(unmodifiedArgumentsRegister(VirtualRegister(pc[2].u.operand)).offset()) = arguments;
    771     }
    772    
    773     LLINT_RETURN_PROFILED(op_get_argument_by_val, getByVal(exec, arguments, LLINT_OP_C(3).jsValue()));
    774 }
    775 
    776756LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
    777757{
     
    12401220}
    12411221
    1242 LLINT_SLOW_PATH_DECL(slow_path_tear_off_arguments)
    1243 {
    1244     LLINT_BEGIN();
    1245     ASSERT(exec->codeBlock()->usesArguments());
    1246     Arguments* arguments = jsCast<Arguments*>(exec->uncheckedR(VirtualRegister(pc[1].u.operand).offset()).jsValue());
    1247     arguments->tearOff(exec);
    1248     LLINT_END();
    1249 }
    1250 
    12511222LLINT_SLOW_PATH_DECL(slow_path_strcat)
    12521223{
     
    14081379    if (modeAndType.type() == LocalClosureVar) {
    14091380        JSLexicalEnvironment* environment = jsCast<JSLexicalEnvironment*>(scope);
    1410         environment->registerAt(pc[6].u.operand).set(vm, environment, value);
     1381        environment->variableAt(ScopeOffset(pc[6].u.operand)).set(vm, environment, value);
    14111382        if (VariableWatchpointSet* set = pc[5].u.watchpointSet)
    14121383            set->notifyWrite(vm, value, "Executed op_put_scope<LocalClosureVar>");
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r181981 r181993  
    4242end
    4343const SlotSize = 8
     44
     45const JSEnvironmentRecord_variables = (sizeof JSEnvironmentRecord + SlotSize - 1) & ~(SlotSize - 1)
     46const DirectArguments_storage = (sizeof DirectArguments + SlotSize - 1) & ~(SlotSize - 1)
    4447
    4548const StackAlignment = 16
     
    924927
    925928
     929_llint_op_create_direct_arguments:
     930    traceExecution()
     931    callSlowPath(_slow_path_create_direct_arguments)
     932    dispatch(2)
     933
     934
     935_llint_op_create_scoped_arguments:
     936    traceExecution()
     937    callSlowPath(_slow_path_create_scoped_arguments)
     938    dispatch(3)
     939
     940
     941_llint_op_create_out_of_band_arguments:
     942    traceExecution()
     943    callSlowPath(_slow_path_create_out_of_band_arguments)
     944    dispatch(2)
     945
     946
     947_llint_op_new_func:
     948    traceExecution()
     949    callSlowPath(_llint_slow_path_new_func)
     950    dispatch(4)
     951
     952
    926953_llint_op_new_array:
    927954    traceExecution()
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm

    r181466 r181993  
    723723_llint_op_create_lexical_environment:
    724724    traceExecution()
    725     loadi 4[PC], t0
    726725    callSlowPath(_llint_slow_path_create_lexical_environment)
    727726    dispatch(3)
     
    736735    storei t0, PayloadOffset[cfr, t1, 8]
    737736    dispatch(2)
    738 
    739 
    740 _llint_op_init_lazy_reg:
    741     traceExecution()
    742     loadi 4[PC], t0
    743     storei EmptyValueTag, TagOffset[cfr, t0, 8]
    744     storei 0, PayloadOffset[cfr, t0, 8]
    745     dispatch(2)
    746 
    747 
    748 _llint_op_create_arguments:
    749     traceExecution()
    750     loadi 4[PC], t0
    751     bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opCreateArgumentsDone
    752     callSlowPath(_slow_path_create_arguments)
    753 .opCreateArgumentsDone:
    754     dispatch(3)
    755737
    756738
     
    14511433
    14521434
    1453 _llint_op_get_arguments_length:
    1454     traceExecution()
    1455     loadi 8[PC], t0
    1456     loadi 4[PC], t1
    1457     bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opGetArgumentsLengthSlow
    1458     loadi ArgumentCount + PayloadOffset[cfr], t2
    1459     subi 1, t2
    1460     storei Int32Tag, TagOffset[cfr, t1, 8]
    1461     storei t2, PayloadOffset[cfr, t1, 8]
    1462     dispatch(4)
    1463 
    1464 .opGetArgumentsLengthSlow:
    1465     callSlowPath(_llint_slow_path_get_arguments_length)
    1466     dispatch(4)
    1467 
    1468 
    14691435macro putById(getPropertyStorage)
    14701436    traceExecution()
     
    16151581    callSlowPath(_llint_slow_path_get_by_val)
    16161582    dispatch(6)
    1617 
    1618 
    1619 _llint_op_get_argument_by_val:
    1620     # FIXME: At some point we should array profile this. Right now it isn't necessary
    1621     # since the DFG will never turn a get_argument_by_val into a GetByVal.
    1622     traceExecution()
    1623     loadi 8[PC], t0
    1624     loadi 12[PC], t1
    1625     bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opGetArgumentByValSlow
    1626     loadConstantOrVariablePayload(t1, Int32Tag, t2, .opGetArgumentByValSlow)
    1627     loadi ArgumentCount + PayloadOffset[cfr], t1
    1628     subi 1, t1
    1629     biaeq t2, t1, .opGetArgumentByValSlow
    1630     loadi 4[PC], t3
    1631     loadi FirstArgumentOffset + TagOffset[cfr, t2, 8], t0
    1632     loadi FirstArgumentOffset + PayloadOffset[cfr, t2, 8], t1
    1633     storei t0, TagOffset[cfr, t3, 8]
    1634     storei t1, PayloadOffset[cfr, t3, 8]
    1635     valueProfile(t0, t1, 24, t2)
    1636     dispatch(7)
    1637 
    1638 .opGetArgumentByValSlow:
    1639     callSlowPath(_llint_slow_path_get_argument_by_val)
    1640     dispatch(7)
    16411583
    16421584
     
    19221864
    19231865
    1924 _llint_op_new_func:
    1925     traceExecution()
    1926     btiz 16[PC], .opNewFuncUnchecked
    1927     loadi 4[PC], t1
    1928     bineq TagOffset[cfr, t1, 8], EmptyValueTag, .opNewFuncDone
    1929 .opNewFuncUnchecked:
    1930     callSlowPath(_llint_slow_path_new_func)
    1931 .opNewFuncDone:
    1932     dispatch(5)
    1933 
    19341866macro arrayProfileForCall()
    19351867    loadi 16[PC], t3
     
    19641896    slowPathForCall(slowPath)
    19651897end
    1966 
    1967 _llint_op_tear_off_arguments:
    1968     traceExecution()
    1969     loadi 4[PC], t0
    1970     bieq TagOffset[cfr, t0, 8], EmptyValueTag, .opTearOffArgumentsNotCreated
    1971     callSlowPath(_llint_slow_path_tear_off_arguments)
    1972 .opTearOffArgumentsNotCreated:
    1973     dispatch(3)
    19741898
    19751899
     
    22142138
    22152139macro getClosureVar()
    2216     loadp JSEnvironmentRecord::m_registers[t0], t0
    22172140    loadisFromInstruction(6, t3)
    2218     loadp TagOffset[t0, t3, 8], t1
    2219     loadp PayloadOffset[t0, t3, 8], t2
     2141    loadp JSEnvironmentRecord_variables + TagOffset[t0, t3, 8], t1
     2142    loadp JSEnvironmentRecord_variables + PayloadOffset[t0, t3, 8], t2
    22202143    valueProfile(t1, t2, 28, t0)
    22212144    loadisFromInstruction(1, t0)
     
    22912214    loadisFromInstruction(3, t1)
    22922215    loadConstantOrVariable(t1, t2, t3)
    2293     loadp JSEnvironmentRecord::m_registers[t0], t0
    22942216    loadisFromInstruction(6, t1)
    2295     storei t2, TagOffset[t0, t1, 8]
    2296     storei t3, PayloadOffset[t0, t1, 8]
     2217    storei t2, JSEnvironmentRecord_variables + TagOffset[t0, t1, 8]
     2218    storei t3, JSEnvironmentRecord_variables + PayloadOffset[t0, t1, 8]
    22972219end
    22982220
     
    23042226    notifyWrite(t4, t2, t3, t1, .pDynamic)
    23052227.noVariableWatchpointSet:
    2306     loadp JSEnvironmentRecord::m_registers[t0], t0
    23072228    loadisFromInstruction(6, t1)
    2308     storei t2, TagOffset[t0, t1, 8]
    2309     storei t3, PayloadOffset[t0, t1, 8]
     2229    storei t2, JSEnvironmentRecord_variables + TagOffset[t0, t1, 8]
     2230    storei t3, JSEnvironmentRecord_variables + PayloadOffset[t0, t1, 8]
    23102231end
    23112232
     
    23682289    callSlowPath(_llint_slow_path_put_to_scope)
    23692290    dispatch(7)
     2291
     2292
     2293_llint_op_get_from_arguments:
     2294    traceExecution()
     2295    loadisFromInstruction(2, t0)
     2296    loadi PayloadOffset[cfr, t0, 8], t0
     2297    loadi 12[PC], t1
     2298    loadi DirectArguments_storage + TagOffset[t0, t1, 8], t2
     2299    loadi DirectArguments_storage + PayloadOffset[t0, t1, 8], t3
     2300    loadisFromInstruction(1, t1)
     2301    valueProfile(t2, t3, 16, t0)
     2302    storei t2, TagOffset[cfr, t1, 8]
     2303    storei t3, PayloadOffset[cfr, t1, 8]
     2304    dispatch(5)
     2305
     2306
     2307_llint_op_put_to_arguments:
     2308    traceExecution()
     2309    writeBarrierOnOperands(1, 3)
     2310    loadisFromInstruction(1, t0)
     2311    loadi PayloadOffset[cfr, t0, 8], t0
     2312    loadisFromInstruction(3, t1)
     2313    loadConstantOrVariable(t1, t2, t3)
     2314    loadi 8[PC], t1
     2315    storei t2, DirectArguments_storage + TagOffset[t0, t1, 8]
     2316    storei t3, DirectArguments_storage + PayloadOffset[t0, t1, 8]
     2317    dispatch(4)
     2318
    23702319
    23712320_llint_op_profile_type:
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

    r181466 r181993  
    610610_llint_op_create_lexical_environment:
    611611    traceExecution()
    612     loadisFromInstruction(1, t0)
    613612    callSlowPath(_llint_slow_path_create_lexical_environment)
    614613    dispatch(3)
     
    622621    storeq t0, [cfr, t1, 8]
    623622    dispatch(2)
    624 
    625 
    626 _llint_op_init_lazy_reg:
    627     traceExecution()
    628     loadisFromInstruction(1, t0)
    629     storeq ValueEmpty, [cfr, t0, 8]
    630     dispatch(2)
    631 
    632 
    633 _llint_op_create_arguments:
    634     traceExecution()
    635     loadisFromInstruction(1, t0)
    636     bqneq [cfr, t0, 8], ValueEmpty, .opCreateArgumentsDone
    637     callSlowPath(_slow_path_create_arguments)
    638 .opCreateArgumentsDone:
    639     dispatch(3)
    640623
    641624
     
    13151298
    13161299
    1317 _llint_op_get_arguments_length:
    1318     traceExecution()
    1319     loadisFromInstruction(2, t0)
    1320     loadisFromInstruction(1, t1)
    1321     btqnz [cfr, t0, 8], .opGetArgumentsLengthSlow
    1322     loadi ArgumentCount + PayloadOffset[cfr], t2
    1323     subi 1, t2
    1324     orq tagTypeNumber, t2
    1325     storeq t2, [cfr, t1, 8]
    1326     dispatch(4)
    1327 
    1328 .opGetArgumentsLengthSlow:
    1329     callSlowPath(_llint_slow_path_get_arguments_length)
    1330     dispatch(4)
    1331 
    1332 
    13331300macro putById(getPropertyStorage)
    13341301    traceExecution()
     
    14751442    callSlowPath(_llint_slow_path_get_by_val)
    14761443    dispatch(6)
    1477 
    1478 
    1479 _llint_op_get_argument_by_val:
    1480     # FIXME: At some point we should array profile this. Right now it isn't necessary
    1481     # since the DFG will never turn a get_argument_by_val into a GetByVal.
    1482     traceExecution()
    1483     loadisFromInstruction(2, t0)
    1484     loadisFromInstruction(3, t1)
    1485     btqnz [cfr, t0, 8], .opGetArgumentByValSlow
    1486     loadConstantOrVariableInt32(t1, t2, .opGetArgumentByValSlow)
    1487     loadi ArgumentCount + PayloadOffset[cfr], t1
    1488     sxi2q t2, t2
    1489     subi 1, t1
    1490     biaeq t2, t1, .opGetArgumentByValSlow
    1491     loadisFromInstruction(1, t3)
    1492     loadpFromInstruction(6, t1)
    1493     loadq FirstArgumentOffset[cfr, t2, 8], t0
    1494     storeq t0, [cfr, t3, 8]
    1495     valueProfile(t0, 6, t1)
    1496     dispatch(7)
    1497 
    1498 .opGetArgumentByValSlow:
    1499     callSlowPath(_llint_slow_path_get_argument_by_val)
    1500     dispatch(7)
    15011444
    15021445
     
    17821725
    17831726
    1784 _llint_op_new_func:
    1785     traceExecution()
    1786     loadisFromInstruction(4, t2)
    1787     btiz t2, .opNewFuncUnchecked
    1788     loadisFromInstruction(1, t1)
    1789     btqnz [cfr, t1, 8], .opNewFuncDone
    1790 .opNewFuncUnchecked:
    1791     callSlowPath(_llint_slow_path_new_func)
    1792 .opNewFuncDone:
    1793     dispatch(5)
    1794 
    17951727macro arrayProfileForCall()
    17961728    loadisFromInstruction(4, t3)
     
    18241756    slowPathForCall(slowPath)
    18251757end
    1826 
    1827 _llint_op_tear_off_arguments:
    1828     traceExecution()
    1829     loadisFromInstruction(1, t0)
    1830     btqz [cfr, t0, 8], .opTearOffArgumentsNotCreated
    1831     callSlowPath(_llint_slow_path_tear_off_arguments)
    1832 .opTearOffArgumentsNotCreated:
    1833     dispatch(3)
    18341758
    18351759
     
    20812005
    20822006macro getClosureVar()
    2083     loadp JSEnvironmentRecord::m_registers[t0], t0
    20842007    loadisFromInstruction(6, t1)
    2085     loadq [t0, t1, 8], t0
     2008    loadq JSEnvironmentRecord_variables[t0, t1, 8], t0
    20862009    valueProfile(t0, 7, t1)
    20872010    loadisFromInstruction(1, t1)
     
    21552078    loadisFromInstruction(3, t1)
    21562079    loadConstantOrVariable(t1, t2)
    2157     loadp JSEnvironmentRecord::m_registers[t0], t0
    21582080    loadisFromInstruction(6, t1)
    2159     storeq t2, [t0, t1, 8]
     2081    storeq t2, JSEnvironmentRecord_variables[t0, t1, 8]
    21602082end
    21612083
     
    21672089    notifyWrite(t3, t2, t1, .pDynamic)
    21682090.noVariableWatchpointSet:
    2169     loadp JSEnvironmentRecord::m_registers[t0], t0
    21702091    loadisFromInstruction(6, t1)
    2171     storeq t2, [t0, t1, 8]
     2092    storeq t2, JSEnvironmentRecord_variables[t0, t1, 8]
    21722093end
    21732094
     
    22302151    callSlowPath(_llint_slow_path_put_to_scope)
    22312152    dispatch(7)
     2153
     2154
     2155_llint_op_get_from_arguments:
     2156    traceExecution()
     2157    loadVariable(2, t0)
     2158    loadi 24[PB, PC, 8], t1
     2159    loadq DirectArguments_storage[t0, t1, 8], t0
     2160    valueProfile(t0, 4, t1)
     2161    loadisFromInstruction(1, t1)
     2162    storeq t0, [cfr, t1, 8]
     2163    dispatch(5)
     2164
     2165
     2166_llint_op_put_to_arguments:
     2167    traceExecution()
     2168    writeBarrierOnOperands(1, 3)
     2169    loadVariable(1, t0)
     2170    loadi 16[PB, PC, 8], t1
     2171    loadisFromInstruction(3, t3)
     2172    loadConstantOrVariable(t3, t2)
     2173    storeq t2, DirectArguments_storage[t0, t1, 8]
     2174    dispatch(4)
     2175
    22322176
    22332177_llint_op_profile_type:
  • trunk/Source/JavaScriptCore/parser/Nodes.h

    r181901 r181993  
    22 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
    33 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
    4  *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved.
     4 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013, 2015 Apple Inc. All rights reserved.
    55 *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
    66 *  Copyright (C) 2007 Maks Orlovich
     
    14711471        size_t capturedVariableCount() const { return m_capturedVariables.size(); }
    14721472        const IdentifierSet& capturedVariables() const { return m_capturedVariables; }
    1473         bool captures(const Identifier& ident) { return m_capturedVariables.contains(ident.impl()); }
     1473        bool captures(StringImpl* uid) { return m_capturedVariables.contains(uid); }
     1474        bool captures(const Identifier& ident) { return captures(ident.impl()); }
    14741475
    14751476        VarStack& varStack() { return m_varStack; }
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp

    r181891 r181993  
    11/*
    2  * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626#include "config.h"
    2727#include "CommonSlowPaths.h"
    28 #include "Arguments.h"
    2928#include "ArityCheckFailReturnThunks.h"
    3029#include "ArrayConstructor.h"
    3130#include "CallFrame.h"
     31#include "ClonedArguments.h"
    3232#include "CodeProfiling.h"
    3333#include "CommonSlowPathsExceptions.h"
     34#include "DirectArguments.h"
     35#include "Error.h"
    3436#include "ErrorHandlingScope.h"
    3537#include "ExceptionFuzz.h"
     
    3941#include "JIT.h"
    4042#include "JITStubs.h"
     43#include "JSCInlines.h"
    4144#include "JSCJSValue.h"
    4245#include "JSGlobalObjectFunctions.h"
     
    5053#include "LowLevelInterpreter.h"
    5154#include "ObjectConstructor.h"
    52 #include "JSCInlines.h"
     55#include "ScopedArguments.h"
    5356#include "StructureRareDataInlines.h"
    5457#include "TypeProfilerLog.h"
     
    211214}
    212215
    213 SLOW_PATH_DECL(slow_path_create_arguments)
    214 {
    215     BEGIN();
    216     int lexicalEnvironmentReg = pc[2].u.operand;
    217     JSLexicalEnvironment* lexicalEnvironment = VirtualRegister(lexicalEnvironmentReg).isValid() ?
    218         exec->uncheckedR(lexicalEnvironmentReg).lexicalEnvironment() : nullptr;
    219     JSValue arguments = JSValue(Arguments::create(vm, exec, lexicalEnvironment));
    220     CHECK_EXCEPTION();
    221     exec->uncheckedR(pc[1].u.operand) = arguments;
    222     exec->uncheckedR(unmodifiedArgumentsRegister(VirtualRegister(pc[1].u.operand)).offset()) = arguments;
    223     END();
     216SLOW_PATH_DECL(slow_path_create_direct_arguments)
     217{
     218    BEGIN();
     219    RETURN(DirectArguments::createByCopying(exec));
     220}
     221
     222SLOW_PATH_DECL(slow_path_create_scoped_arguments)
     223{
     224    BEGIN();
     225    JSLexicalEnvironment* scope = jsCast<JSLexicalEnvironment*>(OP(2).jsValue());
     226    ScopedArgumentsTable* table = exec->codeBlock()->symbolTable()->arguments();
     227    RETURN(ScopedArguments::createByCopying(exec, table, scope));
     228}
     229
     230SLOW_PATH_DECL(slow_path_create_out_of_band_arguments)
     231{
     232    BEGIN();
     233    RETURN(ClonedArguments::createWithMachineFrame(exec, exec, ArgumentsMode::Cloned));
    224234}
    225235
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h

    r181891 r181993  
    11/*
    2  * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011-2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    183183SLOW_PATH_HIDDEN_DECL(slow_path_construct_arityCheck);
    184184SLOW_PATH_HIDDEN_DECL(slow_path_touch_entry);
    185 SLOW_PATH_HIDDEN_DECL(slow_path_create_arguments);
     185SLOW_PATH_HIDDEN_DECL(slow_path_create_direct_arguments);
     186SLOW_PATH_HIDDEN_DECL(slow_path_create_scoped_arguments);
     187SLOW_PATH_HIDDEN_DECL(slow_path_create_out_of_band_arguments);
    186188SLOW_PATH_HIDDEN_DECL(slow_path_create_this);
    187189SLOW_PATH_HIDDEN_DECL(slow_path_enter);
  • trunk/Source/JavaScriptCore/runtime/ConstantMode.h

    r160109 r181993  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2727#define ConstantMode_h
    2828
     29#include <wtf/PrintStream.h>
     30
    2931namespace JSC {
    3032
    3133enum ConstantMode { IsConstant, IsVariable };
    3234
     35inline ConstantMode modeForIsConstant(bool isConstant)
     36{
     37    return isConstant ? IsConstant : IsVariable;
     38}
     39
    3340} // namespace JSC
     41
     42namespace WTF {
     43
     44void printInternal(PrintStream&, JSC::ConstantMode);
     45
     46} // namespace WTF
    3447
    3548#endif // ConstantMode_h
  • trunk/Source/JavaScriptCore/runtime/FunctionPrototype.cpp

    r181901 r181993  
    11/*
    22 *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2015 Apple Inc. All rights reserved.
    44 *
    55 *  This library is free software; you can redistribute it and/or
     
    2222#include "FunctionPrototype.h"
    2323
    24 #include "Arguments.h"
    2524#include "BuiltinExecutables.h"
    2625#include "BuiltinNames.h"
     26#include "Error.h"
    2727#include "JSArray.h"
    2828#include "JSBoundFunction.h"
  • trunk/Source/JavaScriptCore/runtime/JSArgumentsIterator.cpp

    r181203 r181993  
    11/*
    2  * Copyright (C) 2013 Apple, Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple, Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2727#include "JSArgumentsIterator.h"
    2828
    29 #include "Arguments.h"
     29#include "ClonedArguments.h"
     30#include "DirectArguments.h"
    3031#include "JSCInlines.h"
     32#include "ScopedArguments.h"
    3133
    3234namespace JSC {
     
    3436const ClassInfo JSArgumentsIterator::s_info = { "ArgumentsIterator", &Base::s_info, 0, CREATE_METHOD_TABLE(JSArgumentsIterator) };
    3537
    36 void JSArgumentsIterator::finishCreation(VM& vm, Arguments* arguments)
     38void JSArgumentsIterator::finishCreation(VM& vm, JSObject* arguments)
    3739{
    3840    Base::finishCreation(vm);
     
    4749}
    4850
     51EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState* exec)
     52{
     53    JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
     54    if (!thisObj->inherits(DirectArguments::info()) && !thisObj->inherits(ScopedArguments::info()) && !thisObj->inherits(ClonedArguments::info()))
     55        return JSValue::encode(throwTypeError(exec, ASCIILiteral("Attempted to use Arguments iterator on non-Arguments object")));
     56    return JSValue::encode(JSArgumentsIterator::create(exec->vm(), exec->callee()->globalObject()->argumentsIteratorStructure(), thisObj));
    4957}
     58
     59}
  • trunk/Source/JavaScriptCore/runtime/JSArgumentsIterator.h

    r181203 r181993  
    11/*
    2  * Copyright (C) 2013 Apple, Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple, Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2727#define JSArgumentsIterator_h
    2828
    29 #include "Arguments.h"
     29#include "JSObject.h"
    3030
    3131namespace JSC {
     
    4242    }
    4343
    44     static JSArgumentsIterator* create(VM& vm, Structure* structure, Arguments* arguments)
     44    static JSArgumentsIterator* create(VM& vm, Structure* structure, JSObject* arguments)
    4545    {
    4646        JSArgumentsIterator* instance = new (NotNull, allocateCell<JSArgumentsIterator>(vm.heap)) JSArgumentsIterator(vm, structure);
     
    5151    bool next(CallFrame* callFrame, JSValue& value)
    5252    {
    53         if (m_nextIndex >= m_arguments->length(callFrame))
     53        unsigned length =
     54            m_arguments->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
     55        if (m_nextIndex >= length)
    5456            return false;
    55         value = m_arguments->tryGetArgument(m_nextIndex++);
    56         if (!value)
    57             value = jsUndefined();
     57        value = m_arguments->getIndex(callFrame, m_nextIndex++);
    5858        return true;
    5959    }
     
    7272    }
    7373
    74     void finishCreation(VM&, Arguments*);
     74    void finishCreation(VM&, JSObject*);
    7575   
    76     WriteBarrier<Arguments> m_arguments;
     76    WriteBarrier<JSObject> m_arguments;
    7777    size_t m_nextIndex;
    7878};
     79
     80EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState*);
    7981
    8082}
  • trunk/Source/JavaScriptCore/runtime/JSEnvironmentRecord.cpp

    r173490 r181993  
    11/*
    2  * Copyright (C) 2007, 2008, 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2007, 2008, 2012, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3636const ClassInfo JSEnvironmentRecord::s_info = { "EnvironmentRecord", &Base::s_info, 0, CREATE_METHOD_TABLE(JSEnvironmentRecord) };
    3737
     38void JSEnvironmentRecord::visitChildren(JSCell* cell, SlotVisitor& visitor)
     39{
     40    JSEnvironmentRecord* thisObject = jsCast<JSEnvironmentRecord*>(cell);
     41    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
     42    Base::visitChildren(thisObject, visitor);
     43    visitor.appendValues(thisObject->variables(), thisObject->m_symbolTable->scopeSize());
     44}
     45
    3846} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/JSEnvironmentRecord.h

    r180514 r181993  
    4747    typedef JSSymbolTableObject Base;
    4848
    49     WriteBarrierBase<Unknown>* registers() { return m_registers; }
    50     WriteBarrierBase<Unknown>& registerAt(int index) const { return m_registers[index]; }
     49    WriteBarrierBase<Unknown>* variables()
     50    {
     51        return bitwise_cast<WriteBarrierBase<Unknown>*>(bitwise_cast<char*>(this) + offsetOfVariables());
     52    }
     53   
     54    bool isValid(ScopeOffset offset)
     55    {
     56        return !!offset && offset.offset() < m_symbolTable->scopeSize();
     57    }
     58   
     59    WriteBarrierBase<Unknown>& variableAt(ScopeOffset offset)
     60    {
     61        ASSERT(isValid(offset));
     62        return variables()[offset.offset()];
     63    }
    5164
    52     WriteBarrierBase<Unknown>* const * addressOfRegisters() const { return &m_registers; }
    53     static size_t offsetOfRegisters() { return OBJECT_OFFSETOF(JSEnvironmentRecord, m_registers); }
     65    static size_t offsetOfVariables()
     66    {
     67        return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSEnvironmentRecord));
     68    }
     69   
     70    static ptrdiff_t offsetOfVariable(ScopeOffset offset)
     71    {
     72        return offsetOfVariables() + offset.offset() * sizeof(WriteBarrier<Unknown>);
     73    }
    5474
    5575    DECLARE_INFO;
    5676
     77    static size_t allocationSizeForScopeSize(unsigned scopeSize)
     78    {
     79        return offsetOfVariables() + scopeSize * sizeof(WriteBarrier<Unknown>);
     80    }
     81   
     82    static size_t allocationSize(SymbolTable* symbolTable)
     83    {
     84        return allocationSizeForScopeSize(symbolTable->scopeSize());
     85    }
     86   
    5787protected:
    5888    static const unsigned StructureFlags = Base::StructureFlags;
     
    6191        VM& vm,
    6292        Structure* structure,
    63         Register* registers,
    6493        JSScope* scope,
    6594        SymbolTable* symbolTable)
    6695        : Base(vm, structure, scope, symbolTable)
    67         , m_registers(reinterpret_cast<WriteBarrierBase<Unknown>*>(registers))
    6896    {
    6997    }
     98   
     99    void finishCreationUninitialized(VM& vm)
     100    {
     101        Base::finishCreation(vm);
     102    }
     103   
     104    void finishCreation(VM& vm)
     105    {
     106        finishCreationUninitialized(vm);
     107        for (unsigned i = m_symbolTable->scopeSize(); i--;) {
     108            // Filling this with undefined is useful because that's what variables start out as.
     109            variableAt(ScopeOffset(i)).setUndefined();
     110        }
     111    }
    70112
    71     WriteBarrierBase<Unknown>* m_registers; // "r" in the stack.
     113    static void visitChildren(JSCell*, SlotVisitor&);
    72114};
    73115
  • trunk/Source/JavaScriptCore/runtime/JSFunction.cpp

    r180506 r181993  
    2626#include "JSFunction.h"
    2727
    28 #include "Arguments.h"
     28#include "ClonedArguments.h"
    2929#include "CodeBlock.h"
    3030#include "CommonIdentifiers.h"
     
    3535#include "JSArray.h"
    3636#include "JSBoundFunction.h"
     37#include "JSCInlines.h"
    3738#include "JSFunctionInlines.h"
    3839#include "JSGlobalObject.h"
     
    4142#include "ObjectConstructor.h"
    4243#include "ObjectPrototype.h"
    43 #include "JSCInlines.h"
    4444#include "Parser.h"
    4545#include "PropertyNameArray.h"
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r181664 r181993  
    11/*
    2  * Copyright (C) 2007, 2008, 2009, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2007, 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
    33 * Copyright (C) 2008 Cameron Zwarich (cwzwarich@uwaterloo.ca)
    44 *
     
    3131#include "JSGlobalObject.h"
    3232
    33 #include "Arguments.h"
    3433#include "ArgumentsIteratorConstructor.h"
    3534#include "ArgumentsIteratorPrototype.h"
     
    4039#include "BooleanConstructor.h"
    4140#include "BooleanPrototype.h"
     41#include "ClonedArguments.h"
    4242#include "CodeBlock.h"
    4343#include "CodeCache.h"
     
    4747#include "Debugger.h"
    4848#include "DebuggerScope.h"
     49#include "DirectArguments.h"
    4950#include "Error.h"
    5051#include "ErrorConstructor.h"
     
    111112#include "RegExpObject.h"
    112113#include "RegExpPrototype.h"
     114#include "ScopedArguments.h"
    113115#include "SetConstructor.h"
    114116#include "SetIteratorConstructor.h"
     
    281283   
    282284    m_callbackFunctionStructure.set(vm, this, JSCallbackFunction::createStructure(vm, this, m_functionPrototype.get()));
    283     m_argumentsStructure.set(vm, this, Arguments::createStructure(vm, this, m_objectPrototype.get()));
     285    m_directArgumentsStructure.set(vm, this, DirectArguments::createStructure(vm, this, m_objectPrototype.get()));
     286    m_scopedArgumentsStructure.set(vm, this, ScopedArguments::createStructure(vm, this, m_objectPrototype.get()));
     287    m_outOfBandArgumentsStructure.set(vm, this, ClonedArguments::createStructure(vm, this, m_objectPrototype.get()));
    284288    m_callbackConstructorStructure.set(vm, this, JSCallbackConstructor::createStructure(vm, this, m_objectPrototype.get()));
    285289    m_callbackObjectStructure.set(vm, this, JSCallbackObject<JSDestructibleObject>::createStructure(vm, this, m_objectPrototype.get()));
     
    475479{
    476480    ConcurrentJITLocker locker(symbolTable()->m_lock);
    477     int index = symbolTable()->size(locker);
    478     SymbolTableEntry newEntry(index, (constantMode == IsConstant) ? ReadOnly : 0);
     481    SymbolTableEntry entry = symbolTable()->get(locker, ident.impl());
     482    if (!entry.isNull()) {
     483        NewGlobalVar result;
     484        result.offset = entry.scopeOffset();
     485        result.set = entry.watchpointSet();
     486        return result;
     487    }
     488   
     489    ScopeOffset offset = symbolTable()->takeNextScopeOffset(locker);
     490    SymbolTableEntry newEntry(VarOffset(offset), (constantMode == IsConstant) ? ReadOnly : 0);
    479491    if (constantMode == IsVariable)
    480492        newEntry.prepareToWatch(symbolTable());
    481     SymbolTable::Map::AddResult result = symbolTable()->add(locker, ident.impl(), newEntry);
    482     if (result.isNewEntry)
    483         addRegisters(1);
    484493    else
    485         index = result.iterator->value.getIndex();
     494        newEntry.disableWatching();
     495    symbolTable()->add(locker, ident.impl(), newEntry);
     496   
     497    ScopeOffset offsetForAssert = addVariables(1);
     498    RELEASE_ASSERT(offsetForAssert == offset);
     499
    486500    NewGlobalVar var;
    487     var.registerNumber = index;
    488     var.set = result.iterator->value.watchpointSet();
     501    var.offset = offset;
     502    var.set = newEntry.watchpointSet();
    489503    return var;
    490504}
     
    495509    removeDirect(vm, propertyName); // Newly declared functions overwrite existing properties.
    496510    NewGlobalVar var = addGlobalVar(propertyName, IsVariable);
    497     registerAt(var.registerNumber).set(exec->vm(), this, value);
     511    variableAt(var.offset).set(exec->vm(), this, value);
    498512    if (var.set)
    499513        var.set->notifyWrite(vm, value, VariableWriteFireDetail(this, propertyName));
     
    692706    visitor.append(&thisObject->m_catchScopeStructure);
    693707    visitor.append(&thisObject->m_functionNameScopeStructure);
    694     visitor.append(&thisObject->m_argumentsStructure);
     708    visitor.append(&thisObject->m_directArgumentsStructure);
     709    visitor.append(&thisObject->m_scopedArgumentsStructure);
     710    visitor.append(&thisObject->m_outOfBandArgumentsStructure);
    695711    for (unsigned i = 0; i < NumberOfIndexingShapes; ++i)
    696712        visitor.append(&thisObject->m_originalArrayStructureForIndexingShape[i]);
     
    749765void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count)
    750766{
    751     addRegisters(count);
     767    ScopeOffset startOffset = addVariables(count);
    752768
    753769    for (int i = 0; i < count; ++i) {
     
    755771        ASSERT(global.attributes & DontDelete);
    756772       
    757         int index = symbolTable()->size();
    758         SymbolTableEntry newEntry(index, global.attributes);
    759         symbolTable()->add(global.identifier.impl(), newEntry);
    760         registerAt(index).set(vm(), this, global.value);
     773        ScopeOffset offset;
     774        {
     775            ConcurrentJITLocker locker(symbolTable()->m_lock);
     776            offset = symbolTable()->takeNextScopeOffset(locker);
     777            RELEASE_ASSERT(offset = startOffset + i);
     778            SymbolTableEntry newEntry(VarOffset(offset), global.attributes);
     779            symbolTable()->add(locker, global.identifier.impl(), newEntry);
     780        }
     781        variableAt(offset).set(vm(), this, global.value);
    761782    }
    762783}
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h

    r181084 r181993  
    11/*
    22 *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
    3  *  Copyright (C) 2007, 2008, 2009, 2014 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2007, 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
    44 *
    55 *  This library is free software; you can redistribute it and/or
     
    205205    WriteBarrier<Structure> m_catchScopeStructure;
    206206    WriteBarrier<Structure> m_functionNameScopeStructure;
    207     WriteBarrier<Structure> m_argumentsStructure;
     207    WriteBarrier<Structure> m_directArgumentsStructure;
     208    WriteBarrier<Structure> m_scopedArgumentsStructure;
     209    WriteBarrier<Structure> m_outOfBandArgumentsStructure;
    208210       
    209211    // Lists the actual structures used for having these particular indexing shapes.
     
    330332
    331333    struct NewGlobalVar {
    332         int registerNumber;
     334        ScopeOffset offset;
    333335        VariableWatchpointSet* set;
    334336    };
     
    417419    Structure* catchScopeStructure() const { return m_catchScopeStructure.get(); }
    418420    Structure* functionNameScopeStructure() const { return m_functionNameScopeStructure.get(); }
    419     Structure* argumentsStructure() const { return m_argumentsStructure.get(); }
     421    Structure* directArgumentsStructure() const { return m_directArgumentsStructure.get(); }
     422    Structure* scopedArgumentsStructure() const { return m_scopedArgumentsStructure.get(); }
     423    Structure* outOfBandArgumentsStructure() const { return m_outOfBandArgumentsStructure.get(); }
    420424    Structure* originalArrayStructureForIndexingType(IndexingType indexingType) const
    421425    {
  • trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp

    r180529 r181993  
    11/*
    2  * Copyright (C) 2008, 2009, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3030#include "JSLexicalEnvironment.h"
    3131
    32 #include "Arguments.h"
    3332#include "Interpreter.h"
    3433#include "JSFunction.h"
     
    4140const ClassInfo JSLexicalEnvironment::s_info = { "JSLexicalEnvironment", &Base::s_info, 0, CREATE_METHOD_TABLE(JSLexicalEnvironment) };
    4241
    43 void JSLexicalEnvironment::visitChildren(JSCell* cell, SlotVisitor& visitor)
    44 {
    45     JSLexicalEnvironment* thisObject = jsCast<JSLexicalEnvironment*>(cell);
    46     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    47     Base::visitChildren(thisObject, visitor);
    48 
    49     for (int i = 0; i < thisObject->symbolTable()->captureCount(); ++i)
    50         visitor.append(&thisObject->storage()[i]);
    51 }
    52 
    5342inline bool JSLexicalEnvironment::symbolTableGet(PropertyName propertyName, PropertySlot& slot)
    5443{
     
    5746        return false;
    5847
     48    ScopeOffset offset = entry.scopeOffset();
     49
    5950    // Defend against the inspector asking for a var after it has been optimized out.
    60     if (!isValid(entry))
     51    if (!isValid(offset))
    6152        return false;
    6253
    63     slot.setValue(this, DontEnum, registerAt(entry.getIndex()).get());
     54    slot.setValue(this, DontEnum, variableAt(offset).get());
    6455    return true;
    6556}
     
    7162        return false;
    7263
     64    ScopeOffset offset = entry.scopeOffset();
     65
    7366    // Defend against the inspector asking for a var after it has been optimized out.
    74     if (!isValid(entry))
     67    if (!isValid(offset))
    7568        return false;
    7669
    77     descriptor.setDescriptor(registerAt(entry.getIndex()).get(), entry.getAttributes());
     70    descriptor.setDescriptor(variableAt(offset).get(), entry.getAttributes());
    7871    return true;
    7972}
     
    9689            return true;
    9790        }
     91        ScopeOffset offset = iter->value.scopeOffset();
    9892        // Defend against the inspector asking for a var after it has been optimized out.
    99         if (!isValid(iter->value))
     93        if (!isValid(offset))
    10094            return false;
    10195        if (VariableWatchpointSet* set = iter->value.watchpointSet())
    102             set->invalidate(VariableWriteFireDetail(this, propertyName)); // Don't mess around - if we had found this statically, we would have invcalidated it.
    103         reg = &registerAt(iter->value.getIndex());
     96            set->invalidate(VariableWriteFireDetail(this, propertyName)); // Don't mess around - if we had found this statically, we would have invalidated it.
     97        reg = &variableAt(offset);
    10498    }
    10599    reg->set(vm, this, value);
     
    117111            if (it->value.getAttributes() & DontEnum && !shouldIncludeDontEnumProperties(mode))
    118112                continue;
    119             if (!thisObject->isValid(it->value))
     113            if (!thisObject->isValid(it->value.scopeOffset()))
    120114                continue;
    121115            propertyNames.add(Identifier(exec, it->key.get()));
     
    138132        SymbolTableEntry& entry = iter->value;
    139133        ASSERT(!entry.isNull());
    140         if (!isValid(entry))
     134       
     135        ScopeOffset offset = entry.scopeOffset();
     136        if (!isValid(offset))
    141137            return false;
    142138       
    143139        entry.setAttributes(attributes);
    144         reg = &registerAt(entry.getIndex());
     140        reg = &variableAt(offset);
    145141    }
    146142    reg->set(vm, this, value);
  • trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h

    r180529 r181993  
    11/*
    2  * Copyright (C) 2008, 2009, 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2009, 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3333#include "CopiedSpaceInlines.h"
    3434#include "JSEnvironmentRecord.h"
    35 #include "Nodes.h"
    3635#include "SymbolTable.h"
    3736
     
    4241class JSLexicalEnvironment : public JSEnvironmentRecord {
    4342private:
    44     JSLexicalEnvironment(VM&, CallFrame*, Register*, JSScope*, CodeBlock*);
     43    JSLexicalEnvironment(VM&, Structure*, JSScope*, SymbolTable*);
    4544   
    4645public:
    4746    typedef JSEnvironmentRecord Base;
    4847
    49     static JSLexicalEnvironment* create(VM& vm, CallFrame* callFrame, Register* registers, JSScope* currentScope, CodeBlock* codeBlock)
     48    static JSLexicalEnvironment* create(
     49        VM& vm, Structure* structure, JSScope* currentScope, SymbolTable* symbolTable)
    5050    {
     51        JSLexicalEnvironment* result =
     52            new (
     53                NotNull,
     54                allocateCell<JSLexicalEnvironment>(vm.heap, allocationSize(symbolTable)))
     55            JSLexicalEnvironment(vm, structure, currentScope, symbolTable);
     56        result->finishCreation(vm);
     57        return result;
     58    }
     59   
     60    static JSLexicalEnvironment* create(VM& vm, CallFrame* callFrame, JSScope* currentScope, CodeBlock* codeBlock)
     61    {
     62        JSGlobalObject* globalObject = callFrame->lexicalGlobalObject();
     63        Structure* structure = globalObject->activationStructure();
    5164        SymbolTable* symbolTable = codeBlock->symbolTable();
    52         ASSERT(codeBlock->codeType() == FunctionCode);
    53         JSLexicalEnvironment* lexicalEnvironment = new (
    54             NotNull,
    55             allocateCell<JSLexicalEnvironment>(
    56                 vm.heap,
    57                 allocationSize(symbolTable)
    58             )
    59         ) JSLexicalEnvironment(vm, callFrame, registers, currentScope, codeBlock);
    60         lexicalEnvironment->finishCreation(vm);
    61         return lexicalEnvironment;
     65        return create(vm, structure, currentScope, symbolTable);
    6266    }
    6367       
    64     static JSLexicalEnvironment* create(VM& vm, CallFrame* callFrame, JSScope* currentScope, CodeBlock* codeBlock)
    65     {
    66         return create(vm, callFrame, callFrame->registers() + codeBlock->framePointerOffsetToGetActivationRegisters(), currentScope, codeBlock);
    67     }
    68 
    69     static void visitChildren(JSCell*, SlotVisitor&);
    70 
    7168    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
    7269    static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
     
    8279    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject) { return Structure::create(vm, globalObject, jsNull(), TypeInfo(ActivationObjectType, StructureFlags), info()); }
    8380
    84     WriteBarrierBase<Unknown>& registerAt(int) const;
    85     bool isValidIndex(int) const;
    86     bool isValid(const SymbolTableEntry&) const;
    87     int registersOffset();
    88     static int registersOffset(SymbolTable*);
    89 
    9081protected:
    9182    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags;
     
    9788    bool symbolTablePut(ExecState*, PropertyName, JSValue, bool shouldThrow);
    9889    bool symbolTablePutWithAttributes(VM&, PropertyName, JSValue, unsigned attributes);
    99 
    100     static size_t allocationSize(SymbolTable*);
    101     static size_t storageOffset();
    102 
    103     WriteBarrier<Unknown>* storage(); // captureCount() number of registers.
    10490};
    10591
    106 inline JSLexicalEnvironment::JSLexicalEnvironment(VM& vm, CallFrame* callFrame, Register* registers, JSScope* currentScope, CodeBlock* codeBlock)
    107     : Base(
    108         vm,
    109         callFrame->lexicalGlobalObject()->activationStructure(),
    110         registers,
    111         currentScope,
    112         codeBlock->symbolTable())
     92inline JSLexicalEnvironment::JSLexicalEnvironment(VM& vm, Structure* structure, JSScope* currentScope, SymbolTable* symbolTable)
     93    : Base(vm, structure, currentScope, symbolTable)
    11394{
    114     SymbolTable* symbolTable = codeBlock->symbolTable();
    115     WriteBarrier<Unknown>* storage = this->storage();
    116     size_t captureCount = symbolTable->captureCount();
    117     for (size_t i = 0; i < captureCount; ++i)
    118         new (NotNull, &storage[i]) WriteBarrier<Unknown>(UndefinedWriteBarrierTag);
    119     m_registers = reinterpret_cast_ptr<WriteBarrierBase<Unknown>*>(
    120         reinterpret_cast<char*>(this) + registersOffset(symbolTable));
    12195}
    122 
    123 JSLexicalEnvironment* asActivation(JSValue);
    12496
    12597inline JSLexicalEnvironment* asActivation(JSValue value)
     
    134106}
    135107
    136 inline int JSLexicalEnvironment::registersOffset(SymbolTable* symbolTable)
    137 {
    138     return storageOffset() + ((symbolTable->captureCount() - symbolTable->captureStart()  - 1) * sizeof(WriteBarrier<Unknown>));
    139 }
    140 
    141 inline size_t JSLexicalEnvironment::storageOffset()
    142 {
    143     return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSLexicalEnvironment));
    144 }
    145 
    146 inline WriteBarrier<Unknown>* JSLexicalEnvironment::storage()
    147 {
    148     return reinterpret_cast_ptr<WriteBarrier<Unknown>*>(
    149         reinterpret_cast<char*>(this) + storageOffset());
    150 }
    151 
    152 inline size_t JSLexicalEnvironment::allocationSize(SymbolTable* symbolTable)
    153 {
    154     size_t objectSizeInBytes = WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSLexicalEnvironment));
    155     size_t storageSizeInBytes = symbolTable->captureCount() * sizeof(WriteBarrier<Unknown>);
    156     return objectSizeInBytes + storageSizeInBytes;
    157 }
    158 
    159 inline bool JSLexicalEnvironment::isValidIndex(int index) const
    160 {
    161     if (index > symbolTable()->captureStart())
    162         return false;
    163     if (index <= symbolTable()->captureEnd())
    164         return false;
    165     return true;
    166 }
    167 
    168 inline bool JSLexicalEnvironment::isValid(const SymbolTableEntry& entry) const
    169 {
    170     return isValidIndex(entry.getIndex());
    171 }
    172 
    173 inline WriteBarrierBase<Unknown>& JSLexicalEnvironment::registerAt(int index) const
    174 {
    175     ASSERT(isValidIndex(index));
    176     return Base::registerAt(index);
    177 }
    178 
    179108} // namespace JSC
    180109
  • trunk/Source/JavaScriptCore/runtime/JSNameScope.cpp

    r180514 r181993  
    4848}
    4949
    50 void JSNameScope::visitChildren(JSCell* cell, SlotVisitor& visitor)
    51 {
    52     JSNameScope* thisObject = jsCast<JSNameScope*>(cell);
    53     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    54     Base::visitChildren(thisObject, visitor);
    55     visitor.append(&thisObject->m_registerStore);
    56 }
    57 
    5850JSValue JSNameScope::toThis(JSCell*, ExecState* exec, ECMAMode ecmaMode)
    5951{
  • trunk/Source/JavaScriptCore/runtime/JSNameScope.h

    r180514 r181993  
    4545    static T* create(VM& vm, JSGlobalObject* globalObject, JSScope* currentScope, SymbolTable* symbolTable, JSValue value)
    4646    {
    47         T* scopeObject = new (NotNull, allocateCell<T>(vm.heap)) T(vm, globalObject, currentScope, symbolTable);
     47        T* scopeObject = new (
     48            NotNull, allocateCell<T>(vm.heap, allocationSizeForScopeSize(1)))
     49            T(vm, globalObject, currentScope, symbolTable);
    4850        scopeObject->finishCreation(vm, value);
    4951        return scopeObject;
     
    5254    static JSNameScope* create(VM&, JSGlobalObject*, JSScope* currentScope, SymbolTable*, JSValue, Type);
    5355
    54     static void visitChildren(JSCell*, SlotVisitor&);
    5556    static JSValue toThis(JSCell*, ExecState*, ECMAMode);
    5657    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     
    5960    DECLARE_INFO;
    6061
    61     JSValue value() const { return m_registerStore.get(); }
     62    JSValue value() { return variableAt(ScopeOffset(0)).get(); }
    6263
    6364protected:
    6465    void finishCreation(VM& vm, JSValue value)
    6566    {
    66         Base::finishCreation(vm);
    67         m_registerStore.set(vm, this, value);
     67        Base::finishCreationUninitialized(vm);
     68        variableAt(ScopeOffset(0)).set(vm, this, value);
    6869    }
    6970
     
    7172
    7273    JSNameScope(VM& vm, Structure* structure, JSScope* next, SymbolTable* symbolTable)
    73         : Base(vm, structure, reinterpret_cast<Register*>(&m_registerStore + 1), next, symbolTable)
     74        : Base(vm, structure, next, symbolTable)
    7475    {
     76        ASSERT(symbolTable->scopeSize() == 1);
    7577    }
    76 
    77 private:
    78     WriteBarrier<Unknown> m_registerStore;
    7978};
    8079
  • trunk/Source/JavaScriptCore/runtime/JSScope.cpp

    r174226 r181993  
    11/*
    2  * Copyright (C) 2012, 2013, 2014 Apple Inc. All Rights Reserved.
     2 * Copyright (C) 2012-2015 Apple Inc. All Rights Reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6363
    6464        if (!entry.isNull()) {
    65             op = ResolveOp(makeType(ClosureVar, needsVarInjectionChecks), depth, 0, lexicalEnvironment, entry.watchpointSet(), entry.getIndex());
     65            op = ResolveOp(makeType(ClosureVar, needsVarInjectionChecks), depth, 0, lexicalEnvironment, entry.watchpointSet(), entry.scopeOffset().offset());
    6666            return true;
    6767        }
     
    8383            op = ResolveOp(
    8484                makeType(GlobalVar, needsVarInjectionChecks), depth, 0, 0, entry.watchpointSet(),
    85                 reinterpret_cast<uintptr_t>(globalObject->registerAt(entry.getIndex()).slot()));
     85                reinterpret_cast<uintptr_t>(globalObject->variableAt(entry.scopeOffset()).slot()));
    8686            return true;
    8787        }
  • trunk/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp

    r171939 r181993  
    11/*
    2  * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012, 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3434namespace JSC {
    3535
    36 int JSSegmentedVariableObject::findRegisterIndex(void* registerAddress)
     36ScopeOffset JSSegmentedVariableObject::findVariableIndex(void* variableAddress)
    3737{
    3838    ConcurrentJITLocker locker(m_lock);
    3939   
    40     for (int i = m_registers.size(); i--;) {
    41         if (&m_registers[i] != registerAddress)
     40    for (unsigned i = m_variables.size(); i--;) {
     41        if (&m_variables[i] != variableAddress)
    4242            continue;
    43         return i;
     43        return ScopeOffset(i);
    4444    }
    4545    CRASH();
    46     return -1;
     46    return ScopeOffset();
    4747}
    4848
    49 int JSSegmentedVariableObject::addRegisters(int numberOfRegistersToAdd)
     49ScopeOffset JSSegmentedVariableObject::addVariables(unsigned numberOfVariablesToAdd)
    5050{
    5151    ConcurrentJITLocker locker(m_lock);
    5252   
    53     ASSERT(numberOfRegistersToAdd >= 0);
     53    size_t oldSize = m_variables.size();
     54    m_variables.grow(oldSize + numberOfVariablesToAdd);
    5455   
    55     size_t oldSize = m_registers.size();
    56     m_registers.grow(oldSize + numberOfRegistersToAdd);
     56    for (size_t i = numberOfVariablesToAdd; i--;)
     57        m_variables[oldSize + i].setWithoutWriteBarrier(jsUndefined());
    5758   
    58     for (size_t i = numberOfRegistersToAdd; i--;)
    59         m_registers[oldSize + i].setWithoutWriteBarrier(jsUndefined());
    60    
    61     return static_cast<int>(oldSize);
     59    return ScopeOffset(oldSize);
    6260}
    6361
     
    6866    JSSymbolTableObject::visitChildren(thisObject, slotVisitor);
    6967   
    70     for (unsigned i = thisObject->m_registers.size(); i--;)
    71         slotVisitor.append(&thisObject->m_registers[i]);
     68    for (unsigned i = thisObject->m_variables.size(); i--;)
     69        slotVisitor.append(&thisObject->m_variables[i]);
    7270}
    7371
  • trunk/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h

    r180514 r181993  
    5858    typedef JSSymbolTableObject Base;
    5959
    60     WriteBarrier<Unknown>& registerAt(int index) { return m_registers[index]; }
     60    WriteBarrier<Unknown>& variableAt(ScopeOffset offset) { return m_variables[offset.offset()]; }
    6161   
    6262    // This is a slow method call, which searches the register bank to find the index
    6363    // given a pointer. It will CRASH() if it does not find the register. Only use this
    6464    // in debug code (like bytecode dumping).
    65     JS_EXPORT_PRIVATE int findRegisterIndex(void*);
     65    JS_EXPORT_PRIVATE ScopeOffset findVariableIndex(void*);
    6666   
    67     WriteBarrier<Unknown>* assertRegisterIsInThisObject(WriteBarrier<Unknown>* registerPointer)
     67    WriteBarrier<Unknown>* assertVariableIsInThisObject(WriteBarrier<Unknown>* variablePointer)
    6868    {
    69 #if !ASSERT_DISABLED
    70         findRegisterIndex(registerPointer);
    71 #endif
    72         return registerPointer;
     69        if (!ASSERT_DISABLED)
     70            findVariableIndex(variablePointer);
     71        return variablePointer;
    7372    }
    7473   
    7574    // Adds numberOfRegistersToAdd registers, initializes them to Undefined, and returns
    7675    // the index of the first one added.
    77     JS_EXPORT_PRIVATE int addRegisters(int numberOfRegistersToAdd);
     76    JS_EXPORT_PRIVATE ScopeOffset addVariables(unsigned numberOfVariablesToAdd);
    7877   
    7978    JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
     
    9190    }
    9291   
    93     SegmentedVector<WriteBarrier<Unknown>, 16> m_registers;
     92    SegmentedVector<WriteBarrier<Unknown>, 16> m_variables;
    9493    ConcurrentJITLock m_lock;
    9594};
  • trunk/Source/JavaScriptCore/runtime/JSSymbolTableObject.h

    r180514 r181993  
    4848    JS_EXPORT_PRIVATE static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
    4949   
     50    static ptrdiff_t offsetOfSymbolTable() { return OBJECT_OFFSETOF(JSSymbolTableObject, m_symbolTable); }
     51   
    5052protected:
    5153    static const unsigned StructureFlags = IsEnvironmentRecord | OverridesGetPropertyNames | Base::StructureFlags;
     
    7981    SymbolTableEntry::Fast entry = iter->value;
    8082    ASSERT(!entry.isNull());
    81     slot.setValue(object, entry.getAttributes() | DontDelete, object->registerAt(entry.getIndex()).get());
     83    slot.setValue(object, entry.getAttributes() | DontDelete, object->variableAt(entry.scopeOffset()).get());
    8284    return true;
    8385}
     
    9597    ASSERT(!entry.isNull());
    9698    descriptor.setDescriptor(
    97         object->registerAt(entry.getIndex()).get(), entry.getAttributes() | DontDelete);
     99        object->variableAt(entry.scopeOffset()).get(), entry.getAttributes() | DontDelete);
    98100    return true;
    99101}
     
    111113    SymbolTableEntry::Fast entry = iter->value;
    112114    ASSERT(!entry.isNull());
    113     slot.setValue(object, entry.getAttributes() | DontDelete, object->registerAt(entry.getIndex()).get());
     115    slot.setValue(object, entry.getAttributes() | DontDelete, object->variableAt(entry.scopeOffset()).get());
    114116    slotIsWriteable = !entry.isReadOnly();
    115117    return true;
     
    146148            set->notifyWrite(vm, value, object, propertyName);
    147149        }
    148         reg = &object->registerAt(fastEntry.getIndex());
     150        reg = &object->variableAt(fastEntry.scopeOffset());
    149151    }
    150152    // I'd prefer we not hold lock while executing barriers, since I prefer to reserve
     
    174176            set->notifyWrite(vm, value, object, propertyName);
    175177        entry.setAttributes(attributes);
    176         reg = &object->registerAt(entry.getIndex());
     178        reg = &object->variableAt(entry.scopeOffset());
    177179    }
    178180    reg->set(vm, object, value);
  • trunk/Source/JavaScriptCore/runtime/JSType.h

    r179429 r181993  
    11/*
    2  *  Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
     2 *  Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2015 Apple Inc. All rights reserved.
    33 *
    44 *  This library is free software; you can redistribute it and/or
     
    5959    ImpureProxyType,
    6060    WithScopeType,
    61     ArgumentsType,
     61    DirectArgumentsType,
     62    ScopedArgumentsType,
    6263
    6364    Int8ArrayType,
  • trunk/Source/JavaScriptCore/runtime/Options.h

    r181990 r181993  
    126126    v(optionString, dfgFunctionWhitelistFile, nullptr) \
    127127    v(bool, dumpBytecodeAtDFGTime, false) \
     128    v(bool, dumpGraphAfterParsing, false) \
    128129    v(bool, dumpGraphAtEachPhase, false) \
    129130    v(bool, verboseDFGByteCodeParsing, false) \
  • trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp

    r180989 r181993  
    7070void SymbolTableEntry::prepareToWatch(SymbolTable* symbolTable)
    7171{
     72    if (!isWatchable())
     73        return;
    7274    FatEntry* entry = inflate();
    7375    if (entry->m_watchpoints)
     
    99101SymbolTable::SymbolTable(VM& vm)
    100102    : JSCell(vm, vm.symbolTableStructure.get())
    101     , m_parameterCountIncludingThis(0)
    102103    , m_usesNonStrictEval(false)
    103     , m_captureStart(0)
    104     , m_captureEnd(0)
    105104    , m_functionEnteredOnce(ClearWatchpoint)
    106105{
     
    112111{
    113112    SymbolTable* thisSymbolTable = jsCast<SymbolTable*>(thisCell);
     113   
     114    visitor.append(&thisSymbolTable->m_arguments);
     115   
    114116    if (!thisSymbolTable->m_watchpointCleanup) {
    115117        thisSymbolTable->m_watchpointCleanup =
     
    147149        unsigned size = 0;
    148150        for (auto& entry : m_map) {
    149             VirtualRegister reg(entry.value.getIndex());
    150             if (reg.isLocal())
    151                 size = std::max(size, static_cast<unsigned>(reg.toLocal()) + 1);
     151            VarOffset offset = entry.value.varOffset();
     152            if (offset.isScope())
     153                size = std::max(size, offset.scopeOffset().offset() + 1);
    152154        }
    153155   
    154156        m_localToEntry = std::make_unique<LocalToEntryVec>(size, nullptr);
    155157        for (auto& entry : m_map) {
    156             VirtualRegister reg(entry.value.getIndex());
    157             if (reg.isLocal())
    158                 m_localToEntry->at(reg.toLocal()) = &entry.value;
     158            VarOffset offset = entry.value.varOffset();
     159            if (offset.isScope())
     160                m_localToEntry->at(offset.scopeOffset().offset()) = &entry.value;
    159161        }
    160162    }
     
    163165}
    164166
    165 SymbolTableEntry* SymbolTable::entryFor(const ConcurrentJITLocker& locker, VirtualRegister reg)
    166 {
    167     if (!reg.isLocal())
    168         return nullptr;
    169     return localToEntry(locker)[reg.toLocal()];
    170 }
    171 
    172 SymbolTable* SymbolTable::cloneCapturedNames(VM& vm)
     167SymbolTableEntry* SymbolTable::entryFor(const ConcurrentJITLocker& locker, ScopeOffset offset)
     168{
     169    return localToEntry(locker)[offset.offset()];
     170}
     171
     172SymbolTable* SymbolTable::cloneScopePart(VM& vm)
    173173{
    174174    SymbolTable* result = SymbolTable::create(vm);
    175175   
    176     result->m_parameterCountIncludingThis = m_parameterCountIncludingThis;
    177176    result->m_usesNonStrictEval = m_usesNonStrictEval;
    178     result->m_captureStart = m_captureStart;
    179     result->m_captureEnd = m_captureEnd;
    180177
    181178    for (auto iter = m_map.begin(), end = m_map.end(); iter != end; ++iter) {
    182         if (!isCaptured(iter->value.getIndex()))
     179        if (!iter->value.varOffset().isScope())
    183180            continue;
    184181        result->m_map.add(
    185182            iter->key,
    186             SymbolTableEntry(iter->value.getIndex(), iter->value.getAttributes()));
    187     }
    188    
    189     if (m_slowArguments) {
    190         result->m_slowArguments = std::make_unique<SlowArgument[]>(parameterCount());
    191         for (unsigned i = parameterCount(); i--;)
    192             result->m_slowArguments[i] = m_slowArguments[i];
    193     }
    194 
     183            SymbolTableEntry(iter->value.varOffset(), iter->value.getAttributes()));
     184    }
     185   
     186    result->m_maxScopeOffset = m_maxScopeOffset;
     187   
     188    if (ScopedArgumentsTable* arguments = this->arguments())
     189        result->m_arguments.set(vm, result, arguments);
     190   
    195191    if (m_typeProfilingRareData) {
    196192        result->m_typeProfilingRareData = std::make_unique<TypeProfilingRareData>();
     
    204200
    205201        {
    206             auto iter = m_typeProfilingRareData->m_registerToVariableMap.begin();
    207             auto end = m_typeProfilingRareData->m_registerToVariableMap.end();
     202            auto iter = m_typeProfilingRareData->m_offsetToVariableMap.begin();
     203            auto end = m_typeProfilingRareData->m_offsetToVariableMap.end();
    208204            for (; iter != end; ++iter)
    209                 result->m_typeProfilingRareData->m_registerToVariableMap.set(iter->key, iter->value);
     205                result->m_typeProfilingRareData->m_offsetToVariableMap.set(iter->key, iter->value);
    210206        }
    211207
     
    230226    for (auto iter = m_map.begin(), end = m_map.end(); iter != end; ++iter) {
    231227        m_typeProfilingRareData->m_uniqueIDMap.set(iter->key, TypeProfilerNeedsUniqueIDGeneration);
    232         m_typeProfilingRareData->m_registerToVariableMap.set(iter->value.getIndex(), iter->key);
     228        m_typeProfilingRareData->m_offsetToVariableMap.set(iter->value.varOffset(), iter->key);
    233229    }
    234230}
     
    253249}
    254250
    255 GlobalVariableID SymbolTable::uniqueIDForRegister(const ConcurrentJITLocker& locker, int registerIndex, VM& vm)
    256 {
    257     RELEASE_ASSERT(m_typeProfilingRareData);
    258 
    259     auto iter = m_typeProfilingRareData->m_registerToVariableMap.find(registerIndex);
    260     auto end = m_typeProfilingRareData->m_registerToVariableMap.end();
     251GlobalVariableID SymbolTable::uniqueIDForOffset(const ConcurrentJITLocker& locker, VarOffset offset, VM& vm)
     252{
     253    RELEASE_ASSERT(m_typeProfilingRareData);
     254
     255    auto iter = m_typeProfilingRareData->m_offsetToVariableMap.find(offset);
     256    auto end = m_typeProfilingRareData->m_offsetToVariableMap.end();
    261257    if (iter == end)
    262258        return TypeProfilerNoGlobalIDExists;
     
    265261}
    266262
    267 RefPtr<TypeSet> SymbolTable::globalTypeSetForRegister(const ConcurrentJITLocker& locker, int registerIndex, VM& vm)
    268 {
    269     RELEASE_ASSERT(m_typeProfilingRareData);
    270 
    271     uniqueIDForRegister(locker, registerIndex, vm); // Lazily create the TypeSet if necessary.
    272 
    273     auto iter = m_typeProfilingRareData->m_registerToVariableMap.find(registerIndex);
    274     auto end = m_typeProfilingRareData->m_registerToVariableMap.end();
     263RefPtr<TypeSet> SymbolTable::globalTypeSetForOffset(const ConcurrentJITLocker& locker, VarOffset offset, VM& vm)
     264{
     265    RELEASE_ASSERT(m_typeProfilingRareData);
     266
     267    uniqueIDForOffset(locker, offset, vm); // Lazily create the TypeSet if necessary.
     268
     269    auto iter = m_typeProfilingRareData->m_offsetToVariableMap.find(offset);
     270    auto end = m_typeProfilingRareData->m_offsetToVariableMap.end();
    275271    if (iter == end)
    276272        return nullptr;
  • trunk/Source/JavaScriptCore/runtime/SymbolTable.h

    r180989 r181993  
    3131
    3232#include "ConcurrentJITLock.h"
     33#include "ConstantMode.h"
    3334#include "JSObject.h"
     35#include "ScopedArgumentsTable.h"
    3436#include "TypeLocation.h"
     37#include "VarOffset.h"
    3538#include "VariableWatchpointSet.h"
    3639#include <memory>
     
    3942
    4043namespace JSC {
    41 
    42 struct SlowArgument {
    43 public:
    44     enum Status {
    45         Normal = 0,
    46         Captured = 1,
    47         Deleted = 2
    48     };
    49 
    50     SlowArgument()
    51         : status(Normal)
    52         , index(0)
    53     {
    54     }
    55 
    56     Status status;
    57     int index; // If status is 'Deleted', index is bogus.
    58 };
    5944
    6045static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits<int>::max(); }
     
    8772
    8873struct SymbolTableEntry {
     74private:
     75    static VarOffset varOffsetFromBits(intptr_t bits)
     76    {
     77        VarKind kind;
     78        intptr_t kindBits = bits & KindBitsMask;
     79        if (kindBits <= UnwatchableScopeKindBits)
     80            kind = VarKind::Scope;
     81        else if (kindBits == StackKindBits)
     82            kind = VarKind::Stack;
     83        else
     84            kind = VarKind::DirectArgument;
     85        return VarOffset::assemble(kind, static_cast<int>(bits >> FlagBits));
     86    }
     87   
     88    static ScopeOffset scopeOffsetFromBits(intptr_t bits)
     89    {
     90        ASSERT((bits & KindBitsMask) <= UnwatchableScopeKindBits);
     91        return ScopeOffset(static_cast<int>(bits >> FlagBits));
     92    }
     93
     94public:
     95   
    8996    // Use the SymbolTableEntry::Fast class, either via implicit cast or by calling
    9097    // getFast(), when you (1) only care about isNull(), getIndex(), and isReadOnly(),
     
    108115        }
    109116
    110         int getIndex() const
    111         {
    112             return static_cast<int>(m_bits >> FlagBits);
    113         }
    114    
     117        VarOffset varOffset() const
     118        {
     119            return varOffsetFromBits(m_bits);
     120        }
     121       
     122        // Asserts if the offset is anything but a scope offset. This structures the assertions
     123        // in a way that may result in better code, even in release, than doing
     124        // varOffset().scopeOffset().
     125        ScopeOffset scopeOffset() const
     126        {
     127            return scopeOffsetFromBits(m_bits);
     128        }
     129       
    115130        bool isReadOnly() const
    116131        {
     
    118133        }
    119134       
     135        bool isDontEnum() const
     136        {
     137            return m_bits & DontEnumFlag;
     138        }
     139       
    120140        unsigned getAttributes() const
    121141        {
    122142            unsigned attributes = 0;
    123             if (m_bits & ReadOnlyFlag)
     143            if (isReadOnly())
    124144                attributes |= ReadOnly;
    125             if (m_bits & DontEnumFlag)
     145            if (isDontEnum())
    126146                attributes |= DontEnum;
    127147            return attributes;
     
    143163    }
    144164
    145     SymbolTableEntry(int index)
     165    SymbolTableEntry(VarOffset offset)
    146166        : m_bits(SlimFlag)
    147167    {
    148         ASSERT(isValidIndex(index));
    149         pack(index, false, false);
    150     }
    151 
    152     SymbolTableEntry(int index, unsigned attributes)
     168        ASSERT(isValidVarOffset(offset));
     169        pack(offset, true, false, false);
     170    }
     171
     172    SymbolTableEntry(VarOffset offset, unsigned attributes)
    153173        : m_bits(SlimFlag)
    154174    {
    155         ASSERT(isValidIndex(index));
    156         pack(index, attributes & ReadOnly, attributes & DontEnum);
     175        ASSERT(isValidVarOffset(offset));
     176        pack(offset, true, attributes & ReadOnly, attributes & DontEnum);
    157177    }
    158178   
     
    182202    }
    183203
    184     int getIndex() const
    185     {
    186         return static_cast<int>(bits() >> FlagBits);
     204    VarOffset varOffset() const
     205    {
     206        return varOffsetFromBits(bits());
     207    }
     208   
     209    bool isWatchable() const
     210    {
     211        return (m_bits & KindBitsMask) == ScopeKindBits;
     212    }
     213   
     214    // Asserts if the offset is anything but a scope offset. This structures the assertions
     215    // in a way that may result in better code, even in release, than doing
     216    // varOffset().scopeOffset().
     217    ScopeOffset scopeOffset() const
     218    {
     219        return scopeOffsetFromBits(bits());
    187220    }
    188221   
     
    207240        return getFast().getAttributes();
    208241    }
    209 
     242   
    210243    void setAttributes(unsigned attributes)
    211244    {
    212         pack(getIndex(), attributes & ReadOnly, attributes & DontEnum);
     245        pack(varOffset(), isWatchable(), attributes & ReadOnly, attributes & DontEnum);
    213246    }
    214247
     
    218251    }
    219252   
     253    ConstantMode constantMode() const
     254    {
     255        return modeForIsConstant(isReadOnly());
     256    }
     257   
     258    bool isDontEnum() const
     259    {
     260        return bits() & DontEnumFlag;
     261    }
     262   
    220263    JSValue inferredValue();
     264
     265    void disableWatching()
     266    {
     267        if (varOffset().isScope())
     268            pack(varOffset(), false, isReadOnly(), isDontEnum());
     269    }
    221270   
    222271    void prepareToWatch(SymbolTable*);
     
    243292    static const intptr_t DontEnumFlag = 0x4;
    244293    static const intptr_t NotNullFlag = 0x8;
    245     static const intptr_t FlagBits = 4;
     294    static const intptr_t KindBitsMask = 0x30;
     295    static const intptr_t ScopeKindBits = 0x00;
     296    static const intptr_t UnwatchableScopeKindBits = 0x10;
     297    static const intptr_t StackKindBits = 0x20;
     298    static const intptr_t DirectArgumentKindBits = 0x30;
     299    static const intptr_t FlagBits = 6;
    246300   
    247301    class FatEntry {
     
    310364    JS_EXPORT_PRIVATE void freeFatEntrySlow();
    311365
    312     void pack(int index, bool readOnly, bool dontEnum)
     366    void pack(VarOffset offset, bool isWatchable, bool readOnly, bool dontEnum)
    313367    {
    314368        ASSERT(!isFat());
    315369        intptr_t& bitsRef = bits();
    316         bitsRef = (static_cast<intptr_t>(index) << FlagBits) | NotNullFlag | SlimFlag;
     370        bitsRef =
     371            (static_cast<intptr_t>(offset.rawOffset()) << FlagBits) | NotNullFlag | SlimFlag;
    317372        if (readOnly)
    318373            bitsRef |= ReadOnlyFlag;
    319374        if (dontEnum)
    320375            bitsRef |= DontEnumFlag;
    321     }
    322    
    323     bool isValidIndex(int index)
    324     {
    325         return ((static_cast<intptr_t>(index) << FlagBits) >> FlagBits) == static_cast<intptr_t>(index);
     376        switch (offset.kind()) {
     377        case VarKind::Scope:
     378            if (isWatchable)
     379                bitsRef |= ScopeKindBits;
     380            else
     381                bitsRef |= UnwatchableScopeKindBits;
     382            break;
     383        case VarKind::Stack:
     384            bitsRef |= StackKindBits;
     385            break;
     386        case VarKind::DirectArgument:
     387            bitsRef |= DirectArgumentKindBits;
     388            break;
     389        default:
     390            RELEASE_ASSERT_NOT_REACHED();
     391            break;
     392        }
     393    }
     394   
     395    static bool isValidVarOffset(VarOffset offset)
     396    {
     397        return ((static_cast<intptr_t>(offset.rawOffset()) << FlagBits) >> FlagBits) == static_cast<intptr_t>(offset.rawOffset());
    326398    }
    327399
     
    340412    typedef HashMap<RefPtr<StringImpl>, GlobalVariableID> UniqueIDMap;
    341413    typedef HashMap<RefPtr<StringImpl>, RefPtr<TypeSet>> UniqueTypeSetMap;
    342     typedef HashMap<int, RefPtr<StringImpl>, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int>> RegisterToVariableMap;
     414    typedef HashMap<VarOffset, RefPtr<StringImpl>> OffsetToVariableMap;
    343415    typedef Vector<SymbolTableEntry*> LocalToEntryVec;
    344416
     
    353425    {
    354426        SymbolTable* result = create(vm);
    355         result->add(ident.impl(), SymbolTableEntry(-1, attributes));
     427        result->add(ident.impl(), SymbolTableEntry(VarOffset(ScopeOffset(0)), attributes));
    356428        return result;
    357429    }
     
    425497    }
    426498   
    427     Map::AddResult add(const ConcurrentJITLocker&, StringImpl* key, const SymbolTableEntry& entry)
     499    ScopeOffset maxScopeOffset() const
     500    {
     501        return m_maxScopeOffset;
     502    }
     503   
     504    void didUseScopeOffset(ScopeOffset offset)
     505    {
     506        if (!m_maxScopeOffset || m_maxScopeOffset < offset)
     507            m_maxScopeOffset = offset;
     508    }
     509   
     510    void didUseVarOffset(VarOffset offset)
     511    {
     512        if (offset.isScope())
     513            didUseScopeOffset(offset.scopeOffset());
     514    }
     515   
     516    unsigned scopeSize() const
     517    {
     518        ScopeOffset maxScopeOffset = this->maxScopeOffset();
     519       
     520        // Do some calculation that relies on invalid scope offset plus one being zero.
     521        unsigned fastResult = maxScopeOffset.offsetUnchecked() + 1;
     522       
     523        // Assert that this works.
     524        ASSERT(fastResult == (!maxScopeOffset ? 0 : maxScopeOffset.offset() + 1));
     525       
     526        return fastResult;
     527    }
     528   
     529    ScopeOffset nextScopeOffset() const
     530    {
     531        return ScopeOffset(scopeSize());
     532    }
     533   
     534    ScopeOffset takeNextScopeOffset(const ConcurrentJITLocker&)
     535    {
     536        ScopeOffset result = nextScopeOffset();
     537        m_maxScopeOffset = result;
     538        return result;
     539    }
     540   
     541    ScopeOffset takeNextScopeOffset()
     542    {
     543        ConcurrentJITLocker locker(m_lock);
     544        return takeNextScopeOffset(locker);
     545    }
     546   
     547    void add(const ConcurrentJITLocker&, StringImpl* key, const SymbolTableEntry& entry)
    428548    {
    429549        RELEASE_ASSERT(!m_localToEntry);
    430         return m_map.add(key, entry);
     550        didUseVarOffset(entry.varOffset());
     551        Map::AddResult result = m_map.add(key, entry);
     552        ASSERT_UNUSED(result, result.isNewEntry);
    431553    }
    432554   
     
    437559    }
    438560   
    439     Map::AddResult set(const ConcurrentJITLocker&, StringImpl* key, const SymbolTableEntry& entry)
     561    void set(const ConcurrentJITLocker&, StringImpl* key, const SymbolTableEntry& entry)
    440562    {
    441563        RELEASE_ASSERT(!m_localToEntry);
    442         return m_map.set(key, entry);
     564        didUseVarOffset(entry.varOffset());
     565        m_map.set(key, entry);
    443566    }
    444567   
     
    460583    }
    461584   
     585    // The principle behind ScopedArgumentsTable modifications is that we will create one and
     586    // leave it unlocked - thereby allowing in-place changes - until someone asks for a pointer to
     587    // the table. Then, we will lock it. Then both our future changes and their future changes
     588    // will first have to make a copy. This discipline means that usually when we create a
     589    // ScopedArguments object, we don't have to make a copy of the ScopedArgumentsTable - instead
     590    // we just take a reference to one that we already have.
     591   
     592    uint32_t argumentsLength() const
     593    {
     594        if (!m_arguments)
     595            return 0;
     596        return m_arguments->length();
     597    }
     598   
     599    void setArgumentsLength(VM& vm, uint32_t length)
     600    {
     601        if (UNLIKELY(!m_arguments))
     602            m_arguments.set(vm, this, ScopedArgumentsTable::create(vm));
     603        m_arguments.set(vm, this, m_arguments->setLength(vm, length));
     604    }
     605   
     606    ScopeOffset argumentOffset(uint32_t i) const
     607    {
     608        ASSERT_WITH_SECURITY_IMPLICATION(m_arguments);
     609        return m_arguments->get(i);
     610    }
     611   
     612    void setArgumentOffset(VM& vm, uint32_t i, ScopeOffset offset)
     613    {
     614        ASSERT_WITH_SECURITY_IMPLICATION(m_arguments);
     615        m_arguments.set(vm, this, m_arguments->set(vm, i, offset));
     616    }
     617   
     618    ScopedArgumentsTable* arguments() const
     619    {
     620        if (!m_arguments)
     621            return nullptr;
     622        m_arguments->lock();
     623        return m_arguments.get();
     624    }
     625   
    462626    const LocalToEntryVec& localToEntry(const ConcurrentJITLocker&);
    463     SymbolTableEntry* entryFor(const ConcurrentJITLocker&, VirtualRegister);
    464    
    465     GlobalVariableID uniqueIDForVariable(const ConcurrentJITLocker&, StringImpl* key, VM& vm);
    466     GlobalVariableID uniqueIDForRegister(const ConcurrentJITLocker& locker, int registerIndex, VM& vm);
    467     RefPtr<TypeSet> globalTypeSetForRegister(const ConcurrentJITLocker& locker, int registerIndex, VM& vm);
    468     RefPtr<TypeSet> globalTypeSetForVariable(const ConcurrentJITLocker& locker, StringImpl* key, VM& vm);
     627    SymbolTableEntry* entryFor(const ConcurrentJITLocker&, ScopeOffset);
     628   
     629    GlobalVariableID uniqueIDForVariable(const ConcurrentJITLocker&, StringImpl* key, VM&);
     630    GlobalVariableID uniqueIDForOffset(const ConcurrentJITLocker&, VarOffset, VM&);
     631    RefPtr<TypeSet> globalTypeSetForOffset(const ConcurrentJITLocker&, VarOffset, VM&);
     632    RefPtr<TypeSet> globalTypeSetForVariable(const ConcurrentJITLocker&, StringImpl* key, VM&);
    469633
    470634    bool usesNonStrictEval() { return m_usesNonStrictEval; }
    471635    void setUsesNonStrictEval(bool usesNonStrictEval) { m_usesNonStrictEval = usesNonStrictEval; }
    472636
    473     int captureStart() const { return m_captureStart; }
    474     void setCaptureStart(int captureStart) { m_captureStart = captureStart; }
    475 
    476     int captureEnd() const { return m_captureEnd; }
    477     void setCaptureEnd(int captureEnd) { m_captureEnd = captureEnd; }
    478 
    479     int captureCount() const { return -(m_captureEnd - m_captureStart); }
    480    
    481     bool isCaptured(int operand)
    482     {
    483         return operand <= captureStart() && operand > captureEnd();
    484     }
    485 
    486     int parameterCount() { return m_parameterCountIncludingThis - 1; }
    487     int parameterCountIncludingThis() { return m_parameterCountIncludingThis; }
    488     void setParameterCountIncludingThis(int parameterCountIncludingThis) { m_parameterCountIncludingThis = parameterCountIncludingThis; }
    489 
    490     // 0 if we don't capture any arguments; parameterCount() in length if we do.
    491     const SlowArgument* slowArguments() { return m_slowArguments.get(); }
    492     void setSlowArguments(std::unique_ptr<SlowArgument[]> slowArguments) { m_slowArguments = WTF::move(slowArguments); }
    493    
    494     SymbolTable* cloneCapturedNames(VM&);
     637    SymbolTable* cloneScopePart(VM&);
    495638
    496639    void prepareForTypeProfiling(const ConcurrentJITLocker&);
     
    520663
    521664    Map m_map;
     665    ScopeOffset m_maxScopeOffset;
     666   
    522667    struct TypeProfilingRareData {
    523668        UniqueIDMap m_uniqueIDMap;
    524         RegisterToVariableMap m_registerToVariableMap;
     669        OffsetToVariableMap m_offsetToVariableMap;
    525670        UniqueTypeSetMap m_uniqueTypeSetMap;
    526671    };
    527672    std::unique_ptr<TypeProfilingRareData> m_typeProfilingRareData;
    528673
    529     int m_parameterCountIncludingThis;
    530674    bool m_usesNonStrictEval;
    531 
    532     int m_captureStart;
    533     int m_captureEnd;
    534 
    535     std::unique_ptr<SlowArgument[]> m_slowArguments;
     675   
     676    WriteBarrier<ScopedArgumentsTable> m_arguments;
    536677   
    537678    std::unique_ptr<WatchpointCleanup> m_watchpointCleanup;
  • trunk/Source/JavaScriptCore/runtime/VM.cpp

    r181990 r181993  
    218218    getterSetterStructure.set(*this, GetterSetter::createStructure(*this, 0, jsNull()));
    219219    customGetterSetterStructure.set(*this, CustomGetterSetter::createStructure(*this, 0, jsNull()));
     220    scopedArgumentsTableStructure.set(*this, ScopedArgumentsTable::createStructure(*this, 0, jsNull()));
    220221    apiWrapperStructure.set(*this, JSAPIValueWrapper::createStructure(*this, 0, jsNull()));
    221222    JSScopeStructure.set(*this, JSScope::createStructure(*this, 0, jsNull()));
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r181458 r181993  
    11/*
    2  * Copyright (C) 2008, 2009, 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2009, 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    251251    Strong<Structure> getterSetterStructure;
    252252    Strong<Structure> customGetterSetterStructure;
     253    Strong<Structure> scopedArgumentsTableStructure;
    253254    Strong<Structure> apiWrapperStructure;
    254255    Strong<Structure> JSScopeStructure;
  • trunk/Source/WTF/ChangeLog

    r181979 r181993  
     12015-03-25  Filip Pizlo  <fpizlo@apple.com>
     2
     3        Heap variables shouldn't end up in the stack frame
     4        https://bugs.webkit.org/show_bug.cgi?id=141174
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        * wtf/FastBitVector.h:
     9        (WTF::FastBitVector::resize): Small change: don't resize if you don't have to resize.
     10
    1112015-03-25  Filip Pizlo  <fpizlo@apple.com>
    212
  • trunk/Source/WTF/wtf/FastBitVector.h

    r181467 r181993  
    7272    void resize(size_t numBits)
    7373    {
     74        if (numBits == m_numBits)
     75            return;
     76       
    7477        // Use fastCalloc instead of fastRealloc because we expect the common
    7578        // use case for this method to be initializing the size of the bitvector.
Note: See TracChangeset for help on using the changeset viewer.