RESOLVED FIXED185441
Add JSVirtualMachine SPI to shrink the memory footprint of the VM
https://bugs.webkit.org/show_bug.cgi?id=185441
Summary Add JSVirtualMachine SPI to shrink the memory footprint of the VM
Saam Barati
Reported 2018-05-08 12:10:41 PDT
...
Attachments
patch (11.70 KB, patch)
2018-05-08 14:39 PDT, Saam Barati
keith_miller: review+
patch for landing (11.69 KB, patch)
2018-05-08 14:51 PDT, Saam Barati
no flags
patch for landing (11.66 KB, patch)
2018-05-08 18:59 PDT, Saam Barati
ews-watchlist: commit-queue-
Archive of layout-test-results from ews205 for win-future (12.76 MB, application/zip)
2018-05-09 09:02 PDT, EWS Watchlist
no flags
Saam Barati
Comment 1 2018-05-08 14:26:59 PDT
Saam Barati
Comment 2 2018-05-08 14:39:28 PDT
EWS Watchlist
Comment 3 2018-05-08 14:42:43 PDT
Attachment 339881 [details] did not pass style-queue: ERROR: Source/JavaScriptCore/API/JSVirtualMachinePrivate.h:26: Use #pragma once instead of #ifndef for header guard. [build/header_guard] [5] Total errors found: 1 in 7 files If any of these errors are false positives, please file a bug against check-webkit-style.
Keith Miller
Comment 4 2018-05-08 14:45:29 PDT
Comment on attachment 339881 [details] patch r=me.
Keith Miller
Comment 5 2018-05-08 14:47:46 PDT
Comment on attachment 339881 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=339881&action=review > Source/JavaScriptCore/API/JSVirtualMachinePrivate.h:36 > +@property I think this should be @method.
Saam Barati
Comment 6 2018-05-08 14:51:10 PDT
Created attachment 339884 [details] patch for landing
Saam Barati
Comment 7 2018-05-08 14:51:38 PDT
Comment on attachment 339881 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=339881&action=review >> Source/JavaScriptCore/API/JSVirtualMachinePrivate.h:36 >> +@property > > I think this should be @method. fixed
EWS Watchlist
Comment 8 2018-05-08 14:52:45 PDT
Attachment 339884 [details] did not pass style-queue: ERROR: Source/JavaScriptCore/API/JSVirtualMachinePrivate.h:26: Use #pragma once instead of #ifndef for header guard. [build/header_guard] [5] Total errors found: 1 in 7 files If any of these errors are false positives, please file a bug against check-webkit-style.
Joseph Pecoraro
Comment 9 2018-05-08 16:20:53 PDT
Comment on attachment 339884 [details] patch for landing View in context: https://bugs.webkit.org/attachment.cgi?id=339884&action=review > Source/JavaScriptCore/API/JSVirtualMachinePrivate.h:27 > +#ifndef JSVirtualMachinePrivate_h > +#define JSVirtualMachinePrivate_h API/JSVirtualMachine.h doesn't bother with header ifdefs. Should we bother with them here? ObjC is expected to #import which takes care of avoiding duplicate inclusions. > Source/JavaScriptCore/API/JSVirtualMachinePrivate.h:33 > +@interface JSVirtualMachine(Private) I think we normally prefix category names like we prefix classes, since all of this ObjC stuff is in the global namespace. For example WebKit does this with its `WK` prefix: @interface WKUserScript (WKPrivate) ... @end I think we should do the same. For example: @interface JSVirtualMachine (JSPrivate) ... @end > Source/JavaScriptCore/runtime/VM.cpp:776 > + deleteAllCode(DeleteAllCodeIfNotCollecting); Something we do in Web Inspector when triggering a GC is: sanitizeStackForVM(vm); Is that worth doing here, or maybe it is now unnecessary for Web Inspector?
Saam Barati
Comment 10 2018-05-08 16:44:52 PDT
Comment on attachment 339884 [details] patch for landing View in context: https://bugs.webkit.org/attachment.cgi?id=339884&action=review >> Source/JavaScriptCore/API/JSVirtualMachinePrivate.h:27 >> +#define JSVirtualMachinePrivate_h > > API/JSVirtualMachine.h doesn't bother with header ifdefs. Should we bother with them here? ObjC is expected to #import which takes care of avoiding duplicate inclusions. I think we can get rid of this. JSContext does this so I just copied what it did. But I will remove it. This seems extraneous. >> Source/JavaScriptCore/runtime/VM.cpp:776 >> + deleteAllCode(DeleteAllCodeIfNotCollecting); > > Something we do in Web Inspector when triggering a GC is: > > sanitizeStackForVM(vm); > > Is that worth doing here, or maybe it is now unnecessary for Web Inspector? No, this is a good idea. I'll do that.
Saam Barati
Comment 11 2018-05-08 18:56:29 PDT
Comment on attachment 339884 [details] patch for landing View in context: https://bugs.webkit.org/attachment.cgi?id=339884&action=review >> Source/JavaScriptCore/API/JSVirtualMachinePrivate.h:33 >> +@interface JSVirtualMachine(Private) > > I think we normally prefix category names like we prefix classes, since all of this ObjC stuff is in the global namespace. > > For example WebKit does this with its `WK` prefix: > > @interface WKUserScript (WKPrivate) > ... > @end > > I think we should do the same. For example: > > @interface JSVirtualMachine (JSPrivate) > ... > @end This seems reasonable. I'll do this.
Saam Barati
Comment 12 2018-05-08 18:59:52 PDT
Created attachment 339912 [details] patch for landing
EWS Watchlist
Comment 13 2018-05-08 20:19:21 PDT
Comment on attachment 339912 [details] patch for landing Attachment 339912 [details] did not pass jsc-ews (mac): Output: http://webkit-queues.webkit.org/results/7618974 New failing tests: apiTests
EWS Watchlist
Comment 14 2018-05-09 09:02:12 PDT
Comment on attachment 339912 [details] patch for landing Attachment 339912 [details] did not pass win-ews (win): Output: http://webkit-queues.webkit.org/results/7623493 New failing tests: http/tests/security/canvas-remote-read-remote-video-blocked-no-crossorigin.html
EWS Watchlist
Comment 15 2018-05-09 09:02:24 PDT
Created attachment 339968 [details] Archive of layout-test-results from ews205 for win-future The attached test failures were seen while running run-webkit-tests on the win-ews. Bot: ews205 Port: win-future Platform: CYGWIN_NT-6.1-2.9.0-0.318-5-3-x86_64-64bit
Saam Barati
Comment 16 2018-05-09 11:48:36 PDT
I spoke to Ryan. We're going to land this then monitor JSC api tests to see if they fail on the bots/EWS going forward or not. I can't reproduce api test failure locally.
Saam Barati
Comment 17 2018-05-09 13:13:31 PDT
Filip Pizlo
Comment 18 2018-05-16 19:04:41 PDT
Comment on attachment 339912 [details] patch for landing View in context: https://bugs.webkit.org/attachment.cgi?id=339912&action=review > Source/JavaScriptCore/API/tests/testapi.mm:1501 > + @autoreleasepool { > + JSContext *context = [[JSContext alloc] init]; > + JSVirtualMachine *vm = [context virtualMachine]; > + [vm shrinkFootprint]; // Make sure that when we allocate a ton of memory below we reuse at little as possible. > + > + std::optional<size_t> footprintBefore = WTF::memoryFootprint(); > + RELEASE_ASSERT(footprintBefore); > + > + [context evaluateScript:@"for (let i = 0; i < 10000; ++i) { eval(`myVariable_${i} = [i]`); }"]; > + > + static constexpr size_t approximateBytes = 10000 * sizeof(int); > + std::optional<size_t> footprintMiddle = WTF::memoryFootprint(); > + RELEASE_ASSERT(footprintMiddle); > + checkResult(@"Footprint is larger than what we allocated", *footprintMiddle > approximateBytes); > + checkResult(@"Footprint got larger as we allocated a ton of stuff", *footprintMiddle > *footprintBefore); > + size_t allocationDelta = *footprintMiddle - *footprintBefore; > + checkResult(@"We allocated as much or more memory than what we expected to", allocationDelta >= approximateBytes); > + > + [context evaluateScript:@"for (let i = 0; i < 10000; ++i) { eval(`myVariable_${i} = null`); }"]; > + [vm shrinkFootprint]; > + std::optional<size_t> footprintAfter = WTF::memoryFootprint(); > + RELEASE_ASSERT(footprintAfter); > + checkResult(@"Footprint got smaller after we shrank the VM", *footprintAfter < *footprintMiddle); > + size_t freeDelta = *footprintMiddle - *footprintAfter; > + checkResult(@"Shrinking the footprint of the VM actually freed memory", freeDelta > (approximateBytes / 2)); > + } > + This test just randomly failed on my machine. I think it's a bad idea to create tests like these. Footprint is a complex OS metric that can grow or shrink for various reasons. I don't think it's correct to assert anything about it in a correctness test. If you want to add perf tests that report memory, and track regressions on those like perf regressions, then that makes sense. But asserting about footprint is as incorrect as asserting about time.
Saam Barati
Comment 19 2018-05-16 20:54:11 PDT
(In reply to Filip Pizlo from comment #18) > Comment on attachment 339912 [details] > patch for landing > > View in context: > https://bugs.webkit.org/attachment.cgi?id=339912&action=review > > > Source/JavaScriptCore/API/tests/testapi.mm:1501 > > + @autoreleasepool { > > + JSContext *context = [[JSContext alloc] init]; > > + JSVirtualMachine *vm = [context virtualMachine]; > > + [vm shrinkFootprint]; // Make sure that when we allocate a ton of memory below we reuse at little as possible. > > + > > + std::optional<size_t> footprintBefore = WTF::memoryFootprint(); > > + RELEASE_ASSERT(footprintBefore); > > + > > + [context evaluateScript:@"for (let i = 0; i < 10000; ++i) { eval(`myVariable_${i} = [i]`); }"]; > > + > > + static constexpr size_t approximateBytes = 10000 * sizeof(int); > > + std::optional<size_t> footprintMiddle = WTF::memoryFootprint(); > > + RELEASE_ASSERT(footprintMiddle); > > + checkResult(@"Footprint is larger than what we allocated", *footprintMiddle > approximateBytes); > > + checkResult(@"Footprint got larger as we allocated a ton of stuff", *footprintMiddle > *footprintBefore); > > + size_t allocationDelta = *footprintMiddle - *footprintBefore; > > + checkResult(@"We allocated as much or more memory than what we expected to", allocationDelta >= approximateBytes); > > + > > + [context evaluateScript:@"for (let i = 0; i < 10000; ++i) { eval(`myVariable_${i} = null`); }"]; > > + [vm shrinkFootprint]; > > + std::optional<size_t> footprintAfter = WTF::memoryFootprint(); > > + RELEASE_ASSERT(footprintAfter); > > + checkResult(@"Footprint got smaller after we shrank the VM", *footprintAfter < *footprintMiddle); > > + size_t freeDelta = *footprintMiddle - *footprintAfter; > > + checkResult(@"Shrinking the footprint of the VM actually freed memory", freeDelta > (approximateBytes / 2)); > > + } > > + > > This test just randomly failed on my machine. > > I think it's a bad idea to create tests like these. Footprint is a complex > OS metric that can grow or shrink for various reasons. I don't think it's > correct to assert anything about it in a correctness test. > > If you want to add perf tests that report memory, and track regressions on > those like perf regressions, then that makes sense. But asserting about > footprint is as incorrect as asserting about time. Yeah I agree with this w.r.t the OS’s footprint. However, I think we should be able to have this test but with our own internal calculation of the VM’s heap size. What do you think about converting it to be that?
Note You need to log in before you can comment on or make changes to this bug.