<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>153317</bug_id>
          
          <creation_ts>2016-01-21 13:17:30 -0800</creation_ts>
          <short_desc>Worker terminated by GC after calling importScripts</short_desc>
          <delta_ts>2024-01-29 19:02:09 -0800</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>WebCore JavaScript</component>
          <version>WebKit Nightly Build</version>
          <rep_platform>Unspecified</rep_platform>
          <op_sys>OS X 10.11</op_sys>
          <bug_status>NEW</bug_status>
          <resolution></resolution>
          
          <see_also>https://bugs.webkit.org/show_bug.cgi?id=242874</see_also>
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Rob Wu">rob</reporter>
          <assigned_to name="Nobody">webkit-unassigned</assigned_to>
          <cc>ahmad.saleem792</cc>
    
    <cc>ap</cc>
    
    <cc>ggaren</cc>
    
    <cc>tristan.fraipont</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>1157400</commentid>
    <comment_count>0</comment_count>
    <who name="Rob Wu">rob</who>
    <bug_when>2016-01-21 13:17:30 -0800</bug_when>
    <thetext>After calling importScripts, the worker object (on the main thread) is unexpectedly garbage-collected and the worker thread is terminated.
This is because DedicatedWorkerGlobalScope::importScripts calls reportPendingActivity, which notifies the main thread that the worker is idle, regardless of whether there is active code after the importScripts call from JavaScript.

Steps to reproduce:
1. Start WebKit Nightly and open the Inspector (e.g. on example.com)
2. Run the following snippet:

;(function() {
    // setTimeout because the bug only occurs when importScripts is called after the
    // worker script has completely run (in JSC).
    var code = &apos;setTimeout(&apos; + function() {

        importScripts(&quot;data:,&quot;);

        // V8 immediately terminates a thread when the worker object is GC&apos;d,
        // while JSC continues running the worker script until the tab is closed,
        // so schedule the busy loop after GC on the main thread has run.
        setTimeout(function() {
            // Busy loop so we can observe whether the worker script is active.
            while (true) {}
        }, 1000);
    } + &apos;);&apos;;

    // Create worker without saving a reference.
    new Worker(URL.createObjectURL(new Blob([code])));

    // Trigger GC
    setTimeout(function() {
        for (var i = 0; i &lt; 25; ++i)
            new Array(Math.pow(2, i));
    }, 500);
})();
3. Look at the Activity Monitor to watch the CPU usage of Safari.
4. Open a new tab and close the tab from step 3 (to force termination of the worker if not already done).
5. Quit Safari and repeat the above, but with importScripts commented out or removed.

Expected result:
- Step 3 and 5 should give the same results, i.e. 100% usage of a CPU core (caused by the busy loop).

Actual result:
- After step 3, the CPU usage of Safari is negligible. This shows that the scheduled busy loop never executes, i.e. the worker thread is terminated.
- After step 5, the CPU usage of Safari is 100% (as expected).
This difference in behavior shows that importScripts affects the garbage collection behavior.


More info:
- Similar bug in Blink, with work-around for web devs, and patch for Blink: https://crbug.com/572225
- The above example seems contrived, but it was a reduction from a bug that affected real-world code that uses RequireJS in a worker. The worker object was GC&apos;d even though there were message listeners on the Worker instance.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1158569</commentid>
    <comment_count>1</comment_count>
    <who name="Alexey Proskuryakov">ap</who>
    <bug_when>2016-01-25 15:42:41 -0800</bug_when>
    <thetext>Thank you for the great bug report!</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1932248</commentid>
    <comment_count>2</comment_count>
    <who name="Kaiido">tristan.fraipont</who>
    <bug_when>2023-02-08 23:01:42 -0800</bug_when>
    <thetext>Things might have changed since this was first reported, but I&apos;d like to point out that if the snippet still does reproduce in current builds it&apos;s because `&quot;data:,&quot;` does not contain a proper JS mimeType. As far as I can see, this is actually in accordance with the specs, and it&apos;s a bit weird that other browsers do not throw here (e.g they&apos;d throw with a non &quot;data:&quot; URL resulting in the same mimeType).  
But anyway, what happens currently has nothing to do with GC, and it&apos;s normal the worker is terminated before entering the busy loop (an error is even displayed).</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>