Title: [232286] trunk/Source/_javascript_Core
Revision
232286
Author
sbar...@apple.com
Date
2018-05-29 21:36:07 -0700 (Tue, 29 May 2018)

Log Message

Add a version of JSVirtualMachine shrinkFootprint that runs when the VM goes idle
https://bugs.webkit.org/show_bug.cgi?id=186064

Reviewed by Mark Lam.

shrinkFootprint was implemented as:
```
sanitizeStackForVM(this);
deleteAllCode(DeleteAllCodeIfNotCollecting);
heap.collectNow(Synchronousness::Sync);
WTF::releaseFastMallocFreeMemory();
```

However, for correctness reasons, deleteAllCode is implemented to do
work when the VM is idle: no JS is running on the stack. This means
that if shrinkFootprint is called when JS is running on the stack, it
ends up freeing less memory than it could have if it waited to run until
the VM goes idle.

This patch makes it so we wait until idle before doing work. I'm seeing a
10% footprint progression when testing this against a client of the JSC SPI.

Because this is a semantic change in how the SPI works, this patch
adds new SPI named shrinkFootprintWhenIdle. The plan is to move
all clients of the shrinkFootprint SPI to shrinkFootprintWhenIdle.
Once that happens, we will delete shrinkFootprint. Until then,
we make shrinkFootprint do exactly what shrinkFootprintWhenIdle does.

* API/JSVirtualMachine.mm:
(-[JSVirtualMachine shrinkFootprint]):
(-[JSVirtualMachine shrinkFootprintWhenIdle]):
* API/JSVirtualMachinePrivate.h:
* runtime/VM.cpp:
(JSC::VM::shrinkFootprintWhenIdle):
(JSC::VM::shrinkFootprint): Deleted.
* runtime/VM.h:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/API/JSVirtualMachine.mm (232285 => 232286)


--- trunk/Source/_javascript_Core/API/JSVirtualMachine.mm	2018-05-30 04:01:14 UTC (rev 232285)
+++ trunk/Source/_javascript_Core/API/JSVirtualMachine.mm	2018-05-30 04:36:07 UTC (rev 232286)
@@ -272,9 +272,16 @@
 {
     JSC::VM* vm = toJS(m_group);
     JSC::JSLockHolder locker(vm);
-    vm->shrinkFootprint();
+    vm->shrinkFootprintWhenIdle();
 }
 
+- (void)shrinkFootprintWhenIdle
+{
+    JSC::VM* vm = toJS(m_group);
+    JSC::JSLockHolder locker(vm);
+    vm->shrinkFootprintWhenIdle();
+}
+
 @end
 
 static void scanExternalObjectGraph(JSC::VM& vm, JSC::SlotVisitor& visitor, void* root, bool lockAcquired)

Modified: trunk/Source/_javascript_Core/API/JSVirtualMachinePrivate.h (232285 => 232286)


--- trunk/Source/_javascript_Core/API/JSVirtualMachinePrivate.h	2018-05-30 04:01:14 UTC (rev 232285)
+++ trunk/Source/_javascript_Core/API/JSVirtualMachinePrivate.h	2018-05-30 04:36:07 UTC (rev 232286)
@@ -31,14 +31,20 @@
 
 @interface JSVirtualMachine(JSPrivate)
 
+- (void)shrinkFootprint; // FIXME: Remove this SPI when clients move to shrinkFootprintWhenIdle: https://bugs.webkit.org/show_bug.cgi?id=186071
+
 /*!
 @method
 @discussion Shrinks the memory footprint of the VM by deleting various internal caches,
- running synchronous garbage collection, and releasing memory back to the OS. For this
- to free as much memory as possible, do not call this when _javascript_ is running on the stack.
+ running synchronous garbage collection, and releasing memory back to the OS. Note: this
+ API waits until no _javascript_ is running on the stack before it frees any memory. It's
+ best to call this API when no _javascript_ is running on the stack for this reason. However, if
+ you do call this API when _javascript_ is running on the stack, the API will wait until all _javascript_
+ on the stack finishes running to free memory back to the OS. Therefore, calling this
+ API may not synchronously free memory.
 */
 
-- (void)shrinkFootprint; // FIXME: Annotate this with NS_AVAILABLE: <rdar://problem/40071332>.
+- (void)shrinkFootprintWhenIdle; // FIXME: Annotate this with NS_AVAILABLE: <rdar://problem/40071332>.
 
 @end
 

