<!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 <keith_miller@apple.com>
+
+ 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 <fpizlo@apple.com>
</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 && !vm->m_perBytecodeProfiler)
+ vm->m_perBytecodeProfiler = std::make_unique<Profiler::Database>(*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 && success)
+ runInteractive(globalObject);
+
+ result = success ? 0 : 3;
+
+ if (options.m_exitCode)
+ printf("jsc exiting %d\n", result);
+
+ if (options.m_profile) {
+ if (!vm->m_perBytecodeProfiler->save(options.m_profilerOutput.utf8().data()))
+ fprintf(stderr, "could not save profiler output.\n");
+ }
+
+#if ENABLE(JIT)
+ if (Options::useExceptionFuzz())
+ printf("JSC EXCEPTION FUZZ: encountered %u checks.\n", numberOfExceptionFuzzChecks());
+ bool fireAtEnabled =
+ Options::fireExecutableAllocationFuzzAt() || Options::fireExecutableAllocationFuzzAtOrAfter();
+ if (Options::useExecutableAllocationFuzz() && (!fireAtEnabled || Options::verboseExecutableAllocationFuzz()))
+ printf("JSC EXECUTABLE ALLOCATION FUZZ: encountered %u checks.\n", numberOfExecutableAllocationFuzzChecks());
+ if (Options::useOSRExitFuzz()) {
+ printf("JSC OSR EXIT FUZZ: encountered %u static checks.\n", numberOfStaticOSRExitFuzzChecks());
+ printf("JSC OSR EXIT FUZZ: encountered %u dynamic checks.\n", numberOfOSRExitFuzzChecks());
+ }
+#endif
+ auto compileTimeStats = DFG::Plan::compileTimeStats();
+ Vector<CString> compileTimeKeys;
+ for (auto& entry : compileTimeStats)
+ compileTimeKeys.append(entry.key);
+ std::sort(compileTimeKeys.begin(), compileTimeKeys.end());
+ for (CString key : compileTimeKeys)
+ printf("%40s: %.3lf ms\n", 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 = &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->heap.collectAllGarbage();
+ }
</ins><span class="cx">
</span><del>- if (options.m_profile && !vm->m_perBytecodeProfiler)
- vm->m_perBytecodeProfiler = std::make_unique<Profiler::Database>(*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 && success)
- runInteractive(globalObject);
-
- result = success ? 0 : 3;
-
- if (options.m_exitCode)
- printf("jsc exiting %d\n", result);
-
- if (options.m_profile) {
- if (!vm->m_perBytecodeProfiler->save(options.m_profilerOutput.utf8().data()))
- fprintf(stderr, "could not save profiler output.\n");
- }
-
-#if ENABLE(JIT)
- if (Options::useExceptionFuzz())
- printf("JSC EXCEPTION FUZZ: encountered %u checks.\n", numberOfExceptionFuzzChecks());
- bool fireAtEnabled =
- Options::fireExecutableAllocationFuzzAt() || Options::fireExecutableAllocationFuzzAtOrAfter();
- if (Options::useExecutableAllocationFuzz() && (!fireAtEnabled || Options::verboseExecutableAllocationFuzz()))
- printf("JSC EXECUTABLE ALLOCATION FUZZ: encountered %u checks.\n", numberOfExecutableAllocationFuzzChecks());
- if (Options::useOSRExitFuzz()) {
- printf("JSC OSR EXIT FUZZ: encountered %u static checks.\n", numberOfStaticOSRExitFuzzChecks());
- printf("JSC OSR EXIT FUZZ: encountered %u dynamic checks.\n", numberOfOSRExitFuzzChecks());
- }
-#endif
- auto compileTimeStats = DFG::Plan::compileTimeStats();
- Vector<CString> compileTimeKeys;
- for (auto& entry : compileTimeStats)
- compileTimeKeys.append(entry.key);
- std::sort(compileTimeKeys.begin(), compileTimeKeys.end());
- for (CString key : compileTimeKeys)
- printf("%40s: %.3lf ms\n", 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<ArrayPrototype>(vm.heap)) ArrayPrototype(vm, structure);
</span><span class="cx"> prototype->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->unscopablesSymbol, unscopables, DontEnum | ReadOnly);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void ArrayPrototype::destroy(JSC::JSCell* cell)
+{
+ ArrayPrototype* thisObject = static_cast<ArrayPrototype*>(cell);
+ thisObject->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&, 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, "debugging option to log GC activity (0 = None, 1 = Basic, 2 = Verbose)") \
</span><span class="cx"> v(bool, useGC, true, nullptr) \
</span><ins>+ v(bool, gcAtEnd, false, "If true, the jsc CLI will do a GC before exiting") \
</ins><span class="cx"> v(bool, forceGCSlowPaths, false, "If true, we will force all JIT fast allocations down their slow paths.")\
</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>