Ticket #2808: GC_Scheduling_PATCH2_WIP_v1.diff

File GC_Scheduling_PATCH2_WIP_v1.diff, 4.5 KB (added by Yves, 10 years ago)

An attempt to prevent situations where SpiderMonkey needs to trigger GC because it's low on memory. (for testing)

  • source/scriptinterface/ScriptInterface.cpp

     
    139139        m_rooter(NULL),
    140140        m_LastGCBytes(0),
    141141        m_LastGCCheck(0.0f),
    142         m_HeapGrowthBytesGCTrigger(heapGrowthBytesGCTrigger)
     142        m_HeapGrowthBytesGCTrigger(heapGrowthBytesGCTrigger),
     143        m_RuntimeSize(runtimeSize)
    143144    {
    144145        m_rt = JS_NewRuntime(runtimeSize, JS_USE_HELPER_THREADS);
    145146
     
    161162       
    162163        JS::SetGCSliceCallback(m_rt, GCSliceCallbackHook);
    163164       
    164         JS_SetGCParameter(m_rt, JSGC_MAX_MALLOC_BYTES, 384 * 1024 * 1024);
    165         JS_SetGCParameter(m_rt, JSGC_MAX_BYTES, 384 * 1024 * 1024);
     165        JS_SetGCParameter(m_rt, JSGC_MAX_MALLOC_BYTES, m_RuntimeSize);
     166        JS_SetGCParameter(m_rt, JSGC_MAX_BYTES, m_RuntimeSize);
    166167        JS_SetGCParameter(m_rt, JSGC_MODE, JSGC_MODE_INCREMENTAL);
    167         //JS_SetGCParameter(m_rt, JSGC_SLICE_TIME_BUDGET, 5);
    168         JS_SetGCParameter(m_rt, JSGC_ALLOCATION_THRESHOLD, 256);
     168        JS_SetGCParameter(m_rt, JSGC_ALLOCATION_THRESHOLD, m_RuntimeSize / 1024 / 1024);
    169169       
    170170        // The whole heap-growth mechanism seems to work only for non-incremental GCs.
    171171        // We disable it to make it more clear if full GCs happen triggered by this JSAPI internal mechanism.
     
    177177        ENSURE(m_dummyContext);
    178178    }
    179179   
     180    #define GC_DEBUG_PRINT 1
    180181    void MaybeIncrementalGC(double delay)
    181182    {
    182183        PROFILE2("MaybeIncrementalGC");
     
    201202            m_LastGCCheck = timer_Time();
    202203           
    203204            int gcBytes = JS_GetGCParameter(m_rt, JSGC_BYTES);
    204             //std::cout << "gcBytes: " << std::endl; // debugging
     205           
     206#if GC_DEBUG_PRINT
     207                std::cout << "gcBytes: " << gcBytes / 1024 << " KB" << std::endl;
     208#endif
     209           
    205210            if (m_LastGCBytes > gcBytes || m_LastGCBytes == 0)
    206211            {
    207                 //printf("Setting m_LastGCBytes: %d \n", gcBytes); // debugging
     212#if GC_DEBUG_PRINT
     213                printf("Setting m_LastGCBytes: %d KB \n", gcBytes / 1024);
     214#endif
    208215                m_LastGCBytes = gcBytes;
    209216            }
    210            
     217
    211218            // Run an additional incremental GC slice if the currently running incremental GC isn't over yet
    212219            // ... or
    213220            // start a new incremental GC if the JS heap size has grown enough for a GC to make sense
    214221            if (JS::IsIncrementalGCInProgress(m_rt) || (gcBytes - m_LastGCBytes > m_HeapGrowthBytesGCTrigger))
    215             {
    216                 // Use for debugging
    217                 /*if (JS::IsIncrementalGCInProgress(m_rt))
    218                     printf("Running incremental GC because an incremental cycle is in progress. \n");
     222            {               
     223#if GC_DEBUG_PRINT
     224                if (JS::IsIncrementalGCInProgress(m_rt))
     225                    printf("An incremental GC cycle is in progress. \n");
    219226                else
    220                     printf("Running incremental GC because JSGC_BYTES - m_LastGCBytes > m_HeapGrowthBytesGCTrigger "
    221                         " ---- JSGC_BYTES: %d    m_LastGCBytes: %d    m_HeapGrowthBytesGCTrigger: %d ",
    222                         gcBytes,
    223                         m_LastGCBytes,
    224                         m_HeapGrowthBytesGCTrigger);
    225                 }*/
    226                 PrepareContextsForIncrementalGC();
    227                 JS::IncrementalGC(m_rt, JS::gcreason::REFRESH_FRAME, GCSliceTimeBudget);
     227                    printf("GC needed because JSGC_BYTES - m_LastGCBytes > m_HeapGrowthBytesGCTrigger \n"
     228                        "    JSGC_BYTES: %d KB \n    m_LastGCBytes: %d KB \n    m_HeapGrowthBytesGCTrigger: %d KB \n",
     229                        gcBytes / 1024,
     230                        m_LastGCBytes / 1024,
     231                        m_HeapGrowthBytesGCTrigger / 1024);
     232#endif
     233               
     234                // A hack to make sure we never exceed the runtime size because we can't collect the memory
     235                // fast enough.
     236                if(gcBytes > m_RuntimeSize / 2)
     237                {
     238                    if (JS::IsIncrementalGCInProgress(m_rt))
     239                    {
     240#if GC_DEBUG_PRINT
     241                        printf("Finishing incremental GC because gcBytes > m_RuntimeSize / 2. \n");
     242#endif
     243                        PrepareContextsForIncrementalGC();
     244                        JS::FinishIncrementalGC(m_rt, JS::gcreason::REFRESH_FRAME);
     245                    }
     246                    else
     247                    {
     248#if GC_DEBUG_PRINT
     249                        printf("Running full GC because gcBytes > m_RuntimeSize / 2. \n");
     250#endif
     251                        JS_GC(m_rt);
     252                    }
     253                }
     254                else
     255                {
     256#if GC_DEBUG_PRINT
     257                    if (!JS::IsIncrementalGCInProgress(m_rt))
     258                        printf("Starting incremental GC \n");
     259                    else
     260                        printf("Running incremental GC slice \n");
     261#endif
     262                    PrepareContextsForIncrementalGC();
     263                    JS::IncrementalGC(m_rt, JS::gcreason::REFRESH_FRAME, GCSliceTimeBudget);
     264                }
    228265                m_LastGCBytes = gcBytes;
    229266            }
    230267        }
     
    255292    // Workaround for: https://bugzilla.mozilla.org/show_bug.cgi?id=890243
    256293    JSContext* m_dummyContext;
    257294   
     295    int m_RuntimeSize;
    258296    int m_HeapGrowthBytesGCTrigger;
    259297    int m_LastGCBytes;
    260298    double m_LastGCCheck;