Modified: trunk/Source/_javascript_Core/ChangeLog (232285 => 232286)


--- trunk/Source/_javascript_Core/ChangeLog	2018-05-30 04:01:14 UTC (rev 232285)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-05-30 04:36:07 UTC (rev 232286)
@@ -1,5 +1,44 @@
 2018-05-29  Saam Barati  <sbar...@apple.com>
 
+        Add a version of JSVirtualMachine shrinkFootprint that runs when the VM goes idle
+        https://bugs.webkit.org/show_bug.cgi?id=186064
+
+        Reviewed by Mark Lam.
+
+        shrinkFootprint was implemented as:
+        ```
+        sanitizeStackForVM(this);
+        deleteAllCode(DeleteAllCodeIfNotCollecting);
+        heap.collectNow(Synchronousness::Sync);
+        WTF::releaseFastMallocFreeMemory();
+        ```
+        
+        However, for correctness reasons, deleteAllCode is implemented to do
+        work when the VM is idle: no JS is running on the stack. This means
+        that if shrinkFootprint is called when JS is running on the stack, it
+        ends up freeing less memory than it could have if it waited to run until
+        the VM goes idle.
+        
+        This patch makes it so we wait until idle before doing work. I'm seeing a
+        10% footprint progression when testing this against a client of the JSC SPI.
+        
+        Because this is a semantic change in how the SPI works, this patch
+        adds new SPI named shrinkFootprintWhenIdle. The plan is to move
+        all clients of the shrinkFootprint SPI to shrinkFootprintWhenIdle.
+        Once that happens, we will delete shrinkFootprint. Until then,
+        we make shrinkFootprint do exactly what shrinkFootprintWhenIdle does.
+
+        * API/JSVirtualMachine.mm:
+        (-[JSVirtualMachine shrinkFootprint]):
+        (-[JSVirtualMachine shrinkFootprintWhenIdle]):
+        * API/JSVirtualMachinePrivate.h:
+        * runtime/VM.cpp:
+        (JSC::VM::shrinkFootprintWhenIdle):
+        (JSC::VM::shrinkFootprint): Deleted.
+        * runtime/VM.h:
+
+2018-05-29  Saam Barati  <sbar...@apple.com>
+
         shrinkFootprint needs to request a full collection
         https://bugs.webkit.org/show_bug.cgi?id=186069
 

Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (232285 => 232286)


--- trunk/Source/_javascript_Core/runtime/VM.cpp	2018-05-30 04:01:14 UTC (rev 232285)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp	2018-05-30 04:36:07 UTC (rev 232286)
@@ -777,14 +777,16 @@
     });
 }
 
-void VM::shrinkFootprint()
+void VM::shrinkFootprintWhenIdle()
 {
-    sanitizeStackForVM(this);
-    deleteAllCode(DeleteAllCodeIfNotCollecting);
-    heap.collectNow(Synchronousness::Sync, CollectionScope::Full);
-    WTF::releaseFastMallocFreeMemory();
-    // FIXME: Consider stopping various automatic threads here.
-    // https://bugs.webkit.org/show_bug.cgi?id=185447
+    whenIdle([=] () {
+        sanitizeStackForVM(this);
+        deleteAllCode(DeleteAllCodeIfNotCollecting);
+        heap.collectNow(Synchronousness::Sync, CollectionScope::Full);
+        // FIXME: Consider stopping various automatic threads here.
+        // https://bugs.webkit.org/show_bug.cgi?id=185447
+        WTF::releaseFastMallocFreeMemory();
+    });
 }
 
 SourceProviderCache* VM::addSourceProviderCache(SourceProvider* sourceProvider)

Modified: trunk/Source/_javascript_Core/runtime/VM.h (232285 => 232286)


--- trunk/Source/_javascript_Core/runtime/VM.h	2018-05-30 04:01:14 UTC (rev 232285)
+++ trunk/Source/_javascript_Core/runtime/VM.h	2018-05-30 04:36:07 UTC (rev 232286)
@@ -745,7 +745,7 @@
     JS_EXPORT_PRIVATE void deleteAllCode(DeleteAllCodeEffort);
     JS_EXPORT_PRIVATE void deleteAllLinkedCode(DeleteAllCodeEffort);
 
-    void shrinkFootprint();
+    void shrinkFootprintWhenIdle();
 
     WatchpointSet* ensureWatchpointSetForImpureProperty(const Identifier&);
     void registerWatchpointForImpureProperty(const Identifier&, Watchpoint*);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to