<!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>[172614] trunk/Source</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/172614">172614</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2014-08-14 16:59:44 -0700 (Thu, 14 Aug 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Allow high fidelity type profiling to be enabled and disabled.
https://bugs.webkit.org/show_bug.cgi?id=135423

Patch by Saam Barati &lt;sbarati@apple.com&gt; on 2014-08-14
Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

- Merged op_put_to_scope_with_profile and op_get_from_scope_with_profile into
  op_profile_types_with_high_fidelity by adding extra arguments to the opcode.
- Altered SymbolTable to use less memory by adding a rare data structure for
  type profiling.
- Created an interface to turn on and off type profiling from the Web
  Inspector.
- Refactored how entries are written to HighFidelityLog to make it
  easier to inline when generating machine code.
- Implemented op_profile_types_with_high_fidelity in the baseline JIT
  by inlining the process of writing to the log and doing a small amount
  of type inference optimizations.

* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::finalizeUnconditionally):
(JSC::CodeBlock::scopeDependentProfile): Deleted.
* bytecode/CodeBlock.h:
* bytecode/TypeLocation.h:
(JSC::TypeLocation::TypeLocation):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::generate):
(JSC::BytecodeGenerator::emitMove):
(JSC::BytecodeGenerator::emitProfileTypesWithHighFidelity):
(JSC::BytecodeGenerator::emitGetFromScopeWithProfile): Deleted.
(JSC::BytecodeGenerator::emitPutToScopeWithProfile): Deleted.
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::ThisNode::emitBytecode):
(JSC::ResolveNode::emitBytecode):
(JSC::BracketAccessorNode::emitBytecode):
(JSC::DotAccessorNode::emitBytecode):
(JSC::FunctionCallValueNode::emitBytecode):
(JSC::FunctionCallResolveNode::emitBytecode):
(JSC::FunctionCallBracketNode::emitBytecode):
(JSC::FunctionCallDotNode::emitBytecode):
(JSC::CallFunctionCallDotNode::emitBytecode):
(JSC::ApplyFunctionCallDotNode::emitBytecode):
(JSC::PostfixNode::emitResolve):
(JSC::PostfixNode::emitBracket):
(JSC::PostfixNode::emitDot):
(JSC::PrefixNode::emitResolve):
(JSC::PrefixNode::emitBracket):
(JSC::PrefixNode::emitDot):
(JSC::ReadModifyResolveNode::emitBytecode):
(JSC::AssignResolveNode::emitBytecode):
(JSC::AssignDotNode::emitBytecode):
(JSC::ReadModifyDotNode::emitBytecode):
(JSC::AssignBracketNode::emitBytecode):
(JSC::ReadModifyBracketNode::emitBytecode):
(JSC::ReturnNode::emitBytecode):
(JSC::FunctionBodyNode::emitBytecode):
* inspector/agents/InspectorRuntimeAgent.cpp:
(Inspector::InspectorRuntimeAgent::InspectorRuntimeAgent):
(Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
(Inspector::TypeRecompiler::operator()):
(Inspector::recompileAllJSFunctionsForTypeProfiling):
(Inspector::InspectorRuntimeAgent::willDestroyFrontendAndBackend):
(Inspector::InspectorRuntimeAgent::enableHighFidelityTypeProfiling):
(Inspector::InspectorRuntimeAgent::disableHighFidelityTypeProfiling):
(Inspector::InspectorRuntimeAgent::setHighFidelityTypeProfilingEnabledState):
* inspector/agents/InspectorRuntimeAgent.h:
* inspector/agents/JSGlobalObjectRuntimeAgent.cpp:
(Inspector::JSGlobalObjectRuntimeAgent::willDestroyFrontendAndBackend):
* inspector/protocol/Runtime.json:
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompile):
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_profile_types_with_high_fidelity):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_profile_types_with_high_fidelity):
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
(JSC::LLInt::getFromScopeCommon): Deleted.
(JSC::LLInt::putToScopeCommon): Deleted.
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter.asm:
* runtime/CodeCache.cpp:
(JSC::CodeCache::getGlobalCodeBlock):
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
* runtime/HighFidelityLog.cpp:
(JSC::HighFidelityLog::initializeHighFidelityLog):
(JSC::HighFidelityLog::~HighFidelityLog):
(JSC::HighFidelityLog::processHighFidelityLog):
* runtime/HighFidelityLog.h:
(JSC::HighFidelityLog::LogEntry::structureIDOffset):
(JSC::HighFidelityLog::LogEntry::valueOffset):
(JSC::HighFidelityLog::LogEntry::locationOffset):
(JSC::HighFidelityLog::recordTypeInformationForLocation):
(JSC::HighFidelityLog::logEndPtr):
(JSC::HighFidelityLog::logStartOffset):
(JSC::HighFidelityLog::currentLogEntryOffset):
* runtime/HighFidelityTypeProfiler.cpp:
(JSC::HighFidelityTypeProfiler::logTypesForTypeLocation):
(JSC::descriptorMatchesTypeLocation):
* runtime/HighFidelityTypeProfiler.h:
* runtime/SymbolTable.cpp:
(JSC::SymbolTable::SymbolTable):
(JSC::SymbolTable::cloneCapturedNames):
(JSC::SymbolTable::prepareForHighFidelityTypeProfiling):
(JSC::SymbolTable::uniqueIDForVariable):
(JSC::SymbolTable::uniqueIDForRegister):
(JSC::SymbolTable::globalTypeSetForRegister):
(JSC::SymbolTable::globalTypeSetForVariable):
* runtime/SymbolTable.h:
(JSC::SymbolTable::add):
(JSC::SymbolTable::set):
* runtime/TypeLocationCache.cpp:
(JSC::TypeLocationCache::getTypeLocation):
* runtime/TypeSet.cpp:
(JSC::TypeSet::getRuntimeTypeForValue):
(JSC::TypeSet::addTypeInformation):
(JSC::TypeSet::allPrimitiveTypeNames):
(JSC::TypeSet::addTypeForValue): Deleted.
* runtime/TypeSet.h:
* runtime/VM.cpp:
(JSC::VM::VM):
(JSC::VM::nextTypeLocation):
(JSC::VM::enableHighFidelityTypeProfiling):
(JSC::VM::disableHighFidelityTypeProfiling):
(JSC::VM::dumpHighFidelityProfilingTypes):
* runtime/VM.h:
(JSC::VM::nextLocation): Deleted.

Source/WebCore:

PageRuntimeAgent and WorkerRuntimeAgent now call their super
class's (InspectorRuntimeAgent) implementation of willDestroyFrontendAndBackend
to give InspectorRuntimeAgent a chance to recompile all JavaScript
functions, if necessary, for type profiling.

