<!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>[196155] trunk/Source/JavaScriptCore</title>
</head>
<body>

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

<h3>Log Message</h3>
<pre>ArrayPrototype should have a destroy function
https://bugs.webkit.org/show_bug.cgi?id=153847

Reviewed by Filip Pizlo.

ArrayPrototype should have an destroy function as it now has a unique_ptr member that
needs to be freed at the end of the object's life cycle. Also, this patch adds an
option, gcAtEnd, that will cause jsc.cpp to do a garbage collection before exiting.

* jsc.cpp:
(runJSC):
(jscmain):
* runtime/ArrayPrototype.cpp:
(JSC::ArrayPrototype::create):
(JSC::ArrayPrototype::destroy):
* runtime/ArrayPrototype.h:
* runtime/Options.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArrayPrototypecpp">trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArrayPrototypeh">trunk/Source/JavaScriptCore/runtime/ArrayPrototype.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionsh">trunk/Source/JavaScriptCore/runtime/Options.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (196154 => 196155)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-02-04 23:54:33 UTC (rev 196154)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-02-05 00:36:20 UTC (rev 196155)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2016-02-04  Keith Miller  &lt;keith_miller@apple.com&gt;
+
+        ArrayPrototype should have a destroy function
+        https://bugs.webkit.org/show_bug.cgi?id=153847
+
+        Reviewed by Filip Pizlo.
+
+        ArrayPrototype should have an destroy function as it now has a unique_ptr member that
+        needs to be freed at the end of the object's life cycle. Also, this patch adds an
+        option, gcAtEnd, that will cause jsc.cpp to do a garbage collection before exiting.
+
+        * jsc.cpp:
+        (runJSC):
+        (jscmain):
+        * runtime/ArrayPrototype.cpp:
+        (JSC::ArrayPrototype::create):
+        (JSC::ArrayPrototype::destroy):
+        * runtime/ArrayPrototype.h:
+        * runtime/Options.h:
+
</ins><span class="cx"> 2016-02-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         REGRESSION(192409): Cannot rely on add32() to zero-extend
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (196154 => 196155)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2016-02-04 23:54:33 UTC (rev 196154)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2016-02-05 00:36:20 UTC (rev 196155)
</span><span class="lines">@@ -2023,6 +2023,53 @@
</span><span class="cx">         jscExit(EXIT_SUCCESS);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// We make this function no inline so that globalObject won't be on the stack if we do a GC in jscmain.
+static int NEVER_INLINE runJSC(VM* vm, CommandLine options)
+{
+    JSLockHolder locker(vm);
+
+    int result;
+    if (options.m_profile &amp;&amp; !vm-&gt;m_perBytecodeProfiler)
+        vm-&gt;m_perBytecodeProfiler = std::make_unique&lt;Profiler::Database&gt;(*vm);
+
+    GlobalObject* globalObject = GlobalObject::create(*vm, GlobalObject::createStructure(*vm, jsNull()), options.m_arguments);
+    bool success = runWithScripts(globalObject, options.m_scripts, options.m_dump, options.m_module);
+    if (options.m_interactive &amp;&amp; success)
+        runInteractive(globalObject);
+
+    result = success ? 0 : 3;
+
+    if (options.m_exitCode)
+        printf(&quot;jsc exiting %d\n&quot;, result);
+
+    if (options.m_profile) {
+        if (!vm-&gt;m_perBytecodeProfiler-&gt;save(options.m_profilerOutput.utf8().data()))
+            fprintf(stderr, &quot;could not save profiler output.\n&quot;);
+    }
+
+#if ENABLE(JIT)
+    if (Options::useExceptionFuzz())
+        printf(&quot;JSC EXCEPTION FUZZ: encountered %u checks.\n&quot;, numberOfExceptionFuzzChecks());
+    bool fireAtEnabled =
+    Options::fireExecutableAllocationFuzzAt() || Options::fireExecutableAllocationFuzzAtOrAfter();
+    if (Options::useExecutableAllocationFuzz() &amp;&amp; (!fireAtEnabled || Options::verboseExecutableAllocationFuzz()))
+        printf(&quot;JSC EXECUTABLE ALLOCATION FUZZ: encountered %u checks.\n&quot;, numberOfExecutableAllocationFuzzChecks());
+    if (Options::useOSRExitFuzz()) {
+        printf(&quot;JSC OSR EXIT FUZZ: encountered %u static checks.\n&quot;, numberOfStaticOSRExitFuzzChecks());
+        printf(&quot;JSC OSR EXIT FUZZ: encountered %u dynamic checks.\n&quot;, numberOfOSRExitFuzzChecks());
+    }
+#endif
+    auto compileTimeStats = DFG::Plan::compileTimeStats();
+    Vector&lt;CString&gt; compileTimeKeys;
+    for (auto&amp; entry : compileTimeStats)
+        compileTimeKeys.append(entry.key);
+    std::sort(compileTimeKeys.begin(), compileTimeKeys.end());
+    for (CString key : compileTimeKeys)
+        printf(&quot;%40s: %.3lf ms\n&quot;, key.data(), compileTimeStats.get(key));
+
+    return result;
+}
+
</ins><span class="cx"> int jscmain(int argc, char** argv)
</span><span class="cx"> {
</span><span class="cx">     // Note that the options parsing can affect VM creation, and thus
</span><span class="lines">@@ -2037,48 +2084,14 @@
</span><span class="cx"> 
</span><span class="cx">     VM* vm = &amp;VM::create(LargeHeap).leakRef();
</span><span class="cx">     int result;
</span><del>-    {
</del><ins>+    result = runJSC(vm, options);
+
+    if (Options::gcAtEnd()) {
+        // We need to hold the API lock to do a GC.
</ins><span class="cx">         JSLockHolder locker(vm);
</span><ins>+        vm-&gt;heap.collectAllGarbage();
+    }
</ins><span class="cx"> 
</span><del>-        if (options.m_profile &amp;&amp; !vm-&gt;m_perBytecodeProfiler)
-            vm-&gt;m_perBytecodeProfiler = std::make_unique&lt;Profiler::Database&gt;(*vm);
-    
-        GlobalObject* globalObject = GlobalObject::create(*vm, GlobalObject::createStructure(*vm, jsNull()), options.m_arguments);
-        bool success = runWithScripts(globalObject, options.m_scripts, options.m_dump, options.m_module);
-        if (options.m_interactive &amp;&amp; success)
-            runInteractive(globalObject);
-
-        result = success ? 0 : 3;
-
-        if (options.m_exitCode)
-            printf(&quot;jsc exiting %d\n&quot;, result);
-    
-        if (options.m_profile) {
-            if (!vm-&gt;m_perBytecodeProfiler-&gt;save(options.m_profilerOutput.utf8().data()))
-                fprintf(stderr, &quot;could not save profiler output.\n&quot;);
-        }
-        
-#if ENABLE(JIT)
-        if (Options::useExceptionFuzz())
-            printf(&quot;JSC EXCEPTION FUZZ: encountered %u checks.\n&quot;, numberOfExceptionFuzzChecks());
-        bool fireAtEnabled =
-            Options::fireExecutableAllocationFuzzAt() || Options::fireExecutableAllocationFuzzAtOrAfter();
-        if (Options::useExecutableAllocationFuzz() &amp;&amp; (!fireAtEnabled || Options::verboseExecutableAllocationFuzz()))
-            printf(&quot;JSC EXECUTABLE ALLOCATION FUZZ: encountered %u checks.\n&quot;, numberOfExecutableAllocationFuzzChecks());
-        if (Options::useOSRExitFuzz()) {
-            printf(&quot;JSC OSR EXIT FUZZ: encountered %u static checks.\n&quot;, numberOfStaticOSRExitFuzzChecks());
-            printf(&quot;JSC OSR EXIT FUZZ: encountered %u dynamic checks.\n&quot;, numberOfOSRExitFuzzChecks());
-        }
-#endif
-        auto compileTimeStats = DFG::Plan::compileTimeStats();
-        Vector&lt;CString&gt; compileTimeKeys;
-        for (auto&amp; entry : compileTimeStats)
-            compileTimeKeys.append(entry.key);
-        std::sort(compileTimeKeys.begin(), compileTimeKeys.end());
-        for (CString key : compileTimeKeys)
-            printf(&quot;%40s: %.3lf ms\n&quot;, key.data(), compileTimeStats.get(key));
-    }
-    
</del><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayPrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp (196154 => 196155)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp        2016-02-04 23:54:33 UTC (rev 196154)
+++ trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp        2016-02-05 00:36:20 UTC (rev 196155)
</span><span class="lines">@@ -74,6 +74,7 @@
</span><span class="cx"> {
</span><span class="cx">     ArrayPrototype* prototype = new (NotNull, allocateCell&lt;ArrayPrototype&gt;(vm.heap)) ArrayPrototype(vm, structure);
</span><span class="cx">     prototype-&gt;finishCreation(vm, globalObject);
</span><ins>+    vm.heap.addFinalizer(prototype, destroy);
</ins><span class="cx">     return prototype;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -138,6 +139,12 @@
</span><span class="cx">     putDirectWithoutTransition(vm, vm.propertyNames-&gt;unscopablesSymbol, unscopables, DontEnum | ReadOnly);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ArrayPrototype::destroy(JSC::JSCell* cell)
+{
+    ArrayPrototype* thisObject = static_cast&lt;ArrayPrototype*&gt;(cell);
+    thisObject-&gt;ArrayPrototype::~ArrayPrototype();
+}
+
</ins><span class="cx"> // ------------------------------ Array Functions ----------------------------
</span><span class="cx"> 
</span><span class="cx"> static ALWAYS_INLINE JSValue getProperty(ExecState* exec, JSObject* object, unsigned index)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayPrototypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ArrayPrototype.h (196154 => 196155)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayPrototype.h        2016-02-04 23:54:33 UTC (rev 196154)
+++ trunk/Source/JavaScriptCore/runtime/ArrayPrototype.h        2016-02-05 00:36:20 UTC (rev 196155)
</span><span class="lines">@@ -48,6 +48,10 @@
</span><span class="cx"> 
</span><span class="cx">     bool didChangeConstructorProperty() const { return m_didChangeConstructorProperty; }
</span><span class="cx"> 
</span><ins>+    static const bool needsDestruction = false;
+    // We don't need destruction since we use a finalizer.
+    static void destroy(JSC::JSCell*);
+
</ins><span class="cx"> protected:
</span><span class="cx">     void finishCreation(VM&amp;, JSGlobalObject*);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (196154 => 196155)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2016-02-04 23:54:33 UTC (rev 196154)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2016-02-05 00:36:20 UTC (rev 196155)
</span><span class="lines">@@ -319,6 +319,7 @@
</span><span class="cx">     \
</span><span class="cx">     v(gcLogLevel, logGC, GCLogging::None, &quot;debugging option to log GC activity (0 = None, 1 = Basic, 2 = Verbose)&quot;) \
</span><span class="cx">     v(bool, useGC, true, nullptr) \
</span><ins>+    v(bool, gcAtEnd, false, &quot;If true, the jsc CLI will do a GC before exiting&quot;) \
</ins><span class="cx">     v(bool, forceGCSlowPaths, false, &quot;If true, we will force all JIT fast allocations down their slow paths.&quot;)\
</span><span class="cx">     v(unsigned, gcMaxHeapSize, 0, nullptr) \
</span><span class="cx">     v(unsigned, forceRAMSize, 0, nullptr) \
</span></span></pre>
</div>
</div>

</body>
</html>