WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
251261
Large allocations in a tight loop perform poorly when using the JavaScriptCore C and Objective-C APIs
https://bugs.webkit.org/show_bug.cgi?id=251261
Summary
Large allocations in a tight loop perform poorly when using the JavaScriptCor...
Kasper Isager Dalsgarð
Reported
2023-01-27 04:29:14 PST
Consider the following C and Objective-C programs that perform 64 KiB allocations in a tight loop: ``` #include <JavaScriptCore/JavaScriptCore.h> int main () { JSContextRef context = JSGlobalContextCreate(NULL); JSStringRef source = JSStringCreateWithUTF8CString( "for (let i = 0; i < 1e6; i++) new Uint8Array(1024 * 64)" ); JSEvaluateScript(context, source, NULL, NULL, 1, NULL); } ``` ``` #include <JavaScriptCore/JavaScriptCore.h> int main () { JSContext *context = [[JSContext alloc] init]; [context evaluateScript:@"for (let i = 0; i < 1e6; i++) new Uint8Array(1024 * 64)"]; } ``` When running these on my machine, I'm observing an 8x slowdown compared to running the same allocation loop in either Safari or using the jsc helper from the builtin JavaScriptCore framework (/System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/Helpers/jsc) and I cannot seem to figure out why. Both programs were compiled with clang using -O3.
Attachments
Output generated by JSC_dumpDisassembly
(217.98 KB, text/plain)
2023-02-17 00:40 PST
,
Kasper Isager Dalsgarð
no flags
Details
CPU profile of `JavaScriptCore.framework/Versions/Current/Helpers/jsc`
(822.64 KB, application/octet-stream)
2023-05-24 00:20 PDT
,
Kasper Isager Dalsgarð
no flags
Details
CPU profile of `a.out`
(3.15 MB, application/octet-stream)
2023-05-24 00:20 PDT
,
Kasper Isager Dalsgarð
no flags
Details
GC logs for `JavaScriptCore.framework/Versions/Current/Helpers/jsc`
(810.34 KB, text/plain)
2023-05-24 00:21 PDT
,
Kasper Isager Dalsgarð
no flags
Details
GC logs for `a.out`
(28.60 MB, text/plain)
2023-05-24 00:22 PDT
,
Kasper Isager Dalsgarð
no flags
Details
View All
Add attachment
proposed patch, testcase, etc.
Alexey Proskuryakov
Comment 1
2023-01-28 16:55:50 PST
Does your test program allow JIT?
https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_allow-jit
Kasper Isager Dalsgarð
Comment 2
2023-01-29 23:51:17 PST
I think so, yes, but I'm unsure how to verify that's it's actually working: ``` $ codesign --display --entitlements - a.out Executable=<cwd>/a.out [Dict] [Key] com.apple.security.cs.allow-jit [Value] [Bool] true ``` Code signed with the following command: ``` $ codesign --force --options runtime --sign <key> --entitlements entitlements.plist a.out ``` I don't know if it provides any clues, but reducing the size of each allocation to just 1 KiB instead of 64 KiB makes my test program perform similar to Safari and jsc. What kind of optimisations would the JIT be able to do for larger allocations?
Alexey Proskuryakov
Comment 3
2023-01-30 08:33:59 PST
Not sure, CC'ing some folks who would know. FWIW, the jsc binary on macOS has more JIT related entitlements, but others don't seem to be documented.
Kasper Isager Dalsgarð
Comment 4
2023-01-30 12:11:50 PST
Tried matching the jsc entitlements with the exception of com.apple.private.verified-jit, but no dice I'm afraid: ``` $ codesign --display --entitlements - a.out Executable=<cwd>/a.out [Dict] [Key] com.apple.security.cs.allow-jit [Value] [Bool] true [Key] com.apple.security.cs.jit-write-allowlist [Value] [Bool] true [Key] com.apple.security.cs.single-jit [Value] [Bool] true ```
Radar WebKit Bug Importer
Comment 5
2023-02-03 04:30:19 PST
<
rdar://problem/105001996
>
Yusuke Suzuki
Comment 6
2023-02-15 17:02:51 PST
Can you run this with `JSC_dumpDisassembly=1` environment variable? If JIT code is generated from that, then JIT is enabled. If not, JIT is not enabled.
Kasper Isager Dalsgarð
Comment 7
2023-02-17 00:40:49 PST
Created
attachment 465047
[details]
Output generated by JSC_dumpDisassembly
Kasper Isager Dalsgarð
Comment 8
2023-02-17 00:41:55 PST
I've uploaded an attachment with the generated output, let me know if there's anything else I can provide!
Kasper Isager Dalsgarð
Comment 9
2023-05-23 00:14:03 PDT
Do you need anything more from me on this?
Mark Lam
Comment 10
2023-05-23 09:46:26 PDT
Hi Kasper, your dump shows that you are getting JIT support. So, this is not an issue with the JIT being disabled. Next steps: 1. How are you measuring the 8x slowdown? Your description below didn't describe this. Please describe this so that we can make sure that you're comparing equivalent things. 2. My gut feeling is that there might be GC activity at play. Try running your executable and jsc with JSC_logGC=1, and see if there's a difference in GC activity. 3. Run Instruments profiler and collect CPU profiles for runs with your executable and with jsc. Then compare to see if there's a difference in the profiles. Based on the data you get from those, we may be able to give you more advice. Thanks.
Kasper Isager Dalsgarð
Comment 11
2023-05-24 00:20:00 PDT
Created
attachment 466474
[details]
CPU profile of `JavaScriptCore.framework/Versions/Current/Helpers/jsc`
Kasper Isager Dalsgarð
Comment 12
2023-05-24 00:20:48 PDT
Created
attachment 466475
[details]
CPU profile of `a.out`
Kasper Isager Dalsgarð
Comment 13
2023-05-24 00:21:25 PDT
Created
attachment 466476
[details]
GC logs for `JavaScriptCore.framework/Versions/Current/Helpers/jsc`
Kasper Isager Dalsgarð
Comment 14
2023-05-24 00:22:45 PDT
Created
attachment 466477
[details]
GC logs for `a.out`
Kasper Isager Dalsgarð
Comment 15
2023-05-24 00:33:23 PDT
Thanks for detailing the additional steps! 1. I've run both my compiled programs (a.out) and the jsc helper (/System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/Helpers/jsc) through `time` and the slowdown I reported was based on those timings. For the jsc helper, I stuffed the loop in a JavaScript file and passed that to jsc. 2. I've attached the GC logs for both the jsc helper and one of my programs. I think it's safe to say that the GC is on overdrive in my programs; I'm counting 215,577 occurrences of "GC END" for my programs, but only 5,874 occurrences in the case of jsc. 3. I've attached the CPU profiles for both the jsc helper and one of my programs. They look very similar to me, except for the total durations, and I'm unsure where to look specifically for GC activity.
Kasper Isager Dalsgarð
Comment 16
2023-08-27 07:32:57 PDT
Is there anything else I can do to help identify the cause of this?
Kasper Isager Dalsgarð
Comment 17
2023-09-27 04:26:12 PDT
This went away after upgrading to macOS 14 so I assume whatever caused this was fixed. Marking as resolved.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug