<!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>[192321] trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/192321">192321</a></dd>
<dt>Author</dt> <dd>keith_miller@apple.com</dd>
<dt>Date</dt> <dd>2015-11-11 13:34:57 -0800 (Wed, 11 Nov 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>Regression(<a href="http://trac.webkit.org/projects/webkit/changeset/191815">r191815</a>): 5.3% regression on Dromaeo JS Library Benchmark
https://bugs.webkit.org/show_bug.cgi?id=150945
Reviewed by Filip Pizlo.
Source/JavaScriptCore:
This patch fixes a performance regression introduced by <a href="http://trac.webkit.org/projects/webkit/changeset/191815">r191815</a>. Before adding Symbol.toStringTag
we would cache the value of Object.prototype.toString() in the rareData of the structure.
In order to cache the result of Object.prototype.toString() we now need to ensure that the
value stored in Symbol.toStringTag is a known constant. Thus, in order to ensure the stored Symbol.toStringTag
value remains constant adaptive inferred value watchpoints have been re-factored to be generalizable and
a new version that clears the toString value cache when fired has been added.
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp: Copied from Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp.
(JSC::AdaptiveInferredPropertyValueWatchpointBase::AdaptiveInferredPropertyValueWatchpointBase):
(JSC::AdaptiveInferredPropertyValueWatchpointBase::install):
(JSC::AdaptiveInferredPropertyValueWatchpointBase::fire):
(JSC::AdaptiveInferredPropertyValueWatchpointBase::StructureWatchpoint::fireInternal):
(JSC::AdaptiveInferredPropertyValueWatchpointBase::PropertyWatchpoint::fireInternal):
* bytecode/AdaptiveInferredPropertyValueWatchpointBase.h: Copied from Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h.
(JSC::AdaptiveInferredPropertyValueWatchpointBase::key):
(JSC::AdaptiveInferredPropertyValueWatchpointBase::StructureWatchpoint::StructureWatchpoint):
(JSC::AdaptiveInferredPropertyValueWatchpointBase::PropertyWatchpoint::PropertyWatchpoint):
* dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp:
(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::AdaptiveInferredPropertyValueWatchpoint):
(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::handleFire):
(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::install): Deleted.
(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::fire): Deleted.
(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::StructureWatchpoint::fireInternal): Deleted.
(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::PropertyWatchpoint::fireInternal): Deleted.
* dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h:
(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::key): Deleted.
(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::StructureWatchpoint::StructureWatchpoint): Deleted.
(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::PropertyWatchpoint::PropertyWatchpoint): Deleted.
* runtime/ObjectPrototype.cpp:
(JSC::objectProtoFuncToString):
* runtime/Structure.h:
* runtime/StructureInlines.h:
(JSC::Structure::setObjectToStringValue):
* runtime/StructureRareData.cpp:
(JSC::StructureRareData::StructureRareData):
(JSC::StructureRareData::setObjectToStringValue):
(JSC::StructureRareData::clearObjectToStringValue):
(JSC::ObjectToStringAdaptiveStructureWatchpoint::ObjectToStringAdaptiveStructureWatchpoint):
(JSC::ObjectToStringAdaptiveStructureWatchpoint::install):
(JSC::ObjectToStringAdaptiveStructureWatchpoint::fireInternal):
(JSC::ObjectToStringAdaptiveInferredPropertyValueWatchpoint::ObjectToStringAdaptiveInferredPropertyValueWatchpoint):
(JSC::ObjectToStringAdaptiveInferredPropertyValueWatchpoint::handleFire):
* runtime/StructureRareData.h:
* runtime/StructureRareDataInlines.h:
(JSC::StructureRareData::setObjectToStringValue): Deleted.
* tests/stress/symbol-tostringtag-watchpoints.js: Added.
(Base):
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp: Copied from Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp.
(JSC::AdaptiveInferredPropertyValueWatchpointBase::AdaptiveInferredPropertyValueWatchpointBase):
(JSC::AdaptiveInferredPropertyValueWatchpointBase::install):
(JSC::AdaptiveInferredPropertyValueWatchpointBase::fire):
(JSC::AdaptiveInferredPropertyValueWatchpointBase::StructureWatchpoint::fireInternal):
(JSC::AdaptiveInferredPropertyValueWatchpointBase::PropertyWatchpoint::fireInternal):
* bytecode/AdaptiveInferredPropertyValueWatchpointBase.h: Copied from Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h.
(JSC::AdaptiveInferredPropertyValueWatchpointBase::key):
(JSC::AdaptiveInferredPropertyValueWatchpointBase::StructureWatchpoint::StructureWatchpoint):
(JSC::AdaptiveInferredPropertyValueWatchpointBase::PropertyWatchpoint::PropertyWatchpoint):
* dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp:
(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::AdaptiveInferredPropertyValueWatchpoint):
(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::handleFire):
(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::install): Deleted.
(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::fire): Deleted.
(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::StructureWatchpoint::fireInternal): Deleted.
(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::PropertyWatchpoint::fireInternal): Deleted.
* dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h:
(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::key): Deleted.
(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::StructureWatchpoint::StructureWatchpoint): Deleted.
(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::PropertyWatchpoint::PropertyWatchpoint): Deleted.
* runtime/ObjectPrototype.cpp:
(JSC::objectProtoFuncToString):
* runtime/Structure.h:
* runtime/StructureInlines.h:
(JSC::Structure::setObjectToStringValue):
* runtime/StructureRareData.cpp:
(JSC::StructureRareData::StructureRareData):
(JSC::StructureRareData::setObjectToStringValue):
(JSC::StructureRareData::clearObjectToStringValue):
(JSC::ObjectToStringAdaptiveStructureWatchpoint::ObjectToStringAdaptiveStructureWatchpoint):
(JSC::ObjectToStringAdaptiveStructureWatchpoint::install):
(JSC::ObjectToStringAdaptiveStructureWatchpoint::fireInternal):
(JSC::ObjectToStringAdaptiveInferredPropertyValueWatchpoint::ObjectToStringAdaptiveInferredPropertyValueWatchpoint):
(JSC::ObjectToStringAdaptiveInferredPropertyValueWatchpoint::handleFire):
* runtime/StructureRareData.h:
* runtime/StructureRareDataInlines.h:
(JSC::StructureRareData::setObjectToStringValue): Deleted.
* tests/stress/symbol-tostringtag-watchpoints.js: Added.
(Base):
LayoutTests:
Added a preformance regression test that checks the speed of Symbol.toStringTag.
The change to cross-origin-replace-history-object-child-expected.txt is a
result of the toString value being cached.
* http/tests/history/cross-origin-replace-history-object-child-expected.txt:
* js/regress/script-tests/symbol-tostringtag.js: Added.
(buildChain):
(body):
* js/regress/symbol-tostringtag-expected.txt: Added.
* js/regress/symbol-tostringtag.html: Added.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestshttptestshistorycrossoriginreplacehistoryobjectchildexpectedtxt">trunk/LayoutTests/http/tests/history/cross-origin-replace-history-object-child-expected.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAdaptiveInferredPropertyValueWatchpointcpp">trunk/Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAdaptiveInferredPropertyValueWatchpointh">trunk/Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeObjectPrototypecpp">trunk/Source/JavaScriptCore/runtime/ObjectPrototype.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStructureh">trunk/Source/JavaScriptCore/runtime/Structure.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStructureInlinesh">trunk/Source/JavaScriptCore/runtime/StructureInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStructureRareDatacpp">trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStructureRareDatah">trunk/Source/JavaScriptCore/runtime/StructureRareData.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStructureRareDataInlinesh">trunk/Source/JavaScriptCore/runtime/StructureRareDataInlines.h</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsregressscripttestssymboltostringtagjs">trunk/LayoutTests/js/regress/script-tests/symbol-tostringtag.js</a></li>
<li><a href="#trunkLayoutTestsjsregresssymboltostringtagexpectedtxt">trunk/LayoutTests/js/regress/symbol-tostringtag-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregresssymboltostringtaghtml">trunk/LayoutTests/js/regress/symbol-tostringtag.html</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeAdaptiveInferredPropertyValueWatchpointBasecpp">trunk/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeAdaptiveInferredPropertyValueWatchpointBaseh">trunk/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresssymboltostringtagwatchpointsjs">trunk/Source/JavaScriptCore/tests/stress/symbol-tostringtag-watchpoints.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (192320 => 192321)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-11-11 20:35:31 UTC (rev 192320)
+++ trunk/LayoutTests/ChangeLog        2015-11-11 21:34:57 UTC (rev 192321)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2015-11-10 Keith Miller <keith_miller@apple.com>
+
+ Regression(r191815): 5.3% regression on Dromaeo JS Library Benchmark
+ https://bugs.webkit.org/show_bug.cgi?id=150945
+
+ Reviewed by Filip Pizlo.
+
+ Added a preformance regression test that checks the speed of Symbol.toStringTag.
+ The change to cross-origin-replace-history-object-child-expected.txt is a
+ result of the toString value being cached.
+
+ * http/tests/history/cross-origin-replace-history-object-child-expected.txt:
+ * js/regress/script-tests/symbol-tostringtag.js: Added.
+ (buildChain):
+ (body):
+ * js/regress/symbol-tostringtag-expected.txt: Added.
+ * js/regress/symbol-tostringtag.html: Added.
+
</ins><span class="cx"> 2015-11-11 Jon Honeycutt <jhoneycutt@apple.com>
</span><span class="cx">
</span><span class="cx"> Fix a typo.
</span></span></pre></div>
<a id="trunkLayoutTestshttptestshistorycrossoriginreplacehistoryobjectchildexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/history/cross-origin-replace-history-object-child-expected.txt (192320 => 192321)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/history/cross-origin-replace-history-object-child-expected.txt        2015-11-11 20:35:31 UTC (rev 192320)
+++ trunk/LayoutTests/http/tests/history/cross-origin-replace-history-object-child-expected.txt        2015-11-11 21:34:57 UTC (rev 192321)
</span><span class="lines">@@ -4,6 +4,5 @@
</span><span class="cx"> ALERT: About to shadow child window's history object: [object History]
</span><span class="cx"> ALERT: Shadowed child window's history object:
</span><span class="cx"> CONSOLE MESSAGE: line 18: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
</span><del>-CONSOLE MESSAGE: line 18: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
</del><span class="cx"> ALERT: Child window's history object after attempt to clear: [object History]
</span><span class="cx">
</span></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestssymboltostringtagjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/symbol-tostringtag.js (0 => 192321)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/symbol-tostringtag.js         (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/symbol-tostringtag.js        2015-11-11 21:34:57 UTC (rev 192321)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+// Create a really long prototype chain.
+
+// We need to put values on so the objects are not empty and have transition
+// watchpoints.
+function buildChain(depth) {
+ if (depth <= 0)
+ return { bloop: 1 };
+ let result = { value: 1 };
+ Object.setPrototypeOf(result, buildChain(depth - 1));
+ return result;
+}
+
+
+var object = buildChain(20);
+
+function body() {
+ for (let i = 0; i < 100000; i++)
+ value = object.toString();
+}
+noInline(body);
+
+// Try toString with misses.
+body();
+
+Object.prototype[Symbol.toStringTag] = "hit";
+
+// Try toString with hit.
+body();
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresssymboltostringtagexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/symbol-tostringtag-expected.txt (0 => 192321)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/symbol-tostringtag-expected.txt         (rev 0)
+++ trunk/LayoutTests/js/regress/symbol-tostringtag-expected.txt        2015-11-11 21:34:57 UTC (rev 192321)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/symbol-tostringtag
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresssymboltostringtaghtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/symbol-tostringtag.html (0 => 192321)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/symbol-tostringtag.html         (rev 0)
+++ trunk/LayoutTests/js/regress/symbol-tostringtag.html        2015-11-11 21:34:57 UTC (rev 192321)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="../../resources/regress-pre.js"></script>
+<script src="script-tests/symbol-tostringtag.js"></script>
+<script src="../../resources/regress-post.js"></script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (192320 => 192321)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2015-11-11 20:35:31 UTC (rev 192320)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2015-11-11 21:34:57 UTC (rev 192321)
</span><span class="lines">@@ -133,6 +133,7 @@
</span><span class="cx">
</span><span class="cx"> builtins/BuiltinExecutables.cpp
</span><span class="cx">
</span><ins>+ bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp
</ins><span class="cx"> bytecode/ArrayAllocationProfile.cpp
</span><span class="cx"> bytecode/ArrayProfile.cpp
</span><span class="cx"> bytecode/BytecodeBasicBlock.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (192320 => 192321)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-11-11 20:35:31 UTC (rev 192320)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-11-11 21:34:57 UTC (rev 192321)
</span><span class="lines">@@ -1,3 +1,102 @@
</span><ins>+2015-11-10 Keith Miller <keith_miller@apple.com>
+
+ Regression(r191815): 5.3% regression on Dromaeo JS Library Benchmark
+ https://bugs.webkit.org/show_bug.cgi?id=150945
+
+ Reviewed by Filip Pizlo.
+
+ This patch fixes a performance regression introduced by r191815. Before adding Symbol.toStringTag
+ we would cache the value of Object.prototype.toString() in the rareData of the structure.
+ In order to cache the result of Object.prototype.toString() we now need to ensure that the
+ value stored in Symbol.toStringTag is a known constant. Thus, in order to ensure the stored Symbol.toStringTag
+ value remains constant adaptive inferred value watchpoints have been re-factored to be generalizable and
+ a new version that clears the toString value cache when fired has been added.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp: Copied from Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp.
+ (JSC::AdaptiveInferredPropertyValueWatchpointBase::AdaptiveInferredPropertyValueWatchpointBase):
+ (JSC::AdaptiveInferredPropertyValueWatchpointBase::install):
+ (JSC::AdaptiveInferredPropertyValueWatchpointBase::fire):
+ (JSC::AdaptiveInferredPropertyValueWatchpointBase::StructureWatchpoint::fireInternal):
+ (JSC::AdaptiveInferredPropertyValueWatchpointBase::PropertyWatchpoint::fireInternal):
+ * bytecode/AdaptiveInferredPropertyValueWatchpointBase.h: Copied from Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h.
+ (JSC::AdaptiveInferredPropertyValueWatchpointBase::key):
+ (JSC::AdaptiveInferredPropertyValueWatchpointBase::StructureWatchpoint::StructureWatchpoint):
+ (JSC::AdaptiveInferredPropertyValueWatchpointBase::PropertyWatchpoint::PropertyWatchpoint):
+ * dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp:
+ (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::AdaptiveInferredPropertyValueWatchpoint):
+ (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::handleFire):
+ (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::install): Deleted.
+ (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::fire): Deleted.
+ (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::StructureWatchpoint::fireInternal): Deleted.
+ (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::PropertyWatchpoint::fireInternal): Deleted.
+ * dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h:
+ (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::key): Deleted.
+ (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::StructureWatchpoint::StructureWatchpoint): Deleted.
+ (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::PropertyWatchpoint::PropertyWatchpoint): Deleted.
+ * runtime/ObjectPrototype.cpp:
+ (JSC::objectProtoFuncToString):
+ * runtime/Structure.h:
+ * runtime/StructureInlines.h:
+ (JSC::Structure::setObjectToStringValue):
+ * runtime/StructureRareData.cpp:
+ (JSC::StructureRareData::StructureRareData):
+ (JSC::StructureRareData::setObjectToStringValue):
+ (JSC::StructureRareData::clearObjectToStringValue):
+ (JSC::ObjectToStringAdaptiveStructureWatchpoint::ObjectToStringAdaptiveStructureWatchpoint):
+ (JSC::ObjectToStringAdaptiveStructureWatchpoint::install):
+ (JSC::ObjectToStringAdaptiveStructureWatchpoint::fireInternal):
+ (JSC::ObjectToStringAdaptiveInferredPropertyValueWatchpoint::ObjectToStringAdaptiveInferredPropertyValueWatchpoint):
+ (JSC::ObjectToStringAdaptiveInferredPropertyValueWatchpoint::handleFire):
+ * runtime/StructureRareData.h:
+ * runtime/StructureRareDataInlines.h:
+ (JSC::StructureRareData::setObjectToStringValue): Deleted.
+ * tests/stress/symbol-tostringtag-watchpoints.js: Added.
+ (Base):
+
+ * CMakeLists.txt:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp: Copied from Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp.
+ (JSC::AdaptiveInferredPropertyValueWatchpointBase::AdaptiveInferredPropertyValueWatchpointBase):
+ (JSC::AdaptiveInferredPropertyValueWatchpointBase::install):
+ (JSC::AdaptiveInferredPropertyValueWatchpointBase::fire):
+ (JSC::AdaptiveInferredPropertyValueWatchpointBase::StructureWatchpoint::fireInternal):
+ (JSC::AdaptiveInferredPropertyValueWatchpointBase::PropertyWatchpoint::fireInternal):
+ * bytecode/AdaptiveInferredPropertyValueWatchpointBase.h: Copied from Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h.
+ (JSC::AdaptiveInferredPropertyValueWatchpointBase::key):
+ (JSC::AdaptiveInferredPropertyValueWatchpointBase::StructureWatchpoint::StructureWatchpoint):
+ (JSC::AdaptiveInferredPropertyValueWatchpointBase::PropertyWatchpoint::PropertyWatchpoint):
+ * dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp:
+ (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::AdaptiveInferredPropertyValueWatchpoint):
+ (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::handleFire):
+ (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::install): Deleted.
+ (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::fire): Deleted.
+ (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::StructureWatchpoint::fireInternal): Deleted.
+ (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::PropertyWatchpoint::fireInternal): Deleted.
+ * dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h:
+ (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::key): Deleted.
+ (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::StructureWatchpoint::StructureWatchpoint): Deleted.
+ (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::PropertyWatchpoint::PropertyWatchpoint): Deleted.
+ * runtime/ObjectPrototype.cpp:
+ (JSC::objectProtoFuncToString):
+ * runtime/Structure.h:
+ * runtime/StructureInlines.h:
+ (JSC::Structure::setObjectToStringValue):
+ * runtime/StructureRareData.cpp:
+ (JSC::StructureRareData::StructureRareData):
+ (JSC::StructureRareData::setObjectToStringValue):
+ (JSC::StructureRareData::clearObjectToStringValue):
+ (JSC::ObjectToStringAdaptiveStructureWatchpoint::ObjectToStringAdaptiveStructureWatchpoint):
+ (JSC::ObjectToStringAdaptiveStructureWatchpoint::install):
+ (JSC::ObjectToStringAdaptiveStructureWatchpoint::fireInternal):
+ (JSC::ObjectToStringAdaptiveInferredPropertyValueWatchpoint::ObjectToStringAdaptiveInferredPropertyValueWatchpoint):
+ (JSC::ObjectToStringAdaptiveInferredPropertyValueWatchpoint::handleFire):
+ * runtime/StructureRareData.h:
+ * runtime/StructureRareDataInlines.h:
+ (JSC::StructureRareData::setObjectToStringValue): Deleted.
+ * tests/stress/symbol-tostringtag-watchpoints.js: Added.
+ (Base):
+
</ins><span class="cx"> 2015-11-11 Filip Pizlo <fpizlo@apple.com>
</span><span class="cx">
</span><span class="cx"> B3 should be able to compile and canonicalize Mul
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (192320 => 192321)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-11-11 20:35:31 UTC (rev 192320)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-11-11 21:34:57 UTC (rev 192321)
</span><span class="lines">@@ -286,7 +286,7 @@
</span><span class="cx">                 0F338DF61BE93D550013C88F /* B3ConstrainedValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338DF41BE93D550013C88F /* B3ConstrainedValue.h */; };
</span><span class="cx">                 0F338DF91BE96AA80013C88F /* B3CCallValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F338DF71BE96AA80013C88F /* B3CCallValue.cpp */; };
</span><span class="cx">                 0F338DFA1BE96AA80013C88F /* B3CCallValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338DF81BE96AA80013C88F /* B3CCallValue.h */; };
</span><del>-                0F338DFD1BED51270013C88F /* AirSimplifyCFG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F338DFB1BED51270013C88F /* AirSimplifyCFG.cpp */; };
</del><ins>+ 0F338DFD1BED51270013C88F /* AirSimplifyCFG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F338DFB1BED51270013C88F /* AirSimplifyCFG.cpp */; };
</ins><span class="cx">                 0F338DFE1BED51270013C88F /* AirSimplifyCFG.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338DFC1BED51270013C88F /* AirSimplifyCFG.h */; };
</span><span class="cx">                 0F338E0B1BF0276C0013C88F /* B3Compilation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F338DFF1BF0276C0013C88F /* B3Compilation.cpp */; };
</span><span class="cx">                 0F338E0C1BF0276C0013C88F /* B3Compilation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338E001BF0276C0013C88F /* B3Compilation.h */; };
</span><span class="lines">@@ -300,12 +300,12 @@
</span><span class="cx">                 0F338E141BF0276C0013C88F /* B3ValueKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F338E081BF0276C0013C88F /* B3ValueKey.cpp */; };
</span><span class="cx">                 0F338E151BF0276C0013C88F /* B3ValueKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338E091BF0276C0013C88F /* B3ValueKey.h */; };
</span><span class="cx">                 0F338E161BF0276C0013C88F /* B3ValueKeyInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338E0A1BF0276C0013C88F /* B3ValueKeyInlines.h */; };
</span><del>-                0F338E1B1BF286EA0013C88F /* B3BlockInsertionSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F338E171BF286EA0013C88F /* B3BlockInsertionSet.cpp */; };
</del><ins>+ 0F338E1B1BF286EA0013C88F /* B3BlockInsertionSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F338E171BF286EA0013C88F /* B3BlockInsertionSet.cpp */; };
</ins><span class="cx">                 0F338E1C1BF286EA0013C88F /* B3BlockInsertionSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338E181BF286EA0013C88F /* B3BlockInsertionSet.h */; };
</span><span class="cx">                 0F338E1D1BF286EA0013C88F /* B3LowerMacros.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F338E191BF286EA0013C88F /* B3LowerMacros.cpp */; };
</span><span class="cx">                 0F338E1E1BF286EA0013C88F /* B3LowerMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338E1A1BF286EA0013C88F /* B3LowerMacros.h */; };
</span><span class="cx">                 0F34B14916D42010001CDA5A /* DFGUseKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */; };
</span><del>-                0F34B14A16D42013001CDA5A /* DFGUseKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F34B14816D4200E001CDA5A /* DFGUseKind.h */; };
</del><ins>+ 0F34B14A16D42013001CDA5A /* DFGUseKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F34B14816D4200E001CDA5A /* DFGUseKind.h */; };
</ins><span class="cx">                 0F38B01117CF078000B144D3 /* LLIntEntrypoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F38B00F17CF077F00B144D3 /* LLIntEntrypoint.cpp */; };
</span><span class="cx">                 0F38B01217CF078300B144D3 /* LLIntEntrypoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F38B01017CF077F00B144D3 /* LLIntEntrypoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F38B01717CFE75500B144D3 /* DFGCompilationKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F38B01317CFE75500B144D3 /* DFGCompilationKey.cpp */; };
</span><span class="lines">@@ -1128,6 +1128,8 @@
</span><span class="cx">                 52C952B919A28A1C0069B386 /* TypeProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52C952B819A28A1C0069B386 /* TypeProfiler.cpp */; };
</span><span class="cx">                 534C457C1BC72411007476A7 /* JSTypedArrayViewConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 534C457B1BC72411007476A7 /* JSTypedArrayViewConstructor.h */; };
</span><span class="cx">                 534C457E1BC72549007476A7 /* JSTypedArrayViewConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 534C457D1BC72549007476A7 /* JSTypedArrayViewConstructor.cpp */; };
</span><ins>+                5370B4F51BF26202005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5370B4F31BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp */; };
+                5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */; };
</ins><span class="cx">                 53917E7B1B7906FA000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */; };
</span><span class="cx">                 5D53726F0E1C54880021E549 /* Tracing.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D53726E0E1C54880021E549 /* Tracing.h */; };
</span><span class="cx">                 5D5D8AD10E0D0EBE00F9C692 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; };
</span><span class="lines">@@ -2333,7 +2335,7 @@
</span><span class="cx">                 0F338DF41BE93D550013C88F /* B3ConstrainedValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3ConstrainedValue.h; path = b3/B3ConstrainedValue.h; sourceTree = "<group>"; };
</span><span class="cx">                 0F338DF71BE96AA80013C88F /* B3CCallValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3CCallValue.cpp; path = b3/B3CCallValue.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0F338DF81BE96AA80013C88F /* B3CCallValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3CCallValue.h; path = b3/B3CCallValue.h; sourceTree = "<group>"; };
</span><del>-                0F338DFB1BED51270013C88F /* AirSimplifyCFG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirSimplifyCFG.cpp; path = b3/air/AirSimplifyCFG.cpp; sourceTree = "<group>"; };
</del><ins>+ 0F338DFB1BED51270013C88F /* AirSimplifyCFG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirSimplifyCFG.cpp; path = b3/air/AirSimplifyCFG.cpp; sourceTree = "<group>"; };
</ins><span class="cx">                 0F338DFC1BED51270013C88F /* AirSimplifyCFG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirSimplifyCFG.h; path = b3/air/AirSimplifyCFG.h; sourceTree = "<group>"; };
</span><span class="cx">                 0F338DFF1BF0276C0013C88F /* B3Compilation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3Compilation.cpp; path = b3/B3Compilation.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0F338E001BF0276C0013C88F /* B3Compilation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3Compilation.h; path = b3/B3Compilation.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -2347,12 +2349,12 @@
</span><span class="cx">                 0F338E081BF0276C0013C88F /* B3ValueKey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3ValueKey.cpp; path = b3/B3ValueKey.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0F338E091BF0276C0013C88F /* B3ValueKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3ValueKey.h; path = b3/B3ValueKey.h; sourceTree = "<group>"; };
</span><span class="cx">                 0F338E0A1BF0276C0013C88F /* B3ValueKeyInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3ValueKeyInlines.h; path = b3/B3ValueKeyInlines.h; sourceTree = "<group>"; };
</span><del>-                0F338E171BF286EA0013C88F /* B3BlockInsertionSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3BlockInsertionSet.cpp; path = b3/B3BlockInsertionSet.cpp; sourceTree = "<group>"; };
</del><ins>+ 0F338E171BF286EA0013C88F /* B3BlockInsertionSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3BlockInsertionSet.cpp; path = b3/B3BlockInsertionSet.cpp; sourceTree = "<group>"; };
</ins><span class="cx">                 0F338E181BF286EA0013C88F /* B3BlockInsertionSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3BlockInsertionSet.h; path = b3/B3BlockInsertionSet.h; sourceTree = "<group>"; };
</span><span class="cx">                 0F338E191BF286EA0013C88F /* B3LowerMacros.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3LowerMacros.cpp; path = b3/B3LowerMacros.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0F338E1A1BF286EA0013C88F /* B3LowerMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3LowerMacros.h; path = b3/B3LowerMacros.h; sourceTree = "<group>"; };
</span><span class="cx">                 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGUseKind.cpp; path = dfg/DFGUseKind.cpp; sourceTree = "<group>"; };
</span><del>-                0F34B14816D4200E001CDA5A /* DFGUseKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGUseKind.h; path = dfg/DFGUseKind.h; sourceTree = "<group>"; };
</del><ins>+ 0F34B14816D4200E001CDA5A /* DFGUseKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGUseKind.h; path = dfg/DFGUseKind.h; sourceTree = "<group>"; };
</ins><span class="cx">                 0F38B00F17CF077F00B144D3 /* LLIntEntrypoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntEntrypoint.cpp; path = llint/LLIntEntrypoint.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0F38B01017CF077F00B144D3 /* LLIntEntrypoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LLIntEntrypoint.h; path = llint/LLIntEntrypoint.h; sourceTree = "<group>"; };
</span><span class="cx">                 0F38B01317CFE75500B144D3 /* DFGCompilationKey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCompilationKey.cpp; path = dfg/DFGCompilationKey.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -3147,6 +3149,8 @@
</span><span class="cx">                 534C457A1BC703DC007476A7 /* TypedArrayConstructor.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = TypedArrayConstructor.js; sourceTree = "<group>"; };
</span><span class="cx">                 534C457B1BC72411007476A7 /* JSTypedArrayViewConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypedArrayViewConstructor.h; sourceTree = "<group>"; };
</span><span class="cx">                 534C457D1BC72549007476A7 /* JSTypedArrayViewConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTypedArrayViewConstructor.cpp; sourceTree = "<group>"; };
</span><ins>+                5370B4F31BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AdaptiveInferredPropertyValueWatchpointBase.cpp; sourceTree = "<group>"; };
+                5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AdaptiveInferredPropertyValueWatchpointBase.h; sourceTree = "<group>"; };
</ins><span class="cx">                 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGenericTypedArrayViewPrototypeFunctions.h; sourceTree = "<group>"; };
</span><span class="cx">                 53917E7C1B791106000EBD33 /* JSTypedArrayViewPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypedArrayViewPrototype.h; sourceTree = "<group>"; };
</span><span class="cx">                 53917E831B791CB8000EBD33 /* TypedArray.prototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = TypedArray.prototype.js; path = builtins/TypedArray.prototype.js; sourceTree = SOURCE_ROOT; };
</span><span class="lines">@@ -6167,6 +6171,8 @@
</span><span class="cx">                 969A078F0ED1D3AE00F1F681 /* bytecode */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                5370B4F31BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp */,
+                                5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */,
</ins><span class="cx">                                 0F8335B41639C1E3001443B5 /* ArrayAllocationProfile.cpp */,
</span><span class="cx">                                 0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */,
</span><span class="cx">                                 0F63945115D07051006A597C /* ArrayProfile.cpp */,
</span><span class="lines">@@ -7639,6 +7645,7 @@
</span><span class="cx">                                 0FFB6C391AF48DDC00DB1BF7 /* TypeofType.h in Headers */,
</span><span class="cx">                                 52C952B719A289850069B386 /* TypeProfiler.h in Headers */,
</span><span class="cx">                                 0F2D4DEC19832DC4007D4B19 /* TypeProfilerLog.h in Headers */,
</span><ins>+                                5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */,
</ins><span class="cx">                                 0F2D4DF019832DD6007D4B19 /* TypeSet.h in Headers */,
</span><span class="cx">                                 0FF4274B158EBE91004CB9FF /* udis86.h in Headers */,
</span><span class="cx">                                 0FF42741158EBE8D004CB9FF /* udis86_decode.h in Headers */,
</span><span class="lines">@@ -8739,6 +8746,7 @@
</span><span class="cx">                                 A7482B9411671147003B0712 /* JSWeakObjectMapRefPrivate.cpp in Sources */,
</span><span class="cx">                                 709FB8671AE335C60039D069 /* JSWeakSet.cpp in Sources */,
</span><span class="cx">                                 1442566115EDE98D0066A49B /* JSWithScope.cpp in Sources */,
</span><ins>+                                5370B4F51BF26202005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp in Sources */,
</ins><span class="cx">                                 86E3C618167BABEE006D760A /* JSWrapperMap.mm in Sources */,
</span><span class="cx">                                 14280870107EC1340013E7B2 /* JSWrapperObject.cpp in Sources */,
</span><span class="cx">                                 BCFD8C920EEB2EE700283848 /* JumpTable.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeAdaptiveInferredPropertyValueWatchpointBasecppfromrev192320trunkSourceJavaScriptCoredfgDFGAdaptiveInferredPropertyValueWatchpointcpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp (from rev 192320, trunk/Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp) (0 => 192321)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp         (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp        2015-11-11 21:34:57 UTC (rev 192321)
</span><span class="lines">@@ -0,0 +1,87 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AdaptiveInferredPropertyValueWatchpointBase.h"
+
+#include "JSCellInlines.h"
+#include "StructureInlines.h"
+
+namespace JSC {
+
+AdaptiveInferredPropertyValueWatchpointBase::AdaptiveInferredPropertyValueWatchpointBase(const ObjectPropertyCondition& key)
+ : m_key(key)
+{
+ RELEASE_ASSERT(key.kind() == PropertyCondition::Equivalence);
+}
+
+void AdaptiveInferredPropertyValueWatchpointBase::install()
+{
+ RELEASE_ASSERT(m_key.isWatchable());
+
+ m_key.object()->structure()->addTransitionWatchpoint(&m_structureWatchpoint);
+
+ PropertyOffset offset = m_key.object()->structure()->getConcurrently(m_key.uid());
+ WatchpointSet* set = m_key.object()->structure()->propertyReplacementWatchpointSet(offset);
+ set->add(&m_propertyWatchpoint);
+}
+
+void AdaptiveInferredPropertyValueWatchpointBase::fire(const FireDetail& detail)
+{
+ // One of the watchpoints fired, but the other one didn't. Make sure that neither of them are
+ // in any set anymore. This simplifies things by allowing us to reinstall the watchpoints
+ // wherever from scratch.
+ if (m_structureWatchpoint.isOnList())
+ m_structureWatchpoint.remove();
+ if (m_propertyWatchpoint.isOnList())
+ m_propertyWatchpoint.remove();
+
+ if (m_key.isWatchable(PropertyCondition::EnsureWatchability)) {
+ install();
+ return;
+ }
+
+ handleFire(detail);
+}
+
+void AdaptiveInferredPropertyValueWatchpointBase::StructureWatchpoint::fireInternal(const FireDetail& detail)
+{
+ ptrdiff_t myOffset = OBJECT_OFFSETOF(AdaptiveInferredPropertyValueWatchpointBase, m_structureWatchpoint);
+
+ AdaptiveInferredPropertyValueWatchpointBase* parent = bitwise_cast<AdaptiveInferredPropertyValueWatchpointBase*>(bitwise_cast<char*>(this) - myOffset);
+
+ parent->fire(detail);
+}
+
+void AdaptiveInferredPropertyValueWatchpointBase::PropertyWatchpoint::fireInternal(const FireDetail& detail)
+{
+ ptrdiff_t myOffset = OBJECT_OFFSETOF(AdaptiveInferredPropertyValueWatchpointBase, m_propertyWatchpoint);
+
+ AdaptiveInferredPropertyValueWatchpointBase* parent = bitwise_cast<AdaptiveInferredPropertyValueWatchpointBase*>(bitwise_cast<char*>(this) - myOffset);
+
+ parent->fire(detail);
+}
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeAdaptiveInferredPropertyValueWatchpointBasehfromrev192320trunkSourceJavaScriptCoredfgDFGAdaptiveInferredPropertyValueWatchpointh"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.h (from rev 192320, trunk/Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h) (0 => 192321)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.h         (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.h        2015-11-11 21:34:57 UTC (rev 192321)
</span><span class="lines">@@ -0,0 +1,75 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AdaptiveInferredPropertyValueWatchpointBase_h
+#define AdaptiveInferredPropertyValueWatchpointBase_h
+
+#include "ObjectPropertyCondition.h"
+#include "Watchpoint.h"
+#include <wtf/FastMalloc.h>
+#include <wtf/Noncopyable.h>
+
+namespace JSC {
+
+class AdaptiveInferredPropertyValueWatchpointBase {
+ WTF_MAKE_NONCOPYABLE(AdaptiveInferredPropertyValueWatchpointBase);
+ WTF_MAKE_FAST_ALLOCATED;
+
+public:
+ AdaptiveInferredPropertyValueWatchpointBase(const ObjectPropertyCondition&);
+
+ const ObjectPropertyCondition& key() const { return m_key; }
+
+ void install();
+
+ virtual ~AdaptiveInferredPropertyValueWatchpointBase() = default;
+
+protected:
+ virtual void handleFire(const FireDetail&) = 0;
+
+private:
+ class StructureWatchpoint : public Watchpoint {
+ public:
+ StructureWatchpoint() { }
+ protected:
+ virtual void fireInternal(const FireDetail&) override;
+ };
+ class PropertyWatchpoint : public Watchpoint {
+ public:
+ PropertyWatchpoint() { }
+ protected:
+ virtual void fireInternal(const FireDetail&) override;
+ };
+
+ void fire(const FireDetail&);
+
+ ObjectPropertyCondition m_key;
+ StructureWatchpoint m_structureWatchpoint;
+ PropertyWatchpoint m_propertyWatchpoint;
+};
+
+} // namespace JSC
+
+#endif /* AdaptiveInferredPropertyValueWatchpointBase_h */
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAdaptiveInferredPropertyValueWatchpointcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp (192320 => 192321)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp        2015-11-11 20:35:31 UTC (rev 192320)
+++ trunk/Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp        2015-11-11 21:34:57 UTC (rev 192321)
</span><span class="lines">@@ -34,81 +34,26 @@
</span><span class="cx">
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx">
</span><del>-AdaptiveInferredPropertyValueWatchpoint::AdaptiveInferredPropertyValueWatchpoint(
- const ObjectPropertyCondition& key,
- CodeBlock* codeBlock)
- : m_key(key)
</del><ins>+AdaptiveInferredPropertyValueWatchpoint::AdaptiveInferredPropertyValueWatchpoint(const ObjectPropertyCondition& key, CodeBlock* codeBlock)
+ : Base(key)
</ins><span class="cx"> , m_codeBlock(codeBlock)
</span><span class="cx"> {
</span><del>- RELEASE_ASSERT(key.kind() == PropertyCondition::Equivalence);
</del><span class="cx"> }
</span><span class="cx">
</span><del>-void AdaptiveInferredPropertyValueWatchpoint::install()
</del><ins>+void AdaptiveInferredPropertyValueWatchpoint::handleFire(const FireDetail& detail)
</ins><span class="cx"> {
</span><del>- RELEASE_ASSERT(m_key.isWatchable());
-
- m_key.object()->structure()->addTransitionWatchpoint(&m_structureWatchpoint);
-
- PropertyOffset offset = m_key.object()->structure()->getConcurrently(m_key.uid());
- WatchpointSet* set = m_key.object()->structure()->propertyReplacementWatchpointSet(offset);
- set->add(&m_propertyWatchpoint);
-}
</del><ins>+ if (DFG::shouldDumpDisassembly())
+ dataLog("Firing watchpoint ", RawPointer(this), " (", key(), ") on ", *m_codeBlock, "\n");
</ins><span class="cx">
</span><del>-void AdaptiveInferredPropertyValueWatchpoint::fire(const FireDetail& detail)
-{
- // One of the watchpoints fired, but the other one didn't. Make sure that neither of them are
- // in any set anymore. This simplifies things by allowing us to reinstall the watchpoints
- // wherever from scratch.
- if (m_structureWatchpoint.isOnList())
- m_structureWatchpoint.remove();
- if (m_propertyWatchpoint.isOnList())
- m_propertyWatchpoint.remove();
-
- if (m_key.isWatchable(PropertyCondition::EnsureWatchability)) {
- install();
- return;
- }
-
- if (DFG::shouldDumpDisassembly()) {
- dataLog(
- "Firing watchpoint ", RawPointer(this), " (", m_key, ") on ", *m_codeBlock, "\n");
- }
-
</del><ins>+
</ins><span class="cx"> StringPrintStream out;
</span><del>- out.print("Adaptation of ", m_key, " failed: ", detail);
-
</del><ins>+ out.print("Adaptation of ", key(), " failed: ", detail);
+
</ins><span class="cx"> StringFireDetail stringDetail(out.toCString().data());
</span><del>-
- m_codeBlock->jettison(
- Profiler::JettisonDueToUnprofiledWatchpoint, CountReoptimization, &stringDetail);
-}
</del><span class="cx">
</span><del>-void AdaptiveInferredPropertyValueWatchpoint::StructureWatchpoint::fireInternal(
- const FireDetail& detail)
-{
- ptrdiff_t myOffset = OBJECT_OFFSETOF(
- AdaptiveInferredPropertyValueWatchpoint, m_structureWatchpoint);
-
- AdaptiveInferredPropertyValueWatchpoint* parent =
- bitwise_cast<AdaptiveInferredPropertyValueWatchpoint*>(
- bitwise_cast<char*>(this) - myOffset);
-
- parent->fire(detail);
</del><ins>+ m_codeBlock->jettison(Profiler::JettisonDueToUnprofiledWatchpoint, CountReoptimization, &stringDetail);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void AdaptiveInferredPropertyValueWatchpoint::PropertyWatchpoint::fireInternal(
- const FireDetail& detail)
-{
- ptrdiff_t myOffset = OBJECT_OFFSETOF(
- AdaptiveInferredPropertyValueWatchpoint, m_propertyWatchpoint);
-
- AdaptiveInferredPropertyValueWatchpoint* parent =
- bitwise_cast<AdaptiveInferredPropertyValueWatchpoint*>(
- bitwise_cast<char*>(this) - myOffset);
-
- parent->fire(detail);
-}
-
</del><span class="cx"> } } // namespace JSC::DFG
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(DFG_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAdaptiveInferredPropertyValueWatchpointh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h (192320 => 192321)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h        2015-11-11 20:35:31 UTC (rev 192320)
+++ trunk/Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h        2015-11-11 21:34:57 UTC (rev 192321)
</span><span class="lines">@@ -28,44 +28,19 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx">
</span><del>-#include "ObjectPropertyCondition.h"
-#include "Watchpoint.h"
-#include <wtf/FastMalloc.h>
-#include <wtf/Noncopyable.h>
</del><ins>+#include "AdaptiveInferredPropertyValueWatchpointBase.h"
</ins><span class="cx">
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx">
</span><del>-class AdaptiveInferredPropertyValueWatchpoint {
- WTF_MAKE_NONCOPYABLE(AdaptiveInferredPropertyValueWatchpoint);
- WTF_MAKE_FAST_ALLOCATED;
-
</del><ins>+class AdaptiveInferredPropertyValueWatchpoint : public AdaptiveInferredPropertyValueWatchpointBase {
</ins><span class="cx"> public:
</span><ins>+ typedef AdaptiveInferredPropertyValueWatchpointBase Base;
</ins><span class="cx"> AdaptiveInferredPropertyValueWatchpoint(const ObjectPropertyCondition&, CodeBlock*);
</span><del>-
- const ObjectPropertyCondition& key() const { return m_key; }
-
- void install();
</del><span class="cx">
</span><span class="cx"> private:
</span><del>- class StructureWatchpoint : public Watchpoint {
- public:
- StructureWatchpoint() { }
- protected:
- virtual void fireInternal(const FireDetail&) override;
- };
- class PropertyWatchpoint : public Watchpoint {
- public:
- PropertyWatchpoint() { }
- protected:
- virtual void fireInternal(const FireDetail&) override;
- };
-
- void fire(const FireDetail&);
-
- ObjectPropertyCondition m_key;
</del><ins>+ virtual void handleFire(const FireDetail&) override;
+
</ins><span class="cx"> CodeBlock* m_codeBlock;
</span><del>- StructureWatchpoint m_structureWatchpoint;
- PropertyWatchpoint m_propertyWatchpoint;
</del><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } } // namespace JSC::DFG
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeObjectPrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ObjectPrototype.cpp (192320 => 192321)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ObjectPrototype.cpp        2015-11-11 20:35:31 UTC (rev 192320)
+++ trunk/Source/JavaScriptCore/runtime/ObjectPrototype.cpp        2015-11-11 21:34:57 UTC (rev 192321)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> #include "JSString.h"
</span><span class="cx"> #include "JSCInlines.h"
</span><span class="cx"> #include "PropertySlot.h"
</span><ins>+#include "StructureInlines.h"
</ins><span class="cx"> #include "StructureRareDataInlines.h"
</span><span class="cx">
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -244,24 +245,32 @@
</span><span class="cx"> return JSValue::encode(thisValue.isUndefined() ? vm.smallStrings.undefinedObjectString() : vm.smallStrings.nullObjectString());
</span><span class="cx"> JSObject* thisObject = thisValue.toObject(exec);
</span><span class="cx">
</span><del>- JSValue stringTag = thisObject->get(exec, exec->propertyNames().toStringTagSymbol);
- if (stringTag.isString()) {
- JSRopeString::RopeBuilder ropeBuilder(vm);
- ropeBuilder.append(vm.smallStrings.objectStringStart());
- ropeBuilder.append(jsCast<JSString*>(stringTag));
- ropeBuilder.append(vm.smallStrings.singleCharacterString(']'));
- return JSValue::encode(ropeBuilder.release());
- }
-
</del><span class="cx"> JSString* result = thisObject->structure(vm)->objectToStringValue();
</span><span class="cx"> if (!result) {
</span><ins>+ PropertyName toStringTagSymbol = exec->propertyNames().toStringTagSymbol;
+ PropertySlot toStringTagSlot(thisObject);
+ if (thisObject->getPropertySlot(exec, toStringTagSymbol, toStringTagSlot)) {
+ JSValue stringTag = toStringTagSlot.getValue(exec, toStringTagSymbol);
+ if (stringTag.isString()) {
+ JSRopeString::RopeBuilder ropeBuilder(vm);
+ ropeBuilder.append(vm.smallStrings.objectStringStart());
+ ropeBuilder.append(jsCast<JSString*>(stringTag));
+ ropeBuilder.append(vm.smallStrings.singleCharacterString(']'));
+ result = ropeBuilder.release();
+
+ thisObject->structure(vm)->setObjectToStringValue(exec, vm, result, toStringTagSlot);
+ return JSValue::encode(result);
+ }
+ }
+
</ins><span class="cx"> String newString = WTF::tryMakeString("[object ", thisObject->methodTable(exec->vm())->className(thisObject), "]");
</span><span class="cx"> if (!newString)
</span><span class="cx"> return JSValue::encode(throwOutOfMemoryError(exec));
</span><span class="cx">
</span><span class="cx"> result = jsNontrivialString(&vm, newString);
</span><del>- thisObject->structure(vm)->setObjectToStringValue(vm, result);
</del><ins>+ thisObject->structure(vm)->setObjectToStringValue(exec, vm, result, toStringTagSlot);
</ins><span class="cx"> }
</span><ins>+
</ins><span class="cx"> return JSValue::encode(result);
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStructureh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Structure.h (192320 => 192321)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Structure.h        2015-11-11 20:35:31 UTC (rev 192320)
+++ trunk/Source/JavaScriptCore/runtime/Structure.h        2015-11-11 21:34:57 UTC (rev 192321)
</span><span class="lines">@@ -378,12 +378,7 @@
</span><span class="cx"> return rareData()->objectToStringValue();
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void setObjectToStringValue(VM& vm, JSString* value)
- {
- if (!hasRareData())
- allocateRareData(vm);
- rareData()->setObjectToStringValue(vm, value);
- }
</del><ins>+ void setObjectToStringValue(ExecState*, VM&, JSString* value, PropertySlot toStringTagSymbolSlot);
</ins><span class="cx">
</span><span class="cx"> const ClassInfo* classInfo() const { return m_classInfo; }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStructureInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/StructureInlines.h (192320 => 192321)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/StructureInlines.h        2015-11-11 20:35:31 UTC (rev 192320)
+++ trunk/Source/JavaScriptCore/runtime/StructureInlines.h        2015-11-11 21:34:57 UTC (rev 192321)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> #define StructureInlines_h
</span><span class="cx">
</span><span class="cx"> #include "JSArrayBufferView.h"
</span><ins>+#include "JSGlobalObject.h"
</ins><span class="cx"> #include "PropertyMapHashTable.h"
</span><span class="cx"> #include "Structure.h"
</span><span class="cx"> #include "StructureChain.h"
</span><span class="lines">@@ -304,6 +305,13 @@
</span><span class="cx"> return nextOutOfLineStorageCapacity(outOfLineCapacity());
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+inline void Structure::setObjectToStringValue(ExecState* exec, VM& vm, JSString* value, PropertySlot toStringTagSymbolSlot)
+{
+ if (!hasRareData())
+ allocateRareData(vm);
+ rareData()->setObjectToStringValue(exec, vm, this, value, toStringTagSymbolSlot);
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx">
</span><span class="cx"> #endif // StructureInlines_h
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStructureRareDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp (192320 => 192321)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp        2015-11-11 20:35:31 UTC (rev 192320)
+++ trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp        2015-11-11 21:34:57 UTC (rev 192321)
</span><span class="lines">@@ -26,9 +26,11 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "StructureRareData.h"
</span><span class="cx">
</span><ins>+#include "AdaptiveInferredPropertyValueWatchpointBase.h"
</ins><span class="cx"> #include "JSPropertyNameEnumerator.h"
</span><span class="cx"> #include "JSString.h"
</span><span class="cx"> #include "JSCInlines.h"
</span><ins>+#include "ObjectPropertyConditionSet.h"
</ins><span class="cx">
</span><span class="cx"> namespace JSC {
</span><span class="cx">
</span><span class="lines">@@ -53,6 +55,7 @@
</span><span class="cx">
</span><span class="cx"> StructureRareData::StructureRareData(VM& vm, Structure* previous)
</span><span class="cx"> : JSCell(vm, vm.structureRareDataStructure.get())
</span><ins>+ , m_giveUpOnObjectToStringValueCache(false)
</ins><span class="cx"> {
</span><span class="cx"> if (previous)
</span><span class="cx"> m_previous.set(vm, this, previous);
</span><span class="lines">@@ -79,4 +82,144 @@
</span><span class="cx"> m_cachedPropertyNameEnumerator.set(vm, this, enumerator);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+// ----------- Object.prototype.toString() helper watchpoint classes -----------
+
+class ObjectToStringAdaptiveInferredPropertyValueWatchpoint : public AdaptiveInferredPropertyValueWatchpointBase {
+public:
+ typedef AdaptiveInferredPropertyValueWatchpointBase Base;
+ ObjectToStringAdaptiveInferredPropertyValueWatchpoint(const ObjectPropertyCondition&, StructureRareData*);
+
+private:
+ virtual void handleFire(const FireDetail&) override;
+
+ StructureRareData* m_structureRareData;
+};
+
+class ObjectToStringAdaptiveStructureWatchpoint : public Watchpoint {
+public:
+ ObjectToStringAdaptiveStructureWatchpoint(const ObjectPropertyCondition&, StructureRareData*);
+
+ void install();
+
+protected:
+ virtual void fireInternal(const FireDetail&) override;
+
+private:
+ ObjectPropertyCondition m_key;
+ StructureRareData* m_structureRareData;
+};
+
+void StructureRareData::setObjectToStringValue(ExecState* exec, VM& vm, Structure* ownStructure, JSString* value, PropertySlot toStringTagSymbolSlot)
+{
+ if (m_giveUpOnObjectToStringValueCache)
+ return;
+
+ ObjectPropertyConditionSet conditionSet;
+ if (toStringTagSymbolSlot.isValue()) {
+ // We don't handle the own property case of Symbol.toStringTag because we would never know if a new
+ // object transitioning to the same structure had the same value stored in Symbol.toStringTag.
+ // Additionally, this is a super unlikely case anyway.
+ if (!toStringTagSymbolSlot.isCacheable() || toStringTagSymbolSlot.slotBase()->structure(vm) == ownStructure)
+ return;
+
+
+ // This will not create a condition for the current structure but that is good because we know the Symbol.toStringTag
+ // is not on the ownStructure so we will transisition if one is added and this cache will no longer be used.
+ conditionSet = generateConditionsForPrototypePropertyHit(vm, this, exec, ownStructure, toStringTagSymbolSlot.slotBase(), vm.propertyNames->toStringTagSymbol.impl());
+ ASSERT(conditionSet.hasOneSlotBaseCondition());
+ } else if (toStringTagSymbolSlot.isUnset())
+ conditionSet = generateConditionsForPropertyMiss(vm, this, exec, ownStructure, vm.propertyNames->toStringTagSymbol.impl());
+ else
+ return;
+
+ if (!conditionSet.isValid()) {
+ m_giveUpOnObjectToStringValueCache = true;
+ return;
+ }
+
+ ObjectPropertyCondition equivCondition;
+ for (const ObjectPropertyCondition& condition : conditionSet) {
+ if (condition.condition().kind() == PropertyCondition::Presence) {
+ ASSERT(isValidOffset(condition.offset()));
+ condition.object()->structure(vm)->startWatchingPropertyForReplacements(vm, condition.offset());
+ equivCondition = condition.attemptToMakeEquivalenceWithoutBarrier();
+
+ // The equivalence condition won't be watchable if we have already seen a replacement.
+ if (!equivCondition.isWatchable()) {
+ m_giveUpOnObjectToStringValueCache = true;
+ return;
+ }
+ } else if (!condition.isWatchable()) {
+ m_giveUpOnObjectToStringValueCache = true;
+ return;
+ }
+ }
+
+ ASSERT(conditionSet.structuresEnsureValidity());
+ for (ObjectPropertyCondition condition : conditionSet) {
+ if (condition.condition().kind() == PropertyCondition::Presence) {
+ m_objectToStringAdaptiveInferredValueWatchpoint = std::make_unique<ObjectToStringAdaptiveInferredPropertyValueWatchpoint>(equivCondition, this);
+ m_objectToStringAdaptiveInferredValueWatchpoint->install();
+ } else
+ m_objectToStringAdaptiveWatchpointSet.add(condition, this)->install();
+ }
+
+ m_objectToStringValue.set(vm, this, value);
+}
+
+inline void StructureRareData::clearObjectToStringValue()
+{
+ m_objectToStringAdaptiveWatchpointSet.clear();
+ m_objectToStringAdaptiveInferredValueWatchpoint.reset();
+ m_objectToStringValue.clear();
+}
+
+// ------------- Methods for Object.prototype.toString() helper watchpoint classes --------------
+
+ObjectToStringAdaptiveStructureWatchpoint::ObjectToStringAdaptiveStructureWatchpoint(const ObjectPropertyCondition& key, StructureRareData* structureRareData)
+ : m_key(key)
+ , m_structureRareData(structureRareData)
+{
+ RELEASE_ASSERT(key.watchingRequiresStructureTransitionWatchpoint());
+ RELEASE_ASSERT(!key.watchingRequiresReplacementWatchpoint());
+}
+
+void ObjectToStringAdaptiveStructureWatchpoint::install()
+{
+ RELEASE_ASSERT(m_key.isWatchable());
+
+ m_key.object()->structure()->addTransitionWatchpoint(this);
+}
+
+void ObjectToStringAdaptiveStructureWatchpoint::fireInternal(const FireDetail& detail)
+{
+ if (m_key.isWatchable(PropertyCondition::EnsureWatchability)) {
+ install();
+ return;
+ }
+
+ StringPrintStream out;
+ out.print("ObjectToStringValue Adaptation of ", m_key, " failed: ", detail);
+
+ StringFireDetail stringDetail(out.toCString().data());
+
+ m_structureRareData->clearObjectToStringValue();
+}
+
+ObjectToStringAdaptiveInferredPropertyValueWatchpoint::ObjectToStringAdaptiveInferredPropertyValueWatchpoint(const ObjectPropertyCondition& key, StructureRareData* structureRareData)
+ : Base(key)
+ , m_structureRareData(structureRareData)
+{
+}
+
+void ObjectToStringAdaptiveInferredPropertyValueWatchpoint::handleFire(const FireDetail& detail)
+{
+ StringPrintStream out;
+ out.print("Adaptation of ", key(), " failed: ", detail);
+
+ StringFireDetail stringDetail(out.toCString().data());
+
+ m_structureRareData->clearObjectToStringValue();
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStructureRareDatah"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/StructureRareData.h (192320 => 192321)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/StructureRareData.h        2015-11-11 20:35:31 UTC (rev 192320)
+++ trunk/Source/JavaScriptCore/runtime/StructureRareData.h        2015-11-11 21:34:57 UTC (rev 192321)
</span><span class="lines">@@ -30,11 +30,14 @@
</span><span class="cx"> #include "JSCell.h"
</span><span class="cx"> #include "JSTypeInfo.h"
</span><span class="cx"> #include "PropertyOffset.h"
</span><ins>+#include "PropertySlot.h"
</ins><span class="cx">
</span><span class="cx"> namespace JSC {
</span><span class="cx">
</span><span class="cx"> class JSPropertyNameEnumerator;
</span><span class="cx"> class Structure;
</span><ins>+class ObjectToStringAdaptiveStructureWatchpoint;
+class ObjectToStringAdaptiveInferredPropertyValueWatchpoint;
</ins><span class="cx">
</span><span class="cx"> class StructureRareData final : public JSCell {
</span><span class="cx"> public:
</span><span class="lines">@@ -55,7 +58,7 @@
</span><span class="cx"> void clearPreviousID();
</span><span class="cx">
</span><span class="cx"> JSString* objectToStringValue() const;
</span><del>- void setObjectToStringValue(VM&, JSString* value);
</del><ins>+ void setObjectToStringValue(ExecState*, VM&, Structure* baseStructure, JSString* value, PropertySlot toStringTagSymbolSlot);
</ins><span class="cx">
</span><span class="cx"> JSPropertyNameEnumerator* cachedPropertyNameEnumerator() const;
</span><span class="cx"> void setCachedPropertyNameEnumerator(VM&, JSPropertyNameEnumerator*);
</span><span class="lines">@@ -64,7 +67,11 @@
</span><span class="cx">
</span><span class="cx"> private:
</span><span class="cx"> friend class Structure;
</span><del>-
</del><ins>+ friend class ObjectToStringAdaptiveStructureWatchpoint;
+ friend class ObjectToStringAdaptiveInferredPropertyValueWatchpoint;
+
+ void clearObjectToStringValue();
+
</ins><span class="cx"> StructureRareData(VM&, Structure*);
</span><span class="cx">
</span><span class="cx"> WriteBarrier<Structure> m_previous;
</span><span class="lines">@@ -73,6 +80,9 @@
</span><span class="cx">
</span><span class="cx"> typedef HashMap<PropertyOffset, RefPtr<WatchpointSet>, WTF::IntHash<PropertyOffset>, WTF::UnsignedWithZeroKeyHashTraits<PropertyOffset>> PropertyWatchpointMap;
</span><span class="cx"> std::unique_ptr<PropertyWatchpointMap> m_replacementWatchpointSets;
</span><ins>+ Bag<ObjectToStringAdaptiveStructureWatchpoint> m_objectToStringAdaptiveWatchpointSet;
+ std::unique_ptr<ObjectToStringAdaptiveInferredPropertyValueWatchpoint> m_objectToStringAdaptiveInferredValueWatchpoint;
+ bool m_giveUpOnObjectToStringValueCache;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStructureRareDataInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/StructureRareDataInlines.h (192320 => 192321)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/StructureRareDataInlines.h        2015-11-11 20:35:31 UTC (rev 192320)
+++ trunk/Source/JavaScriptCore/runtime/StructureRareDataInlines.h        2015-11-11 21:34:57 UTC (rev 192321)
</span><span class="lines">@@ -51,11 +51,6 @@
</span><span class="cx"> return m_objectToStringValue.get();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-inline void StructureRareData::setObjectToStringValue(VM& vm, JSString* value)
-{
- m_objectToStringValue.set(vm, this, value);
-}
-
</del><span class="cx"> } // namespace JSC
</span><span class="cx">
</span><span class="cx"> #endif // StructureRareDataInlines_h
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresssymboltostringtagwatchpointsjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/symbol-tostringtag-watchpoints.js (0 => 192321)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/symbol-tostringtag-watchpoints.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/symbol-tostringtag-watchpoints.js        2015-11-11 21:34:57 UTC (rev 192321)
</span><span class="lines">@@ -0,0 +1,62 @@
</span><ins>+// Test changing the value of toStringTag
+
+// Test adding toStringTag to the base with miss.
+
+// SuperPrototype can't be an empty object since its transition
+// watchpoint will be clobbered when assigning it to the prototype.
+var SuperPrototype = { bar: 1 }
+var BasePrototype = { }
+Object.setPrototypeOf(BasePrototype, SuperPrototype);
+
+function Base() { }
+Base.prototype = BasePrototype;
+
+var value = new Base();
+
+if (value.toString() !== "[object Object]")
+ throw "bad miss toStringTag";
+
+value[Symbol.toStringTag] = "hello";
+
+if (value.toString() !== "[object hello]")
+ throw "bad swap on base value with miss";
+
+// Test adding toStringTag to the prototype with miss.
+
+value = new Base();
+
+if (value.toString() !== "[object Object]")
+ throw "bad miss toStringTag";
+
+SuperPrototype[Symbol.toStringTag] = "superprototype";
+
+if (value.toString() !== "[object superprototype]")
+ throw "bad prototype toStringTag change with miss";
+
+// Test adding toStringTag to the base with a hit.
+
+value[Symbol.toStringTag] = "hello2";
+
+if (value.toString() !== "[object hello2]")
+ throw "bad swap on base value with hit";
+
+// Test toStringTag on the prototype.
+
+if (Object.getPrototypeOf(value).toString() !== "[object superprototype]")
+ throw "bad prototype toStringTag access";
+
+// Test adding to string to the prototype with hit.
+
+value = new Base();
+
+BasePrototype[Symbol.toStringTag] = "baseprototype";
+
+if (value.toString() !== "[object baseprototype]")
+ throw "bad prototype toStringTag interception with hit";
+
+// Test replacing the string on prototype.
+
+BasePrototype[Symbol.toStringTag] = "not-baseprototype!";
+
+if (value.toString() !== "[object not-baseprototype!]")
+ throw "bad prototype toStringTag interception with hit";
</ins></span></pre>
</div>
</div>
</body>
</html>