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