<!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>[170490] 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/170490">170490</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2014-06-26 12:37:42 -0700 (Thu, 26 Jun 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Web Inspector: debugger should be able to show variable types
https://bugs.webkit.org/show_bug.cgi?id=133395
Patch by Saam Barati <sbarati@apple.com> on 2014-06-24
Reviewed by Filip Pizlo.
Increase the amount of type information the VM gathers when directed
to do so. This initial commit is working towards the goal of
capturing, and then showing (via the Web Inspector) type information for all
assignment and load operations. This patch doesn't have the feature fully
implemented, but it ensures the VM has no performance regressions
unless the feature is specifically turned on.
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::finalizeUnconditionally):
* bytecode/CodeBlock.h:
* bytecode/Instruction.h:
* bytecode/TypeLocation.h: Added.
(JSC::TypeLocation::TypeLocation):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitMove):
(JSC::BytecodeGenerator::emitProfileTypesWithHighFidelity):
(JSC::BytecodeGenerator::emitPutToScope):
(JSC::BytecodeGenerator::emitPutById):
(JSC::BytecodeGenerator::emitPutByVal):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::isProfilingTypesWithHighFidelity):
* bytecompiler/NodesCodegen.cpp:
(JSC::PostfixNode::emitResolve):
(JSC::PrefixNode::emitResolve):
(JSC::ReadModifyResolveNode::emitBytecode):
(JSC::AssignResolveNode::emitBytecode):
(JSC::ConstDeclNode::emitCodeSingle):
(JSC::ForInNode::emitBytecode):
* heap/Heap.cpp:
(JSC::Heap::collect):
* inspector/agents/InspectorRuntimeAgent.cpp:
(Inspector::InspectorRuntimeAgent::getRuntimeTypeForVariableInTextRange):
* inspector/agents/InspectorRuntimeAgent.h:
* inspector/protocol/Runtime.json:
* jsc.cpp:
(GlobalObject::finishCreation):
(functionDumpTypesForAllVariables):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
(JSC::LLInt::putToScopeCommon):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter.asm:
* runtime/HighFidelityLog.cpp: Added.
(JSC::HighFidelityLog::initializeHighFidelityLog):
(JSC::HighFidelityLog::~HighFidelityLog):
(JSC::HighFidelityLog::recordTypeInformationForLocation):
(JSC::HighFidelityLog::processHighFidelityLog):
(JSC::HighFidelityLog::actuallyProcessLogThreadFunction):
* runtime/HighFidelityLog.h: Added.
(JSC::HighFidelityLog::HighFidelityLog):
* runtime/HighFidelityTypeProfiler.cpp: Added.
(JSC::HighFidelityTypeProfiler::getTypesForVariableInRange):
(JSC::HighFidelityTypeProfiler::getGlobalTypesForVariableInRange):
(JSC::HighFidelityTypeProfiler::getLocalTypesForVariableInRange):
(JSC::HighFidelityTypeProfiler::insertNewLocation):
(JSC::HighFidelityTypeProfiler::getLocationBasedHash):
* runtime/HighFidelityTypeProfiler.h: Added.
* runtime/Options.h:
* runtime/Structure.cpp:
(JSC::Structure::toStructureShape):
* runtime/Structure.h:
* runtime/SymbolTable.cpp:
(JSC::SymbolTable::SymbolTable):
(JSC::SymbolTable::cloneCapturedNames):
(JSC::SymbolTable::uniqueIDForVariable):
(JSC::SymbolTable::uniqueIDForRegister):
(JSC::SymbolTable::globalTypeSetForRegister):
(JSC::SymbolTable::globalTypeSetForVariable):
* runtime/SymbolTable.h:
(JSC::SymbolTable::add):
(JSC::SymbolTable::set):
* runtime/TypeSet.cpp: Added.
(JSC::TypeSet::TypeSet):
(JSC::TypeSet::getRuntimeTypeForValue):
(JSC::TypeSet::addTypeForValue):
(JSC::TypeSet::removeDuplicatesInStructureHistory):
(JSC::TypeSet::seenTypes):
(JSC::TypeSet::dumpSeenTypes):
(JSC::StructureShape::StructureShape):
(JSC::StructureShape::markAsFinal):
(JSC::StructureShape::addProperty):
(JSC::StructureShape::propertyHash):
(JSC::StructureShape::leastUpperBound):
(JSC::StructureShape::stringRepresentation):
* runtime/TypeSet.h: Added.
(JSC::StructureShape::create):
(JSC::TypeSet::create):
* runtime/VM.cpp:
(JSC::VM::VM):
(JSC::VM::getTypesForVariableInRange):
(JSC::VM::updateHighFidelityTypeProfileState):
(JSC::VM::dumpHighFidelityProfilingTypes):
* runtime/VM.h:
(JSC::VM::isProfilingTypesWithHighFidelity):
(JSC::VM::highFidelityLog):
(JSC::VM::highFidelityTypeProfiler):
(JSC::VM::nextLocation):
(JSC::VM::getNextUniqueVariableID):</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="#branchesftloptSourceJavaScriptCorebytecodeBytecodeListjson">branches/ftlopt/Source/JavaScriptCore/bytecode/BytecodeList.json</a></li>
<li><a href="#branchesftloptSourceJavaScriptCorebytecodeBytecodeUseDefh">branches/ftlopt/Source/JavaScriptCore/bytecode/BytecodeUseDef.h</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="#branchesftloptSourceJavaScriptCorebytecodeInstructionh">branches/ftlopt/Source/JavaScriptCore/bytecode/Instruction.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="#branchesftloptSourceJavaScriptCorebytecompilerNodesCodegencpp">branches/ftlopt/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp</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="#branchesftloptSourceJavaScriptCorejsccpp">branches/ftlopt/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCorellintLLIntSlowPathscpp">branches/ftlopt/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCorellintLLIntSlowPathsh">branches/ftlopt/Source/JavaScriptCore/llint/LLIntSlowPaths.h</a></li>
<li><a href="#branchesftloptSourceJavaScriptCorellintLowLevelInterpreterasm">branches/ftlopt/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeOptionsh">branches/ftlopt/Source/JavaScriptCore/runtime/Options.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="#branchesftloptSourceJavaScriptCoreruntimeSymbolTablecpp">branches/ftlopt/Source/JavaScriptCore/runtime/SymbolTable.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeSymbolTableh">branches/ftlopt/Source/JavaScriptCore/runtime/SymbolTable.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="#branchesftloptSourceJavaScriptCorebytecodeTypeLocationh">branches/ftlopt/Source/JavaScriptCore/bytecode/TypeLocation.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="#branchesftloptSourceJavaScriptCoreruntimeTypeSetcpp">branches/ftlopt/Source/JavaScriptCore/runtime/TypeSet.cpp</a></li>
<li><a href="#branchesftloptSourceJavaScriptCoreruntimeTypeSeth">branches/ftlopt/Source/JavaScriptCore/runtime/TypeSet.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 (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/ChangeLog        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/ChangeLog        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -1,3 +1,116 @@
</span><ins>+2014-06-24 Saam Barati <sbarati@apple.com>
+
+ Web Inspector: debugger should be able to show variable types
+ https://bugs.webkit.org/show_bug.cgi?id=133395
+
+ Reviewed by Filip Pizlo.
+
+ Increase the amount of type information the VM gathers when directed
+ to do so. This initial commit is working towards the goal of
+ capturing, and then showing (via the Web Inspector) type information for all
+ assignment and load operations. This patch doesn't have the feature fully
+ implemented, but it ensures the VM has no performance regressions
+ unless the feature is specifically turned on.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/BytecodeList.json:
+ * bytecode/BytecodeUseDef.h:
+ (JSC::computeUsesForBytecodeOffset):
+ (JSC::computeDefsForBytecodeOffset):
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpBytecode):
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::finalizeUnconditionally):
+ * bytecode/CodeBlock.h:
+ * bytecode/Instruction.h:
+ * bytecode/TypeLocation.h: Added.
+ (JSC::TypeLocation::TypeLocation):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitMove):
+ (JSC::BytecodeGenerator::emitProfileTypesWithHighFidelity):
+ (JSC::BytecodeGenerator::emitPutToScope):
+ (JSC::BytecodeGenerator::emitPutById):
+ (JSC::BytecodeGenerator::emitPutByVal):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::isProfilingTypesWithHighFidelity):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::PostfixNode::emitResolve):
+ (JSC::PrefixNode::emitResolve):
+ (JSC::ReadModifyResolveNode::emitBytecode):
+ (JSC::AssignResolveNode::emitBytecode):
+ (JSC::ConstDeclNode::emitCodeSingle):
+ (JSC::ForInNode::emitBytecode):
+ * heap/Heap.cpp:
+ (JSC::Heap::collect):
+ * inspector/agents/InspectorRuntimeAgent.cpp:
+ (Inspector::InspectorRuntimeAgent::getRuntimeTypeForVariableInTextRange):
+ * inspector/agents/InspectorRuntimeAgent.h:
+ * inspector/protocol/Runtime.json:
+ * jsc.cpp:
+ (GlobalObject::finishCreation):
+ (functionDumpTypesForAllVariables):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ (JSC::LLInt::putToScopeCommon):
+ * llint/LLIntSlowPaths.h:
+ * llint/LowLevelInterpreter.asm:
+ * runtime/HighFidelityLog.cpp: Added.
+ (JSC::HighFidelityLog::initializeHighFidelityLog):
+ (JSC::HighFidelityLog::~HighFidelityLog):
+ (JSC::HighFidelityLog::recordTypeInformationForLocation):
+ (JSC::HighFidelityLog::processHighFidelityLog):
+ (JSC::HighFidelityLog::actuallyProcessLogThreadFunction):
+ * runtime/HighFidelityLog.h: Added.
+ (JSC::HighFidelityLog::HighFidelityLog):
+ * runtime/HighFidelityTypeProfiler.cpp: Added.
+ (JSC::HighFidelityTypeProfiler::getTypesForVariableInRange):
+ (JSC::HighFidelityTypeProfiler::getGlobalTypesForVariableInRange):
+ (JSC::HighFidelityTypeProfiler::getLocalTypesForVariableInRange):
+ (JSC::HighFidelityTypeProfiler::insertNewLocation):
+ (JSC::HighFidelityTypeProfiler::getLocationBasedHash):
+ * runtime/HighFidelityTypeProfiler.h: Added.
+ * runtime/Options.h:
+ * runtime/Structure.cpp:
+ (JSC::Structure::toStructureShape):
+ * runtime/Structure.h:
+ * runtime/SymbolTable.cpp:
+ (JSC::SymbolTable::SymbolTable):
+ (JSC::SymbolTable::cloneCapturedNames):
+ (JSC::SymbolTable::uniqueIDForVariable):
+ (JSC::SymbolTable::uniqueIDForRegister):
+ (JSC::SymbolTable::globalTypeSetForRegister):
+ (JSC::SymbolTable::globalTypeSetForVariable):
+ * runtime/SymbolTable.h:
+ (JSC::SymbolTable::add):
+ (JSC::SymbolTable::set):
+ * runtime/TypeSet.cpp: Added.
+ (JSC::TypeSet::TypeSet):
+ (JSC::TypeSet::getRuntimeTypeForValue):
+ (JSC::TypeSet::addTypeForValue):
+ (JSC::TypeSet::removeDuplicatesInStructureHistory):
+ (JSC::TypeSet::seenTypes):
+ (JSC::TypeSet::dumpSeenTypes):
+ (JSC::StructureShape::StructureShape):
+ (JSC::StructureShape::markAsFinal):
+ (JSC::StructureShape::addProperty):
+ (JSC::StructureShape::propertyHash):
+ (JSC::StructureShape::leastUpperBound):
+ (JSC::StructureShape::stringRepresentation):
+ * runtime/TypeSet.h: Added.
+ (JSC::StructureShape::create):
+ (JSC::TypeSet::create):
+ * runtime/VM.cpp:
+ (JSC::VM::VM):
+ (JSC::VM::getTypesForVariableInRange):
+ (JSC::VM::updateHighFidelityTypeProfileState):
+ (JSC::VM::dumpHighFidelityProfilingTypes):
+ * runtime/VM.h:
+ (JSC::VM::isProfilingTypesWithHighFidelity):
+ (JSC::VM::highFidelityLog):
+ (JSC::VM::highFidelityTypeProfiler):
+ (JSC::VM::nextLocation):
+ (JSC::VM::getNextUniqueVariableID):
+
</ins><span class="cx"> 2014-06-26 Mark Lam <mark.lam@apple.com>
</span><span class="cx">
</span><span class="cx"> Remove unused instantiation of the WithScope structure.
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -837,6 +837,13 @@
</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>+                52DAD38F195A164E00F30464 /* TypeLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 52DAD38E195A164E00F30464 /* TypeLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                52FB7137195374B800BB612E /* HighFidelityLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FB7133195374B700BB612E /* HighFidelityLog.cpp */; };
+                52FB7138195374B800BB612E /* HighFidelityLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FB7134195374B700BB612E /* HighFidelityLog.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                52FB7139195374B800BB612E /* HighFidelityTypeProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FB7135195374B800BB612E /* HighFidelityTypeProfiler.cpp */; };
+                52FB713A195374B800BB612E /* HighFidelityTypeProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FB7136195374B800BB612E /* HighFidelityTypeProfiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                52FB72141953760C00BB612E /* TypeSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FB72121953760C00BB612E /* TypeSet.cpp */; };
+                52FB72151953760C00BB612E /* TypeSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FB72131953760C00BB612E /* TypeSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 5510502618EB827500001F3E /* JSCallbackFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 1440F88F0A508B100005F061 /* JSCallbackFunction.h */; };
</span><span class="cx">                 552EA70C1908704800A66F2F /* JSDataViewPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2B66BF17B6B5AB00A7AE3F /* JSDataViewPrototype.cpp */; };
</span><span class="cx">                 5540757218DA58AD00EFF7F2 /* ArgList.h in Headers */ = {isa = PBXBuildFile; fileRef = BCF605120E203EF800B9A64D /* ArgList.h */; };
</span><span class="lines">@@ -2974,6 +2981,14 @@
</span><span class="cx">                 45E12D8806A49B0F00E9DF84 /* jsc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = jsc.cpp; sourceTree = "<group>"; tabWidth = 4; };
</span><span class="cx">                 51F0EB6105C86C6B00E6DF1B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
</span><span class="cx">                 51F0EC0705C86C9A00E6DF1B /* libobjc.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libobjc.dylib; path = /usr/lib/libobjc.dylib; sourceTree = "<absolute>"; };
</span><ins>+                522ABAF9194A8043008B1C85 /* TypeLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeLocation.h; sourceTree = "<group>"; };
+                52DAD38E195A164E00F30464 /* TypeLocation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeLocation.h; sourceTree = "<group>"; };
+                52FB7133195374B700BB612E /* HighFidelityLog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HighFidelityLog.cpp; sourceTree = "<group>"; };
+                52FB7134195374B700BB612E /* HighFidelityLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HighFidelityLog.h; sourceTree = "<group>"; };
+                52FB7135195374B800BB612E /* HighFidelityTypeProfiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HighFidelityTypeProfiler.cpp; sourceTree = "<group>"; };
+                52FB7136195374B800BB612E /* HighFidelityTypeProfiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HighFidelityTypeProfiler.h; sourceTree = "<group>"; };
+                52FB72121953760C00BB612E /* TypeSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TypeSet.cpp; sourceTree = "<group>"; };
+                52FB72131953760C00BB612E /* TypeSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeSet.h; sourceTree = "<group>"; };
</ins><span class="cx">                 5540758418F4A37500602A5D /* CompileRuntimeToLLVMIR.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = CompileRuntimeToLLVMIR.xcconfig; sourceTree = "<group>"; };
</span><span class="cx">                 55407AC818DA58AD00EFF7F2 /* libCompileRuntimeToLLVMIR.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCompileRuntimeToLLVMIR.a; sourceTree = BUILT_PRODUCTS_DIR; };
</span><span class="cx">                 5D53726D0E1C546B0021E549 /* Tracing.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Tracing.d; sourceTree = "<group>"; };
</span><span class="lines">@@ -4647,6 +4662,10 @@
</span><span class="cx">                                 0F2B66B317B6B5AB00A7AE3F /* GenericTypedArrayViewInlines.h */,
</span><span class="cx">                                 BC02E9B80E184545000F9297 /* GetterSetter.cpp */,
</span><span class="cx">                                 BC337BDE0E1AF0B80076918A /* GetterSetter.h */,
</span><ins>+                                52FB7133195374B700BB612E /* HighFidelityLog.cpp */,
+                                52FB7134195374B700BB612E /* HighFidelityLog.h */,
+                                52FB7135195374B800BB612E /* HighFidelityTypeProfiler.cpp */,
+                                52FB7136195374B800BB612E /* HighFidelityTypeProfiler.h */,
</ins><span class="cx">                                 933A349D038AE80F008635CE /* Identifier.cpp */,
</span><span class="cx">                                 933A349A038AE7C6008635CE /* Identifier.h */,
</span><span class="cx">                                 8606DDE918DA44AB00A383D0 /* IdentifierInlines.h */,
</span><span class="lines">@@ -4918,6 +4937,8 @@
</span><span class="cx">                                 0F2B66DB17B6B5AB00A7AE3F /* TypedArrays.h */,
</span><span class="cx">                                 0F2B66DC17B6B5AB00A7AE3F /* TypedArrayType.cpp */,
</span><span class="cx">                                 0F2B66DD17B6B5AB00A7AE3F /* TypedArrayType.h */,
</span><ins>+                                52FB72121953760C00BB612E /* TypeSet.cpp */,
+                                52FB72131953760C00BB612E /* TypeSet.h */,
</ins><span class="cx">                                 A7A8AF3217ADB5F3005AB174 /* Uint16Array.h */,
</span><span class="cx">                                 866739D113BFDE710023D87C /* Uint16WithFraction.h */,
</span><span class="cx">                                 A7A8AF3317ADB5F3005AB174 /* Uint32Array.h */,
</span><span class="lines">@@ -5389,6 +5410,7 @@
</span><span class="cx">                                 0FB5467814F5C468002C2989 /* LazyOperandValueProfile.cpp */,
</span><span class="cx">                                 0FB5467614F59AD1002C2989 /* LazyOperandValueProfile.h */,
</span><span class="cx">                                 0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */,
</span><ins>+                                522ABAF9194A8043008B1C85 /* TypeLocation.h */,
</ins><span class="cx">                                 0FB5467C14F5CFD3002C2989 /* MethodOfGettingAValueProfile.cpp */,
</span><span class="cx">                                 0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */,
</span><span class="cx">                                 14CA958C16AB50FA00938A06 /* ObjectAllocationProfile.h */,
</span><span class="lines">@@ -5426,6 +5448,7 @@
</span><span class="cx">                                 BCCF0D070EF0AAB900413C8F /* StructureStubInfo.h */,
</span><span class="cx">                                 0F7AB82C1958DA1C00C6881F /* ToThisStatus.cpp */,
</span><span class="cx">                                 0F7AB82D1958DA1C00C6881F /* ToThisStatus.h */,
</span><ins>+                                52DAD38E195A164E00F30464 /* TypeLocation.h */,
</ins><span class="cx">                                 A79E781E15EECBA80047C855 /* UnlinkedCodeBlock.cpp */,
</span><span class="cx">                                 A79E781F15EECBA80047C855 /* UnlinkedCodeBlock.h */,
</span><span class="cx">                                 B59F89381891ADB500D5CCDC /* UnlinkedInstructionStream.cpp */,
</span><span class="lines">@@ -5895,6 +5918,10 @@
</span><span class="cx">                                 0F6B1CB91861244C00845D97 /* ArityCheckMode.h in Headers */,
</span><span class="cx">                                 A1A009C11831A26E00CF8711 /* ARM64Assembler.h in Headers */,
</span><span class="cx">                                 86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */,
</span><ins>+                                52DAD38F195A164E00F30464 /* TypeLocation.h in Headers */,
+                                52FB72151953760C00BB612E /* TypeSet.h in Headers */,
+                                52FB713A195374B800BB612E /* HighFidelityTypeProfiler.h in Headers */,
+                                52FB7138195374B800BB612E /* HighFidelityLog.h in Headers */,
</ins><span class="cx">                                 A584032018BFFBE1005A0811 /* InspectorAgent.h in Headers */,
</span><span class="cx">                                 2AABCDE718EF294200002096 /* GCLogging.h in Headers */,
</span><span class="cx">                                 FE5248F9191442D900B7FDE4 /* VariableWatchpointSetInlines.h in Headers */,
</span><span class="lines">@@ -7610,6 +7637,7 @@
</span><span class="cx">                                 0F485321187750560083B687 /* DFGArithMode.cpp in Sources */,
</span><span class="cx">                                 0F63948415E48118006A597C /* DFGArrayMode.cpp in Sources */,
</span><span class="cx">                                 A7D9A29417A0BC7400EE2618 /* DFGAtTailAbstractState.cpp in Sources */,
</span><ins>+                                52FB7139195374B800BB612E /* HighFidelityTypeProfiler.cpp in Sources */,
</ins><span class="cx">                                 0F666EC61835672B00D017F1 /* DFGAvailability.cpp in Sources */,
</span><span class="cx">                                 0F714CA416EA92F000F3EBEB /* DFGBackwardsPropagationPhase.cpp in Sources */,
</span><span class="cx">                                 A7D89CF217A0B8CC00773AD8 /* DFGBasicBlock.cpp in Sources */,
</span><span class="lines">@@ -7645,6 +7673,7 @@
</span><span class="cx">                                 A78A9774179738B8009DF744 /* DFGFailedFinalizer.cpp in Sources */,
</span><span class="cx">                                 A78A9776179738B8009DF744 /* DFGFinalizer.cpp in Sources */,
</span><span class="cx">                                 0F2BDC15151C5D4D00CD8910 /* DFGFixupPhase.cpp in Sources */,
</span><ins>+                                52FB72141953760C00BB612E /* TypeSet.cpp in Sources */,
</ins><span class="cx">                                 0F9D339617FFC4E60073C2BC /* DFGFlushedAt.cpp in Sources */,
</span><span class="cx">                                 A7D89CF717A0B8CC00773AD8 /* DFGFlushFormat.cpp in Sources */,
</span><span class="cx">                                 86EC9DC71328DF82002B2AD7 /* DFGGraph.cpp in Sources */,
</span><span class="lines">@@ -7727,6 +7756,7 @@
</span><span class="cx">                                 A7B48F490EE8936F00DCBDB6 /* ExecutableAllocator.cpp in Sources */,
</span><span class="cx">                                 86DB64640F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp in Sources */,
</span><span class="cx">                                 0F56A1D515001CF4002992B1 /* ExecutionCounter.cpp in Sources */,
</span><ins>+                                52FB7137195374B800BB612E /* HighFidelityLog.cpp in Sources */,
</ins><span class="cx">                                 0F0332C018ADFAE1005F979A /* ExitingJITType.cpp in Sources */,
</span><span class="cx">                                 0FB105851675480F00F8AB6E /* ExitKind.cpp in Sources */,
</span><span class="cx">                                 0FEA0A1C1708B00700BB722C /* FTLAbstractHeap.cpp in Sources */,
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecodeBytecodeListjson"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecode/BytecodeList.json (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecode/BytecodeList.json        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/bytecode/BytecodeList.json        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -113,6 +113,7 @@
</span><span class="cx"> { "name" : "op_resolve_scope", "length" : 6 },
</span><span class="cx"> { "name" : "op_get_from_scope", "length" : 8 },
</span><span class="cx"> { "name" : "op_put_to_scope", "length" : 7 },
</span><ins>+ { "name" : "op_put_to_scope_with_profile", "length" : 8 },
</ins><span class="cx"> { "name" : "op_push_with_scope", "length" : 2 },
</span><span class="cx"> { "name" : "op_pop_scope", "length" : 1 },
</span><span class="cx"> { "name" : "op_push_name_scope", "length" : 4 },
</span><span class="lines">@@ -122,7 +123,8 @@
</span><span class="cx"> { "name" : "op_debug", "length" : 3 },
</span><span class="cx"> { "name" : "op_profile_will_call", "length" : 2 },
</span><span class="cx"> { "name" : "op_profile_did_call", "length" : 2 },
</span><del>- { "name" : "op_end", "length" : 2 }
</del><ins>+ { "name" : "op_end", "length" : 2 },
+ { "name" : "op_profile_types_with_high_fidelity", "length" : 4 }
</ins><span class="cx"> ]
</span><span class="cx"> },
</span><span class="cx"> {
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecodeBytecodeUseDefh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecode/BytecodeUseDef.h (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -65,6 +65,7 @@
</span><span class="cx"> case op_tear_off_activation:
</span><span class="cx"> case op_profile_will_call:
</span><span class="cx"> case op_profile_did_call:
</span><ins>+ case op_profile_types_with_high_fidelity:
</ins><span class="cx"> case op_throw:
</span><span class="cx"> case op_push_with_scope:
</span><span class="cx"> case op_end:
</span><span class="lines">@@ -105,6 +106,7 @@
</span><span class="cx"> case op_put_by_id_transition_normal_out_of_line:
</span><span class="cx"> case op_put_by_id_out_of_line:
</span><span class="cx"> case op_put_by_id:
</span><ins>+ case op_put_to_scope_with_profile:
</ins><span class="cx"> case op_put_to_scope: {
</span><span class="cx"> functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
</span><span class="cx"> functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
</span><span class="lines">@@ -249,6 +251,7 @@
</span><span class="cx"> case op_push_name_scope:
</span><span class="cx"> case op_push_with_scope:
</span><span class="cx"> case op_put_to_scope:
</span><ins>+ case op_put_to_scope_with_profile:
</ins><span class="cx"> case op_pop_scope:
</span><span class="cx"> case op_end:
</span><span class="cx"> case op_profile_will_call:
</span><span class="lines">@@ -287,6 +290,7 @@
</span><span class="cx"> case op_put_by_val_direct:
</span><span class="cx"> case op_put_by_index:
</span><span class="cx"> case op_tear_off_arguments:
</span><ins>+ case op_profile_types_with_high_fidelity:
</ins><span class="cx"> case op_touch_entry:
</span><span class="cx"> #define LLINT_HELPER_OPCODES(opcode, length) case opcode:
</span><span class="cx"> FOR_EACH_LLINT_OPCODE_EXTENSION(LLINT_HELPER_OPCODES);
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecode/CodeBlock.cpp (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -39,6 +39,7 @@
</span><span class="cx"> #include "DFGJITCode.h"
</span><span class="cx"> #include "DFGWorklist.h"
</span><span class="cx"> #include "Debugger.h"
</span><ins>+#include "HighFidelityTypeProfiler.h"
</ins><span class="cx"> #include "Interpreter.h"
</span><span class="cx"> #include "JIT.h"
</span><span class="cx"> #include "JITStubs.h"
</span><span class="lines">@@ -47,6 +48,7 @@
</span><span class="cx"> #include "JSFunction.h"
</span><span class="cx"> #include "JSNameScope.h"
</span><span class="cx"> #include "LLIntEntrypoint.h"
</span><ins>+#include "TypeLocation.h"
</ins><span class="cx"> #include "LowLevelInterpreter.h"
</span><span class="cx"> #include "JSCInlines.h"
</span><span class="cx"> #include "PolymorphicGetByIdList.h"
</span><span class="lines">@@ -843,6 +845,14 @@
</span><span class="cx"> ++it;
</span><span class="cx"> break;
</span><span class="cx"> }
</span><ins>+ case op_profile_types_with_high_fidelity: {
+ int r0 = (++it)->u.operand;
+ ++it;
+ ++it;
+ printLocationAndOp(out, exec, location, it, "op_profile_types_with_high_fidelity");
+ out.printf("%s", registerName(r0).data());
+ break;
+ }
</ins><span class="cx"> case op_not: {
</span><span class="cx"> printUnaryOp(out, exec, location, it, "not");
</span><span class="cx"> break;
</span><span class="lines">@@ -1469,6 +1479,7 @@
</span><span class="cx"> operand);
</span><span class="cx"> break;
</span><span class="cx"> }
</span><ins>+ case op_put_to_scope_with_profile:
</ins><span class="cx"> case op_put_to_scope: {
</span><span class="cx"> int r0 = (++it)->u.operand;
</span><span class="cx"> int id0 = (++it)->u.operand;
</span><span class="lines">@@ -1477,6 +1488,8 @@
</span><span class="cx"> ++it; // Structure
</span><span class="cx"> int operand = (++it)->u.operand; // Operand
</span><span class="cx"> printLocationAndOp(out, exec, location, it, "put_to_scope");
</span><ins>+ if (opcode == op_put_to_scope_with_profile)
+ ++it;
</ins><span class="cx"> out.printf("%s, %s, %s, %u<%s|%s>, <structure>, %d",
</span><span class="cx"> registerName(r0).data(), idName(id0, identifier(id0)).data(), registerName(r1).data(),
</span><span class="cx"> modeAndType.operand(), resolveModeName(modeAndType.mode()), resolveTypeName(modeAndType.type()),
</span><span class="lines">@@ -1880,6 +1893,7 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ case op_put_to_scope_with_profile:
</ins><span class="cx"> case op_put_to_scope: {
</span><span class="cx"> // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
</span><span class="cx"> const Identifier& ident = identifier(pc[2].u.operand);
</span><span class="lines">@@ -1895,9 +1909,68 @@
</span><span class="cx"> } else if (op.structure)
</span><span class="cx"> instructions[i + 5].u.structure.set(*vm(), ownerExecutable, op.structure);
</span><span class="cx"> instructions[i + 6].u.pointer = reinterpret_cast<void*>(op.operand);
</span><ins>+
+ if (pc[0].u.opcode == op_put_to_scope_with_profile) {
+ // The format of this instruction is: put_to_scope_with_profile scope, id, value, ResolveModeAndType, Structure, Operand, TypeLocation*
+ TypeLocation* location = vm()->nextLocation();
+ size_t instructionOffset = i + opLength - 1;
+ int divot, startOffset, endOffset;
+ unsigned line = 0, column = 0;
+ expressionRangeForBytecodeOffset(instructionOffset, divot, startOffset, endOffset, line, column);
+
+ location->m_line = line;
+ location->m_column = column;
+ location->m_sourceID = m_ownerExecutable->sourceID();
+
+ // FIXME: handle other values for op.type here, and also consider what to do when we can't statically determine the globalID
+ SymbolTable* symbolTable = 0;
+ if (op.type == ClosureVar)
+ symbolTable = op.activation->symbolTable();
+ else if (op.type == GlobalVar)
+ symbolTable = m_globalObject.get()->symbolTable();
+
+ if (symbolTable) {
+ ConcurrentJITLocker locker(symbolTable->m_lock);
+ location->m_globalVariableID = symbolTable->uniqueIDForVariable(locker, ident.impl(), *vm());
+ location->m_globalTypeSet =symbolTable->globalTypeSetForVariable(locker, ident.impl(), *vm());
+ } else
+ location->m_globalVariableID = HighFidelityNoGlobalIDExists;
+
+ vm()->highFidelityTypeProfiler()->insertNewLocation(location);
+ instructions[i + 7].u.location = location;
+ }
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><ins>+
+ case op_profile_types_with_high_fidelity: {
+
+ VirtualRegister virtualRegister(pc[1].u.operand);
+ SymbolTable* symbolTable = m_symbolTable.get();
+ TypeLocation* location = vm()->nextLocation();
+ size_t instructionOffset = i + opLength - 1;
+ int divot, startOffset, endOffset;
+ unsigned line = 0, column = 0;
+ expressionRangeForBytecodeOffset(instructionOffset, divot, startOffset, endOffset, line, column);
+
+ int hasGlobalIDFlag = pc[3].u.operand;
+ if (hasGlobalIDFlag) {
+ ConcurrentJITLocker locker(symbolTable->m_lock);
+ location->m_globalVariableID = symbolTable->uniqueIDForRegister(locker, virtualRegister.offset(), *vm());
+ location->m_globalTypeSet = symbolTable->globalTypeSetForRegister(locker, virtualRegister.offset(), *vm());
+ } else
+ location->m_globalVariableID = HighFidelityNoGlobalIDExists;
</ins><span class="cx">
</span><ins>+
+ location->m_line = line;
+ location->m_column = column;
+ location->m_sourceID = m_ownerExecutable->sourceID();
+
+ vm()->highFidelityTypeProfiler()->insertNewLocation(location);
+ instructions[i + 2].u.location = location;
+ break;
+ }
+
+
</ins><span class="cx"> case op_captured_mov:
</span><span class="cx"> case op_new_captured_func: {
</span><span class="cx"> if (pc[3].u.index == UINT_MAX) {
</span><span class="lines">@@ -2343,6 +2416,7 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> case op_get_from_scope:
</span><ins>+ case op_put_to_scope_with_profile:
</ins><span class="cx"> case op_put_to_scope: {
</span><span class="cx"> ResolveModeAndType modeAndType =
</span><span class="cx"> ResolveModeAndType(curInstruction[4].u.operand);
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecode/CodeBlock.h (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecode/CodeBlock.h        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/bytecode/CodeBlock.h        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -943,6 +943,7 @@
</span><span class="cx">
</span><span class="cx"> bool isKnownToBeLiveDuringGC(); // Will only return valid results when called during GC. Assumes that you've already established that the owner executable is live.
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> protected:
</span><span class="cx"> virtual void visitWeakReferences(SlotVisitor&) override;
</span><span class="cx"> virtual void finalizeUnconditionally() override;
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecodeInstructionh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecode/Instruction.h (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecode/Instruction.h        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/bytecode/Instruction.h        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx">
</span><span class="cx"> #include "MacroAssembler.h"
</span><span class="cx"> #include "Opcode.h"
</span><ins>+#include "TypeLocation.h"
</ins><span class="cx"> #include "PropertySlot.h"
</span><span class="cx"> #include "SpecialPointer.h"
</span><span class="cx"> #include "Structure.h"
</span><span class="lines">@@ -120,6 +121,7 @@
</span><span class="cx"> void* pointer;
</span><span class="cx"> bool* predicatePointer;
</span><span class="cx"> ToThisStatus toThisStatus;
</span><ins>+ TypeLocation* location;
</ins><span class="cx"> } u;
</span><span class="cx">
</span><span class="cx"> private:
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecodeTypeLocationh"></a>
<div class="addfile"><h4>Added: branches/ftlopt/Source/JavaScriptCore/bytecode/TypeLocation.h (0 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecode/TypeLocation.h         (rev 0)
+++ branches/ftlopt/Source/JavaScriptCore/bytecode/TypeLocation.h        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -0,0 +1,57 @@
</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 TypeLocation_h
+#define TypeLocation_h
+
+#include "TypeSet.h"
+
+namespace JSC {
+
+enum HighFidelityGlobalIDFlags {
+ HighFidelityNeedsUniqueIDGeneration = -1,
+ HighFidelityNoGlobalIDExists = -2
+};
+
+class TypeLocation {
+
+public:
+ TypeLocation()
+ : m_instructionTypeSet(TypeSet::create())
+ , m_globalTypeSet(nullptr)
+ {
+ }
+
+ int64_t m_globalVariableID;
+ intptr_t m_sourceID;
+ unsigned m_line;
+ unsigned m_column;
+ RefPtr<TypeSet> m_instructionTypeSet;
+ RefPtr<TypeSet> m_globalTypeSet;
+};
+
+} //namespace JSC
+
+#endif //TypeLocation_h
</ins></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -1003,6 +1003,10 @@
</span><span class="cx"> instructions().append(src->index());
</span><span class="cx"> if (captureMode == IsCaptured)
</span><span class="cx"> instructions().append(watchableVariable(dst->index()));
</span><ins>+
+ if (!dst->isTemporary() && isProfilingTypesWithHighFidelity())
+ emitProfileTypesWithHighFidelity(dst, true);
+
</ins><span class="cx"> return dst;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1112,6 +1116,18 @@
</span><span class="cx"> return dst;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void BytecodeGenerator::emitProfileTypesWithHighFidelity(RegisterID* registerToProfile, bool hasGlobalID)
+{
+ emitOpcode(op_profile_types_with_high_fidelity);
+ instructions().append(registerToProfile->index());
+ instructions().append(0); // placeholder for TypeLocation
+ // This is a flag indicating whether we should track this value to its globalID or not.
+ if (hasGlobalID)
+ instructions().append(1);
+ else
+ instructions().append(0);
+}
+
</ins><span class="cx"> RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, bool b)
</span><span class="cx"> {
</span><span class="cx"> return emitLoad(dst, jsBoolean(b));
</span><span class="lines">@@ -1256,13 +1272,18 @@
</span><span class="cx"> m_codeBlock->addPropertyAccessInstruction(instructions().size());
</span><span class="cx">
</span><span class="cx"> // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
</span><del>- emitOpcode(op_put_to_scope);
</del><ins>+ if (isProfilingTypesWithHighFidelity())
+ emitOpcode(op_put_to_scope_with_profile);
+ else
+ emitOpcode(op_put_to_scope);
</ins><span class="cx"> instructions().append(scope->index());
</span><span class="cx"> instructions().append(addConstant(identifier));
</span><span class="cx"> instructions().append(value->index());
</span><span class="cx"> instructions().append(ResolveModeAndType(resolveMode, resolveType()).operand());
</span><span class="cx"> instructions().append(0);
</span><span class="cx"> instructions().append(0);
</span><ins>+ if (isProfilingTypesWithHighFidelity())
+ instructions().append(0);
</ins><span class="cx"> return value;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1329,6 +1350,10 @@
</span><span class="cx"> instructions().append(0);
</span><span class="cx"> instructions().append(0);
</span><span class="cx"> instructions().append(0);
</span><ins>+
+ if (isProfilingTypesWithHighFidelity())
+ emitProfileTypesWithHighFidelity(value, false);
+
</ins><span class="cx"> return value;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1425,6 +1450,10 @@
</span><span class="cx"> instructions().append(property->index());
</span><span class="cx"> instructions().append(value->index());
</span><span class="cx"> instructions().append(arrayProfile);
</span><ins>+
+ if (isProfilingTypesWithHighFidelity())
+ emitProfileTypesWithHighFidelity(value, false);
+
</ins><span class="cx"> return value;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -332,6 +332,8 @@
</span><span class="cx"> return emitNode(n);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ void emitProfileTypesWithHighFidelity(RegisterID* dst, bool);
+
</ins><span class="cx"> RegisterID* emitLoad(RegisterID* dst, bool);
</span><span class="cx"> RegisterID* emitLoad(RegisterID* dst, double);
</span><span class="cx"> RegisterID* emitLoad(RegisterID* dst, const Identifier&);
</span><span class="lines">@@ -677,6 +679,8 @@
</span><span class="cx">
</span><span class="cx"> VM* m_vm;
</span><span class="cx">
</span><ins>+ bool isProfilingTypesWithHighFidelity() { return vm()->isProfilingTypesWithHighFidelity(); }
+
</ins><span class="cx"> OpcodeID m_lastOpcodeID;
</span><span class="cx"> #ifndef NDEBUG
</span><span class="cx"> size_t m_lastOpcodePosition;
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorebytecompilerNodesCodegencpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -740,13 +740,15 @@
</span><span class="cx"> if (local.isReadOnly()) {
</span><span class="cx"> generator.emitReadOnlyExceptionIfNeeded();
</span><span class="cx"> localReg = generator.emitMove(generator.tempDestination(dst), localReg);
</span><del>- } else if (local.isCaptured()) {
</del><ins>+ } else if (local.isCaptured() || generator.isProfilingTypesWithHighFidelity()) {
</ins><span class="cx"> RefPtr<RegisterID> tempDst = generator.finalDestination(dst);
</span><span class="cx"> ASSERT(dst != localReg);
</span><span class="cx"> RefPtr<RegisterID> tempDstSrc = generator.newTemporary();
</span><span class="cx"> generator.emitToNumber(tempDst.get(), localReg);
</span><span class="cx"> generator.emitMove(tempDstSrc.get(), localReg);
</span><span class="cx"> emitIncOrDec(generator, tempDstSrc.get(), m_operator);
</span><ins>+ if (generator.isProfilingTypesWithHighFidelity())
+ generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</ins><span class="cx"> generator.emitMove(localReg, tempDstSrc.get());
</span><span class="cx"> return tempDst.get();
</span><span class="cx"> }
</span><span class="lines">@@ -915,10 +917,12 @@
</span><span class="cx"> if (local.isReadOnly()) {
</span><span class="cx"> generator.emitReadOnlyExceptionIfNeeded();
</span><span class="cx"> localReg = generator.emitMove(generator.tempDestination(dst), localReg);
</span><del>- } else if (local.isCaptured()) {
</del><ins>+ } else if (local.isCaptured() || generator.isProfilingTypesWithHighFidelity()) {
</ins><span class="cx"> RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
</span><span class="cx"> generator.emitMove(tempDst.get(), localReg);
</span><span class="cx"> emitIncOrDec(generator, tempDst.get(), m_operator);
</span><ins>+ if (generator.isProfilingTypesWithHighFidelity())
+ generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</ins><span class="cx"> generator.emitMove(localReg, tempDst.get());
</span><span class="cx"> return generator.moveToDestinationIfNeeded(dst, tempDst.get());
</span><span class="cx"> }
</span><span class="lines">@@ -1407,6 +1411,7 @@
</span><span class="cx">
</span><span class="cx"> RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
</span><span class="cx"> {
</span><ins>+ JSTextPosition newDivot = divotStart() + m_ident.length();
</ins><span class="cx"> if (Local local = generator.local(m_ident)) {
</span><span class="cx"> if (local.isReadOnly()) {
</span><span class="cx"> generator.emitReadOnlyExceptionIfNeeded();
</span><span class="lines">@@ -1414,10 +1419,13 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (local.isCaptured()
</span><ins>+ || generator.isProfilingTypesWithHighFidelity()
</ins><span class="cx"> || generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
</span><span class="cx"> RefPtr<RegisterID> result = generator.newTemporary();
</span><span class="cx"> generator.emitMove(result.get(), local.get());
</span><span class="cx"> emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
</span><ins>+ if (generator.isProfilingTypesWithHighFidelity())
+ generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
</ins><span class="cx"> generator.emitMove(local.get(), result.get());
</span><span class="cx"> return generator.moveToDestinationIfNeeded(dst, result.get());
</span><span class="cx"> }
</span><span class="lines">@@ -1426,7 +1434,6 @@
</span><span class="cx"> return generator.moveToDestinationIfNeeded(dst, result);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- JSTextPosition newDivot = divotStart() + m_ident.length();
</del><span class="cx"> generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
</span><span class="cx"> RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), m_ident);
</span><span class="cx"> RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), m_ident, ThrowIfNotFound);
</span><span class="lines">@@ -1443,9 +1450,11 @@
</span><span class="cx"> generator.emitReadOnlyExceptionIfNeeded();
</span><span class="cx"> return generator.emitNode(dst, m_right);
</span><span class="cx"> }
</span><del>- if (local.isCaptured()) {
</del><ins>+ if (local.isCaptured() || generator.isProfilingTypesWithHighFidelity()) {
</ins><span class="cx"> RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
</span><span class="cx"> generator.emitNode(tempDst.get(), m_right);
</span><ins>+ if (generator.isProfilingTypesWithHighFidelity())
+ generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
</ins><span class="cx"> generator.emitMove(local.get(), tempDst.get());
</span><span class="cx"> return generator.moveToDestinationIfNeeded(dst, tempDst.get());
</span><span class="cx"> }
</span><span class="lines">@@ -1548,7 +1557,8 @@
</span><span class="cx"> if (!m_init)
</span><span class="cx"> return local.get();
</span><span class="cx">
</span><del>- if (local.isCaptured()) {
</del><ins>+ // FIXME: Maybe call emitExpressionInfo here.
+ if (local.isCaptured() || generator.isProfilingTypesWithHighFidelity()) {
</ins><span class="cx"> RefPtr<RegisterID> tempDst = generator.newTemporary();
</span><span class="cx"> generator.emitNode(tempDst.get(), m_init);
</span><span class="cx"> return generator.emitMove(local.get(), tempDst.get());
</span><span class="lines">@@ -1871,7 +1881,8 @@
</span><span class="cx"> Identifier ident = simpleBinding->boundProperty();
</span><span class="cx"> Local local = generator.local(ident);
</span><span class="cx"> propertyName = local.get();
</span><del>- if (!propertyName || local.isCaptured())
</del><ins>+ // FIXME: Should I emit expression info here?
+ if (!propertyName || local.isCaptured() || generator.isProfilingTypesWithHighFidelity())
</ins><span class="cx"> goto genericBinding;
</span><span class="cx"> expectedSubscript = generator.emitMove(generator.newTemporary(), propertyName);
</span><span class="cx"> generator.pushOptimisedForIn(expectedSubscript.get(), iter.get(), i.get(), propertyName);
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreheapHeapcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/heap/Heap.cpp (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/heap/Heap.cpp        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/heap/Heap.cpp        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx"> #include "HeapIterationScope.h"
</span><span class="cx"> #include "HeapRootVisitor.h"
</span><span class="cx"> #include "HeapStatistics.h"
</span><ins>+#include "HighFidelityLog.h"
</ins><span class="cx"> #include "IncrementalSweeper.h"
</span><span class="cx"> #include "Interpreter.h"
</span><span class="cx"> #include "JSGlobalObject.h"
</span><span class="lines">@@ -969,6 +970,8 @@
</span><span class="cx"> #if ENABLE(ALLOCATION_LOGGING)
</span><span class="cx"> dataLogF("JSC GC starting collection.\n");
</span><span class="cx"> #endif
</span><ins>+ if (vm()->isProfilingTypesWithHighFidelity())
+ vm()->highFidelityLog()->processHighFidelityLog(false, "GC");
</ins><span class="cx">
</span><span class="cx"> double before = 0;
</span><span class="cx"> if (Options::logGC()) {
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreinspectoragentsInspectorRuntimeAgentcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -191,6 +191,13 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void InspectorRuntimeAgent::getRuntimeTypeForVariableInTextRange(ErrorString*, const String& in_variableName, const String& in_id, int in_startLine, int in_startColumn, int in_endLine, int in_endColumn, String* out_types)
+{
+ VM& vm = globalVM();
+ String types(vm.getTypesForVariableInRange(in_startLine, in_startColumn, in_endLine, in_endColumn, in_variableName, in_id));
+ *out_types = types;
+}
+
</ins><span class="cx"> } // namespace Inspector
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(INSPECTOR)
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreinspectoragentsInspectorRuntimeAgenth"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -66,6 +66,7 @@
</span><span class="cx"> virtual void getProperties(ErrorString*, const String& objectId, const bool* ownProperties, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Runtime::PropertyDescriptor>>& result, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Runtime::InternalPropertyDescriptor>>& internalProperties) override final;
</span><span class="cx"> virtual void releaseObjectGroup(ErrorString*, const String& objectGroup) override final;
</span><span class="cx"> virtual void run(ErrorString*) override;
</span><ins>+ virtual void getRuntimeTypeForVariableInTextRange(ErrorString*, const String& in_variableName, const String& in_id, int in_startLine, int in_startColumn, int in_endLine, int in_endColumn, String* out_types) override;
</ins><span class="cx">
</span><span class="cx"> void setScriptDebugServer(ScriptDebugServer* scriptDebugServer) { m_scriptDebugServer = scriptDebugServer; }
</span><span class="cx">
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreinspectorprotocolRuntimejson"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/inspector/protocol/Runtime.json (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/inspector/protocol/Runtime.json        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/inspector/protocol/Runtime.json        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -196,6 +196,21 @@
</span><span class="cx"> {
</span><span class="cx"> "name": "disable",
</span><span class="cx"> "description": "Disables reporting of execution contexts creation."
</span><ins>+ },
+ {
+ "name": "getRuntimeTypeForVariableInTextRange",
+ "parameters": [
+ { "name": "variableName", "type": "string", "description": "Variable we want type infromation for." },
+ { "name": "sourceID", "type": "string", "description": "sourceID uniquely identifying a script" },
+ { "name": "startLine", "type": "integer", "description": "start line for variable name" },
+ { "name": "startColumn", "type": "integer", "description": "start column for variable name" },
+ { "name": "endLine", "type": "integer", "description": "end line for variable name" },
+ { "name": "endColumn", "type": "integer", "description": "end column for variable name" }
+ ],
+ "returns": [
+ { "name": "types", "type": "string", "description": "Types for requested variable." }
+ ],
+ "description": "Returns detailed informtation on given function."
</ins><span class="cx"> }
</span><span class="cx"> ],
</span><span class="cx"> "events": [
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/jsc.cpp (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/jsc.cpp        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/jsc.cpp        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -24,6 +24,7 @@
</span><span class="cx">
</span><span class="cx"> #include "ButterflyInlines.h"
</span><span class="cx"> #include "BytecodeGenerator.h"
</span><ins>+#include "CodeBlock.h"
</ins><span class="cx"> #include "Completion.h"
</span><span class="cx"> #include "CopiedSpaceInlines.h"
</span><span class="cx"> #include "ExceptionHelpers.h"
</span><span class="lines">@@ -347,6 +348,7 @@
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionUndefined(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionEffectful42(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionMakeMasquerader(ExecState*);
</span><ins>+static EncodedJSValue JSC_HOST_CALL functionDumpTypesForAllVariables (ExecState*);
</ins><span class="cx">
</span><span class="cx"> #if ENABLE(SAMPLING_FLAGS)
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionSetSamplingFlags(ExecState*);
</span><span class="lines">@@ -493,6 +495,7 @@
</span><span class="cx">
</span><span class="cx"> addFunction(vm, "createImpureGetter", functionCreateImpureGetter, 1);
</span><span class="cx"> addFunction(vm, "setImpureGetterDelegate", functionSetImpureGetterDelegate, 2);
</span><ins>+ addFunction(vm, "dumpTypesForAllVariables", functionDumpTypesForAllVariables , 4);
</ins><span class="cx">
</span><span class="cx"> JSArray* array = constructEmptyArray(globalExec(), 0);
</span><span class="cx"> for (size_t i = 0; i < arguments.size(); ++i)
</span><span class="lines">@@ -927,6 +930,12 @@
</span><span class="cx"> return JSValue::encode(Masquerader::create(exec->vm(), exec->lexicalGlobalObject()));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+EncodedJSValue JSC_HOST_CALL functionDumpTypesForAllVariables(ExecState* exec)
+{
+ exec->vm().dumpHighFidelityProfilingTypes();
+ return JSValue::encode(jsUndefined());
+}
+
</ins><span class="cx"> // Use SEH for Release builds only to get rid of the crash report dialog
</span><span class="cx"> // (luckily the same tests fail in Release and Debug builds so far). Need to
</span><span class="cx"> // be in a separate main function because the jscmain function requires object
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -36,6 +36,7 @@
</span><span class="cx"> #include "ErrorHandlingScope.h"
</span><span class="cx"> #include "GetterSetter.h"
</span><span class="cx"> #include "HostCallReturnValue.h"
</span><ins>+#include "HighFidelityLog.h"
</ins><span class="cx"> #include "Interpreter.h"
</span><span class="cx"> #include "JIT.h"
</span><span class="cx"> #include "JITExceptions.h"
</span><span class="lines">@@ -167,7 +168,6 @@
</span><span class="cx"> ExecState* __rcf_exec = (execCallee); \
</span><span class="cx"> LLINT_RETURN_TWO(pc, __rcf_exec); \
</span><span class="cx"> } while (false)
</span><del>-
</del><span class="cx">
</span><span class="cx"> extern "C" SlowPathReturnType llint_trace_operand(ExecState* exec, Instruction* pc, int fromWhere, int operand)
</span><span class="cx"> {
</span><span class="lines">@@ -533,6 +533,15 @@
</span><span class="cx"> LLINT_RETURN(RegExpObject::create(vm, exec->lexicalGlobalObject()->regExpStructure(), regExp));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+LLINT_SLOW_PATH_DECL(slow_path_profile_types_with_high_fidelity)
+{
+ LLINT_BEGIN();
+ TypeLocation* location = pc[2].u.location;
+ JSValue val = LLINT_OP_C(1).jsValue();
+ vm.highFidelityLog()->recordTypeInformationForLocation(val, location);
+ LLINT_END_IMPL();
+}
+
</ins><span class="cx"> LLINT_SLOW_PATH_DECL(slow_path_check_has_instance)
</span><span class="cx"> {
</span><span class="cx"> LLINT_BEGIN();
</span><span class="lines">@@ -1426,9 +1435,8 @@
</span><span class="cx"> LLINT_RETURN(slot.getValue(exec, ident));
</span><span class="cx"> }
</span><span class="cx">
</span><del>-LLINT_SLOW_PATH_DECL(slow_path_put_to_scope)
</del><ins>+static JSObject* putToScopeCommon(ExecState* exec, Instruction* pc, VM& vm)
</ins><span class="cx"> {
</span><del>- LLINT_BEGIN();
</del><span class="cx"> CodeBlock* codeBlock = exec->codeBlock();
</span><span class="cx"> const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
</span><span class="cx"> JSObject* scope = jsCast<JSObject*>(LLINT_OP(1).jsValue());
</span><span class="lines">@@ -1436,7 +1444,7 @@
</span><span class="cx"> ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
</span><span class="cx">
</span><span class="cx"> if (modeAndType.mode() == ThrowIfNotFound && !scope->hasProperty(exec, ident))
</span><del>- LLINT_THROW(createUndefinedVariableError(exec, ident));
</del><ins>+ return createUndefinedVariableError(exec, ident);
</ins><span class="cx">
</span><span class="cx"> PutPropertySlot slot(scope, codeBlock->isStrictMode());
</span><span class="cx"> scope->methodTable()->put(scope, exec, ident, value, slot);
</span><span class="lines">@@ -1450,9 +1458,31 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ return nullptr;
+}
+
+LLINT_SLOW_PATH_DECL(slow_path_put_to_scope)
+{
+ LLINT_BEGIN();
+ JSObject* error = putToScopeCommon(exec, pc, vm);
+ if (error)
+ LLINT_THROW(error);
</ins><span class="cx"> LLINT_END();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+LLINT_SLOW_PATH_DECL(slow_path_put_to_scope_with_profile)
+{
+ // The format of this instruction is the same as put_to_scope with a TypeLocation appended: put_to_scope_with_profile scope, id, value, ResolveModeAndType, Structure, Operand, TypeLocation*
+ LLINT_BEGIN();
+ JSObject* error = putToScopeCommon(exec, pc, vm);
+ if (error)
+ LLINT_THROW(error);
+ TypeLocation* location = pc[7].u.location;
+ JSValue val = LLINT_OP_C(3).jsValue();
+ vm.highFidelityLog()->recordTypeInformationForLocation(val, location);
+ LLINT_END();
+}
+
</ins><span class="cx"> extern "C" SlowPathReturnType llint_throw_stack_overflow_error(VM* vm, ProtoCallFrame* protoFrame)
</span><span class="cx"> {
</span><span class="cx"> ExecState* exec = vm->topCallFrame;
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorellintLLIntSlowPathsh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/llint/LLIntSlowPaths.h (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -124,6 +124,8 @@
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_resolve_scope);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_from_scope);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_to_scope);
</span><ins>+LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_to_scope_with_profile);
+LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_profile_types_with_high_fidelity);
</ins><span class="cx"> extern "C" SlowPathReturnType llint_throw_stack_overflow_error(VM*, ProtoCallFrame*) WTF_INTERNAL;
</span><span class="cx"> #if ENABLE(LLINT_C_LOOP)
</span><span class="cx"> extern "C" SlowPathReturnType llint_stack_check_at_vm_entry(VM*, Register*) WTF_INTERNAL;
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -1232,3 +1232,11 @@
</span><span class="cx"> _llint_op_init_global_const_nop:
</span><span class="cx"> dispatch(5)
</span><span class="cx">
</span><ins>+_llint_op_profile_types_with_high_fidelity:
+ callSlowPath(_llint_slow_path_profile_types_with_high_fidelity)
+ dispatch(4)
+
+_llint_op_put_to_scope_with_profile:
+ traceExecution()
+ callSlowPath(_llint_slow_path_put_to_scope_with_profile)
+ dispatch(8)
</ins></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeHighFidelityLogcpp"></a>
<div class="addfile"><h4>Added: branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityLog.cpp (0 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityLog.cpp         (rev 0)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityLog.cpp        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -0,0 +1,124 @@
</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.
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 "config.h"
+#include "HighFidelityLog.h"
+
+#include "JSCJSValueInlines.h"
+#include "TypeLocation.h"
+#include <wtf/CurrentTime.h>
+
+
+namespace JSC {
+
+static const bool verbose = false;
+
+void HighFidelityLog::initializeHighFidelityLog()
+{
+ ASSERT(!m_logStartPtr);
+ m_highFidelityLogSize = 50000;
+ m_logStartPtr = new LogEntry[m_highFidelityLogSize];
+ m_nextBuffer = new LogEntry[m_highFidelityLogSize];
+ m_currentOffset = 0;
+}
+
+HighFidelityLog::~HighFidelityLog()
+{
+ delete[] m_logStartPtr;
+ delete[] m_nextBuffer;
+}
+
+void HighFidelityLog::recordTypeInformationForLocation(JSValue v, TypeLocation* location)
+{
+ ASSERT(m_logStartPtr);
+ ASSERT(m_currentOffset < m_highFidelityLogSize);
+
+ LogEntry* entry = m_logStartPtr + m_currentOffset;
+
+ entry->location = location;
+ entry->value = v;
+ entry->structure = (v.isCell() ? v.asCell()->structure() : nullptr);
+
+ m_currentOffset += 1;
+ if (m_currentOffset == m_highFidelityLogSize)
+ processHighFidelityLog(true, "Log Full");
+}
+
+void HighFidelityLog::processHighFidelityLog(bool asynchronously, String reason)
+{
+ // This should only be called from the main execution thread.
+ if (!m_currentOffset)
+ return;
+
+ if (verbose)
+ dataLog("Process caller:'", reason,"'");
+
+ ByteSpinLocker* locker = new ByteSpinLocker(m_lock);
+ ThreadData* data = new ThreadData;
+ data->m_proccessLogToOffset = m_currentOffset;
+ data->m_processLogPtr = m_logStartPtr;
+ data->m_locker = locker;
+
+ m_currentOffset = 0;
+ LogEntry* temp = m_logStartPtr;
+ m_logStartPtr = m_nextBuffer;
+ m_nextBuffer = temp;
+
+ if (asynchronously)
+ createThread(actuallyProcessLogThreadFunction, data, "ProcessHighFidelityLog");
+ else
+ actuallyProcessLogThreadFunction(data);
+}
+
+void HighFidelityLog::actuallyProcessLogThreadFunction(void* arg)
+{
+ double before = currentTimeMS();
+ ThreadData* data = static_cast<ThreadData*>(arg);
+ LogEntry* entry = data->m_processLogPtr;
+ size_t processLogToOffset = data->m_proccessLogToOffset;
+ size_t i = 0;
+ while (i < processLogToOffset) {
+ Structure* structure = entry->structure ? entry->structure : nullptr;
+ RefPtr<StructureShape> shape;
+ if (structure)
+ shape = structure->toStructureShape();
+ if (entry->location->m_globalTypeSet)
+ entry->location->m_globalTypeSet->addTypeForValue(entry->value, shape);
+ entry->location->m_instructionTypeSet->addTypeForValue(entry->value, shape);
+ entry++;
+ i++;
+ }
+
+ delete data->m_locker;
+ delete data;
+ double after = currentTimeMS();
+ if (verbose)
+ dataLogF("Processing the log took: '%f' ms\n", after - before);
+}
+
+} //namespace JSC
</ins></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeHighFidelityLogh"></a>
<div class="addfile"><h4>Added: branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityLog.h (0 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityLog.h         (rev 0)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityLog.h        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -0,0 +1,83 @@
</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.
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 HighFidelityLog_h
+#define HighFidelityLog_h
+
+#include "JSCJSValue.h"
+#include "HighFidelityTypeProfiler.h"
+#include "Structure.h"
+#include <wtf/ByteSpinLock.h>
+
+namespace JSC {
+
+class TypeLocation;
+
+class HighFidelityLog {
+
+public:
+ struct LogEntry {
+ public:
+ JSValue value;
+ TypeLocation* location;
+ Structure* structure;
+ };
+
+ HighFidelityLog()
+ : m_logStartPtr(0)
+ {
+ initializeHighFidelityLog();
+ }
+
+ ~HighFidelityLog();
+
+ void recordTypeInformationForLocation(JSValue v, TypeLocation*);
+ void processHighFidelityLog(bool asynchronously = false, String = "");
+
+private:
+ void initializeHighFidelityLog();
+ static void actuallyProcessLogThreadFunction(void*);
+
+ unsigned m_highFidelityLogSize;
+ size_t m_currentOffset;
+ LogEntry* m_logStartPtr;
+ LogEntry* m_nextBuffer;
+
+ ByteSpinLock m_lock;
+
+ struct ThreadData {
+ public:
+ LogEntry* m_processLogPtr;
+ size_t m_proccessLogToOffset;
+ ByteSpinLocker* m_locker;
+ };
+};
+
+} //namespace JSC
+
+#endif //HighFidelityLog_h
</ins></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeHighFidelityTypeProfilercpp"></a>
<div class="addfile"><h4>Added: branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.cpp (0 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.cpp         (rev 0)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.cpp        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -0,0 +1,88 @@
</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 "config.h"
+#include "HighFidelityTypeProfiler.h"
+
+#include "TypeLocation.h"
+
+namespace JSC {
+
+static const bool verbose = false;
+
+String HighFidelityTypeProfiler::getTypesForVariableInRange(unsigned startLine, unsigned startColumn, unsigned endLine , unsigned endColumn, const String& variableName, intptr_t sourceID)
+{
+ String global = getGlobalTypesForVariableInRange(startLine, startColumn, endLine, endColumn, variableName, sourceID);
+ if (!global.isEmpty())
+ return global;
+
+ return getLocalTypesForVariableInRange(startLine, startColumn, endLine, endColumn, variableName, sourceID);
+}
+
+WTF::String HighFidelityTypeProfiler::getGlobalTypesForVariableInRange(unsigned startLine, unsigned, unsigned, unsigned, const WTF::String&, intptr_t sourceID)
+{
+ auto iterLocationMap = m_globalLocationToGlobalIDMap.find(getLocationBasedHash(sourceID, startLine));
+ if (iterLocationMap == m_globalLocationToGlobalIDMap.end())
+ return "";
+
+ auto iterIDMap = m_globalIDMap.find(iterLocationMap->second);
+ if (iterIDMap == m_globalIDMap.end())
+ return "";
+
+ return iterIDMap->second->seenTypes();
+}
+
+WTF::String HighFidelityTypeProfiler::getLocalTypesForVariableInRange(unsigned startLine, unsigned , unsigned , unsigned , const WTF::String& , intptr_t sourceID)
+{
+ auto iter = m_globalLocationMap.find(getLocationBasedHash(sourceID, startLine));
+ auto end = m_globalLocationMap.end();
+ if (iter == end)
+ return "";
+
+ return iter->second->seenTypes();
+}
+
+void HighFidelityTypeProfiler::insertNewLocation(TypeLocation* location)
+{
+ if (verbose)
+ dataLogF("Registering location:: line:%u, column:%u\n", location->m_line, location->m_column);
+
+ LocationKey key(getLocationBasedHash(location->m_sourceID, location->m_line));
+
+ if (location->m_globalVariableID != HighFidelityNoGlobalIDExists) {
+ // Build the mapping relationships Map1:key=>globalId, Map2:globalID=>TypeSet
+ m_globalLocationToGlobalIDMap[key] = location->m_globalVariableID;
+ m_globalIDMap[location->m_globalVariableID] = location->m_globalTypeSet;
+ }
+
+ m_globalLocationMap[key] = location->m_instructionTypeSet;
+}
+
+LocationKey HighFidelityTypeProfiler::getLocationBasedHash(intptr_t id, unsigned line)
+{
+ return LocationKey(id, line, 1);
+}
+
+} //namespace JSC
</ins></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeHighFidelityTypeProfilerh"></a>
<div class="addfile"><h4>Added: branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.h (0 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.h         (rev 0)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/HighFidelityTypeProfiler.h        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -0,0 +1,89 @@
</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 HighFidelityTypeProfiler_h
+#define HighFidelityTypeProfiler_h
+
+#include "CodeBlock.h"
+#include <unordered_map>
+#include <wtf/HashMap.h>
+#include <wtf/HashMethod.h>
+#include <wtf/text/WTFString.h>
+
+namespace JSC {
+
+class TypeLocation;
+
+struct LocationKey {
+
+public:
+ LocationKey(intptr_t sourceID, unsigned line, unsigned column)
+ : m_sourceID(sourceID)
+ , m_line(line)
+ , m_column(column)
+
+ {
+ }
+
+ unsigned hash() const
+ {
+ return m_line + m_sourceID;
+ }
+
+ // FIXME: For now, this is a hack. We do the following: Map:"ID:Line" => TypeSet. Obviously, this assumes all assignments are on discrete lines, which is an incorrect assumption.
+ bool operator==(const LocationKey& other) const
+ {
+ return m_sourceID == other.m_sourceID
+ && m_line == other.m_line;
+ }
+
+ intptr_t m_sourceID;
+ unsigned m_line;
+ unsigned m_column;
+};
+
+class HighFidelityTypeProfiler {
+
+public:
+ String getTypesForVariableInRange(unsigned startLine, unsigned startColumn, unsigned endLine, unsigned endColumn, const String& variableName, intptr_t sourceID);
+ String getGlobalTypesForVariableInRange(unsigned startLine, unsigned startColumn, unsigned endLine, unsigned endColumn, const String& variableName, intptr_t sourceID);
+ String getLocalTypesForVariableInRange(unsigned startLine, unsigned startColumn, unsigned endLine, unsigned endColumn, const String& variableName, intptr_t sourceID);
+ void insertNewLocation(TypeLocation*);
+
+private:
+ static LocationKey getLocationBasedHash(intptr_t, unsigned);
+
+ typedef std::unordered_map<LocationKey, RefPtr<TypeSet>, HashMethod<LocationKey>> GlobalLocationMap;
+ typedef std::unordered_map<int64_t, RefPtr<TypeSet>> GlobalIDMap;
+ typedef std::unordered_map<LocationKey, int64_t, HashMethod<LocationKey>> GlobalLocationToGlobalIDMap;
+
+ GlobalIDMap m_globalIDMap;
+ GlobalLocationMap m_globalLocationMap;
+ GlobalLocationToGlobalIDMap m_globalLocationToGlobalIDMap;
+};
+
+} //namespace JSC
+
+#endif //HighFidelityTypeProfiler_h
</ins></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/Options.h (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/Options.h        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/Options.h        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -271,7 +271,9 @@
</span><span class="cx"> v(bool, disableGC, false) \
</span><span class="cx"> v(unsigned, gcMaxHeapSize, 0) \
</span><span class="cx"> v(bool, recordGCPauseTimes, false) \
</span><del>- v(bool, logHeapStatisticsAtExit, false)
</del><ins>+ v(bool, logHeapStatisticsAtExit, false) \
+ v(bool, profileTypesWithHighFidelity, false)
+
</ins><span class="cx">
</span><span class="cx"> class Options {
</span><span class="cx"> public:
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeStructurecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/Structure.cpp (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/Structure.cpp        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/Structure.cpp        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -1058,6 +1058,39 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+
+PassRefPtr<StructureShape> Structure::toStructureShape()
+{
+ Vector<Structure*, 8> structures;
+ Structure* structure;
+ PropertyTable* table;
+ RefPtr<StructureShape> shape = StructureShape::create();
+
+ findStructuresAndMapForMaterialization(structures, structure, table);
+
+ if (table) {
+ PropertyTable::iterator iter = table->begin();
+ PropertyTable::iterator end = table->end();
+
+ for (; iter != end; ++iter)
+ shape->addProperty(iter->key);
+
+ structure->m_lock.unlock();
+ }
+
+ for (unsigned i = structures.size(); i--;) {
+ Structure* structure = structures[i];
+ if (!structure->m_nameInPrevious)
+ continue;
+
+ shape->addProperty(structure->m_nameInPrevious.get());
+ }
+
+ shape->markAsFinal();
+
+ return shape.release();
+}
+
</ins><span class="cx"> void Structure::dump(PrintStream& out) const
</span><span class="cx"> {
</span><span class="cx"> out.print(RawPointer(this), ":[", classInfo()->className, ", {");
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeStructureh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/Structure.h (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/Structure.h        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/Structure.h        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -373,6 +373,8 @@
</span><span class="cx"> {
</span><span class="cx"> return m_transitionWatchpointSet;
</span><span class="cx"> }
</span><ins>+
+ PassRefPtr<StructureShape> toStructureShape();
</ins><span class="cx">
</span><span class="cx"> void dump(PrintStream&) const;
</span><span class="cx"> void dumpInContext(PrintStream&, DumpContext*) const;
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeSymbolTablecpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/SymbolTable.cpp (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/SymbolTable.cpp        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/SymbolTable.cpp        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -103,6 +103,11 @@
</span><span class="cx"> , m_captureEnd(0)
</span><span class="cx"> , m_functionEnteredOnce(ClearWatchpoint)
</span><span class="cx"> {
</span><ins>+ if (vm.isProfilingTypesWithHighFidelity()) {
+ m_uniqueIDMap = std::make_unique<UniqueIDMap>();
+ m_registerToVariableMap = std::make_unique<RegisterToVariableMap>();
+ m_uniqueTypeSetMap = std::make_unique<UniqueTypeSetMap>();
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> SymbolTable::~SymbolTable() { }
</span><span class="lines">@@ -157,9 +162,72 @@
</span><span class="cx"> for (unsigned i = parameterCount(); i--;)
</span><span class="cx"> result->m_slowArguments[i] = m_slowArguments[i];
</span><span class="cx"> }
</span><ins>+
+ if (m_uniqueIDMap && result->m_uniqueIDMap) {
+
+ {
+ auto iter = m_uniqueIDMap->begin();
+ auto end = m_uniqueIDMap->end();
+ for (; iter != end; ++iter)
+ result->m_uniqueIDMap->set(iter->key, iter->value);
+ }
+
+ {
+ auto iter = m_registerToVariableMap->begin();
+ auto end = m_registerToVariableMap->end();
+ for (; iter != end; ++iter)
+ result->m_registerToVariableMap->set(iter->key, iter->value);
+ }
+
+ {
+ auto iter = m_uniqueTypeSetMap->begin();
+ auto end = m_uniqueTypeSetMap->end();
+ for (; iter != end; ++iter)
+ result->m_uniqueTypeSetMap->set(iter->key, iter->value);
+ }
+ }
+
</ins><span class="cx">
</span><span class="cx"> return result;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+int64_t SymbolTable::uniqueIDForVariable(const ConcurrentJITLocker&, StringImpl* key, VM& vm)
+{
+ auto iter = m_uniqueIDMap->find(key);
+ auto end = m_uniqueIDMap->end();
+ ASSERT_UNUSED(end, iter != end);
+
+ int64_t& id = iter->value;
+ if (id == HighFidelityNeedsUniqueIDGeneration) {
+ id = vm.getNextUniqueVariableID();
+ m_uniqueTypeSetMap->set(key, TypeSet::create()); //make a new global typeset for the ID
+ }
+
+ return id;
+}
+
+int64_t SymbolTable::uniqueIDForRegister(const ConcurrentJITLocker& locker, int registerIndex, VM& vm)
+{
+ auto iter = m_registerToVariableMap->find(registerIndex);
+ auto end = m_registerToVariableMap->end();
+ ASSERT_UNUSED(end, iter != end);
+ return uniqueIDForVariable(locker, iter->value.get(), vm);
+}
+
+RefPtr<TypeSet> SymbolTable::globalTypeSetForRegister(const ConcurrentJITLocker& locker, int registerIndex, VM& vm)
+{
+ uniqueIDForRegister(locker, registerIndex, vm); //ensure it's created
+ auto iter = m_registerToVariableMap->find(registerIndex);
+ auto end = m_registerToVariableMap->end();
+ ASSERT_UNUSED(end, iter != end);
+ return globalTypeSetForVariable(locker, iter->value.get(), vm);
+}
+
+RefPtr<TypeSet> SymbolTable::globalTypeSetForVariable(const ConcurrentJITLocker& locker, StringImpl* key, VM& vm)
+{
+ uniqueIDForVariable(locker, key, vm);
+ return m_uniqueTypeSetMap->find(key)->value;
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx">
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeSymbolTableh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/SymbolTable.h (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/SymbolTable.h        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/SymbolTable.h        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx">
</span><span class="cx"> #include "ConcurrentJITLock.h"
</span><span class="cx"> #include "JSObject.h"
</span><ins>+#include "TypeSet.h"
</ins><span class="cx"> #include "VariableWatchpointSet.h"
</span><span class="cx"> #include <memory>
</span><span class="cx"> #include <wtf/HashTraits.h>
</span><span class="lines">@@ -336,6 +337,9 @@
</span><span class="cx"> typedef JSCell Base;
</span><span class="cx">
</span><span class="cx"> typedef HashMap<RefPtr<StringImpl>, SymbolTableEntry, IdentifierRepHash, HashTraits<RefPtr<StringImpl>>, SymbolTableIndexHashTraits> Map;
</span><ins>+ typedef HashMap<RefPtr<StringImpl>, int64_t> UniqueIDMap;
+ typedef HashMap<RefPtr<StringImpl>, RefPtr<TypeSet>> UniqueTypeSetMap;
+ typedef HashMap<int, RefPtr<StringImpl>, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int>> RegisterToVariableMap;
</ins><span class="cx">
</span><span class="cx"> static SymbolTable* create(VM& vm)
</span><span class="cx"> {
</span><span class="lines">@@ -413,6 +417,12 @@
</span><span class="cx">
</span><span class="cx"> Map::AddResult add(const ConcurrentJITLocker&, StringImpl* key, const SymbolTableEntry& entry)
</span><span class="cx"> {
</span><ins>+ if (m_uniqueIDMap) {
+ // Use a flag to indicate that we need to produce a unique ID. Because VM is in charge of creating uniqueIDs,
+ // when uniqueID() is called, we check this flag to see if uniqueID creation is necessary.
+ m_uniqueIDMap->set(key, HighFidelityNeedsUniqueIDGeneration);
+ m_registerToVariableMap->set(entry.getIndex(), key);
+ }
</ins><span class="cx"> return m_map.add(key, entry);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -424,6 +434,10 @@
</span><span class="cx">
</span><span class="cx"> Map::AddResult set(const ConcurrentJITLocker&, StringImpl* key, const SymbolTableEntry& entry)
</span><span class="cx"> {
</span><ins>+ if (m_uniqueIDMap) {
+ m_uniqueIDMap->set(key, HighFidelityNeedsUniqueIDGeneration);
+ m_registerToVariableMap->set(entry.getIndex(), key);
+ }
</ins><span class="cx"> return m_map.set(key, entry);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -444,6 +458,11 @@
</span><span class="cx"> return contains(locker, key);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ int64_t uniqueIDForVariable(const ConcurrentJITLocker&, StringImpl* key, VM& vm);
+ int64_t uniqueIDForRegister(const ConcurrentJITLocker& locker, int registerIndex, VM& vm);
+ RefPtr<TypeSet> globalTypeSetForRegister(const ConcurrentJITLocker& locker, int registerIndex, VM& vm);
+ RefPtr<TypeSet> globalTypeSetForVariable(const ConcurrentJITLocker& locker, StringImpl* key, VM& vm);
+
</ins><span class="cx"> bool usesNonStrictEval() { return m_usesNonStrictEval; }
</span><span class="cx"> void setUsesNonStrictEval(bool usesNonStrictEval) { m_usesNonStrictEval = usesNonStrictEval; }
</span><span class="cx">
</span><span class="lines">@@ -494,7 +513,10 @@
</span><span class="cx"> ~SymbolTable();
</span><span class="cx">
</span><span class="cx"> Map m_map;
</span><del>-
</del><ins>+ std::unique_ptr<UniqueIDMap> m_uniqueIDMap;
+ std::unique_ptr<RegisterToVariableMap> m_registerToVariableMap;
+ std::unique_ptr<UniqueTypeSetMap> m_uniqueTypeSetMap;
+
</ins><span class="cx"> int m_parameterCountIncludingThis;
</span><span class="cx"> bool m_usesNonStrictEval;
</span><span class="cx">
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeTypeSetcpp"></a>
<div class="addfile"><h4>Added: branches/ftlopt/Source/JavaScriptCore/runtime/TypeSet.cpp (0 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/TypeSet.cpp         (rev 0)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/TypeSet.cpp        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -0,0 +1,236 @@
</span><ins>+/*
+ * Copyright (C) 2008, 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 "config.h"
+#include "TypeSet.h"
+
+#include "JSCJSValue.h"
+#include "JSCJSValueInlines.h"
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+#include <wtf/text/StringBuilder.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+TypeSet::TypeSet()
+ : m_seenTypes(TypeNothing)
+ , m_structureHistory(new Vector<RefPtr<StructureShape>>)
+ , m_mightHaveDuplicatesInStructureHistory(false)
+{
+}
+
+RuntimeType TypeSet::getRuntimeTypeForValue(JSValue v)
+{
+ RuntimeType ret;
+ if (v.isFunction())
+ ret = TypeFunction;
+ else if (v.isUndefined())
+ ret = TypeUndefined;
+ else if (v.isNull())
+ ret = TypeNull;
+ else if (v.isBoolean())
+ ret = TypeBoolean;
+ else if (v.isMachineInt())
+ ret = TypeMachineInt;
+ else if (v.isNumber())
+ ret = TypeNumber;
+ else if (v.isString())
+ ret = TypeString;
+ else if (v.isPrimitive())
+ ret = TypePrimitive;
+ else if (v.isObject())
+ ret = TypeObject;
+ else
+ CRASH();
+
+ return ret;
+}
+
+void TypeSet::addTypeForValue(JSValue v, PassRefPtr<StructureShape> shape)
+{
+ RuntimeType t = getRuntimeTypeForValue(v);
+ m_seenTypes = m_seenTypes | t;
+
+ if (shape) {
+ m_structureHistory->append(shape);
+ m_mightHaveDuplicatesInStructureHistory = true;
+ }
+}
+
+void TypeSet::removeDuplicatesInStructureHistory()
+{
+ Vector<RefPtr<StructureShape>>* newHistory = new Vector<RefPtr<StructureShape>>;
+ HashMap<String, bool> container;
+ for (size_t i = 0; i < m_structureHistory->size(); i++) {
+ RefPtr<StructureShape> a = m_structureHistory->at(i);
+ String hash = a->propertyHash();
+ auto iter = container.find(hash);
+ if (iter == container.end()) {
+ container.add(hash, true);
+ newHistory->append(a);
+ }
+ }
+
+ delete m_structureHistory;
+ m_structureHistory = newHistory;
+ m_mightHaveDuplicatesInStructureHistory = false;
+}
+
+String TypeSet::seenTypes()
+{
+ if (m_seenTypes == TypeNothing)
+ return "(Unreached Statement)";
+
+ if (m_mightHaveDuplicatesInStructureHistory)
+ removeDuplicatesInStructureHistory();
+
+ StringBuilder seen;
+
+ if (m_seenTypes & TypeFunction)
+ seen.append("Function ");
+ if (m_seenTypes & TypeUndefined)
+ seen.append("Undefined ");
+ if (m_seenTypes & TypeNull)
+ seen.append("Null ");
+ if (m_seenTypes & TypeBoolean)
+ seen.append("Boolean ");
+ if (m_seenTypes & TypeMachineInt)
+ seen.append("MachineInt ");
+ if (m_seenTypes & TypeNumber)
+ seen.append("Number ");
+ if (m_seenTypes & TypeString)
+ seen.append("String ");
+ if (m_seenTypes & TypePrimitive)
+ seen.append("Primitive ");
+ if (m_seenTypes & TypeObject)
+ seen.append("Object ");
+
+ if (m_structureHistory->size())
+ seen.append("\nStructures:[ ");
+ for (size_t i = 0; i < m_structureHistory->size(); i++) {
+ seen.append(m_structureHistory->at(i)->stringRepresentation());
+ seen.append(" ");
+ }
+ if (m_structureHistory->size())
+ seen.append("]");
+
+ if (m_structureHistory->size()) {
+ seen.append("\nLUB: ");
+ seen.append(StructureShape::leastUpperBound(m_structureHistory));
+ }
+
+ return seen.toString();
+}
+
+void TypeSet::dumpSeenTypes()
+{
+ dataLog(seenTypes(), "\n");
+}
+
+StructureShape::StructureShape()
+ : m_propertyHash(nullptr)
+ , m_final(false)
+{
+}
+
+void StructureShape::markAsFinal()
+{
+ ASSERT(!m_final);
+ m_final = true;
+}
+
+void StructureShape::addProperty(RefPtr<StringImpl> impl)
+{
+ ASSERT(!m_final);
+ m_fields.set(impl, true);
+}
+
+String StructureShape::propertyHash()
+{
+ ASSERT(m_final);
+ if (m_propertyHash)
+ return *m_propertyHash;
+
+ StringBuilder builder;
+ builder.append(":");
+ for (auto iter = m_fields.begin(), end = m_fields.end(); iter != end; ++iter) {
+ String property = String(iter->key);
+ property.replace(":", "\\:"); // Ensure that hash({"foo:", "bar"}) != hash({"foo", ":bar"}) because we're using colons as a separator and colons are legal characters in field names in JS.
+ builder.append(property);
+ }
+
+ m_propertyHash = std::make_unique<String>(builder.toString());
+ return *m_propertyHash;
+}
+
+String StructureShape::leastUpperBound(Vector<RefPtr<StructureShape>>* shapes)
+{
+ if (!shapes->size())
+ return "";
+
+ StringBuilder lub;
+ RefPtr<StructureShape> origin = shapes->at(0);
+ lub.append("{");
+ for (auto iter = origin->m_fields.begin(), end = origin->m_fields.end(); iter != end; ++iter) {
+ bool shouldAdd = true;
+ for (size_t i = 1, size = shapes->size(); i < size; i++) {
+ // If all other Shapes have the same field as origin, add it to the least upper bound.
+ if (!shapes->at(i)->m_fields.contains(iter->key)) {
+ shouldAdd = false;
+ break;
+ }
+ }
+ if (shouldAdd)
+ lub.append(String(iter->key.get()) + String(", "));
+ }
+
+ if (lub.length() >= 3)
+ lub.resize(lub.length() - 2); // Remove the trailing ', '
+
+ lub.append("}");
+
+ return lub.toString();
+}
+
+String StructureShape::stringRepresentation()
+{
+ StringBuilder representation;
+ representation.append("{");
+ for (auto iter = m_fields.begin(), end = m_fields.end(); iter != end; ++iter) {
+ String prop(iter->key.get());
+ representation.append(prop);
+ representation.append(", ");
+ }
+
+ if (representation.length() >= 3)
+ representation.resize(representation.length() - 2);
+
+ representation.append("}");
+
+ return representation.toString();
+}
+
+} //namespace JSC
</ins></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeTypeSeth"></a>
<div class="addfile"><h4>Added: branches/ftlopt/Source/JavaScriptCore/runtime/TypeSet.h (0 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/TypeSet.h         (rev 0)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/TypeSet.h        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -0,0 +1,90 @@
</span><ins>+/*
+ * Copyright (C) 2008, 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 TypeSet_h
+#define TypeSet_h
+
+#include <wtf/HashMap.h>
+#include <wtf/RefCounted.h>
+#include <wtf/text/WTFString.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+class JSValue;
+
+enum RuntimeType {
+ TypeNothing = 0x0,
+ TypeFunction = 0x1,
+ TypeUndefined = 0x2,
+ TypeNull = 0x4,
+ TypeBoolean = 0x8,
+ TypeMachineInt = 0x10,
+ TypeNumber = 0x20,
+ TypeString = 0x40,
+ TypePrimitive = 0x80,
+ TypeObject = 0x100
+};
+
+class StructureShape : public RefCounted<StructureShape> {
+ friend class TypeSet;
+
+public:
+ StructureShape();
+
+ static PassRefPtr<StructureShape> create() { return adoptRef(new StructureShape); }
+ String propertyHash();
+ void markAsFinal();
+ void addProperty(RefPtr<StringImpl>);
+ static String leastUpperBound(Vector<RefPtr<StructureShape>>*);
+ String stringRepresentation();
+
+private:
+ HashMap<RefPtr<StringImpl>, bool> m_fields;
+ std::unique_ptr<String> m_propertyHash;
+ bool m_final;
+};
+
+class TypeSet : public RefCounted<TypeSet> {
+
+public:
+ static PassRefPtr<TypeSet> create() { return adoptRef(new TypeSet); }
+ TypeSet();
+ void addTypeForValue(JSValue v, PassRefPtr<StructureShape>);
+ static RuntimeType getRuntimeTypeForValue(JSValue);
+ JS_EXPORT_PRIVATE String seenTypes();
+
+private:
+ uint32_t m_seenTypes;
+ void dumpSeenTypes();
+ Vector<RefPtr<StructureShape>>* m_structureHistory;
+ bool m_mightHaveDuplicatesInStructureHistory;
+ void removeDuplicatesInStructureHistory();
+
+};
+
+} //namespace JSC
+
+#endif //TypeSet_h
</ins></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/VM.cpp (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/VM.cpp        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/VM.cpp        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -47,6 +47,8 @@
</span><span class="cx"> #include "GetterSetter.h"
</span><span class="cx"> #include "Heap.h"
</span><span class="cx"> #include "HeapIterationScope.h"
</span><ins>+#include "HighFidelityTypeProfiler.h"
+#include "HighFidelityLog.h"
</ins><span class="cx"> #include "HostCallReturnValue.h"
</span><span class="cx"> #include "Identifier.h"
</span><span class="cx"> #include "IncrementalSweeper.h"
</span><span class="lines">@@ -88,6 +90,7 @@
</span><span class="cx"> #include <wtf/Threading.h>
</span><span class="cx"> #include <wtf/WTFThreadData.h>
</span><span class="cx"> #include <wtf/text/AtomicStringTable.h>
</span><ins>+#include <wtf/CurrentTime.h>
</ins><span class="cx">
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> #include "ConservativeRoots.h"
</span><span class="lines">@@ -236,6 +239,7 @@
</span><span class="cx"> , m_codeCache(CodeCache::create())
</span><span class="cx"> , m_enabledProfiler(nullptr)
</span><span class="cx"> , m_builtinExecutables(BuiltinExecutables::create(*this))
</span><ins>+ , m_nextUniqueVariableID(1)
</ins><span class="cx"> {
</span><span class="cx"> interpreter = new Interpreter(*this);
</span><span class="cx"> StackBounds stack = wtfThreadData().stack();
</span><span class="lines">@@ -326,6 +330,12 @@
</span><span class="cx"> // Initialize this last, as a free way of asserting that VM initialization itself
</span><span class="cx"> // won't use this.
</span><span class="cx"> m_typedArrayController = adoptRef(new SimpleTypedArrayController());
</span><ins>+
+ // FIXME: conditionally allocate this stuff based on whether or not the inspector is running OR this flag is enabled (not just if the flag is enabled).
+ if (Options::profileTypesWithHighFidelity()) {
+ m_highFidelityTypeProfiler = std::make_unique<HighFidelityTypeProfiler>();
+ m_highFidelityLog = std::make_unique<HighFidelityLog>();
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> VM::~VM()
</span><span class="lines">@@ -918,6 +928,46 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+String VM::getTypesForVariableInRange(unsigned startLine, unsigned startColumn, unsigned endLine, unsigned endColumn, const String& variableName, const String& sourceIDAsString)
+{
+ if (!isProfilingTypesWithHighFidelity())
+ return "(Not Profiling)";
+
+ bool okay;
+ intptr_t sourceID = sourceIDAsString.toIntPtrStrict(&okay);
+ if (!okay)
+ CRASH();
+
+ updateHighFidelityTypeProfileState();
+ return m_highFidelityTypeProfiler->getTypesForVariableInRange(startLine, startColumn, endLine, endColumn, variableName, sourceID);
+}
+
+void VM::updateHighFidelityTypeProfileState()
+{
+ if (!isProfilingTypesWithHighFidelity())
+ return;
+
+ highFidelityLog()->processHighFidelityLog(false, "VM Update");
+}
+
+void VM::dumpHighFidelityProfilingTypes()
+{
+ if (!isProfilingTypesWithHighFidelity())
+ return;
+
+ updateHighFidelityTypeProfileState();
+ HighFidelityTypeProfiler* profiler = m_highFidelityTypeProfiler.get();
+ for (Bag<TypeLocation>::iterator iter = m_locationInfo.begin(); !!iter; ++iter) {
+ TypeLocation* location = *iter;
+ dataLogF("[Line, Column]::[%u, %u] ", location->m_line, location->m_column);
+ dataLog("\n\t\t#Local#\n\t\t",
+ profiler->getLocalTypesForVariableInRange(location->m_line, location->m_column, location->m_line, location->m_column, "", location->m_sourceID).replace("\n", "\n\t\t"),
+ "\n\t\t#Global#\n\t\t",
+ profiler->getGlobalTypesForVariableInRange(location->m_line, location->m_column, location->m_line, location->m_column, "", location->m_sourceID).replace("\n", "\n\t\t"),
+ "\n");
+ }
+}
+
</ins><span class="cx"> void sanitizeStackForVM(VM* vm)
</span><span class="cx"> {
</span><span class="cx"> logSanitizeStack(vm);
</span></span></pre></div>
<a id="branchesftloptSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: branches/ftlopt/Source/JavaScriptCore/runtime/VM.h (170489 => 170490)</h4>
<pre class="diff"><span>
<span class="info">--- branches/ftlopt/Source/JavaScriptCore/runtime/VM.h        2014-06-26 19:21:41 UTC (rev 170489)
+++ branches/ftlopt/Source/JavaScriptCore/runtime/VM.h        2014-06-26 19:37:42 UTC (rev 170490)
</span><span class="lines">@@ -46,9 +46,11 @@
</span><span class="cx"> #include "Strong.h"
</span><span class="cx"> #include "ThunkGenerators.h"
</span><span class="cx"> #include "TypedArrayController.h"
</span><ins>+#include "TypeLocation.h"
</ins><span class="cx"> #include "Watchdog.h"
</span><span class="cx"> #include "Watchpoint.h"
</span><span class="cx"> #include "WeakRandom.h"
</span><ins>+#include <wtf/Bag.h>
</ins><span class="cx"> #include <wtf/BumpPointerAllocator.h>
</span><span class="cx"> #include <wtf/DateMath.h>
</span><span class="cx"> #include <wtf/Forward.h>
</span><span class="lines">@@ -74,6 +76,8 @@
</span><span class="cx"> class CommonIdentifiers;
</span><span class="cx"> class ExecState;
</span><span class="cx"> class HandleStack;
</span><ins>+ class HighFidelityTypeProfiler;
+ class HighFidelityLog;
</ins><span class="cx"> class Identifier;
</span><span class="cx"> class Interpreter;
</span><span class="cx"> class JSGlobalObject;
</span><span class="lines">@@ -84,6 +88,7 @@
</span><span class="cx"> class NativeExecutable;
</span><span class="cx"> class ParserArena;
</span><span class="cx"> class RegExpCache;
</span><ins>+ class ScriptExecutable;
</ins><span class="cx"> class SourceProvider;
</span><span class="cx"> class SourceProviderCache;
</span><span class="cx"> struct StackFrame;
</span><span class="lines">@@ -96,6 +101,7 @@
</span><span class="cx"> class UnlinkedEvalCodeBlock;
</span><span class="cx"> class UnlinkedFunctionExecutable;
</span><span class="cx"> class UnlinkedProgramCodeBlock;
</span><ins>+ class VirtualRegister;
</ins><span class="cx"> class VMEntryScope;
</span><span class="cx"> class Watchpoint;
</span><span class="cx"> class WatchpointSet;
</span><span class="lines">@@ -509,6 +515,15 @@
</span><span class="cx">
</span><span class="cx"> BuiltinExecutables* builtinExecutables() { return m_builtinExecutables.get(); }
</span><span class="cx">
</span><ins>+ bool isProfilingTypesWithHighFidelity() { return !!m_highFidelityTypeProfiler; }
+ String getTypesForVariableInRange(unsigned startLine, unsigned startColumn, unsigned endLine, unsigned endColumn, const String& variableName, const String& sourceID);
+ HighFidelityLog* highFidelityLog() { return m_highFidelityLog.get(); }
+ HighFidelityTypeProfiler* highFidelityTypeProfiler() { return m_highFidelityTypeProfiler.get(); }
+ void updateHighFidelityTypeProfileState();
+ 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
+ JS_EXPORT_PRIVATE void dumpHighFidelityProfilingTypes();
+ int64_t getNextUniqueVariableID() { return m_nextUniqueVariableID++; }
+
</ins><span class="cx"> private:
</span><span class="cx"> friend class LLIntOffsetsExtractor;
</span><span class="cx"> friend class ClearExceptionScope;
</span><span class="lines">@@ -557,6 +572,10 @@
</span><span class="cx"> OwnPtr<BuiltinExecutables> m_builtinExecutables;
</span><span class="cx"> RefCountedArray<StackFrame> m_exceptionStack;
</span><span class="cx"> HashMap<String, RefPtr<WatchpointSet>> m_impurePropertyWatchpointSets;
</span><ins>+ std::unique_ptr<HighFidelityTypeProfiler> m_highFidelityTypeProfiler;
+ std::unique_ptr<HighFidelityLog> m_highFidelityLog;
+ int64_t m_nextUniqueVariableID;
+ Bag<TypeLocation> m_locationInfo;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> #if ENABLE(GC_VALIDATION)
</span></span></pre>
</div>
</div>
</body>
</html>