Changeset 56435 in webkit for trunk/JavaScriptCore/API


Ignore:
Timestamp:
Mar 24, 2010, 12:11:51 AM (15 years ago)
Author:
[email protected]
Message:

Bug 36519 - JSGlobalContextRelease is unnecessarily slow

Reviewed by Oliver Hunt.

Since [ http://trac.webkit.org/changeset/35917 ], calling
JSGlobalContextRelease always triggers a GC heap collection
(if not a full destroy). As per 35917's changelog "This is
only really necessary when the (JSGlobalObject's) last
reference is released, but there is no way to determine that,
and no harm in collecting slightly more often."

Well, we now know of cases of API clients who are harmed by
the performance penalty of collecting too often, so it's time
to add a way to determine whether a call to JSGlobalContextRelease
is removing the last protect from it's global object. If further
protects are retaining the global object (likely from other
JSGlobalContextRefs), then don't trigger a GC collection.

  • API/JSContextRef.cpp:
  • runtime/Collector.cpp:

(JSC::Heap::unprotect): return a boolean indicating that the value is now unprotected.

  • runtime/Collector.h:
  • wtf/HashCountedSet.h:

(WTF::::remove): return a boolean indicating whether the value was removed from the set.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/API/JSContextRef.cpp

    r55633 r56435  
    123123
    124124    JSGlobalData& globalData = exec->globalData();
     125    JSGlobalObject* dgo = exec->dynamicGlobalObject();
    125126    IdentifierTable* savedIdentifierTable = setCurrentIdentifierTable(globalData.identifierTable);
    126127
    127     gcUnprotect(exec->dynamicGlobalObject());
     128    // One reference is held by JSGlobalObject, another added by JSGlobalContextRetain().
     129    bool releasingContextGroup = globalData.refCount() == 2;
     130    bool releasingGlobalObject = Heap::heap(dgo)->unprotect(dgo);
     131    // If this is the last reference to a global data, it should also
     132    // be the only remaining reference to the global object too!
     133    ASSERT(!releasingContextGroup || releasingGlobalObject);
    128134
    129     if (globalData.refCount() == 2) { // One reference is held by JSGlobalObject, another added by JSGlobalContextRetain().
    130         // The last reference was released, this is our last chance to collect.
     135    // An API 'JSGlobalContextRef' retains two things - a global object and a
     136    // global data (or context group, in API terminology).
     137    // * If this is the last reference to any contexts in the given context group,
     138    //   call destroy on the heap (the global data is being  freed).
     139    // * If this was the last reference to the global object, then unprotecting
     140    //   it may  release a lot of GC memory - run the garbage collector now.
     141    // * If there are more references remaining the the global object, then do nothing
     142    //   (specifically that is more protects, which we assume come from other JSGlobalContextRefs).
     143    if (releasingContextGroup)
    131144        globalData.heap.destroy();
    132     } else
     145    else if (releasingGlobalObject)
    133146        globalData.heap.collectAllGarbage();
    134147
Note: See TracChangeset for help on using the changeset viewer.