<!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>[182759] trunk</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/182759">182759</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2015-04-13 15:13:12 -0700 (Mon, 13 Apr 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>JSC should detect singleton functions
https://bugs.webkit.org/show_bug.cgi?id=143232

Source/JavaScriptCore:

Reviewed by Geoffrey Garen.
        
This started out as an attempt to make constructors faster by detecting when a constructor is a
singleton. The idea is that each FunctionExecutable has a VariableWatchpointSet - a watchpoint
along with an inferred value - that detects if only one JSFunction has been allocated for that
executable, and if so, what that JSFunction is. Then, inside the code for the FunctionExecutable,
if the watchpoint set has an inferred value (i.e. it's been initialized and it is still valid),
we can constant-fold GetCallee.
        
Unfortunately, constructors don't use GetCallee anymore, so that didn't pan out. But in the
process I realized a bunch of things:
        
- This allows us to completely eliminate the GetCallee/GetScope sequence that we still sometimes
  had even in code where our singleton-closure detection worked. That's because singleton-closure
  inference worked at the op_resolve_scope, and that op_resolve_scope still needed to keep alive
  the incoming scope in case we OSR exit. But by constant-folding GetCallee, that sequence
  disappears. OSR exit can rematerialize the callee or the scope by just knowing their constant
  values.
          
- Singleton detection should be a reusable thing. So, I got rid of VariableWatchpointSet and
  created InferredValue. InferredValue is a cell, so it can handle its own GC magic.
  FunctionExecutable uses an InferredValue to tell you about singleton JSFunctions.
        
- The old singleton-scope detection in op_resolve_scope is better abstracted as a SymbolTable
  detecting a singleton JSSymbolTableObject. So, SymbolTable uses an InferredValue to tell you
  about singleton JSSymbolTableObjects. It's curious that we want to have singleton detection in
  SymbolTable if we already have it in FunctionExecutable. This comes into play in two ways.
  First, it means that the DFG can realize sooner that a resolve_scope resolves to a constant
  scope. Ths saves compile times and it allows prediction propagation to benefit from the
  constant folding. Second, it means that we will detect a singleton scope even if it is
  referenced from a non-singleton scope that is nearer to us in the scope chain. This refactoring
  allows us to eliminate the function reentry watchpoint.
        
- This allows us to use a normal WatchpointSet, instead of a VariableWatchpointSet, for inferring
  constant values in scopes. Previously when the DFG inferred that a closure variable was
  constant, it wouldn't know which closure that variable was in and so it couldn't just load that
  value. But now we are first inferring that the function is a singleton, which means that we
  know exactly what scope it points to, and we can load the value from the scope. Using a
  WatchpointSet instead of a VariableWatchpointSet saves some memory and simplifies a bunch of
  code. This also means that now, the only user of VariableWatchpointSet is FunctionExecutable.
  I've tweaked the code of VariableWatchpointSet to reduce its power to just be what
  FunctionExecutable wants.
        
This also has the effect of simplifying the implementation of block scoping. Prior to this
change, block scoping would have needed to have some story for the function reentry watchpoint on
any nested symbol table. That's totally weird to think about; it's not really a function reentry
but a scope reentry. Now we don't have to think about this. Constant inference on nested scopes
will &quot;just work&quot;: if we prove that we know the constant value of the scope then the machinery
kicks in, otherwise it doesn't.
        
This is a small Octane and AsmBench speed-up. AsmBench sees 1% while Octane sees sub-1%.

* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::finalizeUnconditionally):
(JSC::CodeBlock::valueProfileForBytecodeOffset):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::valueProfileForBytecodeOffset): Deleted.
* bytecode/CodeOrigin.cpp:
(JSC::InlineCallFrame::calleeConstant):
(JSC::InlineCallFrame::visitAggregate):
* bytecode/CodeOrigin.h:
(JSC::InlineCallFrame::calleeConstant): Deleted.
(JSC::InlineCallFrame::visitAggregate): Deleted.
* bytecode/Instruction.h:
* bytecode/VariableWatchpointSet.cpp: Removed.
* bytecode/VariableWatchpointSet.h: Removed.
* bytecode/VariableWatchpointSetInlines.h: Removed.
* bytecode/VariableWriteFireDetail.cpp: Added.
(JSC::VariableWriteFireDetail::dump):
(JSC::VariableWriteFireDetail::touch):
* bytecode/VariableWriteFireDetail.h: Added.
(JSC::VariableWriteFireDetail::VariableWriteFireDetail):
* bytecode/Watchpoint.h:
(JSC::WatchpointSet::stateOnJSThread):
(JSC::WatchpointSet::startWatching):
(JSC::WatchpointSet::fireAll):
(JSC::WatchpointSet::touch):
(JSC::WatchpointSet::invalidate):
(JSC::InlineWatchpointSet::stateOnJSThread):
(JSC::InlineWatchpointSet::state):
(JSC::InlineWatchpointSet::hasBeenInvalidated):
(JSC::InlineWatchpointSet::invalidate):
(JSC::InlineWatchpointSet::touch):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::get):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::getScope): Deleted.
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDesiredWatchpoints.cpp:
(JSC::DFG::InferredValueAdaptor::add):
(JSC::DFG::DesiredWatchpoints::addLazily):
(JSC::DFG::DesiredWatchpoints::reallyAdd):
(JSC::DFG::DesiredWatchpoints::areStillValid):
* dfg/DFGDesiredWatchpoints.h:
(JSC::DFG::InferredValueAdaptor::hasBeenInvalidated):
(JSC::DFG::DesiredWatchpoints::isWatched):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
(JSC::DFG::Graph::tryGetConstantClosureVar):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasWatchpointSet):
(JSC::DFG::Node::watchpointSet):
(JSC::DFG::Node::hasVariableWatchpointSet): Deleted.
(JSC::DFG::Node::variableWatchpointSet): Deleted.
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileNewFunction):
(JSC::DFG::SpeculativeJIT::compileCreateActivation):
(JSC::DFG::SpeculativeJIT::compileNotifyWrite):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGVarargsForwardingPhase.cpp:
* ftl/FTLIntrinsicRepository.h:
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileCreateActivation):
(JSC::FTL::LowerDFGToLLVM::compileNewFunction):
(JSC::FTL::LowerDFGToLLVM::compileNotifyWrite):
* interpreter/Interpreter.cpp:
(JSC::StackFrame::friendlySourceURL):
(JSC::StackFrame::friendlyFunctionName):
* interpreter/Interpreter.h:
(JSC::StackFrame::friendlySourceURL): Deleted.
(JSC::StackFrame::friendlyFunctionName): Deleted.
* jit/JIT.cpp:
(JSC::JIT::emitNotifyWrite):
(JSC::JIT::privateCompileMainPass):
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_touch_entry): Deleted.
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emitPutGlobalVar):
(JSC::JIT::emitPutClosureVar):
(JSC::JIT::emitNotifyWrite): Deleted.
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emitPutGlobalVar):
(JSC::JIT::emitPutClosureVar):
(JSC::JIT::emitNotifyWrite): Deleted.
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL): Deleted.
* runtime/CommonSlowPaths.h:
* runtime/Executable.cpp:
(JSC::FunctionExecutable::finishCreation):
(JSC::FunctionExecutable::visitChildren):
* runtime/Executable.h:
(JSC::FunctionExecutable::singletonFunction):
* runtime/InferredValue.cpp: Added.
(JSC::InferredValue::create):
(JSC::InferredValue::destroy):
(JSC::InferredValue::createStructure):
(JSC::InferredValue::visitChildren):
(JSC::InferredValue::InferredValue):
(JSC::InferredValue::~InferredValue):
(JSC::InferredValue::notifyWriteSlow):
(JSC::InferredValue::ValueCleanup::ValueCleanup):
(JSC::InferredValue::ValueCleanup::~ValueCleanup):
(JSC::InferredValue::ValueCleanup::finalizeUnconditionally):
* runtime/InferredValue.h: Added.
(JSC::InferredValue::inferredValue):
(JSC::InferredValue::state):
(JSC::InferredValue::isStillValid):
(JSC::InferredValue::hasBeenInvalidated):
(JSC::InferredValue::add):
(JSC::InferredValue::notifyWrite):
(JSC::InferredValue::invalidate):
* runtime/JSEnvironmentRecord.cpp:
(JSC::JSEnvironmentRecord::visitChildren):
* runtime/JSEnvironmentRecord.h:
(JSC::JSEnvironmentRecord::isValid):
(JSC::JSEnvironmentRecord::finishCreation):
* runtime/JSFunction.cpp:
(JSC::JSFunction::create):
* runtime/JSFunction.h:
(JSC::JSFunction::createWithInvalidatedReallocationWatchpoint):
(JSC::JSFunction::createImpl):
(JSC::JSFunction::create): Deleted.
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::addGlobalVar):
(JSC::JSGlobalObject::addFunction):
* runtime/JSGlobalObject.h:
* runtime/JSLexicalEnvironment.cpp:
(JSC::JSLexicalEnvironment::symbolTablePut):
* runtime/JSScope.h:
(JSC::ResolveOp::ResolveOp):
* runtime/JSSegmentedVariableObject.h:
(JSC::JSSegmentedVariableObject::finishCreation):
* runtime/JSSymbolTableObject.h:
(JSC::JSSymbolTableObject::JSSymbolTableObject):
(JSC::JSSymbolTableObject::setSymbolTable):
(JSC::symbolTablePut):
(JSC::symbolTablePutWithAttributes):
* runtime/PutPropertySlot.h:
* runtime/SymbolTable.cpp:
(JSC::SymbolTableEntry::prepareToWatch):
(JSC::SymbolTable::SymbolTable):
(JSC::SymbolTable::finishCreation):
(JSC::SymbolTable::visitChildren):
(JSC::SymbolTableEntry::inferredValue): Deleted.
(JSC::SymbolTableEntry::notifyWriteSlow): Deleted.
(JSC::SymbolTable::WatchpointCleanup::WatchpointCleanup): Deleted.
(JSC::SymbolTable::WatchpointCleanup::~WatchpointCleanup): Deleted.
(JSC::SymbolTable::WatchpointCleanup::finalizeUnconditionally): Deleted.
* runtime/SymbolTable.h:
(JSC::SymbolTableEntry::disableWatching):
(JSC::SymbolTableEntry::watchpointSet):
(JSC::SymbolTable::singletonScope):
(JSC::SymbolTableEntry::notifyWrite): Deleted.
* runtime/TypeProfiler.cpp:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
* tests/stress/infer-uninitialized-closure-var.js: Added.
(foo.f):
(foo):
* tests/stress/singleton-scope-then-overwrite.js: Added.
(foo.f):
(foo):
* tests/stress/singleton-scope-then-realloc-and-overwrite.js: Added.
(foo):
* tests/stress/singleton-scope-then-realloc.js: Added.
(foo):

LayoutTests:

Reviewed by Geoffrey Garen and Michael Saboff.

