- Revision
- 243086
- Author
- [email protected]
- Date
- 2019-03-18 11:35:04 -0700 (Mon, 18 Mar 2019)
Log Message
[JSC] Add --destroy-vm shell option and dumpHeapStatisticsAtVMDestruction option
https://bugs.webkit.org/show_bug.cgi?id=195897
Reviewed by Keith Miller.
It is useful if we have an option logging the status of all the existing MarkedBlocks and their objects at VM destruction.
I used this feature to find wasting memory, and successfully removed many wasted MarkedBlocks and JS cells like r243081.
This patch adds,
1. --destroy-vm option to JSC shell to destroy main thread JSC::VM
2. dumpHeapStatisticsAtVMDestruction to dump MarkedBlocks at VM destruction
While the current option name is "dumpHeapStatisticsAtVMDestruction", we just dump the status of MarkedBlocks and cells. But eventually,
we would like to collect heap statistics and dump them to investigate Heap status more.
This patch also removes logHeapStatisticsAtExit option since it is no longer used in JSC.
* heap/Heap.cpp:
(JSC::Heap::dumpHeapStatisticsAtVMDestruction):
(JSC::Heap::lastChanceToFinalize):
* heap/Heap.h:
* jsc.cpp:
(printUsageStatement):
(CommandLine::parseArguments):
(runJSC):
* runtime/Options.h:
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (243085 => 243086)
--- trunk/Source/_javascript_Core/ChangeLog 2019-03-18 18:27:42 UTC (rev 243085)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-03-18 18:35:04 UTC (rev 243086)
@@ -1,5 +1,34 @@
2019-03-18 Yusuke Suzuki <[email protected]>
+ [JSC] Add --destroy-vm shell option and dumpHeapStatisticsAtVMDestruction option
+ https://bugs.webkit.org/show_bug.cgi?id=195897
+
+ Reviewed by Keith Miller.
+
+ It is useful if we have an option logging the status of all the existing MarkedBlocks and their objects at VM destruction.
+ I used this feature to find wasting memory, and successfully removed many wasted MarkedBlocks and JS cells like r243081.
+ This patch adds,
+
+ 1. --destroy-vm option to JSC shell to destroy main thread JSC::VM
+ 2. dumpHeapStatisticsAtVMDestruction to dump MarkedBlocks at VM destruction
+
+ While the current option name is "dumpHeapStatisticsAtVMDestruction", we just dump the status of MarkedBlocks and cells. But eventually,
+ we would like to collect heap statistics and dump them to investigate Heap status more.
+
+ This patch also removes logHeapStatisticsAtExit option since it is no longer used in JSC.
+
+ * heap/Heap.cpp:
+ (JSC::Heap::dumpHeapStatisticsAtVMDestruction):
+ (JSC::Heap::lastChanceToFinalize):
+ * heap/Heap.h:
+ * jsc.cpp:
+ (printUsageStatement):
+ (CommandLine::parseArguments):
+ (runJSC):
+ * runtime/Options.h:
+
+2019-03-18 Yusuke Suzuki <[email protected]>
+
[JSC] jsSubstring should resolve rope before calling JSRopeString::create
https://bugs.webkit.org/show_bug.cgi?id=195840
Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (243085 => 243086)
--- trunk/Source/_javascript_Core/heap/Heap.cpp 2019-03-18 18:27:42 UTC (rev 243085)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp 2019-03-18 18:35:04 UTC (rev 243086)
@@ -344,6 +344,30 @@
return m_objectSpace.isPagedOut(deadline);
}
+void Heap::dumpHeapStatisticsAtVMDestruction()
+{
+ unsigned counter = 0;
+ m_objectSpace.forEachBlock([&] (MarkedBlock::Handle* block) {
+ unsigned live = 0;
+ block->forEachCell([&] (HeapCell* cell, HeapCell::Kind) {
+ if (cell->isLive())
+ live++;
+ return IterationStatus::Continue;
+ });
+ dataLogLn("[", counter++, "] ", block->cellSize(), ", ", live, " / ", block->cellsPerBlock(), " ", static_cast<double>(live) / block->cellsPerBlock() * 100, "% ", block->attributes(), " ", block->subspace()->name());
+ block->forEachCell([&] (HeapCell* heapCell, HeapCell::Kind kind) {
+ if (heapCell->isLive() && kind == HeapCell::Kind::JSCell) {
+ auto* cell = static_cast<JSCell*>(heapCell);
+ if (cell->isObject())
+ dataLogLn(" ", JSValue((JSObject*)cell));
+ else
+ dataLogLn(" ", *cell);
+ }
+ return IterationStatus::Continue;
+ });
+ });
+}
+
// The VM is being destroyed and the collector will never run again.
// Run all pending finalizers now because we won't get another chance.
void Heap::lastChanceToFinalize()
@@ -423,6 +447,9 @@
if (Options::logGC())
dataLog("5 ");
+
+ if (UNLIKELY(Options::dumpHeapStatisticsAtVMDestruction()))
+ dumpHeapStatisticsAtVMDestruction();
m_arrayBuffers.lastChanceToFinalize();
m_objectSpace.stopAllocatingForGood();
Modified: trunk/Source/_javascript_Core/heap/Heap.h (243085 => 243086)
--- trunk/Source/_javascript_Core/heap/Heap.h 2019-03-18 18:27:42 UTC (rev 243085)
+++ trunk/Source/_javascript_Core/heap/Heap.h 2019-03-18 18:35:04 UTC (rev 243086)
@@ -573,6 +573,8 @@
void setBonusVisitorTask(RefPtr<SharedTask<void(SlotVisitor&)>>);
+ void dumpHeapStatisticsAtVMDestruction();
+
static bool useGenerationalGC();
static bool shouldSweepSynchronously();
Modified: trunk/Source/_javascript_Core/jsc.cpp (243085 => 243086)
--- trunk/Source/_javascript_Core/jsc.cpp 2019-03-18 18:27:42 UTC (rev 243085)
+++ trunk/Source/_javascript_Core/jsc.cpp 2019-03-18 18:35:04 UTC (rev 243086)
@@ -413,15 +413,16 @@
parseArguments(argc, argv);
}
+ Vector<Script> m_scripts;
+ Vector<String> m_arguments;
+ String m_profilerOutput;
+ String m_uncaughtExceptionName;
bool m_interactive { false };
bool m_dump { false };
bool m_module { false };
bool m_exitCode { false };
- Vector<Script> m_scripts;
- Vector<String> m_arguments;
+ bool m_destroyVM { false };
bool m_profile { false };
- String m_profilerOutput;
- String m_uncaughtExceptionName;
bool m_treatWatchdogExceptionAsSuccess { false };
bool m_alwaysDumpUncaughtException { false };
bool m_dumpMemoryFootprint { false };
@@ -2692,6 +2693,7 @@
fprintf(stderr, " --options Dumps all JSC VM options and exits\n");
fprintf(stderr, " --dumpOptions Dumps all non-default JSC VM options before continuing\n");
fprintf(stderr, " --<jsc VM option>=<value> Sets the specified JSC VM option\n");
+ fprintf(stderr, " --destroy-vm Destroy VM before exiting\n");
fprintf(stderr, "\n");
fprintf(stderr, "Files with a .mjs extension will always be evaluated as modules.\n");
fprintf(stderr, "\n");
@@ -2800,6 +2802,10 @@
m_dumpSamplingProfilerData = true;
continue;
}
+ if (!strcmp(arg, "--destroy-vm")) {
+ m_destroyVM = true;
+ continue;
+ }
static const char* timeoutMultiplierOptStr = "--timeoutMultiplier=";
static const unsigned timeoutMultiplierOptStrLength = strlen(timeoutMultiplierOptStr);
@@ -2973,7 +2979,7 @@
vm.codeCache()->write(vm);
- if (isWorker) {
+ if (options.m_destroyVM || isWorker) {
JSLockHolder locker(vm);
// This is needed because we don't want the worker's main
// thread to die before its compilation threads finish.
Modified: trunk/Source/_javascript_Core/runtime/Options.h (243085 => 243086)
--- trunk/Source/_javascript_Core/runtime/Options.h 2019-03-18 18:27:42 UTC (rev 243085)
+++ trunk/Source/_javascript_Core/runtime/Options.h 2019-03-18 18:35:04 UTC (rev 243086)
@@ -394,7 +394,7 @@
v(unsigned, gcMaxHeapSize, 0, Normal, nullptr) \
v(unsigned, forceRAMSize, 0, Normal, nullptr) \
v(bool, recordGCPauseTimes, false, Normal, nullptr) \
- v(bool, logHeapStatisticsAtExit, false, Normal, nullptr) \
+ v(bool, dumpHeapStatisticsAtVMDestruction, false, Normal, nullptr) \
v(bool, forceCodeBlockToJettisonDueToOldAge, false, Normal, "If true, this means that anytime we can jettison a CodeBlock due to old age, we do.") \
v(bool, useEagerCodeBlockJettisonTiming, false, Normal, "If true, the time slices for jettisoning a CodeBlock due to old age are shrunk significantly.") \
\