<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[174226] trunk/Source/JavaScriptCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/174226">174226</a></dd>
<dt>Author</dt> <dd>oliver@apple.com</dd>
<dt>Date</dt> <dd>2014-10-02 13:35:58 -0700 (Thu, 02 Oct 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Do all closed variable access through the local lexical object
https://bugs.webkit.org/show_bug.cgi?id=136869

Reviewed by Filip Pizlo.

This patch makes all reads and writes from captured registers
go through the lexical record, and by doing so removes the
need for record tearoff.

To keep the patch simple we still number variables as though
they are local stack allocated registers, but ::local() will
fail. When local fails we perform a generic resolve, and in
that resolve we now use a ResolveScopeInfo struct to pass
around information about whether a lookup is a statically
known captured variable, and its location in the activation.
To ensure correct behaviour during codeblock linking we also
add a LocalClosureVariable resolution type.

To ensure correct semantics for the Arguments object, we now
have to eagerly create the Arguments object for any function
that uses both the Arguments object and requires a lexical
record.

* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::finalizeUnconditionally):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::initializeCapturedVariable):
  During the entry to a function we are not yet in a position
  to allocate temporaries so we directly use the lexical
  environment register.
(JSC::BytecodeGenerator::resolveCallee):
(JSC::BytecodeGenerator::emitMove):
(JSC::BytecodeGenerator::local):
(JSC::BytecodeGenerator::constLocal):
(JSC::BytecodeGenerator::emitResolveScope):
(JSC::BytecodeGenerator::emitResolveConstantLocal):
  The two resolve scope operations could technically skip
  the op_resolve_scope, and simply perform
      op_mov dst, recordRegister
  but for now it seemed best to maintain the same basic
  behaviour.
(JSC::BytecodeGenerator::emitGetFromScope):
(JSC::BytecodeGenerator::emitPutToScope):
(JSC::BytecodeGenerator::createArgumentsIfNecessary):
  If we have an environment we've already created Arguments
  so no need to check again.
(JSC::BytecodeGenerator::emitReturn):
  Don't need to emit tearoff_environment
