Bug 145433 - JavaScriptCore Garbage Collector Issue
Summary: JavaScriptCore Garbage Collector Issue
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: 420+
Hardware: iPhone / iPad iOS 8.2
: P2 Major
Assignee: Nobody
Depends on:
Reported: 2015-05-28 04:43 PDT by maxh
Modified: 2015-06-06 09:25 PDT (History)
2 users (show)

See Also:

iOS project with reproduced bug (607.99 KB, application/zip)
2015-05-28 04:45 PDT, maxh
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description maxh 2015-05-28 04:43:51 PDT

Geoffrey Garen advised me to report my following problem here, as it seems to be a bug in JavaScriptCore.

I implemented a JavaScript library for a Swift iOS app connecting via JavaScriptCore. Although I don’t really know if this mail list is the correct place to ask, I thought I’d give it a shot.
I really liked how easy it was to get Swift to work with JavaScript and vice versa. But I stumbled upon a problem when I was testing the performance of my app. I wrote a XCTest in Xcode which performs multiple calls of the JavaScript library (with loops) but it always stops or freezes after the 292nd call.
I guess that the JavaScriptCore context (or virtual machine) is not deinitialized after the method call was successful. I even tried a manual deinitialize (or is deallocate the better word?) but it still freezes. I looked up the allocations and threads in Instruments and it shows multiple VM: JS garbage collector allocations which are still active in the app.
I wrote a question on StackOverflow with some code examples and the Instruments log:
but I haven’t received a single answer yet. I guess JavaScriptCore on iOS is still something that is not being used very much.
I was able to reproduce the issue in another project which I added as a zip file to this report. Just open the project and test or profile it. The loop in the test class will freeze the app after the 292nd call.

I would be very happy if someone could take a look into my problem and share thoughts on it. This is part of my bachelor thesis so it would really help a lot.

Thank you very much in advance and best regards,
Max Hentschel

p.s.: I am using iOS 8.3 but it wasn't selectable from the dropdown. And I cannot tell the version of JavaScriptCore as I wasn't able to find out which version iOS 8.3 uses (no note on Apple's Developer page as well).
Comment 1 maxh 2015-05-28 04:45:25 PDT
Created attachment 253842 [details]
iOS project with reproduced bug
Comment 2 maxh 2015-06-04 06:18:26 PDT
So I've tried some different tests with repeating calls from Swift to JS but the freeze keeps coming up. Any ideas on this?
Comment 3 maxh 2015-06-06 06:33:10 PDT

I gathered some citations for my bachelor thesis and I read the JavaScriptCore WebKit page again and noticed the section about the three kinds of JIT compilers for JavaScriptCore. Is it possible that in my tests the baseline JIT tries to handle everything and the dfg JIT is not taking over? Or am I misunderstanding that part? Am I able to manually access the different JITs or is this handled automatically?
Comment 4 Saam Barati 2015-06-06 08:03:39 PDT
Hi Max,
I can maybe take a closer look when I'm not on vacation (I'm on my phone now)
but I have a question:
Are you initializing a new VM in every loop iteration?

It sounds like you may be misinterpreting what's happening with the JITs.
The JITs should "Just Work" as if everything were just run through
an Interpreter without any intervention on your part. Tiering up from
the baseline JIT to the DFG is handled automatically and you don't
have to think about that.
Comment 5 maxh 2015-06-06 08:13:16 PDT
Hi Saam,

thanks for looking into this.
In my tests I have to loops, one for the number of test runs (let's say 20) and the inner loop that takes a single test from an array (an array may contain up to 255 values for one test), which then calls the function for the JavaScriptCore implementation. So yes, every time I run one test in the inner loop a new JSVirtualMachine() and a new JSContext(virtualMachine) object will be created.

Should I just keep on JSVirtualMachine alive all the time and create new JSContext's instead?
Comment 6 maxh 2015-06-06 08:30:45 PDT
By the way, I need to say that I also had the issue before I manually initialized the JSVirtualMachine but only the JSContext. But I guess that if I don't manually initialize the VM it will automatically generated with a new JSContext right?
If you want to take a quick look at some code, you can use my StackOverflow question:

Thanks again.
Comment 7 maxh 2015-06-06 09:25:51 PDT
So ... yeah ... I found it ... 
I was initializing a new VM every loop. I got rid of this (opening one single VM on start and be done with it) and everything works fine now.
I guess my misconception was that I tried to manually close every VM at the end of each loop, which didn't work. So I guess my last question is: is there a way to manually deinitialize a VM from Swift/Objective-C somehow?
I tried a deinitialize(){} but as you know that doesn't work either.

Thank you all (especially Saam for pushing me in the right direction),