* js/regress/create-lots-of-functions-expected.txt: Added.
* js/regress/create-lots-of-functions.html: Added.
* js/regress/no-inline-constructor-expected.txt: Added.
* js/regress/no-inline-constructor.html: Added.
* js/regress/script-tests/create-lots-of-functions.js: Added.
* js/regress/script-tests/no-inline-constructor.js: Added.
* js/regress/script-tests/singleton-scope.js: Added.
* js/regress/singleton-scope-expected.txt: Added.
* js/regress/singleton-scope.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</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="#trunkSourceJavaScriptCorebytecodeCodeBlockh">trunk/Source/JavaScriptCore/bytecode/CodeBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeOrigincpp">trunk/Source/JavaScriptCore/bytecode/CodeOrigin.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeOriginh">trunk/Source/JavaScriptCore/bytecode/CodeOrigin.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeInstructionh">trunk/Source/JavaScriptCore/bytecode/Instruction.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeWatchpointh">trunk/Source/JavaScriptCore/bytecode/Watchpoint.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.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="#trunkSourceJavaScriptCoredfgDFGDesiredWatchpointscpp">trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDesiredWatchpointsh">trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphcpp">trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationscpp">trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationsh">trunk/Source/JavaScriptCore/dfg/DFGOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITh">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.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="#trunkSourceJavaScriptCoredfgDFGVarargsForwardingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLIntrinsicRepositoryh">trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterInterpretercpp">trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterInterpreterh">trunk/Source/JavaScriptCore/interpreter/Interpreter.h</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="#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="#trunkSourceJavaScriptCorellintLLIntSlowPathscpp">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</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="#trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathsh">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeExecutablecpp">trunk/Source/JavaScriptCore/runtime/Executable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeExecutableh">trunk/Source/JavaScriptCore/runtime/Executable.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSEnvironmentRecordcpp">trunk/Source/JavaScriptCore/runtime/JSEnvironmentRecord.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSEnvironmentRecordh">trunk/Source/JavaScriptCore/runtime/JSEnvironmentRecord.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSFunctioncpp">trunk/Source/JavaScriptCore/runtime/JSFunction.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSFunctionh">trunk/Source/JavaScriptCore/runtime/JSFunction.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSFunctionInlinesh">trunk/Source/JavaScriptCore/runtime/JSFunctionInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjecth">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSLexicalEnvironmentcpp">trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSScopeh">trunk/Source/JavaScriptCore/runtime/JSScope.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSSegmentedVariableObjecth">trunk/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSSymbolTableObjecth">trunk/Source/JavaScriptCore/runtime/JSSymbolTableObject.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimePutPropertySloth">trunk/Source/JavaScriptCore/runtime/PutPropertySlot.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeSymbolTablecpp">trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeSymbolTableh">trunk/Source/JavaScriptCore/runtime/SymbolTable.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeTypeProfilercpp">trunk/Source/JavaScriptCore/runtime/TypeProfiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMcpp">trunk/Source/JavaScriptCore/runtime/VM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMh">trunk/Source/JavaScriptCore/runtime/VM.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsregresscreatelotsoffunctionsexpectedtxt">trunk/LayoutTests/js/regress/create-lots-of-functions-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregresscreatelotsoffunctionshtml">trunk/LayoutTests/js/regress/create-lots-of-functions.html</a></li>
<li><a href="#trunkLayoutTestsjsregressnoinlineconstructorexpectedtxt">trunk/LayoutTests/js/regress/no-inline-constructor-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressnoinlineconstructorhtml">trunk/LayoutTests/js/regress/no-inline-constructor.html</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestscreatelotsoffunctionsjs">trunk/LayoutTests/js/regress/script-tests/create-lots-of-functions.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsnoinlineconstructorjs">trunk/LayoutTests/js/regress/script-tests/no-inline-constructor.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestssingletonscopejs">trunk/LayoutTests/js/regress/script-tests/singleton-scope.js</a></li>
<li><a href="#trunkLayoutTestsjsregresssingletonscopeexpectedtxt">trunk/LayoutTests/js/regress/singleton-scope-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregresssingletonscopehtml">trunk/LayoutTests/js/regress/singleton-scope.html</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeVariableWriteFireDetailcpp">trunk/Source/JavaScriptCore/bytecode/VariableWriteFireDetail.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeVariableWriteFireDetailh">trunk/Source/JavaScriptCore/bytecode/VariableWriteFireDetail.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeInferredValuecpp">trunk/Source/JavaScriptCore/runtime/InferredValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeInferredValueh">trunk/Source/JavaScriptCore/runtime/InferredValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressinferuninitializedclosurevarjs">trunk/Source/JavaScriptCore/tests/stress/infer-uninitialized-closure-var.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresssingletonscopethenoverwritejs">trunk/Source/JavaScriptCore/tests/stress/singleton-scope-then-overwrite.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresssingletonscopethenreallocandoverwritejs">trunk/Source/JavaScriptCore/tests/stress/singleton-scope-then-realloc-and-overwrite.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresssingletonscopethenreallocjs">trunk/Source/JavaScriptCore/tests/stress/singleton-scope-then-realloc.js</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCorebytecodeVariableWatchpointSetcpp">trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSet.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeVariableWatchpointSeth">trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeVariableWatchpointSetInlinesh">trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSetInlines.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/LayoutTests/ChangeLog        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2015-04-08  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        JSC should detect singleton functions
+        https://bugs.webkit.org/show_bug.cgi?id=143232
+
+        Reviewed by Geoffrey Garen and Michael Saboff.
+
+        * js/regress/create-lots-of-functions-expected.txt: Added.
+        * js/regress/create-lots-of-functions.html: Added.
+        * js/regress/no-inline-constructor-expected.txt: Added.
+        * js/regress/no-inline-constructor.html: Added.
+        * js/regress/script-tests/create-lots-of-functions.js: Added.
+        * js/regress/script-tests/no-inline-constructor.js: Added.
+        * js/regress/script-tests/singleton-scope.js: Added.
+        * js/regress/singleton-scope-expected.txt: Added.
+        * js/regress/singleton-scope.html: Added.
+
</ins><span class="cx"> 2015-04-13  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add missing layout test result.
</span></span></pre></div>
<a id="trunkLayoutTestsjsregresscreatelotsoffunctionsexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/create-lots-of-functions-expected.txt (0 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/create-lots-of-functions-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/create-lots-of-functions-expected.txt        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/create-lots-of-functions
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresscreatelotsoffunctionshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/create-lots-of-functions.html (0 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/create-lots-of-functions.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/create-lots-of-functions.html        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/create-lots-of-functions.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressnoinlineconstructorexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/no-inline-constructor-expected.txt (0 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/no-inline-constructor-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/no-inline-constructor-expected.txt        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/no-inline-constructor
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressnoinlineconstructorhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/no-inline-constructor.html (0 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/no-inline-constructor.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/no-inline-constructor.html        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/no-inline-constructor.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestscreatelotsoffunctionsjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/create-lots-of-functions.js (0 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/create-lots-of-functions.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/create-lots-of-functions.js        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+function foo() {
+    var result = 0;
+    for (var i = 0; i &lt; 100; ++i)
+        result += (function() { return i })();
+    return result;
+}
+
+for (var i = 0; i &lt; 10000; ++i) {
+    var result = foo();
+    if (result != 4950)
+        throw &quot;Error: bad result: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsnoinlineconstructorjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/no-inline-constructor.js (0 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/no-inline-constructor.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/no-inline-constructor.js        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+function Foo() {
+    var o = {f:{f:{f:{f:42}}}};
+    this.f = 42;
+}
+
+noInline(Foo);
+
+for (var i = 0; i &lt; 3000000; ++i) {
+    var result = new Foo();
+    if (result.f != 42)
+        throw &quot;Error: bad result: &quot; + result.f;
+}
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestssingletonscopejs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/singleton-scope.js (0 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/singleton-scope.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/singleton-scope.js        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+function foo() {
+    var x = 42;
+    var y = 43;
+    return function(z) {
+        var result = x + y;
+        x += z;
+        y += z;
+        return result;
+    }
+}
+
+var f = foo();
+noInline(f);
+
+for (var i = 0; i &lt; 10000000; ++i)
+    f(1);
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresssingletonscopeexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/singleton-scope-expected.txt (0 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/singleton-scope-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/singleton-scope-expected.txt        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/singleton-scope
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresssingletonscopehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/singleton-scope.html (0 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/singleton-scope.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/singleton-scope.html        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/singleton-scope.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -105,7 +105,7 @@
</span><span class="cx">     bytecode/UnlinkedCodeBlock.cpp
</span><span class="cx">     bytecode/UnlinkedInstructionStream.cpp
</span><span class="cx">     bytecode/ValueRecovery.cpp
</span><del>-    bytecode/VariableWatchpointSet.cpp
</del><ins>+    bytecode/VariableWriteFireDetail.cpp
</ins><span class="cx">     bytecode/VirtualRegister.cpp
</span><span class="cx">     bytecode/Watchpoint.cpp
</span><span class="cx"> 
</span><span class="lines">@@ -452,6 +452,7 @@
</span><span class="cx">     runtime/GetterSetter.cpp
</span><span class="cx">     runtime/Identifier.cpp
</span><span class="cx">     runtime/IndexingType.cpp
</span><ins>+    runtime/InferredValue.cpp
</ins><span class="cx">     runtime/InitializeThreading.cpp
</span><span class="cx">     runtime/IntendedStructureChain.cpp
</span><span class="cx">     runtime/InternalFunction.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -1,3 +1,257 @@
</span><ins>+2015-04-08  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        JSC should detect singleton functions
+        https://bugs.webkit.org/show_bug.cgi?id=143232
+
+        Reviewed by Geoffrey Garen.
+        
+        This started out as an attempt to make constructors faster by detecting when a constructor is a
+        singleton. The idea is that each FunctionExecutable has a VariableWatchpointSet - a watchpoint
+        along with an inferred value - that detects if only one JSFunction has been allocated for that
+        executable, and if so, what that JSFunction is. Then, inside the code for the FunctionExecutable,
+        if the watchpoint set has an inferred value (i.e. it's been initialized and it is still valid),
+        we can constant-fold GetCallee.
+        
+        Unfortunately, constructors don't use GetCallee anymore, so that didn't pan out. But in the
+        process I realized a bunch of things:
+        
+        - This allows us to completely eliminate the GetCallee/GetScope sequence that we still sometimes
+          had even in code where our singleton-closure detection worked. That's because singleton-closure
+          inference worked at the op_resolve_scope, and that op_resolve_scope still needed to keep alive
+          the incoming scope in case we OSR exit. But by constant-folding GetCallee, that sequence
+          disappears. OSR exit can rematerialize the callee or the scope by just knowing their constant
+          values.
+          
+        - Singleton detection should be a reusable thing. So, I got rid of VariableWatchpointSet and
+          created InferredValue. InferredValue is a cell, so it can handle its own GC magic.
+          FunctionExecutable uses an InferredValue to tell you about singleton JSFunctions.
+        
+        - The old singleton-scope detection in op_resolve_scope is better abstracted as a SymbolTable
+          detecting a singleton JSSymbolTableObject. So, SymbolTable uses an InferredValue to tell you
+          about singleton JSSymbolTableObjects. It's curious that we want to have singleton detection in
+          SymbolTable if we already have it in FunctionExecutable. This comes into play in two ways.
+          First, it means that the DFG can realize sooner that a resolve_scope resolves to a constant
+          scope. Ths saves compile times and it allows prediction propagation to benefit from the
+          constant folding. Second, it means that we will detect a singleton scope even if it is
+          referenced from a non-singleton scope that is nearer to us in the scope chain. This refactoring
+          allows us to eliminate the function reentry watchpoint.
+        
+        - This allows us to use a normal WatchpointSet, instead of a VariableWatchpointSet, for inferring
+          constant values in scopes. Previously when the DFG inferred that a closure variable was
+          constant, it wouldn't know which closure that variable was in and so it couldn't just load that
+          value. But now we are first inferring that the function is a singleton, which means that we
+          know exactly what scope it points to, and we can load the value from the scope. Using a
+          WatchpointSet instead of a VariableWatchpointSet saves some memory and simplifies a bunch of
+          code. This also means that now, the only user of VariableWatchpointSet is FunctionExecutable.
+          I've tweaked the code of VariableWatchpointSet to reduce its power to just be what
+          FunctionExecutable wants.
+        
+        This also has the effect of simplifying the implementation of block scoping. Prior to this
+        change, block scoping would have needed to have some story for the function reentry watchpoint on
+        any nested symbol table. That's totally weird to think about; it's not really a function reentry
+        but a scope reentry. Now we don't have to think about this. Constant inference on nested scopes
+        will &quot;just work&quot;: if we prove that we know the constant value of the scope then the machinery
+        kicks in, otherwise it doesn't.
+        
+        This is a small Octane and AsmBench speed-up. AsmBench sees 1% while Octane sees sub-1%.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::finalizeUnconditionally):
+        (JSC::CodeBlock::valueProfileForBytecodeOffset):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::valueProfileForBytecodeOffset): Deleted.
+        * bytecode/CodeOrigin.cpp:
+        (JSC::InlineCallFrame::calleeConstant):
+        (JSC::InlineCallFrame::visitAggregate):
+        * bytecode/CodeOrigin.h:
+        (JSC::InlineCallFrame::calleeConstant): Deleted.
+        (JSC::InlineCallFrame::visitAggregate): Deleted.
+        * bytecode/Instruction.h:
+        * bytecode/VariableWatchpointSet.cpp: Removed.
+        * bytecode/VariableWatchpointSet.h: Removed.
+        * bytecode/VariableWatchpointSetInlines.h: Removed.
+        * bytecode/VariableWriteFireDetail.cpp: Added.
+        (JSC::VariableWriteFireDetail::dump):
+        (JSC::VariableWriteFireDetail::touch):
+        * bytecode/VariableWriteFireDetail.h: Added.
+        (JSC::VariableWriteFireDetail::VariableWriteFireDetail):
+        * bytecode/Watchpoint.h:
+        (JSC::WatchpointSet::stateOnJSThread):
+        (JSC::WatchpointSet::startWatching):
+        (JSC::WatchpointSet::fireAll):
+        (JSC::WatchpointSet::touch):
+        (JSC::WatchpointSet::invalidate):
+        (JSC::InlineWatchpointSet::stateOnJSThread):
+        (JSC::InlineWatchpointSet::state):
+        (JSC::InlineWatchpointSet::hasBeenInvalidated):
+        (JSC::InlineWatchpointSet::invalidate):
+        (JSC::InlineWatchpointSet::touch):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::get):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        (JSC::DFG::ByteCodeParser::getScope): Deleted.
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDesiredWatchpoints.cpp:
+        (JSC::DFG::InferredValueAdaptor::add):
+        (JSC::DFG::DesiredWatchpoints::addLazily):
+        (JSC::DFG::DesiredWatchpoints::reallyAdd):
+        (JSC::DFG::DesiredWatchpoints::areStillValid):
+        * dfg/DFGDesiredWatchpoints.h:
+        (JSC::DFG::InferredValueAdaptor::hasBeenInvalidated):
+        (JSC::DFG::DesiredWatchpoints::isWatched):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        (JSC::DFG::Graph::tryGetConstantClosureVar):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasWatchpointSet):
+        (JSC::DFG::Node::watchpointSet):
+        (JSC::DFG::Node::hasVariableWatchpointSet): Deleted.
+        (JSC::DFG::Node::variableWatchpointSet): Deleted.
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileNewFunction):
+        (JSC::DFG::SpeculativeJIT::compileCreateActivation):
+        (JSC::DFG::SpeculativeJIT::compileNotifyWrite):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGVarargsForwardingPhase.cpp:
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileCreateActivation):
+        (JSC::FTL::LowerDFGToLLVM::compileNewFunction):
+        (JSC::FTL::LowerDFGToLLVM::compileNotifyWrite):
+        * interpreter/Interpreter.cpp:
+        (JSC::StackFrame::friendlySourceURL):
+        (JSC::StackFrame::friendlyFunctionName):
+        * interpreter/Interpreter.h:
+        (JSC::StackFrame::friendlySourceURL): Deleted.
+        (JSC::StackFrame::friendlyFunctionName): Deleted.
+        * jit/JIT.cpp:
+        (JSC::JIT::emitNotifyWrite):
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_touch_entry): Deleted.
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitPutGlobalVar):
+        (JSC::JIT::emitPutClosureVar):
+        (JSC::JIT::emitNotifyWrite): Deleted.
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emitPutGlobalVar):
+        (JSC::JIT::emitPutClosureVar):
+        (JSC::JIT::emitNotifyWrite): Deleted.
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL): Deleted.
+        * runtime/CommonSlowPaths.h:
+        * runtime/Executable.cpp:
+        (JSC::FunctionExecutable::finishCreation):
+        (JSC::FunctionExecutable::visitChildren):
+        * runtime/Executable.h:
+        (JSC::FunctionExecutable::singletonFunction):
+        * runtime/InferredValue.cpp: Added.
+        (JSC::InferredValue::create):
+        (JSC::InferredValue::destroy):
+        (JSC::InferredValue::createStructure):
+        (JSC::InferredValue::visitChildren):
+        (JSC::InferredValue::InferredValue):
+        (JSC::InferredValue::~InferredValue):
+        (JSC::InferredValue::notifyWriteSlow):
+        (JSC::InferredValue::ValueCleanup::ValueCleanup):
+        (JSC::InferredValue::ValueCleanup::~ValueCleanup):
+        (JSC::InferredValue::ValueCleanup::finalizeUnconditionally):
+        * runtime/InferredValue.h: Added.
+        (JSC::InferredValue::inferredValue):
+        (JSC::InferredValue::state):
+        (JSC::InferredValue::isStillValid):
+        (JSC::InferredValue::hasBeenInvalidated):
+        (JSC::InferredValue::add):
+        (JSC::InferredValue::notifyWrite):
+        (JSC::InferredValue::invalidate):
+        * runtime/JSEnvironmentRecord.cpp:
+        (JSC::JSEnvironmentRecord::visitChildren):
+        * runtime/JSEnvironmentRecord.h:
+        (JSC::JSEnvironmentRecord::isValid):
+        (JSC::JSEnvironmentRecord::finishCreation):
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::create):
+        * runtime/JSFunction.h:
+        (JSC::JSFunction::createWithInvalidatedReallocationWatchpoint):
+        (JSC::JSFunction::createImpl):
+        (JSC::JSFunction::create): Deleted.
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::addGlobalVar):
+        (JSC::JSGlobalObject::addFunction):
+        * runtime/JSGlobalObject.h:
+        * runtime/JSLexicalEnvironment.cpp:
+        (JSC::JSLexicalEnvironment::symbolTablePut):
+        * runtime/JSScope.h:
+        (JSC::ResolveOp::ResolveOp):
+        * runtime/JSSegmentedVariableObject.h:
+        (JSC::JSSegmentedVariableObject::finishCreation):
+        * runtime/JSSymbolTableObject.h:
+        (JSC::JSSymbolTableObject::JSSymbolTableObject):
+        (JSC::JSSymbolTableObject::setSymbolTable):
+        (JSC::symbolTablePut):
+        (JSC::symbolTablePutWithAttributes):
+        * runtime/PutPropertySlot.h:
+        * runtime/SymbolTable.cpp:
+        (JSC::SymbolTableEntry::prepareToWatch):
+        (JSC::SymbolTable::SymbolTable):
+        (JSC::SymbolTable::finishCreation):
+        (JSC::SymbolTable::visitChildren):
+        (JSC::SymbolTableEntry::inferredValue): Deleted.
+        (JSC::SymbolTableEntry::notifyWriteSlow): Deleted.
+        (JSC::SymbolTable::WatchpointCleanup::WatchpointCleanup): Deleted.
+        (JSC::SymbolTable::WatchpointCleanup::~WatchpointCleanup): Deleted.
+        (JSC::SymbolTable::WatchpointCleanup::finalizeUnconditionally): Deleted.
+        * runtime/SymbolTable.h:
+        (JSC::SymbolTableEntry::disableWatching):
+        (JSC::SymbolTableEntry::watchpointSet):
+        (JSC::SymbolTable::singletonScope):
+        (JSC::SymbolTableEntry::notifyWrite): Deleted.
+        * runtime/TypeProfiler.cpp:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+        * tests/stress/infer-uninitialized-closure-var.js: Added.
+        (foo.f):
+        (foo):
+        * tests/stress/singleton-scope-then-overwrite.js: Added.
+        (foo.f):
+        (foo):
+        * tests/stress/singleton-scope-then-realloc-and-overwrite.js: Added.
+        (foo):
+        * tests/stress/singleton-scope-then-realloc.js: Added.
+        (foo):
+
</ins><span class="cx"> 2015-04-13  Andreas Kling  &lt;akling@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Don't segregate heap objects based on Structure immortality.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -352,7 +352,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\UnlinkedCodeBlock.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\UnlinkedInstructionStream.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\ValueRecovery.cpp&quot; /&gt;
</span><del>-    &lt;ClCompile Include=&quot;..\bytecode\VariableWatchpointSet.cpp&quot; /&gt;
</del><ins>+    &lt;ClCompile Include=&quot;..\bytecode\VariableWriteFireDetail.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\VirtualRegister.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\Watchpoint.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecompiler\BytecodeGenerator.cpp&quot; /&gt;
</span><span class="lines">@@ -720,6 +720,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\runtime\GetterSetter.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\runtime\Identifier.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\runtime\IndexingType.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\runtime\InferredValue.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\runtime\InitializeThreading.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\runtime\IntendedStructureChain.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\runtime\InternalFunction.cpp&quot; /&gt;
</span><span class="lines">@@ -1004,7 +1005,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\UnlinkedInstructionStream.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\ValueProfile.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\ValueRecovery.h&quot; /&gt;
</span><del>-    &lt;ClInclude Include=&quot;..\bytecode\VariableWatchpointSet.h&quot; /&gt;
</del><ins>+    &lt;ClInclude Include=&quot;..\bytecode\VariableWriteFireDetail.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\VirtualRegister.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\Watchpoint.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecompiler\BytecodeGenerator.h&quot; /&gt;
</span><span class="lines">@@ -1507,6 +1508,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\runtime\IndexingHeader.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\runtime\IndexingHeaderInlines.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\runtime\IndexingType.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\runtime\InferredValue.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\runtime\InitializeThreading.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\runtime\Int16Array.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\runtime\Int32Array.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -383,6 +383,8 @@
</span><span class="cx">                 0F6B1CC61862C47800845D97 /* FTLUnwindInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CC21862C47800845D97 /* FTLUnwindInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F6B1CC918641DF800845D97 /* ArityCheckFailReturnThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B1CC718641DF800845D97 /* ArityCheckFailReturnThunks.cpp */; };
</span><span class="cx">                 0F6B1CCA18641DF800845D97 /* ArityCheckFailReturnThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CC818641DF800845D97 /* ArityCheckFailReturnThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0F6C73501AC9F99F00BE1682 /* VariableWriteFireDetail.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6C734E1AC9F99F00BE1682 /* VariableWriteFireDetail.cpp */; };
+                0F6C73511AC9F99F00BE1682 /* VariableWriteFireDetail.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6C734F1AC9F99F00BE1682 /* VariableWriteFireDetail.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0F6E845A19030BEF00562741 /* DFGVariableAccessData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6E845919030BEF00562741 /* DFGVariableAccessData.cpp */; };
</span><span class="cx">                 0F6FC750196110A800E1D02D /* ComplexGetStatus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6FC74E196110A800E1D02D /* ComplexGetStatus.cpp */; };
</span><span class="cx">                 0F6FC751196110A800E1D02D /* ComplexGetStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6FC74F196110A800E1D02D /* ComplexGetStatus.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -425,7 +427,6 @@
</span><span class="cx">                 0F8F94421667633500D61971 /* CodeType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8F943F1667632D00D61971 /* CodeType.cpp */; };
</span><span class="cx">                 0F8F94441667635400D61971 /* JITCode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8F94431667635200D61971 /* JITCode.cpp */; };
</span><span class="cx">                 0F8F9446166764F100D61971 /* CodeOrigin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8F9445166764EE00D61971 /* CodeOrigin.cpp */; };
</span><del>-                0F9181C718415CA50057B669 /* VariableWatchpointSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9181C618415CA50057B669 /* VariableWatchpointSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><span class="cx">                 0F919D0C157EE09F004A4E7D /* JSSymbolTableObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F919D09157EE09D004A4E7D /* JSSymbolTableObject.cpp */; };
</span><span class="cx">                 0F919D0D157EE0A2004A4E7D /* JSSymbolTableObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F919D0A157EE09D004A4E7D /* JSSymbolTableObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F919D10157F3329004A4E7D /* JSSegmentedVariableObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F919D0E157F3327004A4E7D /* JSSegmentedVariableObject.cpp */; };
</span><span class="lines">@@ -550,7 +551,6 @@
</span><span class="cx">                 0FC97F4018202119002C9B26 /* DFGJumpReplacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC97F3A18202119002C9B26 /* DFGJumpReplacement.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FC97F4118202119002C9B26 /* DFGWatchpointCollectionPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC97F3B18202119002C9B26 /* DFGWatchpointCollectionPhase.cpp */; };
</span><span class="cx">                 0FC97F4218202119002C9B26 /* DFGWatchpointCollectionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC97F3C18202119002C9B26 /* DFGWatchpointCollectionPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                0FCA9113195E66A000426438 /* VariableWatchpointSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCA9112195E66A000426438 /* VariableWatchpointSet.cpp */; };
</del><span class="cx">                 0FCCAE4516D0CF7400D0C65B /* ParserError.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCCAE4316D0CF6E00D0C65B /* ParserError.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FCEFAAB1804C13E00472CE4 /* FTLSaveRestore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCEFAA91804C13E00472CE4 /* FTLSaveRestore.cpp */; };
</span><span class="cx">                 0FCEFAAC1804C13E00472CE4 /* FTLSaveRestore.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCEFAAA1804C13E00472CE4 /* FTLSaveRestore.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -719,6 +719,8 @@
</span><span class="cx">                 0FF729BE166AD360000F5BA3 /* ProfilerExecutionCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF7299E166AD347000F5BA3 /* ProfilerExecutionCounter.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FF729BF166AD360000F5BA3 /* ProfilerOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF729A0166AD347000F5BA3 /* ProfilerOrigin.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FF729C0166AD360000F5BA3 /* ProfilerOriginStack.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF729A2166AD347000F5BA3 /* ProfilerOriginStack.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0FF8BDEA1AD4CF7100DFE884 /* InferredValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF8BDE81AD4CF7100DFE884 /* InferredValue.cpp */; };
+                0FF8BDEB1AD4CF7100DFE884 /* InferredValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF8BDE91AD4CF7100DFE884 /* InferredValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0FF922D414F46B410041A24E /* LLIntOffsetsExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */; };
</span><span class="cx">                 0FFA549716B8835000B3A982 /* A64DOpcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 652A3A221651C69700A80AFE /* A64DOpcode.cpp */; };
</span><span class="cx">                 0FFA549816B8835300B3A982 /* A64DOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 652A3A231651C69700A80AFE /* A64DOpcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -1644,7 +1646,6 @@
</span><span class="cx">                 FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 FE4A331F15BD2E07006F54F3 /* VMInspector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE4A331D15BD2E07006F54F3 /* VMInspector.cpp */; };
</span><span class="cx">                 FE4A332015BD2E07006F54F3 /* VMInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4A331E15BD2E07006F54F3 /* VMInspector.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                FE5248F9191442D900B7FDE4 /* VariableWatchpointSetInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FE5248F8191442D900B7FDE4 /* VariableWatchpointSetInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><span class="cx">                 FE5932A7183C5A2600A1ECCC /* VMEntryScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */; };
</span><span class="cx">                 FE5932A8183C5A2600A1ECCC /* VMEntryScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FE5932A6183C5A2600A1ECCC /* VMEntryScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 FE7BA60F1A1A7CEC00F1F7B4 /* HeapVerifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE7BA60D1A1A7CEC00F1F7B4 /* HeapVerifier.cpp */; };
</span><span class="lines">@@ -2100,6 +2101,8 @@
</span><span class="cx">                 0F6B1CC21862C47800845D97 /* FTLUnwindInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLUnwindInfo.h; path = ftl/FTLUnwindInfo.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6B1CC718641DF800845D97 /* ArityCheckFailReturnThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArityCheckFailReturnThunks.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6B1CC818641DF800845D97 /* ArityCheckFailReturnThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArityCheckFailReturnThunks.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F6C734E1AC9F99F00BE1682 /* VariableWriteFireDetail.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VariableWriteFireDetail.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F6C734F1AC9F99F00BE1682 /* VariableWriteFireDetail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariableWriteFireDetail.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F6E845919030BEF00562741 /* DFGVariableAccessData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVariableAccessData.cpp; path = dfg/DFGVariableAccessData.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6FC74E196110A800E1D02D /* ComplexGetStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ComplexGetStatus.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6FC74F196110A800E1D02D /* ComplexGetStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ComplexGetStatus.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2140,7 +2143,6 @@
</span><span class="cx">                 0F8F943F1667632D00D61971 /* CodeType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeType.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F8F94431667635200D61971 /* JITCode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITCode.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F8F9445166764EE00D61971 /* CodeOrigin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeOrigin.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0F9181C618415CA50057B669 /* VariableWatchpointSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariableWatchpointSet.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0F919D09157EE09D004A4E7D /* JSSymbolTableObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSymbolTableObject.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F919D0A157EE09D004A4E7D /* JSSymbolTableObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSymbolTableObject.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F919D0E157F3327004A4E7D /* JSSegmentedVariableObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSegmentedVariableObject.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2276,7 +2278,6 @@
</span><span class="cx">                 0FC97F3A18202119002C9B26 /* DFGJumpReplacement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGJumpReplacement.h; path = dfg/DFGJumpReplacement.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FC97F3B18202119002C9B26 /* DFGWatchpointCollectionPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGWatchpointCollectionPhase.cpp; path = dfg/DFGWatchpointCollectionPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FC97F3C18202119002C9B26 /* DFGWatchpointCollectionPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGWatchpointCollectionPhase.h; path = dfg/DFGWatchpointCollectionPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0FCA9112195E66A000426438 /* VariableWatchpointSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VariableWatchpointSet.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0FCB408515C0A3C30048932B /* SlotVisitorInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlotVisitorInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FCCAE4316D0CF6E00D0C65B /* ParserError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParserError.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FCEFAA91804C13E00472CE4 /* FTLSaveRestore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLSaveRestore.cpp; path = ftl/FTLSaveRestore.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2441,6 +2442,8 @@
</span><span class="cx">                 0FF729A0166AD347000F5BA3 /* ProfilerOrigin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerOrigin.h; path = profiler/ProfilerOrigin.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FF729A1166AD347000F5BA3 /* ProfilerOriginStack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerOriginStack.cpp; path = profiler/ProfilerOriginStack.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FF729A2166AD347000F5BA3 /* ProfilerOriginStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerOriginStack.h; path = profiler/ProfilerOriginStack.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0FF8BDE81AD4CF7100DFE884 /* InferredValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InferredValue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FF8BDE91AD4CF7100DFE884 /* InferredValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InferredValue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */ = {isa = PBXFileReference; explicitFileType = &quot;compiled.mach-o.executable&quot;; includeInIndex = 0; path = JSCLLIntOffsetsExtractor; sourceTree = BUILT_PRODUCTS_DIR; };
</span><span class="cx">                 0FFC99D0184EC8AD009C10AB /* ConstantMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstantMode.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FFC99D2184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayBufferNeuteringWatchpoint.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -3421,7 +3424,6 @@
</span><span class="cx">                 FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntCLoop.h; path = llint/LLIntCLoop.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FE4A331D15BD2E07006F54F3 /* VMInspector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMInspector.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FE4A331E15BD2E07006F54F3 /* VMInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMInspector.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                FE5248F8191442D900B7FDE4 /* VariableWatchpointSetInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariableWatchpointSetInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMEntryScope.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FE5932A6183C5A2600A1ECCC /* VMEntryScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMEntryScope.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FE7BA60D1A1A7CEC00F1F7B4 /* HeapVerifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeapVerifier.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4409,6 +4411,8 @@
</span><span class="cx">                                 0FB7F38E15ED8E3800F167B2 /* IndexingHeaderInlines.h */,
</span><span class="cx">                                 0F13E04C16164A1B00DC8DE7 /* IndexingType.cpp */,
</span><span class="cx">                                 0FB7F38F15ED8E3800F167B2 /* IndexingType.h */,
</span><ins>+                                0FF8BDE81AD4CF7100DFE884 /* InferredValue.cpp */,
+                                0FF8BDE91AD4CF7100DFE884 /* InferredValue.h */,
</ins><span class="cx">                                 E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */,
</span><span class="cx">                                 E178633F0D9BEC0000D74E75 /* InitializeThreading.h */,
</span><span class="cx">                                 A7A8AF2B17ADB5F3005AB174 /* Int8Array.h */,
</span><span class="lines">@@ -5277,9 +5281,8 @@
</span><span class="cx">                                 0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */,
</span><span class="cx">                                 0F24E55717F74EDB00ABB217 /* ValueRecovery.cpp */,
</span><span class="cx">                                 0F426A451460CBAB00131F8F /* ValueRecovery.h */,
</span><del>-                                0FCA9112195E66A000426438 /* VariableWatchpointSet.cpp */,
-                                0F9181C618415CA50057B669 /* VariableWatchpointSet.h */,
-                                FE5248F8191442D900B7FDE4 /* VariableWatchpointSetInlines.h */,
</del><ins>+                                0F6C734E1AC9F99F00BE1682 /* VariableWriteFireDetail.cpp */,
+                                0F6C734F1AC9F99F00BE1682 /* VariableWriteFireDetail.h */,
</ins><span class="cx">                                 0F20C2581A8013AB00DA3229 /* VirtualRegister.cpp */,
</span><span class="cx">                                 0F426A461460CBAB00131F8F /* VirtualRegister.h */,
</span><span class="cx">                                 0F919D2215853CDE004A4E7D /* Watchpoint.cpp */,
</span><span class="lines">@@ -5565,7 +5568,6 @@
</span><span class="cx">                                 C4F4B6F51A05C984005CAB76 /* generate_objc_protocol_types_implementation.py in Headers */,
</span><span class="cx">                                 A584032018BFFBE1005A0811 /* InspectorAgent.h in Headers */,
</span><span class="cx">                                 2AABCDE718EF294200002096 /* GCLogging.h in Headers */,
</span><del>-                                FE5248F9191442D900B7FDE4 /* VariableWatchpointSetInlines.h in Headers */,
</del><span class="cx">                                 FE7BA6101A1A7CEC00F1F7B4 /* HeapVerifier.h in Headers */,
</span><span class="cx">                                 A5EF9B141A1D43F600702E90 /* generate_cpp_backend_dispatcher_header.py in Headers */,
</span><span class="cx">                                 C2DA778318E259990066FCB6 /* HeapInlines.h in Headers */,
</span><span class="lines">@@ -6347,6 +6349,7 @@
</span><span class="cx">                                 A790DD6E182F499700588807 /* SetIteratorPrototype.h in Headers */,
</span><span class="cx">                                 A7299DA217D12848005F5FF9 /* SetPrototype.h in Headers */,
</span><span class="cx">                                 86AE64AA135E5E1C00963012 /* SH4Assembler.h in Headers */,
</span><ins>+                                0FF8BDEB1AD4CF7100DFE884 /* InferredValue.h in Headers */,
</ins><span class="cx">                                 0F2B670517B6B5AB00A7AE3F /* SimpleTypedArrayController.h in Headers */,
</span><span class="cx">                                 14BA78F113AAB88F005B7C2C /* SlotVisitor.h in Headers */,
</span><span class="cx">                                 0FB17661196B8F9E0091052A /* DFGHeapLocation.h in Headers */,
</span><span class="lines">@@ -6354,6 +6357,7 @@
</span><span class="cx">                                 A709F2F017A0AC0400512E98 /* SlowPathCall.h in Headers */,
</span><span class="cx">                                 933040040E6A749400786E6A /* SmallStrings.h in Headers */,
</span><span class="cx">                                 BC18C4640E16F5CD00B34460 /* SourceCode.h in Headers */,
</span><ins>+                                0F6C73511AC9F99F00BE1682 /* VariableWriteFireDetail.h in Headers */,
</ins><span class="cx">                                 BC18C4630E16F5CD00B34460 /* SourceProvider.h in Headers */,
</span><span class="cx">                                 70EC0EC31AA0D7DA00B6AAFA /* JSStringIterator.h in Headers */,
</span><span class="cx">                                 E49DC16C12EF294E00184A1F /* SourceProviderCache.h in Headers */,
</span><span class="lines">@@ -6421,7 +6425,6 @@
</span><span class="cx">                                 0F2E892C16D028AD009E4FD2 /* UnusedPointer.h in Headers */,
</span><span class="cx">                                 0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */,
</span><span class="cx">                                 0F426A481460CBB300131F8F /* ValueRecovery.h in Headers */,
</span><del>-                                0F9181C718415CA50057B669 /* VariableWatchpointSet.h in Headers */,
</del><span class="cx">                                 0F9C5E5F18E35F5E00D431C3 /* FTLDWARFRegister.h in Headers */,
</span><span class="cx">                                 0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */,
</span><span class="cx">                                 BC18C4200E16F5CD00B34460 /* VM.h in Headers */,
</span><span class="lines">@@ -6963,6 +6966,7 @@
</span><span class="cx">                                 A77F1821164088B200640A47 /* CodeCache.cpp in Sources */,
</span><span class="cx">                                 0F8F9446166764F100D61971 /* CodeOrigin.cpp in Sources */,
</span><span class="cx">                                 86B5826714D2796C00A9C306 /* CodeProfile.cpp in Sources */,
</span><ins>+                                0F6C73501AC9F99F00BE1682 /* VariableWriteFireDetail.cpp in Sources */,
</ins><span class="cx">                                 86B5826914D2797000A9C306 /* CodeProfiling.cpp in Sources */,
</span><span class="cx">                                 0F8F943C1667631300D61971 /* CodeSpecializationKind.cpp in Sources */,
</span><span class="cx">                                 0F8F94421667633500D61971 /* CodeType.cpp in Sources */,
</span><span class="lines">@@ -7027,7 +7031,6 @@
</span><span class="cx">                                 C2981FD817BAEE4B00A3BC98 /* DFGDesiredWeakReferences.cpp in Sources */,
</span><span class="cx">                                 C2981FDC17BAFF4400A3BC98 /* DFGDesiredWriteBarriers.cpp in Sources */,
</span><span class="cx">                                 0FF427641591A1CC004CB9FF /* DFGDisassembler.cpp in Sources */,
</span><del>-                                0FCA9113195E66A000426438 /* VariableWatchpointSet.cpp in Sources */,
</del><span class="cx">                                 0FD81AD2154FB4EE00983E72 /* DFGDominators.cpp in Sources */,
</span><span class="cx">                                 0FD3C82614115D4000FD81CB /* DFGDriver.cpp in Sources */,
</span><span class="cx">                                 0F2B9CE219D0BA7D00B1D1B5 /* DFGAvailabilityMap.cpp in Sources */,
</span><span class="lines">@@ -7331,6 +7334,7 @@
</span><span class="cx">                                 0F2B66FE17B6B5AB00A7AE3F /* JSTypedArrays.cpp in Sources */,
</span><span class="cx">                                 0FF054F91AC35B4400E5BE57 /* ExecutableAllocationFuzz.cpp in Sources */,
</span><span class="cx">                                 86E3C61A167BABEE006D760A /* JSValue.mm in Sources */,
</span><ins>+                                0FF8BDEA1AD4CF7100DFE884 /* InferredValue.cpp in Sources */,
</ins><span class="cx">                                 14BD5A320A3E91F600BAF59C /* JSValueRef.cpp in Sources */,
</span><span class="cx">                                 147F39D7107EC37600427A48 /* JSEnvironmentRecord.cpp in Sources */,
</span><span class="cx">                                 86E3C61C167BABEE006D760A /* JSVirtualMachine.mm in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeListjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeList.json (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -6,7 +6,6 @@
</span><span class="cx">             { &quot;name&quot; : &quot;op_enter&quot;, &quot;length&quot; : 1 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_create_lexical_environment&quot;, &quot;length&quot; : 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_get_scope&quot;, &quot;length&quot; : 2 },
</span><del>-            { &quot;name&quot; : &quot;op_touch_entry&quot;, &quot;length&quot; : 1 },
</del><span class="cx">             { &quot;name&quot; : &quot;op_create_direct_arguments&quot;, &quot;length&quot; : 2 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_create_scoped_arguments&quot;, &quot;length&quot; : 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_create_out_of_band_arguments&quot;, &quot;length&quot; : 2 },
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeUseDefh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -50,7 +50,6 @@
</span><span class="cx">     case op_new_object:
</span><span class="cx">     case op_enter:
</span><span class="cx">     case op_catch:
</span><del>-    case op_touch_entry:
</del><span class="cx">     case op_profile_control_flow:
</span><span class="cx">     case op_create_direct_arguments:
</span><span class="cx">     case op_create_out_of_band_arguments:
</span><span class="lines">@@ -278,7 +277,6 @@
</span><span class="cx">     case op_put_by_index:
</span><span class="cx">     case op_profile_type:
</span><span class="cx">     case op_profile_control_flow:
</span><del>-    case op_touch_entry:
</del><span class="cx">     case op_put_to_arguments:
</span><span class="cx"> #define LLINT_HELPER_OPCODES(opcode, length) case opcode:
</span><span class="cx">         FOR_EACH_LLINT_OPCODE_EXTENSION(LLINT_HELPER_OPCODES);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -758,10 +758,6 @@
</span><span class="cx">             printLocationAndOp(out, exec, location, it, &quot;enter&quot;);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><del>-        case op_touch_entry: {
-            printLocationAndOp(out, exec, location, it, &quot;touch_entry&quot;);
-            break;
-        }
</del><span class="cx">         case op_create_lexical_environment: {
</span><span class="cx">             int r0 = (++it)-&gt;u.operand;
</span><span class="cx">             int r1 = (++it)-&gt;u.operand;
</span><span class="lines">@@ -1957,7 +1953,7 @@
</span><span class="cx">             instructions[i + 4].u.operand = op.type;
</span><span class="cx">             instructions[i + 5].u.operand = op.depth;
</span><span class="cx">             if (op.lexicalEnvironment)
</span><del>-                instructions[i + 6].u.lexicalEnvironment.set(*vm(), ownerExecutable, op.lexicalEnvironment);
</del><ins>+                instructions[i + 6].u.symbolTable.set(*vm(), ownerExecutable, op.lexicalEnvironment-&gt;symbolTable());
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -1985,7 +1981,6 @@
</span><span class="cx">             else if (op.structure)
</span><span class="cx">                 instructions[i + 5].u.structure.set(*vm(), ownerExecutable, op.structure);
</span><span class="cx">             instructions[i + 6].u.pointer = reinterpret_cast&lt;void*&gt;(op.operand);
</span><del>-
</del><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2001,7 +1996,7 @@
</span><span class="cx">                     ConcurrentJITLocker locker(m_symbolTable-&gt;m_lock);
</span><span class="cx">                     SymbolTable::Map::iterator iter = m_symbolTable-&gt;find(locker, uid);
</span><span class="cx">                     ASSERT(iter != m_symbolTable-&gt;end(locker));
</span><del>-                    iter-&gt;value.prepareToWatch(symbolTable());
</del><ins>+                    iter-&gt;value.prepareToWatch();
</ins><span class="cx">                     instructions[i + 5].u.watchpointSet = iter-&gt;value.watchpointSet();
</span><span class="cx">                 } else
</span><span class="cx">                     instructions[i + 5].u.watchpointSet = nullptr;
</span><span class="lines">@@ -2546,12 +2541,15 @@
</span><span class="cx">                     curInstruction[3].u.toThisStatus, ToThisClearedByGC);
</span><span class="cx">                 break;
</span><span class="cx">             case op_resolve_scope: {
</span><del>-                WriteBarrierBase&lt;JSLexicalEnvironment&gt;&amp; lexicalEnvironment = curInstruction[6].u.lexicalEnvironment;
-                if (!lexicalEnvironment || Heap::isMarked(lexicalEnvironment.get()))
</del><ins>+                // Right now this isn't strictly necessary. Any symbol tables that this will refer to
+                // are for outer functions, and we refer to those functions strongly, and they refer
+                // to the symbol table strongly. But it's nice to be on the safe side.
+                WriteBarrierBase&lt;SymbolTable&gt;&amp; symbolTable = curInstruction[6].u.symbolTable;
+                if (!symbolTable || Heap::isMarked(symbolTable.get()))
</ins><span class="cx">                     break;
</span><span class="cx">                 if (Options::verboseOSR())
</span><del>-                    dataLogF(&quot;Clearing dead lexicalEnvironment %p.\n&quot;, lexicalEnvironment.get());
-                lexicalEnvironment.clear();
</del><ins>+                    dataLogF(&quot;Clearing dead symbolTable %p.\n&quot;, symbolTable.get());
+                symbolTable.clear();
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             case op_get_from_scope:
</span><span class="lines">@@ -3815,6 +3813,18 @@
</span><span class="cx">     return &quot;&quot;;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+ValueProfile* CodeBlock::valueProfileForBytecodeOffset(int bytecodeOffset)
+{
+    ValueProfile* result = binarySearch&lt;ValueProfile, int&gt;(
+        m_valueProfiles, m_valueProfiles.size(), bytecodeOffset,
+        getValueProfileBytecodeOffset&lt;ValueProfile&gt;);
+    ASSERT(result-&gt;m_bytecodeOffset != -1);
+    ASSERT(instructions()[bytecodeOffset + opcodeLength(
+        m_vm-&gt;interpreter-&gt;getOpcodeID(
+            instructions()[bytecodeOffset].u.opcode)) - 1].u.profile == result);
+    return result;
+}
+
</ins><span class="cx"> void CodeBlock::validate()
</span><span class="cx"> {
</span><span class="cx">     BytecodeLivenessAnalysis liveness(this); // Compute directly from scratch so it doesn't effect CodeBlock footprint.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -386,17 +386,7 @@
</span><span class="cx"> 
</span><span class="cx">     unsigned numberOfValueProfiles() { return m_valueProfiles.size(); }
</span><span class="cx">     ValueProfile* valueProfile(int index) { return &amp;m_valueProfiles[index]; }
</span><del>-    ValueProfile* valueProfileForBytecodeOffset(int bytecodeOffset)
-    {
-        ValueProfile* result = binarySearch&lt;ValueProfile, int&gt;(
-            m_valueProfiles, m_valueProfiles.size(), bytecodeOffset,
-            getValueProfileBytecodeOffset&lt;ValueProfile&gt;);
-        ASSERT(result-&gt;m_bytecodeOffset != -1);
-        ASSERT(instructions()[bytecodeOffset + opcodeLength(
-            m_vm-&gt;interpreter-&gt;getOpcodeID(
-                instructions()[bytecodeOffset].u.opcode)) - 1].u.profile == result);
-        return result;
-    }
</del><ins>+    ValueProfile* valueProfileForBytecodeOffset(int bytecodeOffset);
</ins><span class="cx">     SpeculatedType valueProfilePredictionForBytecodeOffset(const ConcurrentJITLocker&amp; locker, int bytecodeOffset)
</span><span class="cx">     {
</span><span class="cx">         return valueProfileForBytecodeOffset(bytecodeOffset)-&gt;computeUpdatedPrediction(locker);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeOrigincpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeOrigin.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeOrigin.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/bytecode/CodeOrigin.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -141,6 +141,18 @@
</span><span class="cx">     dump(out);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+JSFunction* InlineCallFrame::calleeConstant() const
+{
+    if (calleeRecovery.isConstant())
+        return jsCast&lt;JSFunction*&gt;(calleeRecovery.constant());
+    return nullptr;
+}
+
+void InlineCallFrame::visitAggregate(SlotVisitor&amp; visitor)
+{
+    visitor.append(&amp;executable);
+}
+
</ins><span class="cx"> JSFunction* InlineCallFrame::calleeForCallFrame(ExecState* exec) const
</span><span class="cx"> {
</span><span class="cx">     return jsCast&lt;JSFunction*&gt;(calleeRecovery.recover(exec));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeOriginh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeOrigin.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeOrigin.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/bytecode/CodeOrigin.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -28,7 +28,6 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CodeBlockHash.h&quot;
</span><span class="cx"> #include &quot;CodeSpecializationKind.h&quot;
</span><del>-#include &quot;JSFunction.h&quot;
</del><span class="cx"> #include &quot;ValueRecovery.h&quot;
</span><span class="cx"> #include &quot;WriteBarrier.h&quot;
</span><span class="cx"> #include &lt;wtf/BitVector.h&gt;
</span><span class="lines">@@ -207,17 +206,8 @@
</span><span class="cx">     
</span><span class="cx">     CodeSpecializationKind specializationKind() const { return specializationKindFor(static_cast&lt;Kind&gt;(kind)); }
</span><span class="cx"> 
</span><del>-    JSFunction* calleeConstant() const
-    {
-        if (calleeRecovery.isConstant())
-            return jsCast&lt;JSFunction*&gt;(calleeRecovery.constant());
-        return 0;
-    }
-
-    void visitAggregate(SlotVisitor&amp; visitor)
-    {
-        visitor.append(&amp;executable);
-    }
</del><ins>+    JSFunction* calleeConstant() const;
+    void visitAggregate(SlotVisitor&amp;);
</ins><span class="cx">     
</span><span class="cx">     // Get the callee given a machine call frame to which this InlineCallFrame belongs.
</span><span class="cx">     JSFunction* calleeForCallFrame(ExecState*) const;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeInstructionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/Instruction.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/Instruction.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/bytecode/Instruction.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;BasicBlockLocation.h&quot;
</span><span class="cx"> #include &quot;MacroAssembler.h&quot;
</span><span class="cx"> #include &quot;Opcode.h&quot;
</span><ins>+#include &quot;SymbolTable.h&quot;
</ins><span class="cx"> #include &quot;TypeLocation.h&quot;
</span><span class="cx"> #include &quot;PropertySlot.h&quot;
</span><span class="cx"> #include &quot;SpecialPointer.h&quot;
</span><span class="lines">@@ -46,7 +47,7 @@
</span><span class="cx"> class ArrayAllocationProfile;
</span><span class="cx"> class ArrayProfile;
</span><span class="cx"> class ObjectAllocationProfile;
</span><del>-class VariableWatchpointSet;
</del><ins>+class WatchpointSet;
</ins><span class="cx"> struct LLIntCallLinkInfo;
</span><span class="cx"> struct ValueProfile;
</span><span class="cx"> 
</span><span class="lines">@@ -106,6 +107,7 @@
</span><span class="cx">         Opcode opcode;
</span><span class="cx">         int operand;
</span><span class="cx">         WriteBarrierBase&lt;Structure&gt; structure;
</span><ins>+        WriteBarrierBase&lt;SymbolTable&gt; symbolTable;
</ins><span class="cx">         WriteBarrierBase&lt;StructureChain&gt; structureChain;
</span><span class="cx">         WriteBarrierBase&lt;JSCell&gt; jsCell;
</span><span class="cx">         WriteBarrier&lt;Unknown&gt;* variablePointer;
</span><span class="lines">@@ -117,8 +119,7 @@
</span><span class="cx">         ArrayProfile* arrayProfile;
</span><span class="cx">         ArrayAllocationProfile* arrayAllocationProfile;
</span><span class="cx">         ObjectAllocationProfile* objectAllocationProfile;
</span><del>-        VariableWatchpointSet* watchpointSet;
-        WriteBarrierBase&lt;JSLexicalEnvironment&gt; lexicalEnvironment;
</del><ins>+        WatchpointSet* watchpointSet;
</ins><span class="cx">         void* pointer;
</span><span class="cx">         bool* predicatePointer;
</span><span class="cx">         ToThisStatus toThisStatus;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeVariableWatchpointSetcpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSet.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSet.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSet.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -1,49 +0,0 @@
</span><del>-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include &quot;config.h&quot;
-#include &quot;VariableWatchpointSet.h&quot;
-
-#include &quot;JSCInlines.h&quot;
-
-namespace JSC {
-
-void VariableWriteFireDetail::dump(PrintStream&amp; out) const
-{
-    out.print(&quot;Write to &quot;, m_name, &quot; in &quot;, JSValue(m_object));
-}
-
-void VariableWatchpointSet::notifyWrite(VM&amp; vm, JSValue value, JSObject* baseObject, const PropertyName&amp; propertyName)
-{
-    notifyWrite(vm, value, VariableWriteFireDetail(baseObject, propertyName));
-}
-
-void VariableWatchpointSet::notifyWrite(VM&amp; vm, JSValue value, const char* reason)
-{
-    notifyWrite(vm, value, StringFireDetail(reason));
-}
-
-} // namespace JSC
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeVariableWatchpointSeth"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSet.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSet.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSet.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -1,110 +0,0 @@
</span><del>-/*
- * Copyright (C) 2012-2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef VariableWatchpointSet_h
-#define VariableWatchpointSet_h
-
-#include &quot;Watchpoint.h&quot;
-#include &quot;WriteBarrier.h&quot;
-
-namespace JSC {
-
-class JSObject;
-class SymbolTable;
-
-class VariableWriteFireDetail : public FireDetail {
-public:
-    VariableWriteFireDetail(JSObject* object, const PropertyName&amp; name)
-        : m_object(object)
-        , m_name(name)
-    {
-    }
-    
-    virtual void dump(PrintStream&amp;) const override;
-
-private:
-    JSObject* m_object;
-    const PropertyName&amp; m_name;
-};
-
-class VariableWatchpointSet : public WatchpointSet {
-    friend class LLIntOffsetsExtractor;
-public:
-    VariableWatchpointSet(SymbolTable&amp; symbolTable)
-        : WatchpointSet(ClearWatchpoint)
-        , m_symbolTable(symbolTable)
-    {
-    }
-    
-    ~VariableWatchpointSet() { }
-    
-    // For the purpose of deciding whether or not to watch this variable, you only need
-    // to inspect inferredValue(). If this returns something other than the empty
-    // value, then it means that at all future safepoints, this watchpoint set will be
-    // in one of these states:
-    //
-    //    IsWatched: in this case, the variable's value must still be the
-    //        inferredValue.
-    //
-    //    IsInvalidated: in this case the variable's value may be anything but you'll
-    //        either notice that it's invalidated and not install the watchpoint, or
-    //        you will have been notified that the watchpoint was fired.
-    JSValue inferredValue() const { return m_inferredValue.get(); }
-    
-    void notifyWrite(VM&amp;, JSValue, const FireDetail&amp;);
-    JS_EXPORT_PRIVATE void notifyWrite(VM&amp;, JSValue, JSObject* baseObject, const PropertyName&amp;);
-    void notifyWrite(VM&amp;, JSValue, const char* reason);
-    
-    void invalidate(const FireDetail&amp; detail)
-    {
-        m_inferredValue.clear();
-        WatchpointSet::invalidate(detail);
-    }
-    
-    void finalizeUnconditionally(const FireDetail&amp; detail)
-    {
-        ASSERT(!!m_inferredValue == (state() == IsWatched));
-        if (!m_inferredValue)
-            return;
-        JSValue inferredValue = m_inferredValue.get();
-        if (!inferredValue.isCell())
-            return;
-        JSCell* cell = inferredValue.asCell();
-        if (Heap::isMarked(cell))
-            return;
-        invalidate(detail);
-    }
-
-    WriteBarrier&lt;Unknown&gt;* addressOfInferredValue() { return &amp;m_inferredValue; }
-    
-private:
-    SymbolTable&amp; m_symbolTable;
-    WriteBarrier&lt;Unknown&gt; m_inferredValue;
-};
-
-} // namespace JSC
-
-#endif // VariableWatchpointSet_h
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeVariableWatchpointSetInlinesh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSetInlines.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSetInlines.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/bytecode/VariableWatchpointSetInlines.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -1,60 +0,0 @@
</span><del>-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#ifndef VariableWatchpointSetInlines_h
-#define VariableWatchpointSetInlines_h
-
-#include &quot;SymbolTable.h&quot;
-#include &quot;VariableWatchpointSet.h&quot;
-
-namespace JSC {
-
-inline void VariableWatchpointSet::notifyWrite(VM&amp; vm, JSValue value, const FireDetail&amp; detail)
-{
-    ASSERT(!!value);
-    switch (state()) {
-    case ClearWatchpoint:
-        m_inferredValue.set(vm, &amp;m_symbolTable, value);
-        startWatching();
-        return;
-
-    case IsWatched:
-        ASSERT(!!m_inferredValue);
-        if (value == m_inferredValue.get())
-            return;
-        invalidate(detail);
-        return;
-            
-    case IsInvalidated:
-        ASSERT(!m_inferredValue);
-        return;
-    }
-        
-    ASSERT_NOT_REACHED();
-}
-
-} // namespace JSC
-
-#endif // VariableWatchpointSetInlines_h
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeVariableWriteFireDetailcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/bytecode/VariableWriteFireDetail.cpp (0 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/VariableWriteFireDetail.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/VariableWriteFireDetail.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -0,0 +1,44 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;VariableWriteFireDetail.h&quot;
+
+#include &quot;JSCInlines.h&quot;
+
+namespace JSC {
+
+void VariableWriteFireDetail::dump(PrintStream&amp; out) const
+{
+    out.print(&quot;Write to &quot;, m_name, &quot; in &quot;, JSValue(m_object));
+}
+
+void VariableWriteFireDetail::touch(WatchpointSet* set, JSObject* object, const PropertyName&amp; name)
+{
+    set-&gt;touch(VariableWriteFireDetail(object, name));
+}
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeVariableWriteFireDetailh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/bytecode/VariableWriteFireDetail.h (0 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/VariableWriteFireDetail.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/VariableWriteFireDetail.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -0,0 +1,55 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef VariableWriteFireDetail_h
+#define VariableWriteFireDetail_h
+
+#include &quot;Watchpoint.h&quot;
+
+namespace JSC {
+
+class JSObject;
+class PropertyName;
+
+class VariableWriteFireDetail : public FireDetail {
+public:
+    VariableWriteFireDetail(JSObject* object, const PropertyName&amp; name)
+        : m_object(object)
+        , m_name(name)
+    {
+    }
+    
+    virtual void dump(PrintStream&amp;) const override;
+    
+    JS_EXPORT_PRIVATE static void touch(WatchpointSet*, JSObject*, const PropertyName&amp;);
+
+private:
+    JSObject* m_object;
+    const PropertyName&amp; m_name;
+};
+
+} // namespace JSC
+
+#endif // VariableWriteFireDetail_h
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeWatchpointh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/Watchpoint.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/Watchpoint.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/bytecode/Watchpoint.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -34,6 +34,8 @@
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx"> class FireDetail {
</span><ins>+    void* operator new(size_t) = delete;
+    
</ins><span class="cx"> public:
</span><span class="cx">     FireDetail()
</span><span class="cx">     {
</span><span class="lines">@@ -87,6 +89,12 @@
</span><span class="cx">     JS_EXPORT_PRIVATE WatchpointSet(WatchpointState);
</span><span class="cx">     JS_EXPORT_PRIVATE ~WatchpointSet(); // Note that this will not fire any of the watchpoints; if you need to know when a WatchpointSet dies then you need a separate mechanism for this.
</span><span class="cx">     
</span><ins>+    // Fast way of getting the state, which only works from the main thread.
+    WatchpointState stateOnJSThread() const
+    {
+        return static_cast&lt;WatchpointState&gt;(m_state);
+    }
+    
</ins><span class="cx">     // It is safe to call this from another thread. It may return an old
</span><span class="cx">     // state. Guarantees that if *first* read the state() of the thing being
</span><span class="cx">     // watched and it returned IsWatched and *second* you actually read its
</span><span class="lines">@@ -125,20 +133,24 @@
</span><span class="cx">     // set watchpoints that we believe will actually be fired.
</span><span class="cx">     void startWatching()
</span><span class="cx">     {
</span><del>-        ASSERT(state() != IsInvalidated);
</del><ins>+        ASSERT(m_state != IsInvalidated);
+        if (m_state == IsWatched)
+            return;
+        WTF::storeStoreFence();
</ins><span class="cx">         m_state = IsWatched;
</span><ins>+        WTF::storeStoreFence();
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void fireAll(const FireDetail&amp; detail)
</span><span class="cx">     {
</span><del>-        if (LIKELY(state() != IsWatched))
</del><ins>+        if (LIKELY(m_state != IsWatched))
</ins><span class="cx">             return;
</span><span class="cx">         fireAllSlow(detail);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void fireAll(const char* reason)
</span><span class="cx">     {
</span><del>-        if (LIKELY(state() != IsWatched))
</del><ins>+        if (LIKELY(m_state != IsWatched))
</ins><span class="cx">             return;
</span><span class="cx">         fireAllSlow(reason);
</span><span class="cx">     }
</span><span class="lines">@@ -151,13 +163,23 @@
</span><span class="cx">             fireAll(detail);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void touch(const char* reason)
+    {
+        touch(StringFireDetail(reason));
+    }
+    
</ins><span class="cx">     void invalidate(const FireDetail&amp; detail)
</span><span class="cx">     {
</span><span class="cx">         if (state() == IsWatched)
</span><span class="cx">             fireAll(detail);
</span><span class="cx">         m_state = IsInvalidated;
</span><span class="cx">     }
</span><del>-
</del><ins>+    
+    void invalidate(const char* reason)
+    {
+        invalidate(StringFireDetail(reason));
+    }
+    
</ins><span class="cx">     int8_t* addressOfState() { return &amp;m_state; }
</span><span class="cx">     int8_t* addressOfSetIsNotEmpty() { return &amp;m_setIsNotEmpty; }
</span><span class="cx">     
</span><span class="lines">@@ -209,18 +231,34 @@
</span><span class="cx">         freeFat();
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    // Fast way of getting the state, which only works from the main thread.
+    WatchpointState stateOnJSThread() const
+    {
+        uintptr_t data = m_data;
+        if (isFat(data))
+            return fat(data)-&gt;stateOnJSThread();
+        return decodeState(data);
+    }
+
+    // It is safe to call this from another thread. It may return a prior state,
+    // but that should be fine since you should only perform actions based on the
+    // state if you also add a watchpoint.
+    WatchpointState state() const
+    {
+        WTF::loadLoadFence();
+        uintptr_t data = m_data;
+        WTF::loadLoadFence();
+        if (isFat(data))
+            return fat(data)-&gt;state();
+        return decodeState(data);
+    }
+    
</ins><span class="cx">     // It is safe to call this from another thread.  It may return false
</span><span class="cx">     // even if the set actually had been invalidated, but that ought to happen
</span><span class="cx">     // only in the case of races, and should be rare.
</span><span class="cx">     bool hasBeenInvalidated() const
</span><span class="cx">     {
</span><del>-        WTF::loadLoadFence();
-        uintptr_t data = m_data;
-        if (isFat(data)) {
-            WTF::loadLoadFence();
-            return fat(data)-&gt;hasBeenInvalidated();
-        }
-        return decodeState(data) == IsInvalidated;
</del><ins>+        return state() == IsInvalidated;
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     // Like hasBeenInvalidated(), may be called from another thread.
</span><span class="lines">@@ -253,6 +291,14 @@
</span><span class="cx">         WTF::storeStoreFence();
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void invalidate(const FireDetail&amp; detail)
+    {
+        if (isFat())
+            fat()-&gt;invalidate(detail);
+        else
+            m_data = encodeState(IsInvalidated);
+    }
+    
</ins><span class="cx">     JS_EXPORT_PRIVATE void fireAll(const char* reason);
</span><span class="cx">     
</span><span class="cx">     void touch(const FireDetail&amp; detail)
</span><span class="lines">@@ -261,7 +307,11 @@
</span><span class="cx">             fat()-&gt;touch(detail);
</span><span class="cx">             return;
</span><span class="cx">         }
</span><del>-        if (decodeState(m_data) == ClearWatchpoint)
</del><ins>+        uintptr_t data = m_data;
+        if (decodeState(data) == IsInvalidated)
+            return;
+        WTF::storeStoreFence();
+        if (decodeState(data) == ClearWatchpoint)
</ins><span class="cx">             m_data = encodeState(IsWatched);
</span><span class="cx">         else
</span><span class="cx">             m_data = encodeState(IsInvalidated);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -466,9 +466,6 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    if (m_symbolTable-&gt;scopeSize())
-        emitOpcode(op_touch_entry);
-
</del><span class="cx">     if (isConstructor()) {
</span><span class="cx">         if (constructorKind() == ConstructorKind::Derived) {
</span><span class="cx">             m_newTargetRegister = addVar();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -1342,6 +1342,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     case CreateThis: {
</span><ins>+        // FIXME: We can fold this to NewObject if the incoming callee is a constant.
</ins><span class="cx">         forNode(node).setType(SpecFinalObject);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="lines">@@ -1401,6 +1402,15 @@
</span><span class="cx">         break;
</span><span class="cx">         
</span><span class="cx">     case GetCallee:
</span><ins>+        if (FunctionExecutable* executable = jsDynamicCast&lt;FunctionExecutable*&gt;(m_codeBlock-&gt;ownerExecutable())) {
+            InferredValue* singleton = executable-&gt;singletonFunction();
+            if (JSValue value = singleton-&gt;inferredValue()) {
+                m_graph.watchpoints().addLazily(singleton);
+                JSFunction* function = jsCast&lt;JSFunction*&gt;(value);
+                setConstant(node, *m_graph.freeze(function));
+                break;
+            }
+        }
</ins><span class="cx">         forNode(node).setType(SpecFunction);
</span><span class="cx">         break;
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -215,8 +215,6 @@
</span><span class="cx">         bool isDirect);
</span><span class="cx">     void emitChecks(const ConstantStructureCheckVector&amp;);
</span><span class="cx"> 
</span><del>-    Node* getScope(VirtualRegister scopeChain, unsigned skipCount);
-    
</del><span class="cx">     void prepareToParseBlock();
</span><span class="cx">     void clearCaches();
</span><span class="cx"> 
</span><span class="lines">@@ -279,8 +277,20 @@
</span><span class="cx">                 if (operand.offset() == JSStack::Callee)
</span><span class="cx">                     return weakJSConstant(callee);
</span><span class="cx">             }
</span><del>-        } else if (operand.offset() == JSStack::Callee)
</del><ins>+        } else if (operand.offset() == JSStack::Callee) {
+            // We have to do some constant-folding here because this enables CreateThis folding. Note
+            // that we don't have such watchpoint-based folding for inlined uses of Callee, since in that
+            // case if the function is a singleton then we already know it.
+            if (FunctionExecutable* executable = jsDynamicCast&lt;FunctionExecutable*&gt;(m_codeBlock-&gt;ownerExecutable())) {
+                InferredValue* singleton = executable-&gt;singletonFunction();
+                if (JSValue value = singleton-&gt;inferredValue()) {
+                    m_graph.watchpoints().addLazily(singleton);
+                    JSFunction* function = jsCast&lt;JSFunction*&gt;(value);
+                    return weakJSConstant(function);
+                }
+            }
</ins><span class="cx">             return addToGraph(GetCallee);
</span><ins>+        }
</ins><span class="cx">         
</span><span class="cx">         return getDirect(m_inlineStackTop-&gt;remapOperand(operand));
</span><span class="cx">     }
</span><span class="lines">@@ -2534,14 +2544,6 @@
</span><span class="cx">     m_constants.resize(0);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Node* ByteCodeParser::getScope(VirtualRegister scopeChain, unsigned skipCount)
-{
-    Node* localBase = get(scopeChain);
-    for (unsigned n = skipCount; n--;)
-        localBase = addToGraph(SkipScope, localBase);
-    return localBase;
-}
-
</del><span class="cx"> bool ByteCodeParser::parseBlock(unsigned limit)
</span><span class="cx"> {
</span><span class="cx">     bool shouldContinueParsing = true;
</span><span class="lines">@@ -2611,11 +2613,6 @@
</span><span class="cx">             NEXT_OPCODE(op_enter);
</span><span class="cx">         }
</span><span class="cx">             
</span><del>-        case op_touch_entry:
-            if (m_inlineStackTop-&gt;m_codeBlock-&gt;symbolTable()-&gt;m_functionEnteredOnce.isStillValid())
-                addToGraph(ForceOSRExit);
-            NEXT_OPCODE(op_touch_entry);
-            
</del><span class="cx">         case op_to_this: {
</span><span class="cx">             Node* op1 = getThis();
</span><span class="cx">             if (op1-&gt;op() != ToThis) {
</span><span class="lines">@@ -3393,17 +3390,28 @@
</span><span class="cx">             case LocalClosureVar:
</span><span class="cx">             case ClosureVar:
</span><span class="cx">             case ClosureVarWithVarInjectionChecks: {
</span><del>-                JSLexicalEnvironment* lexicalEnvironment = currentInstruction[6].u.lexicalEnvironment.get();
-                if (lexicalEnvironment
-                    &amp;&amp; lexicalEnvironment-&gt;symbolTable()-&gt;m_functionEnteredOnce.isStillValid()) {
-                    m_graph.watchpoints().addLazily(lexicalEnvironment-&gt;symbolTable()-&gt;m_functionEnteredOnce);
-                    addToGraph(Phantom, getDirect(m_inlineStackTop-&gt;remapOperand(VirtualRegister(currentInstruction[2].u.operand))));
-                    set(VirtualRegister(dst), weakJSConstant(lexicalEnvironment));
</del><ins>+                Node* localBase = get(VirtualRegister(currentInstruction[2].u.operand));
+                addToGraph(Phantom, localBase); // OSR exit cannot handle resolve_scope on a DCE'd scope.
+                
+                // We have various forms of constant folding here. This is necessary to avoid
+                // spurious recompiles in dead-but-foldable code.
+                if (SymbolTable* symbolTable = currentInstruction[6].u.symbolTable.get()) {
+                    InferredValue* singleton = symbolTable-&gt;singletonScope();
+                    if (JSValue value = singleton-&gt;inferredValue()) {
+                        m_graph.watchpoints().addLazily(singleton);
+                        set(VirtualRegister(dst), weakJSConstant(value));
+                        break;
+                    }
+                }
+                if (JSScope* scope = localBase-&gt;dynamicCastConstant&lt;JSScope*&gt;()) {
+                    for (unsigned n = depth; n--;)
+                        scope = scope-&gt;next();
+                    set(VirtualRegister(dst), weakJSConstant(scope));
</ins><span class="cx">                     break;
</span><span class="cx">                 }
</span><del>-                set(VirtualRegister(dst), getScope(VirtualRegister(currentInstruction[2].u.operand), depth));
-                if (inlineCallFrame())
-                    addToGraph(Phantom, getDirect(m_inlineStackTop-&gt;remapOperand(VirtualRegister(currentInstruction[2].u.operand))));
</del><ins>+                for (unsigned n = depth; n--;)
+                    localBase = addToGraph(SkipScope, localBase);
+                set(VirtualRegister(dst), localBase);
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             case Dynamic:
</span><span class="lines">@@ -3455,19 +3463,67 @@
</span><span class="cx">             case GlobalVar:
</span><span class="cx">             case GlobalVarWithVarInjectionChecks: {
</span><span class="cx">                 addToGraph(Phantom, get(VirtualRegister(scope)));
</span><del>-                ConcurrentJITLocker locker(globalObject-&gt;symbolTable()-&gt;m_lock);
-                SymbolTableEntry entry = globalObject-&gt;symbolTable()-&gt;get(locker, uid);
-                VariableWatchpointSet* watchpointSet = entry.watchpointSet();
-                JSValue inferredValue =
-                    watchpointSet ? watchpointSet-&gt;inferredValue() : JSValue();
-                if (!inferredValue) {
-                    SpeculatedType prediction = getPrediction();
-                    set(VirtualRegister(dst), addToGraph(GetGlobalVar, OpInfo(operand), OpInfo(prediction)));
-                    break;
</del><ins>+                WatchpointSet* watchpointSet;
+                ScopeOffset offset;
+                {
+                    ConcurrentJITLocker locker(globalObject-&gt;symbolTable()-&gt;m_lock);
+                    SymbolTableEntry entry = globalObject-&gt;symbolTable()-&gt;get(locker, uid);
+                    watchpointSet = entry.watchpointSet();
+                    offset = entry.scopeOffset();
</ins><span class="cx">                 }
</span><ins>+                if (watchpointSet &amp;&amp; watchpointSet-&gt;state() == IsWatched) {
+                    // This has a fun concurrency story. There is the possibility of a race in two
+                    // directions:
+                    //
+                    // We see that the set IsWatched, but in the meantime it gets invalidated: this is
+                    // fine because if we saw that it IsWatched then we add a watchpoint. If it gets
+                    // invalidated, then this compilation is invalidated. Note that in the meantime we
+                    // may load an absurd value from the global object. It's fine to load an absurd
+                    // value if the compilation is invalidated anyway.
+                    //
+                    // We see that the set IsWatched, but the value isn't yet initialized: this isn't
+                    // possible because of the ordering of operations.
+                    //
+                    // Here's how we order operations:
+                    //
+                    // Main thread stores to the global object: always store a value first, and only
+                    // after that do we touch the watchpoint set. There is a fence in the touch, that
+                    // ensures that the store to the global object always happens before the touch on the
+                    // set.
+                    //
+                    // Compilation thread: always first load the state of the watchpoint set, and then
+                    // load the value. The WatchpointSet::state() method does fences for us to ensure
+                    // that the load of the state happens before our load of the value.
+                    //
+                    // Finalizing compilation: this happens on the main thread and synchronously checks
+                    // validity of all watchpoint sets.
+                    //
+                    // We will only perform optimizations if the load of the state yields IsWatched. That
+                    // means that at least one store would have happened to initialize the original value
+                    // of the variable (that is, the value we'd like to constant fold to). There may be
+                    // other stores that happen after that, but those stores will invalidate the
+                    // watchpoint set and also the compilation.
+                    
+                    // Note that we need to use the operand, which is a direct pointer at the global,
+                    // rather than looking up the global by doing variableAt(offset). That's because the
+                    // internal data structures of JSSegmentedVariableObject are not thread-safe even
+                    // though accessing the global itself is. The segmentation involves a vector spine
+                    // that resizes with malloc/free, so if new globals unrelated to the one we are
+                    // reading are added, we might access freed memory if we do variableAt().
+                    WriteBarrier&lt;Unknown&gt;* pointer = bitwise_cast&lt;WriteBarrier&lt;Unknown&gt;*&gt;(operand);
+                    
+                    ASSERT(globalObject-&gt;findVariableIndex(pointer) == offset);
+                    
+                    JSValue value = pointer-&gt;get();
+                    if (value) {
+                        m_graph.watchpoints().addLazily(watchpointSet);
+                        set(VirtualRegister(dst), weakJSConstant(value));
+                        break;
+                    }
+                }
</ins><span class="cx">                 
</span><del>-                m_graph.watchpoints().addLazily(watchpointSet);
-                set(VirtualRegister(dst), weakJSConstant(inferredValue));
</del><ins>+                SpeculatedType prediction = getPrediction();
+                set(VirtualRegister(dst), addToGraph(GetGlobalVar, OpInfo(operand), OpInfo(prediction)));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             case LocalClosureVar:
</span><span class="lines">@@ -3484,6 +3540,10 @@
</span><span class="cx">                 // won't be able to handle an Undefined scope.
</span><span class="cx">                 addToGraph(Phantom, scopeNode);
</span><span class="cx">                 
</span><ins>+                // Constant folding in the bytecode parser is important for performance. This may not
+                // have executed yet. If it hasn't, then we won't have a prediction. Lacking a
+                // prediction, we'd otherwise think that it has to exit. Then when it did execute, we
+                // would recompile. But if we can fold it here, we avoid the exit.
</ins><span class="cx">                 if (JSValue value = m_graph.tryGetConstantClosureVar(scopeNode, ScopeOffset(operand))) {
</span><span class="cx">                     set(VirtualRegister(dst), weakJSConstant(value));
</span><span class="cx">                     break;
</span><span class="lines">@@ -3514,7 +3574,7 @@
</span><span class="cx">                 uid = nullptr;
</span><span class="cx">             
</span><span class="cx">             Structure* structure = nullptr;
</span><del>-            VariableWatchpointSet* watchpoints = nullptr;
</del><ins>+            WatchpointSet* watchpoints = nullptr;
</ins><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><span class="lines">@@ -3557,8 +3617,10 @@
</span><span class="cx">                 }
</span><span class="cx">                 Node* valueNode = get(VirtualRegister(value));
</span><span class="cx">                 addToGraph(PutGlobalVar, OpInfo(operand), valueNode);
</span><del>-                if (watchpoints &amp;&amp; watchpoints-&gt;state() != IsInvalidated)
-                    addToGraph(NotifyWrite, OpInfo(watchpoints), valueNode);
</del><ins>+                if (watchpoints &amp;&amp; watchpoints-&gt;state() != IsInvalidated) {
+                    // Must happen after the store. See comment for GetGlobalVar.
+                    addToGraph(NotifyWrite, OpInfo(watchpoints));
+                }
</ins><span class="cx">                 // Keep scope alive until after put.
</span><span class="cx">                 addToGraph(Phantom, get(VirtualRegister(scope)));
</span><span class="cx">                 break;
</span><span class="lines">@@ -3569,10 +3631,12 @@
</span><span class="cx">                 Node* scopeNode = get(VirtualRegister(scope));
</span><span class="cx">                 Node* valueNode = get(VirtualRegister(value));
</span><span class="cx"> 
</span><del>-                if (watchpoints &amp;&amp; watchpoints-&gt;state() != IsInvalidated)
-                    addToGraph(NotifyWrite, OpInfo(watchpoints), valueNode);
</del><ins>+                addToGraph(PutClosureVar, OpInfo(operand), scopeNode, valueNode);
</ins><span class="cx"> 
</span><del>-                addToGraph(PutClosureVar, OpInfo(operand), scopeNode, valueNode);
</del><ins>+                if (watchpoints &amp;&amp; watchpoints-&gt;state() != IsInvalidated) {
+                    // Must happen after the store. See comment for GetGlobalVar.
+                    addToGraph(NotifyWrite, OpInfo(watchpoints));
+                }
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             case Dynamic:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -96,7 +96,6 @@
</span><span class="cx">     
</span><span class="cx">     switch (opcodeID) {
</span><span class="cx">     case op_enter:
</span><del>-    case op_touch_entry:
</del><span class="cx">     case op_to_this:
</span><span class="cx">     case op_check_tdz:
</span><span class="cx">     case op_create_this:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -311,10 +311,14 @@
</span><span class="cx">         write(SideState);
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    case CreateActivation:
</del><ins>+    case CreateActivation: {
+        SymbolTable* table = graph.symbolTableFor(node-&gt;origin.semantic);
+        if (table-&gt;singletonScope()-&gt;isStillValid())
+            write(Watchpoint_fire);
</ins><span class="cx">         read(HeapObjectCount);
</span><span class="cx">         write(HeapObjectCount);
</span><span class="cx">         return;
</span><ins>+    }
</ins><span class="cx">         
</span><span class="cx">     case CreateDirectArguments:
</span><span class="cx">     case CreateScopedArguments:
</span><span class="lines">@@ -858,11 +862,17 @@
</span><span class="cx">     case NewStringObject:
</span><span class="cx">     case PhantomNewObject:
</span><span class="cx">     case MaterializeNewObject:
</span><ins>+        read(HeapObjectCount);
+        write(HeapObjectCount);
+        return;
+        
</ins><span class="cx">     case NewFunction:
</span><ins>+        if (node-&gt;castOperand&lt;FunctionExecutable*&gt;()-&gt;singletonFunction()-&gt;isStillValid())
+            write(Watchpoint_fire);
</ins><span class="cx">         read(HeapObjectCount);
</span><span class="cx">         write(HeapObjectCount);
</span><span class="cx">         return;
</span><del>-        
</del><ins>+
</ins><span class="cx">     case RegExpExec:
</span><span class="cx">     case RegExpTest:
</span><span class="cx">         read(RegExpState);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDesiredWatchpointscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -44,6 +44,13 @@
</span><span class="cx">     codeBlock-&gt;vm()-&gt;heap.addReference(neuteringWatchpoint, view-&gt;buffer());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void InferredValueAdaptor::add(
+    CodeBlock* codeBlock, InferredValue* inferredValue, Watchpoint* watchpoint)
+{
+    codeBlock-&gt;addConstant(inferredValue); // For common users, it doesn't really matter if it's weak or not. If references to it go away, we go away, too.
+    inferredValue-&gt;add(watchpoint);
+}
+
</ins><span class="cx"> DesiredWatchpoints::DesiredWatchpoints() { }
</span><span class="cx"> DesiredWatchpoints::~DesiredWatchpoints() { }
</span><span class="cx"> 
</span><span class="lines">@@ -57,6 +64,11 @@
</span><span class="cx">     m_inlineSets.addLazily(&amp;set);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void DesiredWatchpoints::addLazily(InferredValue* inferredValue)
+{
+    m_inferredValues.addLazily(inferredValue);
+}
+
</ins><span class="cx"> void DesiredWatchpoints::addLazily(JSArrayBufferView* view)
</span><span class="cx"> {
</span><span class="cx">     m_bufferViews.addLazily(view);
</span><span class="lines">@@ -74,6 +86,7 @@
</span><span class="cx"> {
</span><span class="cx">     m_sets.reallyAdd(codeBlock, commonData);
</span><span class="cx">     m_inlineSets.reallyAdd(codeBlock, commonData);
</span><ins>+    m_inferredValues.reallyAdd(codeBlock, commonData);
</ins><span class="cx">     m_bufferViews.reallyAdd(codeBlock, commonData);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -81,6 +94,7 @@
</span><span class="cx"> {
</span><span class="cx">     return m_sets.areStillValid()
</span><span class="cx">         &amp;&amp; m_inlineSets.areStillValid()
</span><ins>+        &amp;&amp; m_inferredValues.areStillValid()
</ins><span class="cx">         &amp;&amp; m_bufferViews.areStillValid();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDesiredWatchpointsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CodeOrigin.h&quot;
</span><span class="cx"> #include &quot;DFGCommonData.h&quot;
</span><ins>+#include &quot;InferredValue.h&quot;
</ins><span class="cx"> #include &quot;JSArrayBufferView.h&quot;
</span><span class="cx"> #include &quot;Watchpoint.h&quot;
</span><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="lines">@@ -50,6 +51,14 @@
</span><span class="cx">     static bool hasBeenInvalidated(T* set) { return set-&gt;hasBeenInvalidated(); }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+struct InferredValueAdaptor {
+    static void add(CodeBlock*, InferredValue*, Watchpoint*);
+    static bool hasBeenInvalidated(InferredValue* inferredValue)
+    {
+        return inferredValue-&gt;hasBeenInvalidated();
+    }
+};
+
</ins><span class="cx"> struct ArrayBufferViewWatchpointAdaptor {
</span><span class="cx">     static void add(CodeBlock*, JSArrayBufferView*, Watchpoint*);
</span><span class="cx">     static bool hasBeenInvalidated(JSArrayBufferView* view)
</span><span class="lines">@@ -119,6 +128,7 @@
</span><span class="cx">     
</span><span class="cx">     void addLazily(WatchpointSet*);
</span><span class="cx">     void addLazily(InlineWatchpointSet&amp;);
</span><ins>+    void addLazily(InferredValue*);
</ins><span class="cx">     void addLazily(JSArrayBufferView*);
</span><span class="cx">     
</span><span class="cx">     bool consider(Structure*);
</span><span class="lines">@@ -135,6 +145,10 @@
</span><span class="cx">     {
</span><span class="cx">         return m_inlineSets.isWatched(&amp;set);
</span><span class="cx">     }
</span><ins>+    bool isWatched(InferredValue* inferredValue)
+    {
+        return m_inferredValues.isWatched(inferredValue);
+    }
</ins><span class="cx">     bool isWatched(JSArrayBufferView* view)
</span><span class="cx">     {
</span><span class="cx">         return m_bufferViews.isWatched(view);
</span><span class="lines">@@ -143,6 +157,7 @@
</span><span class="cx"> private:
</span><span class="cx">     GenericDesiredWatchpoints&lt;WatchpointSet&gt; m_sets;
</span><span class="cx">     GenericDesiredWatchpoints&lt;InlineWatchpointSet&gt; m_inlineSets;
</span><ins>+    GenericDesiredWatchpoints&lt;InferredValue, InferredValueAdaptor&gt; m_inferredValues;
</ins><span class="cx">     GenericDesiredWatchpoints&lt;JSArrayBufferView, ArrayBufferViewWatchpointAdaptor&gt; m_bufferViews;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -311,8 +311,8 @@
</span><span class="cx">         out.print(comma, &quot;^&quot;, node-&gt;phi()-&gt;index());
</span><span class="cx">     if (node-&gt;hasExecutionCounter())
</span><span class="cx">         out.print(comma, RawPointer(node-&gt;executionCounter()));
</span><del>-    if (node-&gt;hasVariableWatchpointSet())
-        out.print(comma, RawPointer(node-&gt;variableWatchpointSet()));
</del><ins>+    if (node-&gt;hasWatchpointSet())
+        out.print(comma, RawPointer(node-&gt;watchpointSet()));
</ins><span class="cx">     if (node-&gt;hasStoragePointer())
</span><span class="cx">         out.print(comma, RawPointer(node-&gt;storagePointer()));
</span><span class="cx">     if (node-&gt;hasObjectMaterializationData())
</span><span class="lines">@@ -1026,6 +1026,8 @@
</span><span class="cx"> 
</span><span class="cx"> JSValue Graph::tryGetConstantClosureVar(JSValue base, ScopeOffset offset)
</span><span class="cx"> {
</span><ins>+    // This has an awesome concurrency story. See comment for GetGlobalVar in ByteCodeParser.
+    
</ins><span class="cx">     if (!base)
</span><span class="cx">         return JSValue();
</span><span class="cx">     
</span><span class="lines">@@ -1034,24 +1036,28 @@
</span><span class="cx">         return JSValue();
</span><span class="cx">     
</span><span class="cx">     SymbolTable* symbolTable = activation-&gt;symbolTable();
</span><del>-    ConcurrentJITLocker locker(symbolTable-&gt;m_lock);
</del><ins>+    JSValue value;
+    WatchpointSet* set;
+    {
+        ConcurrentJITLocker locker(symbolTable-&gt;m_lock);
+        
+        SymbolTableEntry* entry = symbolTable-&gt;entryFor(locker, offset);
+        if (!entry)
+            return JSValue();
+        
+        set = entry-&gt;watchpointSet();
+        if (!set)
+            return JSValue();
+        
+        if (set-&gt;state() != IsWatched)
+            return JSValue();
+        
+        ASSERT(entry-&gt;scopeOffset() == offset);
+        value = activation-&gt;variableAt(offset).get();
+        if (!value)
+            return JSValue();
+    }
</ins><span class="cx">     
</span><del>-    if (symbolTable-&gt;m_functionEnteredOnce.hasBeenInvalidated())
-        return JSValue();
-    
-    SymbolTableEntry* entry = symbolTable-&gt;entryFor(locker, offset);
-    if (!entry)
-        return JSValue();
-    
-    VariableWatchpointSet* set = entry-&gt;watchpointSet();
-    if (!set)
-        return JSValue();
-    
-    JSValue value = set-&gt;inferredValue();
-    if (!value)
-        return JSValue();
-    
-    watchpoints().addLazily(symbolTable-&gt;m_functionEnteredOnce);
</del><span class="cx">     watchpoints().addLazily(set);
</span><span class="cx">     
</span><span class="cx">     return value;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -1219,14 +1219,14 @@
</span><span class="cx">         m_opInfo = bitwise_cast&lt;uintptr_t&gt;(value);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool hasVariableWatchpointSet()
</del><ins>+    bool hasWatchpointSet()
</ins><span class="cx">     {
</span><span class="cx">         return op() == NotifyWrite;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    VariableWatchpointSet* variableWatchpointSet()
</del><ins>+    WatchpointSet* watchpointSet()
</ins><span class="cx">     {
</span><del>-        return reinterpret_cast&lt;VariableWatchpointSet*&gt;(m_opInfo);
</del><ins>+        return reinterpret_cast&lt;WatchpointSet*&gt;(m_opInfo);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     bool hasStoragePointer()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -1077,13 +1077,12 @@
</span><span class="cx">     return static_cast&lt;char*&gt;(exec-&gt;codeBlock()-&gt;stringSwitchJumpTable(tableIndex).ctiForValue(string-&gt;value(exec).impl()).executableAddress());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JIT_OPERATION operationNotifyWrite(ExecState* exec, VariableWatchpointSet* set, EncodedJSValue encodedValue)
</del><ins>+void JIT_OPERATION operationNotifyWrite(ExecState* exec, WatchpointSet* set)
</ins><span class="cx"> {
</span><span class="cx">     VM&amp; vm = exec-&gt;vm();
</span><span class="cx">     NativeCallFrameTracer tracer(&amp;vm, exec);
</span><del>-    JSValue value = JSValue::decode(encodedValue);
</del><span class="cx"> 
</span><del>-    set-&gt;notifyWrite(vm, value, &quot;Executed NotifyWrite&quot;);
</del><ins>+    set-&gt;touch(&quot;Executed NotifyWrite&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JIT_OPERATION operationThrowStackOverflowForVarargs(ExecState* exec)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -127,7 +127,7 @@
</span><span class="cx"> JSCell* JIT_OPERATION operationMakeRope3(ExecState*, JSString*, JSString*, JSString*);
</span><span class="cx"> char* JIT_OPERATION operationFindSwitchImmTargetForDouble(ExecState*, EncodedJSValue, size_t tableIndex);
</span><span class="cx"> char* JIT_OPERATION operationSwitchString(ExecState*, size_t tableIndex, JSString*);
</span><del>-void JIT_OPERATION operationNotifyWrite(ExecState*, VariableWatchpointSet*, EncodedJSValue);
</del><ins>+void JIT_OPERATION operationNotifyWrite(ExecState*, WatchpointSet*);
</ins><span class="cx"> void JIT_OPERATION operationThrowStackOverflowForVarargs(ExecState*) WTF_INTERNAL;
</span><span class="cx"> int32_t JIT_OPERATION operationSizeOfVarargs(ExecState*, EncodedJSValue arguments, int32_t firstVarArgOffset);
</span><span class="cx"> void JIT_OPERATION operationLoadVarargs(ExecState*, int32_t firstElementDest, EncodedJSValue arguments, int32_t offset, int32_t length, int32_t mandatoryMinimum);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -4367,8 +4367,13 @@
</span><span class="cx">     SpeculateCellOperand scope(this, node-&gt;child1());
</span><span class="cx">     GPRReg scopeGPR = scope.gpr();
</span><span class="cx">     flushRegisters();
</span><del>-    callOperation(
-        operationNewFunction, resultGPR, scopeGPR, node-&gt;castOperand&lt;FunctionExecutable*&gt;());
</del><ins>+    FunctionExecutable* executable = node-&gt;castOperand&lt;FunctionExecutable*&gt;();
+    J_JITOperation_EJscC function;
+    if (executable-&gt;singletonFunction()-&gt;isStillValid())
+        function = operationNewFunction;
+    else
+        function = operationNewFunctionWithInvalidatedReallocationWatchpoint;
+    callOperation(function, resultGPR, scopeGPR, executable);
</ins><span class="cx">     cellResult(resultGPR, node);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -4436,19 +4441,31 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::compileCreateActivation(Node* node)
</span><span class="cx"> {
</span><ins>+    SymbolTable* table = m_jit.graph().symbolTableFor(node-&gt;origin.semantic);
+    Structure* structure = m_jit.graph().globalObjectFor(
+        node-&gt;origin.semantic)-&gt;activationStructure();
+        
</ins><span class="cx">     SpeculateCellOperand scope(this, node-&gt;child1());
</span><ins>+    GPRReg scopeGPR = scope.gpr();
+    
+    if (table-&gt;singletonScope()-&gt;isStillValid()) {
+        GPRFlushedCallResult result(this);
+        GPRReg resultGPR = result.gpr();
+        
+        flushRegisters();
+        
+        callOperation(operationCreateActivationDirect, resultGPR, structure, scopeGPR, table);
+        cellResult(resultGPR, node);
+        return;
+    }
+    
</ins><span class="cx">     GPRTemporary result(this);
</span><span class="cx">     GPRTemporary scratch1(this);
</span><span class="cx">     GPRTemporary scratch2(this);
</span><del>-    GPRReg scopeGPR = scope.gpr();
</del><span class="cx">     GPRReg resultGPR = result.gpr();
</span><span class="cx">     GPRReg scratch1GPR = scratch1.gpr();
</span><span class="cx">     GPRReg scratch2GPR = scratch2.gpr();
</span><span class="cx">         
</span><del>-    SymbolTable* table = m_jit.graph().symbolTableFor(node-&gt;origin.semantic);
-    Structure* structure = m_jit.graph().globalObjectFor(
-        node-&gt;origin.semantic)-&gt;activationStructure();
-        
</del><span class="cx">     JITCompiler::JumpList slowPath;
</span><span class="cx">     emitAllocateJSObjectWithKnownSize&lt;JSLexicalEnvironment&gt;(
</span><span class="cx">         resultGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratch1GPR, scratch2GPR,
</span><span class="lines">@@ -4714,6 +4731,21 @@
</span><span class="cx">     cellResult(resultGPR, node);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SpeculativeJIT::compileNotifyWrite(Node* node)
+{
+    WatchpointSet* set = node-&gt;watchpointSet();
+    
+    JITCompiler::Jump slowCase = m_jit.branch8(
+        JITCompiler::NotEqual,
+        JITCompiler::AbsoluteAddress(set-&gt;addressOfState()),
+        TrustedImm32(IsInvalidated));
+    
+    addSlowPathGenerator(
+        slowPathCall(slowCase, this, operationNotifyWrite, NoResult, set));
+    
+    noResult(node);
+}
+
</ins><span class="cx"> bool SpeculativeJIT::compileRegExpExec(Node* node)
</span><span class="cx"> {
</span><span class="cx">     unsigned branchIndexInBlock = detectPeepHoleBranch();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -1200,6 +1200,12 @@
</span><span class="cx">         return appendCallWithExceptionCheckSetResult(operation, result);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    JITCompiler::Call callOperation(V_JITOperation_EWs operation, WatchpointSet* watchpointSet)
+    {
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(watchpointSet));
+        return appendCall(operation);
+    }
+
</ins><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx">     JITCompiler::Call callOperation(J_JITOperation_E operation, GPRReg result)
</span><span class="cx">     {
</span><span class="lines">@@ -1460,12 +1466,6 @@
</span><span class="cx">         return appendCallWithExceptionCheck(operation);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    JITCompiler::Call callOperation(V_JITOperation_EVwsJ operation, VariableWatchpointSet* watchpointSet, GPRReg arg)
-    {
-        m_jit.setupArgumentsWithExecState(TrustedImmPtr(watchpointSet), arg);
-        return appendCall(operation);
-    }
-
</del><span class="cx">     JITCompiler::Call callOperation(D_JITOperation_EJ operation, FPRReg result, GPRReg arg1)
</span><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(arg1);
</span><span class="lines">@@ -1776,12 +1776,6 @@
</span><span class="cx">         return appendCallWithExceptionCheck(operation);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    JITCompiler::Call callOperation(V_JITOperation_EVwsJ operation, VariableWatchpointSet* watchpointSet, GPRReg argTag, GPRReg argPayload)
-    {
-        m_jit.setupArgumentsWithExecState(TrustedImmPtr(watchpointSet), argPayload, argTag);
-        return appendCall(operation);
-    }
-
</del><span class="cx">     JITCompiler::Call callOperation(D_JITOperation_EJ operation, FPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
</span><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
</span><span class="lines">@@ -2213,6 +2207,7 @@
</span><span class="cx">     void compilePutToArguments(Node*);
</span><span class="cx">     void compileCreateScopedArguments(Node*);
</span><span class="cx">     void compileCreateClonedArguments(Node*);
</span><ins>+    void compileNotifyWrite(Node*);
</ins><span class="cx">     bool compileRegExpExec(Node*);
</span><span class="cx">     
</span><span class="cx">     JITCompiler::Jump branchIsCell(JSValueRegs);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -3994,32 +3994,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     case NotifyWrite: {
</span><del>-        VariableWatchpointSet* set = node-&gt;variableWatchpointSet();
-    
-        JSValueOperand value(this, node-&gt;child1());
-        GPRReg valueTagGPR = value.tagGPR();
-        GPRReg valuePayloadGPR = value.payloadGPR();
-    
-        GPRTemporary temp(this);
-        GPRReg tempGPR = temp.gpr();
-    
-        m_jit.load8(set-&gt;addressOfState(), tempGPR);
-    
-        JITCompiler::Jump isDone = m_jit.branch32(JITCompiler::Equal, tempGPR, TrustedImm32(IsInvalidated));
-        JITCompiler::JumpList notifySlow;
-        notifySlow.append(m_jit.branch32(
-            JITCompiler::NotEqual,
-            JITCompiler::AbsoluteAddress(set-&gt;addressOfInferredValue()-&gt;payloadPointer()),
-            valuePayloadGPR));
-        notifySlow.append(m_jit.branch32(
-            JITCompiler::NotEqual, 
-            JITCompiler::AbsoluteAddress(set-&gt;addressOfInferredValue()-&gt;tagPointer()),
-            valueTagGPR));
-        addSlowPathGenerator(
-            slowPathCall(notifySlow, this, operationNotifyWrite, NoResult, set, valueTagGPR, valuePayloadGPR));
-        isDone.link(&amp;m_jit);
-    
-        noResult(node);
</del><ins>+        compileNotifyWrite(node);
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -4019,26 +4019,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     case NotifyWrite: {
</span><del>-        VariableWatchpointSet* set = node-&gt;variableWatchpointSet();
-    
-        JSValueOperand value(this, node-&gt;child1());
-        GPRReg valueGPR = value.gpr();
-    
-        GPRTemporary temp(this);
-        GPRReg tempGPR = temp.gpr();
-    
-        m_jit.load8(set-&gt;addressOfState(), tempGPR);
-    
-        JITCompiler::Jump isDone =
-            m_jit.branch32(JITCompiler::Equal, tempGPR, TrustedImm32(IsInvalidated));
-        JITCompiler::Jump slowCase = m_jit.branch64(JITCompiler::NotEqual,
-            JITCompiler::AbsoluteAddress(set-&gt;addressOfInferredValue()), valueGPR);
-        isDone.link(&amp;m_jit);
-    
-        addSlowPathGenerator(
-            slowPathCall(slowCase, this, operationNotifyWrite, NoResult, set, valueGPR));
-
-        noResult(node);
</del><ins>+        compileNotifyWrite(node);
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGVarargsForwardingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;DFGClobberize.h&quot;
</span><span class="cx"> #include &quot;DFGGraph.h&quot;
</span><span class="cx"> #include &quot;DFGPhase.h&quot;
</span><ins>+#include &quot;JSCInlines.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLIntrinsicRepositoryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -105,7 +105,7 @@
</span><span class="cx">     macro(V_JITOperation_EOZJ, functionType(voidType, intPtr, intPtr, int32, int64)) \
</span><span class="cx">     macro(V_JITOperation_EC, functionType(voidType, intPtr, intPtr)) \
</span><span class="cx">     macro(V_JITOperation_ECb, functionType(voidType, intPtr, intPtr)) \
</span><del>-    macro(V_JITOperation_EVwsJ, functionType(voidType, intPtr, intPtr, int64)) \
</del><ins>+    macro(V_JITOperation_EWs, functionType(voidType, intPtr, intPtr)) \
</ins><span class="cx">     macro(V_JITOperation_EZJZZZ, functionType(voidType, intPtr, int32, int64, int32, int32, int32)) \
</span><span class="cx">     macro(V_JITOperation_J, functionType(voidType, int64)) \
</span><span class="cx">     macro(V_JITOperation_Z, functionType(voidType, int32)) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -2877,6 +2877,14 @@
</span><span class="cx">         SymbolTable* table = m_graph.symbolTableFor(m_node-&gt;origin.semantic);
</span><span class="cx">         Structure* structure = m_graph.globalObjectFor(m_node-&gt;origin.semantic)-&gt;activationStructure();
</span><span class="cx">         
</span><ins>+        if (table-&gt;singletonScope()-&gt;isStillValid()) {
+            LValue callResult = vmCall(
+                m_out.operation(operationCreateActivationDirect), m_callFrame, weakPointer(structure),
+                scope, weakPointer(table));
+            setJSValue(callResult);
+            return;
+        }
+        
</ins><span class="cx">         LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, (&quot;CreateActivation slow path&quot;));
</span><span class="cx">         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;CreateActivation continuation&quot;));
</span><span class="cx">         
</span><span class="lines">@@ -2912,9 +2920,16 @@
</span><span class="cx">     
</span><span class="cx">     void compileNewFunction()
</span><span class="cx">     {
</span><ins>+        FunctionExecutable* executable = m_node-&gt;castOperand&lt;FunctionExecutable*&gt;();
+        J_JITOperation_EJscC function;
+        if (executable-&gt;singletonFunction()-&gt;isStillValid())
+            function = operationNewFunction;
+        else
+            function = operationNewFunctionWithInvalidatedReallocationWatchpoint;
+        
</ins><span class="cx">         LValue result = vmCall(
</span><del>-            m_out.operation(operationNewFunction), m_callFrame,
-            lowCell(m_node-&gt;child1()), weakPointer(m_node-&gt;castOperand&lt;FunctionExecutable*&gt;()));
</del><ins>+            m_out.operation(function), m_callFrame, lowCell(m_node-&gt;child1()),
+            weakPointer(executable));
</ins><span class="cx">         setJSValue(result);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -3783,29 +3798,19 @@
</span><span class="cx">     
</span><span class="cx">     void compileNotifyWrite()
</span><span class="cx">     {
</span><del>-        VariableWatchpointSet* set = m_node-&gt;variableWatchpointSet();
</del><ins>+        WatchpointSet* set = m_node-&gt;watchpointSet();
</ins><span class="cx">         
</span><del>-        LValue value = lowJSValue(m_node-&gt;child1());
-        
</del><span class="cx">         LBasicBlock isNotInvalidated = FTL_NEW_BLOCK(m_out, (&quot;NotifyWrite not invalidated case&quot;));
</span><del>-        LBasicBlock notifySlow = FTL_NEW_BLOCK(m_out, (&quot;NotifyWrite notify slow case&quot;));
</del><span class="cx">         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;NotifyWrite continuation&quot;));
</span><span class="cx">         
</span><span class="cx">         LValue state = m_out.load8(m_out.absolute(set-&gt;addressOfState()));
</span><del>-        
</del><span class="cx">         m_out.branch(
</span><span class="cx">             m_out.equal(state, m_out.constInt8(IsInvalidated)),
</span><span class="cx">             usually(continuation), rarely(isNotInvalidated));
</span><span class="cx">         
</span><del>-        LBasicBlock lastNext = m_out.appendTo(isNotInvalidated, notifySlow);
</del><ins>+        LBasicBlock lastNext = m_out.appendTo(isNotInvalidated, continuation);
</ins><span class="cx"> 
</span><del>-        m_out.branch(
-            m_out.equal(value, m_out.load64(m_out.absolute(set-&gt;addressOfInferredValue()))),
-            unsure(continuation), unsure(notifySlow));
-
-        m_out.appendTo(notifySlow, continuation);
-
-        vmCall(m_out.operation(operationNotifyWrite), m_callFrame, m_out.constIntPtr(set), value);
</del><ins>+        vmCall(m_out.operation(operationNotifyWrite), m_callFrame, m_out.constIntPtr(set));
</ins><span class="cx">         m_out.jump(continuation);
</span><span class="cx">         
</span><span class="cx">         m_out.appendTo(continuation, lastNext);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterInterpretercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -89,6 +89,47 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+String StackFrame::friendlySourceURL() const
+{
+    String traceLine;
+    
+    switch (codeType) {
+    case StackFrameEvalCode:
+    case StackFrameFunctionCode:
+    case StackFrameGlobalCode:
+        if (!sourceURL.isEmpty())
+            traceLine = sourceURL.impl();
+        break;
+    case StackFrameNativeCode:
+        traceLine = &quot;[native code]&quot;;
+        break;
+    }
+    return traceLine.isNull() ? emptyString() : traceLine;
+}
+
+String StackFrame::friendlyFunctionName(CallFrame* callFrame) const
+{
+    String traceLine;
+    JSObject* stackFrameCallee = callee.get();
+
+    switch (codeType) {
+    case StackFrameEvalCode:
+        traceLine = &quot;eval code&quot;;
+        break;
+    case StackFrameNativeCode:
+        if (callee)
+            traceLine = getCalculatedDisplayName(callFrame, stackFrameCallee).impl();
+        break;
+    case StackFrameFunctionCode:
+        traceLine = getCalculatedDisplayName(callFrame, stackFrameCallee).impl();
+        break;
+    case StackFrameGlobalCode:
+        traceLine = &quot;global code&quot;;
+        break;
+    }
+    return traceLine.isNull() ? emptyString() : traceLine;
+}
+
</ins><span class="cx"> JSValue eval(CallFrame* callFrame)
</span><span class="cx"> {
</span><span class="cx">     if (!callFrame-&gt;argumentCount())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterInterpreterh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/Interpreter.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/Interpreter.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/interpreter/Interpreter.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -33,7 +33,6 @@
</span><span class="cx"> #include &quot;ArgList.h&quot;
</span><span class="cx"> #include &quot;JSCJSValue.h&quot;
</span><span class="cx"> #include &quot;JSCell.h&quot;
</span><del>-#include &quot;JSFunction.h&quot;
</del><span class="cx"> #include &quot;JSObject.h&quot;
</span><span class="cx"> #include &quot;JSStack.h&quot;
</span><span class="cx"> #include &quot;LLIntData.h&quot;
</span><span class="lines">@@ -51,6 +50,7 @@
</span><span class="cx">     class ExecutableBase;
</span><span class="cx">     class FunctionExecutable;
</span><span class="cx">     class VM;
</span><ins>+    class JSFunction;
</ins><span class="cx">     class JSGlobalObject;
</span><span class="cx">     class LLIntOffsetsExtractor;
</span><span class="cx">     class ProgramExecutable;
</span><span class="lines">@@ -90,45 +90,8 @@
</span><span class="cx">         unsigned bytecodeOffset;
</span><span class="cx">         String sourceURL;
</span><span class="cx">         JS_EXPORT_PRIVATE String toString(CallFrame*);
</span><del>-        String friendlySourceURL() const
-        {
-            String traceLine;
-
-            switch (codeType) {
-            case StackFrameEvalCode:
-            case StackFrameFunctionCode:
-            case StackFrameGlobalCode:
-                if (!sourceURL.isEmpty())
-                    traceLine = sourceURL.impl();
-                break;
-            case StackFrameNativeCode:
-                traceLine = &quot;[native code]&quot;;
-                break;
-            }
-            return traceLine.isNull() ? emptyString() : traceLine;
-        }
-        String friendlyFunctionName(CallFrame* callFrame) const
-        {
-            String traceLine;
-            JSObject* stackFrameCallee = callee.get();
-
-            switch (codeType) {
-            case StackFrameEvalCode:
-                traceLine = &quot;eval code&quot;;
-                break;
-            case StackFrameNativeCode:
-                if (callee)
-                    traceLine = getCalculatedDisplayName(callFrame, stackFrameCallee).impl();
-                break;
-            case StackFrameFunctionCode:
-                traceLine = getCalculatedDisplayName(callFrame, stackFrameCallee).impl();
-                break;
-            case StackFrameGlobalCode:
-                traceLine = &quot;global code&quot;;
-                break;
-            }
-            return traceLine.isNull() ? emptyString() : traceLine;
-        }
</del><ins>+        String friendlySourceURL() const;
+        String friendlyFunctionName(CallFrame*) const;
</ins><span class="cx">         JS_EXPORT_PRIVATE void computeLineAndColumn(unsigned&amp; line, unsigned&amp; column);
</span><span class="cx"> 
</span><span class="cx">     private:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/jit/JIT.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -105,6 +105,14 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+void JIT::emitNotifyWrite(WatchpointSet* set)
+{
+    if (!set || set-&gt;state() == IsInvalidated)
+        return;
+    
+    addSlowCase(branch8(NotEqual, AbsoluteAddress(set-&gt;addressOfState()), TrustedImm32(IsInvalidated)));
+}
+
</ins><span class="cx"> void JIT::assertStackPointerOffset()
</span><span class="cx"> {
</span><span class="cx">     if (ASSERT_DISABLED)
</span><span class="lines">@@ -189,7 +197,6 @@
</span><span class="cx">         DEFINE_SLOW_OP(is_object_or_null)
</span><span class="cx">         DEFINE_SLOW_OP(typeof)
</span><span class="cx"> 
</span><del>-        DEFINE_OP(op_touch_entry)
</del><span class="cx">         DEFINE_OP(op_add)
</span><span class="cx">         DEFINE_OP(op_bitand)
</span><span class="cx">         DEFINE_OP(op_bitor)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/jit/JIT.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -457,7 +457,6 @@
</span><span class="cx">         
</span><span class="cx">         void assertStackPointerOffset();
</span><span class="cx"> 
</span><del>-        void emit_op_touch_entry(Instruction*);
</del><span class="cx">         void emit_op_add(Instruction*);
</span><span class="cx">         void emit_op_bitand(Instruction*);
</span><span class="cx">         void emit_op_bitor(Instruction*);
</span><span class="lines">@@ -640,13 +639,9 @@
</span><span class="cx">         void emitGetGlobalVar(uintptr_t operand);
</span><span class="cx">         void emitGetClosureVar(int scope, uintptr_t operand);
</span><span class="cx">         void emitPutGlobalProperty(uintptr_t* operandSlot, int value);
</span><del>-#if USE(JSVALUE64)
-        void emitNotifyWrite(RegisterID value, RegisterID scratch, VariableWatchpointSet*);
-#else
-        void emitNotifyWrite(RegisterID tag, RegisterID payload, RegisterID scratch, VariableWatchpointSet*);
-#endif
-        void emitPutGlobalVar(uintptr_t operand, int value, VariableWatchpointSet*);
-        void emitPutClosureVar(int scope, uintptr_t operand, int value, VariableWatchpointSet*);
</del><ins>+        void emitNotifyWrite(WatchpointSet*);
+        void emitPutGlobalVar(uintptr_t operand, int value, WatchpointSet*);
+        void emitPutClosureVar(int scope, uintptr_t operand, int value, WatchpointSet*);
</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 (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -879,15 +879,6 @@
</span><span class="cx"> 
</span><span class="cx"> #endif // USE(JSVALUE64)
</span><span class="cx"> 
</span><del>-void JIT::emit_op_touch_entry(Instruction* currentInstruction)
-{
-    if (m_codeBlock-&gt;symbolTable()-&gt;m_functionEnteredOnce.hasBeenInvalidated())
-        return;
-    
-    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_touch_entry);
-    slowPathCall.call();
-}
-
</del><span class="cx"> void JIT::emit_op_loop_hint(Instruction*)
</span><span class="cx"> {
</span><span class="cx">     // Emit the JIT optimization check: 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -952,6 +952,14 @@
</span><span class="cx">     return JSValue::encode(JSFunction::create(vm, static_cast&lt;FunctionExecutable*&gt;(functionExecutable), scope));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+EncodedJSValue JIT_OPERATION operationNewFunctionWithInvalidatedReallocationWatchpoint(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
+{
+    ASSERT(functionExecutable-&gt;inherits(FunctionExecutable::info()));
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+    return JSValue::encode(JSFunction::createWithInvalidatedReallocationWatchpoint(vm, static_cast&lt;FunctionExecutable*&gt;(functionExecutable), scope));
+}
+
</ins><span class="cx"> JSCell* JIT_OPERATION operationNewObject(ExecState* exec, Structure* structure)
</span><span class="cx"> {
</span><span class="cx">     VM* vm = &amp;exec-&gt;vm();
</span><span class="lines">@@ -1722,8 +1730,8 @@
</span><span class="cx">     if (modeAndType.type() == LocalClosureVar) {
</span><span class="cx">         JSLexicalEnvironment* environment = jsCast&lt;JSLexicalEnvironment*&gt;(scope);
</span><span class="cx">         environment-&gt;variableAt(ScopeOffset(pc[6].u.operand)).set(vm, environment, value);
</span><del>-        if (VariableWatchpointSet* set = pc[5].u.watchpointSet)
-            set-&gt;notifyWrite(vm, value, &quot;Executed op_put_scope&lt;LocalClosureVar&gt;&quot;);
</del><ins>+        if (WatchpointSet* set = pc[5].u.watchpointSet)
+            set-&gt;touch(&quot;Executed op_put_scope&lt;LocalClosureVar&gt;&quot;);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     if (modeAndType.mode() == ThrowIfNotFound &amp;&amp; !scope-&gt;hasProperty(exec, ident)) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -37,7 +37,6 @@
</span><span class="cx"> #include &quot;PutKind.h&quot;
</span><span class="cx"> #include &quot;SpillRegistersMode.h&quot;
</span><span class="cx"> #include &quot;StructureStubInfo.h&quot;
</span><del>-#include &quot;VariableWatchpointSet.h&quot;
</del><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -85,7 +84,7 @@
</span><span class="cx">     Symtab: SymbolTable*
</span><span class="cx">     V: void
</span><span class="cx">     Vm: VM*
</span><del>-    Vws: VariableWatchpointSet*
</del><ins>+    Ws: WatchpointSet*
</ins><span class="cx">     Z: int32_t
</span><span class="cx"> */
</span><span class="cx"> 
</span><span class="lines">@@ -191,7 +190,7 @@
</span><span class="cx"> typedef void JIT_OPERATION (*V_JITOperation_EPc)(ExecState*, Instruction*);
</span><span class="cx"> typedef void JIT_OPERATION (*V_JITOperation_EPZJ)(ExecState*, void*, int32_t, EncodedJSValue);
</span><span class="cx"> typedef void JIT_OPERATION (*V_JITOperation_ESsiJJI)(ExecState*, StructureStubInfo*, EncodedJSValue, EncodedJSValue, StringImpl*);
</span><del>-typedef void JIT_OPERATION (*V_JITOperation_EVwsJ)(ExecState*, VariableWatchpointSet*, EncodedJSValue);
</del><ins>+typedef void JIT_OPERATION (*V_JITOperation_EWs)(ExecState*, WatchpointSet*);
</ins><span class="cx"> typedef void JIT_OPERATION (*V_JITOperation_EZ)(ExecState*, int32_t);
</span><span class="cx"> typedef void JIT_OPERATION (*V_JITOperation_EZJ)(ExecState*, int32_t, EncodedJSValue);
</span><span class="cx"> typedef void JIT_OPERATION (*V_JITOperation_EZJZZZ)(ExecState*, int32_t, EncodedJSValue, int32_t, int32_t, int32_t);
</span><span class="lines">@@ -278,6 +277,7 @@
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationNewArrayBufferWithProfile(ExecState*, ArrayAllocationProfile*, const JSValue* values, int32_t size) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationNewArrayWithSizeAndProfile(ExecState*, ArrayAllocationProfile*, EncodedJSValue size) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationNewFunction(ExecState*, JSScope*, JSCell*) WTF_INTERNAL;
</span><ins>+EncodedJSValue JIT_OPERATION operationNewFunctionWithInvalidatedReallocationWatchpoint(ExecState*, JSScope*, JSCell*) WTF_INTERNAL;
</ins><span class="cx"> JSCell* JIT_OPERATION operationNewObject(ExecState*, Structure*) WTF_INTERNAL;
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationNewRegexp(ExecState*, void*) WTF_INTERNAL;
</span><span class="cx"> void JIT_OPERATION operationHandleWatchdogTimer(ExecState*) WTF_INTERNAL;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITPropertyAccesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -728,29 +728,18 @@
</span><span class="cx">     storePtr(regT2, BaseIndex(regT0, regT1, TimesEight, (firstOutOfLineOffset - 2) * sizeof(EncodedJSValue)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JIT::emitNotifyWrite(RegisterID value, RegisterID scratch, VariableWatchpointSet* set)
</del><ins>+void JIT::emitPutGlobalVar(uintptr_t operand, int value, WatchpointSet* set)
</ins><span class="cx"> {
</span><del>-    if (!set || set-&gt;state() == IsInvalidated)
-        return;
-    
-    load8(set-&gt;addressOfState(), scratch);
-    Jump isDone = branch32(Equal, scratch, TrustedImm32(IsInvalidated));
-    addSlowCase(branch64(NotEqual, AbsoluteAddress(set-&gt;addressOfInferredValue()), value));
-    isDone.link(this);
-}
-
-void JIT::emitPutGlobalVar(uintptr_t operand, int value, VariableWatchpointSet* set)
-{
</del><span class="cx">     emitGetVirtualRegister(value, regT0);
</span><del>-    emitNotifyWrite(regT0, regT1, set);
</del><ins>+    emitNotifyWrite(set);
</ins><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, VariableWatchpointSet* set)
</del><ins>+void JIT::emitPutClosureVar(int scope, uintptr_t operand, int value, WatchpointSet* set)
</ins><span class="cx"> {
</span><span class="cx">     emitGetVirtualRegister(value, regT1);
</span><span class="cx">     emitGetVirtualRegister(scope, regT0);
</span><del>-    emitNotifyWrite(regT1, regT2, set);
</del><ins>+    emitNotifyWrite(set);
</ins><span class="cx">     storePtr(regT1, Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register)));
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITPropertyAccess32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -750,36 +750,19 @@
</span><span class="cx">     store32(regT2, BaseIndex(regT0, regT1, TimesEight, (firstOutOfLineOffset - 2) * sizeof(EncodedJSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JIT::emitNotifyWrite(RegisterID tag, RegisterID payload, RegisterID scratch, VariableWatchpointSet* set)
</del><ins>+void JIT::emitPutGlobalVar(uintptr_t operand, int value, WatchpointSet* set)
</ins><span class="cx"> {
</span><del>-    if (!set || set-&gt;state() == IsInvalidated)
-        return;
-    
-    load8(set-&gt;addressOfState(), scratch);
-    Jump isDone = branch32(Equal, scratch, TrustedImm32(IsInvalidated));
-
-    JumpList notifySlow = branch32(
-        NotEqual, AbsoluteAddress(set-&gt;addressOfInferredValue()-&gt;payloadPointer()), payload);
-    notifySlow.append(branch32(
-        NotEqual, AbsoluteAddress(set-&gt;addressOfInferredValue()-&gt;tagPointer()), tag));
-    addSlowCase(notifySlow);
-
-    isDone.link(this);
-}
-
-void JIT::emitPutGlobalVar(uintptr_t operand, int value, VariableWatchpointSet* set)
-{
</del><span class="cx">     emitLoad(value, regT1, regT0);
</span><del>-    emitNotifyWrite(regT1, regT0, regT2, set);
</del><ins>+    emitNotifyWrite(set);
</ins><span class="cx">     store32(regT1, reinterpret_cast&lt;char*&gt;(operand) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
</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, VariableWatchpointSet* set)
</del><ins>+void JIT::emitPutClosureVar(int scope, uintptr_t operand, int value, WatchpointSet* set)
</ins><span class="cx"> {
</span><span class="cx">     emitLoad(value, regT3, regT2);
</span><span class="cx">     emitLoad(scope, regT1, regT0);
</span><del>-    emitNotifyWrite(regT3, regT2, regT4, set);
</del><ins>+    emitNotifyWrite(set);
</ins><span class="cx">     store32(regT3, Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register) + TagOffset));
</span><span class="cx">     store32(regT2, Address(regT0, JSEnvironmentRecord::offsetOfVariables() + operand * sizeof(Register) + PayloadOffset));
</span><span class="cx"> }
</span><span class="lines">@@ -826,7 +809,7 @@
</span><span class="cx">         linkCount++;
</span><span class="cx">     if ((resolveType == GlobalVar || resolveType == GlobalVarWithVarInjectionChecks || resolveType == LocalClosureVar)
</span><span class="cx">         &amp;&amp; currentInstruction[5].u.watchpointSet-&gt;state() != IsInvalidated)
</span><del>-        linkCount += 2;
</del><ins>+        linkCount++;
</ins><span class="cx">     if (!linkCount)
</span><span class="cx">         return;
</span><span class="cx">     while (linkCount--)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -1402,8 +1402,12 @@
</span><span class="cx">     if (modeAndType.type() == LocalClosureVar) {
</span><span class="cx">         JSLexicalEnvironment* environment = jsCast&lt;JSLexicalEnvironment*&gt;(scope);
</span><span class="cx">         environment-&gt;variableAt(ScopeOffset(pc[6].u.operand)).set(vm, environment, value);
</span><del>-        if (VariableWatchpointSet* set = pc[5].u.watchpointSet)
-            set-&gt;notifyWrite(vm, value, &quot;Executed op_put_scope&lt;LocalClosureVar&gt;&quot;);
</del><ins>+        
+        // Have to do this *after* the write, because if this puts the set into IsWatched, then we need
+        // to have already changed the value of the variable. Otherwise we might watch and constant-fold
+        // to the Undefined value from before the assignment.
+        if (WatchpointSet* set = pc[5].u.watchpointSet)
+            set-&gt;touch(&quot;Executed op_put_scope&lt;LocalClosureVar&gt;&quot;);
</ins><span class="cx">         LLINT_END();
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -519,6 +519,10 @@
</span><span class="cx">     continuation(scratch1)
</span><span class="cx"> end
</span><span class="cx"> 
</span><ins>+macro notifyWrite(set, slow)
+    bbneq WatchpointSet::m_state[set], IsInvalidated, slow
+end
+
</ins><span class="cx"> macro checkSwitchToJIT(increment, action)
</span><span class="cx">     loadp CodeBlock[cfr], t0
</span><span class="cx">     baddis increment, CodeBlock::m_llintExecuteCounter + BaselineExecutionCounter::m_counter[t0], .continue
</span><span class="lines">@@ -920,12 +924,6 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> # Value-representation-agnostic code.
</span><del>-_llint_op_touch_entry:
-    traceExecution()
-    callSlowPath(_slow_path_touch_entry)
-    dispatch(1)
-
-
</del><span class="cx"> _llint_op_create_direct_arguments:
</span><span class="cx">     traceExecution()
</span><span class="cx">     callSlowPath(_slow_path_create_direct_arguments)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -805,14 +805,6 @@
</span><span class="cx">     dispatch(3)
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-macro notifyWrite(set, valueTag, valuePayload, scratch, slow)
-    loadb VariableWatchpointSet::m_state[set], scratch
-    bieq scratch, IsInvalidated, .done
-    bineq valuePayload, VariableWatchpointSet::m_inferredValue + PayloadOffset[set], slow
-    bineq valueTag, VariableWatchpointSet::m_inferredValue + TagOffset[set], slow
-.done:
-end
-
</del><span class="cx"> _llint_op_not:
</span><span class="cx">     traceExecution()
</span><span class="cx">     loadi 8[PC], t0
</span><span class="lines">@@ -2204,7 +2196,7 @@
</span><span class="cx">     loadisFromInstruction(3, t0)
</span><span class="cx">     loadConstantOrVariable(t0, t1, t2)
</span><span class="cx">     loadpFromInstruction(5, t3)
</span><del>-    notifyWrite(t3, t1, t2, t0, .pDynamic)
</del><ins>+    notifyWrite(t3, .pDynamic)
</ins><span class="cx">     loadpFromInstruction(6, t0)
</span><span class="cx">     storei t1, TagOffset[t0]
</span><span class="cx">     storei t2, PayloadOffset[t0]
</span><span class="lines">@@ -2223,7 +2215,7 @@
</span><span class="cx">     loadConstantOrVariable(t1, t2, t3)
</span><span class="cx">     loadpFromInstruction(5, t4)
</span><span class="cx">     btpz t4, .noVariableWatchpointSet
</span><del>-    notifyWrite(t4, t2, t3, t1, .pDynamic)
</del><ins>+    notifyWrite(t4, .pDynamic)
</ins><span class="cx"> .noVariableWatchpointSet:
</span><span class="cx">     loadisFromInstruction(6, t1)
</span><span class="cx">     storei t2, JSEnvironmentRecord_variables + TagOffset[t0, t1, 8]
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -690,13 +690,6 @@
</span><span class="cx">     dispatch(3)
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-macro notifyWrite(set, value, scratch, slow)
-    loadb VariableWatchpointSet::m_state[set], scratch
-    bieq scratch, IsInvalidated, .done
-    bqneq value, VariableWatchpointSet::m_inferredValue[set], slow
-.done:
-end
-
</del><span class="cx"> _llint_op_not:
</span><span class="cx">     traceExecution()
</span><span class="cx">     loadisFromInstruction(2, t0)
</span><span class="lines">@@ -2069,8 +2062,8 @@
</span><span class="cx">     loadisFromInstruction(3, t0)
</span><span class="cx">     loadConstantOrVariable(t0, t1)
</span><span class="cx">     loadpFromInstruction(5, t2)
</span><del>-    notifyWrite(t2, t1, t0, .pDynamic)
</del><span class="cx">     loadpFromInstruction(6, t0)
</span><ins>+    notifyWrite(t2, .pDynamic)
</ins><span class="cx">     storeq t1, [t0]
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="lines">@@ -2086,7 +2079,7 @@
</span><span class="cx">     loadConstantOrVariable(t1, t2)
</span><span class="cx">     loadpFromInstruction(5, t3)
</span><span class="cx">     btpz t3, .noVariableWatchpointSet
</span><del>-    notifyWrite(t3, t2, t1, .pDynamic)
</del><ins>+    notifyWrite(t3, .pDynamic)
</ins><span class="cx"> .noVariableWatchpointSet:
</span><span class="cx">     loadisFromInstruction(6, t1)
</span><span class="cx">     storeq t2, JSEnvironmentRecord_variables[t0, t1, 8]
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -55,7 +55,6 @@
</span><span class="cx"> #include &quot;ScopedArguments.h&quot;
</span><span class="cx"> #include &quot;StructureRareDataInlines.h&quot;
</span><span class="cx"> #include &quot;TypeProfilerLog.h&quot;
</span><del>-#include &quot;VariableWatchpointSetInlines.h&quot;
</del><span class="cx"> #include &lt;wtf/StringPrintStream.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -206,13 +205,6 @@
</span><span class="cx">     RETURN_TWO(0, setupArityCheckData(vm, slotsToAdd));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-SLOW_PATH_DECL(slow_path_touch_entry)
-{
-    BEGIN();
-    exec-&gt;codeBlock()-&gt;symbolTable()-&gt;m_functionEnteredOnce.touch(&quot;Function (re)entered&quot;);
-    END();
-}
-
</del><span class="cx"> SLOW_PATH_DECL(slow_path_create_direct_arguments)
</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 (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -181,7 +181,6 @@
</span><span class="cx">     
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_call_arityCheck);
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_construct_arityCheck);
</span><del>-SLOW_PATH_HIDDEN_DECL(slow_path_touch_entry);
</del><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_create_direct_arguments);
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_create_scoped_arguments);
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_create_out_of_band_arguments);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeExecutablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Executable.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Executable.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/Executable.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -414,6 +414,12 @@
</span><span class="cx">     m_typeProfilingEndOffset = unlinkedExecutable-&gt;typeProfilingEndOffset();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void FunctionExecutable::finishCreation(VM&amp; vm)
+{
+    Base::finishCreation(vm);
+    m_singletonFunction.set(vm, this, InferredValue::create(vm));
+}
+
</ins><span class="cx"> void FunctionExecutable::destroy(JSCell* cell)
</span><span class="cx"> {
</span><span class="cx">     static_cast&lt;FunctionExecutable*&gt;(cell)-&gt;FunctionExecutable::~FunctionExecutable();
</span><span class="lines">@@ -567,6 +573,7 @@
</span><span class="cx">     if (thisObject-&gt;m_codeBlockForConstruct)
</span><span class="cx">         thisObject-&gt;m_codeBlockForConstruct-&gt;visitAggregate(visitor);
</span><span class="cx">     visitor.append(&amp;thisObject-&gt;m_unlinkedExecutable);
</span><ins>+    visitor.append(&amp;thisObject-&gt;m_singletonFunction);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> SymbolTable* FunctionExecutable::symbolTable(CodeSpecializationKind kind)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeExecutableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Executable.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Executable.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/Executable.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -33,8 +33,7 @@
</span><span class="cx"> #include &quot;CompilationResult.h&quot;
</span><span class="cx"> #include &quot;DFGPlan.h&quot;
</span><span class="cx"> #include &quot;HandlerInfo.h&quot;
</span><del>-#include &quot;JSFunction.h&quot;
-#include &quot;Interpreter.h&quot;
</del><ins>+#include &quot;InferredValue.h&quot;
</ins><span class="cx"> #include &quot;JITCode.h&quot;
</span><span class="cx"> #include &quot;JSGlobalObject.h&quot;
</span><span class="cx"> #include &quot;RegisterPreservationMode.h&quot;
</span><span class="lines">@@ -653,11 +652,15 @@
</span><span class="cx">     void unlinkCalls();
</span><span class="cx"> 
</span><span class="cx">     void clearCode();
</span><ins>+    
+    InferredValue* singletonFunction() { return m_singletonFunction.get(); }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     FunctionExecutable(
</span><span class="cx">         VM&amp;, const SourceCode&amp;, UnlinkedFunctionExecutable*, unsigned firstLine, 
</span><span class="cx">         unsigned lastLine, unsigned startColumn, unsigned endColumn);
</span><ins>+    
+    void finishCreation(VM&amp;);
</ins><span class="cx"> 
</span><span class="cx">     bool isCompiling()
</span><span class="cx">     {
</span><span class="lines">@@ -671,12 +674,13 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     friend class ScriptExecutable;
</span><del>-
</del><ins>+    
</ins><span class="cx">     WriteBarrier&lt;UnlinkedFunctionExecutable&gt; m_unlinkedExecutable;
</span><span class="cx">     RefPtr&lt;FunctionCodeBlock&gt; m_codeBlockForCall;
</span><span class="cx">     RefPtr&lt;FunctionCodeBlock&gt; m_codeBlockForConstruct;
</span><span class="cx">     RefPtr&lt;TypeSet&gt; m_returnStatementTypeSet;
</span><span class="cx">     unsigned m_parametersStartOffset;
</span><ins>+    WriteBarrier&lt;InferredValue&gt; m_singletonFunction;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> inline void ExecutableBase::clearCodeVirtual(ExecutableBase* executable)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeInferredValuecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/runtime/InferredValue.cpp (0 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/InferredValue.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/InferredValue.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -0,0 +1,132 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;InferredValue.h&quot;
+
+#include &quot;JSCInlines.h&quot;
+
+namespace JSC {
+
+const ClassInfo InferredValue::s_info = { &quot;InferredValue&quot;, 0, 0, CREATE_METHOD_TABLE(InferredValue) };
+
+InferredValue* InferredValue::create(VM&amp; vm)
+{
+    InferredValue* result = new (NotNull, allocateCell&lt;InferredValue&gt;(vm.heap)) InferredValue(vm);
+    result-&gt;finishCreation(vm);
+    return result;
+}
+
+void InferredValue::destroy(JSCell* cell)
+{
+    InferredValue* inferredValue = static_cast&lt;InferredValue*&gt;(cell);
+    inferredValue-&gt;InferredValue::~InferredValue();
+}
+
+Structure* InferredValue::createStructure(VM&amp; vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+    return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
+}
+
+void InferredValue::visitChildren(JSCell* cell, SlotVisitor&amp; visitor)
+{
+    InferredValue* inferredValue = jsCast&lt;InferredValue*&gt;(cell);
+    
+    if (inferredValue-&gt;m_set.hasBeenInvalidated()) {
+        inferredValue-&gt;m_cleanup = nullptr;
+        return;
+    }
+    
+    if (!inferredValue-&gt;m_value)
+        return;
+    if (!inferredValue-&gt;m_value.get().isCell())
+        return;
+    
+    if (!inferredValue-&gt;m_cleanup)
+        inferredValue-&gt;m_cleanup = std::make_unique&lt;ValueCleanup&gt;(inferredValue);
+    visitor.addUnconditionalFinalizer(inferredValue-&gt;m_cleanup.get());
+}
+
+InferredValue::InferredValue(VM&amp; vm)
+    : Base(vm, vm.inferredValueStructure.get())
+    , m_set(ClearWatchpoint)
+{
+}
+
+InferredValue::~InferredValue()
+{
+}
+
+void InferredValue::notifyWriteSlow(VM&amp; vm, JSValue value, const FireDetail&amp; detail)
+{
+    ASSERT(!!value);
+    switch (m_set.state()) {
+    case ClearWatchpoint:
+        m_value.set(vm, this, value);
+        m_set.startWatching();
+        return;
+        
+    case IsWatched:
+        ASSERT(!!m_value);
+        if (m_value.get() == value)
+            return;
+        invalidate(detail);
+        return;
+        
+    case IsInvalidated:
+        ASSERT_NOT_REACHED();
+        return;
+    }
+    
+    ASSERT_NOT_REACHED();
+}
+
+void InferredValue::notifyWriteSlow(VM&amp; vm, JSValue value, const char* reason)
+{
+    notifyWriteSlow(vm, value, StringFireDetail(reason));
+}
+
+InferredValue::ValueCleanup::ValueCleanup(InferredValue* owner)
+    : m_owner(owner)
+{
+}
+
+InferredValue::ValueCleanup::~ValueCleanup()
+{
+}
+
+void InferredValue::ValueCleanup::finalizeUnconditionally()
+{
+    ASSERT(m_owner-&gt;m_value);
+    ASSERT(m_owner-&gt;m_value.get().isCell());
+    
+    if (Heap::isMarked(m_owner-&gt;m_value.get().asCell()))
+        return;
+    
+    m_owner-&gt;invalidate(StringFireDetail(&quot;InferredValue clean-up during GC&quot;));
+}
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeInferredValueh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/runtime/InferredValue.h (0 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/InferredValue.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/InferredValue.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -0,0 +1,138 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef InferredValue_h
+#define InferredValue_h
+
+#include &quot;JSCell.h&quot;
+#include &quot;Watchpoint.h&quot;
+#include &quot;WriteBarrier.h&quot;
+
+namespace JSC {
+
+// Allocate one of these if you'd like to infer a constant value. Writes to the value should use
+// notifyWrite(). So long as exactly one value had ever been written and invalidate() has never been
+// called, and you register a watchpoint, you can rely on the inferredValue() being the one true
+// value.
+//
+// Commonly used for inferring singletons - in that case each allocation does notifyWrite(). But you
+// can use it for other things as well.
+
+class InferredValue : public JSCell {
+public:
+    typedef JSCell Base;
+    
+    static InferredValue* create(VM&amp;);
+    
+    static const bool needsDestruction = true;
+    static const bool hasImmortalStructure = true;
+    static void destroy(JSCell*);
+    
+    static Structure* createStructure(VM&amp;, JSGlobalObject*, JSValue prototype);
+    
+    static void visitChildren(JSCell*, SlotVisitor&amp;);
+    
+    DECLARE_INFO;
+    
+    // For the purpose of deciding whether or not to watch this variable, you only need
+    // to inspect inferredValue(). If this returns something other than the empty
+    // value, then it means that at all future safepoints, this watchpoint set will be
+    // in one of these states:
+    //
+    //    IsWatched: in this case, the variable's value must still be the
+    //        inferredValue.
+    //
+    //    IsInvalidated: in this case the variable's value may be anything but you'll
+    //        either notice that it's invalidated and not install the watchpoint, or
+    //        you will have been notified that the watchpoint was fired.
+    JSValue inferredValue() { return m_value.get(); }
+
+    // Forwards some WatchpointSet methods.
+    WatchpointState state() const { return m_set.state(); }
+    bool isStillValid() const { return m_set.isStillValid(); }
+    bool hasBeenInvalidated() const { return m_set.hasBeenInvalidated(); }
+    void add(Watchpoint* watchpoint) { m_set.add(watchpoint); }
+    
+    void notifyWrite(VM&amp; vm, JSValue value, const FireDetail&amp; detail)
+    {
+        if (LIKELY(m_set.stateOnJSThread() == IsInvalidated))
+            return;
+        notifyWriteSlow(vm, value, detail);
+    }
+    
+    void notifyWrite(VM&amp; vm, JSValue value, const char* reason)
+    {
+        if (LIKELY(m_set.stateOnJSThread() == IsInvalidated))
+            return;
+        notifyWriteSlow(vm, value, reason);
+    }
+    
+    void invalidate(const FireDetail&amp; detail)
+    {
+        m_value.clear();
+        m_set.invalidate(detail);
+    }
+    
+protected:
+    static const unsigned StructureFlags = StructureIsImmortal | Base::StructureFlags;
+    
+private:
+    InferredValue(VM&amp;);
+    ~InferredValue();
+    
+    JS_EXPORT_PRIVATE void notifyWriteSlow(VM&amp;, JSValue, const FireDetail&amp;);
+    JS_EXPORT_PRIVATE void notifyWriteSlow(VM&amp;, JSValue, const char* reason);
+    
+    // We could have used Weak&lt;&gt;. But we want arbitrary JSValues, not just cells. It's also somewhat
+    // convenient to have eager notification of death.
+    class ValueCleanup : public UnconditionalFinalizer {
+        WTF_MAKE_FAST_ALLOCATED;
+        
+    public:
+        ValueCleanup(InferredValue*);
+        virtual ~ValueCleanup();
+        
+    protected:
+        void finalizeUnconditionally() override;
+        
+    private:
+        InferredValue* m_owner;
+    };
+    
+    friend class ValueCleanup;
+    
+    InlineWatchpointSet m_set;
+    WriteBarrier&lt;Unknown&gt; m_value;
+    std::unique_ptr&lt;ValueCleanup&gt; m_cleanup;
+};
+
+// FIXME: We could have an InlineInferredValue, which only allocates the InferredValue object when
+// a notifyWrite() transitions us towards watching, and then clears the reference (allowing the object
+// to die) when we get invalidated.
+
+} // namespace JSC
+
+#endif // InferredValue_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSEnvironmentRecordcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSEnvironmentRecord.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSEnvironmentRecord.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/JSEnvironmentRecord.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -40,7 +40,7 @@
</span><span class="cx">     JSEnvironmentRecord* thisObject = jsCast&lt;JSEnvironmentRecord*&gt;(cell);
</span><span class="cx">     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
</span><span class="cx">     Base::visitChildren(thisObject, visitor);
</span><del>-    visitor.appendValues(thisObject-&gt;variables(), thisObject-&gt;m_symbolTable-&gt;scopeSize());
</del><ins>+    visitor.appendValues(thisObject-&gt;variables(), thisObject-&gt;symbolTable()-&gt;scopeSize());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSEnvironmentRecordh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSEnvironmentRecord.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSEnvironmentRecord.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/JSEnvironmentRecord.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -54,7 +54,7 @@
</span><span class="cx">     
</span><span class="cx">     bool isValid(ScopeOffset offset)
</span><span class="cx">     {
</span><del>-        return !!offset &amp;&amp; offset.offset() &lt; m_symbolTable-&gt;scopeSize();
</del><ins>+        return !!offset &amp;&amp; offset.offset() &lt; symbolTable()-&gt;scopeSize();
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     WriteBarrierBase&lt;Unknown&gt;&amp; variableAt(ScopeOffset offset)
</span><span class="lines">@@ -103,7 +103,7 @@
</span><span class="cx">     void finishCreation(VM&amp; vm)
</span><span class="cx">     {
</span><span class="cx">         finishCreationUninitialized(vm);
</span><del>-        for (unsigned i = m_symbolTable-&gt;scopeSize(); i--;) {
</del><ins>+        for (unsigned i = symbolTable()-&gt;scopeSize(); i--;) {
</ins><span class="cx">             // Filling this with undefined is useful because that's what variables start out as.
</span><span class="cx">             variableAt(ScopeOffset(i)).setUndefined();
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSFunctioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSFunction.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSFunction.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/JSFunction.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -59,6 +59,13 @@
</span><span class="cx">     return isHostFunction();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+JSFunction* JSFunction::create(VM&amp; vm, FunctionExecutable* executable, JSScope* scope)
+{
+    JSFunction* result = createImpl(vm, executable, scope);
+    executable-&gt;singletonFunction()-&gt;notifyWrite(vm, result, &quot;Allocating a function&quot;);
+    return result;
+}
+
</ins><span class="cx"> JSFunction* JSFunction::create(VM&amp; vm, JSGlobalObject* globalObject, int length, const String&amp; name, NativeFunction nativeFunction, Intrinsic intrinsic, NativeFunction nativeConstructor)
</span><span class="cx"> {
</span><span class="cx">     NativeExecutable* executable;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSFunctionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSFunction.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSFunction.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/JSFunction.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -60,14 +60,10 @@
</span><span class="cx">     const static unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
</span><span class="cx"> 
</span><span class="cx">     JS_EXPORT_PRIVATE static JSFunction* create(VM&amp;, JSGlobalObject*, int length, const String&amp; name, NativeFunction, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor);
</span><ins>+    
+    static JSFunction* createWithInvalidatedReallocationWatchpoint(VM&amp;, FunctionExecutable*, JSScope*);
</ins><span class="cx"> 
</span><del>-    static JSFunction* create(VM&amp; vm, FunctionExecutable* executable, JSScope* scope)
-    {
-        JSFunction* function = new (NotNull, allocateCell&lt;JSFunction&gt;(vm.heap)) JSFunction(vm, executable, scope);
-        ASSERT(function-&gt;structure()-&gt;globalObject());
-        function-&gt;finishCreation(vm);
-        return function;
-    }
</del><ins>+    static JSFunction* create(VM&amp;, FunctionExecutable*, JSScope*);
</ins><span class="cx"> 
</span><span class="cx">     static JSFunction* createBuiltinFunction(VM&amp;, FunctionExecutable*, JSGlobalObject*);
</span><span class="cx"> 
</span><span class="lines">@@ -148,6 +144,14 @@
</span><span class="cx">     static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    static JSFunction* createImpl(VM&amp; vm, FunctionExecutable* executable, JSScope* scope)
+    {
+        JSFunction* function = new (NotNull, allocateCell&lt;JSFunction&gt;(vm.heap)) JSFunction(vm, executable, scope);
+        ASSERT(function-&gt;structure()-&gt;globalObject());
+        function-&gt;finishCreation(vm);
+        return function;
+    }
+    
</ins><span class="cx">     friend class LLIntOffsetsExtractor;
</span><span class="cx"> 
</span><span class="cx">     static EncodedJSValue argumentsGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSFunctionInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSFunctionInlines.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSFunctionInlines.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/JSFunctionInlines.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -31,6 +31,13 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+inline JSFunction* JSFunction::createWithInvalidatedReallocationWatchpoint(
+    VM&amp; vm, FunctionExecutable* executable, JSScope* scope)
+{
+    ASSERT(executable-&gt;singletonFunction()-&gt;hasBeenInvalidated());
+    return createImpl(vm, executable, scope);
+}
+
</ins><span class="cx"> inline JSFunction::JSFunction(VM&amp; vm, FunctionExecutable* executable, JSScope* scope)
</span><span class="cx">     : Base(vm, scope, scope-&gt;globalObject()-&gt;functionStructure())
</span><span class="cx">     , m_executable(vm, this, executable)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -124,7 +124,7 @@
</span><span class="cx"> #include &quot;Symbol.h&quot;
</span><span class="cx"> #include &quot;SymbolConstructor.h&quot;
</span><span class="cx"> #include &quot;SymbolPrototype.h&quot;
</span><del>-#include &quot;VariableWatchpointSetInlines.h&quot;
</del><ins>+#include &quot;VariableWriteFireDetail.h&quot;
</ins><span class="cx"> #include &quot;WeakGCMapInlines.h&quot;
</span><span class="cx"> #include &quot;WeakMapConstructor.h&quot;
</span><span class="cx"> #include &quot;WeakMapPrototype.h&quot;
</span><span class="lines">@@ -489,7 +489,7 @@
</span><span class="cx">     ScopeOffset offset = symbolTable()-&gt;takeNextScopeOffset(locker);
</span><span class="cx">     SymbolTableEntry newEntry(VarOffset(offset), (constantMode == IsConstant) ? ReadOnly : 0);
</span><span class="cx">     if (constantMode == IsVariable)
</span><del>-        newEntry.prepareToWatch(symbolTable());
</del><ins>+        newEntry.prepareToWatch();
</ins><span class="cx">     else
</span><span class="cx">         newEntry.disableWatching();
</span><span class="cx">     symbolTable()-&gt;add(locker, ident.impl(), newEntry);
</span><span class="lines">@@ -510,7 +510,7 @@
</span><span class="cx">     NewGlobalVar var = addGlobalVar(propertyName, IsVariable);
</span><span class="cx">     variableAt(var.offset).set(exec-&gt;vm(), this, value);
</span><span class="cx">     if (var.set)
</span><del>-        var.set-&gt;notifyWrite(vm, value, VariableWriteFireDetail(this, propertyName));
</del><ins>+        var.set-&gt;touch(VariableWriteFireDetail(this, propertyName));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static inline JSObject* lastInPrototypeChain(JSObject* object)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -335,7 +335,7 @@
</span><span class="cx"> 
</span><span class="cx">     struct NewGlobalVar {
</span><span class="cx">         ScopeOffset offset;
</span><del>-        VariableWatchpointSet* set;
</del><ins>+        WatchpointSet* set;
</ins><span class="cx">     };
</span><span class="cx">     NewGlobalVar addGlobalVar(const Identifier&amp;, ConstantMode);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSLexicalEnvironmentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -77,6 +77,7 @@
</span><span class="cx">     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
</span><span class="cx">     
</span><span class="cx">     WriteBarrierBase&lt;Unknown&gt;* reg;
</span><ins>+    WatchpointSet* set;
</ins><span class="cx">     {
</span><span class="cx">         GCSafeConcurrentJITLocker locker(symbolTable()-&gt;m_lock, exec-&gt;vm().heap);
</span><span class="cx">         SymbolTable::Map::iterator iter = symbolTable()-&gt;find(locker, propertyName.uid());
</span><span class="lines">@@ -92,11 +93,12 @@
</span><span class="cx">         // Defend against the inspector asking for a var after it has been optimized out.
</span><span class="cx">         if (!isValid(offset))
</span><span class="cx">             return false;
</span><del>-        if (VariableWatchpointSet* set = iter-&gt;value.watchpointSet())
-            set-&gt;invalidate(VariableWriteFireDetail(this, propertyName)); // Don't mess around - if we had found this statically, we would have invalidated it.
</del><ins>+        set = iter-&gt;value.watchpointSet();
</ins><span class="cx">         reg = &amp;variableAt(offset);
</span><span class="cx">     }
</span><span class="cx">     reg-&gt;set(vm, this, value);
</span><ins>+    if (set)
+        set-&gt;invalidate(VariableWriteFireDetail(this, propertyName)); // Don't mess around - if we had found this statically, we would have invalidated it.
</ins><span class="cx">     return true;
</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 (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSScope.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/JSScope.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -31,7 +31,7 @@
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx"> class ScopeChainIterator;
</span><del>-class VariableWatchpointSet;
</del><ins>+class WatchpointSet;
</ins><span class="cx"> 
</span><span class="cx"> enum ResolveMode {
</span><span class="cx">     ThrowIfNotFound,
</span><span class="lines">@@ -102,7 +102,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> struct ResolveOp {
</span><del>-    ResolveOp(ResolveType type, size_t depth, Structure* structure, JSLexicalEnvironment* lexicalEnvironment, VariableWatchpointSet* watchpointSet, uintptr_t operand)
</del><ins>+    ResolveOp(ResolveType type, size_t depth, Structure* structure, JSLexicalEnvironment* lexicalEnvironment, WatchpointSet* watchpointSet, uintptr_t operand)
</ins><span class="cx">         : type(type)
</span><span class="cx">         , depth(depth)
</span><span class="cx">         , structure(structure)
</span><span class="lines">@@ -116,7 +116,7 @@
</span><span class="cx">     size_t depth;
</span><span class="cx">     Structure* structure;
</span><span class="cx">     JSLexicalEnvironment* lexicalEnvironment;
</span><del>-    VariableWatchpointSet* watchpointSet;
</del><ins>+    WatchpointSet* watchpointSet;
</ins><span class="cx">     uintptr_t operand;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSSegmentedVariableObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -57,6 +57,10 @@
</span><span class="cx"> public:
</span><span class="cx">     typedef JSSymbolTableObject Base;
</span><span class="cx"> 
</span><ins>+    // This is not thread-safe, since m_variables is a segmented vector, and its spine can resize with
+    // malloc/free if new variables - unrelated to the one you are accessing - are added. You can get
+    // around this by grabbing m_lock, or finding some other way to get to the variable pointer (global
+    // variable access bytecode instructions will have a direct pointer already).
</ins><span class="cx">     WriteBarrier&lt;Unknown&gt;&amp; variableAt(ScopeOffset offset) { return m_variables[offset.offset()]; }
</span><span class="cx">     
</span><span class="cx">     // This is a slow method call, which searches the register bank to find the index
</span><span class="lines">@@ -86,7 +90,7 @@
</span><span class="cx">     void finishCreation(VM&amp; vm)
</span><span class="cx">     {
</span><span class="cx">         Base::finishCreation(vm);
</span><del>-        m_symbolTable.set(vm, this, SymbolTable::create(vm));
</del><ins>+        setSymbolTable(vm, SymbolTable::create(vm));
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     SegmentedVector&lt;WriteBarrier&lt;Unknown&gt;, 16&gt; m_variables;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSSymbolTableObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSSymbolTableObject.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSSymbolTableObject.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/JSSymbolTableObject.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -32,7 +32,7 @@
</span><span class="cx"> #include &quot;JSScope.h&quot;
</span><span class="cx"> #include &quot;PropertyDescriptor.h&quot;
</span><span class="cx"> #include &quot;SymbolTable.h&quot;
</span><del>-#include &quot;VariableWatchpointSetInlines.h&quot;
</del><ins>+#include &quot;VariableWriteFireDetail.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -60,11 +60,19 @@
</span><span class="cx">         : Base(vm, structure, scope)
</span><span class="cx">     {
</span><span class="cx">         ASSERT(symbolTable);
</span><ins>+        setSymbolTable(vm, symbolTable);
+    }
+    
+    void setSymbolTable(VM&amp; vm, SymbolTable* symbolTable)
+    {
+        ASSERT(!m_symbolTable);
+        symbolTable-&gt;singletonScope()-&gt;notifyWrite(vm, this, &quot;Allocated a scope&quot;);
</ins><span class="cx">         m_symbolTable.set(vm, this, symbolTable);
</span><span class="cx">     }
</span><del>-
</del><ins>+    
</ins><span class="cx">     static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><del>-
</del><ins>+    
+private:
</ins><span class="cx">     WriteBarrier&lt;SymbolTable&gt; m_symbolTable;
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -125,6 +133,7 @@
</span><span class="cx">     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object));
</span><span class="cx">     
</span><span class="cx">     WriteBarrierBase&lt;Unknown&gt;* reg;
</span><ins>+    WatchpointSet* set;
</ins><span class="cx">     {
</span><span class="cx">         SymbolTable&amp; symbolTable = *object-&gt;symbolTable();
</span><span class="cx">         // FIXME: This is very suspicious. We shouldn't need a GC-safe lock here.
</span><span class="lines">@@ -141,17 +150,15 @@
</span><span class="cx">                 throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
</span><span class="cx">             return true;
</span><span class="cx">         }
</span><del>-        if (VariableWatchpointSet* set = iter-&gt;value.watchpointSet()) {
-            // FIXME: It's strange that we're doing this while holding the symbol table's lock.
-            // https://bugs.webkit.org/show_bug.cgi?id=134601
-            set-&gt;notifyWrite(vm, value, object, propertyName);
-        }
</del><ins>+        set = iter-&gt;value.watchpointSet();
</ins><span class="cx">         reg = &amp;object-&gt;variableAt(fastEntry.scopeOffset());
</span><span class="cx">     }
</span><span class="cx">     // I'd prefer we not hold lock while executing barriers, since I prefer to reserve
</span><span class="cx">     // the right for barriers to be able to trigger GC. And I don't want to hold VM
</span><span class="cx">     // locks while GC'ing.
</span><span class="cx">     reg-&gt;set(vm, object, value);
</span><ins>+    if (set)
+        VariableWriteFireDetail::touch(set, object, propertyName);
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -163,6 +170,7 @@
</span><span class="cx">     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object));
</span><span class="cx"> 
</span><span class="cx">     WriteBarrierBase&lt;Unknown&gt;* reg;
</span><ins>+    WatchpointSet* set;
</ins><span class="cx">     {
</span><span class="cx">         SymbolTable&amp; symbolTable = *object-&gt;symbolTable();
</span><span class="cx">         ConcurrentJITLocker locker(symbolTable.m_lock);
</span><span class="lines">@@ -171,12 +179,13 @@
</span><span class="cx">             return false;
</span><span class="cx">         SymbolTableEntry&amp; entry = iter-&gt;value;
</span><span class="cx">         ASSERT(!entry.isNull());
</span><del>-        if (VariableWatchpointSet* set = entry.watchpointSet())
-            set-&gt;notifyWrite(vm, value, object, propertyName);
</del><ins>+        set = entry.watchpointSet();
</ins><span class="cx">         entry.setAttributes(attributes);
</span><span class="cx">         reg = &amp;object-&gt;variableAt(entry.scopeOffset());
</span><span class="cx">     }
</span><span class="cx">     reg-&gt;set(vm, object, value);
</span><ins>+    if (set)
+        VariableWriteFireDetail::touch(set, object, propertyName);
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimePutPropertySloth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/PutPropertySlot.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/PutPropertySlot.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/PutPropertySlot.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> #define PutPropertySlot_h
</span><span class="cx"> 
</span><span class="cx"> #include &quot;JSCJSValue.h&quot;
</span><ins>+#include &quot;PropertyOffset.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> #include &lt;wtf/Assertions.h&gt;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSymbolTablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -33,7 +33,6 @@
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;SlotVisitorInlines.h&quot;
</span><span class="cx"> #include &quot;TypeProfiler.h&quot;
</span><del>-#include &quot;VariableWatchpointSetInlines.h&quot;
</del><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -60,21 +59,14 @@
</span><span class="cx">     delete fatEntry();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSValue SymbolTableEntry::inferredValue()
</del><ins>+void SymbolTableEntry::prepareToWatch()
</ins><span class="cx"> {
</span><del>-    if (!isFat())
-        return JSValue();
-    return fatEntry()-&gt;m_watchpoints-&gt;inferredValue();
-}
-
-void SymbolTableEntry::prepareToWatch(SymbolTable* symbolTable)
-{
</del><span class="cx">     if (!isWatchable())
</span><span class="cx">         return;
</span><span class="cx">     FatEntry* entry = inflate();
</span><span class="cx">     if (entry-&gt;m_watchpoints)
</span><span class="cx">         return;
</span><del>-    entry-&gt;m_watchpoints = adoptRef(new VariableWatchpointSet(*symbolTable));
</del><ins>+    entry-&gt;m_watchpoints = adoptRef(new WatchpointSet(ClearWatchpoint));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SymbolTableEntry::addWatchpoint(Watchpoint* watchpoint)
</span><span class="lines">@@ -82,15 +74,6 @@
</span><span class="cx">     fatEntry()-&gt;m_watchpoints-&gt;add(watchpoint);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SymbolTableEntry::notifyWriteSlow(VM&amp; vm, JSValue value, const FireDetail&amp; detail)
-{
-    VariableWatchpointSet* watchpoints = fatEntry()-&gt;m_watchpoints.get();
-    if (!watchpoints)
-        return;
-    
-    watchpoints-&gt;notifyWrite(vm, value, detail);
-}
-
</del><span class="cx"> SymbolTableEntry::FatEntry* SymbolTableEntry::inflateSlow()
</span><span class="cx"> {
</span><span class="cx">     FatEntry* entry = new FatEntry(m_bits);
</span><span class="lines">@@ -101,48 +84,29 @@
</span><span class="cx"> SymbolTable::SymbolTable(VM&amp; vm)
</span><span class="cx">     : JSCell(vm, vm.symbolTableStructure.get())
</span><span class="cx">     , m_usesNonStrictEval(false)
</span><del>-    , m_functionEnteredOnce(ClearWatchpoint)
</del><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> SymbolTable::~SymbolTable() { }
</span><span class="cx"> 
</span><ins>+void SymbolTable::finishCreation(VM&amp; vm)
+{
+    Base::finishCreation(vm);
+    m_singletonScope.set(vm, this, InferredValue::create(vm));
+}
+
</ins><span class="cx"> void SymbolTable::visitChildren(JSCell* thisCell, SlotVisitor&amp; visitor)
</span><span class="cx"> {
</span><span class="cx">     SymbolTable* thisSymbolTable = jsCast&lt;SymbolTable*&gt;(thisCell);
</span><span class="cx">     
</span><span class="cx">     visitor.append(&amp;thisSymbolTable-&gt;m_arguments);
</span><ins>+    visitor.append(&amp;thisSymbolTable-&gt;m_singletonScope);
</ins><span class="cx">     
</span><del>-    if (!thisSymbolTable-&gt;m_watchpointCleanup) {
-        thisSymbolTable-&gt;m_watchpointCleanup =
-            std::make_unique&lt;WatchpointCleanup&gt;(thisSymbolTable);
-    }
-    
-    visitor.addUnconditionalFinalizer(thisSymbolTable-&gt;m_watchpointCleanup.get());
-    
</del><span class="cx">     // Save some memory. This is O(n) to rebuild and we do so on the fly.
</span><span class="cx">     ConcurrentJITLocker locker(thisSymbolTable-&gt;m_lock);
</span><span class="cx">     thisSymbolTable-&gt;m_localToEntry = nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-SymbolTable::WatchpointCleanup::WatchpointCleanup(SymbolTable* symbolTable)
-    : m_symbolTable(symbolTable)
-{
-}
-
-SymbolTable::WatchpointCleanup::~WatchpointCleanup() { }
-
-void SymbolTable::WatchpointCleanup::finalizeUnconditionally()
-{
-    StringFireDetail detail(&quot;Symbol table clean-up during GC&quot;);
-    Map::iterator iter = m_symbolTable-&gt;m_map.begin();
-    Map::iterator end = m_symbolTable-&gt;m_map.end();
-    for (; iter != end; ++iter) {
-        if (VariableWatchpointSet* set = iter-&gt;value.watchpointSet())
-            set-&gt;finalizeUnconditionally(detail);
-    }
-}
-
</del><span class="cx"> const SymbolTable::LocalToEntryVec&amp; SymbolTable::localToEntry(const ConcurrentJITLocker&amp;)
</span><span class="cx"> {
</span><span class="cx">     if (UNLIKELY(!m_localToEntry)) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSymbolTableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SymbolTable.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SymbolTable.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/SymbolTable.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -31,17 +31,20 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ConcurrentJITLock.h&quot;
</span><span class="cx"> #include &quot;ConstantMode.h&quot;
</span><ins>+#include &quot;InferredValue.h&quot;
</ins><span class="cx"> #include &quot;JSObject.h&quot;
</span><span class="cx"> #include &quot;ScopedArgumentsTable.h&quot;
</span><span class="cx"> #include &quot;TypeLocation.h&quot;
</span><span class="cx"> #include &quot;VarOffset.h&quot;
</span><del>-#include &quot;VariableWatchpointSet.h&quot;
</del><ins>+#include &quot;Watchpoint.h&quot;
</ins><span class="cx"> #include &lt;memory&gt;
</span><span class="cx"> #include &lt;wtf/HashTraits.h&gt;
</span><span class="cx"> #include &lt;wtf/text/StringImpl.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+class SymbolTable;
+
</ins><span class="cx"> static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits&lt;int&gt;::max(); }
</span><span class="cx"> 
</span><span class="cx"> // The bit twiddling in this class assumes that every register index is a
</span><span class="lines">@@ -63,11 +66,11 @@
</span><span class="cx"> // counted pointer to a shared WatchpointSet. Thus, in-place edits of the
</span><span class="cx"> // WatchpointSet will manifest in all copies. Here's a picture:
</span><span class="cx"> //
</span><del>-// SymbolTableEntry --&gt; FatEntry --&gt; VariableWatchpointSet
</del><ins>+// SymbolTableEntry --&gt; FatEntry --&gt; WatchpointSet
</ins><span class="cx"> //
</span><span class="cx"> // If you make a copy of a SymbolTableEntry, you will have:
</span><span class="cx"> //
</span><del>-// original: SymbolTableEntry --&gt; FatEntry --&gt; VariableWatchpointSet
</del><ins>+// original: SymbolTableEntry --&gt; FatEntry --&gt; WatchpointSet
</ins><span class="cx"> // copy:     SymbolTableEntry --&gt; FatEntry -----^
</span><span class="cx"> 
</span><span class="cx"> struct SymbolTableEntry {
</span><span class="lines">@@ -260,32 +263,44 @@
</span><span class="cx">         return bits() &amp; DontEnumFlag;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    JSValue inferredValue();
-
</del><span class="cx">     void disableWatching()
</span><span class="cx">     {
</span><ins>+        if (WatchpointSet* set = watchpointSet())
+            set-&gt;invalidate(&quot;Disabling watching in symbol table&quot;);
</ins><span class="cx">         if (varOffset().isScope())
</span><span class="cx">             pack(varOffset(), false, isReadOnly(), isDontEnum());
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void prepareToWatch(SymbolTable*);
</del><ins>+    void prepareToWatch();
</ins><span class="cx">     
</span><span class="cx">     void addWatchpoint(Watchpoint*);
</span><span class="cx">     
</span><del>-    VariableWatchpointSet* watchpointSet()
</del><ins>+    // This watchpoint set is initialized clear, and goes through the following state transitions:
+    // 
+    // First write to this var, in any scope that has this symbol table: Clear-&gt;IsWatched.
+    //
+    // Second write to this var, in any scope that has this symbol table: IsWatched-&gt;IsInvalidated.
+    //
+    // We ensure that we touch the set (i.e. trigger its state transition) after we do the write. This
+    // means that if you're in the compiler thread, and you:
+    //
+    // 1) Observe that the set IsWatched and commit to adding your watchpoint.
+    // 2) Load a value from any scope that has this watchpoint set.
+    //
+    // Then you can be sure that that value is either going to be the correct value for that var forever,
+    // or the watchpoint set will invalidate and you'll get fired.
+    //
+    // It's possible to write a program that first creates multiple scopes with the same var, and then
+    // initializes that var in just one of them. This means that a compilation could constant-fold to one
+    // of the scopes that still has an undefined value for this variable. That's fine, because at that
+    // point any write to any of the instances of that variable would fire the watchpoint.
+    WatchpointSet* watchpointSet()
</ins><span class="cx">     {
</span><span class="cx">         if (!isFat())
</span><span class="cx">             return 0;
</span><span class="cx">         return fatEntry()-&gt;m_watchpoints.get();
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    ALWAYS_INLINE void notifyWrite(VM&amp; vm, JSValue value, const FireDetail&amp; detail)
-    {
-        if (LIKELY(!isFat()))
-            return;
-        notifyWriteSlow(vm, value, detail);
-    }
-    
</del><span class="cx"> private:
</span><span class="cx">     static const intptr_t SlimFlag = 0x1;
</span><span class="cx">     static const intptr_t ReadOnlyFlag = 0x2;
</span><span class="lines">@@ -308,7 +323,7 @@
</span><span class="cx">         
</span><span class="cx">         intptr_t m_bits; // always has FatFlag set and exactly matches what the bits would have been if this wasn't fat.
</span><span class="cx">         
</span><del>-        RefPtr&lt;VariableWatchpointSet&gt; m_watchpoints;
</del><ins>+        RefPtr&lt;WatchpointSet&gt; m_watchpoints;
</ins><span class="cx">     };
</span><span class="cx">     
</span><span class="cx">     SymbolTableEntry&amp; copySlow(const SymbolTableEntry&amp;);
</span><span class="lines">@@ -637,26 +652,18 @@
</span><span class="cx">     SymbolTable* cloneScopePart(VM&amp;);
</span><span class="cx"> 
</span><span class="cx">     void prepareForTypeProfiling(const ConcurrentJITLocker&amp;);
</span><ins>+    
+    InferredValue* singletonScope() { return m_singletonScope.get(); }
</ins><span class="cx"> 
</span><span class="cx">     static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><span class="cx"> 
</span><span class="cx">     DECLARE_EXPORT_INFO;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    class WatchpointCleanup : public UnconditionalFinalizer {
-    public:
-        WatchpointCleanup(SymbolTable*);
-        virtual ~WatchpointCleanup();
-        
-    protected:
-        virtual void finalizeUnconditionally() override;
-
-    private:
-        SymbolTable* m_symbolTable;
-    };
-    
</del><span class="cx">     JS_EXPORT_PRIVATE SymbolTable(VM&amp;);
</span><span class="cx">     ~SymbolTable();
</span><ins>+    
+    JS_EXPORT_PRIVATE void finishCreation(VM&amp;);
</ins><span class="cx"> 
</span><span class="cx">     Map m_map;
</span><span class="cx">     ScopeOffset m_maxScopeOffset;
</span><span class="lines">@@ -671,13 +678,11 @@
</span><span class="cx">     bool m_usesNonStrictEval;
</span><span class="cx">     
</span><span class="cx">     WriteBarrier&lt;ScopedArgumentsTable&gt; m_arguments;
</span><ins>+    WriteBarrier&lt;InferredValue&gt; m_singletonScope;
</ins><span class="cx">     
</span><del>-    std::unique_ptr&lt;WatchpointCleanup&gt; m_watchpointCleanup;
</del><span class="cx">     std::unique_ptr&lt;LocalToEntryVec&gt; m_localToEntry;
</span><span class="cx"> 
</span><span class="cx"> public:
</span><del>-    InlineWatchpointSet m_functionEnteredOnce;
-    
</del><span class="cx">     mutable ConcurrentJITLock m_lock;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeTypeProfilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/TypeProfiler.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/TypeProfiler.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/TypeProfiler.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;InspectorProtocolObjects.h&quot;
</span><span class="cx"> #include &quot;TypeLocation.h&quot;
</span><ins>+#include &lt;wtf/text/StringBuilder.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.cpp (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.cpp        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/VM.cpp        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -237,6 +237,7 @@
</span><span class="cx">     unlinkedFunctionCodeBlockStructure.set(*this, UnlinkedFunctionCodeBlock::createStructure(*this, 0, jsNull()));
</span><span class="cx">     propertyTableStructure.set(*this, PropertyTable::createStructure(*this, 0, jsNull()));
</span><span class="cx">     weakMapDataStructure.set(*this, WeakMapData::createStructure(*this, 0, jsNull()));
</span><ins>+    inferredValueStructure.set(*this, InferredValue::createStructure(*this, 0, jsNull()));
</ins><span class="cx"> #if ENABLE(PROMISES)
</span><span class="cx">     promiseDeferredStructure.set(*this, JSPromiseDeferred::createStructure(*this, 0, jsNull()));
</span><span class="cx">     promiseReactionStructure.set(*this, JSPromiseReaction::createStructure(*this, 0, jsNull()));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (182758 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2015-04-13 21:42:16 UTC (rev 182758)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -270,6 +270,7 @@
</span><span class="cx">     Strong&lt;Structure&gt; unlinkedFunctionCodeBlockStructure;
</span><span class="cx">     Strong&lt;Structure&gt; propertyTableStructure;
</span><span class="cx">     Strong&lt;Structure&gt; weakMapDataStructure;
</span><ins>+    Strong&lt;Structure&gt; inferredValueStructure;
</ins><span class="cx"> #if ENABLE(PROMISES)
</span><span class="cx">     Strong&lt;Structure&gt; promiseDeferredStructure;
</span><span class="cx">     Strong&lt;Structure&gt; promiseReactionStructure;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressinferuninitializedclosurevarjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/infer-uninitialized-closure-var.js (0 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/infer-uninitialized-closure-var.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/infer-uninitialized-closure-var.js        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+function foo(p) {
+    var x;
+    
+    noInline(f);
+    
+    if (p) {
+        var f = function() { return x; }
+        
+        foo(false);
+        
+        for (var i = 0; i &lt; 10000; ++i) {
+            var result = f();
+            if (result !== void 0)
+                throw &quot;Error: bad result (1): &quot; + result;
+        }
+        
+        x = 43;
+        
+        var result = f();
+        if (result != 43)
+            throw &quot;Error: bad result (2): &quot; + result;
+    } else
+        x = 42;
+}
+
+foo(true);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresssingletonscopethenoverwritejs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/singleton-scope-then-overwrite.js (0 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/singleton-scope-then-overwrite.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/singleton-scope-then-overwrite.js        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+function foo(a) {
+    var x = a + 1;
+    var f = function(a) {
+        return x + a;
+    };
+    noInline(f);
+    for (var i = 0; i &lt; 10000; ++i) {
+        var result = f(i);
+        if (result != a + 1 + i)
+            throw &quot;Error: bad result: &quot; + result;
+    }
+    x = 999;
+    var result = f(1);
+    if (result != 999 + 1)
+        throw &quot;Error: bad result: &quot; + result;
+}
+
+noInline(foo);
+for (var i = 0; i &lt; 3; ++i)
+    foo(42 + i);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresssingletonscopethenreallocandoverwritejs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/singleton-scope-then-realloc-and-overwrite.js (0 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/singleton-scope-then-realloc-and-overwrite.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/singleton-scope-then-realloc-and-overwrite.js        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+function foo(a) {
+    var x = a + 1;
+    return function(a) {
+        return x + a;
+    };
+}
+
+var f = foo(42);
+noInline(f);
+
+for (var i = 0; i &lt; 10000; ++i) {
+    var result = f(i);
+    if (result != 42 + 1 + i)
+        throw &quot;Error: bad result: &quot; + result;
+}
+
+var f = foo(43);
+var result = f(1);
+if (result != 43 + 1 + 1)
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresssingletonscopethenreallocjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/singleton-scope-then-realloc.js (0 => 182759)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/singleton-scope-then-realloc.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/singleton-scope-then-realloc.js        2015-04-13 22:13:12 UTC (rev 182759)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+function foo(a) {
+    var x = a + 1;
+    return function(a) {
+        return x += a;
+    };
+}
+
+var f = foo(42);
+noInline(f);
+
+for (var i = 0; i &lt; 10000; ++i) {
+    var result = f(1);
+    if (result != 42 + 1 + i + 1)
+        throw &quot;Error: bad result: &quot; + result;
+}
+
+var f = foo(43);
+var result = f(1);
+if (result != 43 + 1 + 1)
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre>
</div>
</div>

</body>
</html>