* bytecompiler/BytecodeGenerator.h:
(JSC::Local::Local):
(JSC::Local::operator bool):
(JSC::Local::get):
(JSC::Local::isReadOnly):
(JSC::Local::isSpecial):
(JSC::ResolveScopeInfo::ResolveScopeInfo):
(JSC::ResolveScopeInfo::isLocal):
(JSC::ResolveScopeInfo::localIndex):
(JSC::BytecodeGenerator::shouldCreateArgumentsEagerly):
(JSC::Local::isCaptured): Deleted.
(JSC::Local::captureMode): Deleted.
* bytecompiler/NodesCodegen.cpp:
(JSC::ResolveNode::emitBytecode):
(JSC::EvalFunctionCallNode::emitBytecode):
(JSC::FunctionCallResolveNode::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::BindingNode::bindValue):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::tryGetRegisters):
* dfg/DFGNodeType.h:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* interpreter/Interpreter.cpp:
(JSC::unwindCallFrame):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_captured_mov): Deleted.
(JSC::JIT::emit_op_tear_off_lexical_environment): Deleted.
(JSC::JIT::emitSlow_op_captured_mov): Deleted.
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_captured_mov): Deleted.
(JSC::JIT::emit_op_tear_off_lexical_environment): Deleted.
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_resolve_scope):
(JSC::JIT::emit_op_get_from_scope):
(JSC::JIT::emitPutClosureVar):
(JSC::JIT::emit_op_put_to_scope):
(JSC::JIT::emitSlow_op_put_to_scope):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_resolve_scope):
(JSC::JIT::emit_op_get_from_scope):
(JSC::JIT::emitPutClosureVar):
(JSC::JIT::emit_op_put_to_scope):
(JSC::JIT::emitSlow_op_put_to_scope):
* llint/LLIntData.cpp:
(JSC::LLInt::Data::performAssertions):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/Arguments.cpp:
(JSC::Arguments::tearOff):
* runtime/Arguments.h:
(JSC::Arguments::argument):
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL): Deleted.
* runtime/CommonSlowPaths.h:
* runtime/JSLexicalEnvironment.cpp:
(JSC::JSLexicalEnvironment::visitChildren):
(JSC::JSLexicalEnvironment::symbolTableGet):
(JSC::JSLexicalEnvironment::symbolTablePut):
(JSC::JSLexicalEnvironment::getOwnNonIndexPropertyNames):
(JSC::JSLexicalEnvironment::getOwnPropertySlot):
(JSC::JSLexicalEnvironment::argumentsGetter):
* runtime/JSLexicalEnvironment.h:
(JSC::JSLexicalEnvironment::create):
(JSC::JSLexicalEnvironment::JSLexicalEnvironment):
(JSC::JSLexicalEnvironment::tearOff): Deleted.
(JSC::JSLexicalEnvironment::isTornOff): Deleted.
* runtime/JSScope.cpp:
(JSC::resolveTypeName):
* runtime/JSScope.h:
(JSC::makeType):
(JSC::needsVarInjectionChecks):
* runtime/WriteBarrier.h:
(JSC::WriteBarrier&lt;Unknown&gt;::WriteBarrier):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeListjson">trunk/Source/JavaScriptCore/bytecode/BytecodeList.json</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeUseDefh">trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerNodesCodegencpp">trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCapabilitiescpp">trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDoesGCcpp">trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphcpp">trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafeToExecuteh">trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterInterpretercpp">trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITcpp">trunk/Source/JavaScriptCore/jit/JIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITh">trunk/Source/JavaScriptCore/jit/JIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodescpp">trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodes32_64cpp">trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationscpp">trunk/Source/JavaScriptCore/jit/JITOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationsh">trunk/Source/JavaScriptCore/jit/JITOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITPropertyAccesscpp">trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITPropertyAccess32_64cpp">trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntDatacpp">trunk/Source/JavaScriptCore/llint/LLIntData.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathscpp">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathsh">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreterasm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArgumentscpp">trunk/Source/JavaScriptCore/runtime/Arguments.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArgumentsh">trunk/Source/JavaScriptCore/runtime/Arguments.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathsh">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSLexicalEnvironmentcpp">trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSLexicalEnvironmenth">trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSScopecpp">trunk/Source/JavaScriptCore/runtime/JSScope.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSScopeh">trunk/Source/JavaScriptCore/runtime/JSScope.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeWriteBarrierh">trunk/Source/JavaScriptCore/runtime/WriteBarrier.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -1,3 +1,175 @@
</span><ins>+2014-10-01  Oliver Hunt  &lt;oliver@apple.com&gt;
+
+        Do all closed variable access through the local lexical object
+        https://bugs.webkit.org/show_bug.cgi?id=136869
+
+        Reviewed by Filip Pizlo.
+
+        This patch makes all reads and writes from captured registers
+        go through the lexical record, and by doing so removes the
+        need for record tearoff.
+
+        To keep the patch simple we still number variables as though
+        they are local stack allocated registers, but ::local() will
+        fail. When local fails we perform a generic resolve, and in
+        that resolve we now use a ResolveScopeInfo struct to pass
+        around information about whether a lookup is a statically
+        known captured variable, and its location in the activation.
+        To ensure correct behaviour during codeblock linking we also
+        add a LocalClosureVariable resolution type.
+
+        To ensure correct semantics for the Arguments object, we now
+        have to eagerly create the Arguments object for any function
+        that uses both the Arguments object and requires a lexical
+        record.
+
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::finalizeUnconditionally):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::initializeCapturedVariable):
+          During the entry to a function we are not yet in a position
+          to allocate temporaries so we directly use the lexical
+          environment register.
+        (JSC::BytecodeGenerator::resolveCallee):
+        (JSC::BytecodeGenerator::emitMove):
+        (JSC::BytecodeGenerator::local):
+        (JSC::BytecodeGenerator::constLocal):
+        (JSC::BytecodeGenerator::emitResolveScope):
+        (JSC::BytecodeGenerator::emitResolveConstantLocal):
+          The two resolve scope operations could technically skip
+          the op_resolve_scope, and simply perform 
+              op_mov dst, recordRegister
+          but for now it seemed best to maintain the same basic
+          behaviour.
+        (JSC::BytecodeGenerator::emitGetFromScope):
+        (JSC::BytecodeGenerator::emitPutToScope):
+        (JSC::BytecodeGenerator::createArgumentsIfNecessary):
+          If we have an environment we've already created Arguments
+          so no need to check again.
+        (JSC::BytecodeGenerator::emitReturn):
+          Don't need to emit tearoff_environment
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::Local::Local):
+        (JSC::Local::operator bool):
+        (JSC::Local::get):
+        (JSC::Local::isReadOnly):
+        (JSC::Local::isSpecial):
+        (JSC::ResolveScopeInfo::ResolveScopeInfo):
+        (JSC::ResolveScopeInfo::isLocal):
+        (JSC::ResolveScopeInfo::localIndex):
+        (JSC::BytecodeGenerator::shouldCreateArgumentsEagerly):
+        (JSC::Local::isCaptured): Deleted.
+        (JSC::Local::captureMode): Deleted.
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ResolveNode::emitBytecode):
+        (JSC::EvalFunctionCallNode::emitBytecode):
+        (JSC::FunctionCallResolveNode::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::BindingNode::bindValue):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::tryGetRegisters):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * interpreter/Interpreter.cpp:
+        (JSC::unwindCallFrame):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompileSlowCases):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_captured_mov): Deleted.
+        (JSC::JIT::emit_op_tear_off_lexical_environment): Deleted.
+        (JSC::JIT::emitSlow_op_captured_mov): Deleted.
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_captured_mov): Deleted.
+        (JSC::JIT::emit_op_tear_off_lexical_environment): Deleted.
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emit_op_resolve_scope):
+        (JSC::JIT::emit_op_get_from_scope):
+        (JSC::JIT::emitPutClosureVar):
+        (JSC::JIT::emit_op_put_to_scope):
+        (JSC::JIT::emitSlow_op_put_to_scope):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emit_op_resolve_scope):
+        (JSC::JIT::emit_op_get_from_scope):
+        (JSC::JIT::emitPutClosureVar):
+        (JSC::JIT::emit_op_put_to_scope):
+        (JSC::JIT::emitSlow_op_put_to_scope):
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::Data::performAssertions):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LLIntSlowPaths.h:
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::tearOff):
+        * runtime/Arguments.h:
+        (JSC::Arguments::argument):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL): Deleted.
+        * runtime/CommonSlowPaths.h:
+        * runtime/JSLexicalEnvironment.cpp:
+        (JSC::JSLexicalEnvironment::visitChildren):
+        (JSC::JSLexicalEnvironment::symbolTableGet):
+        (JSC::JSLexicalEnvironment::symbolTablePut):
+        (JSC::JSLexicalEnvironment::getOwnNonIndexPropertyNames):
+        (JSC::JSLexicalEnvironment::getOwnPropertySlot):
+        (JSC::JSLexicalEnvironment::argumentsGetter):
+        * runtime/JSLexicalEnvironment.h:
+        (JSC::JSLexicalEnvironment::create):
+        (JSC::JSLexicalEnvironment::JSLexicalEnvironment):
+        (JSC::JSLexicalEnvironment::tearOff): Deleted.
+        (JSC::JSLexicalEnvironment::isTornOff): Deleted.
+        * runtime/JSScope.cpp:
+        (JSC::resolveTypeName):
+        * runtime/JSScope.h:
+        (JSC::makeType):
+        (JSC::needsVarInjectionChecks):
+        * runtime/WriteBarrier.h:
+        (JSC::WriteBarrier&lt;Unknown&gt;::WriteBarrier):
+
</ins><span class="cx"> 2014-10-02  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Object allocation sinking should have a sound story for picking materialization points
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeListjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeList.json (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -17,7 +17,6 @@
</span><span class="cx">             { &quot;name&quot; : &quot;op_new_array_buffer&quot;, &quot;length&quot; : 5 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_new_regexp&quot;, &quot;length&quot; : 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_mov&quot;, &quot;length&quot; : 3 },
</span><del>-            { &quot;name&quot; : &quot;op_captured_mov&quot;, &quot;length&quot; : 4 },
</del><span class="cx">             { &quot;name&quot; : &quot;op_not&quot;, &quot;length&quot; : 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_eq&quot;, &quot;length&quot; : 4 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_eq_null&quot;, &quot;length&quot; : 3 },
</span><span class="lines">@@ -99,7 +98,6 @@
</span><span class="cx">             { &quot;name&quot; : &quot;op_call&quot;, &quot;length&quot; : 9 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_call_eval&quot;, &quot;length&quot; : 9 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_call_varargs&quot;, &quot;length&quot; : 9 },
</span><del>-            { &quot;name&quot; : &quot;op_tear_off_lexical_environment&quot;, &quot;length&quot; : 2 },
</del><span class="cx">             { &quot;name&quot; : &quot;op_tear_off_arguments&quot;, &quot;length&quot; : 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_ret&quot;, &quot;length&quot; : 2 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_ret_object_or_this&quot;, &quot;length&quot; : 3 },
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeUseDefh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -62,7 +62,6 @@
</span><span class="cx">     case op_create_lexical_environment: 
</span><span class="cx">     case op_create_arguments:
</span><span class="cx">     case op_to_this:
</span><del>-    case op_tear_off_lexical_environment:
</del><span class="cx">     case op_profile_will_call:
</span><span class="cx">     case op_profile_did_call:
</span><span class="cx">     case op_profile_type:
</span><span class="lines">@@ -141,7 +140,6 @@
</span><span class="cx">     case op_eq_null:
</span><span class="cx">     case op_not:
</span><span class="cx">     case op_mov:
</span><del>-    case op_captured_mov:
</del><span class="cx">     case op_new_array_with_size:
</span><span class="cx">     case op_create_this:
</span><span class="cx">     case op_del_by_id:
</span><span class="lines">@@ -305,7 +303,6 @@
</span><span class="cx">     case op_next_enumerator_pname:
</span><span class="cx">     case op_resolve_scope:
</span><span class="cx">     case op_strcat:
</span><del>-    case op_tear_off_lexical_environment:
</del><span class="cx">     case op_to_primitive:
</span><span class="cx">     case op_catch:
</span><span class="cx">     case op_create_this:
</span><span class="lines">@@ -365,7 +362,6 @@
</span><span class="cx">     case op_eq_null:
</span><span class="cx">     case op_not:
</span><span class="cx">     case op_mov:
</span><del>-    case op_captured_mov:
</del><span class="cx">     case op_new_object:
</span><span class="cx">     case op_to_this:
</span><span class="cx">     case op_get_callee:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -833,14 +833,6 @@
</span><span class="cx">             out.printf(&quot;%s, %s&quot;, registerName(r0).data(), registerName(r1).data());
</span><span class="cx">             break;
</span><span class="cx">         }
</span><del>-        case op_captured_mov: {
-            int r0 = (++it)-&gt;u.operand;
-            int r1 = (++it)-&gt;u.operand;
-            printLocationAndOp(out, exec, location, it, &quot;captured_mov&quot;);
-            out.printf(&quot;%s, %s&quot;, registerName(r0).data(), registerName(r1).data());
-            ++it;
-            break;
-        }
</del><span class="cx">         case op_profile_type: {
</span><span class="cx">             int r0 = (++it)-&gt;u.operand;
</span><span class="cx">             ++it;
</span><span class="lines">@@ -1316,12 +1308,7 @@
</span><span class="cx">             dumpValueProfiling(out, it, hasPrintedProfiling);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><del>-            
-        case op_tear_off_lexical_environment: {
-            int r0 = (++it)-&gt;u.operand;
-            printLocationOpAndRegisterOperand(out, exec, location, it, &quot;tear_off_lexical_environment&quot;, r0);
-            break;
-        }
</del><ins>+
</ins><span class="cx">         case op_tear_off_arguments: {
</span><span class="cx">             int r0 = (++it)-&gt;u.operand;
</span><span class="cx">             int r1 = (++it)-&gt;u.operand;
</span><span class="lines">@@ -1946,6 +1933,10 @@
</span><span class="cx">         case op_resolve_scope: {
</span><span class="cx">             const Identifier&amp; ident = identifier(pc[2].u.operand);
</span><span class="cx">             ResolveType type = static_cast&lt;ResolveType&gt;(pc[3].u.operand);
</span><ins>+            if (type == LocalClosureVar) {
+                instructions[i + 3].u.operand = ClosureVar;
+                break;
+            }
</ins><span class="cx"> 
</span><span class="cx">             ResolveOp op = JSScope::abstractResolve(m_globalObject-&gt;globalExec(), needsActivation(), scope, ident, Get, type);
</span><span class="cx">             instructions[i + 3].u.operand = op.type;
</span><span class="lines">@@ -1962,8 +1953,14 @@
</span><span class="cx">             instructions[i + opLength - 1] = profile;
</span><span class="cx"> 
</span><span class="cx">             // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
</span><ins>+
</ins><span class="cx">             const Identifier&amp; ident = identifier(pc[3].u.operand);
</span><span class="cx">             ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
</span><ins>+            if (modeAndType.type() == LocalClosureVar) {
+                instructions[i + 4] = ResolveModeAndType(modeAndType.mode(), ClosureVar).operand();
+                break;
+            }
+
</ins><span class="cx">             ResolveOp op = JSScope::abstractResolve(m_globalObject-&gt;globalExec(), needsActivation(), scope, ident, Get, modeAndType.type());
</span><span class="cx"> 
</span><span class="cx">             instructions[i + 4].u.operand = ResolveModeAndType(modeAndType.mode(), op.type).operand();
</span><span class="lines">@@ -1979,7 +1976,26 @@
</span><span class="cx">         case op_put_to_scope: {
</span><span class="cx">             // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
</span><span class="cx">             const Identifier&amp; ident = identifier(pc[2].u.operand);
</span><ins>+
</ins><span class="cx">             ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
</span><ins>+            if (modeAndType.type() == LocalClosureVar) {
+                if (pc[5].u.index == UINT_MAX) {
+                    instructions[i + 5].u.watchpointSet = 0;
+                    break;
+                }
+                StringImpl* uid = identifier(pc[5].u.index).impl();
+                RELEASE_ASSERT(didCloneSymbolTable);
+                if (ident != m_vm-&gt;propertyNames-&gt;arguments) {
+                    ConcurrentJITLocker locker(m_symbolTable-&gt;m_lock);
+                    SymbolTable::Map::iterator iter = m_symbolTable-&gt;find(locker, uid);
+                    ASSERT(iter != m_symbolTable-&gt;end(locker));
+                    iter-&gt;value.prepareToWatch(symbolTable());
+                    instructions[i + 5].u.watchpointSet = iter-&gt;value.watchpointSet();
+                } else
+                    instructions[i + 5].u.watchpointSet = nullptr;
+                break;
+            }
+
</ins><span class="cx">             ResolveOp op = JSScope::abstractResolve(m_globalObject-&gt;globalExec(), needsActivation(), scope, ident, Put, modeAndType.type());
</span><span class="cx"> 
</span><span class="cx">             instructions[i + 4].u.operand = ResolveModeAndType(modeAndType.mode(), op.type).operand();
</span><span class="lines">@@ -2031,6 +2047,19 @@
</span><span class="cx"> 
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><ins>+            case ProfileTypeBytecodePutToLocalScope:
+            case ProfileTypeBytecodeGetFromLocalScope: {
+                const Identifier&amp; ident = identifier(pc[4].u.operand);
+                symbolTable = m_symbolTable.get();
+                ConcurrentJITLocker locker(symbolTable-&gt;m_lock);
+                // If our parent scope was created while profiling was disabled, it will not have prepared for profiling yet.
+                symbolTable-&gt;prepareForTypeProfiling(locker);
+                globalVariableID = symbolTable-&gt;uniqueIDForVariable(locker, ident.impl(), *vm());
+                globalTypeSet = symbolTable-&gt;globalTypeSetForVariable(locker, ident.impl(), *vm());
+
+                break;
+            }
+
</ins><span class="cx">             case ProfileTypeBytecodeHasGlobalID: {
</span><span class="cx">                 symbolTable = m_symbolTable.get();
</span><span class="cx">                 ConcurrentJITLocker locker(symbolTable-&gt;m_lock);
</span><span class="lines">@@ -2075,7 +2104,6 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        case op_captured_mov:
</del><span class="cx">         case op_new_captured_func: {
</span><span class="cx">             if (pc[3].u.index == UINT_MAX) {
</span><span class="cx">                 instructions[i + 3].u.watchpointSet = 0;
</span><span class="lines">@@ -2546,7 +2574,7 @@
</span><span class="cx">             case op_put_to_scope: {
</span><span class="cx">                 ResolveModeAndType modeAndType =
</span><span class="cx">                     ResolveModeAndType(curInstruction[4].u.operand);
</span><del>-                if (modeAndType.type() == GlobalVar || modeAndType.type() == GlobalVarWithVarInjectionChecks)
</del><ins>+                if (modeAndType.type() == GlobalVar || modeAndType.type() == GlobalVarWithVarInjectionChecks || modeAndType.type() == LocalClosureVar)
</ins><span class="cx">                     continue;
</span><span class="cx">                 WriteBarrierBase&lt;Structure&gt;&amp; structure = curInstruction[5].u.structure;
</span><span class="cx">                 if (!structure || Heap::isMarked(structure.get()))
</span><span class="lines">@@ -3868,7 +3896,6 @@
</span><span class="cx"> 
</span><span class="cx">         switch (opcodeID) {
</span><span class="cx">         case op_enter:
</span><del>-        case op_captured_mov:
</del><span class="cx">         case op_init_lazy_reg:
</span><span class="cx">         case op_create_arguments:
</span><span class="cx">         case op_new_captured_func:
</span><span class="lines">@@ -3876,11 +3903,14 @@
</span><span class="cx">         default:
</span><span class="cx">             break;
</span><span class="cx">         }
</span><del>-        
</del><ins>+
</ins><span class="cx">         VirtualRegister virtualReg(operand);
</span><span class="cx">         if (!virtualReg.isLocal())
</span><span class="cx">             return;
</span><del>-        
</del><ins>+
+        if (codeBlock-&gt;usesArguments() &amp;&amp; virtualReg == codeBlock-&gt;argumentsRegister())
+            return;
+
</ins><span class="cx">         if (codeBlock-&gt;captureCount() &amp;&amp; codeBlock-&gt;symbolTable()-&gt;isCaptured(operand)) {
</span><span class="cx">             codeBlock-&gt;beginValidationDidFail();
</span><span class="cx">             dataLog(&quot;    At bc#&quot;, bytecodeOffset, &quot; encountered invalid assignment to captured variable loc&quot;, virtualReg.toLocal(), &quot;.\n&quot;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -246,7 +246,6 @@
</span><span class="cx">     emitOpcode(op_enter);
</span><span class="cx">     if (m_codeBlock-&gt;needsFullScopeChain() || m_shouldEmitDebugHooks) {
</span><span class="cx">         m_lexicalEnvironmentRegister = addVar();
</span><del>-        emitInitLazyRegister(m_lexicalEnvironmentRegister);
</del><span class="cx">         m_codeBlock-&gt;setActivationRegister(m_lexicalEnvironmentRegister-&gt;virtualRegister());
</span><span class="cx">         emitOpcode(op_create_lexical_environment);
</span><span class="cx">         instructions().append(m_lexicalEnvironmentRegister-&gt;index());
</span><span class="lines">@@ -267,9 +266,15 @@
</span><span class="cx">         emitInitLazyRegister(argumentsRegister);
</span><span class="cx">         emitInitLazyRegister(unmodifiedArgumentsRegister);
</span><span class="cx">         
</span><del>-        if (shouldTearOffArgumentsEagerly()) {
</del><ins>+        if (shouldCreateArgumentsEagerly() || shouldTearOffArgumentsEagerly()) {
</ins><span class="cx">             emitOpcode(op_create_arguments);
</span><span class="cx">             instructions().append(argumentsRegister-&gt;index());
</span><ins>+            if (m_codeBlock-&gt;hasActivationRegister()) {
+                RegisterID* argumentsRegister = &amp;registerFor(m_codeBlock-&gt;argumentsRegister().offset());
+                initializeCapturedVariable(argumentsRegister, propertyNames().arguments, argumentsRegister);
+                RegisterID* uncheckedArgumentsRegister = &amp;registerFor(JSC::unmodifiedArgumentsRegister(m_codeBlock-&gt;argumentsRegister()).offset());
+                initializeCapturedVariable(uncheckedArgumentsRegister, propertyNames().arguments, uncheckedArgumentsRegister);
+            }
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -316,23 +321,26 @@
</span><span class="cx"> 
</span><span class="cx">     // Captured variables and functions go first so that activations don't have
</span><span class="cx">     // to step over the non-captured locals to mark them.
</span><del>-    if (functionBody-&gt;hasCapturedVariables()) {
</del><ins>+    if (functionBody-&gt;hasCapturedVariables() || shouldCaptureAllTheThings) {
</ins><span class="cx">         for (size_t i = 0; i &lt; boundParameterProperties.size(); i++) {
</span><span class="cx">             const Identifier&amp; ident = boundParameterProperties[i];
</span><del>-            if (functionBody-&gt;captures(ident))
</del><ins>+            if (functionBody-&gt;captures(ident) || shouldCaptureAllTheThings)
</ins><span class="cx">                 addVar(ident, IsVariable, IsWatchable);
</span><span class="cx">         }
</span><span class="cx">         for (size_t i = 0; i &lt; functionStack.size(); ++i) {
</span><span class="cx">             FunctionBodyNode* function = functionStack[i];
</span><span class="cx">             const Identifier&amp; ident = function-&gt;ident();
</span><del>-            if (functionBody-&gt;captures(ident)) {
</del><ins>+            if (functionBody-&gt;captures(ident) || shouldCaptureAllTheThings) {
</ins><span class="cx">                 m_functions.add(ident.impl());
</span><del>-                emitNewFunction(addVar(ident, IsVariable, IsWatchable), IsCaptured, function);
</del><ins>+                // We rely on still allocating stack space for captured variables
+                // here.
+                RegisterID* newFunction = emitNewFunction(addVar(ident, IsVariable, IsWatchable), IsCaptured, function);
+                initializeCapturedVariable(newFunction, ident, newFunction);
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">         for (size_t i = 0; i &lt; varStack.size(); ++i) {
</span><span class="cx">             const Identifier&amp; ident = varStack[i].first;
</span><del>-            if (functionBody-&gt;captures(ident))
</del><ins>+            if (functionBody-&gt;captures(ident) || shouldCaptureAllTheThings)
</ins><span class="cx">                 addVar(ident, (varStack[i].second &amp; DeclarationStacks::IsConstant) ? IsConstant : IsVariable, IsWatchable);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -341,37 +349,36 @@
</span><span class="cx"> 
</span><span class="cx">     bool canLazilyCreateFunctions = !functionBody-&gt;needsActivationForMoreThanVariables() &amp;&amp; !m_shouldEmitDebugHooks &amp;&amp; !m_vm-&gt;typeProfiler();
</span><span class="cx">     m_firstLazyFunction = codeBlock-&gt;m_numVars;
</span><del>-    for (size_t i = 0; i &lt; functionStack.size(); ++i) {
-        FunctionBodyNode* function = functionStack[i];
-        const Identifier&amp; ident = function-&gt;ident();
-        if (!functionBody-&gt;captures(ident)) {
-            m_functions.add(ident.impl());
-            RefPtr&lt;RegisterID&gt; reg = addVar(ident, IsVariable, NotWatchable);
-            // Don't lazily create functions that override the name 'arguments'
-            // as this would complicate lazy instantiation of actual arguments.
-            if (!canLazilyCreateFunctions || ident == propertyNames().arguments)
-                emitNewFunction(reg.get(), NotCaptured, function);
-            else {
-                emitInitLazyRegister(reg.get());
-                m_lazyFunctions.set(reg-&gt;virtualRegister().toLocal(), function);
</del><ins>+    if (!shouldCaptureAllTheThings) {
+        for (size_t i = 0; i &lt; functionStack.size(); ++i) {
+            FunctionBodyNode* function = functionStack[i];
+            const Identifier&amp; ident = function-&gt;ident();
+            if (!functionBody-&gt;captures(ident)) {
+                m_functions.add(ident.impl());
+                RefPtr&lt;RegisterID&gt; reg = addVar(ident, IsVariable, NotWatchable);
+                // Don't lazily create functions that override the name 'arguments'
+                // as this would complicate lazy instantiation of actual arguments.
+                if (!canLazilyCreateFunctions || ident == propertyNames().arguments)
+                    emitNewFunction(reg.get(), NotCaptured, function);
+                else {
+                    emitInitLazyRegister(reg.get());
+                    m_lazyFunctions.set(reg-&gt;virtualRegister().toLocal(), function);
+                }
</ins><span class="cx">             }
</span><span class="cx">         }
</span><ins>+        m_lastLazyFunction = canLazilyCreateFunctions ? codeBlock-&gt;m_numVars : m_firstLazyFunction;
+        for (size_t i = 0; i &lt; boundParameterProperties.size(); i++) {
+            const Identifier&amp; ident = boundParameterProperties[i];
+            if (!functionBody-&gt;captures(ident))
+                addVar(ident, IsVariable, IsWatchable);
+        }
+        for (size_t i = 0; i &lt; varStack.size(); ++i) {
+            const Identifier&amp; ident = varStack[i].first;
+            if (!functionBody-&gt;captures(ident))
+                addVar(ident, (varStack[i].second &amp; DeclarationStacks::IsConstant) ? IsConstant : IsVariable, NotWatchable);
+        }
</ins><span class="cx">     }
</span><del>-    m_lastLazyFunction = canLazilyCreateFunctions ? codeBlock-&gt;m_numVars : m_firstLazyFunction;
-    for (size_t i = 0; i &lt; boundParameterProperties.size(); i++) {
-        const Identifier&amp; ident = boundParameterProperties[i];
-        if (!functionBody-&gt;captures(ident))
-            addVar(ident, IsVariable, IsWatchable);
-    }
-    for (size_t i = 0; i &lt; varStack.size(); ++i) {
-        const Identifier&amp; ident = varStack[i].first;
-        if (!functionBody-&gt;captures(ident))
-            addVar(ident, (varStack[i].second &amp; DeclarationStacks::IsConstant) ? IsConstant : IsVariable, NotWatchable);
-    }
</del><span class="cx"> 
</span><del>-    if (shouldCaptureAllTheThings)
-        m_symbolTable-&gt;setCaptureEnd(virtualRegisterForLocal(codeBlock-&gt;m_numVars).offset());
-
</del><span class="cx">     if (m_symbolTable-&gt;captureCount())
</span><span class="cx">         emitOpcode(op_touch_entry);
</span><span class="cx">     
</span><span class="lines">@@ -396,7 +403,7 @@
</span><span class="cx">             ASSERT((functionBody-&gt;hasCapturedVariables() &amp;&amp; functionBody-&gt;captures(simpleParameter-&gt;boundProperty())) || shouldCaptureAllTheThings);
</span><span class="cx">             index = capturedArguments[i]-&gt;index();
</span><span class="cx">             RegisterID original(nextParameterIndex);
</span><del>-            emitMove(capturedArguments[i], &amp;original);
</del><ins>+            initializeCapturedVariable(capturedArguments[i], simpleParameter-&gt;boundProperty(), &amp;original);
</ins><span class="cx">         }
</span><span class="cx">         addParameter(simpleParameter-&gt;boundProperty(), index);
</span><span class="cx">     }
</span><span class="lines">@@ -476,6 +483,20 @@
</span><span class="cx">     return reg;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RegisterID* BytecodeGenerator::initializeCapturedVariable(RegisterID* dst, const Identifier&amp; propertyName, RegisterID* value)
+{
+
+    m_codeBlock-&gt;addPropertyAccessInstruction(instructions().size());
+    emitOpcode(op_put_to_scope);
+    instructions().append(m_lexicalEnvironmentRegister-&gt;index());
+    instructions().append(addConstant(propertyName));
+    instructions().append(value-&gt;index());
+    instructions().append(ResolveModeAndType(ThrowIfNotFound, LocalClosureVar).operand());
+    instructions().append(0);
+    instructions().append(dst-&gt;index());
+    return dst;
+}
+
</ins><span class="cx"> RegisterID* BytecodeGenerator::resolveCallee(FunctionBodyNode* functionBodyNode)
</span><span class="cx"> {
</span><span class="cx">     if (!functionNameIsInScope(functionBodyNode-&gt;ident(), functionBodyNode-&gt;functionMode()))
</span><span class="lines">@@ -486,7 +507,7 @@
</span><span class="cx"> 
</span><span class="cx">     m_calleeRegister.setIndex(JSStack::Callee);
</span><span class="cx">     if (functionBodyNode-&gt;captures(functionBodyNode-&gt;ident()))
</span><del>-        return emitMove(addVar(), IsCaptured, &amp;m_calleeRegister);
</del><ins>+        return initializeCapturedVariable(addVar(), functionBodyNode-&gt;ident(), &amp;m_calleeRegister);
</ins><span class="cx"> 
</span><span class="cx">     return &amp;m_calleeRegister;
</span><span class="cx"> }
</span><span class="lines">@@ -996,15 +1017,13 @@
</span><span class="cx">     return m_codeBlock-&gt;addRegExp(r);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, CaptureMode captureMode, RegisterID* src)
</del><ins>+RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src)
</ins><span class="cx"> {
</span><span class="cx">     m_staticPropertyAnalyzer.mov(dst-&gt;index(), src-&gt;index());
</span><del>-
-    emitOpcode(captureMode == IsCaptured ? op_captured_mov : op_mov);
</del><ins>+    ASSERT(dst-&gt;virtualRegister() == m_codeBlock-&gt;argumentsRegister() || !isCaptured(dst-&gt;index()));
+    emitOpcode(op_mov);
</ins><span class="cx">     instructions().append(dst-&gt;index());
</span><span class="cx">     instructions().append(src-&gt;index());
</span><del>-    if (captureMode == IsCaptured)
-        instructions().append(watchableVariable(dst-&gt;index()));
</del><span class="cx"> 
</span><span class="cx">     if (!dst-&gt;isTemporary() &amp;&amp; vm()-&gt;typeProfiler())
</span><span class="cx">         emitProfileType(dst, ProfileTypeBytecodeHasGlobalID, nullptr);
</span><span class="lines">@@ -1012,11 +1031,6 @@
</span><span class="cx">     return dst;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src)
-{
-    return emitMove(dst, captureMode(dst-&gt;index()), src);
-}
-
</del><span class="cx"> RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src)
</span><span class="cx"> {
</span><span class="cx">     emitOpcode(opcodeID);
</span><span class="lines">@@ -1197,9 +1211,9 @@
</span><span class="cx"> Local BytecodeGenerator::local(const Identifier&amp; property)
</span><span class="cx"> {
</span><span class="cx">     if (property == propertyNames().thisIdentifier)
</span><del>-        return Local(thisRegister(), ReadOnly, NotCaptured);
-    
-    if (property == propertyNames().arguments)
</del><ins>+        return Local(thisRegister(), ReadOnly, Local::SpecialLocal);
+    bool isArguments = property == propertyNames().arguments;
+    if (isArguments)
</ins><span class="cx">         createArgumentsIfNecessary();
</span><span class="cx"> 
</span><span class="cx">     if (!shouldOptimizeLocals())
</span><span class="lines">@@ -1209,8 +1223,13 @@
</span><span class="cx">     if (entry.isNull())
</span><span class="cx">         return Local();
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     RegisterID* local = createLazyRegisterIfNecessary(&amp;registerFor(entry.getIndex()));
</span><del>-    return Local(local, entry.getAttributes(), captureMode(local-&gt;index()));
</del><ins>+
+    if (isCaptured(local-&gt;index()) &amp;&amp; m_lexicalEnvironmentRegister)
+        return Local();
+
+    return Local(local, entry.getAttributes(), isArguments ? Local::SpecialLocal : Local::NormalLocal);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Local BytecodeGenerator::constLocal(const Identifier&amp; property)
</span><span class="lines">@@ -1223,7 +1242,12 @@
</span><span class="cx">         return Local();
</span><span class="cx"> 
</span><span class="cx">     RegisterID* local = createLazyRegisterIfNecessary(&amp;registerFor(entry.getIndex()));
</span><del>-    return Local(local, entry.getAttributes(), captureMode(local-&gt;index()));
</del><ins>+
+    bool isArguments = property == propertyNames().arguments;
+    if (isCaptured(local-&gt;index()) &amp;&amp; m_lexicalEnvironmentRegister)
+        return Local();
+
+    return Local(local, entry.getAttributes(), isArguments ? Local::SpecialLocal : Local::NormalLocal);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void BytecodeGenerator::emitCheckHasInstance(RegisterID* dst, RegisterID* value, RegisterID* base, Label* target)
</span><span class="lines">@@ -1247,10 +1271,24 @@
</span><span class="cx">     return GlobalProperty;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* BytecodeGenerator::emitResolveScope(RegisterID* dst, const Identifier&amp; identifier)
</del><ins>+RegisterID* BytecodeGenerator::emitResolveScope(RegisterID* dst, const Identifier&amp; identifier, ResolveScopeInfo&amp; info)
</ins><span class="cx"> {
</span><span class="cx">     m_codeBlock-&gt;addPropertyAccessInstruction(instructions().size());
</span><span class="cx"> 
</span><ins>+    if (m_symbolTable &amp;&amp; m_codeType == FunctionCode &amp;&amp; !m_localScopeDepth) {
+        SymbolTableEntry entry = m_symbolTable-&gt;get(identifier.impl());
+        if (!entry.isNull()) {
+            emitOpcode(op_resolve_scope);
+            instructions().append(kill(dst));
+            instructions().append(addConstant(identifier));
+            instructions().append(LocalClosureVar);
+            instructions().append(0);
+            instructions().append(0);
+            info = ResolveScopeInfo(entry.getIndex());
+            return dst;
+        }
+    }
+
</ins><span class="cx">     ASSERT(!m_symbolTable || !m_symbolTable-&gt;contains(identifier.impl()) || resolveType() == Dynamic);
</span><span class="cx"> 
</span><span class="cx">     // resolve_scope dst, id, ResolveType, depth
</span><span class="lines">@@ -1263,8 +1301,21 @@
</span><span class="cx">     return dst;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* BytecodeGenerator::emitGetFromScope(RegisterID* dst, RegisterID* scope, const Identifier&amp; identifier, ResolveMode resolveMode)
</del><ins>+RegisterID* BytecodeGenerator::emitResolveConstantLocal(RegisterID* dst, const Identifier&amp; identifier, ResolveScopeInfo&amp; info)
</ins><span class="cx"> {
</span><ins>+    if (!m_symbolTable || m_codeType != FunctionCode)
+        return nullptr;
+
+    SymbolTableEntry entry = m_symbolTable-&gt;get(identifier.impl());
+    if (entry.isNull())
+        return nullptr;
+    info = ResolveScopeInfo(entry.getIndex());
+    return emitMove(dst, m_lexicalEnvironmentRegister);
+
+}
+
+RegisterID* BytecodeGenerator::emitGetFromScope(RegisterID* dst, RegisterID* scope, const Identifier&amp; identifier, ResolveMode resolveMode, const ResolveScopeInfo&amp; info)
+{
</ins><span class="cx">     m_codeBlock-&gt;addPropertyAccessInstruction(instructions().size());
</span><span class="cx"> 
</span><span class="cx">     // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
</span><span class="lines">@@ -1272,14 +1323,14 @@
</span><span class="cx">     instructions().append(kill(dst));
</span><span class="cx">     instructions().append(scope-&gt;index());
</span><span class="cx">     instructions().append(addConstant(identifier));
</span><del>-    instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
</del><ins>+    instructions().append(ResolveModeAndType(resolveMode, info.isLocal() ? LocalClosureVar : resolveType()).operand());
</ins><span class="cx">     instructions().append(0);
</span><del>-    instructions().append(0);
</del><ins>+    instructions().append(info.localIndex());
</ins><span class="cx">     instructions().append(profile);
</span><span class="cx">     return dst;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Identifier&amp; identifier, RegisterID* value, ResolveMode resolveMode)
</del><ins>+RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Identifier&amp; identifier, RegisterID* value, ResolveMode resolveMode, const ResolveScopeInfo&amp; info)
</ins><span class="cx"> {
</span><span class="cx">     m_codeBlock-&gt;addPropertyAccessInstruction(instructions().size());
</span><span class="cx"> 
</span><span class="lines">@@ -1288,9 +1339,14 @@
</span><span class="cx">     instructions().append(scope-&gt;index());
</span><span class="cx">     instructions().append(addConstant(identifier));
</span><span class="cx">     instructions().append(value-&gt;index());
</span><del>-    instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
-    instructions().append(0);
-    instructions().append(0);
</del><ins>+    if (info.isLocal()) {
+        instructions().append(ResolveModeAndType(resolveMode, LocalClosureVar).operand());
+        instructions().append(watchableVariable(registerFor(info.localIndex()).index()));
+    } else {
+        instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
+        instructions().append(0);
+    }
+    instructions().append(info.localIndex());
</ins><span class="cx">     return value;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1659,7 +1715,7 @@
</span><span class="cx">     if (!m_codeBlock-&gt;usesArguments())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    if (shouldTearOffArgumentsEagerly())
</del><ins>+    if (shouldTearOffArgumentsEagerly() || shouldCreateArgumentsEagerly())
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     emitOpcode(op_create_arguments);
</span><span class="lines">@@ -1855,11 +1911,6 @@
</span><span class="cx"> 
</span><span class="cx"> RegisterID* BytecodeGenerator::emitReturn(RegisterID* src)
</span><span class="cx"> {
</span><del>-    if (m_lexicalEnvironmentRegister) {
-        emitOpcode(op_tear_off_lexical_environment);
-        instructions().append(m_lexicalEnvironmentRegister-&gt;index());
-    }
-
</del><span class="cx">     if (m_codeBlock-&gt;usesArguments() &amp;&amp; m_codeBlock-&gt;numParameters() != 1 &amp;&amp; !isStrictMode()) {
</span><span class="cx">         emitOpcode(op_tear_off_arguments);
</span><span class="cx">         instructions().append(m_codeBlock-&gt;argumentsRegister().offset());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -189,31 +189,53 @@
</span><span class="cx">         Local()
</span><span class="cx">             : m_local(0)
</span><span class="cx">             , m_attributes(0)
</span><ins>+            , m_kind(NormalLocal)
</ins><span class="cx">         {
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        Local(RegisterID* local, unsigned attributes, CaptureMode captureMode)
</del><ins>+        enum LocalKind { NormalLocal, SpecialLocal };
+
+        Local(RegisterID* local, unsigned attributes, LocalKind kind)
</ins><span class="cx">             : m_local(local)
</span><span class="cx">             , m_attributes(attributes)
</span><del>-            , m_isCaptured(captureMode == IsCaptured)
</del><ins>+            , m_kind(kind)
</ins><span class="cx">         {
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        operator bool() { return m_local; }
</del><ins>+        operator bool() const { return m_local; }
</ins><span class="cx"> 
</span><del>-        RegisterID* get() { return m_local; }
</del><ins>+        RegisterID* get() const { return m_local; }
</ins><span class="cx"> 
</span><del>-        bool isReadOnly() { return m_attributes &amp; ReadOnly; }
-        
-        bool isCaptured() { return m_isCaptured; }
-        CaptureMode captureMode() { return isCaptured() ? IsCaptured : NotCaptured; }
</del><ins>+        bool isReadOnly() const { return m_attributes &amp; ReadOnly; }
+        bool isSpecial() const { return m_kind != NormalLocal; }
</ins><span class="cx"> 
</span><span class="cx">     private:
</span><span class="cx">         RegisterID* m_local;
</span><span class="cx">         unsigned m_attributes;
</span><del>-        bool m_isCaptured;
</del><ins>+        LocalKind m_kind;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    struct ResolveScopeInfo {
+        ResolveScopeInfo()
+            : m_localIndex(0)
+            , m_resolveScopeKind(NonLocalScope)
+        {
+        }
+
+        ResolveScopeInfo(int index)
+            : m_localIndex(index)
+            , m_resolveScopeKind(LocalScope)
+        {
+        }
+
+        bool isLocal() const { return m_resolveScopeKind == LocalScope; }
+        int localIndex() const { return m_localIndex; }
+
+    private:
+        int m_localIndex;
+        enum { LocalScope, NonLocalScope } m_resolveScopeKind;
+    };
+
</ins><span class="cx">     struct TryRange {
</span><span class="cx">         RefPtr&lt;Label&gt; start;
</span><span class="cx">         RefPtr&lt;Label&gt; end;
</span><span class="lines">@@ -223,6 +245,8 @@
</span><span class="cx">     enum ProfileTypeBytecodeFlag {
</span><span class="cx">         ProfileTypeBytecodePutToScope,
</span><span class="cx">         ProfileTypeBytecodeGetFromScope,
</span><ins>+        ProfileTypeBytecodePutToLocalScope,
+        ProfileTypeBytecodeGetFromLocalScope,
</ins><span class="cx">         ProfileTypeBytecodeHasGlobalID,
</span><span class="cx">         ProfileTypeBytecodeDoesNotHaveGlobalID,
</span><span class="cx">         ProfileTypeBytecodeFunctionArgument,
</span><span class="lines">@@ -431,7 +455,6 @@
</span><span class="cx">         RegisterID* emitNewFunctionExpression(RegisterID* dst, FuncExprNode* func);
</span><span class="cx">         RegisterID* emitNewRegExp(RegisterID* dst, RegExp*);
</span><span class="cx"> 
</span><del>-        RegisterID* emitMove(RegisterID* dst, CaptureMode, RegisterID* src);
</del><span class="cx">         RegisterID* emitMove(RegisterID* dst, RegisterID* src);
</span><span class="cx"> 
</span><span class="cx">         RegisterID* emitToNumber(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_number, dst, src); }
</span><span class="lines">@@ -473,9 +496,10 @@
</span><span class="cx">         void emitToPrimitive(RegisterID* dst, RegisterID* src);
</span><span class="cx"> 
</span><span class="cx">         ResolveType resolveType();
</span><del>-        RegisterID* emitResolveScope(RegisterID* dst, const Identifier&amp;);
-        RegisterID* emitGetFromScope(RegisterID* dst, RegisterID* scope, const Identifier&amp;, ResolveMode);
-        RegisterID* emitPutToScope(RegisterID* scope, const Identifier&amp;, RegisterID* value, ResolveMode);
</del><ins>+        RegisterID* emitResolveConstantLocal(RegisterID* dst, const Identifier&amp;, ResolveScopeInfo&amp;);
+        RegisterID* emitResolveScope(RegisterID* dst, const Identifier&amp;, ResolveScopeInfo&amp;);
+        RegisterID* emitGetFromScope(RegisterID* dst, RegisterID* scope, const Identifier&amp;, ResolveMode, const ResolveScopeInfo&amp;);
+        RegisterID* emitPutToScope(RegisterID* scope, const Identifier&amp;, RegisterID* value, ResolveMode, const ResolveScopeInfo&amp;);
</ins><span class="cx"> 
</span><span class="cx">         PassRefPtr&lt;Label&gt; emitLabel(Label*);
</span><span class="cx">         void emitLoopHint();
</span><span class="lines">@@ -633,7 +657,8 @@
</span><span class="cx">         
</span><span class="cx">         RegisterID* emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx">         RegisterID* emitCallVarargs(OpcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><del>-        
</del><ins>+        RegisterID* initializeCapturedVariable(RegisterID* dst, const Identifier&amp;, RegisterID*);
+
</ins><span class="cx">     public:
</span><span class="cx">         JSString* addStringConstant(const Identifier&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -671,6 +696,13 @@
</span><span class="cx">             return m_codeType == FunctionCode &amp;&amp; isStrictMode() &amp;&amp; m_scopeNode-&gt;modifiesParameter();
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        bool shouldCreateArgumentsEagerly()
+        {
+            if (m_codeType != FunctionCode)
+                return false;
+            return m_lexicalEnvironmentRegister &amp;&amp; m_codeBlock-&gt;usesArguments();
+        }
+
</ins><span class="cx">         RegisterID* emitThrowExpressionTooDeepException();
</span><span class="cx"> 
</span><span class="cx">         void createArgumentsIfNecessary();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerNodesCodegencpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -168,11 +168,12 @@
</span><span class="cx">     
</span><span class="cx">     JSTextPosition divot = m_start + m_ident.length();
</span><span class="cx">     generator.emitExpressionInfo(divot, m_start, divot);
</span><del>-    RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.tempDestination(dst), m_ident);
</del><ins>+    ResolveScopeInfo resolveScopeInfo;
+    RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.tempDestination(dst), m_ident, resolveScopeInfo);
</ins><span class="cx">     RegisterID* finalDest = generator.finalDestination(dst);
</span><del>-    RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), m_ident, ThrowIfNotFound);
</del><ins>+    RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), m_ident, ThrowIfNotFound, resolveScopeInfo);
</ins><span class="cx">     if (generator.vm()-&gt;typeProfiler()) {
</span><del>-        generator.emitProfileType(finalDest, ProfileTypeBytecodeGetFromScope, &amp;m_ident);
</del><ins>+        generator.emitProfileType(finalDest, resolveScopeInfo.isLocal() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &amp;m_ident);
</ins><span class="cx">         generator.emitTypeProfilerExpressionInfo(m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
</span><span class="cx">     }
</span><span class="cx">     return result;
</span><span class="lines">@@ -489,8 +490,9 @@
</span><span class="cx">     CallArguments callArguments(generator, m_args);
</span><span class="cx">     JSTextPosition newDivot = divotStart() + 4;
</span><span class="cx">     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
</span><del>-    generator.emitResolveScope(callArguments.thisRegister(), generator.propertyNames().eval);
-    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), generator.propertyNames().eval, ThrowIfNotFound);
</del><ins>+    ResolveScopeInfo resolveScopeInfo;
+    generator.emitResolveScope(callArguments.thisRegister(), generator.propertyNames().eval, resolveScopeInfo);
+    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), generator.propertyNames().eval, ThrowIfNotFound, resolveScopeInfo);
</ins><span class="cx">     return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -537,8 +539,9 @@
</span><span class="cx"> 
</span><span class="cx">     JSTextPosition newDivot = divotStart() + m_ident.length();
</span><span class="cx">     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
</span><del>-    generator.emitResolveScope(callArguments.thisRegister(), m_ident);
-    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), m_ident, ThrowIfNotFound);
</del><ins>+    ResolveScopeInfo resolveScopeInfo;
+    generator.emitResolveScope(callArguments.thisRegister(), m_ident, resolveScopeInfo);
+    generator.emitGetFromScope(func.get(), callArguments.thisRegister(), m_ident, ThrowIfNotFound, resolveScopeInfo);
</ins><span class="cx">     RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
</span><span class="cx">     if (generator.vm()-&gt;typeProfiler()) {
</span><span class="cx">         generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
</span><span class="lines">@@ -802,7 +805,7 @@
</span><span class="cx">         if (local.isReadOnly()) {
</span><span class="cx">             generator.emitReadOnlyExceptionIfNeeded();
</span><span class="cx">             localReg = generator.emitMove(generator.tempDestination(dst), localReg);
</span><del>-        } else if (local.isCaptured() || generator.vm()-&gt;typeProfiler()) {
</del><ins>+        } else if (generator.vm()-&gt;typeProfiler()) {
</ins><span class="cx">             RefPtr&lt;RegisterID&gt; tempDst = generator.finalDestination(dst);
</span><span class="cx">             ASSERT(dst != localReg);
</span><span class="cx">             RefPtr&lt;RegisterID&gt; tempDstSrc = generator.newTemporary();
</span><span class="lines">@@ -818,12 +821,13 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><del>-    RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.newTemporary(), ident);
-    RefPtr&lt;RegisterID&gt; value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound);
</del><ins>+    ResolveScopeInfo resolveScopeInfo;
+    RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.newTemporary(), ident, resolveScopeInfo);
+    RefPtr&lt;RegisterID&gt; value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound, resolveScopeInfo);
</ins><span class="cx">     RefPtr&lt;RegisterID&gt; oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
</span><del>-    generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound);
</del><ins>+    generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound, resolveScopeInfo);
</ins><span class="cx">     if (generator.vm()-&gt;typeProfiler()) {
</span><del>-        generator.emitProfileType(value.get(), ProfileTypeBytecodePutToScope, &amp;ident);
</del><ins>+        generator.emitProfileType(value.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &amp;ident);
</ins><span class="cx">         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -903,7 +907,8 @@
</span><span class="cx">         return generator.emitLoad(generator.finalDestination(dst), false);
</span><span class="cx"> 
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><del>-    RefPtr&lt;RegisterID&gt; base = generator.emitResolveScope(generator.tempDestination(dst), m_ident);
</del><ins>+    ResolveScopeInfo resolveScopeInfo;
+    RefPtr&lt;RegisterID&gt; base = generator.emitResolveScope(generator.tempDestination(dst), m_ident, resolveScopeInfo);
</ins><span class="cx">     return generator.emitDeleteById(generator.finalDestination(dst, base.get()), base.get(), m_ident);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -960,8 +965,9 @@
</span><span class="cx">         return generator.emitTypeOf(generator.finalDestination(dst), local.get());
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.tempDestination(dst), m_ident);
-    RefPtr&lt;RegisterID&gt; value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, DoNotThrowIfNotFound);
</del><ins>+    ResolveScopeInfo resolveScopeInfo;
+    RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.tempDestination(dst), m_ident, resolveScopeInfo);
+    RefPtr&lt;RegisterID&gt; value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, DoNotThrowIfNotFound, resolveScopeInfo);
</ins><span class="cx">     if (dst == generator.ignoredResult())
</span><span class="cx">         return 0;
</span><span class="cx">     return generator.emitTypeOf(generator.finalDestination(dst, scope.get()), value.get());
</span><span class="lines">@@ -992,7 +998,7 @@
</span><span class="cx">         if (local.isReadOnly()) {
</span><span class="cx">             generator.emitReadOnlyExceptionIfNeeded();
</span><span class="cx">             localReg = generator.emitMove(generator.tempDestination(dst), localReg);
</span><del>-        } else if (local.isCaptured() || generator.vm()-&gt;typeProfiler()) {
</del><ins>+        } else if (generator.vm()-&gt;typeProfiler()) {
</ins><span class="cx">             RefPtr&lt;RegisterID&gt; tempDst = generator.tempDestination(dst);
</span><span class="cx">             generator.emitMove(tempDst.get(), localReg);
</span><span class="cx">             emitIncOrDec(generator, tempDst.get(), m_operator);
</span><span class="lines">@@ -1006,12 +1012,13 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><del>-    RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.tempDestination(dst), ident);
-    RefPtr&lt;RegisterID&gt; value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound);
</del><ins>+    ResolveScopeInfo resolveScopeInfo;
+    RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.tempDestination(dst), ident, resolveScopeInfo);
+    RefPtr&lt;RegisterID&gt; value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound, resolveScopeInfo);
</ins><span class="cx">     emitIncOrDec(generator, value.get(), m_operator);
</span><del>-    generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound);
</del><ins>+    generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound, resolveScopeInfo);
</ins><span class="cx">     if (generator.vm()-&gt;typeProfiler()) {
</span><del>-        generator.emitProfileType(value.get(), ProfileTypeBytecodePutToScope, &amp;ident);
</del><ins>+        generator.emitProfileType(value.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &amp;ident);
</ins><span class="cx">         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx">     return generator.moveToDestinationIfNeeded(dst, value.get());
</span><span class="lines">@@ -1505,8 +1512,7 @@
</span><span class="cx">             return emitReadModifyAssignment(generator, generator.finalDestination(dst), local.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right-&gt;resultDescriptor()));
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        if (local.isCaptured()
-            || generator.vm()-&gt;typeProfiler()
</del><ins>+        if (generator.vm()-&gt;typeProfiler()
</ins><span class="cx">             || generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right-&gt;isPure(generator))) {
</span><span class="cx">             RefPtr&lt;RegisterID&gt; result = generator.newTemporary();
</span><span class="cx">             generator.emitMove(result.get(), local.get());
</span><span class="lines">@@ -1524,12 +1530,13 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
</span><del>-    RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.newTemporary(), m_ident);
-    RefPtr&lt;RegisterID&gt; value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, ThrowIfNotFound);
</del><ins>+    ResolveScopeInfo resolveScopeInfo;
+    RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.newTemporary(), m_ident, resolveScopeInfo);
+    RefPtr&lt;RegisterID&gt; value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, ThrowIfNotFound, resolveScopeInfo);
</ins><span class="cx">     RefPtr&lt;RegisterID&gt; result = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right-&gt;resultDescriptor()), this);
</span><del>-    RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), ThrowIfNotFound);
</del><ins>+    RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), ThrowIfNotFound, resolveScopeInfo);
</ins><span class="cx">     if (generator.vm()-&gt;typeProfiler()) {
</span><del>-        generator.emitProfileType(result.get(), ProfileTypeBytecodePutToScope, &amp;m_ident);
</del><ins>+        generator.emitProfileType(result.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &amp;m_ident);
</ins><span class="cx">         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx">     return returnResult;
</span><span class="lines">@@ -1544,7 +1551,7 @@
</span><span class="cx">             generator.emitReadOnlyExceptionIfNeeded();
</span><span class="cx">             return generator.emitNode(dst, m_right);
</span><span class="cx">         }
</span><del>-        if (local.isCaptured() || generator.vm()-&gt;typeProfiler()) {
</del><ins>+        if (local.isSpecial() || generator.vm()-&gt;typeProfiler()) {
</ins><span class="cx">             RefPtr&lt;RegisterID&gt; tempDst = generator.tempDestination(dst);
</span><span class="cx">             generator.emitNode(tempDst.get(), m_right);
</span><span class="cx">             generator.emitMove(local.get(), tempDst.get());
</span><span class="lines">@@ -1560,14 +1567,15 @@
</span><span class="cx"> 
</span><span class="cx">     if (generator.isStrictMode())
</span><span class="cx">         generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><del>-    RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.newTemporary(), m_ident);
</del><ins>+    ResolveScopeInfo resolveScopeInfo;
+    RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.newTemporary(), m_ident, resolveScopeInfo);
</ins><span class="cx">     if (dst == generator.ignoredResult())
</span><span class="cx">         dst = 0;
</span><span class="cx">     RefPtr&lt;RegisterID&gt; result = generator.emitNode(dst, m_right);
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><del>-    RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
</del><ins>+    RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
</ins><span class="cx">     if (generator.vm()-&gt;typeProfiler()) {
</span><del>-        generator.emitProfileType(result.get(), ProfileTypeBytecodePutToScope, &amp;m_ident);
</del><ins>+        generator.emitProfileType(result.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &amp;m_ident);
</ins><span class="cx">         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     } 
</span><span class="cx">     return returnResult;
</span><span class="lines">@@ -1676,7 +1684,7 @@
</span><span class="cx">             return local.get();
</span><span class="cx"> 
</span><span class="cx">         // FIXME: Maybe call emitExpressionInfo here.
</span><del>-        if (local.isCaptured() || generator.vm()-&gt;typeProfiler()) {
</del><ins>+        if (local.isSpecial() || generator.vm()-&gt;typeProfiler()) {
</ins><span class="cx">             RefPtr&lt;RegisterID&gt; tempDst = generator.newTemporary();
</span><span class="cx">             generator.emitNode(tempDst.get(), m_init);
</span><span class="cx">             return generator.emitMove(local.get(), tempDst.get());
</span><span class="lines">@@ -1690,12 +1698,19 @@
</span><span class="cx">     if (generator.codeType() == GlobalCode)
</span><span class="cx">         return generator.emitInitGlobalConst(m_ident, value.get());
</span><span class="cx"> 
</span><del>-    if (generator.codeType() != EvalCode)
</del><ins>+    if (generator.codeType() != EvalCode) {
+
+        ResolveScopeInfo resolveScopeInfo;
+        if (RefPtr&lt;RegisterID&gt; scope = generator.emitResolveConstantLocal(generator.newTemporary(), m_ident, resolveScopeInfo))
+            return generator.emitPutToScope(scope.get(), m_ident, value.get(), DoNotThrowIfNotFound, resolveScopeInfo);
+
</ins><span class="cx">         return value.get();
</span><ins>+    }
</ins><span class="cx"> 
</span><span class="cx">     // FIXME: This will result in incorrect assignment if m_ident exists in an intervening with scope.
</span><del>-    RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.newTemporary(), m_ident);
-    return generator.emitPutToScope(scope.get(), m_ident, value.get(), DoNotThrowIfNotFound);
</del><ins>+    ResolveScopeInfo resolveScopeInfo;
+    RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.newTemporary(), m_ident, resolveScopeInfo);
+    return generator.emitPutToScope(scope.get(), m_ident, value.get(), DoNotThrowIfNotFound, resolveScopeInfo);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*)
</span><span class="lines">@@ -1792,9 +1807,10 @@
</span><span class="cx">     if (Local local = generator.local(m_ident))
</span><span class="cx">         generator.emitProfileType(local.get(), ProfileTypeBytecodeHasGlobalID, nullptr);
</span><span class="cx">     else {
</span><del>-        RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.newTemporary(), m_ident);
-        RefPtr&lt;RegisterID&gt; value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, DoNotThrowIfNotFound);
-        generator.emitProfileType(value.get(), ProfileTypeBytecodeGetFromScope, &amp;m_ident);
</del><ins>+        ResolveScopeInfo resolveScopeInfo;
+        RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.newTemporary(), m_ident, resolveScopeInfo);
+        RefPtr&lt;RegisterID&gt; value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, DoNotThrowIfNotFound, resolveScopeInfo);
+        generator.emitProfileType(value.get(), resolveScopeInfo.isLocal() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &amp;m_ident);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     generator.emitTypeProfilerExpressionInfo(position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
</span><span class="lines">@@ -1955,8 +1971,6 @@
</span><span class="cx">     if (m_lexpr-&gt;isResolveNode()) {
</span><span class="cx">         const Identifier&amp; ident = static_cast&lt;ResolveNode*&gt;(m_lexpr)-&gt;identifier();
</span><span class="cx">         Local local = generator.local(ident);
</span><del>-        if (local.isCaptured())
-            return nullptr;
</del><span class="cx">         return local.get();
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -1969,7 +1983,7 @@
</span><span class="cx">         auto simpleBinding = static_cast&lt;BindingNode*&gt;(binding);
</span><span class="cx">         const Identifier&amp; ident = simpleBinding-&gt;boundProperty();
</span><span class="cx">         Local local = generator.local(ident);
</span><del>-        if (local.isCaptured())
</del><ins>+        if (local.isSpecial())
</ins><span class="cx">             return nullptr;
</span><span class="cx">         return local.get();
</span><span class="cx">     }
</span><span class="lines">@@ -1987,9 +2001,10 @@
</span><span class="cx">         else {
</span><span class="cx">             if (generator.isStrictMode())
</span><span class="cx">                 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><del>-            RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), ident);
</del><ins>+            ResolveScopeInfo resolveScopeInfo;
+            RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), ident, resolveScopeInfo);
</ins><span class="cx">             generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><del>-            generator.emitPutToScope(scope, ident, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
</del><ins>+            generator.emitPutToScope(scope, ident, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
</ins><span class="cx">         }
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="lines">@@ -2021,7 +2036,7 @@
</span><span class="cx">         auto simpleBinding = static_cast&lt;BindingNode*&gt;(binding);
</span><span class="cx">         const Identifier&amp; ident = simpleBinding-&gt;boundProperty();
</span><span class="cx">         Local local = generator.local(ident);
</span><del>-        if (!local.get() || local.isCaptured()) {
</del><ins>+        if (!local.get() || local.isSpecial()) {
</ins><span class="cx">             assignNode-&gt;bindings()-&gt;bindValue(generator, propertyName);
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="lines">@@ -2183,9 +2198,10 @@
</span><span class="cx">             else {
</span><span class="cx">                 if (generator.isStrictMode())
</span><span class="cx">                     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><del>-                RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), ident);
</del><ins>+                ResolveScopeInfo resolveScopeInfo;
+                RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), ident, resolveScopeInfo);
</ins><span class="cx">                 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><del>-                generator.emitPutToScope(scope, ident, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
</del><ins>+                generator.emitPutToScope(scope, ident, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
</ins><span class="cx">             }
</span><span class="cx">         } else if (m_lexpr-&gt;isDotAccessorNode()) {
</span><span class="cx">             DotAccessorNode* assignNode = static_cast&lt;DotAccessorNode*&gt;(m_lexpr);
</span><span class="lines">@@ -2822,11 +2838,12 @@
</span><span class="cx">     }
</span><span class="cx">     if (generator.isStrictMode())
</span><span class="cx">         generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
</span><del>-    RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), m_boundProperty);
</del><ins>+    ResolveScopeInfo resolveScopeInfo;
+    RegisterID* scope = generator.emitResolveScope(generator.newTemporary(), m_boundProperty, resolveScopeInfo);
</ins><span class="cx">     generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
</span><del>-    generator.emitPutToScope(scope, m_boundProperty, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
</del><ins>+    generator.emitPutToScope(scope, m_boundProperty, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, resolveScopeInfo);
</ins><span class="cx">     if (generator.vm()-&gt;typeProfiler()) {
</span><del>-        generator.emitProfileType(value, ProfileTypeBytecodePutToScope, &amp;m_boundProperty);
</del><ins>+        generator.emitProfileType(value, resolveScopeInfo.isLocal() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &amp;m_boundProperty);
</ins><span class="cx">         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx">     return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -1299,7 +1299,6 @@
</span><span class="cx">         forNode(node).merge(SpecArguments);
</span><span class="cx">         break;
</span><span class="cx">         
</span><del>-    case TearOffActivation:
</del><span class="cx">     case TearOffArguments:
</span><span class="cx">         // Does nothing that is user-visible.
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -2630,16 +2630,6 @@
</span><span class="cx">             set(VirtualRegister(currentInstruction[1].u.operand), op);
</span><span class="cx">             NEXT_OPCODE(op_mov);
</span><span class="cx">         }
</span><del>-            
-        case op_captured_mov: {
-            Node* op = get(VirtualRegister(currentInstruction[2].u.operand));
-            if (VariableWatchpointSet* set = currentInstruction[3].u.watchpointSet) {
-                if (set-&gt;state() != IsInvalidated)
-                    addToGraph(NotifyWrite, OpInfo(set), op);
-            }
-            set(VirtualRegister(currentInstruction[1].u.operand), op);
-            NEXT_OPCODE(op_captured_mov);
-        }
</del><span class="cx"> 
</span><span class="cx">         case op_check_has_instance:
</span><span class="cx">             addToGraph(CheckHasInstance, get(VirtualRegister(currentInstruction[3].u.operand)));
</span><span class="lines">@@ -3196,6 +3186,7 @@
</span><span class="cx">             case GlobalVarWithVarInjectionChecks:
</span><span class="cx">                 set(VirtualRegister(dst), weakJSConstant(m_inlineStackTop-&gt;m_codeBlock-&gt;globalObject()));
</span><span class="cx">                 break;
</span><ins>+            case LocalClosureVar:
</ins><span class="cx">             case ClosureVar:
</span><span class="cx">             case ClosureVarWithVarInjectionChecks: {
</span><span class="cx">                 JSLexicalEnvironment* lexicalEnvironment = currentInstruction[5].u.lexicalEnvironment.get();
</span><span class="lines">@@ -3271,6 +3262,7 @@
</span><span class="cx">                 set(VirtualRegister(dst), weakJSConstant(inferredValue));
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><ins>+            case LocalClosureVar:
</ins><span class="cx">             case ClosureVar:
</span><span class="cx">             case ClosureVarWithVarInjectionChecks: {
</span><span class="cx">                 Node* scopeNode = get(VirtualRegister(scope));
</span><span class="lines">@@ -3314,7 +3306,7 @@
</span><span class="cx">             uintptr_t operand;
</span><span class="cx">             {
</span><span class="cx">                 ConcurrentJITLocker locker(m_inlineStackTop-&gt;m_profiledBlock-&gt;m_lock);
</span><del>-                if (resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks)
</del><ins>+                if (resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks || resolveType == LocalClosureVar)
</ins><span class="cx">                     watchpoints = currentInstruction[5].u.watchpointSet;
</span><span class="cx">                 else
</span><span class="cx">                     structure = currentInstruction[5].u.structure.get();
</span><span class="lines">@@ -3353,11 +3345,17 @@
</span><span class="cx">                 addToGraph(Phantom, get(VirtualRegister(scope)));
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><ins>+            case LocalClosureVar:
</ins><span class="cx">             case ClosureVar:
</span><span class="cx">             case ClosureVarWithVarInjectionChecks: {
</span><span class="cx">                 Node* scopeNode = get(VirtualRegister(scope));
</span><span class="cx">                 Node* scopeRegisters = addToGraph(GetClosureRegisters, scopeNode);
</span><del>-                addToGraph(PutClosureVar, OpInfo(operand), scopeNode, scopeRegisters, get(VirtualRegister(value)));
</del><ins>+                Node* valueNode = get(VirtualRegister(value));
+
+                if (watchpoints &amp;&amp; watchpoints-&gt;state() != IsInvalidated)
+                    addToGraph(NotifyWrite, OpInfo(watchpoints), valueNode);
+
+                addToGraph(PutClosureVar, OpInfo(operand), scopeNode, scopeRegisters, valueNode);
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             case Dynamic:
</span><span class="lines">@@ -3406,11 +3404,6 @@
</span><span class="cx">             set(unmodifiedArgumentsRegister(VirtualRegister(currentInstruction[1].u.operand)), createArguments);
</span><span class="cx">             NEXT_OPCODE(op_create_arguments);
</span><span class="cx">         }
</span><del>-            
-        case op_tear_off_lexical_environment: {
-            addToGraph(TearOffActivation, get(VirtualRegister(currentInstruction[1].u.operand)));
-            NEXT_OPCODE(op_tear_off_lexical_environment);
-        }
</del><span class="cx"> 
</span><span class="cx">         case op_tear_off_arguments: {
</span><span class="cx">             m_graph.m_hasArguments = true;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -122,7 +122,6 @@
</span><span class="cx">     case op_profile_did_call:
</span><span class="cx">     case op_profile_type:
</span><span class="cx">     case op_mov:
</span><del>-    case op_captured_mov:
</del><span class="cx">     case op_check_has_instance:
</span><span class="cx">     case op_instanceof:
</span><span class="cx">     case op_is_undefined:
</span><span class="lines">@@ -232,7 +231,6 @@
</span><span class="cx"> 
</span><span class="cx">     case op_new_regexp: 
</span><span class="cx">     case op_create_lexical_environment:
</span><del>-    case op_tear_off_lexical_environment:
</del><span class="cx">     case op_new_func:
</span><span class="cx">     case op_new_captured_func:
</span><span class="cx">     case op_new_func_exp:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -848,11 +848,6 @@
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">             return;
</span><span class="cx">         }
</span><del>-
-    case TearOffActivation:
-        read(Variables);
-        write(JSEnvironmentRecord_registers);
-        return;
</del><span class="cx">         
</span><span class="cx">     case TearOffArguments:
</span><span class="cx">         read(Variables);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -138,7 +138,6 @@
</span><span class="cx">     case ToPrimitive:
</span><span class="cx">     case ToString:
</span><span class="cx">     case In:
</span><del>-    case TearOffActivation:
</del><span class="cx">     case PhantomArguments:
</span><span class="cx">     case TearOffArguments:
</span><span class="cx">     case GetMyArgumentsLength:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -1040,14 +1040,6 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        case TearOffActivation: {
-            Node* barrierNode = m_graph.addNode(
-                SpecNone, StoreBarrierWithNullCheck, m_currentNode-&gt;origin, 
-                Edge(node-&gt;child1().node(), UntypedUse));
-            m_insertionSet.insert(m_indexInBlock, barrierNode);
-            break;
-        }
-
</del><span class="cx">         case IsString:
</span><span class="cx">             if (node-&gt;child1()-&gt;shouldSpeculateString()) {
</span><span class="cx">                 m_insertionSet.insertNode(
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -1013,8 +1013,6 @@
</span><span class="cx">     JSLexicalEnvironment* lexicalEnvironment = tryGetActivation(node);
</span><span class="cx">     if (!lexicalEnvironment)
</span><span class="cx">         return 0;
</span><del>-    if (!lexicalEnvironment-&gt;isTornOff())
-        return 0;
</del><span class="cx">     return lexicalEnvironment-&gt;registers();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -263,7 +263,6 @@
</span><span class="cx">     /* epilgoues via TearOffActivation, and all CreateActivation nodes kept alive by */\
</span><span class="cx">     /* being threaded with each other. */\
</span><span class="cx">     macro(CreateActivation, NodeResultJS) \
</span><del>-    macro(TearOffActivation, NodeMustGenerate) \
</del><span class="cx">     \
</span><span class="cx">     /* Nodes used for arguments. Similar to lexical environment support, only it makes even less */\
</span><span class="cx">     /* sense. */\
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -656,7 +656,6 @@
</span><span class="cx">         case CheckCell:
</span><span class="cx">         case CheckBadCell:
</span><span class="cx">         case PutStructure:
</span><del>-        case TearOffActivation:
</del><span class="cx">         case TearOffArguments:
</span><span class="cx">         case CheckArgumentsNotCreated:
</span><span class="cx">         case VariableWatchpoint:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -217,7 +217,6 @@
</span><span class="cx">     case MakeRope:
</span><span class="cx">     case In:
</span><span class="cx">     case CreateActivation:
</span><del>-    case TearOffActivation:
</del><span class="cx">     case CreateArguments:
</span><span class="cx">     case PhantomArguments:
</span><span class="cx">     case TearOffArguments:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -4170,22 +4170,12 @@
</span><span class="cx">         break;
</span><span class="cx"> 
</span><span class="cx">     case CreateActivation: {
</span><del>-        JSValueOperand value(this, node-&gt;child1());
-        GPRTemporary result(this, Reuse, value, PayloadWord);
-        
-        GPRReg valueTagGPR = value.tagGPR();
-        GPRReg valuePayloadGPR = value.payloadGPR();
</del><ins>+        GPRTemporary result(this);
</ins><span class="cx">         GPRReg resultGPR = result.gpr();
</span><ins>+
+        flushRegisters();
+        callOperation(operationCreateActivation, resultGPR, framePointerOffsetToGetActivationRegisters());
</ins><span class="cx">         
</span><del>-        m_jit.move(valuePayloadGPR, resultGPR);
-        
-        JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
-        
-        addSlowPathGenerator(
-            slowPathCall(
-                notCreated, this, operationCreateActivation, resultGPR,
-                framePointerOffsetToGetActivationRegisters()));
-        
</del><span class="cx">         cellResult(resultGPR, node);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="lines">@@ -4242,45 +4232,6 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">         
</span><del>-    case TearOffActivation: {
-        JSValueOperand activationValue(this, node-&gt;child1());
-        GPRTemporary scratch(this);
-        
-        GPRReg activationValueTagGPR = activationValue.tagGPR();
-        GPRReg activationValuePayloadGPR = activationValue.payloadGPR();
-        GPRReg scratchGPR = scratch.gpr();
-
-        JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, activationValueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
-
-        SymbolTable* symbolTable = m_jit.symbolTableFor(node-&gt;origin.semantic);
-        int registersOffset = JSLexicalEnvironment::registersOffset(symbolTable);
-
-        int bytecodeCaptureStart = symbolTable-&gt;captureStart();
-        int machineCaptureStart = m_jit.graph().m_machineCaptureStart;
-        for (int i = symbolTable-&gt;captureCount(); i--;) {
-            m_jit.loadPtr(
-                JITCompiler::Address(
-                    GPRInfo::callFrameRegister, (machineCaptureStart - i) * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
-                scratchGPR);
-            m_jit.storePtr(
-                scratchGPR, JITCompiler::Address(
-                    activationValuePayloadGPR, registersOffset + (bytecodeCaptureStart - i) * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
-            m_jit.loadPtr(
-                JITCompiler::Address(
-                    GPRInfo::callFrameRegister, (machineCaptureStart - i) * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
-                scratchGPR);
-            m_jit.storePtr(
-                scratchGPR, JITCompiler::Address(
-                    activationValuePayloadGPR, registersOffset + (bytecodeCaptureStart - i) * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
-        }
-        m_jit.addPtr(TrustedImm32(registersOffset), activationValuePayloadGPR, scratchGPR);
-        m_jit.storePtr(scratchGPR, JITCompiler::Address(activationValuePayloadGPR, JSLexicalEnvironment::offsetOfRegisters()));
-        
-        notCreated.link(&amp;m_jit);
-        noResult(node);
-        break;
-    }
-        
</del><span class="cx">     case TearOffArguments: {
</span><span class="cx">         JSValueOperand unmodifiedArgumentsValue(this, node-&gt;child1());
</span><span class="cx">         JSValueOperand activationValue(this, node-&gt;child2());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -4236,21 +4236,12 @@
</span><span class="cx">     case CreateActivation: {
</span><span class="cx">         DFG_ASSERT(m_jit.graph(), node, !node-&gt;origin.semantic.inlineCallFrame);
</span><span class="cx">         
</span><del>-        JSValueOperand value(this, node-&gt;child1());
-        GPRTemporary result(this, Reuse, value);
-        
-        GPRReg valueGPR = value.gpr();
</del><ins>+        GPRTemporary result(this);
</ins><span class="cx">         GPRReg resultGPR = result.gpr();
</span><del>-        
-        m_jit.move(valueGPR, resultGPR);
-        
-        JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR);
-        
-        addSlowPathGenerator(
-            slowPathCall(
-                notCreated, this, operationCreateActivation, resultGPR,
-                framePointerOffsetToGetActivationRegisters()));
-        
</del><ins>+    
+        flushRegisters();
+        callOperation(operationCreateActivation, resultGPR, framePointerOffsetToGetActivationRegisters());
+
</ins><span class="cx">         cellResult(resultGPR, node);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="lines">@@ -4306,41 +4297,6 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case TearOffActivation: {
-        DFG_ASSERT(m_jit.graph(), node, !node-&gt;origin.semantic.inlineCallFrame);
-
-        JSValueOperand activationValue(this, node-&gt;child1());
-        GPRTemporary scratch(this);
-        GPRReg activationValueGPR = activationValue.gpr();
-        GPRReg scratchGPR = scratch.gpr();
-
-        JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, activationValueGPR);
-
-        SymbolTable* symbolTable = m_jit.symbolTableFor(node-&gt;origin.semantic);
-        int registersOffset = JSLexicalEnvironment::registersOffset(symbolTable);
-
-        int bytecodeCaptureStart = symbolTable-&gt;captureStart();
-        int machineCaptureStart = m_jit.graph().m_machineCaptureStart;
-        for (int i = symbolTable-&gt;captureCount(); i--;) {
-            m_jit.load64(
-                JITCompiler::Address(
-                    GPRInfo::callFrameRegister,
-                    (machineCaptureStart - i) * sizeof(Register)),
-                scratchGPR);
-            m_jit.store64(
-                scratchGPR,
-                JITCompiler::Address(
-                    activationValueGPR,
-                    registersOffset + (bytecodeCaptureStart - i) * sizeof(Register)));
-        }
-        m_jit.addPtr(TrustedImm32(registersOffset), activationValueGPR, scratchGPR);
-        m_jit.storePtr(scratchGPR, JITCompiler::Address(activationValueGPR, JSLexicalEnvironment::offsetOfRegisters()));
-
-        notCreated.link(&amp;m_jit);
-        noResult(node);
-        break;
-    }
-
</del><span class="cx">     case TearOffArguments: {
</span><span class="cx">         JSValueOperand unmodifiedArgumentsValue(this, node-&gt;child1());
</span><span class="cx">         JSValueOperand activationValue(this, node-&gt;child2());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -369,7 +369,7 @@
</span><span class="cx">     
</span><span class="cx">     if (graph.m_codeBlock-&gt;needsActivation()) {
</span><span class="cx">         // Need this because although we also don't support
</span><del>-        // CreateActivation/TearOffActivation, we might not see those nodes in case of
</del><ins>+        // CreateActivation, we might not see those nodes in case of
</ins><span class="cx">         // OSR entry.
</span><span class="cx">         // FIXME: Support activations.
</span><span class="cx">         // https://bugs.webkit.org/show_bug.cgi?id=129576
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterInterpretercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -439,8 +439,6 @@
</span><span class="cx"> {
</span><span class="cx">     CallFrame* callFrame = visitor-&gt;callFrame();
</span><span class="cx">     CodeBlock* codeBlock = visitor-&gt;codeBlock();
</span><del>-    JSScope* scope = callFrame-&gt;scope();
-
</del><span class="cx">     if (Debugger* debugger = callFrame-&gt;vmEntryGlobalObject()-&gt;debugger()) {
</span><span class="cx">         ClearExceptionScope scope(&amp;callFrame-&gt;vm());
</span><span class="cx">         if (jsDynamicCast&lt;JSFunction*&gt;(callFrame-&gt;callee()))
</span><span class="lines">@@ -455,15 +453,6 @@
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx">         RELEASE_ASSERT(!visitor-&gt;isInlinedFrame());
</span><span class="cx"> #endif
</span><del>-        lexicalEnvironment = callFrame-&gt;uncheckedActivation();
-        // Protect against the lexical environment not being created, or the variable still being
-        // initialized to Undefined inside op_enter.
-        if (lexicalEnvironment &amp;&amp; lexicalEnvironment.isCell()) {
-            JSLexicalEnvironment* activationObject = jsCast&lt;JSLexicalEnvironment*&gt;(lexicalEnvironment);
-            // Protect against throwing exceptions after tear-off.
-            if (!activationObject-&gt;isTornOff())
-                activationObject-&gt;tearOff(*scope-&gt;vm());
-        }
</del><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (codeBlock-&gt;codeType() == FunctionCode &amp;&amp; codeBlock-&gt;usesArguments()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/jit/JIT.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -247,7 +247,6 @@
</span><span class="cx">         DEFINE_OP(op_loop_hint)
</span><span class="cx">         DEFINE_OP(op_lshift)
</span><span class="cx">         DEFINE_OP(op_mod)
</span><del>-        DEFINE_OP(op_captured_mov)
</del><span class="cx">         DEFINE_OP(op_mov)
</span><span class="cx">         DEFINE_OP(op_mul)
</span><span class="cx">         DEFINE_OP(op_negate)
</span><span class="lines">@@ -296,7 +295,6 @@
</span><span class="cx">         DEFINE_OP(op_switch_char)
</span><span class="cx">         DEFINE_OP(op_switch_imm)
</span><span class="cx">         DEFINE_OP(op_switch_string)
</span><del>-        DEFINE_OP(op_tear_off_lexical_environment)
</del><span class="cx">         DEFINE_OP(op_tear_off_arguments)
</span><span class="cx">         DEFINE_OP(op_throw)
</span><span class="cx">         DEFINE_OP(op_throw_static_error)
</span><span class="lines">@@ -384,7 +382,6 @@
</span><span class="cx">         DEFINE_SLOWCASE_OP(op_construct)
</span><span class="cx">         DEFINE_SLOWCASE_OP(op_to_this)
</span><span class="cx">         DEFINE_SLOWCASE_OP(op_create_this)
</span><del>-        DEFINE_SLOWCASE_OP(op_captured_mov)
</del><span class="cx">         DEFINE_SLOWCASE_OP(op_div)
</span><span class="cx">         DEFINE_SLOWCASE_OP(op_eq)
</span><span class="cx">         DEFINE_SLOWCASE_OP(op_get_callee)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.h (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.h        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/jit/JIT.h        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -463,7 +463,6 @@
</span><span class="cx">         void emit_op_call_eval(Instruction*);
</span><span class="cx">         void emit_op_call_varargs(Instruction*);
</span><span class="cx">         void emit_op_construct_varargs(Instruction*);
</span><del>-        void emit_op_captured_mov(Instruction*);
</del><span class="cx">         void emit_op_catch(Instruction*);
</span><span class="cx">         void emit_op_construct(Instruction*);
</span><span class="cx">         void emit_op_get_callee(Instruction*);
</span><span class="lines">@@ -543,7 +542,6 @@
</span><span class="cx">         void emit_op_switch_char(Instruction*);
</span><span class="cx">         void emit_op_switch_imm(Instruction*);
</span><span class="cx">         void emit_op_switch_string(Instruction*);
</span><del>-        void emit_op_tear_off_lexical_environment(Instruction*);
</del><span class="cx">         void emit_op_tear_off_arguments(Instruction*);
</span><span class="cx">         void emit_op_throw(Instruction*);
</span><span class="cx">         void emit_op_throw_static_error(Instruction*);
</span><span class="lines">@@ -570,7 +568,6 @@
</span><span class="cx">         void emitSlow_op_call_eval(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span><span class="cx">         void emitSlow_op_call_varargs(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span><span class="cx">         void emitSlow_op_construct_varargs(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span><del>-        void emitSlow_op_captured_mov(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</del><span class="cx">         void emitSlow_op_construct(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span><span class="cx">         void emitSlow_op_to_this(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span><span class="cx">         void emitSlow_op_create_this(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span><span class="lines">@@ -640,7 +637,7 @@
</span><span class="cx">         void emitNotifyWrite(RegisterID tag, RegisterID payload, RegisterID scratch, VariableWatchpointSet*);
</span><span class="cx"> #endif
</span><span class="cx">         void emitPutGlobalVar(uintptr_t operand, int value, VariableWatchpointSet*);
</span><del>-        void emitPutClosureVar(int scope, uintptr_t operand, int value);
</del><ins>+        void emitPutClosureVar(int scope, uintptr_t operand, int value, VariableWatchpointSet*);
</ins><span class="cx"> 
</span><span class="cx">         void emitInitRegister(int dst);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -63,16 +63,7 @@
</span><span class="cx">     emitPutVirtualRegister(dst);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JIT::emit_op_captured_mov(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-    int src = currentInstruction[2].u.operand;
</del><span class="cx"> 
</span><del>-    emitGetVirtualRegister(src, regT0);
-    emitNotifyWrite(regT0, regT1, currentInstruction[3].u.watchpointSet);
-    emitPutVirtualRegister(dst);
-}
-
</del><span class="cx"> void JIT::emit_op_end(Instruction* currentInstruction)
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(returnValueGPR != callFrameRegister);
</span><span class="lines">@@ -233,15 +224,6 @@
</span><span class="cx">     emitPutVirtualRegister(dst);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JIT::emit_op_tear_off_lexical_environment(Instruction* currentInstruction)
-{
-    int lexicalEnvironment = currentInstruction[1].u.operand;
-    Jump activationNotCreated = branchTest64(Zero, addressFor(lexicalEnvironment));
-    emitGetVirtualRegister(lexicalEnvironment, regT0);
-    callOperation(operationTearOffActivation, regT0);
-    activationNotCreated.link(this);
-}
-
</del><span class="cx"> void JIT::emit_op_tear_off_arguments(Instruction* currentInstruction)
</span><span class="cx"> {
</span><span class="cx">     int arguments = currentInstruction[1].u.operand;
</span><span class="lines">@@ -1100,19 +1082,6 @@
</span><span class="cx">     callOperation(operationNewArrayBufferWithProfile, dst, currentInstruction[4].u.arrayAllocationProfile, values, size);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JIT::emitSlow_op_captured_mov(Instruction* currentInstruction, Vector&lt;SlowCaseEntry&gt;::iterator&amp; iter)
-{
-    VariableWatchpointSet* set = currentInstruction[3].u.watchpointSet;
-    if (!set || set-&gt;state() == IsInvalidated)
-        return;
-#if USE(JSVALUE32_64)
-    linkSlowCase(iter);
-#endif
-    linkSlowCase(iter);
-    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_captured_mov);
-    slowPathCall.call();
-}
-
</del><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx"> void JIT::emit_op_get_enumerable_length(Instruction* currentInstruction)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodes32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -153,16 +153,6 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JIT::emit_op_captured_mov(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-    int src = currentInstruction[2].u.operand;
-
-    emitLoad(src, regT1, regT0);
-    emitNotifyWrite(regT1, regT0, regT2, currentInstruction[3].u.watchpointSet);
-    emitStore(dst, regT1, regT0);
-}
-
</del><span class="cx"> void JIT::emit_op_end(Instruction* currentInstruction)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(returnValueGPR != callFrameRegister);
</span><span class="lines">@@ -350,15 +340,6 @@
</span><span class="cx">     emitStoreBool(dst, regT0);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JIT::emit_op_tear_off_lexical_environment(Instruction* currentInstruction)
-{
-    int lexicalEnvironment = currentInstruction[1].u.operand;
-    Jump activationNotCreated = branch32(Equal, tagFor(lexicalEnvironment), TrustedImm32(JSValue::EmptyValueTag));
-    emitLoadPayload(lexicalEnvironment, regT0);
-    callOperation(operationTearOffActivation, regT0);
-    activationNotCreated.link(this);
-}
-
</del><span class="cx"> void JIT::emit_op_tear_off_arguments(Instruction* currentInstruction)
</span><span class="cx"> {
</span><span class="cx">     VirtualRegister arguments = VirtualRegister(currentInstruction[1].u.operand);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -1589,16 +1589,7 @@
</span><span class="cx"> 
</span><span class="cx">     return JSValue::encode(result);
</span><span class="cx"> }
</span><del>-    
-void JIT_OPERATION operationTearOffActivation(ExecState* exec, JSCell* activationCell)
-{
-    VM&amp; vm = exec-&gt;vm();
-    NativeCallFrameTracer tracer(&amp;vm, exec);
</del><span class="cx"> 
</span><del>-    ASSERT(exec-&gt;codeBlock()-&gt;needsActivation());
-    jsCast&lt;JSLexicalEnvironment*&gt;(activationCell)-&gt;tearOff(vm);
-}
-
</del><span class="cx"> void JIT_OPERATION operationTearOffArguments(ExecState* exec, JSCell* argumentsCell, JSCell* activationCell)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(exec-&gt;codeBlock()-&gt;usesArguments());
</span><span class="lines">@@ -1771,7 +1762,13 @@
</span><span class="cx">     JSObject* scope = jsCast&lt;JSObject*&gt;(exec-&gt;uncheckedR(pc[1].u.operand).jsValue());
</span><span class="cx">     JSValue value = exec-&gt;r(pc[3].u.operand).jsValue();
</span><span class="cx">     ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
</span><del>-
</del><ins>+    if (modeAndType.type() == LocalClosureVar) {
+        JSLexicalEnvironment* environment = jsCast&lt;JSLexicalEnvironment*&gt;(scope);
+        environment-&gt;registerAt(pc[6].u.operand).set(vm, environment, value);
+        if (VariableWatchpointSet* set = pc[5].u.watchpointSet)
+            set-&gt;notifyWrite(vm, value, &quot;Executed op_put_scope&lt;LocalClosureVar&gt;&quot;);
+        return;
+    }
</ins><span class="cx">     if (modeAndType.mode() == ThrowIfNotFound &amp;&amp; !scope-&gt;hasProperty(exec, ident)) {
</span><span class="cx">         exec-&gt;vm().throwException(exec, createUndefinedVariableError(exec, ident));
</span><span class="cx">         return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.h (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.h        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.h        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -292,7 +292,6 @@
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationGetByValString(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationHasIndexedPropertyDefault(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationHasIndexedPropertyGeneric(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
</span><del>-void JIT_OPERATION operationTearOffActivation(ExecState*, JSCell*) WTF_INTERNAL;
</del><span class="cx"> void JIT_OPERATION operationTearOffArguments(ExecState*, JSCell*, JSCell*) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationDeleteById(ExecState*, EncodedJSValue base, const Identifier*) WTF_INTERNAL;
</span><span class="cx"> JSCell* JIT_OPERATION operationGetPNames(ExecState*, JSObject*) WTF_INTERNAL;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITPropertyAccesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -621,6 +621,8 @@
</span><span class="cx">     case Dynamic:
</span><span class="cx">         addSlowCase(jump());
</span><span class="cx">         break;
</span><ins>+    case LocalClosureVar:
+        RELEASE_ASSERT_NOT_REACHED();
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -691,6 +693,8 @@
</span><span class="cx">     case Dynamic:
</span><span class="cx">         addSlowCase(jump());
</span><span class="cx">         break;
</span><ins>+    case LocalClosureVar:
+        RELEASE_ASSERT_NOT_REACHED();
</ins><span class="cx">     }
</span><span class="cx">     emitPutVirtualRegister(dst);
</span><span class="cx">     emitValueProfilingSite();
</span><span class="lines">@@ -738,11 +742,12 @@
</span><span class="cx">     storePtr(regT0, reinterpret_cast&lt;void*&gt;(operand));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JIT::emitPutClosureVar(int scope, uintptr_t operand, int value)
</del><ins>+void JIT::emitPutClosureVar(int scope, uintptr_t operand, int value, VariableWatchpointSet* set)
</ins><span class="cx"> {
</span><span class="cx">     emitGetVirtualRegister(value, regT1);
</span><span class="cx">     emitGetVirtualRegister(scope, regT0);
</span><span class="cx">     loadPtr(Address(regT0, JSEnvironmentRecord::offsetOfRegisters()), regT0);
</span><ins>+    emitNotifyWrite(regT1, regT2, set);
</ins><span class="cx">     storePtr(regT1, Address(regT0, operand * sizeof(Register)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -767,11 +772,12 @@
</span><span class="cx">         emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
</span><span class="cx">         emitPutGlobalVar(*operandSlot, value, currentInstruction[5].u.watchpointSet);
</span><span class="cx">         break;
</span><ins>+    case LocalClosureVar:
</ins><span class="cx">     case ClosureVar:
</span><span class="cx">     case ClosureVarWithVarInjectionChecks:
</span><span class="cx">         emitWriteBarrier(scope, value, ShouldFilterValue);
</span><span class="cx">         emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
</span><del>-        emitPutClosureVar(scope, *operandSlot, value);
</del><ins>+        emitPutClosureVar(scope, *operandSlot, value, currentInstruction[5].u.watchpointSet);
</ins><span class="cx">         break;
</span><span class="cx">     case Dynamic:
</span><span class="cx">         addSlowCase(jump());
</span><span class="lines">@@ -783,9 +789,9 @@
</span><span class="cx"> {
</span><span class="cx">     ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type();
</span><span class="cx">     unsigned linkCount = 0;
</span><del>-    if (resolveType != GlobalVar &amp;&amp; resolveType != ClosureVar)
</del><ins>+    if (resolveType != GlobalVar &amp;&amp; resolveType != ClosureVar &amp;&amp; resolveType != LocalClosureVar)
</ins><span class="cx">         linkCount++;
</span><del>-    if ((resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks)
</del><ins>+    if ((resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks || resolveType == LocalClosureVar)
</ins><span class="cx">         &amp;&amp; currentInstruction[5].u.watchpointSet-&gt;state() != IsInvalidated)
</span><span class="cx">         linkCount++;
</span><span class="cx">     if (resolveType == GlobalProperty || resolveType == GlobalPropertyWithVarInjectionChecks)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITPropertyAccess32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -645,6 +645,8 @@
</span><span class="cx">     case Dynamic:
</span><span class="cx">         addSlowCase(jump());
</span><span class="cx">         break;
</span><ins>+    case LocalClosureVar:
+        RELEASE_ASSERT_NOT_REACHED();
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -716,6 +718,8 @@
</span><span class="cx">     case Dynamic:
</span><span class="cx">         addSlowCase(jump());
</span><span class="cx">         break;
</span><ins>+    case LocalClosureVar:
+        RELEASE_ASSERT_NOT_REACHED();
</ins><span class="cx">     }
</span><span class="cx">     emitValueProfilingSite();
</span><span class="cx">     emitStore(dst, regT1, regT0);
</span><span class="lines">@@ -769,10 +773,11 @@
</span><span class="cx">     store32(regT0, reinterpret_cast&lt;char*&gt;(operand) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JIT::emitPutClosureVar(int scope, uintptr_t operand, int value)
</del><ins>+void JIT::emitPutClosureVar(int scope, uintptr_t operand, int value, VariableWatchpointSet* set)
</ins><span class="cx"> {
</span><span class="cx">     emitLoad(value, regT3, regT2);
</span><span class="cx">     emitLoad(scope, regT1, regT0);
</span><ins>+    emitNotifyWrite(regT3, regT2, regT4, set);
</ins><span class="cx">     loadPtr(Address(regT0, JSEnvironmentRecord::offsetOfRegisters()), regT0);
</span><span class="cx">     store32(regT3, Address(regT0, operand * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
</span><span class="cx">     store32(regT2, Address(regT0, operand * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
</span><span class="lines">@@ -799,11 +804,12 @@
</span><span class="cx">         emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
</span><span class="cx">         emitPutGlobalVar(*operandSlot, value, currentInstruction[5].u.watchpointSet);
</span><span class="cx">         break;
</span><ins>+    case LocalClosureVar:
</ins><span class="cx">     case ClosureVar:
</span><span class="cx">     case ClosureVarWithVarInjectionChecks:
</span><span class="cx">         emitWriteBarrier(scope, value, ShouldFilterValue);
</span><span class="cx">         emitVarInjectionCheck(needsVarInjectionChecks(resolveType));
</span><del>-        emitPutClosureVar(scope, *operandSlot, value);
</del><ins>+        emitPutClosureVar(scope, *operandSlot, value, currentInstruction[5].u.watchpointSet);
</ins><span class="cx">         break;
</span><span class="cx">     case Dynamic:
</span><span class="cx">         addSlowCase(jump());
</span><span class="lines">@@ -815,9 +821,9 @@
</span><span class="cx"> {
</span><span class="cx">     ResolveType resolveType = ResolveModeAndType(currentInstruction[4].u.operand).type();
</span><span class="cx">     unsigned linkCount = 0;
</span><del>-    if (resolveType != GlobalVar &amp;&amp; resolveType != ClosureVar)
</del><ins>+    if (resolveType != GlobalVar &amp;&amp; resolveType != ClosureVar &amp;&amp; resolveType != LocalClosureVar)
</ins><span class="cx">         linkCount++;
</span><del>-    if ((resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks)
</del><ins>+    if ((resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks || resolveType == LocalClosureVar)
</ins><span class="cx">         &amp;&amp; currentInstruction[5].u.watchpointSet-&gt;state() != IsInvalidated)
</span><span class="cx">         linkCount += 2;
</span><span class="cx">     if (!linkCount)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntData.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntData.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/llint/LLIntData.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -143,13 +143,14 @@
</span><span class="cx">     ASSERT(EvalCode == 1);
</span><span class="cx">     ASSERT(FunctionCode == 2);
</span><span class="cx"> 
</span><del>-    ASSERT(GlobalProperty == 0);
-    ASSERT(GlobalVar == 1);
-    ASSERT(ClosureVar == 2);
-    ASSERT(GlobalPropertyWithVarInjectionChecks == 3);
-    ASSERT(GlobalVarWithVarInjectionChecks == 4);
-    ASSERT(ClosureVarWithVarInjectionChecks == 5);
-    ASSERT(Dynamic == 6);
</del><ins>+    static_assert(GlobalProperty == 0, &quot;LLInt assumes GlobalProperty ResultType is == 0&quot;);
+    static_assert(GlobalVar == 1, &quot;LLInt assumes GlobalVar ResultType is == 1&quot;);
+    static_assert(ClosureVar == 2, &quot;LLInt assumes ClosureVar ResultType is == 2&quot;);
+    static_assert(LocalClosureVar == 3, &quot;LLInt assumes LocalClosureVar ResultType is == 3&quot;);
+    static_assert(GlobalPropertyWithVarInjectionChecks == 4, &quot;LLInt assumes GlobalPropertyWithVarInjectionChecks ResultType is == 4&quot;);
+    static_assert(GlobalVarWithVarInjectionChecks == 5, &quot;LLInt assumes GlobalVarWithVarInjectionChecks ResultType is == 5&quot;);
+    static_assert(ClosureVarWithVarInjectionChecks == 6, &quot;LLInt assumes ClosureVarWithVarInjectionChecks ResultType is == 6&quot;);
+    static_assert(Dynamic == 7, &quot;LLInt assumes Dynamic ResultType is == 7&quot;);
</ins><span class="cx">     
</span><span class="cx">     ASSERT(ResolveModeAndType::mask == 0xffff);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -1245,14 +1245,6 @@
</span><span class="cx">     LLINT_CALL_RETURN(exec, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-LLINT_SLOW_PATH_DECL(slow_path_tear_off_lexical_environment)
-{
-    LLINT_BEGIN();
-    ASSERT(exec-&gt;codeBlock()-&gt;needsActivation());
-    jsCast&lt;JSLexicalEnvironment*&gt;(LLINT_OP(1).jsValue())-&gt;tearOff(vm);
-    LLINT_END();
-}
-
</del><span class="cx"> LLINT_SLOW_PATH_DECL(slow_path_tear_off_arguments)
</span><span class="cx"> {
</span><span class="cx">     LLINT_BEGIN();
</span><span class="lines">@@ -1411,6 +1403,13 @@
</span><span class="cx">     JSObject* scope = jsCast&lt;JSObject*&gt;(LLINT_OP(1).jsValue());
</span><span class="cx">     JSValue value = LLINT_OP_C(3).jsValue();
</span><span class="cx">     ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
</span><ins>+    if (modeAndType.type() == LocalClosureVar) {
+        JSLexicalEnvironment* environment = jsCast&lt;JSLexicalEnvironment*&gt;(scope);
+        environment-&gt;registerAt(pc[6].u.operand).set(vm, environment, value);
+        if (VariableWatchpointSet* set = pc[5].u.watchpointSet)
+            set-&gt;notifyWrite(vm, value, &quot;Executed op_put_scope&lt;LocalClosureVar&gt;&quot;);
+        LLINT_END();
+    }
</ins><span class="cx"> 
</span><span class="cx">     if (modeAndType.mode() == ThrowIfNotFound &amp;&amp; !scope-&gt;hasProperty(exec, ident))
</span><span class="cx">         LLINT_THROW(createUndefinedVariableError(exec, ident));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -102,7 +102,6 @@
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_call_varargs);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_construct_varargs);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_call_eval);
</span><del>-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_tear_off_lexical_environment);
</del><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_tear_off_arguments);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_strcat);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_to_primitive);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -183,10 +183,11 @@
</span><span class="cx"> const GlobalProperty = 0
</span><span class="cx"> const GlobalVar = 1
</span><span class="cx"> const ClosureVar = 2
</span><del>-const GlobalPropertyWithVarInjectionChecks = 3
-const GlobalVarWithVarInjectionChecks = 4
-const ClosureVarWithVarInjectionChecks = 5
-const Dynamic = 6
</del><ins>+const LocalClosureVar = 3
+const GlobalPropertyWithVarInjectionChecks = 4
+const GlobalVarWithVarInjectionChecks = 5
+const ClosureVarWithVarInjectionChecks = 6
+const Dynamic = 7
</ins><span class="cx"> 
</span><span class="cx"> const ResolveModeMask = 0xffff
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -824,24 +824,6 @@
</span><span class="cx"> .done:
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-_llint_op_captured_mov:
-    traceExecution()
-    loadi 8[PC], t1
-    loadConstantOrVariable(t1, t2, t3)
-    loadpFromInstruction(3, t0)
-    btpz t0, .opCapturedMovReady
-    notifyWrite(t0, t2, t3, t1, .opCapturedMovSlow)
-.opCapturedMovReady:
-    loadi 4[PC], t0
-    storei t2, TagOffset[cfr, t0, 8]
-    storei t3, PayloadOffset[cfr, t0, 8]
-    dispatch(4)
-
-.opCapturedMovSlow:
-    callSlowPath(_slow_path_captured_mov)
-    dispatch(4)
-
-
</del><span class="cx"> _llint_op_not:
</span><span class="cx">     traceExecution()
</span><span class="cx">     loadi 8[PC], t0
</span><span class="lines">@@ -1970,16 +1952,6 @@
</span><span class="cx">     slowPathForCall(slowPath)
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-
-_llint_op_tear_off_lexical_environment:
-    traceExecution()
-    loadi 4[PC], t0
-    bieq TagOffset[cfr, t0, 8], EmptyValueTag, .opTearOffActivationNotCreated
-    callSlowPath(_llint_slow_path_tear_off_lexical_environment)
-.opTearOffActivationNotCreated:
-    dispatch(2)
-
-
</del><span class="cx"> _llint_op_tear_off_arguments:
</span><span class="cx">     traceExecution()
</span><span class="cx">     loadi 4[PC], t0
</span><span class="lines">@@ -2370,7 +2342,14 @@
</span><span class="cx">     loadisFromInstruction(4, t0)
</span><span class="cx">     andi ResolveModeMask, t0
</span><span class="cx"> 
</span><del>-#pGlobalProperty:
</del><ins>+#pLocalClosureVar:
+    bineq t0, LocalClosureVar, .pGlobalProperty
+    writeBarrierOnOperands(1, 3)
+    loadVariable(1, t2, t1, t0)
+    putClosureVar()
+    dispatch(7)
+
+.pGlobalProperty:
</ins><span class="cx">     bineq t0, GlobalProperty, .pGlobalVar
</span><span class="cx">     writeBarrierOnOperands(1, 3)
</span><span class="cx">     loadWithStructureCheck(1, .pDynamic)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -707,23 +707,6 @@
</span><span class="cx"> .done:
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-_llint_op_captured_mov:
-    traceExecution()
-    loadisFromInstruction(2, t1)
-    loadConstantOrVariable(t1, t2)
-    loadpFromInstruction(3, t0)
-    btpz t0, .opCapturedMovReady
-    notifyWrite(t0, t2, t1, .opCapturedMovSlow)
-.opCapturedMovReady:
-    loadisFromInstruction(1, t0)
-    storeq t2, [cfr, t0, 8]
-    dispatch(4)
-
-.opCapturedMovSlow:
-    callSlowPath(_slow_path_captured_mov)
-    dispatch(4)
-
-
</del><span class="cx"> _llint_op_not:
</span><span class="cx">     traceExecution()
</span><span class="cx">     loadisFromInstruction(2, t0)
</span><span class="lines">@@ -1827,16 +1810,6 @@
</span><span class="cx">     slowPathForCall(slowPath)
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-
-_llint_op_tear_off_lexical_environment:
-    traceExecution()
-    loadisFromInstruction(1, t0)
-    btqz [cfr, t0, 8], .opTearOffActivationNotCreated
-    callSlowPath(_llint_slow_path_tear_off_lexical_environment)
-.opTearOffActivationNotCreated:
-    dispatch(2)
-
-
</del><span class="cx"> _llint_op_tear_off_arguments:
</span><span class="cx">     traceExecution()
</span><span class="cx">     loadisFromInstruction(1, t0)
</span><span class="lines">@@ -2189,13 +2162,29 @@
</span><span class="cx">     storeq t2, [t0, t1, 8]
</span><span class="cx"> end
</span><span class="cx"> 
</span><ins>+macro putLocalClosureVar()
+    loadisFromInstruction(3, t1)
+    loadConstantOrVariable(t1, t2)
+    notifyWrite(t0, t2, t1, .pDynamic)
+    loadp JSEnvironmentRecord::m_registers[t0], t0
+    loadisFromInstruction(6, t1)
+    storeq t2, [t0, t1, 8]
+end
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx"> _llint_op_put_to_scope:
</span><span class="cx">     traceExecution()
</span><span class="cx">     loadisFromInstruction(4, t0)
</span><span class="cx">     andi ResolveModeMask, t0
</span><span class="cx"> 
</span><del>-#pGlobalProperty:
</del><ins>+#pLocalClosureVar:
+    bineq t0, LocalClosureVar, .pGlobalProperty
+    writeBarrierOnOperands(1, 3)
+    loadVariable(1, t0)
+    putLocalClosureVar()
+    dispatch(7)
+
+.pGlobalProperty:
</ins><span class="cx">     bineq t0, GlobalProperty, .pGlobalVar
</span><span class="cx">     writeBarrierOnOperands(1, 3)
</span><span class="cx">     loadWithStructureCheck(1, .pDynamic)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArgumentscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Arguments.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Arguments.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/runtime/Arguments.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -384,20 +384,11 @@
</span><span class="cx">     allocateRegisterArray(callFrame-&gt;vm());
</span><span class="cx">     m_registers = m_registerArray.get() - CallFrame::offsetFor(1) - 1;
</span><span class="cx"> 
</span><del>-    // If we have a captured argument that logically aliases lexical environment storage,
-    // but we optimize away the lexicalEnvironment, the argument needs to tear off into
-    // our storage. The simplest way to do this is to revert it to Normal status.
-    if (m_slowArgumentData &amp;&amp; !m_lexicalEnvironment) {
-        for (size_t i = 0; i &lt; m_numArguments; ++i) {
-            if (m_slowArgumentData-&gt;slowArguments()[i].status != SlowArgument::Captured)
-                continue;
-            m_slowArgumentData-&gt;slowArguments()[i].status = SlowArgument::Normal;
-            m_slowArgumentData-&gt;slowArguments()[i].index = CallFrame::argumentOffset(i);
-        }
-    }
-
-    for (size_t i = 0; i &lt; m_numArguments; ++i)
</del><ins>+    for (size_t i = 0; i &lt; m_numArguments; ++i) {
+        if (m_slowArgumentData &amp;&amp; m_slowArgumentData-&gt;slowArguments()[i].status == SlowArgument::Captured)
+            continue;
</ins><span class="cx">         trySetArgument(callFrame-&gt;vm(), i, callFrame-&gt;argumentAfterCapture(i));
</span><ins>+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Arguments::didTearOffActivation(ExecState* exec, JSLexicalEnvironment* lexicalEnvironment)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArgumentsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Arguments.h (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Arguments.h        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/runtime/Arguments.h        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -270,10 +270,13 @@
</span><span class="cx">         return m_registers[CallFrame::argumentOffset(argument)];
</span><span class="cx"> 
</span><span class="cx">     int index = m_slowArgumentData-&gt;slowArguments()[argument].index;
</span><del>-    if (!m_lexicalEnvironment || m_slowArgumentData-&gt;slowArguments()[argument].status != SlowArgument::Captured)
</del><ins>+    if (m_slowArgumentData-&gt;slowArguments()[argument].status != SlowArgument::Captured)
</ins><span class="cx">         return m_registers[index];
</span><span class="cx"> 
</span><del>-    return m_lexicalEnvironment-&gt;registerAt(index - m_slowArgumentData-&gt;bytecodeToMachineCaptureOffset());
</del><ins>+    JSLexicalEnvironment* lexicalEnvironment = m_lexicalEnvironment.get();
+    if (!lexicalEnvironment)
+        lexicalEnvironment = CallFrame::create(reinterpret_cast&lt;Register*&gt;(m_registers))-&gt;lexicalEnvironment();
+    return lexicalEnvironment-&gt;registerAt(index - m_slowArgumentData-&gt;bytecodeToMachineCaptureOffset());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline void Arguments::finishCreation(CallFrame* callFrame, ArgumentsMode mode)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -262,15 +262,6 @@
</span><span class="cx">     RETURN(v1.toThis(exec, exec-&gt;codeBlock()-&gt;isStrictMode() ? StrictMode : NotStrictMode));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-SLOW_PATH_DECL(slow_path_captured_mov)
-{
-    BEGIN();
-    JSValue value = OP_C(2).jsValue();
-    if (VariableWatchpointSet* set = pc[3].u.watchpointSet)
-        set-&gt;notifyWrite(vm, value, &quot;Executed op_captured_mov&quot;);
-    RETURN(value);
-}
-
</del><span class="cx"> SLOW_PATH_DECL(slow_path_new_captured_func)
</span><span class="cx"> {
</span><span class="cx">     BEGIN();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -190,7 +190,6 @@
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_enter);
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_get_callee);
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_to_this);
</span><del>-SLOW_PATH_HIDDEN_DECL(slow_path_captured_mov);
</del><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_new_captured_func);
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_not);
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_eq);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSLexicalEnvironmentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -46,10 +46,6 @@
</span><span class="cx">     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
</span><span class="cx">     Base::visitChildren(thisObject, visitor);
</span><span class="cx"> 
</span><del>-    // No need to mark our registers if they're still in the JSStack.
-    if (!thisObject-&gt;isTornOff())
-        return;
-
</del><span class="cx">     for (int i = 0; i &lt; thisObject-&gt;symbolTable()-&gt;captureCount(); ++i)
</span><span class="cx">         visitor.append(&amp;thisObject-&gt;storage()[i]);
</span><span class="cx"> }
</span><span class="lines">@@ -61,7 +57,7 @@
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     // Defend against the inspector asking for a var after it has been optimized out.
</span><del>-    if (isTornOff() &amp;&amp; !isValid(entry))
</del><ins>+    if (!isValid(entry))
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     slot.setValue(this, DontEnum, registerAt(entry.getIndex()).get());
</span><span class="lines">@@ -75,7 +71,7 @@
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     // Defend against the inspector asking for a var after it has been optimized out.
</span><del>-    if (isTornOff() &amp;&amp; !isValid(entry))
</del><ins>+    if (!isValid(entry))
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     descriptor.setDescriptor(registerAt(entry.getIndex()).get(), entry.getAttributes());
</span><span class="lines">@@ -100,7 +96,7 @@
</span><span class="cx">             return true;
</span><span class="cx">         }
</span><span class="cx">         // Defend against the inspector asking for a var after it has been optimized out.
</span><del>-        if (isTornOff() &amp;&amp; !isValid(iter-&gt;value))
</del><ins>+        if (!isValid(iter-&gt;value))
</ins><span class="cx">             return false;
</span><span class="cx">         if (VariableWatchpointSet* set = iter-&gt;value.watchpointSet())
</span><span class="cx">             set-&gt;invalidate(VariableWriteFireDetail(this, propertyName)); // Don't mess around - if we had found this statically, we would have invcalidated it.
</span><span class="lines">@@ -114,10 +110,6 @@
</span><span class="cx"> {
</span><span class="cx">     JSLexicalEnvironment* thisObject = jsCast&lt;JSLexicalEnvironment*&gt;(object);
</span><span class="cx"> 
</span><del>-    CallFrame* callFrame = CallFrame::create(reinterpret_cast&lt;Register*&gt;(thisObject-&gt;m_registers));
-    if (shouldIncludeDontEnumProperties(mode) &amp;&amp; !thisObject-&gt;isTornOff() &amp;&amp; (callFrame-&gt;codeBlock()-&gt;usesArguments() || callFrame-&gt;codeBlock()-&gt;usesEval()))
-        propertyNames.add(exec-&gt;propertyNames().arguments);
-
</del><span class="cx">     {
</span><span class="cx">         ConcurrentJITLocker locker(thisObject-&gt;symbolTable()-&gt;m_lock);
</span><span class="cx">         SymbolTable::Map::iterator end = thisObject-&gt;symbolTable()-&gt;end(locker);
</span><span class="lines">@@ -159,15 +151,6 @@
</span><span class="cx"> {
</span><span class="cx">     JSLexicalEnvironment* thisObject = jsCast&lt;JSLexicalEnvironment*&gt;(object);
</span><span class="cx"> 
</span><del>-    if (propertyName == exec-&gt;propertyNames().arguments) {
-        // Defend against the inspector asking for the arguments object after it has been optimized out.
-        CallFrame* callFrame = CallFrame::create(reinterpret_cast&lt;Register*&gt;(thisObject-&gt;m_registers));
-        if (!thisObject-&gt;isTornOff() &amp;&amp; (callFrame-&gt;codeBlock()-&gt;usesArguments() || callFrame-&gt;codeBlock()-&gt;usesEval())) {
-            slot.setCustom(thisObject, DontEnum, argumentsGetter);
-            return true;
-        }
-    }
-
</del><span class="cx">     if (thisObject-&gt;symbolTableGet(propertyName, slot))
</span><span class="cx">         return true;
</span><span class="cx"> 
</span><span class="lines">@@ -218,9 +201,7 @@
</span><span class="cx"> {
</span><span class="cx">     JSLexicalEnvironment* lexicalEnvironment = jsCast&lt;JSLexicalEnvironment*&gt;(slotBase);
</span><span class="cx">     CallFrame* callFrame = CallFrame::create(reinterpret_cast&lt;Register*&gt;(lexicalEnvironment-&gt;m_registers));
</span><del>-    ASSERT(!lexicalEnvironment-&gt;isTornOff() &amp;&amp; (callFrame-&gt;codeBlock()-&gt;usesArguments() || callFrame-&gt;codeBlock()-&gt;usesEval()));
-    if (lexicalEnvironment-&gt;isTornOff() || !(callFrame-&gt;codeBlock()-&gt;usesArguments() || callFrame-&gt;codeBlock()-&gt;usesEval()))
-        return JSValue::encode(jsUndefined());
</del><ins>+    return JSValue::encode(jsUndefined());
</ins><span class="cx"> 
</span><span class="cx">     VirtualRegister argumentsRegister = callFrame-&gt;codeBlock()-&gt;argumentsRegister();
</span><span class="cx">     if (JSValue arguments = callFrame-&gt;uncheckedR(argumentsRegister.offset()).jsValue())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSLexicalEnvironmenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -41,7 +41,7 @@
</span><span class="cx">     
</span><span class="cx"> class JSLexicalEnvironment : public JSEnvironmentRecord {
</span><span class="cx"> private:
</span><del>-    JSLexicalEnvironment(VM&amp;, CallFrame*, Register*, SymbolTable*);
</del><ins>+    JSLexicalEnvironment(VM&amp;, CallFrame*, Register*, CodeBlock*);
</ins><span class="cx">     
</span><span class="cx"> public:
</span><span class="cx">     typedef JSEnvironmentRecord Base;
</span><span class="lines">@@ -56,7 +56,7 @@
</span><span class="cx">                 vm.heap,
</span><span class="cx">                 allocationSize(symbolTable)
</span><span class="cx">             )
</span><del>-        ) JSLexicalEnvironment(vm, callFrame, registers, symbolTable);
</del><ins>+        ) JSLexicalEnvironment(vm, callFrame, registers, codeBlock);
</ins><span class="cx">         lexicalEnvironment-&gt;finishCreation(vm);
</span><span class="cx">         return lexicalEnvironment;
</span><span class="cx">     }
</span><span class="lines">@@ -77,8 +77,6 @@
</span><span class="cx"> 
</span><span class="cx">     static JSValue toThis(JSCell*, ExecState*, ECMAMode);
</span><span class="cx"> 
</span><del>-    void tearOff(VM&amp;);
-        
</del><span class="cx">     DECLARE_INFO;
</span><span class="cx"> 
</span><span class="cx">     static Structure* createStructure(VM&amp; vm, JSGlobalObject* globalObject) { return Structure::create(vm, globalObject, jsNull(), TypeInfo(ActivationObjectType, StructureFlags), info()); }
</span><span class="lines">@@ -86,7 +84,6 @@
</span><span class="cx">     WriteBarrierBase&lt;Unknown&gt;&amp; registerAt(int) const;
</span><span class="cx">     bool isValidIndex(int) const;
</span><span class="cx">     bool isValid(const SymbolTableEntry&amp;) const;
</span><del>-    bool isTornOff();
</del><span class="cx">     int registersOffset();
</span><span class="cx">     static int registersOffset(SymbolTable*);
</span><span class="cx"> 
</span><span class="lines">@@ -111,18 +108,21 @@
</span><span class="cx"> extern int activationCount;
</span><span class="cx"> extern int allTheThingsCount;
</span><span class="cx"> 
</span><del>-inline JSLexicalEnvironment::JSLexicalEnvironment(VM&amp; vm, CallFrame* callFrame, Register* registers, SymbolTable* symbolTable)
</del><ins>+inline JSLexicalEnvironment::JSLexicalEnvironment(VM&amp; vm, CallFrame* callFrame, Register* registers, CodeBlock* codeBlock)
</ins><span class="cx">     : Base(
</span><span class="cx">         vm,
</span><span class="cx">         callFrame-&gt;lexicalGlobalObject()-&gt;activationStructure(),
</span><span class="cx">         registers,
</span><span class="cx">         callFrame-&gt;scope(),
</span><del>-        symbolTable)
</del><ins>+        codeBlock-&gt;symbolTable())
</ins><span class="cx"> {
</span><ins>+    SymbolTable* symbolTable = codeBlock-&gt;symbolTable();
</ins><span class="cx">     WriteBarrier&lt;Unknown&gt;* storage = this-&gt;storage();
</span><span class="cx">     size_t captureCount = symbolTable-&gt;captureCount();
</span><span class="cx">     for (size_t i = 0; i &lt; captureCount; ++i)
</span><del>-        new (NotNull, &amp;storage[i]) WriteBarrier&lt;Unknown&gt;;
</del><ins>+        new (NotNull, &amp;storage[i]) WriteBarrier&lt;Unknown&gt;(UndefinedWriteBarrierTag);
+    m_registers = reinterpret_cast_ptr&lt;WriteBarrierBase&lt;Unknown&gt;*&gt;(
+        reinterpret_cast&lt;char*&gt;(this) + registersOffset(symbolTable));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSLexicalEnvironment* asActivation(JSValue);
</span><span class="lines">@@ -143,28 +143,6 @@
</span><span class="cx">     return storageOffset() + ((symbolTable-&gt;captureCount() - symbolTable-&gt;captureStart()  - 1) * sizeof(WriteBarrier&lt;Unknown&gt;));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void JSLexicalEnvironment::tearOff(VM&amp; vm)
-{
-    ASSERT(!isTornOff());
-
-    WriteBarrierBase&lt;Unknown&gt;* dst = reinterpret_cast_ptr&lt;WriteBarrierBase&lt;Unknown&gt;*&gt;(
-        reinterpret_cast&lt;char*&gt;(this) + registersOffset(symbolTable()));
-    WriteBarrierBase&lt;Unknown&gt;* src = m_registers;
-
-    int captureEnd = symbolTable()-&gt;captureEnd();
-    for (int i = symbolTable()-&gt;captureStart(); i &gt; captureEnd; --i)
-        dst[i].set(vm, this, src[i].get());
-
-    m_registers = dst;
-    ASSERT(isTornOff());
-}
-
-inline bool JSLexicalEnvironment::isTornOff()
-{
-    return m_registers == reinterpret_cast_ptr&lt;WriteBarrierBase&lt;Unknown&gt;*&gt;(
-        reinterpret_cast&lt;char*&gt;(this) + registersOffset(symbolTable()));
-}
-
</del><span class="cx"> inline size_t JSLexicalEnvironment::storageOffset()
</span><span class="cx"> {
</span><span class="cx">     return WTF::roundUpToMultipleOf&lt;sizeof(WriteBarrier&lt;Unknown&gt;)&gt;(sizeof(JSLexicalEnvironment));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSScopecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSScope.cpp (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSScope.cpp        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/runtime/JSScope.cpp        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -180,12 +180,12 @@
</span><span class="cx">         &quot;GlobalProperty&quot;,
</span><span class="cx">         &quot;GlobalVar&quot;,
</span><span class="cx">         &quot;ClosureVar&quot;,
</span><ins>+        &quot;LocalClosureVar&quot;,
</ins><span class="cx">         &quot;GlobalPropertyWithVarInjectionChecks&quot;,
</span><span class="cx">         &quot;GlobalVarWithVarInjectionChecks&quot;,
</span><span class="cx">         &quot;ClosureVarWithVarInjectionChecks&quot;,
</span><span class="cx">         &quot;Dynamic&quot;
</span><span class="cx">     };
</span><del>-    ASSERT(type &lt; sizeof(names) / sizeof(names[0]));
</del><span class="cx">     return names[type];
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSScopeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSScope.h (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSScope.h        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/runtime/JSScope.h        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -43,6 +43,7 @@
</span><span class="cx">     GlobalProperty,
</span><span class="cx">     GlobalVar,
</span><span class="cx">     ClosureVar,
</span><ins>+    LocalClosureVar,
</ins><span class="cx"> 
</span><span class="cx">     // Ditto, but at least one intervening scope used non-strict eval, which
</span><span class="cx">     // can inject an intercepting var delcaration at runtime.
</span><span class="lines">@@ -68,6 +69,7 @@
</span><span class="cx">     case GlobalVar:
</span><span class="cx">         return GlobalVarWithVarInjectionChecks;
</span><span class="cx">     case ClosureVar:
</span><ins>+    case LocalClosureVar:
</ins><span class="cx">         return ClosureVarWithVarInjectionChecks;
</span><span class="cx">     case GlobalPropertyWithVarInjectionChecks:
</span><span class="cx">     case GlobalVarWithVarInjectionChecks:
</span><span class="lines">@@ -86,6 +88,7 @@
</span><span class="cx">     case GlobalProperty:
</span><span class="cx">     case GlobalVar:
</span><span class="cx">     case ClosureVar:
</span><ins>+    case LocalClosureVar:
</ins><span class="cx">         return false;
</span><span class="cx">     case GlobalPropertyWithVarInjectionChecks:
</span><span class="cx">     case GlobalVarWithVarInjectionChecks:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeWriteBarrierh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/WriteBarrier.h (174225 => 174226)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/WriteBarrier.h        2014-10-02 19:39:41 UTC (rev 174225)
+++ trunk/Source/JavaScriptCore/runtime/WriteBarrier.h        2014-10-02 20:35:58 UTC (rev 174226)
</span><span class="lines">@@ -201,6 +201,7 @@
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+enum UndefinedWriteBarrierTagType { UndefinedWriteBarrierTag };
</ins><span class="cx"> template &lt;&gt; class WriteBarrier&lt;Unknown&gt; : public WriteBarrierBase&lt;Unknown&gt; {
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><span class="lines">@@ -208,6 +209,10 @@
</span><span class="cx">     {
</span><span class="cx">         this-&gt;setWithoutWriteBarrier(JSValue());
</span><span class="cx">     }
</span><ins>+    WriteBarrier(UndefinedWriteBarrierTagType)
+    {
+        this-&gt;setWithoutWriteBarrier(jsUndefined());
+    }
</ins><span class="cx"> 
</span><span class="cx">     WriteBarrier(VM&amp; vm, const JSCell* owner, JSValue value)
</span><span class="cx">     {
</span></span></pre>
</div>
</div>

</body>
</html>