<!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>[171510] branches/ftlopt/Source/JavaScriptCore</title>
</head>
<body>

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

<h3>Log Message</h3>
<pre>Make improvements to Type Profiling
https://bugs.webkit.org/show_bug.cgi?id=134860

Patch by Saam Barati &lt;sbarati@apple.com&gt; on 2014-07-23
Reviewed by Filip Pizlo.

I improved the API between the inspector and JSC. We no longer send one huge
string to the inspector. We now send structured data that represents the type
information that JSC has collected. I've also created a beginning implementation 
of a type lattice that allows us to resolve a display name for a type that
consists of a single word.

I created a data structure that knows which functions have executed. This
solves the bug where types inside an un-executed function will resolve
to the type of the enclosing expression of that function. This data
structure may also be useful later if the inspector chooses to create a UI
around showing which functions have executed.

Better type information is gathered for objects. StructureShape now
represents an object's prototype chain.  StructureShape also collects
the constructor name for an object.

Expression ranges are now zero indexed.

Removed some extraneous methods.

* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::scopeDependentProfile):
* bytecode/CodeBlock.h:
* bytecode/TypeLocation.h:
(JSC::TypeLocation::TypeLocation):
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedFunctionExecutable::highFidelityTypeProfilingStartOffset):
(JSC::UnlinkedFunctionExecutable::highFidelityTypeProfilingEndOffset):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::emitHighFidelityTypeProfilingExpressionInfo):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::emitHighFidelityTypeProfilingExpressionInfo): Deleted.
* heap/Heap.cpp:
(JSC::Heap::collect):
* inspector/agents/InspectorRuntimeAgent.cpp:
(Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
(Inspector::InspectorRuntimeAgent::getRuntimeTypeForVariableAtOffset): Deleted.
* inspector/agents/InspectorRuntimeAgent.h:
* inspector/protocol/Runtime.json:
* runtime/Executable.cpp:
(JSC::ScriptExecutable::ScriptExecutable):
(JSC::ProgramExecutable::ProgramExecutable):
(JSC::FunctionExecutable::FunctionExecutable):
(JSC::ProgramExecutable::initializeGlobalProperties):
* runtime/Executable.h:
(JSC::ScriptExecutable::highFidelityTypeProfilingStartOffset):
(JSC::ScriptExecutable::highFidelityTypeProfilingEndOffset):
* runtime/FunctionHasExecutedCache.cpp: Added.
(JSC::FunctionHasExecutedCache::hasExecutedAtOffset):
(JSC::FunctionHasExecutedCache::insertUnexecutedRange):
(JSC::FunctionHasExecutedCache::removeUnexecutedRange):
* runtime/FunctionHasExecutedCache.h: Added.
(JSC::FunctionHasExecutedCache::FunctionRange::FunctionRange):
(JSC::FunctionHasExecutedCache::FunctionRange::operator==):
(JSC::FunctionHasExecutedCache::FunctionRange::hash):
* runtime/HighFidelityLog.cpp:
(JSC::HighFidelityLog::processHighFidelityLog):
(JSC::HighFidelityLog::actuallyProcessLogThreadFunction): Deleted.
* runtime/HighFidelityLog.h:
(JSC::HighFidelityLog::recordTypeInformationForLocation):
* runtime/HighFidelityTypeProfiler.cpp:
(JSC::HighFidelityTypeProfiler::logTypesForTypeLocation):
(JSC::HighFidelityTypeProfiler::insertNewLocation):
(JSC::HighFidelityTypeProfiler::getTypesForVariableAtOffsetForInspector):
(JSC::descriptorMatchesTypeLocation):
(JSC::HighFidelityTypeProfiler::findLocation):
(JSC::HighFidelityTypeProfiler::getTypesForVariableInAtOffset): Deleted.
(JSC::HighFidelityTypeProfiler::getGlobalTypesForVariableAtOffset): Deleted.
(JSC::HighFidelityTypeProfiler::getLocalTypesForVariableAtOffset): Deleted.
* runtime/HighFidelityTypeProfiler.h:
(JSC::QueryKey::QueryKey):
(JSC::QueryKey::isHashTableDeletedValue):
(JSC::QueryKey::operator==):
(JSC::QueryKey::hash):
(JSC::QueryKeyHash::hash):
(JSC::QueryKeyHash::equal):
(JSC::HighFidelityTypeProfiler::functionHasExecutedCache):
(JSC::HighFidelityTypeProfiler::typeLocationCache):
* runtime/Structure.cpp:
(JSC::Structure::toStructureShape):
* runtime/Structure.h:
* runtime/TypeLocationCache.cpp: Added.
(JSC::TypeLocationCache::getTypeLocation):
* runtime/TypeLocationCache.h: Added.
(JSC::TypeLocationCache::LocationKey::LocationKey):
(JSC::TypeLocationCache::LocationKey::operator==):
(JSC::TypeLocationCache::LocationKey::hash):
* runtime/TypeSet.cpp:
(JSC::TypeSet::getRuntimeTypeForValue):
(JSC::TypeSet::addTypeForValue):
(JSC::TypeSet::seenTypes):
(JSC::TypeSet::doesTypeConformTo):
(JSC::TypeSet::displayName):
(JSC::TypeSet::allPrimitiveTypeNames):
(JSC::TypeSet::allStructureRepresentations):
(JSC::TypeSet::leastCommonAncestor):
(JSC::StructureShape::StructureShape):
(JSC::StructureShape::addProperty):
(JSC::StructureShape::propertyHash):
(JSC::StructureShape::leastCommonAncestor):
(JSC::StructureShape::stringRepresentation):
(JSC::StructureShape::inspectorRepresentation):
(JSC::StructureShape::leastUpperBound): Deleted.
* runtime/TypeSet.h:
(JSC::StructureShape::setConstructorName):
(JSC::StructureShape::constructorName):
(JSC::StructureShape::setProto):
* runtime/VM.cpp:
(JSC::VM::dumpHighFidelityProfilingTypes):
(JSC::VM::getTypesForVariableAtOffset): Deleted.
(JSC::VM::updateHighFidelityTypeProfileState): Deleted.
* runtime/VM.h:
(JSC::VM::isProfilingTypesWithHighFidelity):
(JSC::VM::highFidelityTypeProfiler):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchesftloptSourceJavaScriptCoreChangeLog">branches/ftlopt/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">branches/ftlopt/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#branchesftloptSourceJavaScriptCorebytecodeCodeBlockcpp">branches/ftlopt/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCorebytecodeCodeBlockh">branches/ftlopt/Source/JavaScriptCore/bytecode/CodeBlock.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCorebytecodeTypeLocationh">branches/ftlopt/Source/JavaScriptCore/bytecode/TypeLocation.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCorebytecodeUnlinkedCodeBlockcpp">branches/ftlopt/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCorebytecodeUnlinkedCodeBlockh">branches/ftlopt/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">branches/ftlopt/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCorebytecompilerBytecodeGeneratorh">branches/ftlopt/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreheapHeapcpp">branches/ftlopt/Source/JavaScriptCore/heap/Heap.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreinspectoragentsInspectorRuntimeAgentcpp">branches/ftlopt/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreinspectoragentsInspectorRuntimeAgenth">branches/ftlopt/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreinspectorprotocolRuntimejson">branches/ftlopt/Source/JavaScriptCore/inspector/protocol/Runtime.json</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeExecutablecpp">branches/ftlopt/Source/JavaScriptCore/runtime/Executable.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeExecutableh">branches/ftlopt/Source/JavaScriptCore/runtime/Executable.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeHighFidelityLogcpp">branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityLog.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeHighFidelityLogh">branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityLog.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeHighFidelityTypeProfilercpp">branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeHighFidelityTypeProfilerh">branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeStructurecpp">branches/ftlopt/Source/JavaScriptCore/runtime/Structure.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeStructureh">branches/ftlopt/Source/JavaScriptCore/runtime/Structure.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeTypeSetcpp">branches/ftlopt/Source/JavaScriptCore/runtime/TypeSet.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeTypeSeth">branches/ftlopt/Source/JavaScriptCore/runtime/TypeSet.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeVMcpp">branches/ftlopt/Source/JavaScriptCore/runtime/VM.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeVMh">branches/ftlopt/Source/JavaScriptCore/runtime/VM.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeFunctionHasExecutedCachecpp">branches/ftlopt/Source/JavaScriptCore/runtime/FunctionHasExecutedCache.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeFunctionHasExecutedCacheh">branches/ftlopt/Source/JavaScriptCore/runtime/FunctionHasExecutedCache.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeTypeLocationCachecpp">branches/ftlopt/Source/JavaScriptCore/runtime/TypeLocationCache.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeTypeLocationCacheh">branches/ftlopt/Source/JavaScriptCore/runtime/TypeLocationCache.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchesftloptSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/ChangeLog (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/ChangeLog        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/ChangeLog        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -1,3 +1,130 @@
</span><ins>+2014-07-23  Saam Barati  &lt;sbarati@apple.com&gt;
+
+        Make improvements to Type Profiling
+        https://bugs.webkit.org/show_bug.cgi?id=134860
+
+        Reviewed by Filip Pizlo.
+
+        I improved the API between the inspector and JSC. We no longer send one huge
+        string to the inspector. We now send structured data that represents the type
+        information that JSC has collected. I've also created a beginning implementation 
+        of a type lattice that allows us to resolve a display name for a type that
+        consists of a single word.
+
+        I created a data structure that knows which functions have executed. This
+        solves the bug where types inside an un-executed function will resolve
+        to the type of the enclosing expression of that function. This data
+        structure may also be useful later if the inspector chooses to create a UI
+        around showing which functions have executed.
+
+        Better type information is gathered for objects. StructureShape now
+        represents an object's prototype chain.  StructureShape also collects
+        the constructor name for an object.
+
+        Expression ranges are now zero indexed.
+
+        Removed some extraneous methods.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::scopeDependentProfile):
+        * bytecode/CodeBlock.h:
+        * bytecode/TypeLocation.h:
+        (JSC::TypeLocation::TypeLocation):
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedFunctionExecutable::highFidelityTypeProfilingStartOffset):
+        (JSC::UnlinkedFunctionExecutable::highFidelityTypeProfilingEndOffset):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::emitHighFidelityTypeProfilingExpressionInfo):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::emitHighFidelityTypeProfilingExpressionInfo): Deleted.
+        * heap/Heap.cpp:
+        (JSC::Heap::collect):
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
+        (Inspector::InspectorRuntimeAgent::getRuntimeTypeForVariableAtOffset): Deleted.
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * inspector/protocol/Runtime.json:
+        * runtime/Executable.cpp:
+        (JSC::ScriptExecutable::ScriptExecutable):
+        (JSC::ProgramExecutable::ProgramExecutable):
+        (JSC::FunctionExecutable::FunctionExecutable):
+        (JSC::ProgramExecutable::initializeGlobalProperties):
+        * runtime/Executable.h:
+        (JSC::ScriptExecutable::highFidelityTypeProfilingStartOffset):
+        (JSC::ScriptExecutable::highFidelityTypeProfilingEndOffset):
+        * runtime/FunctionHasExecutedCache.cpp: Added.
+        (JSC::FunctionHasExecutedCache::hasExecutedAtOffset):
+        (JSC::FunctionHasExecutedCache::insertUnexecutedRange):
+        (JSC::FunctionHasExecutedCache::removeUnexecutedRange):
+        * runtime/FunctionHasExecutedCache.h: Added.
+        (JSC::FunctionHasExecutedCache::FunctionRange::FunctionRange):
+        (JSC::FunctionHasExecutedCache::FunctionRange::operator==):
+        (JSC::FunctionHasExecutedCache::FunctionRange::hash):
+        * runtime/HighFidelityLog.cpp:
+        (JSC::HighFidelityLog::processHighFidelityLog):
+        (JSC::HighFidelityLog::actuallyProcessLogThreadFunction): Deleted.
+        * runtime/HighFidelityLog.h:
+        (JSC::HighFidelityLog::recordTypeInformationForLocation):
+        * runtime/HighFidelityTypeProfiler.cpp:
+        (JSC::HighFidelityTypeProfiler::logTypesForTypeLocation):
+        (JSC::HighFidelityTypeProfiler::insertNewLocation):
+        (JSC::HighFidelityTypeProfiler::getTypesForVariableAtOffsetForInspector):
+        (JSC::descriptorMatchesTypeLocation):
+        (JSC::HighFidelityTypeProfiler::findLocation):
+        (JSC::HighFidelityTypeProfiler::getTypesForVariableInAtOffset): Deleted.
+        (JSC::HighFidelityTypeProfiler::getGlobalTypesForVariableAtOffset): Deleted.
+        (JSC::HighFidelityTypeProfiler::getLocalTypesForVariableAtOffset): Deleted.
+        * runtime/HighFidelityTypeProfiler.h:
+        (JSC::QueryKey::QueryKey):
+        (JSC::QueryKey::isHashTableDeletedValue):
+        (JSC::QueryKey::operator==):
+        (JSC::QueryKey::hash):
+        (JSC::QueryKeyHash::hash):
+        (JSC::QueryKeyHash::equal):
+        (JSC::HighFidelityTypeProfiler::functionHasExecutedCache):
+        (JSC::HighFidelityTypeProfiler::typeLocationCache):
+        * runtime/Structure.cpp:
+        (JSC::Structure::toStructureShape):
+        * runtime/Structure.h:
+        * runtime/TypeLocationCache.cpp: Added.
+        (JSC::TypeLocationCache::getTypeLocation):
+        * runtime/TypeLocationCache.h: Added.
+        (JSC::TypeLocationCache::LocationKey::LocationKey):
+        (JSC::TypeLocationCache::LocationKey::operator==):
+        (JSC::TypeLocationCache::LocationKey::hash):
+        * runtime/TypeSet.cpp:
+        (JSC::TypeSet::getRuntimeTypeForValue):
+        (JSC::TypeSet::addTypeForValue):
+        (JSC::TypeSet::seenTypes):
+        (JSC::TypeSet::doesTypeConformTo):
+        (JSC::TypeSet::displayName):
+        (JSC::TypeSet::allPrimitiveTypeNames):
+        (JSC::TypeSet::allStructureRepresentations):
+        (JSC::TypeSet::leastCommonAncestor):
+        (JSC::StructureShape::StructureShape):
+        (JSC::StructureShape::addProperty):
+        (JSC::StructureShape::propertyHash):
+        (JSC::StructureShape::leastCommonAncestor):
+        (JSC::StructureShape::stringRepresentation):
+        (JSC::StructureShape::inspectorRepresentation):
+        (JSC::StructureShape::leastUpperBound): Deleted.
+        * runtime/TypeSet.h:
+        (JSC::StructureShape::setConstructorName):
+        (JSC::StructureShape::constructorName):
+        (JSC::StructureShape::setProto):
+        * runtime/VM.cpp:
+        (JSC::VM::dumpHighFidelityProfilingTypes):
+        (JSC::VM::getTypesForVariableAtOffset): Deleted.
+        (JSC::VM::updateHighFidelityTypeProfileState): Deleted.
+        * runtime/VM.h:
+        (JSC::VM::isProfilingTypesWithHighFidelity):
+        (JSC::VM::highFidelityTypeProfiler):
+
</ins><span class="cx"> 2014-07-23  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix debug build.
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -846,6 +846,10 @@
</span><span class="cx">                 41359CF30FDD89AD00206180 /* DateConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = D21202290AD4310C00ED79B6 /* DateConversion.h */; };
</span><span class="cx">                 4443AE3316E188D90076F110 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F0EB6105C86C6B00E6DF1B /* Foundation.framework */; };
</span><span class="cx">                 451539B912DC994500EF7AC4 /* Yarr.h in Headers */ = {isa = PBXBuildFile; fileRef = 451539B812DC994500EF7AC4 /* Yarr.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                52B310FB1974AE610080857C /* FunctionHasExecutedCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B310FA1974AE610080857C /* FunctionHasExecutedCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                52B310FD1974AE870080857C /* FunctionHasExecutedCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B310FC1974AE870080857C /* FunctionHasExecutedCache.cpp */; };
+                52B310FF1975B4240080857C /* TypeLocationCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B310FE1975B4240080857C /* TypeLocationCache.cpp */; };
+                52B311011975B4670080857C /* TypeLocationCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B311001975B4670080857C /* TypeLocationCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 52DAD38F195A164E00F30464 /* TypeLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 52DAD38E195A164E00F30464 /* TypeLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 52FB7137195374B800BB612E /* HighFidelityLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FB7133195374B700BB612E /* HighFidelityLog.cpp */; };
</span><span class="cx">                 52FB7138195374B800BB612E /* HighFidelityLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FB7134195374B700BB612E /* HighFidelityLog.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -3000,6 +3004,10 @@
</span><span class="cx">                 51F0EB6105C86C6B00E6DF1B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = &quot;&lt;absolute&gt;&quot;; };
</span><span class="cx">                 51F0EC0705C86C9A00E6DF1B /* libobjc.dylib */ = {isa = PBXFileReference; lastKnownFileType = &quot;compiled.mach-o.dylib&quot;; name = libobjc.dylib; path = /usr/lib/libobjc.dylib; sourceTree = &quot;&lt;absolute&gt;&quot;; };
</span><span class="cx">                 522ABAF9194A8043008B1C85 /* TypeLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeLocation.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                52B310FA1974AE610080857C /* FunctionHasExecutedCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FunctionHasExecutedCache.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                52B310FC1974AE870080857C /* FunctionHasExecutedCache.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionHasExecutedCache.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                52B310FE1975B4240080857C /* TypeLocationCache.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypeLocationCache.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                52B311001975B4670080857C /* TypeLocationCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeLocationCache.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 52DAD38E195A164E00F30464 /* TypeLocation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeLocation.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 52FB7133195374B700BB612E /* HighFidelityLog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HighFidelityLog.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 52FB7134195374B700BB612E /* HighFidelityLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HighFidelityLog.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4674,6 +4682,8 @@
</span><span class="cx">                                 BC2680C10E16D4E900A06E92 /* FunctionConstructor.h */,
</span><span class="cx">                                 0FB4B52116B6278D003F696B /* FunctionExecutableDump.cpp */,
</span><span class="cx">                                 0FB4B52216B6278D003F696B /* FunctionExecutableDump.h */,
</span><ins>+                                52B310FA1974AE610080857C /* FunctionHasExecutedCache.h */,
+                                52B310FC1974AE870080857C /* FunctionHasExecutedCache.cpp */,
</ins><span class="cx">                                 F692A85C0255597D01FF60F7 /* FunctionPrototype.cpp */,
</span><span class="cx">                                 F692A85D0255597D01FF60F7 /* FunctionPrototype.h */,
</span><span class="cx">                                 0F2B66B217B6B5AB00A7AE3F /* GenericTypedArrayView.h */,
</span><span class="lines">@@ -4955,6 +4965,8 @@
</span><span class="cx">                                 0F2B66DB17B6B5AB00A7AE3F /* TypedArrays.h */,
</span><span class="cx">                                 0F2B66DC17B6B5AB00A7AE3F /* TypedArrayType.cpp */,
</span><span class="cx">                                 0F2B66DD17B6B5AB00A7AE3F /* TypedArrayType.h */,
</span><ins>+                                52B311001975B4670080857C /* TypeLocationCache.h */,
+                                52B310FE1975B4240080857C /* TypeLocationCache.cpp */,
</ins><span class="cx">                                 52FB72121953760C00BB612E /* TypeSet.cpp */,
</span><span class="cx">                                 52FB72131953760C00BB612E /* TypeSet.h */,
</span><span class="cx">                                 A7A8AF3217ADB5F3005AB174 /* Uint16Array.h */,
</span><span class="lines">@@ -6254,6 +6266,7 @@
</span><span class="cx">                                 0F235BDD17178E1C00690C7F /* FTLOSRExit.h in Headers */,
</span><span class="cx">                                 0F235BDE17178E1C00690C7F /* FTLOSRExitCompilationInfo.h in Headers */,
</span><span class="cx">                                 0F235BE017178E1C00690C7F /* FTLOSRExitCompiler.h in Headers */,
</span><ins>+                                52B310FB1974AE610080857C /* FunctionHasExecutedCache.h in Headers */,
</ins><span class="cx">                                 0FEA0A11170513DB00BB722C /* FTLOutput.h in Headers */,
</span><span class="cx">                                 9E72940B190F0514001A91B5 /* BundlePath.h in Headers */,
</span><span class="cx">                                 0F48532A187DFDEC0083B687 /* FTLRecoveryOpcode.h in Headers */,
</span><span class="lines">@@ -6603,6 +6616,7 @@
</span><span class="cx">                                 0FF729BB166AD360000F5BA3 /* ProfilerCompilationKind.h in Headers */,
</span><span class="cx">                                 0FF729BC166AD360000F5BA3 /* ProfilerCompiledBytecode.h in Headers */,
</span><span class="cx">                                 0FF729BD166AD360000F5BA3 /* ProfilerDatabase.h in Headers */,
</span><ins>+                                52B311011975B4670080857C /* TypeLocationCache.h in Headers */,
</ins><span class="cx">                                 0FF729BE166AD360000F5BA3 /* ProfilerExecutionCounter.h in Headers */,
</span><span class="cx">                                 0F190CAD189D82F6000AE5F0 /* ProfilerJettisonReason.h in Headers */,
</span><span class="cx">                                 0FF729BF166AD360000F5BA3 /* ProfilerOrigin.h in Headers */,
</span><span class="lines">@@ -7588,6 +7602,7 @@
</span><span class="cx">                         isa = PBXSourcesBuildPhase;
</span><span class="cx">                         buildActionMask = 2147483647;
</span><span class="cx">                         files = (
</span><ins>+                                52B310FF1975B4240080857C /* TypeLocationCache.cpp in Sources */,
</ins><span class="cx">                                 9EA5C7A2190F088700508EBE /* InitializeLLVMMac.cpp in Sources */,
</span><span class="cx">                                 9EA5C7A1190F084200508EBE /* BundlePath.mm in Sources */,
</span><span class="cx">                                 9E729408190F021E001A91B5 /* InitializeLLVMPOSIX.cpp in Sources */,
</span><span class="lines">@@ -7835,6 +7850,7 @@
</span><span class="cx">                                 0F5A6283188C98D40072C9DF /* FTLValueRange.cpp in Sources */,
</span><span class="cx">                                 147F39CB107EC37600427A48 /* FunctionConstructor.cpp in Sources */,
</span><span class="cx">                                 0FF0F19F16B72A17005DF95B /* FunctionExecutableDump.cpp in Sources */,
</span><ins>+                                52B310FD1974AE870080857C /* FunctionHasExecutedCache.cpp in Sources */,
</ins><span class="cx">                                 147F39CC107EC37600427A48 /* FunctionPrototype.cpp in Sources */,
</span><span class="cx">                                 0F766D2F15A8DCE0008F363E /* GCAwareJITStubRoutine.cpp in Sources */,
</span><span class="cx">                                 C2239D1A16262BDD005AC5FD /* GCThread.cpp in Sources */,
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecode/CodeBlock.cpp (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -49,7 +49,7 @@
</span><span class="cx"> #include &quot;JSFunction.h&quot;
</span><span class="cx"> #include &quot;JSNameScope.h&quot;
</span><span class="cx"> #include &quot;LLIntEntrypoint.h&quot;
</span><del>-#include &quot;TypeLocation.h&quot;
</del><ins>+#include &quot;TypeLocationCache.h&quot;
</ins><span class="cx"> #include &quot;LowLevelInterpreter.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;PolymorphicGetByIdList.h&quot;
</span><span class="lines">@@ -1685,12 +1685,17 @@
</span><span class="cx">     ASSERT(m_source);
</span><span class="cx">     setNumParameters(unlinkedCodeBlock-&gt;numParameters());
</span><span class="cx"> 
</span><ins>+    if (vm()-&gt;isProfilingTypesWithHighFidelity())
+        vm()-&gt;highFidelityTypeProfiler()-&gt;functionHasExecutedCache()-&gt;removeUnexecutedRange(m_ownerExecutable-&gt;sourceID(), m_ownerExecutable-&gt;highFidelityTypeProfilingStartOffset(), m_ownerExecutable-&gt;highFidelityTypeProfilingEndOffset());
+
</ins><span class="cx">     setConstantRegisters(unlinkedCodeBlock-&gt;constantRegisters());
</span><span class="cx">     if (unlinkedCodeBlock-&gt;usesGlobalObject())
</span><span class="cx">         m_constantRegisters[unlinkedCodeBlock-&gt;globalObjectRegister().toConstantIndex()].set(*m_vm, ownerExecutable, m_globalObject.get());
</span><span class="cx">     m_functionDecls.resizeToFit(unlinkedCodeBlock-&gt;numberOfFunctionDecls());
</span><span class="cx">     for (size_t count = unlinkedCodeBlock-&gt;numberOfFunctionDecls(), i = 0; i &lt; count; ++i) {
</span><span class="cx">         UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock-&gt;functionDecl(i);
</span><ins>+        if (vm()-&gt;isProfilingTypesWithHighFidelity())
+            vm()-&gt;highFidelityTypeProfiler()-&gt;functionHasExecutedCache()-&gt;insertUnexecutedRange(m_ownerExecutable-&gt;sourceID(), unlinkedExecutable-&gt;highFidelityTypeProfilingStartOffset(), unlinkedExecutable-&gt;highFidelityTypeProfilingEndOffset());
</ins><span class="cx">         unsigned lineCount = unlinkedExecutable-&gt;lineCount();
</span><span class="cx">         unsigned firstLine = ownerExecutable-&gt;lineNo() + unlinkedExecutable-&gt;firstLineOffset();
</span><span class="cx">         bool startColumnIsOnOwnerStartLine = !unlinkedExecutable-&gt;firstLineOffset();
</span><span class="lines">@@ -1707,6 +1712,8 @@
</span><span class="cx">     m_functionExprs.resizeToFit(unlinkedCodeBlock-&gt;numberOfFunctionExprs());
</span><span class="cx">     for (size_t count = unlinkedCodeBlock-&gt;numberOfFunctionExprs(), i = 0; i &lt; count; ++i) {
</span><span class="cx">         UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock-&gt;functionExpr(i);
</span><ins>+        if (vm()-&gt;isProfilingTypesWithHighFidelity())
+            vm()-&gt;highFidelityTypeProfiler()-&gt;functionHasExecutedCache()-&gt;insertUnexecutedRange(m_ownerExecutable-&gt;sourceID(), unlinkedExecutable-&gt;highFidelityTypeProfilingStartOffset(), unlinkedExecutable-&gt;highFidelityTypeProfilingEndOffset());
</ins><span class="cx">         unsigned lineCount = unlinkedExecutable-&gt;lineCount();
</span><span class="cx">         unsigned firstLine = ownerExecutable-&gt;lineNo() + unlinkedExecutable-&gt;firstLineOffset();
</span><span class="cx">         bool startColumnIsOnOwnerStartLine = !unlinkedExecutable-&gt;firstLineOffset();
</span><span class="lines">@@ -1922,8 +1929,7 @@
</span><span class="cx">             if (pc[0].u.opcode == op_get_from_scope_with_profile) {
</span><span class="cx">                 // The format of this instruction is: get_from_scope_with_profile dst, scope, id, ResolveModeAndType, Structure, Operand, ..., TypeLocation
</span><span class="cx">                 size_t instructionOffset = i + opLength - 1;
</span><del>-                TypeLocation* location = vm()-&gt;nextLocation();
-                scopeDependentProfile(op, ident, instructionOffset, location);
</del><ins>+                TypeLocation* location = scopeDependentProfile(op, ident, instructionOffset);
</ins><span class="cx">                 instructions[i + 8].u.location = location;
</span><span class="cx">             }
</span><span class="cx">             break;
</span><span class="lines">@@ -1949,8 +1955,7 @@
</span><span class="cx">             if (pc[0].u.opcode == op_put_to_scope_with_profile) {
</span><span class="cx">                 // The format of this instruction is: put_to_scope_with_profile scope, id, value, ResolveModeAndType, Structure, Operand, TypeLocation*
</span><span class="cx">                 size_t instructionOffset = i + opLength - 1;
</span><del>-                TypeLocation* location = vm()-&gt;nextLocation();
-                scopeDependentProfile(op, ident, instructionOffset, location);
</del><ins>+                TypeLocation* location = scopeDependentProfile(op, ident, instructionOffset);
</ins><span class="cx">                 instructions[i + 7].u.location = location;
</span><span class="cx">             }
</span><span class="cx">             break;
</span><span class="lines">@@ -1959,44 +1964,52 @@
</span><span class="cx">         case op_profile_types_with_high_fidelity: {
</span><span class="cx">             size_t instructionOffset = i + opLength - 1;
</span><span class="cx">             unsigned divotStart, divotEnd;
</span><ins>+            intptr_t globalVariableID;
+            RefPtr&lt;TypeSet&gt; globalTypeSet;
</ins><span class="cx">             bool shouldAnalyze = m_unlinkedCode-&gt;highFidelityTypeProfileExpressionInfoForBytecodeOffset(instructionOffset, divotStart, divotEnd);
</span><span class="cx">             VirtualRegister virtualRegister(pc[1].u.operand);
</span><span class="cx">             SymbolTable* symbolTable = m_symbolTable.get();
</span><del>-            TypeLocation* location = vm()-&gt;nextLocation();
-            location-&gt;m_divotStart = divotStart;
-            location-&gt;m_divotEnd = divotEnd;
-            location-&gt;m_sourceID = m_ownerExecutable-&gt;sourceID();
</del><span class="cx"> 
</span><span class="cx">             ProfileTypesWithHighFidelityBytecodeFlag flag = static_cast&lt;ProfileTypesWithHighFidelityBytecodeFlag&gt;(pc[3].u.operand);
</span><span class="cx">             switch (flag) {
</span><span class="cx">             case ProfileTypesBytecodeHasGlobalID: {
</span><span class="cx">                 ConcurrentJITLocker locker(symbolTable-&gt;m_lock);
</span><del>-                location-&gt;m_globalVariableID = symbolTable-&gt;uniqueIDForRegister(locker, virtualRegister.offset(), *vm());
-                location-&gt;m_globalTypeSet = symbolTable-&gt;globalTypeSetForRegister(locker, virtualRegister.offset(), *vm());
</del><ins>+                globalVariableID = symbolTable-&gt;uniqueIDForRegister(locker, virtualRegister.offset(), *vm());
+                globalTypeSet = symbolTable-&gt;globalTypeSetForRegister(locker, virtualRegister.offset(), *vm());
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             case ProfileTypesBytecodeDoesNotHaveGlobalID: 
</span><del>-            case ProfileTypesBytecodeFunctionArgument:
</del><ins>+            case ProfileTypesBytecodeFunctionArgument: {
+                globalVariableID = HighFidelityNoGlobalIDExists;
+                break;
+            }
</ins><span class="cx">             case ProfileTypesBytecodeFunctionThisObject: {
</span><del>-                location-&gt;m_globalVariableID = HighFidelityNoGlobalIDExists;
</del><ins>+                globalVariableID = HighFidelityThisStatement;
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             case ProfileTypesBytecodeFunctionReturnStatement: {
</span><del>-                location-&gt;m_globalTypeSet = returnStatementTypeSet();
-                location-&gt;m_globalVariableID = HighFidelityReturnStatement;
-                location-&gt;m_divotForFunctionOffsetIfReturnStatement = m_sourceOffset; 
</del><ins>+                globalTypeSet = returnStatementTypeSet();
+                globalVariableID = HighFidelityReturnStatement;
</ins><span class="cx">                 if (!shouldAnalyze) {
</span><span class="cx">                     // Because some return statements are added implicitly (to return undefined at the end of a function), and these nodes don't emit expression ranges, give them some range.
</span><span class="cx">                     // Currently, this divot is on the open brace of the function. 
</span><del>-                    location-&gt;m_divotStart = location-&gt;m_divotEnd = location-&gt;m_divotForFunctionOffsetIfReturnStatement;
</del><ins>+                    divotStart = divotEnd = m_sourceOffset;
</ins><span class="cx">                     shouldAnalyze = true;
</span><span class="cx">                 }
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            if (shouldAnalyze)
</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());
+            TypeLocation* location = locationPair.first;
+            bool isNewLocation = locationPair.second;
+
+            if (ProfileTypesBytecodeFunctionReturnStatement)
+                location-&gt;m_divotForFunctionOffsetIfReturnStatement = m_sourceOffset;
+
+            if (shouldAnalyze &amp;&amp; isNewLocation)
</ins><span class="cx">                 vm()-&gt;highFidelityTypeProfiler()-&gt;insertNewLocation(location);
</span><ins>+
</ins><span class="cx">             instructions[i + 2].u.location = location;
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -3883,13 +3896,12 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-void CodeBlock::scopeDependentProfile(ResolveOp op, const Identifier&amp; ident, size_t instructionOffset, TypeLocation* location)
</del><ins>+TypeLocation* CodeBlock::scopeDependentProfile(ResolveOp op, const Identifier&amp; ident, size_t instructionOffset)
</ins><span class="cx"> {
</span><span class="cx">     unsigned divotStart, divotEnd;
</span><span class="cx">     bool shouldAnalyze = m_unlinkedCode-&gt;highFidelityTypeProfileExpressionInfoForBytecodeOffset(instructionOffset, divotStart, divotEnd);
</span><del>-    location-&gt;m_divotStart = divotStart;
-    location-&gt;m_divotEnd = divotEnd;
-    location-&gt;m_sourceID = m_ownerExecutable-&gt;sourceID();
</del><ins>+    intptr_t globalVariableID;
+    RefPtr&lt;TypeSet&gt; globalTypeSet;
</ins><span class="cx"> 
</span><span class="cx">     // FIXME: handle other values for op.type here, and also consider what to do when we can't statically determine the globalID
</span><span class="cx">     SymbolTable* symbolTable = nullptr;
</span><span class="lines">@@ -3900,13 +3912,19 @@
</span><span class="cx">     
</span><span class="cx">     if (symbolTable) {
</span><span class="cx">         ConcurrentJITLocker locker(symbolTable-&gt;m_lock);
</span><del>-        location-&gt;m_globalVariableID = symbolTable-&gt;uniqueIDForVariable(locker, ident.impl(), *vm());
-        location-&gt;m_globalTypeSet = symbolTable-&gt;globalTypeSetForVariable(locker, ident.impl(), *vm());
</del><ins>+        globalVariableID = symbolTable-&gt;uniqueIDForVariable(locker, ident.impl(), *vm());
+        globalTypeSet = symbolTable-&gt;globalTypeSetForVariable(locker, ident.impl(), *vm());
</ins><span class="cx">     } else
</span><del>-        location-&gt;m_globalVariableID = HighFidelityNoGlobalIDExists;
</del><ins>+        globalVariableID = HighFidelityNoGlobalIDExists;
</ins><span class="cx"> 
</span><del>-    if (shouldAnalyze)
</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());
+    TypeLocation* location = locationPair.first;
+    bool isNewLocation = locationPair.second;
+
+    if (shouldAnalyze &amp; isNewLocation)
</ins><span class="cx">         vm()-&gt;highFidelityTypeProfiler()-&gt;insertNewLocation(location);
</span><ins>+
+    return location;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecode/CodeBlock.h (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecode/CodeBlock.h        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/bytecode/CodeBlock.h        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -83,6 +83,7 @@
</span><span class="cx"> class ExecState;
</span><span class="cx"> class LLIntOffsetsExtractor;
</span><span class="cx"> class RepatchBuffer;
</span><ins>+class TypeLocation;
</ins><span class="cx"> 
</span><span class="cx"> inline VirtualRegister unmodifiedArgumentsRegister(VirtualRegister argumentsRegister) { return VirtualRegister(argumentsRegister.offset() + 1); }
</span><span class="cx"> 
</span><span class="lines">@@ -1021,7 +1022,7 @@
</span><span class="cx">             m_rareData = adoptPtr(new RareData);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void scopeDependentProfile(ResolveOp, const Identifier&amp;, size_t, TypeLocation*);
</del><ins>+    TypeLocation* scopeDependentProfile(ResolveOp, const Identifier&amp;, size_t);
</ins><span class="cx">     
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx">     void resetStubInternal(RepatchBuffer&amp;, StructureStubInfo&amp;);
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecodeTypeLocationh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecode/TypeLocation.h (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecode/TypeLocation.h        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/bytecode/TypeLocation.h        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -33,13 +33,15 @@
</span><span class="cx"> enum HighFidelityGlobalIDFlags {
</span><span class="cx">     HighFidelityNeedsUniqueIDGeneration = -1,
</span><span class="cx">     HighFidelityNoGlobalIDExists = -2,
</span><del>-    HighFidelityReturnStatement = -3
</del><ins>+    HighFidelityReturnStatement = -3,
+    HighFidelityThisStatement = -4
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class TypeLocation {
</span><span class="cx"> public:
</span><span class="cx">     TypeLocation() 
</span><del>-        : m_instructionTypeSet(TypeSet::create())
</del><ins>+        : m_divotForFunctionOffsetIfReturnStatement(UINT_MAX)
+        , m_instructionTypeSet(TypeSet::create())
</ins><span class="cx">         , m_globalTypeSet(nullptr)
</span><span class="cx">     {
</span><span class="cx">     }
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecodeUnlinkedCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -100,6 +100,8 @@
</span><span class="cx">     , m_unlinkedBodyEndColumn(m_lineCount ? node-&gt;endColumn() : node-&gt;endColumn() - node-&gt;startColumn())
</span><span class="cx">     , m_startOffset(node-&gt;source().startOffset() - source.startOffset())
</span><span class="cx">     , m_sourceLength(node-&gt;source().length())
</span><ins>+    , m_highFidelityTypeProfilingStartOffset(node-&gt;functionNameStart())
+    , m_highFidelityTypeProfilingEndOffset(node-&gt;startStartOffset() + node-&gt;source().length() - 1)
</ins><span class="cx">     , m_features(node-&gt;features())
</span><span class="cx">     , m_functionMode(node-&gt;functionMode())
</span><span class="cx"> {
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecodeUnlinkedCodeBlockh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -125,6 +125,8 @@
</span><span class="cx">     unsigned unlinkedBodyEndColumn() const { return m_unlinkedBodyEndColumn; }
</span><span class="cx">     unsigned startOffset() const { return m_startOffset; }
</span><span class="cx">     unsigned sourceLength() { return m_sourceLength; }
</span><ins>+    unsigned highFidelityTypeProfilingStartOffset() const { return m_highFidelityTypeProfilingStartOffset; }
+    unsigned highFidelityTypeProfilingEndOffset() const { return m_highFidelityTypeProfilingEndOffset; }
</ins><span class="cx"> 
</span><span class="cx">     String paramString() const;
</span><span class="cx"> 
</span><span class="lines">@@ -186,6 +188,8 @@
</span><span class="cx">     unsigned m_unlinkedBodyEndColumn;
</span><span class="cx">     unsigned m_startOffset;
</span><span class="cx">     unsigned m_sourceLength;
</span><ins>+    unsigned m_highFidelityTypeProfilingStartOffset;
+    unsigned m_highFidelityTypeProfilingEndOffset;
</ins><span class="cx"> 
</span><span class="cx">     CodeFeatures m_features;
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -337,7 +337,7 @@
</span><span class="cx"> 
</span><span class="cx">     m_symbolTable-&gt;setCaptureEnd(virtualRegisterForLocal(codeBlock-&gt;m_numVars).offset());
</span><span class="cx"> 
</span><del>-    bool canLazilyCreateFunctions = !functionBody-&gt;needsActivationForMoreThanVariables() &amp;&amp; !m_shouldEmitDebugHooks;
</del><ins>+    bool canLazilyCreateFunctions = !functionBody-&gt;needsActivationForMoreThanVariables() &amp;&amp; !m_shouldEmitDebugHooks &amp;&amp; !isProfilingTypesWithHighFidelity();
</ins><span class="cx">     m_firstLazyFunction = codeBlock-&gt;m_numVars;
</span><span class="cx">     for (size_t i = 0; i &lt; functionStack.size(); ++i) {
</span><span class="cx">         FunctionBodyNode* function = functionStack[i];
</span><span class="lines">@@ -1116,6 +1116,14 @@
</span><span class="cx">     return dst;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void BytecodeGenerator::emitHighFidelityTypeProfilingExpressionInfo(const JSTextPosition&amp; startDivot, const JSTextPosition&amp; endDivot)
+{
+    unsigned start = startDivot.offset; // Ranges are inclusive of their endpoints, AND 0 indexed.
+    unsigned end = endDivot.offset - 1; // End Ranges already go one past the inclusive range, so subtract 1.
+    unsigned instructionOffset = instructions().size() - 1;
+    m_codeBlock-&gt;addHighFidelityTypeProfileExpressionInfo(instructionOffset, start, end);
+}
+
</ins><span class="cx"> void BytecodeGenerator::emitProfileTypesWithHighFidelity(RegisterID* registerToProfile, ProfileTypesWithHighFidelityBytecodeFlag flag)
</span><span class="cx"> {
</span><span class="cx">     emitOpcode(op_profile_types_with_high_fidelity);
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -324,13 +324,6 @@
</span><span class="cx">                 m_codeBlock-&gt;addExpressionInfo(instructionOffset, divotOffset, startOffset, endOffset, line, column);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        void emitHighFidelityTypeProfilingExpressionInfo(const JSTextPosition&amp; startDivot, const JSTextPosition&amp; endDivot)
-        {
-            unsigned start = startDivot.offset + 1; // Ranges are inclusive of their endpoints, AND 1 indexed.
-            unsigned end = endDivot.offset; // End Ranges already go one past the inclusive range, so no need to do + 1 - 1.
-            unsigned instructionOffset = instructions().size() - 1;
-            m_codeBlock-&gt;addHighFidelityTypeProfileExpressionInfo(instructionOffset, start, end);
-        }
</del><span class="cx"> 
</span><span class="cx">         ALWAYS_INLINE bool leftHandSideNeedsCopy(bool rightHasAssignments, bool rightIsPure)
</span><span class="cx">         {
</span><span class="lines">@@ -348,6 +341,7 @@
</span><span class="cx">             return emitNode(n);
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        void emitHighFidelityTypeProfilingExpressionInfo(const JSTextPosition&amp; startDivot, const JSTextPosition&amp; endDivot);
</ins><span class="cx">         void emitProfileTypesWithHighFidelity(RegisterID* dst, ProfileTypesWithHighFidelityBytecodeFlag);
</span><span class="cx"> 
</span><span class="cx">         RegisterID* emitLoad(RegisterID* dst, bool);
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreheapHeapcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/heap/Heap.cpp (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/heap/Heap.cpp        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/heap/Heap.cpp        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -970,8 +970,6 @@
</span><span class="cx"> #if ENABLE(ALLOCATION_LOGGING)
</span><span class="cx">     dataLogF(&quot;JSC GC starting collection.\n&quot;);
</span><span class="cx"> #endif
</span><del>-    if (vm()-&gt;isProfilingTypesWithHighFidelity())
-        vm()-&gt;highFidelityLog()-&gt;processHighFidelityLog(false, &quot;GC&quot;);
</del><span class="cx">     
</span><span class="cx">     double before = 0;
</span><span class="cx">     if (Options::logGC()) {
</span><span class="lines">@@ -981,6 +979,11 @@
</span><span class="cx">     
</span><span class="cx">     SamplingRegion samplingRegion(&quot;Garbage Collection&quot;);
</span><span class="cx">     
</span><ins>+    if (vm()-&gt;isProfilingTypesWithHighFidelity()) {
+        DeferGCForAWhile awhile(*this);
+        vm()-&gt;highFidelityLog()-&gt;processHighFidelityLog(&quot;GC&quot;);
+    }
+    
</ins><span class="cx">     RELEASE_ASSERT(!m_deferralDepth);
</span><span class="cx">     ASSERT(vm()-&gt;currentThreadIsHoldingAPILock());
</span><span class="cx">     RELEASE_ASSERT(vm()-&gt;atomicStringTable() == wtfThreadData().atomicStringTable());
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreinspectoragentsInspectorRuntimeAgentcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -35,6 +35,8 @@
</span><span class="cx"> #if ENABLE(INSPECTOR)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;Completion.h&quot;
</span><ins>+#include &quot;HighFidelityLog.h&quot;
+#include &quot;HighFidelityTypeProfiler.h&quot;
</ins><span class="cx"> #include &quot;InjectedScript.h&quot;
</span><span class="cx"> #include &quot;InjectedScriptManager.h&quot;
</span><span class="cx"> #include &quot;InspectorValues.h&quot;
</span><span class="lines">@@ -43,6 +45,7 @@
</span><span class="cx"> #include &quot;ScriptDebugServer.h&quot;
</span><span class="cx"> #include &quot;SourceCode.h&quot;
</span><span class="cx"> #include &lt;wtf/PassRefPtr.h&gt;
</span><ins>+#include &lt;wtf/CurrentTime.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> using namespace JSC;
</span><span class="cx"> 
</span><span class="lines">@@ -191,11 +194,41 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void InspectorRuntimeAgent::getRuntimeTypeForVariableAtOffset(ErrorString*, const String&amp; in_variableName, const String&amp; in_id, int in_divot, String* out_types) 
</del><ins>+void InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets(ErrorString* errorString, const RefPtr&lt;Inspector::InspectorArray&gt;&amp; in_locations, RefPtr&lt;Inspector::InspectorArray&gt;&amp; out_types)
</ins><span class="cx"> {
</span><ins>+    static const bool verbose = false;
</ins><span class="cx">     VM&amp; vm = globalVM();
</span><del>-    String types(vm.getTypesForVariableAtOffset(in_divot, in_variableName, in_id));
-    *out_types = types;
</del><ins>+    out_types = Inspector::InspectorArray::create();
+    if (!vm.isProfilingTypesWithHighFidelity())
+        return;
+
+    double start = currentTimeMS();
+    vm.highFidelityLog()-&gt;processHighFidelityLog(&quot;User Query&quot;);
+
+    for (size_t i = 0; i &lt; in_locations-&gt;length(); i++) {
+        RefPtr&lt;Inspector::InspectorValue&gt; value = in_locations-&gt;get(i);
+        RefPtr&lt;InspectorObject&gt; location;
+        if (!value-&gt;asObject(&amp;location)) {
+            *errorString = ASCIILiteral(&quot;Array of TypeLocation objects has an object that does not have type of TypeLocation.&quot;);
+            return;
+        }
+
+        int descriptor;
+        String sourceIDAsString;
+        int divot;
+        location-&gt;getNumber(ASCIILiteral(&quot;typeInformationDescriptor&quot;), &amp;descriptor);
+        location-&gt;getString(ASCIILiteral(&quot;sourceID&quot;), &amp;sourceIDAsString);
+        location-&gt;getNumber(ASCIILiteral(&quot;divot&quot;), &amp;divot);
+        
+        RefPtr&lt;Inspector::InspectorObject&gt; typeDescription = Inspector::InspectorObject::create();
+        bool okay;
+        vm.highFidelityTypeProfiler()-&gt;getTypesForVariableAtOffsetForInspector(static_cast&lt;TypeProfilerSearchDescriptor&gt;(descriptor), divot, sourceIDAsString.toIntPtrStrict(&amp;okay), typeDescription);
+        out_types-&gt;pushObject(typeDescription);
+    }
+
+    double end = currentTimeMS();
+    if (verbose)
+        dataLogF(&quot;Inspector::getRuntimeTypesForVariablesAtOffsets took %lfms\n&quot;, end - start);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace Inspector
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreinspectoragentsInspectorRuntimeAgenth"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -66,8 +66,8 @@
</span><span class="cx">     virtual void getProperties(ErrorString*, const String&amp; objectId, const bool* ownProperties, RefPtr&lt;Inspector::TypeBuilder::Array&lt;Inspector::TypeBuilder::Runtime::PropertyDescriptor&gt;&gt;&amp; result, RefPtr&lt;Inspector::TypeBuilder::Array&lt;Inspector::TypeBuilder::Runtime::InternalPropertyDescriptor&gt;&gt;&amp; internalProperties) override final;
</span><span class="cx">     virtual void releaseObjectGroup(ErrorString*, const String&amp; objectGroup) override final;
</span><span class="cx">     virtual void run(ErrorString*) override;
</span><del>-    virtual void getRuntimeTypeForVariableAtOffset(ErrorString*, const String&amp; in_variableName, const String&amp; in_id, int in_divot, String* out_types) override;
-
</del><ins>+    virtual void getRuntimeTypesForVariablesAtOffsets(ErrorString*, const RefPtr&lt;Inspector::InspectorArray&gt;&amp; in_locations, RefPtr&lt;Inspector::InspectorArray&gt;&amp; out_types) override;
+    
</ins><span class="cx">     void setScriptDebugServer(ScriptDebugServer* scriptDebugServer) { m_scriptDebugServer = scriptDebugServer; }
</span><span class="cx"> 
</span><span class="cx">     bool enabled() const { return m_enabled; }
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreinspectorprotocolRuntimejson"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/inspector/protocol/Runtime.json (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/inspector/protocol/Runtime.json        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/inspector/protocol/Runtime.json        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -111,6 +111,39 @@
</span><span class="cx">                 { &quot;name&quot;: &quot;startOffset&quot;, &quot;type&quot;: &quot;integer&quot;, &quot;description&quot;: &quot;Start offset of range (inclusive).&quot; },
</span><span class="cx">                 { &quot;name&quot;: &quot;endOffset&quot;, &quot;type&quot;: &quot;integer&quot;, &quot;description&quot;: &quot;End offset of range (exclusive).&quot; }
</span><span class="cx">             ]
</span><ins>+        },
+        {
+            &quot;id&quot;: &quot;StructureDescription&quot;,
+            &quot;type&quot;: &quot;object&quot;,
+            &quot;properties&quot;: [
+                { &quot;name&quot;: &quot;fields&quot;, &quot;type&quot;: &quot;array&quot;,  &quot;items&quot;: { &quot;type&quot;: &quot;string&quot; }, &quot;description&quot;: &quot;Array of strings, where the strings represent object properties.&quot; },
+                { &quot;name&quot;: &quot;constructorName&quot;, &quot;type&quot;: &quot;string&quot;, &quot;description&quot;: &quot;Name of the constructor.&quot; },
+                { &quot;name&quot;: &quot;prototypeStructure&quot;, &quot;$ref&quot;: &quot;StructureDescription&quot;, &quot;optional&quot;: &quot;true&quot;, &quot;description&quot;: &quot;Pointer to the StructureRepresentation of the protoype if one exists.&quot; }
+            ]
+        },
+        {
+            &quot;id&quot;: &quot;TypeDescription&quot;,
+            &quot;type&quot;: &quot;object&quot;,
+            &quot;description&quot;: &quot;Container for type information that has been gathered.&quot;,
+            &quot;properties&quot;: [
+                { &quot;name&quot;: &quot;displayTypeName&quot;, &quot;type&quot;: &quot;string&quot;, &quot;optional&quot;: true, &quot;description&quot;: &quot;What the inspector should display as a simple type.&quot; },
+                { &quot;name&quot;: &quot;localPrimitiveTypeNames&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;type&quot;: &quot;string&quot; }, &quot;optional&quot;: &quot;true&quot;, &quot;description&quot;: &quot;Array of type names for primtive types (int, string, etc) seen at an instruction&quot; },
+                { &quot;name&quot;: &quot;localObjectTypeNames&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;type&quot;: &quot;string&quot; }, &quot;optional&quot;: &quot;true&quot;, &quot;description&quot;: &quot;Array of type names for all object seen at an instruction&quot; },
+                { &quot;name&quot;: &quot;localStructures&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;$ref&quot;: &quot;StructureDescription&quot; }, &quot;optional&quot;: true, &quot;description&quot;: &quot;Array of descriptions for all structures seen at this this instruction.&quot; },
+                { &quot;name&quot;: &quot;globalPrimitiveTypeNames&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;type&quot;: &quot;string&quot; }, &quot;optional&quot;: true, &quot;description&quot;: &quot;Array of type names for all primitive types seen globally.&quot; },
+                { &quot;name&quot;: &quot;globalObjectTypeNames&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;type&quot;: &quot;string&quot; }, &quot;optional&quot;: true, &quot;description&quot;: &quot;Array of type names for all primitive types seen globally.&quot; },
+                { &quot;name&quot;: &quot;globalStructures&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;$ref&quot;: &quot;StructureDescription&quot; }, &quot;optional&quot;: true, &quot;description&quot;: &quot;Array of descriptions for all structures seen for this variable.&quot; }
+            ]
+        },
+        {
+            &quot;id&quot;: &quot;TypeLocation&quot;,
+            &quot;type&quot;: &quot;object&quot;,
+            &quot;description&quot;: &quot;Describes the location of an expression we want type information for.&quot;,
+            &quot;properties&quot;: [
+                { &quot;name&quot;: &quot;typeInformationDescriptor&quot;, &quot;type&quot;: &quot;integer&quot;, &quot;description&quot;: &quot;What kind of type information do we want (normal, function return values, 'this' statement).&quot; },
+                { &quot;name&quot;: &quot;sourceID&quot;, &quot;type&quot;: &quot;string&quot;, &quot;description&quot;: &quot;sourceID uniquely identifying a script&quot; },
+                { &quot;name&quot;: &quot;divot&quot;, &quot;type&quot;: &quot;integer&quot;, &quot;description&quot;: &quot;character offset for assignment range&quot; }
+            ]
</ins><span class="cx">         }
</span><span class="cx">     ],
</span><span class="cx">     &quot;commands&quot;: [
</span><span class="lines">@@ -198,14 +231,12 @@
</span><span class="cx">             &quot;description&quot;: &quot;Disables reporting of execution contexts creation.&quot;
</span><span class="cx">         },
</span><span class="cx">         {
</span><del>-            &quot;name&quot;: &quot;getRuntimeTypeForVariableAtOffset&quot;,
</del><ins>+            &quot;name&quot;: &quot;getRuntimeTypesForVariablesAtOffsets&quot;,
</ins><span class="cx">             &quot;parameters&quot;: [
</span><del>-                { &quot;name&quot;: &quot;variableName&quot;, &quot;type&quot;: &quot;string&quot;, &quot;description&quot;: &quot;Variable we want type infromation for.&quot; },
-                { &quot;name&quot;: &quot;sourceID&quot;, &quot;type&quot;: &quot;string&quot;, &quot;description&quot;: &quot;sourceID uniquely identifying a script&quot; },
-                { &quot;name&quot;: &quot;divot&quot;, &quot;type&quot;: &quot;integer&quot;, &quot;description&quot;: &quot;character offset for assignment range&quot; }
</del><ins>+                { &quot;name&quot;: &quot;locations&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;$ref&quot;: &quot;TypeLocation&quot; }, &quot;description&quot;: &quot;An array of type locations we're requesting information for. Results are expected in the same order they're sent in.&quot;}
</ins><span class="cx">             ],
</span><span class="cx">             &quot;returns&quot;: [
</span><del>-                { &quot;name&quot;: &quot;types&quot;, &quot;type&quot;: &quot;string&quot;, &quot;description&quot;: &quot;Types for requested variable.&quot; }
</del><ins>+                { &quot;name&quot;: &quot;types&quot;, &quot;type&quot;: &quot;array&quot;, &quot;item&quot;: { &quot;$ref&quot;: &quot;TypeDescription&quot;, &quot;description&quot;: &quot;Types for requested variable.&quot; } }
</ins><span class="cx">             ],
</span><span class="cx">             &quot;description&quot;: &quot;Returns detailed informtation on given function.&quot;
</span><span class="cx">         }
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeExecutablecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/Executable.cpp (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/Executable.cpp        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/Executable.cpp        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #include &quot;BytecodeGenerator.h&quot;
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><span class="cx"> #include &quot;DFGDriver.h&quot;
</span><ins>+#include &quot;HighFidelityTypeProfiler.h&quot;
</ins><span class="cx"> #include &quot;JIT.h&quot;
</span><span class="cx"> #include &quot;LLIntEntrypoint.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="lines">@@ -103,6 +104,8 @@
</span><span class="cx">     , m_lastLine(-1)
</span><span class="cx">     , m_startColumn(UINT_MAX)
</span><span class="cx">     , m_endColumn(UINT_MAX)
</span><ins>+    , m_highFidelityTypeProfilingStartOffset(UINT_MAX)
+    , m_highFidelityTypeProfilingEndOffset(UINT_MAX)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -379,6 +382,10 @@
</span><span class="cx"> ProgramExecutable::ProgramExecutable(ExecState* exec, const SourceCode&amp; source)
</span><span class="cx">     : ScriptExecutable(exec-&gt;vm().programExecutableStructure.get(), exec-&gt;vm(), source, false)
</span><span class="cx"> {
</span><ins>+    m_highFidelityTypeProfilingStartOffset = 0;
+    m_highFidelityTypeProfilingEndOffset = source.length() - 1;
+    if (exec-&gt;vm().isProfilingTypesWithHighFidelity())
+        exec-&gt;vm().highFidelityTypeProfiler()-&gt;functionHasExecutedCache()-&gt;insertUnexecutedRange(sourceID(), m_highFidelityTypeProfilingStartOffset, m_highFidelityTypeProfilingEndOffset);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ProgramExecutable::destroy(JSCell* cell)
</span><span class="lines">@@ -402,6 +409,8 @@
</span><span class="cx">     ASSERT(endColumn != UINT_MAX);
</span><span class="cx">     m_startColumn = startColumn;
</span><span class="cx">     m_endColumn = endColumn;
</span><ins>+    m_highFidelityTypeProfilingStartOffset = unlinkedExecutable-&gt;highFidelityTypeProfilingStartOffset();
+    m_highFidelityTypeProfilingEndOffset = unlinkedExecutable-&gt;highFidelityTypeProfilingEndOffset();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void FunctionExecutable::destroy(JSCell* cell)
</span><span class="lines">@@ -500,6 +509,11 @@
</span><span class="cx">         UnlinkedFunctionExecutable* unlinkedFunctionExecutable = functionDeclarations[i].second.get();
</span><span class="cx">         JSValue value = JSFunction::create(vm, unlinkedFunctionExecutable-&gt;link(vm, m_source, lineNo()), scope);
</span><span class="cx">         globalObject-&gt;addFunction(callFrame, functionDeclarations[i].first, value);
</span><ins>+        if (vm.isProfilingTypesWithHighFidelity()) {
+            vm.highFidelityTypeProfiler()-&gt;functionHasExecutedCache()-&gt;insertUnexecutedRange(sourceID(), 
+                unlinkedFunctionExecutable-&gt;highFidelityTypeProfilingStartOffset(), 
+                unlinkedFunctionExecutable-&gt;highFidelityTypeProfilingEndOffset());
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     for (size_t i = 0; i &lt; variableDeclarations.size(); ++i) {
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeExecutableh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/Executable.h (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/Executable.h        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/Executable.h        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -365,6 +365,8 @@
</span><span class="cx">     int lastLine() const { return m_lastLine; }
</span><span class="cx">     unsigned startColumn() const { return m_startColumn; }
</span><span class="cx">     unsigned endColumn() const { return m_endColumn; }
</span><ins>+    unsigned highFidelityTypeProfilingStartOffset() const { return m_highFidelityTypeProfilingStartOffset; }
+    unsigned highFidelityTypeProfilingEndOffset() const { return m_highFidelityTypeProfilingEndOffset; }
</ins><span class="cx"> 
</span><span class="cx">     bool usesEval() const { return m_features &amp; EvalFeature; }
</span><span class="cx">     bool usesArguments() const { return m_features &amp; ArgumentsFeature; }
</span><span class="lines">@@ -435,6 +437,8 @@
</span><span class="cx">     int m_lastLine;
</span><span class="cx">     unsigned m_startColumn;
</span><span class="cx">     unsigned m_endColumn;
</span><ins>+    unsigned m_highFidelityTypeProfilingStartOffset;
+    unsigned m_highFidelityTypeProfilingEndOffset;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class EvalExecutable : public ScriptExecutable {
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeFunctionHasExecutedCachecpp"></a>
<div class="addfile"><h4>Added: branches/ftlopt/Source/JavaScriptCore/runtime/FunctionHasExecutedCache.cpp (0 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/FunctionHasExecutedCache.cpp                                (rev 0)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/FunctionHasExecutedCache.cpp        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -0,0 +1,81 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;FunctionHasExecutedCache.h&quot;
+
+namespace JSC {
+
+bool FunctionHasExecutedCache::hasExecutedAtOffset(intptr_t id, unsigned offset)
+{
+    if (m_rangeMap.find(id) == m_rangeMap.end())
+        return false;
+
+    RangeMap&amp; map = m_rangeMap.find(id)-&gt;second;
+    unsigned distance = UINT_MAX;
+    bool hasExecuted = false;
+    for (auto iter = map.begin(), end = map.end(); iter != end; ++iter) {
+        const FunctionRange&amp; range = iter-&gt;first;
+        if (range.m_start &lt;= offset &amp;&amp; offset &lt;= range.m_end &amp;&amp; range.m_end - range.m_start &lt; distance) {
+            hasExecuted = iter-&gt;second;
+            distance = range.m_end - range.m_start;
+        }
+    }
+
+    return hasExecuted;
+}
+
+void FunctionHasExecutedCache::insertUnexecutedRange(intptr_t id, unsigned start, unsigned end) 
+{
+    if (m_rangeMap.find(id) == m_rangeMap.end()) {
+        RangeMap map;
+        m_rangeMap[id] = map;
+    }
+
+    RangeMap&amp; map = m_rangeMap.find(id)-&gt;second;
+    FunctionRange range;
+    range.m_start = start;
+    range.m_end = end;
+    // Only insert unexecuted ranges once for a given sourceID because we may run into a situation where an executable executes, then is GCed, and then is allocated again,
+    // and tries to reinsert itself, claiming it has never run, but this is false because it indeed already executed.
+    if (map.find(range) == map.end())
+        map[range] = false;
+}
+
+void FunctionHasExecutedCache::removeUnexecutedRange(intptr_t id, unsigned start, unsigned end)
+{
+    // FIXME: We should never have an instance where we return here, but currently do in some situations. Find out why.
+    if (m_rangeMap.find(id) == m_rangeMap.end())
+        return;
+
+    RangeMap&amp; map = m_rangeMap.find(id)-&gt;second;
+
+    FunctionRange range;
+    range.m_start = start;
+    range.m_end = end;
+    map[range] = true;
+}
+
+} // namespace JSC
</ins></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeFunctionHasExecutedCacheh"></a>
<div class="addfile"><h4>Added: branches/ftlopt/Source/JavaScriptCore/runtime/FunctionHasExecutedCache.h (0 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/FunctionHasExecutedCache.h                                (rev 0)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/FunctionHasExecutedCache.h        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -0,0 +1,63 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FunctionHasExecutedCache_h
+#define FunctionHasExecutedCache_h
+
+#include &lt;unordered_map&gt;
+#include &lt;wtf/HashMethod.h&gt;
+
+namespace JSC {
+
+class FunctionHasExecutedCache {
+public:
+    struct FunctionRange {
+        FunctionRange() {}
+        bool operator==(const FunctionRange&amp; other) const 
+        {
+            return m_start == other.m_start &amp;&amp; m_end == other.m_end;
+        }
+        unsigned hash() const
+        {
+            return m_start * m_end;
+        }
+
+        unsigned m_start;
+        unsigned m_end;
+    };
+
+    bool hasExecutedAtOffset(intptr_t id, unsigned offset);
+    void insertUnexecutedRange(intptr_t id, unsigned start, unsigned end);
+    void removeUnexecutedRange(intptr_t id, unsigned start, unsigned end);
+
+private:     
+    typedef std::unordered_map&lt;FunctionRange, bool, HashMethod&lt;FunctionRange&gt;&gt; RangeMap;
+    typedef std::unordered_map&lt;intptr_t, RangeMap&gt; SourceIDToRangeMap;
+    SourceIDToRangeMap m_rangeMap;
+};
+
+} // namespace JSC
+
+#endif // FunctionHasExecutedCache_h
</ins></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeHighFidelityLogcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityLog.cpp (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityLog.cpp        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityLog.cpp        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -53,45 +53,25 @@
</span><span class="cx">     delete[] m_nextBuffer;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void HighFidelityLog::processHighFidelityLog(bool asynchronously, String reason)
</del><ins>+void HighFidelityLog::processHighFidelityLog(String reason)
</ins><span class="cx"> {
</span><del>-    // This should only be called from the main execution thread.
</del><span class="cx">     if (!m_currentOffset)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     if (verbose)
</span><span class="cx">         dataLog(&quot;Process caller:'&quot;, reason,&quot;'&quot;);
</span><span class="cx"> 
</span><del>-    ByteSpinLocker* locker = new ByteSpinLocker(m_lock);
-    ThreadData* data = new ThreadData;
-    data-&gt;m_proccessLogToOffset = m_currentOffset;
-    data-&gt;m_processLogPtr = m_logStartPtr;
-    data-&gt;m_locker = locker;
-
-    m_currentOffset = 0;
-    std::swap(m_logStartPtr, m_nextBuffer);
-    
-    if (asynchronously)
-        createThread(actuallyProcessLogThreadFunction, data, &quot;ProcessHighFidelityLog&quot;);
-    else 
-        actuallyProcessLogThreadFunction(data);
-}
-
-void HighFidelityLog::actuallyProcessLogThreadFunction(void* arg)
-{
</del><span class="cx">     double before = currentTimeMS();
</span><del>-    ThreadData* data = static_cast&lt;ThreadData*&gt;(arg);
-    LogEntry* entry = data-&gt;m_processLogPtr;
</del><ins>+    LogEntry* entry = m_logStartPtr;
</ins><span class="cx">     HashMap&lt;StructureID, RefPtr&lt;StructureShape&gt;&gt; seenShapes;
</span><del>-    size_t processLogToOffset = data-&gt;m_proccessLogToOffset; 
</del><span class="cx">     size_t i = 0;
</span><del>-    while (i &lt; processLogToOffset) {
</del><ins>+    while (i &lt; m_currentOffset) {
</ins><span class="cx">         StructureID id = entry-&gt;structureID;
</span><span class="cx">         RefPtr&lt;StructureShape&gt; shape; 
</span><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 = entry-&gt;value.asCell()-&gt;structure()-&gt;toStructureShape();
</del><ins>+                shape = Heap::heap(entry-&gt;value.asCell())-&gt;structureIDTable().get(entry-&gt;structureID)-&gt;toStructureShape(entry-&gt;value);
</ins><span class="cx">                 seenShapes.set(id, shape);
</span><span class="cx">             } else 
</span><span class="cx">                 shape = iter-&gt;value;
</span><span class="lines">@@ -105,11 +85,12 @@
</span><span class="cx">         i++;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    delete data-&gt;m_locker;
-    delete data;
-    double after = currentTimeMS();
-    if (verbose)
</del><ins>+    m_currentOffset = 0;
+
+    if (verbose) {
+        double after = currentTimeMS();
</ins><span class="cx">         dataLogF(&quot; Processing the log took: '%f' ms\n&quot;, after - before);
</span><ins>+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } //namespace JSC
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeHighFidelityLogh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityLog.h (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityLog.h        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityLog.h        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -69,14 +69,13 @@
</span><span class="cx">     
</span><span class="cx">         m_currentOffset += 1;
</span><span class="cx">         if (m_currentOffset == m_highFidelityLogSize)
</span><del>-            processHighFidelityLog(true, &quot;Log Full&quot;);
</del><ins>+            processHighFidelityLog(&quot;Log Full&quot;);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void processHighFidelityLog(bool asynchronously = false, String = &quot;&quot;);
</del><ins>+    void processHighFidelityLog(String);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     void initializeHighFidelityLog();
</span><del>-    static void actuallyProcessLogThreadFunction(void*);
</del><span class="cx"> 
</span><span class="cx">     unsigned m_highFidelityLogSize;
</span><span class="cx">     size_t m_currentOffset;
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeHighFidelityTypeProfilercpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.cpp (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.cpp        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.cpp        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -26,40 +26,33 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;HighFidelityTypeProfiler.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;InspectorJSTypeBuilders.h&quot;
</ins><span class="cx"> #include &quot;TypeLocation.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx"> static const bool verbose = false;
</span><span class="cx"> 
</span><del>-String HighFidelityTypeProfiler::getTypesForVariableInAtOffset(unsigned divot, const String&amp; variableName, intptr_t sourceID)
</del><ins>+void HighFidelityTypeProfiler::logTypesForTypeLocation(TypeLocation* location)
</ins><span class="cx"> {
</span><del>-    String global = getGlobalTypesForVariableAtOffset(divot, variableName, sourceID);
-    if (!global.isEmpty())
-        return global;
-    
-    return getLocalTypesForVariableAtOffset(divot, variableName, sourceID);
-}
</del><ins>+    TypeProfilerSearchDescriptor descriptor = location-&gt;m_globalVariableID == HighFidelityReturnStatement ? TypeProfilerSearchDescriptorFunctionReturn
+        : location-&gt;m_globalVariableID == HighFidelityThisStatement ? TypeProfilerSearchDescriptorThisStatement
+        : TypeProfilerSearchDescriptorNormal;
</ins><span class="cx"> 
</span><del>-String HighFidelityTypeProfiler::getGlobalTypesForVariableAtOffset(unsigned divot, const String&amp; , intptr_t sourceID)
-{
-    TypeLocation* location = findLocation(divot, sourceID);
-    if (!location)
-        return  &quot;&quot;;
</del><ins>+    dataLogF(&quot;[Start, End]::[%u, %u]\n&quot;, location-&gt;m_divotStart, location-&gt;m_divotEnd);
</ins><span class="cx"> 
</span><del>-    if (location-&gt;m_globalVariableID == HighFidelityNoGlobalIDExists)
-        return &quot;&quot;;
</del><ins>+    if (findLocation(location-&gt;m_divotStart, location-&gt;m_sourceID, descriptor))
+        dataLog(&quot;\t\t[Entry IS in System]\n&quot;);
+    else
+        dataLog(&quot;\t\t[Entry IS NOT in system]\n&quot;);
</ins><span class="cx"> 
</span><del>-    return location-&gt;m_globalTypeSet-&gt;seenTypes();
-}
</del><ins>+    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;);
</ins><span class="cx"> 
</span><del>-String HighFidelityTypeProfiler::getLocalTypesForVariableAtOffset(unsigned divot, const String&amp; , intptr_t sourceID)
-{
-    TypeLocation* location = findLocation(divot, sourceID);
-    if (!location)
-        return  &quot;&quot;;
-
-    return location-&gt;m_instructionTypeSet-&gt;seenTypes();
</del><ins>+    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;);
+    if (location-&gt;m_globalTypeSet)
+        dataLog(&quot;\t\t#Global#\n\t\t&quot;, location-&gt;m_globalTypeSet-&gt;seenTypes().replace(&quot;\n&quot;, &quot;\n\t\t&quot;), &quot;\n&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HighFidelityTypeProfiler::insertNewLocation(TypeLocation* location)
</span><span class="lines">@@ -76,22 +69,67 @@
</span><span class="cx">     bucket.append(location);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TypeLocation* HighFidelityTypeProfiler::findLocation(unsigned divot, intptr_t sourceID)
</del><ins>+void HighFidelityTypeProfiler::getTypesForVariableAtOffsetForInspector(TypeProfilerSearchDescriptor descriptor, unsigned divot, intptr_t sourceID, RefPtr&lt;Inspector::InspectorObject&gt;&amp; ret)
</ins><span class="cx"> {
</span><del>-    ASSERT(m_bucketMap.contains(sourceID)); 
</del><ins>+    TypeLocation* location = findLocation(divot, sourceID, descriptor);
+    if (!location)
+        return;
</ins><span class="cx"> 
</span><ins>+    if (location-&gt;m_globalTypeSet &amp;&amp; location-&gt;m_globalVariableID != HighFidelityNoGlobalIDExists) {
+        ret-&gt;setString(ASCIILiteral(&quot;displayTypeName&quot;), location-&gt;m_globalTypeSet-&gt;displayName());
+        ret-&gt;setArray(ASCIILiteral(&quot;globalPrimitiveTypeNames&quot;), location-&gt;m_globalTypeSet-&gt;allPrimitiveTypeNames()-&gt;asArray());
+        ret-&gt;setArray(ASCIILiteral(&quot;globalStructures&quot;), location-&gt;m_globalTypeSet-&gt;allStructureRepresentations()-&gt;asArray());
+    } else
+        ret-&gt;setString(ASCIILiteral(&quot;displayTypeName&quot;), location-&gt;m_instructionTypeSet-&gt;displayName());
+
+    ret-&gt;setArray(ASCIILiteral(&quot;localPrimitiveTypeNames&quot;), location-&gt;m_instructionTypeSet-&gt;allPrimitiveTypeNames()-&gt;asArray());
+    ret-&gt;setArray(ASCIILiteral(&quot;localStructures&quot;), location-&gt;m_instructionTypeSet-&gt;allStructureRepresentations()-&gt;asArray());
+}
+
+static bool descriptorMatchesTypeLocation(TypeProfilerSearchDescriptor descriptor, TypeLocation* location)
+{
+    if (descriptor == TypeProfilerSearchDescriptorFunctionReturn &amp;&amp; location-&gt;m_globalVariableID == HighFidelityReturnStatement)  
+        return true;
+
+    if (descriptor == TypeProfilerSearchDescriptorThisStatement &amp;&amp; location-&gt;m_globalVariableID == HighFidelityThisStatement)  
+        return true;
+
+    if (descriptor == TypeProfilerSearchDescriptorNormal &amp;&amp; location-&gt;m_globalVariableID != HighFidelityReturnStatement &amp;&amp; location-&gt;m_globalVariableID != HighFidelityThisStatement)  
+        return true;
+
+    return false;
+}
+
+TypeLocation* HighFidelityTypeProfiler::findLocation(unsigned divot, intptr_t sourceID, TypeProfilerSearchDescriptor descriptor)
+{
+    QueryKey queryKey(sourceID, divot);
+    auto iter = m_queryCache.find(queryKey);
+    if (iter != m_queryCache.end())
+        return iter-&gt;value;
+
+    if (!m_functionHasExecutedCache.hasExecutedAtOffset(sourceID, divot))
+        return nullptr;
+
+    ASSERT(m_bucketMap.contains(sourceID));
+
</ins><span class="cx">     Vector&lt;TypeLocation*&gt;&amp; bucket = m_bucketMap.find(sourceID)-&gt;value;
</span><ins>+    TypeLocation* bestMatch = nullptr;
</ins><span class="cx">     unsigned distance = UINT_MAX; // Because assignments may be nested, make sure we find the closest enclosing assignment to this character offset.
</span><del>-    TypeLocation* bestMatch = nullptr;
</del><span class="cx">     for (size_t i = 0, size = bucket.size(); i &lt; size; i++) {
</span><span class="cx">         TypeLocation* location = bucket.at(i);
</span><del>-        if (location-&gt;m_divotStart &lt;= divot &amp;&amp; divot &lt;= location-&gt;m_divotEnd &amp;&amp; location-&gt;m_divotEnd - location-&gt;m_divotStart &lt;= distance) {
</del><ins>+        if (descriptor == TypeProfilerSearchDescriptorFunctionReturn &amp;&amp; descriptorMatchesTypeLocation(descriptor, location) &amp;&amp; location-&gt;m_divotForFunctionOffsetIfReturnStatement == divot)
+            return location;
+
+        if (location-&gt;m_divotStart &lt;= divot &amp;&amp; divot &lt;= location-&gt;m_divotEnd &amp;&amp; location-&gt;m_divotEnd - location-&gt;m_divotStart &lt;= distance &amp;&amp; descriptorMatchesTypeLocation(descriptor, location)) {
</ins><span class="cx">             distance = location-&gt;m_divotEnd - location-&gt;m_divotStart;
</span><span class="cx">             bestMatch = location;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // FIXME: BestMatch should never be null. This doesn't hold currently because we ignore some Eval/With/VarInjection variable assignments.
</del><ins>+    if (bestMatch)
+        m_queryCache.set(queryKey, bestMatch);
+    // FIXME: BestMatch should never be null past this point. This doesn't hold currently because we ignore var assignments when code contains eval/With (VarInjection). 
+    // https://bugs.webkit.org/show_bug.cgi?id=135184
</ins><span class="cx">     return bestMatch;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeHighFidelityTypeProfilerh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.h (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.h        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.h        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -27,31 +27,93 @@
</span><span class="cx"> #define HighFidelityTypeProfiler_h
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><del>-#include &lt;unordered_map&gt;
</del><ins>+#include &quot;FunctionHasExecutedCache.h&quot;
+#include &quot;TypeLocationCache.h&quot;
</ins><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><del>-#include &lt;wtf/HashMethod.h&gt;
</del><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> 
</span><ins>+namespace Inspector { namespace TypeBuilder  { namespace Runtime {
+class TypeDescription;
+}}}
+namespace Inspector {
+class InspectorObject;
+}
+
</ins><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx"> class TypeLocation;
</span><span class="cx"> 
</span><ins>+struct QueryKey {
+    QueryKey()
+        : m_sourceID(0)
+        , m_divot(0)
+    { }
+
+    QueryKey(intptr_t sourceID, unsigned divot)
+        : m_sourceID(sourceID)
+        , m_divot(divot)
+    { }
+
+    QueryKey(WTF::HashTableDeletedValueType)
+        : m_sourceID(INTPTR_MAX)
+        , m_divot(UINT_MAX)
+    { }
+
+    bool isHashTableDeletedValue() const { return m_sourceID == INTPTR_MAX &amp;&amp; m_divot == UINT_MAX; }
+    bool operator==(const QueryKey&amp; other) const { return m_sourceID == other.m_sourceID &amp;&amp; m_divot == other.m_divot; }
+    unsigned hash() const { return m_sourceID + m_divot; }
+
+    intptr_t m_sourceID;
+    unsigned m_divot;
+};
+
+struct QueryKeyHash {
+    static unsigned hash(const QueryKey&amp; key) { return key.hash(); }
+    static bool equal(const QueryKey&amp; a, const QueryKey&amp; b) { return a == b; }
+    static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} //namespace JSC
+
+namespace WTF {
+
+template&lt;typename T&gt; struct DefaultHash;
+template&lt;&gt; struct DefaultHash&lt;JSC::QueryKey&gt; {
+    typedef JSC::QueryKeyHash Hash;
+};
+
+template&lt;typename T&gt; struct HashTraits;
+template&lt;&gt; struct HashTraits&lt;JSC::QueryKey&gt; : SimpleClassHashTraits&lt;JSC::QueryKey&gt; { };
+
+} // namespace WTF
+
+namespace JSC {
+
+enum TypeProfilerSearchDescriptor {
+    TypeProfilerSearchDescriptorNormal = 1,
+    TypeProfilerSearchDescriptorThisStatement = 2,
+    TypeProfilerSearchDescriptorFunctionReturn = 3
+};
+
</ins><span class="cx"> class HighFidelityTypeProfiler {
</span><del>-
</del><span class="cx"> public:
</span><del>-    String getTypesForVariableInAtOffset(unsigned divot, const String&amp; variableName, intptr_t sourceID);
-    String getGlobalTypesForVariableAtOffset(unsigned divot, const String&amp; variableName, intptr_t sourceID);
-    String getLocalTypesForVariableAtOffset(unsigned divot, const String&amp; variableName, intptr_t sourceID);
</del><ins>+    void logTypesForTypeLocation(TypeLocation*);
+    void getTypesForVariableAtOffsetForInspector(TypeProfilerSearchDescriptor descriptor, unsigned divot, intptr_t sourceID, RefPtr&lt;Inspector::InspectorObject&gt;&amp;);
</ins><span class="cx">     void insertNewLocation(TypeLocation*);
</span><ins>+    FunctionHasExecutedCache* functionHasExecutedCache() { return &amp;m_functionHasExecutedCache; }
+    TypeLocationCache* typeLocationCache() { return &amp;m_typeLocationCache; }
</ins><span class="cx">     
</span><span class="cx"> private:
</span><del>-    TypeLocation* findLocation(unsigned divot, intptr_t sourceID);
-
</del><ins>+    TypeLocation* findLocation(unsigned divot, intptr_t sourceID, TypeProfilerSearchDescriptor descriptor);
</ins><span class="cx">     typedef HashMap&lt;intptr_t, Vector&lt;TypeLocation*&gt;&gt; SourceIDToLocationBucketMap;
</span><span class="cx">     SourceIDToLocationBucketMap m_bucketMap;
</span><ins>+    FunctionHasExecutedCache m_functionHasExecutedCache;
+    TypeLocationCache m_typeLocationCache;
+    typedef HashMap&lt;QueryKey, TypeLocation*&gt; TypeLocationQueryCache;
+    TypeLocationQueryCache m_queryCache;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-} //namespace JSC
</del><ins>+} // namespace JSC
</ins><span class="cx"> 
</span><span class="cx"> #endif //HighFidelityTypeProfiler_h
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeStructurecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/Structure.cpp (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/Structure.cpp        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/Structure.cpp        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -1048,36 +1048,73 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-
-PassRefPtr&lt;StructureShape&gt; Structure::toStructureShape()
</del><ins>+PassRefPtr&lt;StructureShape&gt; Structure::toStructureShape(JSValue value)
</ins><span class="cx"> {
</span><del>-    Vector&lt;Structure*, 8&gt; structures;
-    Structure* structure;
-    PropertyTable* table;
-    RefPtr&lt;StructureShape&gt; shape = StructureShape::create();
</del><ins>+    RefPtr&lt;StructureShape&gt; baseShape = StructureShape::create();
+    RefPtr&lt;StructureShape&gt; curShape = baseShape;
+    Structure* curStructure = this;
+    JSValue curValue = value;
+    while (curStructure) {
+        Vector&lt;Structure*, 8&gt; structures;
+        Structure* structure;
+        PropertyTable* table;
</ins><span class="cx"> 
</span><del>-    findStructuresAndMapForMaterialization(structures, structure, table);
-    
-    if (table) {
-        PropertyTable::iterator iter = table-&gt;begin();
-        PropertyTable::iterator end = table-&gt;end();
</del><ins>+        curStructure-&gt;findStructuresAndMapForMaterialization(structures, structure, table);
+        if (table) {
+            PropertyTable::iterator iter = table-&gt;begin();
+            PropertyTable::iterator end = table-&gt;end();
+            for (; iter != end; ++iter)
+                curShape-&gt;addProperty(iter-&gt;key);
+            
+            structure-&gt;m_lock.unlock();
+        }
+        for (unsigned i = structures.size(); i--;) {
+            Structure* structure = structures[i];
+            if (structure-&gt;m_nameInPrevious)
+                curShape-&gt;addProperty(structure-&gt;m_nameInPrevious.get());
+        }
</ins><span class="cx"> 
</span><del>-        for (; iter != end; ++iter)
-            shape-&gt;addProperty(iter-&gt;key);
-        
-        structure-&gt;m_lock.unlock();
</del><ins>+        bool foundCtorName = false;
+        if (JSObject* profilingVal = curValue.getObject()) {
+            ExecState* exec = profilingVal-&gt;globalObject()-&gt;globalExec();
+            PropertySlot slot(storedPrototype());
+            PropertyName constructor(exec-&gt;propertyNames().constructor);
+            if (profilingVal-&gt;getPropertySlot(exec, constructor, slot)) {
+                if (slot.isValue()) {
+                    JSValue constructorValue = slot.getValue(exec, constructor);
+                    if (constructorValue.isCell()) {
+                        if (JSCell* constructorCell = constructorValue.asCell()) {
+                            if (JSObject* ctorObject = constructorCell-&gt;getObject()) {
+                                if (JSFunction* constructorFunction = jsDynamicCast&lt;JSFunction*&gt;(ctorObject)) {
+                                    curShape-&gt;setConstructorName(constructorFunction-&gt;calculatedDisplayName(exec));
+                                    foundCtorName = true;
+                                } else if (InternalFunction* constructorFunction = jsDynamicCast&lt;InternalFunction*&gt;(ctorObject)) {
+                                    curShape-&gt;setConstructorName(constructorFunction-&gt;calculatedDisplayName(exec));
+                                    foundCtorName = true;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        if (!foundCtorName)
+            curShape-&gt;setConstructorName(curStructure-&gt;classInfo()-&gt;className);
+
+        curShape-&gt;markAsFinal();
+
+        if (curStructure-&gt;storedPrototypeStructure()) {
+            RefPtr&lt;StructureShape&gt; newShape = StructureShape::create();
+            curShape-&gt;setProto(newShape);
+            curShape = newShape;
+            curValue = curStructure-&gt;storedPrototype();
+        }
+
+        curStructure = curStructure-&gt;storedPrototypeStructure();
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    for (unsigned i = structures.size(); i--;) {
-        Structure* structure = structures[i];
-        if (!structure-&gt;m_nameInPrevious)
-            continue;
-
-        shape-&gt;addProperty(structure-&gt;m_nameInPrevious.get());
-    }
-
-    shape-&gt;markAsFinal();
-    return shape.release();
</del><ins>+    return baseShape.release();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Structure::dump(PrintStream&amp; out) const
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeStructureh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/Structure.h (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/Structure.h        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/Structure.h        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -390,7 +390,7 @@
</span><span class="cx">             structure-&gt;startWatchingInternalPropertiesIfNecessary(vm);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    PassRefPtr&lt;StructureShape&gt; toStructureShape();
</del><ins>+    PassRefPtr&lt;StructureShape&gt; toStructureShape(JSValue);
</ins><span class="cx">     
</span><span class="cx">     void dump(PrintStream&amp;) const;
</span><span class="cx">     void dumpInContext(PrintStream&amp;, DumpContext*) const;
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeTypeLocationCachecpp"></a>
<div class="addfile"><h4>Added: branches/ftlopt/Source/JavaScriptCore/runtime/TypeLocationCache.cpp (0 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/TypeLocationCache.cpp                                (rev 0)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/TypeLocationCache.cpp        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include &quot;config.h&quot;
+#include &quot;TypeLocationCache.h&quot;
+
+#include &quot;VM.h&quot;
+
+namespace JSC {
+
+std::pair&lt;TypeLocation*, bool&gt; TypeLocationCache::getTypeLocation(int64_t globalVariableID, intptr_t sourceID, unsigned start, unsigned end, PassRefPtr&lt;TypeSet&gt; globalTypeSet, VM* vm)
+{
+    LocationKey key;
+    key.m_globalVariableID = globalVariableID;
+    key.m_sourceID = sourceID;
+    key.m_start = start;
+    key.m_end = end;
+
+    bool isNewLocation = false;
+    if (m_locationMap.find(key) == m_locationMap.end()) {
+        TypeLocation* location = vm-&gt;nextLocation();
+        location-&gt;m_globalVariableID = globalVariableID;
+        location-&gt;m_sourceID = sourceID;
+        location-&gt;m_divotStart = start;
+        location-&gt;m_divotEnd = end;
+        location-&gt;m_globalTypeSet = globalTypeSet;
+
+        m_locationMap[key] = location;
+        isNewLocation = true;
+    }
+
+    TypeLocation* location = m_locationMap.find(key)-&gt;second;
+    return std::pair&lt;TypeLocation*, bool&gt;(location, isNewLocation);
+}
+
+} // namespace JSC
</ins></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeTypeLocationCacheh"></a>
<div class="addfile"><h4>Added: branches/ftlopt/Source/JavaScriptCore/runtime/TypeLocationCache.h (0 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/TypeLocationCache.h                                (rev 0)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/TypeLocationCache.h        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -0,0 +1,68 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TypeLocationCache_h
+#define TypeLocationCache_h
+
+#include &quot;TypeLocation.h&quot;
+#include &lt;unordered_map&gt;
+#include &lt;wtf/HashMethod.h&gt;
+
+namespace JSC {
+
+class VM;
+
+class TypeLocationCache {
+public:
+    struct LocationKey {
+        LocationKey() {}
+        bool operator==(const LocationKey&amp; other) const 
+        {
+            return m_globalVariableID == other.m_globalVariableID
+                &amp;&amp; m_sourceID == other.m_sourceID
+                &amp;&amp; m_start == other.m_start
+                &amp;&amp; m_end == other.m_end;
+        }
+
+        unsigned hash() const
+        {
+            return m_globalVariableID + m_sourceID + m_start + m_end;
+        }
+
+        int64_t m_globalVariableID;
+        intptr_t m_sourceID;
+        unsigned m_start;
+        unsigned m_end;
+    };
+
+    std::pair&lt;TypeLocation*, bool&gt; getTypeLocation(int64_t, intptr_t, unsigned start, unsigned end, PassRefPtr&lt;TypeSet&gt;, VM*);
+private:     
+    typedef std::unordered_map&lt;LocationKey, TypeLocation*, HashMethod&lt;LocationKey&gt;&gt; LocationMap;
+    LocationMap m_locationMap;
+};
+
+} // namespace JSC
+
+#endif // TypeLocationCache_h
</ins></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeTypeSetcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/TypeSet.cpp (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/TypeSet.cpp        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/TypeSet.cpp        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;TypeSet.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;InspectorJSTypeBuilders.h&quot;
</ins><span class="cx"> #include &quot;JSCJSValue.h&quot;
</span><span class="cx"> #include &quot;JSCJSValueInlines.h&quot;
</span><span class="cx"> #include &lt;wtf/text/CString.h&gt;
</span><span class="lines">@@ -58,8 +59,6 @@
</span><span class="cx">         ret = TypeNumber;
</span><span class="cx">     else if (v.isString())
</span><span class="cx">         ret = TypeString;
</span><del>-    else if (v.isPrimitive())
-        ret = TypePrimitive;
</del><span class="cx">     else if (v.isObject())
</span><span class="cx">         ret = TypeObject;
</span><span class="cx">     else
</span><span class="lines">@@ -73,7 +72,7 @@
</span><span class="cx">     RuntimeType t = getRuntimeTypeForValue(v);
</span><span class="cx">     m_seenTypes = m_seenTypes | t;
</span><span class="cx"> 
</span><del>-    if (id &amp;&amp; shape) {
</del><ins>+    if (id &amp;&amp; shape &amp;&amp; !v.isString() &amp;&amp; !v.isFunction()) {
</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">@@ -95,7 +94,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-String TypeSet::seenTypes() 
</del><ins>+String TypeSet::seenTypes() const
</ins><span class="cx"> {
</span><span class="cx">     if (m_seenTypes == TypeNothing)
</span><span class="cx">         return &quot;(Unreached Statement)&quot;;
</span><span class="lines">@@ -116,17 +115,13 @@
</span><span class="cx">          seen.append(&quot;Number &quot;);
</span><span class="cx">     if (m_seenTypes &amp; TypeString)
</span><span class="cx">          seen.append(&quot;String &quot;);
</span><del>-    if (m_seenTypes &amp; TypePrimitive)
-         seen.append(&quot;Primitive &quot;);
</del><span class="cx">     if (m_seenTypes &amp; TypeObject)
</span><span class="cx">          seen.append(&quot;Object &quot;);
</span><span class="cx"> 
</span><span class="cx">     for (size_t i = 0; i &lt; m_structureHistory-&gt;size(); i++) {
</span><span class="cx">         RefPtr&lt;StructureShape&gt; shape = m_structureHistory-&gt;at(i);
</span><del>-        if (!shape-&gt;m_constructorName.isEmpty()) {
-            seen.append(shape-&gt;m_constructorName);
-            seen.append(&quot; &quot;);
-        }
</del><ins>+        seen.append(shape-&gt;m_constructorName);
+        seen.append(&quot; &quot;);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (m_structureHistory-&gt;size()) 
</span><span class="lines">@@ -139,20 +134,131 @@
</span><span class="cx">         seen.append(&quot;]&quot;);
</span><span class="cx"> 
</span><span class="cx">     if (m_structureHistory-&gt;size()) {
</span><del>-        seen.append(&quot;\nLUB: &quot;);
-        seen.append(StructureShape::leastUpperBound(m_structureHistory));
</del><ins>+        seen.append(&quot;\nLeast Common Ancestor: &quot;);
+        seen.append(leastCommonAncestor());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return seen.toString();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool TypeSet::doesTypeConformTo(uint32_t test) const
+{
+    // This function checks if our seen types conform  to the types described by the test bitstring. (i.e we haven't seen more types than test).
+    // We are &lt;= to those types if ANDing with the bitstring doesn't zero out any of our bits.
+
+    // For example:
+
+    // 0b0110 (seen)
+    // 0b1111 (test)
+    // ------ (AND)
+    // 0b0110 == seen
+
+    // 0b0110 (seen)
+    // 0b0010 (test)
+    // ------ (AND)
+    // 0b0010 != seen
+
+    return (m_seenTypes &amp; test) == m_seenTypes;
+}
+
+String TypeSet::displayName() const
+{
+    if (m_seenTypes == TypeNothing)
+        return &quot;&quot;;
+
+    if (m_structureHistory-&gt;size() &amp;&amp; doesTypeConformTo(TypeObject | TypeNull | TypeUndefined)) {
+        String ctorName = leastCommonAncestor(); 
+
+        if (doesTypeConformTo(TypeObject))
+            return ctorName;
+        else if (doesTypeConformTo(TypeObject | TypeNull | TypeUndefined))
+            return ctorName + &quot;?&quot;;
+    }
+
+    // The order of these checks are important. For example, if a value is only a function, it conforms to TypeFunction, but it also conforms to TypeFunction | TypeNull.
+    // Therefore, more specific types must be checked first.
+
+    if (doesTypeConformTo(TypeFunction))
+        return &quot;Function&quot;;
+    if (doesTypeConformTo(TypeUndefined))
+        return &quot;Undefined&quot;;
+    if (doesTypeConformTo(TypeNull))
+        return &quot;Null&quot;;
+    if (doesTypeConformTo(TypeBoolean))
+        return &quot;Boolean&quot;;
+    if (doesTypeConformTo(TypeMachineInt))
+        return &quot;Integer&quot;;
+    if (doesTypeConformTo(TypeNumber | TypeMachineInt))
+        return &quot;Number&quot;;
+    if (doesTypeConformTo(TypeString))
+        return &quot;String&quot;;
+
+    if (doesTypeConformTo(TypeNull | TypeUndefined))
+        return &quot;(?)&quot;;
+
+    if (doesTypeConformTo(TypeFunction | TypeNull | TypeUndefined))
+        return &quot;Function?&quot;;
+    if (doesTypeConformTo(TypeBoolean | TypeNull | TypeUndefined))
+        return &quot;Boolean?&quot;;
+    if (doesTypeConformTo(TypeMachineInt | TypeNull | TypeUndefined))
+        return &quot;Integer?&quot;;
+    if (doesTypeConformTo(TypeNumber | TypeMachineInt | TypeNull | TypeUndefined))
+        return &quot;Number?&quot;;
+    if (doesTypeConformTo(TypeString | TypeNull | TypeUndefined))
+        return &quot;String?&quot;;
+   
+    if (doesTypeConformTo(TypeObject | TypeFunction | TypeString))
+        return &quot;Object&quot;;
+    if (doesTypeConformTo(TypeObject | TypeFunction | TypeString | TypeNull | TypeUndefined))
+        return &quot;Object?&quot;;
+
+    return &quot;(many)&quot;;
+}
+
+PassRefPtr&lt;Inspector::TypeBuilder::Array&lt;String&gt;&gt; TypeSet::allPrimitiveTypeNames() const
+{
+    RefPtr&lt;Inspector::TypeBuilder::Array&lt;String&gt;&gt; seen = Inspector::TypeBuilder::Array&lt;String&gt;::create();
+    if (m_seenTypes &amp; TypeFunction)
+         seen-&gt;addItem(&quot;Function&quot;);
+    if (m_seenTypes &amp; TypeUndefined)
+         seen-&gt;addItem(&quot;Undefined&quot;);
+    if (m_seenTypes &amp; TypeNull)
+         seen-&gt;addItem(&quot;Null&quot;);
+    if (m_seenTypes &amp; TypeBoolean)
+         seen-&gt;addItem(&quot;Boolean&quot;);
+    if (m_seenTypes &amp; TypeMachineInt)
+         seen-&gt;addItem(&quot;Integer&quot;);
+    if (m_seenTypes &amp; TypeNumber)
+         seen-&gt;addItem(&quot;Number&quot;);
+    if (m_seenTypes &amp; TypeString)
+         seen-&gt;addItem(&quot;String&quot;);
+
+    return seen.release();
+}
+
+PassRefPtr&lt;Inspector::TypeBuilder::Array&lt;Inspector::InspectorObject&gt;&gt; TypeSet::allStructureRepresentations() const
+{
+    RefPtr&lt;Inspector::TypeBuilder::Array&lt;Inspector::InspectorObject&gt;&gt; ret = Inspector::TypeBuilder::Array&lt;Inspector::InspectorObject&gt;::create();
+
+    for (size_t i = 0; i &lt; m_structureHistory-&gt;size(); i++)
+        ret-&gt;addItem(m_structureHistory-&gt;at(i)-&gt;inspectorRepresentation());
+
+    return ret.release();
+}
+
+String TypeSet::leastCommonAncestor() const
+{
+    return StructureShape::leastCommonAncestor(m_structureHistory);
+}
+
</ins><span class="cx"> void TypeSet::dumpSeenTypes()
</span><span class="cx"> {
</span><span class="cx">     dataLog(seenTypes(), &quot;\n&quot;);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> StructureShape::StructureShape()
</span><del>-    : m_propertyHash(nullptr)
</del><ins>+    : m_proto(nullptr)
+    , m_propertyHash(nullptr)
</ins><span class="cx">     , m_final(false)
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -166,7 +272,7 @@
</span><span class="cx"> void StructureShape::addProperty(RefPtr&lt;StringImpl&gt; impl)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!m_final);
</span><del>-    m_fields.set(impl, true);
</del><ins>+    m_fields.append(impl);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String StructureShape::propertyHash() 
</span><span class="lines">@@ -177,53 +283,77 @@
</span><span class="cx"> 
</span><span class="cx">     StringBuilder builder;
</span><span class="cx">     builder.append(&quot;:&quot;);
</span><ins>+    builder.append(m_constructorName);
+    builder.append(&quot;:&quot;);
+    
</ins><span class="cx">     for (auto iter = m_fields.begin(), end = m_fields.end(); iter != end; ++iter) {
</span><del>-        String property = String(iter-&gt;key);
</del><ins>+        String property = String((*iter));
</ins><span class="cx">         property.replace(&quot;:&quot;, &quot;\\:&quot;); // Ensure that hash({&quot;foo:&quot;, &quot;bar&quot;}) != hash({&quot;foo&quot;, &quot;:bar&quot;}) because we're using colons as a separator and colons are legal characters in field names in JS.
</span><span class="cx">         builder.append(property);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (m_proto) {
+        builder.append(&quot;:&quot;);
+        builder.append(&quot;__proto__&quot;);
+        builder.append(m_proto-&gt;propertyHash());
+    }
+
</ins><span class="cx">     m_propertyHash = std::make_unique&lt;String&gt;(builder.toString());
</span><span class="cx">     return *m_propertyHash;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-String StructureShape::leastUpperBound(Vector&lt;RefPtr&lt;StructureShape&gt;&gt;* shapes)
</del><ins>+String StructureShape::leastCommonAncestor(const Vector&lt;RefPtr&lt;StructureShape&gt;&gt;* shapes)
</ins><span class="cx"> {
</span><span class="cx">     if (!shapes-&gt;size())
</span><span class="cx">         return &quot;&quot;;
</span><span class="cx"> 
</span><del>-    StringBuilder lub;
</del><span class="cx">     RefPtr&lt;StructureShape&gt; origin = shapes-&gt;at(0);
</span><del>-    lub.append(&quot;{&quot;);
-    for (auto iter = origin-&gt;m_fields.begin(), end = origin-&gt;m_fields.end(); iter != end; ++iter) {
-        bool shouldAdd = true;
-        for (size_t i = 1, size = shapes-&gt;size(); i &lt; size; i++) {
-            // If all other Shapes have the same field as origin, add it to the least upper bound.
-            if (!shapes-&gt;at(i)-&gt;m_fields.contains(iter-&gt;key)) {
-                shouldAdd = false;
-                break;
</del><ins>+    for (size_t i = 1; i &lt; shapes-&gt;size(); i++) {
+        bool foundLUB = false;
+        while (!foundLUB) {
+            RefPtr&lt;StructureShape&gt; check = shapes-&gt;at(i);
+            String curCtorName = origin-&gt;m_constructorName;
+            while (check) {
+                if (check-&gt;m_constructorName == curCtorName) {
+                    foundLUB = true;
+                    break;
+                }
+                check = check-&gt;m_proto;
</ins><span class="cx">             }
</span><ins>+            if (!foundLUB) {
+                origin = origin-&gt;m_proto;
+                // All Objects must share the 'Object' Prototype. Therefore, at the very least, we should always converge on 'Object' before reaching a null prototype.
+                RELEASE_ASSERT(origin); 
+            }
</ins><span class="cx">         }
</span><del>-        if (shouldAdd)
-            lub.append(String(iter-&gt;key.get()) + String(&quot;, &quot;));
</del><ins>+
+        if (origin-&gt;m_constructorName == &quot;Object&quot;)
+            break;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (lub.length() &gt;= 3)
-        lub.resize(lub.length() - 2); // Remove the trailing ', '
-
-    lub.append(&quot;}&quot;);
-    
-    return lub.toString();
</del><ins>+    return origin-&gt;m_constructorName;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String StructureShape::stringRepresentation()
</span><span class="cx"> {
</span><span class="cx">     StringBuilder representation;
</span><ins>+    RefPtr&lt;StructureShape&gt; curShape = this;
+
</ins><span class="cx">     representation.append(&quot;{&quot;);
</span><del>-    for (auto iter = m_fields.begin(), end = m_fields.end(); iter != end; ++iter) {
-        String prop(iter-&gt;key.get());
-        representation.append(prop);
-        representation.append(&quot;, &quot;);
</del><ins>+    while (curShape) {
+        for (auto iter = curShape-&gt;m_fields.begin(), end = curShape-&gt;m_fields.end(); iter != end; ++iter) {
+            String prop((*iter).get());
+            representation.append(prop);
+            representation.append(&quot;, &quot;);
+        }
+
+        if (curShape-&gt;m_proto) {
+            String prot = String(&quot;__proto__&quot;) + String(&quot; [&quot;) + curShape-&gt;m_proto-&gt;m_constructorName + String(&quot;]&quot;);
+            representation.append(prot);
+            representation.append(&quot;, &quot;);
+        }
+
+        curShape = curShape-&gt;m_proto;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (representation.length() &gt;= 3)
</span><span class="lines">@@ -234,4 +364,30 @@
</span><span class="cx">     return representation.toString();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+PassRefPtr&lt;Inspector::InspectorObject&gt; StructureShape::inspectorRepresentation()
+{
+    RefPtr&lt;Inspector::InspectorObject&gt; base = Inspector::InspectorObject::create();
+    RefPtr&lt;Inspector::InspectorObject&gt; currentObject = base;
+    RefPtr&lt;StructureShape&gt; currentShape = this;
+
+    while (currentShape) {
+        RefPtr&lt;Inspector::TypeBuilder::Array&lt;String&gt;&gt; fields = Inspector::TypeBuilder::Array&lt;String&gt;::create();
+        for (auto iter = currentShape-&gt;m_fields.begin(), end = currentShape-&gt;m_fields.end(); iter != end; ++iter)
+            fields-&gt;addItem((*iter).get());
+
+        currentObject-&gt;setArray(ASCIILiteral(&quot;fields&quot;), fields-&gt;asArray());
+        currentObject-&gt;setString(ASCIILiteral(&quot;constructorName&quot;), currentShape-&gt;m_constructorName);
+
+        if (currentShape-&gt;m_proto) {
+            RefPtr&lt;Inspector::InspectorObject&gt; nextObject = Inspector::InspectorObject::create();
+            currentObject-&gt;setObject(ASCIILiteral(&quot;prototypeStructure&quot;), nextObject);
+            currentObject = nextObject;
+        }
+
+        currentShape = currentShape-&gt;m_proto;
+    }
+
+    return base.release();
+}
+
</ins><span class="cx"> } //namespace JSC
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeTypeSeth"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/TypeSet.h (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/TypeSet.h        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/TypeSet.h        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -32,6 +32,15 @@
</span><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> 
</span><ins>+namespace Inspector { namespace TypeBuilder  { 
+template&lt;typename T&gt;
+class Array;
+}}
+
+namespace Inspector { 
+class InspectorObject;
+}
+
</ins><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx"> class JSValue;
</span><span class="lines">@@ -45,8 +54,7 @@
</span><span class="cx">     TypeMachineInt         = 0x10,
</span><span class="cx">     TypeNumber             = 0x20,
</span><span class="cx">     TypeString             = 0x40,
</span><del>-    TypePrimitive          = 0x80,
-    TypeObject             = 0x100
</del><ins>+    TypeObject             = 0x80
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class StructureShape : public RefCounted&lt;StructureShape&gt; {
</span><span class="lines">@@ -59,12 +67,17 @@
</span><span class="cx">     String propertyHash();
</span><span class="cx">     void markAsFinal();
</span><span class="cx">     void addProperty(RefPtr&lt;StringImpl&gt;);
</span><del>-    static String leastUpperBound(Vector&lt;RefPtr&lt;StructureShape&gt;&gt;*);
</del><span class="cx">     String stringRepresentation();
</span><del>-    void setConstructorName(String name) { m_constructorName = name; }
</del><ins>+    PassRefPtr&lt;Inspector::InspectorObject&gt; inspectorRepresentation();
+    void setConstructorName(String name) { m_constructorName = (name.isEmpty() ? &quot;Object&quot; : name); }
+    String constructorName() { return m_constructorName; }
+    void setProto(PassRefPtr&lt;StructureShape&gt; shape) { m_proto = shape; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    HashMap&lt;RefPtr&lt;StringImpl&gt;, bool&gt; m_fields;         
</del><ins>+    static String leastCommonAncestor(const Vector&lt;RefPtr&lt;StructureShape&gt;&gt;*);
+
+    Vector&lt;RefPtr&lt;StringImpl&gt;&gt; m_fields;
+    RefPtr&lt;StructureShape&gt; m_proto;
</ins><span class="cx">     std::unique_ptr&lt;String&gt; m_propertyHash;
</span><span class="cx">     String m_constructorName;
</span><span class="cx">     bool m_final;
</span><span class="lines">@@ -77,11 +90,17 @@
</span><span class="cx">     TypeSet();
</span><span class="cx">     void addTypeForValue(JSValue v, PassRefPtr&lt;StructureShape&gt;, StructureID);
</span><span class="cx">     static RuntimeType getRuntimeTypeForValue(JSValue);
</span><del>-    JS_EXPORT_PRIVATE String seenTypes();
</del><ins>+    JS_EXPORT_PRIVATE String seenTypes() const;
+    String displayName() const;
+    PassRefPtr&lt;Inspector::TypeBuilder::Array&lt;String&gt;&gt; allPrimitiveTypeNames() const;
+    PassRefPtr&lt;Inspector::TypeBuilder::Array&lt;Inspector::InspectorObject&gt;&gt; allStructureRepresentations() const;
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    String leastCommonAncestor() const;
+    void dumpSeenTypes();
+    bool doesTypeConformTo(uint32_t test) const;
+
</ins><span class="cx">     uint32_t m_seenTypes;
</span><del>-    void dumpSeenTypes();
</del><span class="cx">     Vector&lt;RefPtr&lt;StructureShape&gt;&gt;* m_structureHistory;
</span><span class="cx">     HashMap&lt;StructureID, uint8_t&gt; m_structureIDHistory;
</span><span class="cx"> };
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/VM.cpp (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/VM.cpp        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/VM.cpp        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -926,43 +926,16 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-String VM::getTypesForVariableAtOffset(unsigned offset, const String&amp; variableName, const String&amp; sourceIDAsString)
-{
-    if (!isProfilingTypesWithHighFidelity())
-        return &quot;(Not Profiling)&quot;;
-
-    bool okay;
-    intptr_t sourceID = sourceIDAsString.toIntPtrStrict(&amp;okay);
-    if (!okay)
-        CRASH();
-
-    updateHighFidelityTypeProfileState();
-    return m_highFidelityTypeProfiler-&gt;getTypesForVariableInAtOffset(offset, variableName, sourceID);
-}
-
-void VM::updateHighFidelityTypeProfileState()
-{
-    if (!isProfilingTypesWithHighFidelity())
-        return;
-
-    highFidelityLog()-&gt;processHighFidelityLog(false, &quot;VM Update&quot;);
-}
-
</del><span class="cx"> void VM::dumpHighFidelityProfilingTypes()
</span><span class="cx"> {
</span><span class="cx">     if (!isProfilingTypesWithHighFidelity())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    updateHighFidelityTypeProfileState();
</del><ins>+    highFidelityLog()-&gt;processHighFidelityLog(&quot;VM Dump Types&quot;);
</ins><span class="cx">     HighFidelityTypeProfiler* profiler = m_highFidelityTypeProfiler.get();
</span><span class="cx">     for (Bag&lt;TypeLocation&gt;::iterator iter = m_locationInfo.begin(); !!iter; ++iter) {
</span><span class="cx">         TypeLocation* location = *iter;
</span><del>-        dataLogF(&quot;[Start, End]::[%u, %u] &quot;, location-&gt;m_divotStart, location-&gt;m_divotEnd);
-        dataLog(&quot;\n\t\t#Local#\n\t\t&quot;,
-                profiler-&gt;getLocalTypesForVariableAtOffset(location-&gt;m_divotStart, &quot;&quot;, location-&gt;m_sourceID).replace(&quot;\n&quot;, &quot;\n\t\t&quot;),
-                &quot;\n\t\t#Global#\n\t\t&quot;,
-                profiler-&gt;getGlobalTypesForVariableAtOffset(location-&gt;m_divotStart, &quot;&quot;, location-&gt;m_sourceID).replace(&quot;\n&quot;, &quot;\n\t\t&quot;),
-                &quot;\n&quot;);
</del><ins>+        profiler-&gt;logTypesForTypeLocation(location);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/VM.h (171509 => 171510)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/VM.h        2014-07-24 05:17:43 UTC (rev 171509)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/VM.h        2014-07-24 05:30:52 UTC (rev 171510)
</span><span class="lines">@@ -515,10 +515,8 @@
</span><span class="cx">         BuiltinExecutables* builtinExecutables() { return m_builtinExecutables.get(); }
</span><span class="cx"> 
</span><span class="cx">         bool isProfilingTypesWithHighFidelity() { return !!m_highFidelityTypeProfiler; }
</span><del>-        String getTypesForVariableAtOffset(unsigned divot, const String&amp; variableName, const String&amp; sourceID);
</del><span class="cx">         HighFidelityLog* highFidelityLog() { return m_highFidelityLog.get(); }
</span><span class="cx">         HighFidelityTypeProfiler* highFidelityTypeProfiler() { return m_highFidelityTypeProfiler.get(); }
</span><del>-        void updateHighFidelityTypeProfileState();
</del><span class="cx">         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
</span><span class="cx">         JS_EXPORT_PRIVATE void dumpHighFidelityProfilingTypes();
</span><span class="cx">         int64_t getNextUniqueVariableID() { return m_nextUniqueVariableID++; }
</span></span></pre>
</div>
</div>

</body>
</html>