* inspector/PageRuntimeAgent.cpp:
(WebCore::PageRuntimeAgent::willDestroyFrontendAndBackend):
* inspector/WorkerRuntimeAgent.cpp:
(WebCore::WorkerRuntimeAgent::willDestroyFrontendAndBackend):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeListjson">trunk/Source/JavaScriptCore/bytecode/BytecodeList.json</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeUseDefh">trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockh">trunk/Source/JavaScriptCore/bytecode/CodeBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeTypeLocationh">trunk/Source/JavaScriptCore/bytecode/TypeLocation.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerNodesCodegencpp">trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorRuntimeAgentcpp">trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorRuntimeAgenth">trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsJSGlobalObjectRuntimeAgentcpp">trunk/Source/JavaScriptCore/inspector/agents/JSGlobalObjectRuntimeAgent.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorprotocolRuntimejson">trunk/Source/JavaScriptCore/inspector/protocol/Runtime.json</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITcpp">trunk/Source/JavaScriptCore/jit/JIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITh">trunk/Source/JavaScriptCore/jit/JIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodescpp">trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodes32_64cpp">trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationscpp">trunk/Source/JavaScriptCore/jit/JITOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationsh">trunk/Source/JavaScriptCore/jit/JITOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathscpp">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathsh">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreterasm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCodeCachecpp">trunk/Source/JavaScriptCore/runtime/CodeCache.cpp</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="#trunkSourceJavaScriptCoreruntimeHighFidelityLogcpp">trunk/Source/JavaScriptCore/runtime/HighFidelityLog.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeHighFidelityLogh">trunk/Source/JavaScriptCore/runtime/HighFidelityLog.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeHighFidelityTypeProfilercpp">trunk/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeHighFidelityTypeProfilerh">trunk/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.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="#trunkSourceJavaScriptCoreruntimeTypeLocationCachecpp">trunk/Source/JavaScriptCore/runtime/TypeLocationCache.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeTypeSetcpp">trunk/Source/JavaScriptCore/runtime/TypeSet.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeTypeSeth">trunk/Source/JavaScriptCore/runtime/TypeSet.h</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>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreinspectorPageRuntimeAgentcpp">trunk/Source/WebCore/inspector/PageRuntimeAgent.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorWorkerRuntimeAgentcpp">trunk/Source/WebCore/inspector/WorkerRuntimeAgent.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -1,3 +1,144 @@
</span><ins>+2014-08-14  Saam Barati  &lt;sbarati@apple.com&gt;
+
+        Allow high fidelity type profiling to be enabled and disabled.
+        https://bugs.webkit.org/show_bug.cgi?id=135423
+
+        Reviewed by Geoffrey Garen.
+
+        - Merged op_put_to_scope_with_profile and op_get_from_scope_with_profile into
+          op_profile_types_with_high_fidelity by adding extra arguments to the opcode.
+        - Altered SymbolTable to use less memory by adding a rare data structure for 
+          type profiling.
+        - Created an interface to turn on and off type profiling from the Web
+          Inspector.
+        - Refactored how entries are written to HighFidelityLog to make it
+          easier to inline when generating machine code.
+        - Implemented op_profile_types_with_high_fidelity in the baseline JIT
+          by inlining the process of writing to the log and doing a small amount
+          of type inference optimizations.
+
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::finalizeUnconditionally):
+        (JSC::CodeBlock::scopeDependentProfile): Deleted.
+        * bytecode/CodeBlock.h:
+        * bytecode/TypeLocation.h:
+        (JSC::TypeLocation::TypeLocation):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::generate):
+        (JSC::BytecodeGenerator::emitMove):
+        (JSC::BytecodeGenerator::emitProfileTypesWithHighFidelity):
+        (JSC::BytecodeGenerator::emitGetFromScopeWithProfile): Deleted.
+        (JSC::BytecodeGenerator::emitPutToScopeWithProfile): Deleted.
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ThisNode::emitBytecode):
+        (JSC::ResolveNode::emitBytecode):
+        (JSC::BracketAccessorNode::emitBytecode):
+        (JSC::DotAccessorNode::emitBytecode):
+        (JSC::FunctionCallValueNode::emitBytecode):
+        (JSC::FunctionCallResolveNode::emitBytecode):
+        (JSC::FunctionCallBracketNode::emitBytecode):
+        (JSC::FunctionCallDotNode::emitBytecode):
+        (JSC::CallFunctionCallDotNode::emitBytecode):
+        (JSC::ApplyFunctionCallDotNode::emitBytecode):
+        (JSC::PostfixNode::emitResolve):
+        (JSC::PostfixNode::emitBracket):
+        (JSC::PostfixNode::emitDot):
+        (JSC::PrefixNode::emitResolve):
+        (JSC::PrefixNode::emitBracket):
+        (JSC::PrefixNode::emitDot):
+        (JSC::ReadModifyResolveNode::emitBytecode):
+        (JSC::AssignResolveNode::emitBytecode):
+        (JSC::AssignDotNode::emitBytecode):
+        (JSC::ReadModifyDotNode::emitBytecode):
+        (JSC::AssignBracketNode::emitBytecode):
+        (JSC::ReadModifyBracketNode::emitBytecode):
+        (JSC::ReturnNode::emitBytecode):
+        (JSC::FunctionBodyNode::emitBytecode):
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::InspectorRuntimeAgent):
+        (Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
+        (Inspector::TypeRecompiler::operator()):
+        (Inspector::recompileAllJSFunctionsForTypeProfiling):
+        (Inspector::InspectorRuntimeAgent::willDestroyFrontendAndBackend):
+        (Inspector::InspectorRuntimeAgent::enableHighFidelityTypeProfiling):
+        (Inspector::InspectorRuntimeAgent::disableHighFidelityTypeProfiling):
+        (Inspector::InspectorRuntimeAgent::setHighFidelityTypeProfilingEnabledState):
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * inspector/agents/JSGlobalObjectRuntimeAgent.cpp:
+        (Inspector::JSGlobalObjectRuntimeAgent::willDestroyFrontendAndBackend):
+        * inspector/protocol/Runtime.json:
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompile):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_profile_types_with_high_fidelity):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_profile_types_with_high_fidelity):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        (JSC::LLInt::getFromScopeCommon): Deleted.
+        (JSC::LLInt::putToScopeCommon): Deleted.
+        * llint/LLIntSlowPaths.h:
+        * llint/LowLevelInterpreter.asm:
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getGlobalCodeBlock):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        * runtime/HighFidelityLog.cpp:
+        (JSC::HighFidelityLog::initializeHighFidelityLog):
+        (JSC::HighFidelityLog::~HighFidelityLog):
+        (JSC::HighFidelityLog::processHighFidelityLog):
+        * runtime/HighFidelityLog.h:
+        (JSC::HighFidelityLog::LogEntry::structureIDOffset):
+        (JSC::HighFidelityLog::LogEntry::valueOffset):
+        (JSC::HighFidelityLog::LogEntry::locationOffset):
+        (JSC::HighFidelityLog::recordTypeInformationForLocation):
+        (JSC::HighFidelityLog::logEndPtr):
+        (JSC::HighFidelityLog::logStartOffset):
+        (JSC::HighFidelityLog::currentLogEntryOffset):
+        * runtime/HighFidelityTypeProfiler.cpp:
+        (JSC::HighFidelityTypeProfiler::logTypesForTypeLocation):
+        (JSC::descriptorMatchesTypeLocation):
+        * runtime/HighFidelityTypeProfiler.h:
+        * runtime/SymbolTable.cpp:
+        (JSC::SymbolTable::SymbolTable):
+        (JSC::SymbolTable::cloneCapturedNames):
+        (JSC::SymbolTable::prepareForHighFidelityTypeProfiling):
+        (JSC::SymbolTable::uniqueIDForVariable):
+        (JSC::SymbolTable::uniqueIDForRegister):
+        (JSC::SymbolTable::globalTypeSetForRegister):
+        (JSC::SymbolTable::globalTypeSetForVariable):
+        * runtime/SymbolTable.h:
+        (JSC::SymbolTable::add):
+        (JSC::SymbolTable::set):
+        * runtime/TypeLocationCache.cpp:
+        (JSC::TypeLocationCache::getTypeLocation):
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::getRuntimeTypeForValue):
+        (JSC::TypeSet::addTypeInformation):
+        (JSC::TypeSet::allPrimitiveTypeNames):
+        (JSC::TypeSet::addTypeForValue): Deleted.
+        * runtime/TypeSet.h:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        (JSC::VM::nextTypeLocation):
+        (JSC::VM::enableHighFidelityTypeProfiling):
+        (JSC::VM::disableHighFidelityTypeProfiling):
+        (JSC::VM::dumpHighFidelityProfilingTypes):
+        * runtime/VM.h:
+        (JSC::VM::nextLocation): Deleted.
+
</ins><span class="cx"> 2014-08-14  Oliver Hunt  &lt;oliver@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Update scope resolution to assume that the parent activation is always there
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeListjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeList.json (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -109,9 +109,7 @@
</span><span class="cx">             { &quot;name&quot; : &quot;op_to_primitive&quot;, &quot;length&quot; : 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_resolve_scope&quot;, &quot;length&quot; : 6 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_get_from_scope&quot;, &quot;length&quot; : 8 },
</span><del>-            { &quot;name&quot; : &quot;op_get_from_scope_with_profile&quot;, &quot;length&quot; : 9 },
</del><span class="cx">             { &quot;name&quot; : &quot;op_put_to_scope&quot;, &quot;length&quot; : 7 },
</span><del>-            { &quot;name&quot; : &quot;op_put_to_scope_with_profile&quot;, &quot;length&quot; : 8 },
</del><span class="cx">             { &quot;name&quot; : &quot;op_push_with_scope&quot;, &quot;length&quot; : 2 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_pop_scope&quot;, &quot;length&quot; : 1 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_push_name_scope&quot;, &quot;length&quot; : 4 },
</span><span class="lines">@@ -122,7 +120,7 @@
</span><span class="cx">             { &quot;name&quot; : &quot;op_profile_will_call&quot;, &quot;length&quot; : 2 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_profile_did_call&quot;, &quot;length&quot; : 2 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_end&quot;, &quot;length&quot; : 2 },
</span><del>-            { &quot;name&quot; : &quot;op_profile_types_with_high_fidelity&quot;, &quot;length&quot; : 4 },
</del><ins>+            { &quot;name&quot; : &quot;op_profile_types_with_high_fidelity&quot;, &quot;length&quot; : 6 },
</ins><span class="cx">             { &quot;name&quot; : &quot;op_get_enumerable_length&quot;, &quot;length&quot; : 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_has_indexed_property&quot;, &quot;length&quot; : 5 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_has_structure_property&quot;, &quot;length&quot; : 5 },
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeUseDefh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -106,7 +106,6 @@
</span><span class="cx">     case op_put_by_id_transition_normal_out_of_line:
</span><span class="cx">     case op_put_by_id_out_of_line:
</span><span class="cx">     case op_put_by_id:
</span><del>-    case op_put_to_scope_with_profile:
</del><span class="cx">     case op_put_to_scope: {
</span><span class="cx">         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
</span><span class="cx">         functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
</span><span class="lines">@@ -123,7 +122,6 @@
</span><span class="cx">     case op_init_global_const_nop:
</span><span class="cx">     case op_init_global_const:
</span><span class="cx">     case op_push_name_scope:
</span><del>-    case op_get_from_scope_with_profile:
</del><span class="cx">     case op_get_from_scope:
</span><span class="cx">     case op_to_primitive:
</span><span class="cx">     case op_get_by_id:
</span><span class="lines">@@ -251,7 +249,6 @@
</span><span class="cx">     case op_push_name_scope:
</span><span class="cx">     case op_push_with_scope:
</span><span class="cx">     case op_put_to_scope:
</span><del>-    case op_put_to_scope_with_profile:
</del><span class="cx">     case op_pop_scope:
</span><span class="cx">     case op_end:
</span><span class="cx">     case op_profile_will_call:
</span><span class="lines">@@ -321,7 +318,6 @@
</span><span class="cx">     case op_new_func_exp:
</span><span class="cx">     case op_call_varargs:
</span><span class="cx">     case op_construct_varargs:
</span><del>-    case op_get_from_scope_with_profile:
</del><span class="cx">     case op_get_from_scope:
</span><span class="cx">     case op_call:
</span><span class="cx">     case op_call_eval:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -1523,7 +1523,6 @@
</span><span class="cx">                 operand);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><del>-        case op_put_to_scope_with_profile:
</del><span class="cx">         case op_put_to_scope: {
</span><span class="cx">             int r0 = (++it)-&gt;u.operand;
</span><span class="cx">             int id0 = (++it)-&gt;u.operand;
</span><span class="lines">@@ -1532,8 +1531,6 @@
</span><span class="cx">             ++it; // Structure
</span><span class="cx">             int operand = (++it)-&gt;u.operand; // Operand
</span><span class="cx">             printLocationAndOp(out, exec, location, it, &quot;put_to_scope&quot;);
</span><del>-            if (opcode == op_put_to_scope_with_profile)
-                ++it;
</del><span class="cx">             out.printf(&quot;%s, %s, %s, %u&lt;%s|%s&gt;, &lt;structure&gt;, %d&quot;,
</span><span class="cx">                 registerName(r0).data(), idName(id0, identifier(id0)).data(), registerName(r1).data(),
</span><span class="cx">                 modeAndType.operand(), resolveModeName(modeAndType.mode()), resolveTypeName(modeAndType.type()),
</span><span class="lines">@@ -1716,6 +1713,11 @@
</span><span class="cx">     bool didCloneSymbolTable = false;
</span><span class="cx">     
</span><span class="cx">     if (SymbolTable* symbolTable = unlinkedCodeBlock-&gt;symbolTable()) {
</span><ins>+        if (m_vm-&gt;isProfilingTypesWithHighFidelity()) {
+            ConcurrentJITLocker locker(symbolTable-&gt;m_lock);
+            symbolTable-&gt;prepareForHighFidelityTypeProfiling(locker);
+        }
+
</ins><span class="cx">         if (codeType() == FunctionCode &amp;&amp; symbolTable-&gt;captureCount()) {
</span><span class="cx">             m_symbolTable.set(*m_vm, m_ownerExecutable.get(), symbolTable-&gt;cloneCapturedNames(*m_vm));
</span><span class="cx">             didCloneSymbolTable = true;
</span><span class="lines">@@ -1949,13 +1951,11 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        case op_get_from_scope_with_profile:
</del><span class="cx">         case op_get_from_scope: {
</span><del>-            int offset = (pc[0].u.opcode == op_get_from_scope_with_profile ? 2 : 1);
-            ValueProfile* profile = &amp;m_valueProfiles[pc[opLength - offset].u.operand];
</del><ins>+            ValueProfile* profile = &amp;m_valueProfiles[pc[opLength - 1].u.operand];
</ins><span class="cx">             ASSERT(profile-&gt;m_bytecodeOffset == -1);
</span><span class="cx">             profile-&gt;m_bytecodeOffset = i;
</span><del>-            instructions[i + opLength - offset] = profile;
</del><ins>+            instructions[i + opLength - 1] = profile;
</ins><span class="cx"> 
</span><span class="cx">             // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
</span><span class="cx">             const Identifier&amp; ident = identifier(pc[3].u.operand);
</span><span class="lines">@@ -1969,16 +1969,9 @@
</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><span class="cx"> 
</span><del>-            if (pc[0].u.opcode == op_get_from_scope_with_profile) {
-                // The format of this instruction is: get_from_scope_with_profile dst, scope, id, ResolveModeAndType, Structure, Operand, ..., TypeLocation
-                size_t instructionOffset = i + opLength - 1;
-                TypeLocation* location = scopeDependentProfile(op, ident, instructionOffset);
-                instructions[i + 8].u.location = location;
-            }
</del><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        case op_put_to_scope_with_profile:
</del><span class="cx">         case op_put_to_scope: {
</span><span class="cx">             // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
</span><span class="cx">             const Identifier&amp; ident = identifier(pc[2].u.operand);
</span><span class="lines">@@ -1995,30 +1988,50 @@
</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><span class="cx"> 
</span><del>-            if (pc[0].u.opcode == op_put_to_scope_with_profile) {
-                // The format of this instruction is: put_to_scope_with_profile scope, id, value, ResolveModeAndType, Structure, Operand, TypeLocation*
-                size_t instructionOffset = i + opLength - 1;
-                TypeLocation* location = scopeDependentProfile(op, ident, instructionOffset);
-                instructions[i + 7].u.location = location;
-            }
</del><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         case op_profile_types_with_high_fidelity: {
</span><ins>+            // The format of this instruction is: op_profile_types_with_high_fidelity regToProfile, TypeLocation*, flag, identifier?, resolveType?
</ins><span class="cx">             size_t instructionOffset = i + opLength - 1;
</span><span class="cx">             unsigned divotStart, divotEnd;
</span><span class="cx">             GlobalVariableID globalVariableID;
</span><span class="cx">             RefPtr&lt;TypeSet&gt; globalTypeSet;
</span><span class="cx">             bool shouldAnalyze = m_unlinkedCode-&gt;highFidelityTypeProfileExpressionInfoForBytecodeOffset(instructionOffset, divotStart, divotEnd);
</span><del>-            VirtualRegister virtualRegister(pc[1].u.operand);
-            SymbolTable* symbolTable = m_symbolTable.get();
-
</del><ins>+            VirtualRegister profileRegister(pc[1].u.operand);
</ins><span class="cx">             ProfileTypesWithHighFidelityBytecodeFlag flag = static_cast&lt;ProfileTypesWithHighFidelityBytecodeFlag&gt;(pc[3].u.operand);
</span><ins>+            SymbolTable* symbolTable = nullptr;
+
</ins><span class="cx">             switch (flag) {
</span><ins>+            case ProfileTypesBytecodePutToScope:
+            case ProfileTypesBytecodeGetFromScope: {
+                const Identifier&amp; ident = identifier(pc[4].u.operand);
+                ResolveType type = static_cast&lt;ResolveType&gt;(pc[5].u.operand);
+                ResolveOp op = JSScope::abstractResolve(m_globalObject-&gt;globalExec(), scope, ident, (flag == ProfileTypesBytecodeGetFromScope ? Get : Put), type);
+
+                // FIXME: handle other values for op.type here, and also consider what to do when we can't statically determine the globalID
+                // https://bugs.webkit.org/show_bug.cgi?id=135184
+                if (op.type == ClosureVar)
+                    symbolTable = op.activation-&gt;symbolTable();
+                else if (op.type == GlobalVar)
+                    symbolTable = m_globalObject.get()-&gt;symbolTable();
+                
+                if (symbolTable) {
+                    ConcurrentJITLocker locker(symbolTable-&gt;m_lock);
+                    // If our parent scope was created while profiling was disabled, it will not have prepared for profiling yet.
+                    symbolTable-&gt;prepareForHighFidelityTypeProfiling(locker);
+                    globalVariableID = symbolTable-&gt;uniqueIDForVariable(locker, ident.impl(), *vm());
+                    globalTypeSet = symbolTable-&gt;globalTypeSetForVariable(locker, ident.impl(), *vm());
+                } else
+                    globalVariableID = HighFidelityNoGlobalIDExists;
+
+                break;
+            }
</ins><span class="cx">             case ProfileTypesBytecodeHasGlobalID: {
</span><ins>+                symbolTable = m_symbolTable.get();
</ins><span class="cx">                 ConcurrentJITLocker locker(symbolTable-&gt;m_lock);
</span><del>-                globalVariableID = symbolTable-&gt;uniqueIDForRegister(locker, virtualRegister.offset(), *vm());
-                globalTypeSet = symbolTable-&gt;globalTypeSetForRegister(locker, virtualRegister.offset(), *vm());
</del><ins>+                globalVariableID = symbolTable-&gt;uniqueIDForRegister(locker, profileRegister.offset(), *vm());
+                globalTypeSet = symbolTable-&gt;globalTypeSetForRegister(locker, profileRegister.offset(), *vm());
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             case ProfileTypesBytecodeDoesNotHaveGlobalID: 
</span><span class="lines">@@ -2026,10 +2039,6 @@
</span><span class="cx">                 globalVariableID = HighFidelityNoGlobalIDExists;
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><del>-            case ProfileTypesBytecodeFunctionThisObject: {
-                globalVariableID = HighFidelityThisStatement;
-                break;
-            }
</del><span class="cx">             case ProfileTypesBytecodeFunctionReturnStatement: {
</span><span class="cx">                 globalTypeSet = returnStatementTypeSet();
</span><span class="cx">                 globalVariableID = HighFidelityReturnStatement;
</span><span class="lines">@@ -2043,7 +2052,8 @@
</span><span class="cx">             }
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            std::pair&lt;TypeLocation*, bool&gt; locationPair = vm()-&gt;highFidelityTypeProfiler()-&gt;typeLocationCache()-&gt;getTypeLocation(globalVariableID, m_ownerExecutable-&gt;sourceID(), divotStart, divotEnd, globalTypeSet, vm());
</del><ins>+            std::pair&lt;TypeLocation*, bool&gt; locationPair = vm()-&gt;highFidelityTypeProfiler()-&gt;typeLocationCache()-&gt;getTypeLocation(globalVariableID,
+                m_ownerExecutable-&gt;sourceID(), divotStart, divotEnd, globalTypeSet, vm());
</ins><span class="cx">             TypeLocation* location = locationPair.first;
</span><span class="cx">             bool isNewLocation = locationPair.second;
</span><span class="cx"> 
</span><span class="lines">@@ -2524,9 +2534,7 @@
</span><span class="cx">                 activation.clear();
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><del>-            case op_get_from_scope_with_profile:
</del><span class="cx">             case op_get_from_scope:
</span><del>-            case op_put_to_scope_with_profile:
</del><span class="cx">             case op_put_to_scope: {
</span><span class="cx">                 ResolveModeAndType modeAndType =
</span><span class="cx">                     ResolveModeAndType(curInstruction[4].u.operand);
</span><span class="lines">@@ -3935,35 +3943,4 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-TypeLocation* CodeBlock::scopeDependentProfile(ResolveOp op, const Identifier&amp; ident, size_t instructionOffset)
-{
-    unsigned divotStart, divotEnd;
-    bool shouldAnalyze = m_unlinkedCode-&gt;highFidelityTypeProfileExpressionInfoForBytecodeOffset(instructionOffset, divotStart, divotEnd);
-    GlobalVariableID globalVariableID;
-    RefPtr&lt;TypeSet&gt; globalTypeSet;
-
-    // FIXME: handle other values for op.type here, and also consider what to do when we can't statically determine the globalID
-    SymbolTable* symbolTable = nullptr;
-    if (op.type == ClosureVar) 
-        symbolTable = op.activation-&gt;symbolTable();
-    else if (op.type == GlobalVar)
-        symbolTable = m_globalObject.get()-&gt;symbolTable();
-    
-    if (symbolTable) {
-        ConcurrentJITLocker locker(symbolTable-&gt;m_lock);
-        globalVariableID = symbolTable-&gt;uniqueIDForVariable(locker, ident.impl(), *vm());
-        globalTypeSet = symbolTable-&gt;globalTypeSetForVariable(locker, ident.impl(), *vm());
-    } else
-        globalVariableID = HighFidelityNoGlobalIDExists;
-
-    std::pair&lt;TypeLocation*, bool&gt; locationPair = vm()-&gt;highFidelityTypeProfiler()-&gt;typeLocationCache()-&gt;getTypeLocation(globalVariableID, m_ownerExecutable-&gt;sourceID(), divotStart, divotEnd, globalTypeSet, vm());
-    TypeLocation* location = locationPair.first;
-    bool isNewLocation = locationPair.second;
-
-    if (shouldAnalyze &amp; isNewLocation)
-        vm()-&gt;highFidelityTypeProfiler()-&gt;insertNewLocation(location);
-
-    return location;
-}
-
</del><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.h (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -1020,8 +1020,6 @@
</span><span class="cx">             m_rareData = adoptPtr(new RareData);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    TypeLocation* scopeDependentProfile(ResolveOp, const Identifier&amp;, size_t);
-    
</del><span class="cx"> #if ENABLE(JIT)
</span><span class="cx">     void resetStubInternal(RepatchBuffer&amp;, StructureStubInfo&amp;);
</span><span class="cx">     void resetStubDuringGCInternal(RepatchBuffer&amp;, StructureStubInfo&amp;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeTypeLocationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/TypeLocation.h (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/TypeLocation.h        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/bytecode/TypeLocation.h        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -33,22 +33,23 @@
</span><span class="cx"> enum HighFidelityGlobalIDFlags {
</span><span class="cx">     HighFidelityNeedsUniqueIDGeneration = -1,
</span><span class="cx">     HighFidelityNoGlobalIDExists = -2,
</span><del>-    HighFidelityReturnStatement = -3,
-    HighFidelityThisStatement = -4
</del><ins>+    HighFidelityReturnStatement = -3
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> typedef intptr_t GlobalVariableID;
</span><span class="cx"> 
</span><span class="cx"> class TypeLocation {
</span><span class="cx"> public:
</span><del>-    TypeLocation() 
-        : m_divotForFunctionOffsetIfReturnStatement(UINT_MAX)
</del><ins>+    TypeLocation()
+        : m_lastSeenType(TypeNothing)
+        , m_divotForFunctionOffsetIfReturnStatement(UINT_MAX)
</ins><span class="cx">         , m_instructionTypeSet(TypeSet::create())
</span><span class="cx">         , m_globalTypeSet(nullptr)
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     GlobalVariableID m_globalVariableID;
</span><ins>+    RuntimeType m_lastSeenType;
</ins><span class="cx">     intptr_t m_sourceID;
</span><span class="cx">     unsigned m_divotStart;
</span><span class="cx">     unsigned m_divotEnd;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -115,7 +115,7 @@
</span><span class="cx"> 
</span><span class="cx">     m_codeBlock-&gt;shrinkToFit();
</span><span class="cx"> 
</span><del>-    if (m_codeBlock-&gt;symbolTable())
</del><ins>+    if (m_codeBlock-&gt;symbolTable() &amp;&amp; !m_codeBlock-&gt;vm()-&gt;isProfilingTypesWithHighFidelity())
</ins><span class="cx">         m_codeBlock-&gt;setSymbolTable(m_codeBlock-&gt;symbolTable()-&gt;cloneCapturedNames(*m_codeBlock-&gt;vm()));
</span><span class="cx"> 
</span><span class="cx">     if (m_expressionTooDeep)
</span><span class="lines">@@ -1007,7 +1007,7 @@
</span><span class="cx">         instructions().append(watchableVariable(dst-&gt;index()));
</span><span class="cx"> 
</span><span class="cx">     if (!dst-&gt;isTemporary() &amp;&amp; isProfilingTypesWithHighFidelity())
</span><del>-        emitProfileTypesWithHighFidelity(dst, ProfileTypesBytecodeHasGlobalID);
</del><ins>+        emitProfileTypesWithHighFidelity(dst, ProfileTypesBytecodeHasGlobalID, nullptr);
</ins><span class="cx"> 
</span><span class="cx">     return dst;
</span><span class="cx"> }
</span><span class="lines">@@ -1126,12 +1126,18 @@
</span><span class="cx">     m_codeBlock-&gt;addHighFidelityTypeProfileExpressionInfo(instructionOffset, start, end);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void BytecodeGenerator::emitProfileTypesWithHighFidelity(RegisterID* registerToProfile, ProfileTypesWithHighFidelityBytecodeFlag flag)
</del><ins>+void BytecodeGenerator::emitProfileTypesWithHighFidelity(RegisterID* registerToProfile, ProfileTypesWithHighFidelityBytecodeFlag flag, const Identifier* identifier)
</ins><span class="cx"> {
</span><ins>+    if (flag == ProfileTypesBytecodeGetFromScope || flag == ProfileTypesBytecodePutToScope)
+        RELEASE_ASSERT(identifier);
+
+    // The format of this instruction is: op_profile_types_with_high_fidelity regToProfile, TypeLocation*, flag, identifier?, resolveType?
</ins><span class="cx">     emitOpcode(op_profile_types_with_high_fidelity);
</span><span class="cx">     instructions().append(registerToProfile-&gt;index());
</span><del>-    instructions().append(0); // This is a placeholder for the TypeLocation object pointer.
</del><ins>+    instructions().append(0);
</ins><span class="cx">     instructions().append(flag);
</span><ins>+    instructions().append(identifier ? addConstant(*identifier) : 0);
+    instructions().append(resolveType());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, bool b)
</span><span class="lines">@@ -1273,22 +1279,6 @@
</span><span class="cx">     return dst;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* BytecodeGenerator::emitGetFromScopeWithProfile(RegisterID* dst, RegisterID* scope, const Identifier&amp; identifier, ResolveMode resolveMode)
-{
-    m_codeBlock-&gt;addPropertyAccessInstruction(instructions().size());
-
-    UnlinkedValueProfile profile = emitProfiledOpcode(op_get_from_scope_with_profile);
-    instructions().append(kill(dst));
-    instructions().append(scope-&gt;index());
-    instructions().append(addConstant(identifier));
-    instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
-    instructions().append(0);
-    instructions().append(0);
-    instructions().append(profile);
-    instructions().append(0); // This is a placeholder for a TypeLocation pointer.
-    return dst;
-}
-
</del><span class="cx"> RegisterID* BytecodeGenerator::emitPutToScope(RegisterID* scope, const Identifier&amp; identifier, RegisterID* value, ResolveMode resolveMode)
</span><span class="cx"> {
</span><span class="cx">     m_codeBlock-&gt;addPropertyAccessInstruction(instructions().size());
</span><span class="lines">@@ -1304,21 +1294,6 @@
</span><span class="cx">     return value;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RegisterID* BytecodeGenerator::emitPutToScopeWithProfile(RegisterID* scope, const Identifier&amp; identifier, RegisterID* value, ResolveMode resolveMode)
-{
-    m_codeBlock-&gt;addPropertyAccessInstruction(instructions().size());
-
-    emitOpcode(op_put_to_scope_with_profile);
-    instructions().append(scope-&gt;index());
-    instructions().append(addConstant(identifier));
-    instructions().append(value-&gt;index());
-    instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
-    instructions().append(0);
-    instructions().append(0);
-    instructions().append(0); // This is a placeholder for a TypeLocation pointer.
-    return value;
-}
-
</del><span class="cx"> RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype)
</span><span class="cx"> { 
</span><span class="cx">     emitOpcode(op_instanceof);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -223,12 +223,13 @@
</span><span class="cx">         TryData* tryData;
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    enum ProfileTypesWithHighFidelityBytecodeFlag { 
</del><ins>+    enum ProfileTypesWithHighFidelityBytecodeFlag {
+        ProfileTypesBytecodePutToScope,
+        ProfileTypesBytecodeGetFromScope,
</ins><span class="cx">         ProfileTypesBytecodeHasGlobalID,
</span><span class="cx">         ProfileTypesBytecodeDoesNotHaveGlobalID,
</span><span class="cx">         ProfileTypesBytecodeFunctionArgument,
</span><del>-        ProfileTypesBytecodeFunctionThisObject,
-        ProfileTypesBytecodeFunctionReturnStatement  
</del><ins>+        ProfileTypesBytecodeFunctionReturnStatement
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     class BytecodeGenerator {
</span><span class="lines">@@ -410,7 +411,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         void emitHighFidelityTypeProfilingExpressionInfo(const JSTextPosition&amp; startDivot, const JSTextPosition&amp; endDivot);
</span><del>-        void emitProfileTypesWithHighFidelity(RegisterID* dst, ProfileTypesWithHighFidelityBytecodeFlag);
</del><ins>+        void emitProfileTypesWithHighFidelity(RegisterID* registerToProfile, ProfileTypesWithHighFidelityBytecodeFlag, const Identifier*);
</ins><span class="cx"> 
</span><span class="cx">         RegisterID* emitLoad(RegisterID* dst, bool);
</span><span class="cx">         RegisterID* emitLoad(RegisterID* dst, double);
</span><span class="lines">@@ -477,9 +478,7 @@
</span><span class="cx">         ResolveType resolveType();
</span><span class="cx">         RegisterID* emitResolveScope(RegisterID* dst, const Identifier&amp;);
</span><span class="cx">         RegisterID* emitGetFromScope(RegisterID* dst, RegisterID* scope, const Identifier&amp;, ResolveMode);
</span><del>-        RegisterID* emitGetFromScopeWithProfile(RegisterID* dst, RegisterID* scope, const Identifier&amp;, ResolveMode);
</del><span class="cx">         RegisterID* emitPutToScope(RegisterID* scope, const Identifier&amp;, RegisterID* value, ResolveMode);
</span><del>-        RegisterID* emitPutToScopeWithProfile(RegisterID* scope, const Identifier&amp;, RegisterID* value, ResolveMode);
</del><span class="cx"> 
</span><span class="cx">         PassRefPtr&lt;Label&gt; emitLabel(Label*);
</span><span class="cx">         void emitLoopHint();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerNodesCodegencpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -137,7 +137,14 @@
</span><span class="cx"> {
</span><span class="cx">     if (dst == generator.ignoredResult())
</span><span class="cx">         return 0;
</span><del>-    return generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
</del><ins>+
+    RegisterID* result = generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
+    if (generator.isProfilingTypesWithHighFidelity()) {
+        generator.emitProfileTypesWithHighFidelity(generator.thisRegister(), ProfileTypesBytecodeDoesNotHaveGlobalID, nullptr);
+        static const unsigned thisLength = 4;
+        generator.emitHighFidelityTypeProfilingExpressionInfo(position(), JSTextPosition(-1, position().offset + thisLength, -1));
+    }
+    return result;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ResolveNode ----------------------------------
</span><span class="lines">@@ -153,7 +160,7 @@
</span><span class="cx">         if (dst == generator.ignoredResult())
</span><span class="cx">             return 0;
</span><span class="cx">         if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-            generator.emitProfileTypesWithHighFidelity(local.get(), ProfileTypesBytecodeHasGlobalID);
</del><ins>+            generator.emitProfileTypesWithHighFidelity(local.get(), ProfileTypesBytecodeHasGlobalID, nullptr);
</ins><span class="cx">             generator.emitHighFidelityTypeProfilingExpressionInfo(m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
</span><span class="cx">         }
</span><span class="cx">         return generator.moveToDestinationIfNeeded(dst, local.get());
</span><span class="lines">@@ -162,13 +169,13 @@
</span><span class="cx">     JSTextPosition divot = m_start + m_ident.length();
</span><span class="cx">     generator.emitExpressionInfo(divot, m_start, divot);
</span><span class="cx">     RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.tempDestination(dst), m_ident);
</span><del>-    RegisterID* ret;
</del><ins>+    RegisterID* finalDest = generator.finalDestination(dst);
+    RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), m_ident, ThrowIfNotFound);
</ins><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        ret = generator.emitGetFromScopeWithProfile(generator.finalDestination(dst), scope.get(), m_ident, ThrowIfNotFound);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(finalDest, ProfileTypesBytecodeGetFromScope, &amp;m_ident);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
</span><del>-    } else
-        ret = generator.emitGetFromScope(generator.finalDestination(dst), scope.get(), m_ident, ThrowIfNotFound);
-    return ret;
</del><ins>+    }
+    return result;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ ArrayNode ------------------------------------
</span><span class="lines">@@ -387,7 +394,7 @@
</span><span class="cx">     RegisterID* finalDest = generator.finalDestination(dst);
</span><span class="cx">     RegisterID* ret = generator.emitGetByVal(finalDest, base.get(), property);
</span><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        generator.emitProfileTypesWithHighFidelity(finalDest, ProfileTypesBytecodeDoesNotHaveGlobalID);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(finalDest, ProfileTypesBytecodeDoesNotHaveGlobalID, nullptr);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx">     return ret;
</span><span class="lines">@@ -413,7 +420,7 @@
</span><span class="cx">     RegisterID* finalDest = generator.finalDestination(dst);
</span><span class="cx">     RegisterID* ret = generator.emitGetById(finalDest, base, m_ident);
</span><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        generator.emitProfileTypesWithHighFidelity(finalDest, ProfileTypesBytecodeDoesNotHaveGlobalID);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(finalDest, ProfileTypesBytecodeDoesNotHaveGlobalID, nullptr);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx">     return ret;
</span><span class="lines">@@ -497,7 +504,7 @@
</span><span class="cx">     generator.emitLoad(callArguments.thisRegister(), jsUndefined());
</span><span class="cx">     RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</span><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID, nullptr);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx">     return ret;
</span><span class="lines">@@ -518,7 +525,7 @@
</span><span class="cx">         // local variable, then it's not one of our built-in constructors.
</span><span class="cx">         RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</span><span class="cx">         if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-            generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID);
</del><ins>+            generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID, nullptr);
</ins><span class="cx">             generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">         }
</span><span class="cx">         return ret;
</span><span class="lines">@@ -534,7 +541,7 @@
</span><span class="cx">     generator.emitGetFromScope(func.get(), callArguments.thisRegister(), m_ident, ThrowIfNotFound);
</span><span class="cx">     RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
</span><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID, nullptr);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx">     return ret;
</span><span class="lines">@@ -553,7 +560,7 @@
</span><span class="cx">     generator.emitMove(callArguments.thisRegister(), base.get());
</span><span class="cx">     RegisterID* ret = generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</span><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID, nullptr);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx">     return ret;
</span><span class="lines">@@ -571,7 +578,7 @@
</span><span class="cx">     generator.emitGetById(function.get(), callArguments.thisRegister(), m_ident);
</span><span class="cx">     RegisterID* ret = generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
</span><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID, nullptr);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx">     return ret;
</span><span class="lines">@@ -645,7 +652,7 @@
</span><span class="cx">         generator.emitLabel(end.get());
</span><span class="cx">     }
</span><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID, nullptr);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx">     return returnValue.get();
</span><span class="lines">@@ -759,7 +766,7 @@
</span><span class="cx">         generator.emitLabel(end.get());
</span><span class="cx">     }
</span><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(returnValue.get(), ProfileTypesBytecodeDoesNotHaveGlobalID, nullptr);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx">     return returnValue.get();
</span><span class="lines">@@ -814,11 +821,11 @@
</span><span class="cx">     RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.newTemporary(), ident);
</span><span class="cx">     RefPtr&lt;RegisterID&gt; value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound);
</span><span class="cx">     RefPtr&lt;RegisterID&gt; oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
</span><ins>+    generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound);
</ins><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        generator.emitPutToScopeWithProfile(scope.get(), ident, value.get(), ThrowIfNotFound);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(value.get(), ProfileTypesBytecodePutToScope, &amp;ident);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><del>-    } else
-        generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound);
</del><ins>+    }
</ins><span class="cx"> 
</span><span class="cx">     return oldValue.get();
</span><span class="cx"> }
</span><span class="lines">@@ -842,7 +849,7 @@
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><span class="cx">     generator.emitPutByVal(base.get(), property.get(), value.get());
</span><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        generator.emitProfileTypesWithHighFidelity(value.get(), ProfileTypesBytecodeDoesNotHaveGlobalID);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(value.get(), ProfileTypesBytecodeDoesNotHaveGlobalID, nullptr);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx">     return generator.moveToDestinationIfNeeded(dst, oldValue);
</span><span class="lines">@@ -866,7 +873,7 @@
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><span class="cx">     generator.emitPutById(base.get(), ident, value.get());
</span><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        generator.emitProfileTypesWithHighFidelity(value.get(), ProfileTypesBytecodeDoesNotHaveGlobalID);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(value.get(), ProfileTypesBytecodeDoesNotHaveGlobalID, nullptr);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx">     return generator.moveToDestinationIfNeeded(dst, oldValue);
</span><span class="lines">@@ -1002,11 +1009,11 @@
</span><span class="cx">     RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.tempDestination(dst), ident);
</span><span class="cx">     RefPtr&lt;RegisterID&gt; value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), ident, ThrowIfNotFound);
</span><span class="cx">     emitIncOrDec(generator, value.get(), m_operator);
</span><ins>+    generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound);
</ins><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        generator.emitPutToScopeWithProfile(scope.get(), ident, value.get(), ThrowIfNotFound);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(value.get(), ProfileTypesBytecodePutToScope, &amp;ident);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><del>-    } else 
-        generator.emitPutToScope(scope.get(), ident, value.get(), ThrowIfNotFound);
</del><ins>+    }
</ins><span class="cx">     return generator.moveToDestinationIfNeeded(dst, value.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1027,7 +1034,7 @@
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><span class="cx">     generator.emitPutByVal(base.get(), property.get(), value);
</span><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        generator.emitProfileTypesWithHighFidelity(value, ProfileTypesBytecodeDoesNotHaveGlobalID);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(value, ProfileTypesBytecodeDoesNotHaveGlobalID, nullptr);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx">     return generator.moveToDestinationIfNeeded(dst, propDst.get());
</span><span class="lines">@@ -1049,7 +1056,7 @@
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><span class="cx">     generator.emitPutById(base.get(), ident, value);
</span><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        generator.emitProfileTypesWithHighFidelity(value, ProfileTypesBytecodeDoesNotHaveGlobalID);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(value, ProfileTypesBytecodeDoesNotHaveGlobalID, nullptr);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx">     return generator.moveToDestinationIfNeeded(dst, propDst.get());
</span><span class="lines">@@ -1520,13 +1527,12 @@
</span><span class="cx">     RefPtr&lt;RegisterID&gt; scope = generator.emitResolveScope(generator.newTemporary(), m_ident);
</span><span class="cx">     RefPtr&lt;RegisterID&gt; value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, ThrowIfNotFound);
</span><span class="cx">     RefPtr&lt;RegisterID&gt; result = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right-&gt;resultDescriptor()), this);
</span><del>-    RegisterID* ret; 
</del><ins>+    RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), ThrowIfNotFound);
</ins><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        ret = generator.emitPutToScopeWithProfile(scope.get(), m_ident, result.get(), ThrowIfNotFound);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(result.get(), ProfileTypesBytecodePutToScope, &amp;m_ident);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><del>-    } else
-        ret = generator.emitPutToScope(scope.get(), m_ident, result.get(), ThrowIfNotFound);
-    return ret;
</del><ins>+    }
+    return returnResult;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ AssignResolveNode -----------------------------------
</span><span class="lines">@@ -1559,13 +1565,12 @@
</span><span class="cx">         dst = 0;
</span><span class="cx">     RefPtr&lt;RegisterID&gt; result = generator.emitNode(dst, m_right);
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><del>-    RegisterID* ret;
</del><ins>+    RegisterID* returnResult = generator.emitPutToScope(scope.get(), m_ident, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
</ins><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        ret = generator.emitPutToScopeWithProfile(scope.get(), m_ident, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(result.get(), ProfileTypesBytecodePutToScope, &amp;m_ident);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><del>-    } else
-        ret = generator.emitPutToScope(scope.get(), m_ident, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
-    return ret;
</del><ins>+    } 
+    return returnResult;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ AssignDotNode -----------------------------------
</span><span class="lines">@@ -1579,7 +1584,7 @@
</span><span class="cx">     RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result : generator.moveToDestinationIfNeeded(generator.tempDestination(result), result);
</span><span class="cx">     generator.emitPutById(base.get(), m_ident, forwardResult);
</span><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        generator.emitProfileTypesWithHighFidelity(forwardResult, ProfileTypesBytecodeDoesNotHaveGlobalID);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(forwardResult, ProfileTypesBytecodeDoesNotHaveGlobalID, nullptr);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx">     return generator.moveToDestinationIfNeeded(dst, forwardResult);
</span><span class="lines">@@ -1598,7 +1603,7 @@
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><span class="cx">     RegisterID* ret = generator.emitPutById(base.get(), m_ident, updatedValue);
</span><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        generator.emitProfileTypesWithHighFidelity(updatedValue, ProfileTypesBytecodeDoesNotHaveGlobalID);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(updatedValue, ProfileTypesBytecodeDoesNotHaveGlobalID, nullptr);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx">     return ret;
</span><span class="lines">@@ -1624,7 +1629,7 @@
</span><span class="cx">     RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result : generator.moveToDestinationIfNeeded(generator.tempDestination(result), result);
</span><span class="cx">     generator.emitPutByVal(base.get(), property.get(), forwardResult);
</span><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        generator.emitProfileTypesWithHighFidelity(forwardResult, ProfileTypesBytecodeDoesNotHaveGlobalID);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(forwardResult, ProfileTypesBytecodeDoesNotHaveGlobalID, nullptr);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx">     return generator.moveToDestinationIfNeeded(dst, forwardResult);
</span><span class="lines">@@ -1644,7 +1649,7 @@
</span><span class="cx">     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</span><span class="cx">     generator.emitPutByVal(base.get(), property.get(), updatedValue);
</span><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        generator.emitProfileTypesWithHighFidelity(updatedValue, ProfileTypesBytecodeDoesNotHaveGlobalID);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(updatedValue, ProfileTypesBytecodeDoesNotHaveGlobalID, nullptr);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -2251,7 +2256,7 @@
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;RegisterID&gt; returnRegister = m_value ? generator.emitNode(dst, m_value) : generator.emitLoad(dst, jsUndefined());
</span><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        generator.emitProfileTypesWithHighFidelity(returnRegister.get(), ProfileTypesBytecodeFunctionReturnStatement);
</del><ins>+        generator.emitProfileTypesWithHighFidelity(returnRegister.get(), ProfileTypesBytecodeFunctionReturnStatement, nullptr);
</ins><span class="cx">         generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd());
</span><span class="cx">     }
</span><span class="cx">     if (generator.scopeDepth()) {
</span><span class="lines">@@ -2582,17 +2587,13 @@
</span><span class="cx"> void FunctionBodyNode::emitBytecode(BytecodeGenerator&amp; generator, RegisterID*)
</span><span class="cx"> {
</span><span class="cx">     if (generator.isProfilingTypesWithHighFidelity()) {
</span><del>-        JSTextPosition start(-1, m_startStartOffset, -1); // This divot is at the open brace of the function.
-        JSTextPosition end(-1, m_startStartOffset + 1, -1);
-        generator.emitProfileTypesWithHighFidelity(generator.thisRegister(), ProfileTypesBytecodeFunctionThisObject);
-        generator.emitHighFidelityTypeProfilingExpressionInfo(start, end);
</del><span class="cx">         for (size_t i = 0; i &lt; m_parameters-&gt;size(); i++) {
</span><span class="cx">             // FIXME: Handle Destructuring assignments into arguments.
</span><span class="cx">             if (!m_parameters-&gt;at(i)-&gt;isBindingNode())
</span><span class="cx">                 continue;
</span><span class="cx">             BindingNode* parameter = static_cast&lt;BindingNode*&gt;(m_parameters-&gt;at(i));
</span><span class="cx">             RegisterID reg(CallFrame::argumentOffset(i));
</span><del>-            generator.emitProfileTypesWithHighFidelity(&amp;reg, ProfileTypesBytecodeFunctionArgument);
</del><ins>+            generator.emitProfileTypesWithHighFidelity(&amp;reg, ProfileTypesBytecodeFunctionArgument, nullptr);
</ins><span class="cx">             generator.emitHighFidelityTypeProfilingExpressionInfo(parameter-&gt;divotStart(), parameter-&gt;divotEnd());
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -2614,7 +2615,7 @@
</span><span class="cx">     if (!returnNode) {
</span><span class="cx">         RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined());
</span><span class="cx">         if (generator.isProfilingTypesWithHighFidelity())
</span><del>-            generator.emitProfileTypesWithHighFidelity(r0, ProfileTypesBytecodeFunctionReturnStatement); // Do not emit expression info for this profile because it's not in the user's source code.
</del><ins>+            generator.emitProfileTypesWithHighFidelity(r0, ProfileTypesBytecodeFunctionReturnStatement, nullptr); // Do not emit expression info for this profile because it's not in the user's source code.
</ins><span class="cx">         ASSERT(startOffset() &gt;= lineStartOffset());
</span><span class="cx">         generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
</span><span class="cx">         generator.emitReturn(r0);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorRuntimeAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx"> #if ENABLE(INSPECTOR)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;Completion.h&quot;
</span><ins>+#include &quot;HeapIterationScope.h&quot;
</ins><span class="cx"> #include &quot;HighFidelityLog.h&quot;
</span><span class="cx"> #include &quot;HighFidelityTypeProfiler.h&quot;
</span><span class="cx"> #include &quot;InjectedScript.h&quot;
</span><span class="lines">@@ -44,6 +45,7 @@
</span><span class="cx"> #include &quot;ParserError.h&quot;
</span><span class="cx"> #include &quot;ScriptDebugServer.h&quot;
</span><span class="cx"> #include &quot;SourceCode.h&quot;
</span><ins>+#include &quot;VMEntryScope.h&quot;
</ins><span class="cx"> #include &lt;wtf/PassRefPtr.h&gt;
</span><span class="cx"> #include &lt;wtf/CurrentTime.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -61,6 +63,7 @@
</span><span class="cx">     , m_injectedScriptManager(injectedScriptManager)
</span><span class="cx">     , m_scriptDebugServer(nullptr)
</span><span class="cx">     , m_enabled(false)
</span><ins>+    , m_isTypeProfilingEnabled(false)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -199,8 +202,10 @@
</span><span class="cx">     static const bool verbose = false;
</span><span class="cx">     VM&amp; vm = globalVM();
</span><span class="cx">     typeDescriptions = Inspector::TypeBuilder::Array&lt;Inspector::TypeBuilder::Runtime::TypeDescription&gt;::create();
</span><del>-    if (!vm.isProfilingTypesWithHighFidelity())
</del><ins>+    if (!vm.isProfilingTypesWithHighFidelity()) {
+        *errorString = ASCIILiteral(&quot;The VM does not currently have Type Information.&quot;);
</ins><span class="cx">         return;
</span><ins>+    }
</ins><span class="cx"> 
</span><span class="cx">     double start = currentTimeMS();
</span><span class="cx">     vm.highFidelityLog()-&gt;processHighFidelityLog(&quot;User Query&quot;);
</span><span class="lines">@@ -231,6 +236,68 @@
</span><span class="cx">         dataLogF(&quot;Inspector::getRuntimeTypesForVariablesAtOffsets took %lfms\n&quot;, end - start);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+class TypeRecompiler : public MarkedBlock::VoidFunctor {
+public:
+    inline void operator()(JSCell* cell)
+    {
+        if (!cell-&gt;inherits(FunctionExecutable::info()))
+            return;
+
+        FunctionExecutable* executable = jsCast&lt;FunctionExecutable*&gt;(cell);
+        executable-&gt;clearCodeIfNotCompiling();
+        executable-&gt;clearUnlinkedCodeForRecompilationIfNotCompiling();
+    }
+};
+
+static void recompileAllJSFunctionsForTypeProfiling(VM&amp; vm, bool shouldEnableTypeProfiling)
+{
+    vm.waitForCompilationsToComplete();
+
+    bool needsToRecompile = (shouldEnableTypeProfiling ? vm.enableHighFidelityTypeProfiling() : vm.disableHighFidelityTypeProfiling());
+    if (needsToRecompile) {
+        TypeRecompiler recompiler;
+        HeapIterationScope iterationScope(vm.heap);
+        vm.heap.objectSpace().forEachLiveCell(iterationScope, recompiler);
+    }
+}
+
+void InspectorRuntimeAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason reason)
+{
+    if (reason != InspectorDisconnectReason::InspectedTargetDestroyed &amp;&amp; m_isTypeProfilingEnabled)
+        setHighFidelityTypeProfilingEnabledState(false);
+}
+
+void InspectorRuntimeAgent::enableHighFidelityTypeProfiling(ErrorString*)
+{
+    setHighFidelityTypeProfilingEnabledState(true);
+}
+
+void InspectorRuntimeAgent::disableHighFidelityTypeProfiling(ErrorString*)
+{
+    setHighFidelityTypeProfilingEnabledState(false);
+}
+
+void InspectorRuntimeAgent::setHighFidelityTypeProfilingEnabledState(bool shouldEnableTypeProfiling)
+{
+    if (m_isTypeProfilingEnabled == shouldEnableTypeProfiling)
+        return;
+
+    m_isTypeProfilingEnabled = shouldEnableTypeProfiling;
+
+    VM&amp; vm = globalVM();
+
+    // If JavaScript is running, it's not safe to recompile, since we'll end
+    // up throwing away code that is live on the stack.
+    if (vm.entryScope) {
+        vm.entryScope-&gt;setEntryScopeDidPopListener(this,
+            [=] (VM&amp; vm, JSGlobalObject*) {
+                recompileAllJSFunctionsForTypeProfiling(vm, shouldEnableTypeProfiling); 
+            }
+        );
+    } else
+        recompileAllJSFunctionsForTypeProfiling(vm, shouldEnableTypeProfiling);
+}
+
</ins><span class="cx"> } // namespace Inspector
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(INSPECTOR)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorRuntimeAgenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -57,6 +57,8 @@
</span><span class="cx"> public:
</span><span class="cx">     virtual ~InspectorRuntimeAgent();
</span><span class="cx"> 
</span><ins>+    virtual void willDestroyFrontendAndBackend(InspectorDisconnectReason) override;
+
</ins><span class="cx">     virtual void enable(ErrorString*) override { m_enabled = true; }
</span><span class="cx">     virtual void disable(ErrorString*) override { m_enabled = false; }
</span><span class="cx">     virtual void parse(ErrorString*, const String&amp; expression, Inspector::TypeBuilder::Runtime::SyntaxErrorType::Enum* result, Inspector::TypeBuilder::OptOutput&lt;String&gt;* message, RefPtr&lt;Inspector::TypeBuilder::Runtime::ErrorRange&gt;&amp;) override final;
</span><span class="lines">@@ -67,6 +69,8 @@
</span><span class="cx">     virtual void releaseObjectGroup(ErrorString*, const String&amp; objectGroup) override final;
</span><span class="cx">     virtual void run(ErrorString*) override;
</span><span class="cx">     virtual void getRuntimeTypesForVariablesAtOffsets(ErrorString*, const RefPtr&lt;Inspector::InspectorArray&gt;&amp; locations, RefPtr&lt;Inspector::TypeBuilder::Array&lt;Inspector::TypeBuilder::Runtime::TypeDescription&gt;&gt;&amp;) override;
</span><ins>+    virtual void enableHighFidelityTypeProfiling(ErrorString*) override;
+    virtual void disableHighFidelityTypeProfiling(ErrorString*) override;
</ins><span class="cx">     
</span><span class="cx">     void setScriptDebugServer(ScriptDebugServer* scriptDebugServer) { m_scriptDebugServer = scriptDebugServer; }
</span><span class="cx"> 
</span><span class="lines">@@ -84,9 +88,12 @@
</span><span class="cx">     virtual void unmuteConsole() = 0;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    void setHighFidelityTypeProfilingEnabledState(bool);
+
</ins><span class="cx">     InjectedScriptManager* m_injectedScriptManager;
</span><span class="cx">     ScriptDebugServer* m_scriptDebugServer;
</span><span class="cx">     bool m_enabled;
</span><ins>+    bool m_isTypeProfilingEnabled;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace Inspector
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsJSGlobalObjectRuntimeAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/JSGlobalObjectRuntimeAgent.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/JSGlobalObjectRuntimeAgent.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/inspector/agents/JSGlobalObjectRuntimeAgent.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -48,10 +48,12 @@
</span><span class="cx">     m_backendDispatcher = InspectorRuntimeBackendDispatcher::create(backendDispatcher, this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JSGlobalObjectRuntimeAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason)
</del><ins>+void JSGlobalObjectRuntimeAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason reason)
</ins><span class="cx"> {
</span><span class="cx">     m_frontendDispatcher = nullptr;
</span><span class="cx">     m_backendDispatcher.clear();
</span><ins>+
+    InspectorRuntimeAgent::willDestroyFrontendAndBackend(reason);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> VM&amp; JSGlobalObjectRuntimeAgent::globalVM()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorprotocolRuntimejson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/protocol/Runtime.json (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/protocol/Runtime.json        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/inspector/protocol/Runtime.json        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -239,6 +239,14 @@
</span><span class="cx">                 { &quot;name&quot;: &quot;types&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;$ref&quot;: &quot;TypeDescription&quot;, &quot;description&quot;: &quot;Types for requested variable.&quot; } }
</span><span class="cx">             ],
</span><span class="cx">             &quot;description&quot;: &quot;Returns detailed informtation on given function.&quot;
</span><ins>+        },
+        {
+            &quot;name&quot;: &quot;enableHighFidelityTypeProfiling&quot;,
+            &quot;description&quot;: &quot;Enables high fidelity type profiling on the VM.&quot;
+        },
+        {
+            &quot;name&quot;: &quot;disableHighFidelityTypeProfiling&quot;,
+            &quot;description&quot;: &quot;Disables high fidelity type profiling on the VM.&quot;
</ins><span class="cx">         }
</span><span class="cx">     ],
</span><span class="cx">     &quot;events&quot;: [
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/jit/JIT.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx"> #include &quot;ArityCheckFailReturnThunks.h&quot;
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><span class="cx"> #include &quot;DFGCapabilities.h&quot;
</span><ins>+#include &quot;HighFidelityLog.h&quot;
</ins><span class="cx"> #include &quot;Interpreter.h&quot;
</span><span class="cx"> #include &quot;JITInlines.h&quot;
</span><span class="cx"> #include &quot;JITOperations.h&quot;
</span><span class="lines">@@ -267,6 +268,7 @@
</span><span class="cx">         DEFINE_OP(op_inc)
</span><span class="cx">         DEFINE_OP(op_profile_did_call)
</span><span class="cx">         DEFINE_OP(op_profile_will_call)
</span><ins>+        DEFINE_OP(op_profile_types_with_high_fidelity)
</ins><span class="cx">         DEFINE_OP(op_push_name_scope)
</span><span class="cx">         DEFINE_OP(op_push_with_scope)
</span><span class="cx">         case op_put_by_id_out_of_line:
</span><span class="lines">@@ -498,6 +500,10 @@
</span><span class="cx">         m_codeBlock-&gt;m_shouldAlwaysBeInlined &amp;= canInline(level) &amp;&amp; DFG::mightInlineFunction(m_codeBlock);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><ins>+
+    // This ensures that we have the most up to date type information when performing typecheck optimizations for op_profile_types_with_high_fidelity.
+    if (m_vm-&gt;isProfilingTypesWithHighFidelity())
+        m_vm-&gt;highFidelityLog()-&gt;processHighFidelityLog(ASCIILiteral(&quot;Preparing for JIT compilation.&quot;));
</ins><span class="cx">     
</span><span class="cx">     if (Options::showDisassembly() || m_vm-&gt;m_perBytecodeProfiler)
</span><span class="cx">         m_disassembler = adoptPtr(new JITDisassembler(m_codeBlock));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.h (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.h        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/jit/JIT.h        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -527,6 +527,7 @@
</span><span class="cx">         void emit_op_inc(Instruction*);
</span><span class="cx">         void emit_op_profile_did_call(Instruction*);
</span><span class="cx">         void emit_op_profile_will_call(Instruction*);
</span><ins>+        void emit_op_profile_types_with_high_fidelity(Instruction*);
</ins><span class="cx">         void emit_op_push_name_scope(Instruction*);
</span><span class="cx">         void emit_op_push_with_scope(Instruction*);
</span><span class="cx">         void emit_op_put_by_id(Instruction*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;CopiedSpaceInlines.h&quot;
</span><span class="cx"> #include &quot;Debugger.h&quot;
</span><span class="cx"> #include &quot;Heap.h&quot;
</span><ins>+#include &quot;HighFidelityLog.h&quot;
</ins><span class="cx"> #include &quot;JITInlines.h&quot;
</span><span class="cx"> #include &quot;JSArray.h&quot;
</span><span class="cx"> #include &quot;JSCell.h&quot;
</span><span class="lines">@@ -41,6 +42,7 @@
</span><span class="cx"> #include &quot;MaxFrameExtentForSlowPathCall.h&quot;
</span><span class="cx"> #include &quot;RepatchBuffer.h&quot;
</span><span class="cx"> #include &quot;SlowPathCall.h&quot;
</span><ins>+#include &quot;TypeLocation.h&quot;
</ins><span class="cx"> #include &quot;VirtualRegister.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -1336,6 +1338,69 @@
</span><span class="cx">     JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_to_index_string);
</span><span class="cx">     slowPathCall.call();
</span><span class="cx"> }
</span><ins>+
+void JIT::emit_op_profile_types_with_high_fidelity(Instruction* currentInstruction)
+{
+    TypeLocation* cachedTypeLocation = currentInstruction[2].u.location;
+    int valueToProfile = currentInstruction[1].u.operand;
+
+    emitGetVirtualRegister(valueToProfile, regT0);
+
+    JumpList jumpToEnd;
+
+    // Compile in a predictive type check, if possible, to see if we can skip writing to the log.
+    // These typechecks are inlined to match those of the 64-bit JSValue type checks.
+    if (cachedTypeLocation-&gt;m_lastSeenType == TypeUndefined)
+        jumpToEnd.append(branch64(Equal, regT0, TrustedImm64(JSValue::encode(jsUndefined()))));
+    else if (cachedTypeLocation-&gt;m_lastSeenType == TypeNull)
+        jumpToEnd.append(branch64(Equal, regT0, TrustedImm64(JSValue::encode(jsNull()))));
+    else if (cachedTypeLocation-&gt;m_lastSeenType == TypeBoolean) {
+        move(regT0, regT1);
+        and64(TrustedImm32(~1), regT1);
+        jumpToEnd.append(branch64(Equal, regT1, TrustedImm64(ValueFalse)));
+    } else if (cachedTypeLocation-&gt;m_lastSeenType == TypeMachineInt)
+        jumpToEnd.append(emitJumpIfImmediateInteger(regT0));
+    else if (cachedTypeLocation-&gt;m_lastSeenType == TypeNumber)
+        jumpToEnd.append(emitJumpIfImmediateNumber(regT0));
+    else if (cachedTypeLocation-&gt;m_lastSeenType == TypeString) {
+        Jump isNotCell = emitJumpIfNotJSCell(regT0);
+        jumpToEnd.append(branch8(Equal, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32(StringType)));
+        isNotCell.link(this);
+    }
+
+    // Load the type profiling log into T2.
+    HighFidelityLog* cachedHighFidelityLog = m_vm-&gt;highFidelityLog();
+    move(TrustedImmPtr(cachedHighFidelityLog), regT2);
+    // Load the next log entry into T1.
+    loadPtr(Address(regT2, HighFidelityLog::currentLogEntryOffset()), regT1);
+
+    // Store the JSValue onto the log entry.
+    store64(regT0, Address(regT1, HighFidelityLog::LogEntry::valueOffset()));
+
+    // Store the structureID of the cell if T0 is a cell, otherwise, store 0 on the log entry.
+    Jump notCell = emitJumpIfNotJSCell(regT0);
+    load32(Address(regT0, JSCell::structureIDOffset()), regT0);
+    store32(regT0, Address(regT1, HighFidelityLog::LogEntry::structureIDOffset()));
+    Jump skipIsCell = jump();
+    notCell.link(this);
+    store32(TrustedImm32(0), Address(regT1, HighFidelityLog::LogEntry::structureIDOffset()));
+    skipIsCell.link(this);
+
+    // Store the typeLocation on the log entry.
+    move(TrustedImmPtr(cachedTypeLocation), regT0);
+    store64(regT0, Address(regT1, HighFidelityLog::LogEntry::locationOffset()));
+
+    // Increment the current log entry.
+    addPtr(TrustedImm32(sizeof(HighFidelityLog::LogEntry)), regT1);
+    store64(regT1, Address(regT2, HighFidelityLog::currentLogEntryOffset()));
+    Jump skipClearLog = branchPtr(NotEqual, regT1, TrustedImmPtr(cachedHighFidelityLog-&gt;logEndPtr()));
+    // Clear the log if we're at the end of the log.
+    callOperation(operationProcessTypeProfilerLog);
+    skipClearLog.link(this);
+
+    jumpToEnd.link(this);
+}
+
</ins><span class="cx"> #endif // USE(JSVALUE64)
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodes32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -1306,6 +1306,12 @@
</span><span class="cx">     slowPathCall.call();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JIT::emit_op_profile_types_with_high_fidelity(Instruction* currentInstruction)
+{
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_profile_types_with_high_fidelity);
+    slowPathCall.call();
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // USE(JSVALUE32_64)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx"> #include &quot;ErrorHandlingScope.h&quot;
</span><span class="cx"> #include &quot;ExceptionFuzz.h&quot;
</span><span class="cx"> #include &quot;GetterSetter.h&quot;
</span><ins>+#include &quot;HighFidelityLog.h&quot;
</ins><span class="cx"> #include &quot;HostCallReturnValue.h&quot;
</span><span class="cx"> #include &quot;JIT.h&quot;
</span><span class="cx"> #include &quot;JITToDFGDeferredCompilationCallback.h&quot;
</span><span class="lines">@@ -1921,6 +1922,11 @@
</span><span class="cx">     return jsString(exec, Identifier::from(exec, index).string());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JIT_OPERATION operationProcessTypeProfilerLog(ExecState* exec)
+{
+    exec-&gt;vm().highFidelityLog()-&gt;processHighFidelityLog(ASCIILiteral(&quot;Log Full, called from inside baseline JIT&quot;));
+}
+
</ins><span class="cx"> } // extern &quot;C&quot;
</span><span class="cx"> 
</span><span class="cx"> // Note: getHostCallReturnValueWithExecState() needs to be placed before the
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.h (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.h        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.h        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -324,6 +324,8 @@
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationNextEnumeratorPname(ExecState*, JSCell*, int32_t);
</span><span class="cx"> JSCell* JIT_OPERATION operationToIndexString(ExecState*, int32_t);
</span><span class="cx"> 
</span><ins>+void JIT_OPERATION operationProcessTypeProfilerLog(ExecState*) WTF_INTERNAL;
+
</ins><span class="cx"> } // extern &quot;C&quot;
</span><span class="cx"> 
</span><span class="cx"> inline P_JITOperation_ECli operationLinkFor(
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -540,15 +540,6 @@
</span><span class="cx">     LLINT_RETURN(RegExpObject::create(vm, exec-&gt;lexicalGlobalObject()-&gt;regExpStructure(), regExp));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-LLINT_SLOW_PATH_DECL(slow_path_profile_types_with_high_fidelity)
-{
-    LLINT_BEGIN();
-    TypeLocation* location = pc[2].u.location;
-    JSValue val = LLINT_OP_C(1).jsValue();
-    vm.highFidelityLog()-&gt;recordTypeInformationForLocation(val, location);
-    LLINT_END_IMPL();
-}
-
</del><span class="cx"> LLINT_SLOW_PATH_DECL(slow_path_check_has_instance)
</span><span class="cx"> {
</span><span class="cx">     LLINT_BEGIN();
</span><span class="lines">@@ -1375,8 +1366,10 @@
</span><span class="cx">     LLINT_RETURN(JSScope::resolve(exec, exec-&gt;scope(), ident));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static JSValue getFromScopeCommon(ExecState* exec, Instruction* pc, VM&amp; vm)
</del><ins>+LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
</ins><span class="cx"> {
</span><ins>+    LLINT_BEGIN();
+
</ins><span class="cx">     const Identifier&amp; ident = exec-&gt;codeBlock()-&gt;identifier(pc[3].u.operand);
</span><span class="cx">     JSObject* scope = jsCast&lt;JSObject*&gt;(LLINT_OP(2).jsValue());
</span><span class="cx">     ResolveModeAndType modeAndType(pc[4].u.operand);
</span><span class="lines">@@ -1384,8 +1377,8 @@
</span><span class="cx">     PropertySlot slot(scope);
</span><span class="cx">     if (!scope-&gt;getPropertySlot(exec, ident, slot)) {
</span><span class="cx">         if (modeAndType.mode() == ThrowIfNotFound)
</span><del>-            return exec-&gt;vm().throwException(exec, createUndefinedVariableError(exec, ident));
-        return jsUndefined();
</del><ins>+            LLINT_RETURN(exec-&gt;vm().throwException(exec, createUndefinedVariableError(exec, ident)));
+        LLINT_RETURN(jsUndefined());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
</span><span class="lines">@@ -1402,27 +1395,13 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return slot.getValue(exec, ident);
</del><ins>+    LLINT_RETURN(slot.getValue(exec, ident));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
</del><ins>+LLINT_SLOW_PATH_DECL(slow_path_put_to_scope)
</ins><span class="cx"> {
</span><span class="cx">     LLINT_BEGIN();
</span><del>-    JSValue value = getFromScopeCommon(exec, pc, vm);
-    LLINT_RETURN(value);
-}
</del><span class="cx"> 
</span><del>-LLINT_SLOW_PATH_DECL(slow_path_get_from_scope_with_profile)
-{
-    LLINT_BEGIN();
-    JSValue value = getFromScopeCommon(exec, pc, vm);
-    TypeLocation* location = pc[8].u.location;
-    vm.highFidelityLog()-&gt;recordTypeInformationForLocation(value, location);
-    LLINT_RETURN(value);
-}
-
-static JSObject* putToScopeCommon(ExecState* exec, Instruction* pc)
-{
</del><span class="cx">     CodeBlock* codeBlock = exec-&gt;codeBlock();
</span><span class="cx">     const Identifier&amp; ident = codeBlock-&gt;identifier(pc[2].u.operand);
</span><span class="cx">     JSObject* scope = jsCast&lt;JSObject*&gt;(LLINT_OP(1).jsValue());
</span><span class="lines">@@ -1430,38 +1409,16 @@
</span><span class="cx">     ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
</span><span class="cx"> 
</span><span class="cx">     if (modeAndType.mode() == ThrowIfNotFound &amp;&amp; !scope-&gt;hasProperty(exec, ident))
</span><del>-        return createUndefinedVariableError(exec, ident);
</del><ins>+        LLINT_THROW(createUndefinedVariableError(exec, ident));
</ins><span class="cx"> 
</span><span class="cx">     PutPropertySlot slot(scope, codeBlock-&gt;isStrictMode());
</span><span class="cx">     scope-&gt;methodTable()-&gt;put(scope, exec, ident, value, slot);
</span><span class="cx">     
</span><span class="cx">     CommonSlowPaths::tryCachePutToScopeGlobal(exec, codeBlock, pc, scope, modeAndType, slot);
</span><span class="cx"> 
</span><del>-    return nullptr;
-}
-
-LLINT_SLOW_PATH_DECL(slow_path_put_to_scope)
-{
-    LLINT_BEGIN();
-    JSObject* error = putToScopeCommon(exec, pc);
-    if (error)
-        LLINT_THROW(error);
</del><span class="cx">     LLINT_END();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-LLINT_SLOW_PATH_DECL(slow_path_put_to_scope_with_profile)
-{
-    // The format of this instruction is the same as put_to_scope with a TypeLocation appended: put_to_scope_with_profile scope, id, value, ResolveModeAndType, Structure, Operand, TypeLocation*
-    LLINT_BEGIN();
-    JSObject* error = putToScopeCommon(exec, pc);
-    if (error)
-        LLINT_THROW(error);
-    TypeLocation* location = pc[7].u.location;
-    JSValue val = LLINT_OP_C(3).jsValue();
-    vm.highFidelityLog()-&gt;recordTypeInformationForLocation(val, location);
-    LLINT_END();
-}
-
</del><span class="cx"> extern &quot;C&quot; SlowPathReturnType llint_throw_stack_overflow_error(VM* vm, ProtoCallFrame* protoFrame)
</span><span class="cx"> {
</span><span class="cx">     ExecState* exec = vm-&gt;topCallFrame;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -118,10 +118,7 @@
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_handle_exception);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_resolve_scope);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_from_scope);
</span><del>-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_from_scope_with_profile);
</del><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_to_scope);
</span><del>-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_to_scope_with_profile);
-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_profile_types_with_high_fidelity);
</del><span class="cx"> extern &quot;C&quot; SlowPathReturnType llint_throw_stack_overflow_error(VM*, ProtoCallFrame*) WTF_INTERNAL;
</span><span class="cx"> #if !ENABLE(JIT)
</span><span class="cx"> extern &quot;C&quot; SlowPathReturnType llint_stack_check_at_vm_entry(VM*, Register*) WTF_INTERNAL;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -1381,15 +1381,5 @@
</span><span class="cx">     dispatch(5)
</span><span class="cx"> 
</span><span class="cx"> _llint_op_profile_types_with_high_fidelity:
</span><del>-    callSlowPath(_llint_slow_path_profile_types_with_high_fidelity)
-    dispatch(4)
-
-_llint_op_put_to_scope_with_profile:
-    traceExecution()
-    callSlowPath(_llint_slow_path_put_to_scope_with_profile)
-    dispatch(8)
-
-_llint_op_get_from_scope_with_profile:
-    traceExecution()
-    callSlowPath(_llint_slow_path_get_from_scope_with_profile)
-    dispatch(9)
</del><ins>+    callSlowPath(_slow_path_profile_types_with_high_fidelity)
+    dispatch(6)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCodeCachecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CodeCache.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CodeCache.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/runtime/CodeCache.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -79,7 +79,7 @@
</span><span class="cx"> {
</span><span class="cx">     SourceCodeKey key = SourceCodeKey(source, String(), CacheTypes&lt;UnlinkedCodeBlockType&gt;::codeType, strictness);
</span><span class="cx">     CodeCacheMap::AddResult addResult = m_sourceCode.add(key, SourceCodeValue());
</span><del>-    bool canCache = debuggerMode == DebuggerOff &amp;&amp; profilerMode == ProfilerOff;
</del><ins>+    bool canCache = debuggerMode == DebuggerOff &amp;&amp; profilerMode == ProfilerOff &amp;&amp; !vm.isProfilingTypesWithHighFidelity();
</ins><span class="cx">     if (!addResult.isNewEntry &amp;&amp; canCache) {
</span><span class="cx">         UnlinkedCodeBlockType* unlinkedCodeBlock = jsCast&lt;UnlinkedCodeBlockType*&gt;(addResult.iterator-&gt;value.cell.get());
</span><span class="cx">         unsigned firstLine = source.firstLine() + unlinkedCodeBlock-&gt;firstLine();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -34,6 +34,7 @@
</span><span class="cx"> #include &quot;ErrorHandlingScope.h&quot;
</span><span class="cx"> #include &quot;ExceptionFuzz.h&quot;
</span><span class="cx"> #include &quot;GetterSetter.h&quot;
</span><ins>+#include &quot;HighFidelityLog.h&quot;
</ins><span class="cx"> #include &quot;HostCallReturnValue.h&quot;
</span><span class="cx"> #include &quot;Interpreter.h&quot;
</span><span class="cx"> #include &quot;JIT.h&quot;
</span><span class="lines">@@ -636,4 +637,13 @@
</span><span class="cx">     RETURN(jsString(exec, Identifier::from(exec, OP(2).jsValue().asUInt32()).string()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+SLOW_PATH_DECL(slow_path_profile_types_with_high_fidelity)
+{
+    BEGIN();
+    TypeLocation* location = pc[2].u.location;
+    JSValue val = OP_C(1).jsValue();
+    vm.highFidelityLog()-&gt;recordTypeInformationForLocation(val, location);
+    END();
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -233,6 +233,7 @@
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_get_generic_property_enumerator);
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_next_enumerator_pname);
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_to_index_string);
</span><ins>+SLOW_PATH_HIDDEN_DECL(slow_path_profile_types_with_high_fidelity);
</ins><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeHighFidelityLogcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/HighFidelityLog.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/HighFidelityLog.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/runtime/HighFidelityLog.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -43,49 +43,47 @@
</span><span class="cx">     ASSERT(!m_logStartPtr);
</span><span class="cx">     m_highFidelityLogSize = 50000;
</span><span class="cx">     m_logStartPtr = new LogEntry[m_highFidelityLogSize];
</span><del>-    m_nextBuffer = new LogEntry[m_highFidelityLogSize];
-    m_currentOffset = 0;
</del><ins>+    m_currentLogEntryPtr = m_logStartPtr;
+    m_logEndPtr = m_logStartPtr + m_highFidelityLogSize;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> HighFidelityLog::~HighFidelityLog()
</span><span class="cx"> {
</span><span class="cx">     delete[] m_logStartPtr;
</span><del>-    delete[] m_nextBuffer;
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HighFidelityLog::processHighFidelityLog(String reason)
</span><span class="cx"> {
</span><del>-    if (!m_currentOffset)
-        return;
-
</del><span class="cx">     if (verbose)
</span><span class="cx">         dataLog(&quot;Process caller:'&quot;, reason,&quot;'&quot;);
</span><span class="cx"> 
</span><span class="cx">     double before = currentTimeMS();
</span><span class="cx">     LogEntry* entry = m_logStartPtr;
</span><span class="cx">     HashMap&lt;StructureID, RefPtr&lt;StructureShape&gt;&gt; seenShapes;
</span><del>-    size_t i = 0;
-    while (i &lt; m_currentOffset) {
</del><ins>+    while (entry != m_currentLogEntryPtr) {
</ins><span class="cx">         StructureID id = entry-&gt;structureID;
</span><span class="cx">         RefPtr&lt;StructureShape&gt; shape; 
</span><ins>+        JSValue value = entry-&gt;value;
</ins><span class="cx">         if (id) {
</span><span class="cx">             auto iter = seenShapes.find(id);
</span><span class="cx">             if (iter == seenShapes.end()) {
</span><del>-                shape = Heap::heap(entry-&gt;value.asCell())-&gt;structureIDTable().get(entry-&gt;structureID)-&gt;toStructureShape(entry-&gt;value);
</del><ins>+                shape = Heap::heap(value.asCell())-&gt;structureIDTable().get(entry-&gt;structureID)-&gt;toStructureShape(value);
</ins><span class="cx">                 seenShapes.set(id, shape);
</span><del>-            } else 
</del><ins>+            } else
</ins><span class="cx">                 shape = iter-&gt;value;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (entry-&gt;location-&gt;m_globalTypeSet)
-            entry-&gt;location-&gt;m_globalTypeSet-&gt;addTypeForValue(entry-&gt;value, shape, id);
-        entry-&gt;location-&gt;m_instructionTypeSet-&gt;addTypeForValue(entry-&gt;value, shape, id);
</del><ins>+        RuntimeType type = TypeSet::getRuntimeTypeForValue(value);
+        TypeLocation* location = entry-&gt;location;
+        location-&gt;m_lastSeenType = type;
+        if (location-&gt;m_globalTypeSet)
+            location-&gt;m_globalTypeSet-&gt;addTypeInformation(type, shape, id);
+        location-&gt;m_instructionTypeSet-&gt;addTypeInformation(type, shape, id);
</ins><span class="cx"> 
</span><span class="cx">         entry++;
</span><del>-        i++;
</del><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_currentOffset = 0;
</del><ins>+    m_currentLogEntryPtr = m_logStartPtr;
</ins><span class="cx"> 
</span><span class="cx">     if (verbose) {
</span><span class="cx">         double after = currentTimeMS();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeHighFidelityLogh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/HighFidelityLog.h (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/HighFidelityLog.h        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/runtime/HighFidelityLog.h        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -46,8 +46,13 @@
</span><span class="cx">         JSValue value;
</span><span class="cx">         TypeLocation* location; 
</span><span class="cx">         StructureID structureID;
</span><ins>+
+        static ptrdiff_t structureIDOffset() { return OBJECT_OFFSETOF(LogEntry, structureID); }
+        static ptrdiff_t valueOffset() { return OBJECT_OFFSETOF(LogEntry, value); }
+        static ptrdiff_t locationOffset() { return OBJECT_OFFSETOF(LogEntry, location); }
</ins><span class="cx">     };
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     HighFidelityLog()
</span><span class="cx">         : m_logStartPtr(0)
</span><span class="cx">     {
</span><span class="lines">@@ -59,37 +64,29 @@
</span><span class="cx">     ALWAYS_INLINE void recordTypeInformationForLocation(JSValue value, TypeLocation* location)
</span><span class="cx">     {
</span><span class="cx">         ASSERT(m_logStartPtr);
</span><del>-        ASSERT(m_currentOffset &lt; m_highFidelityLogSize);
</del><ins>+
+        m_currentLogEntryPtr-&gt;location = location;
+        m_currentLogEntryPtr-&gt;value = value;
+        m_currentLogEntryPtr-&gt;structureID = (value.isCell() ? value.asCell()-&gt;structureID() : 0);
</ins><span class="cx">     
</span><del>-        LogEntry* entry = m_logStartPtr + m_currentOffset;
-    
-        entry-&gt;location = location;
-        entry-&gt;value = value;
-        entry-&gt;structureID = (value.isCell() ? value.asCell()-&gt;structureID() : 0);
-    
-        m_currentOffset += 1;
-        if (m_currentOffset == m_highFidelityLogSize)
</del><ins>+        m_currentLogEntryPtr += 1;
+        if (UNLIKELY(m_currentLogEntryPtr == m_logEndPtr))
</ins><span class="cx">             processHighFidelityLog(&quot;Log Full&quot;);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void processHighFidelityLog(String);
</span><ins>+    LogEntry* logEndPtr() const { return m_logEndPtr; }
</ins><span class="cx"> 
</span><ins>+    static ptrdiff_t logStartOffset() { return OBJECT_OFFSETOF(HighFidelityLog, m_logStartPtr); }
+    static ptrdiff_t currentLogEntryOffset() { return OBJECT_OFFSETOF(HighFidelityLog, m_currentLogEntryPtr); }
+
</ins><span class="cx"> private:
</span><span class="cx">     void initializeHighFidelityLog();
</span><span class="cx"> 
</span><span class="cx">     unsigned m_highFidelityLogSize;
</span><del>-    size_t m_currentOffset;
</del><span class="cx">     LogEntry* m_logStartPtr;
</span><del>-    LogEntry* m_nextBuffer;
-
-    ByteSpinLock m_lock;
-
-    struct ThreadData {
-        public:
-        LogEntry* m_processLogPtr;
-        size_t m_proccessLogToOffset;
-        ByteSpinLocker* m_locker;
-    };
</del><ins>+    LogEntry* m_currentLogEntryPtr;
+    LogEntry* m_logEndPtr;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } //namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeHighFidelityTypeProfilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -35,9 +35,7 @@
</span><span class="cx"> 
</span><span class="cx"> void HighFidelityTypeProfiler::logTypesForTypeLocation(TypeLocation* location)
</span><span class="cx"> {
</span><del>-    TypeProfilerSearchDescriptor descriptor = location-&gt;m_globalVariableID == HighFidelityReturnStatement ? TypeProfilerSearchDescriptorFunctionReturn
-        : location-&gt;m_globalVariableID == HighFidelityThisStatement ? TypeProfilerSearchDescriptorThisStatement
-        : TypeProfilerSearchDescriptorNormal;
</del><ins>+    TypeProfilerSearchDescriptor descriptor = location-&gt;m_globalVariableID == HighFidelityReturnStatement ? TypeProfilerSearchDescriptorFunctionReturn : TypeProfilerSearchDescriptorNormal;
</ins><span class="cx"> 
</span><span class="cx">     dataLogF(&quot;[Start, End]::[%u, %u]\n&quot;, location-&gt;m_divotStart, location-&gt;m_divotEnd);
</span><span class="cx"> 
</span><span class="lines">@@ -46,9 +44,7 @@
</span><span class="cx">     else
</span><span class="cx">         dataLog(&quot;\t\t[Entry IS NOT in system]\n&quot;);
</span><span class="cx"> 
</span><del>-    dataLog(&quot;\t\t&quot;, location-&gt;m_globalVariableID == HighFidelityReturnStatement ? &quot;[Return Statement]&quot;
-        : location-&gt;m_globalVariableID == HighFidelityThisStatement ? &quot;[This Statement]&quot;
-        : &quot;[Normal Statement]&quot;, &quot;\n&quot;);
</del><ins>+    dataLog(&quot;\t\t&quot;, location-&gt;m_globalVariableID == HighFidelityReturnStatement ? &quot;[Return Statement]&quot; : &quot;[Normal Statement]&quot;, &quot;\n&quot;);
</ins><span class="cx"> 
</span><span class="cx">     dataLog(&quot;\t\t#Local#\n\t\t&quot;, location-&gt;m_instructionTypeSet-&gt;seenTypes().replace(&quot;\n&quot;, &quot;\n\t\t&quot;), &quot;\n&quot;);
</span><span class="cx">     if (location-&gt;m_globalTypeSet)
</span><span class="lines">@@ -91,12 +87,9 @@
</span><span class="cx">     if (descriptor == TypeProfilerSearchDescriptorFunctionReturn &amp;&amp; location-&gt;m_globalVariableID == HighFidelityReturnStatement)  
</span><span class="cx">         return true;
</span><span class="cx"> 
</span><del>-    if (descriptor == TypeProfilerSearchDescriptorThisStatement &amp;&amp; location-&gt;m_globalVariableID == HighFidelityThisStatement)  
</del><ins>+    if (descriptor == TypeProfilerSearchDescriptorNormal &amp;&amp; location-&gt;m_globalVariableID != HighFidelityReturnStatement)  
</ins><span class="cx">         return true;
</span><span class="cx"> 
</span><del>-    if (descriptor == TypeProfilerSearchDescriptorNormal &amp;&amp; location-&gt;m_globalVariableID != HighFidelityReturnStatement &amp;&amp; location-&gt;m_globalVariableID != HighFidelityThisStatement)  
-        return true;
-
</del><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeHighFidelityTypeProfilerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.h (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.h        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.h        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -89,8 +89,7 @@
</span><span class="cx"> 
</span><span class="cx"> enum TypeProfilerSearchDescriptor {
</span><span class="cx">     TypeProfilerSearchDescriptorNormal = 1,
</span><del>-    TypeProfilerSearchDescriptorThisStatement = 2,
-    TypeProfilerSearchDescriptorFunctionReturn = 3
</del><ins>+    TypeProfilerSearchDescriptorFunctionReturn = 2
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class HighFidelityTypeProfiler {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSymbolTablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/runtime/SymbolTable.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -103,11 +103,6 @@
</span><span class="cx">     , m_captureEnd(0)
</span><span class="cx">     , m_functionEnteredOnce(ClearWatchpoint)
</span><span class="cx"> {
</span><del>-    if (vm.isProfilingTypesWithHighFidelity()) {
-        m_uniqueIDMap = std::make_unique&lt;UniqueIDMap&gt;();
-        m_registerToVariableMap = std::make_unique&lt;RegisterToVariableMap&gt;();
-        m_uniqueTypeSetMap = std::make_unique&lt;UniqueTypeSetMap&gt;();
-    }
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> SymbolTable::~SymbolTable() { }
</span><span class="lines">@@ -164,70 +159,104 @@
</span><span class="cx">             result-&gt;m_slowArguments[i] = m_slowArguments[i];
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (m_uniqueIDMap &amp;&amp; result-&gt;m_uniqueIDMap) {
</del><ins>+    if (m_typeProfilingRareData) {
+        result-&gt;m_typeProfilingRareData = std::make_unique&lt;TypeProfilingRareData&gt;();
</ins><span class="cx"> 
</span><span class="cx">         {
</span><del>-            auto iter = m_uniqueIDMap-&gt;begin();
-            auto end = m_uniqueIDMap-&gt;end();
</del><ins>+            auto iter = m_typeProfilingRareData-&gt;m_uniqueIDMap.begin();
+            auto end = m_typeProfilingRareData-&gt;m_uniqueIDMap.end();
</ins><span class="cx">             for (; iter != end; ++iter)
</span><del>-                result-&gt;m_uniqueIDMap-&gt;set(iter-&gt;key, iter-&gt;value);
</del><ins>+                result-&gt;m_typeProfilingRareData-&gt;m_uniqueIDMap.set(iter-&gt;key, iter-&gt;value);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         {
</span><del>-            auto iter = m_registerToVariableMap-&gt;begin();
-            auto end = m_registerToVariableMap-&gt;end();
</del><ins>+            auto iter = m_typeProfilingRareData-&gt;m_registerToVariableMap.begin();
+            auto end = m_typeProfilingRareData-&gt;m_registerToVariableMap.end();
</ins><span class="cx">             for (; iter != end; ++iter)
</span><del>-                result-&gt;m_registerToVariableMap-&gt;set(iter-&gt;key, iter-&gt;value);
</del><ins>+                result-&gt;m_typeProfilingRareData-&gt;m_registerToVariableMap.set(iter-&gt;key, iter-&gt;value);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         {
</span><del>-            auto iter = m_uniqueTypeSetMap-&gt;begin();
-            auto end = m_uniqueTypeSetMap-&gt;end();
</del><ins>+            auto iter = m_typeProfilingRareData-&gt;m_uniqueTypeSetMap.begin();
+            auto end = m_typeProfilingRareData-&gt;m_uniqueTypeSetMap.end();
</ins><span class="cx">             for (; iter != end; ++iter)
</span><del>-                result-&gt;m_uniqueTypeSetMap-&gt;set(iter-&gt;key, iter-&gt;value);
</del><ins>+                result-&gt;m_typeProfilingRareData-&gt;m_uniqueTypeSetMap.set(iter-&gt;key, iter-&gt;value);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><del>-
</del><span class="cx">     
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SymbolTable::prepareForHighFidelityTypeProfiling(const ConcurrentJITLocker&amp;)
+{
+    if (m_typeProfilingRareData)
+        return;
+
+    m_typeProfilingRareData = std::make_unique&lt;TypeProfilingRareData&gt;();
+
+    for (auto iter = m_map.begin(), end = m_map.end(); iter != end; ++iter) {
+        m_typeProfilingRareData-&gt;m_uniqueIDMap.set(iter-&gt;key, HighFidelityNeedsUniqueIDGeneration);
+        m_typeProfilingRareData-&gt;m_registerToVariableMap.set(iter-&gt;value.getIndex(), iter-&gt;key);
+    }
+}
+
</ins><span class="cx"> GlobalVariableID SymbolTable::uniqueIDForVariable(const ConcurrentJITLocker&amp;, StringImpl* key, VM&amp; vm)
</span><span class="cx"> {
</span><del>-    auto iter = m_uniqueIDMap-&gt;find(key);
-    auto end = m_uniqueIDMap-&gt;end();
-    ASSERT_UNUSED(end, iter != end);
</del><ins>+    RELEASE_ASSERT(m_typeProfilingRareData);
</ins><span class="cx"> 
</span><del>-    GlobalVariableID&amp; id = iter-&gt;value;
</del><ins>+    auto iter = m_typeProfilingRareData-&gt;m_uniqueIDMap.find(key);
+    auto end = m_typeProfilingRareData-&gt;m_uniqueIDMap.end();
+    if (iter == end)
+        return HighFidelityNoGlobalIDExists;
+
+    GlobalVariableID id = iter-&gt;value;
</ins><span class="cx">     if (id == HighFidelityNeedsUniqueIDGeneration) {
</span><span class="cx">         id = vm.getNextUniqueVariableID();
</span><del>-        m_uniqueTypeSetMap-&gt;set(key, TypeSet::create()); //make a new global typeset for the ID
</del><ins>+        m_typeProfilingRareData-&gt;m_uniqueIDMap.set(key, id);
+        m_typeProfilingRareData-&gt;m_uniqueTypeSetMap.set(key, TypeSet::create()); // Make a new global typeset for this corresponding ID.
</ins><span class="cx">     }
</span><del>-         
</del><ins>+
</ins><span class="cx">     return id;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> GlobalVariableID SymbolTable::uniqueIDForRegister(const ConcurrentJITLocker&amp; locker, int registerIndex, VM&amp; vm)
</span><span class="cx"> {
</span><del>-    auto iter = m_registerToVariableMap-&gt;find(registerIndex);
-    auto end = m_registerToVariableMap-&gt;end();
-    ASSERT_UNUSED(end, iter != end);
</del><ins>+    RELEASE_ASSERT(m_typeProfilingRareData);
+
+    auto iter = m_typeProfilingRareData-&gt;m_registerToVariableMap.find(registerIndex);
+    auto end = m_typeProfilingRareData-&gt;m_registerToVariableMap.end();
+    if (iter == end)
+        return HighFidelityNoGlobalIDExists;
+
</ins><span class="cx">     return uniqueIDForVariable(locker, iter-&gt;value.get(), vm);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;TypeSet&gt; SymbolTable::globalTypeSetForRegister(const ConcurrentJITLocker&amp; locker, int registerIndex, VM&amp; vm)
</span><span class="cx"> {
</span><del>-    uniqueIDForRegister(locker, registerIndex, vm); //ensure it's created
-    auto iter = m_registerToVariableMap-&gt;find(registerIndex);
-    auto end = m_registerToVariableMap-&gt;end();
-    ASSERT_UNUSED(end, iter != end);
</del><ins>+    RELEASE_ASSERT(m_typeProfilingRareData);
+
+    uniqueIDForRegister(locker, registerIndex, vm); // Lazily create the TypeSet if necessary.
+
+    auto iter = m_typeProfilingRareData-&gt;m_registerToVariableMap.find(registerIndex);
+    auto end = m_typeProfilingRareData-&gt;m_registerToVariableMap.end();
+    if (iter == end)
+        return nullptr;
+
</ins><span class="cx">     return globalTypeSetForVariable(locker, iter-&gt;value.get(), vm);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;TypeSet&gt; SymbolTable::globalTypeSetForVariable(const ConcurrentJITLocker&amp; locker, StringImpl* key, VM&amp; vm)
</span><span class="cx"> {
</span><del>-    uniqueIDForVariable(locker, key, vm);
-    return m_uniqueTypeSetMap-&gt;find(key)-&gt;value;
</del><ins>+    RELEASE_ASSERT(m_typeProfilingRareData);
+
+    uniqueIDForVariable(locker, key, vm); // Lazily create the TypeSet if necessary.
+
+    auto iter = m_typeProfilingRareData-&gt;m_uniqueTypeSetMap.find(key);
+    auto end = m_typeProfilingRareData-&gt;m_uniqueTypeSetMap.end();
+    if (iter == end)
+        return nullptr;
+
+    return iter-&gt;value;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSymbolTableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SymbolTable.h (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SymbolTable.h        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/runtime/SymbolTable.h        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -417,12 +417,6 @@
</span><span class="cx">     
</span><span class="cx">     Map::AddResult add(const ConcurrentJITLocker&amp;, StringImpl* key, const SymbolTableEntry&amp; entry)
</span><span class="cx">     {
</span><del>-        if (m_uniqueIDMap) {
-            // Use a flag to indicate that we need to produce a unique ID. Because VM is in charge of creating uniqueIDs, 
-            // when uniqueID() is called, we check this flag to see if uniqueID creation is necessary.
-            m_uniqueIDMap-&gt;set(key, HighFidelityNeedsUniqueIDGeneration); 
-            m_registerToVariableMap-&gt;set(entry.getIndex(), key);
-        }
</del><span class="cx">         return m_map.add(key, entry);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -434,10 +428,6 @@
</span><span class="cx">     
</span><span class="cx">     Map::AddResult set(const ConcurrentJITLocker&amp;, StringImpl* key, const SymbolTableEntry&amp; entry)
</span><span class="cx">     {
</span><del>-        if (m_uniqueIDMap) {
-            m_uniqueIDMap-&gt;set(key, HighFidelityNeedsUniqueIDGeneration); 
-            m_registerToVariableMap-&gt;set(entry.getIndex(), key);
-        }
</del><span class="cx">         return m_map.set(key, entry);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -489,6 +479,8 @@
</span><span class="cx">     
</span><span class="cx">     SymbolTable* cloneCapturedNames(VM&amp;);
</span><span class="cx"> 
</span><ins>+    void prepareForHighFidelityTypeProfiling(const ConcurrentJITLocker&amp;);
+
</ins><span class="cx">     static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><span class="cx"> 
</span><span class="cx">     DECLARE_EXPORT_INFO;
</span><span class="lines">@@ -513,9 +505,12 @@
</span><span class="cx">     ~SymbolTable();
</span><span class="cx"> 
</span><span class="cx">     Map m_map;
</span><del>-    std::unique_ptr&lt;UniqueIDMap&gt; m_uniqueIDMap;
-    std::unique_ptr&lt;RegisterToVariableMap&gt; m_registerToVariableMap;
-    std::unique_ptr&lt;UniqueTypeSetMap&gt; m_uniqueTypeSetMap;
</del><ins>+    struct TypeProfilingRareData {
+        UniqueIDMap m_uniqueIDMap;
+        RegisterToVariableMap m_registerToVariableMap;
+        UniqueTypeSetMap m_uniqueTypeSetMap;
+    };
+    std::unique_ptr&lt;TypeProfilingRareData&gt; m_typeProfilingRareData;
</ins><span class="cx"> 
</span><span class="cx">     int m_parameterCountIncludingThis;
</span><span class="cx">     bool m_usesNonStrictEval;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeTypeLocationCachecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/TypeLocationCache.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/TypeLocationCache.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/runtime/TypeLocationCache.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -41,7 +41,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool isNewLocation = false;
</span><span class="cx">     if (m_locationMap.find(key) == m_locationMap.end()) {
</span><del>-        TypeLocation* location = vm-&gt;nextLocation();
</del><ins>+        TypeLocation* location = vm-&gt;nextTypeLocation();
</ins><span class="cx">         location-&gt;m_globalVariableID = globalVariableID;
</span><span class="cx">         location-&gt;m_sourceID = sourceID;
</span><span class="cx">         location-&gt;m_divotStart = start;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeTypeSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/TypeSet.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/TypeSet.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/runtime/TypeSet.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -62,17 +62,16 @@
</span><span class="cx">     else if (v.isObject())
</span><span class="cx">         ret = TypeObject;
</span><span class="cx">     else
</span><del>-        CRASH();
</del><ins>+        ret = TypeNothing;
</ins><span class="cx"> 
</span><span class="cx">     return ret;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void TypeSet::addTypeForValue(JSValue v, PassRefPtr&lt;StructureShape&gt; shape, StructureID id) 
</del><ins>+void TypeSet::addTypeInformation(RuntimeType type, PassRefPtr&lt;StructureShape&gt; shape, StructureID id) 
</ins><span class="cx"> {
</span><del>-    RuntimeType t = getRuntimeTypeForValue(v);
-    m_seenTypes = m_seenTypes | t;
</del><ins>+    m_seenTypes = m_seenTypes | type;
</ins><span class="cx"> 
</span><del>-    if (id &amp;&amp; shape &amp;&amp; !v.isString() &amp;&amp; !v.isFunction()) {
</del><ins>+    if (id &amp;&amp; shape &amp;&amp; type != TypeString) {
</ins><span class="cx">         ASSERT(m_structureIDHistory.isValidKey(id));
</span><span class="cx">         auto iter = m_structureIDHistory.find(id);
</span><span class="cx">         if (iter == m_structureIDHistory.end()) {
</span><span class="lines">@@ -218,8 +217,6 @@
</span><span class="cx"> PassRefPtr&lt;Inspector::TypeBuilder::Array&lt;String&gt;&gt; TypeSet::allPrimitiveTypeNames() const
</span><span class="cx"> {
</span><span class="cx">     RefPtr&lt;Inspector::TypeBuilder::Array&lt;String&gt;&gt; seen = Inspector::TypeBuilder::Array&lt;String&gt;::create();
</span><del>-    if (m_seenTypes &amp; TypeFunction)
-         seen-&gt;addItem(&quot;Function&quot;);
</del><span class="cx">     if (m_seenTypes &amp; TypeUndefined)
</span><span class="cx">          seen-&gt;addItem(&quot;Undefined&quot;);
</span><span class="cx">     if (m_seenTypes &amp; TypeNull)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeTypeSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/TypeSet.h (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/TypeSet.h        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/runtime/TypeSet.h        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -90,7 +90,7 @@
</span><span class="cx"> public:
</span><span class="cx">     static PassRefPtr&lt;TypeSet&gt; create() { return adoptRef(new TypeSet); }
</span><span class="cx">     TypeSet();
</span><del>-    void addTypeForValue(JSValue v, PassRefPtr&lt;StructureShape&gt;, StructureID);
</del><ins>+    void addTypeInformation(RuntimeType, PassRefPtr&lt;StructureShape&gt;, StructureID);
</ins><span class="cx">     static RuntimeType getRuntimeTypeForValue(JSValue);
</span><span class="cx">     JS_EXPORT_PRIVATE String seenTypes() const;
</span><span class="cx">     String displayName() const;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/runtime/VM.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -191,6 +191,7 @@
</span><span class="cx">     , m_enabledProfiler(nullptr)
</span><span class="cx">     , m_builtinExecutables(BuiltinExecutables::create(*this))
</span><span class="cx">     , m_nextUniqueVariableID(1)
</span><ins>+    , m_highFidelityTypeProfilingEnabledCount(0)
</ins><span class="cx"> {
</span><span class="cx">     interpreter = new Interpreter(*this);
</span><span class="cx">     StackBounds stack = wtfThreadData().stack();
</span><span class="lines">@@ -283,11 +284,8 @@
</span><span class="cx">     // won't use this.
</span><span class="cx">     m_typedArrayController = adoptRef(new SimpleTypedArrayController());
</span><span class="cx"> 
</span><del>-    // FIXME: conditionally allocate this stuff based on whether or not the inspector is running OR this flag is enabled (not just if the flag is enabled).
-    if (Options::profileTypesWithHighFidelity()) {
-        m_highFidelityTypeProfiler = std::make_unique&lt;HighFidelityTypeProfiler&gt;();
-        m_highFidelityLog = std::make_unique&lt;HighFidelityLog&gt;();
-    }
</del><ins>+    if (Options::profileTypesWithHighFidelity())
+        enableHighFidelityTypeProfiling();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> VM::~VM()
</span><span class="lines">@@ -858,6 +856,43 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+TypeLocation* VM::nextTypeLocation() 
+{ 
+    RELEASE_ASSERT(!!m_typeLocationInfo);
+
+    return m_typeLocationInfo-&gt;add(); 
+}
+
+bool VM::enableHighFidelityTypeProfiling()
+{
+    bool needsToRecompile = false;
+    if (!m_highFidelityTypeProfilingEnabledCount) {
+        m_highFidelityTypeProfiler = std::make_unique&lt;HighFidelityTypeProfiler&gt;();
+        m_highFidelityLog = std::make_unique&lt;HighFidelityLog&gt;();
+        m_typeLocationInfo = std::make_unique&lt;Bag&lt;TypeLocation&gt;&gt;();
+        needsToRecompile = true;
+    }
+    m_highFidelityTypeProfilingEnabledCount++;
+
+    return needsToRecompile;
+}
+
+bool VM::disableHighFidelityTypeProfiling()
+{
+    RELEASE_ASSERT(m_highFidelityTypeProfilingEnabledCount &gt; 0);
+
+    bool needsToRecompile = false;
+    m_highFidelityTypeProfilingEnabledCount--;
+    if (!m_highFidelityTypeProfilingEnabledCount) {
+        m_highFidelityTypeProfiler.reset(nullptr);
+        m_highFidelityLog.reset(nullptr);
+        m_typeLocationInfo.reset(nullptr);
+        needsToRecompile = true;
+    }
+
+    return needsToRecompile;
+}
+
</ins><span class="cx"> void VM::dumpHighFidelityProfilingTypes()
</span><span class="cx"> {
</span><span class="cx">     if (!isProfilingTypesWithHighFidelity())
</span><span class="lines">@@ -865,7 +900,7 @@
</span><span class="cx"> 
</span><span class="cx">     highFidelityLog()-&gt;processHighFidelityLog(&quot;VM Dump Types&quot;);
</span><span class="cx">     HighFidelityTypeProfiler* profiler = m_highFidelityTypeProfiler.get();
</span><del>-    for (Bag&lt;TypeLocation&gt;::iterator iter = m_locationInfo.begin(); !!iter; ++iter) {
</del><ins>+    for (Bag&lt;TypeLocation&gt;::iterator iter = m_typeLocationInfo-&gt;begin(); !!iter; ++iter) {
</ins><span class="cx">         TypeLocation* location = *iter;
</span><span class="cx">         profiler-&gt;logTypesForTypeLocation(location);
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -496,9 +496,11 @@
</span><span class="cx">         BuiltinExecutables* builtinExecutables() { return m_builtinExecutables.get(); }
</span><span class="cx"> 
</span><span class="cx">         bool isProfilingTypesWithHighFidelity() { return !!m_highFidelityTypeProfiler; }
</span><ins>+        bool enableHighFidelityTypeProfiling();
+        bool disableHighFidelityTypeProfiling();
</ins><span class="cx">         HighFidelityLog* highFidelityLog() { return m_highFidelityLog.get(); }
</span><span class="cx">         HighFidelityTypeProfiler* highFidelityTypeProfiler() { return m_highFidelityTypeProfiler.get(); }
</span><del>-        TypeLocation* nextLocation() { return m_locationInfo.add(); } //TODO: possible optmization: when codeblocks die, report which locations are no longer being changed so we don't walk over them
</del><ins>+        TypeLocation* nextTypeLocation();
</ins><span class="cx">         JS_EXPORT_PRIVATE void dumpHighFidelityProfilingTypes();
</span><span class="cx">         GlobalVariableID getNextUniqueVariableID() { return m_nextUniqueVariableID++; }
</span><span class="cx"> 
</span><span class="lines">@@ -553,7 +555,8 @@
</span><span class="cx">         std::unique_ptr&lt;HighFidelityTypeProfiler&gt; m_highFidelityTypeProfiler;
</span><span class="cx">         std::unique_ptr&lt;HighFidelityLog&gt; m_highFidelityLog;
</span><span class="cx">         GlobalVariableID m_nextUniqueVariableID;
</span><del>-        Bag&lt;TypeLocation&gt; m_locationInfo;
</del><ins>+        unsigned m_highFidelityTypeProfilingEnabledCount;
+        std::unique_ptr&lt;Bag&lt;TypeLocation&gt;&gt; m_typeLocationInfo;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(GC_VALIDATION)
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/WebCore/ChangeLog        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2014-08-14  Saam Barati  &lt;sbarati@apple.com&gt;
+
+        Allow high fidelity type profiling to be enabled and disabled.
+        https://bugs.webkit.org/show_bug.cgi?id=135423
+
+        Reviewed by Geoffrey Garen.
+
+        PageRuntimeAgent and WorkerRuntimeAgent now call their super 
+        class's (InspectorRuntimeAgent) implementation of willDestroyFrontendAndBackend
+        to give InspectorRuntimeAgent a chance to recompile all JavaScript
+        functions, if necessary, for type profiling.
+
+        * inspector/PageRuntimeAgent.cpp:
+        (WebCore::PageRuntimeAgent::willDestroyFrontendAndBackend):
+        * inspector/WorkerRuntimeAgent.cpp:
+        (WebCore::WorkerRuntimeAgent::willDestroyFrontendAndBackend):
+
</ins><span class="cx"> 2014-08-14  Brent Fulgham  &lt;bfulgham@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Win] Correct build when DerivedSources location not supplied by build environment
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorPageRuntimeAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/PageRuntimeAgent.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/PageRuntimeAgent.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/WebCore/inspector/PageRuntimeAgent.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -67,13 +67,15 @@
</span><span class="cx">     m_backendDispatcher = InspectorRuntimeBackendDispatcher::create(backendDispatcher, this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void PageRuntimeAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason)
</del><ins>+void PageRuntimeAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason reason)
</ins><span class="cx"> {
</span><span class="cx">     m_frontendDispatcher = nullptr;
</span><span class="cx">     m_backendDispatcher.clear();
</span><span class="cx"> 
</span><span class="cx">     String errorString;
</span><span class="cx">     disable(&amp;errorString);
</span><ins>+
+    InspectorRuntimeAgent::willDestroyFrontendAndBackend(reason);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void PageRuntimeAgent::enable(ErrorString* errorString)
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorWorkerRuntimeAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/WorkerRuntimeAgent.cpp (172613 => 172614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/WorkerRuntimeAgent.cpp        2014-08-14 23:50:46 UTC (rev 172613)
+++ trunk/Source/WebCore/inspector/WorkerRuntimeAgent.cpp        2014-08-14 23:59:44 UTC (rev 172614)
</span><span class="lines">@@ -59,9 +59,11 @@
</span><span class="cx">     m_backendDispatcher = InspectorRuntimeBackendDispatcher::create(backendDispatcher, this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WorkerRuntimeAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason)
</del><ins>+void WorkerRuntimeAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason reason)
</ins><span class="cx"> {
</span><span class="cx">     m_backendDispatcher.clear();
</span><ins>+
+    InspectorRuntimeAgent::willDestroyFrontendAndBackend(reason);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> InjectedScript WorkerRuntimeAgent::injectedScriptForEval(ErrorString* error, const int* executionContextId)
</span></span></pre>
</div>
</div>

</body>
</html>