Ignore:
Timestamp:
Jan 11, 2007, 10:25:15 PM (18 years ago)
Author:
ggaren
Message:

RS by Brady Eidson.


Rolling out r18786 because it caused leaks.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/bindings/runtime_root.cpp

    r18786 r18795  
    4545// are represented by a jlong.
    4646
    47 typedef HashMap<const RootObject*, ProtectCountSet*> RootObjectMap;
    48 
    49 static RootObjectMap* getRootObjectMap()
    50 {
    51     static RootObjectMap staticRootObjectMap;
    52     return &staticRootObjectMap;
    53 }
    54 
    55 static ProtectCountSet* getProtectCountSet(const RootObject* rootObject)
    56 {
    57     RootObjectMap* rootObjectMap = getRootObjectMap();
    58     ProtectCountSet* protectCountSet = rootObjectMap->get(rootObject);
    59 
    60     if (!protectCountSet) {
    61         protectCountSet = new ProtectCountSet;
    62         rootObjectMap->add(rootObject, protectCountSet);
    63     }
    64     return protectCountSet;
    65 }
    66 
    67 static void destroyProtectCountSet(const RootObject* rootObject, ProtectCountSet* protectCountSet)
    68 {
    69     RootObjectMap* rootObjectMap = getRootObjectMap();
    70     rootObjectMap->remove(rootObject);
    71     delete protectCountSet;
    72 }
    73 
    74 // FIXME:  These two functions are a potential performance problem.  We could
    75 // fix them by adding a JSObject to RootObject dictionary.
    76 
    77 ProtectCountSet* getProtectCountSet(JSObject* jsObject)
    78 {
    79     const RootObject* rootObject = getRootObject(jsObject);
    80     return getProtectCountSet(rootObject);
    81 }
    82 
    83 const RootObject* getRootObject(JSObject* jsObject)
    84 {
    85     RootObjectMap* rooObjectMap = getRootObjectMap();
    86    
    87     RootObjectMap::const_iterator end = rooObjectMap->end();
    88     for (RootObjectMap::const_iterator it = rooObjectMap->begin(); it != end; ++it) {
    89         ProtectCountSet* set = it->second;
    90         if (set->contains(jsObject))
    91             return it->first;
     47typedef HashMap<const RootObject*, ReferencesSet*> ReferencesByRootMap;
     48
     49static ReferencesByRootMap* getReferencesByRootMap()
     50{
     51    static ReferencesByRootMap* referencesByRootMap = 0;
     52   
     53    if (!referencesByRootMap)
     54        referencesByRootMap = new ReferencesByRootMap;
     55   
     56    return referencesByRootMap;
     57}
     58
     59static ReferencesSet* getReferencesSet(const RootObject* rootObject)
     60{
     61    ReferencesByRootMap* refsByRoot = getReferencesByRootMap();
     62    ReferencesSet* referencesSet = 0;
     63   
     64    referencesSet = refsByRoot->get(rootObject);
     65    if (!referencesSet) {
     66        referencesSet  = new ReferencesSet;
     67        refsByRoot->add(rootObject, referencesSet);
     68    }
     69    return referencesSet;
     70}
     71
     72// Scan all the dictionary for all the roots to see if any have a
     73// reference to the imp, and if so, return it's reference count
     74// dictionary.
     75// FIXME:  This is a potential performance bottleneck with many applets.  We could fix be adding a
     76// imp to root dictionary.
     77ReferencesSet* findReferenceSet(JSObject* imp)
     78{
     79    ReferencesByRootMap* refsByRoot = getReferencesByRootMap ();
     80    if (refsByRoot) {
     81        ReferencesByRootMap::const_iterator end = refsByRoot->end();
     82        for (ReferencesByRootMap::const_iterator it = refsByRoot->begin(); it != end; ++it) {
     83            ReferencesSet* set = it->second;
     84           
     85            if (set->contains(imp))
     86                return set;
     87        }
    9288    }
    9389   
     
    9591}
    9692
    97 const RootObject* getRootObject(Interpreter* interpreter)
    98 {
    99     RootObjectMap* rooObjectMap = getRootObjectMap();
    100    
    101     if (rooObjectMap) {
    102         RootObjectMap::const_iterator end = rooObjectMap->end();
    103         for (RootObjectMap::const_iterator it = rooObjectMap->begin(); it != end; ++it) {
     93// FIXME:  This is a potential performance bottleneck with many applets.  We could fix be adding a
     94// imp to root dictionary.
     95const RootObject* rootObjectForImp (JSObject* imp)
     96{
     97    ReferencesByRootMap* refsByRoot = getReferencesByRootMap ();
     98    const RootObject* rootObject = 0;
     99   
     100    if (refsByRoot) {
     101        ReferencesByRootMap::const_iterator end = refsByRoot->end();
     102        for (ReferencesByRootMap::const_iterator it = refsByRoot->begin(); it != end; ++it) {
     103            ReferencesSet* set = it->second;
     104            if (set->contains(imp)) {
     105                rootObject = it->first;
     106                break;
     107            }
     108        }
     109    }
     110   
     111    return rootObject;
     112}
     113
     114const RootObject* rootObjectForInterpreter(Interpreter* interpreter)
     115{
     116    ReferencesByRootMap* refsByRoot = getReferencesByRootMap ();
     117   
     118    if (refsByRoot) {
     119        ReferencesByRootMap::const_iterator end = refsByRoot->end();
     120        for (ReferencesByRootMap::const_iterator it = refsByRoot->begin(); it != end; ++it) {
    104121            const RootObject* aRootObject = it->first;
    105122           
     
    112129}
    113130
    114 void addNativeReference(const RootObject* rootObject, JSObject* jsObject)
    115 {
    116     if (!rootObject)
     131void addNativeReference(const RootObject* rootObject, JSObject* imp)
     132{
     133    if (rootObject) {
     134        ReferencesSet* referenceMap = getReferencesSet(rootObject);
     135       
     136        unsigned numReferences = referenceMap->count(imp);
     137        if (numReferences == 0) {
     138            JSLock lock;
     139            gcProtect(imp);
     140        }
     141        referenceMap->add(imp);
     142    }
     143}
     144
     145void removeNativeReference(JSObject* imp)
     146{
     147    if (!imp)
    117148        return;
    118    
    119     ProtectCountSet* protectCountSet = getProtectCountSet(rootObject);
    120     if (!protectCountSet->contains(jsObject)) {
    121         JSLock lock;
    122         gcProtect(jsObject);
    123     }
    124     protectCountSet->add(jsObject);
    125 }
    126 
    127 void removeNativeReference(JSObject* jsObject)
    128 {
    129     if (!jsObject)
    130         return;
    131 
    132     ProtectCountSet* protectCountSet = getProtectCountSet(jsObject);
    133     if (protectCountSet->count(jsObject) == 1) {
    134         JSLock lock;
    135         gcUnprotect(jsObject);
    136     }
    137     protectCountSet->remove(jsObject);
     149
     150    ReferencesSet *referencesSet = findReferenceSet(imp);
     151    if (referencesSet) {
     152        unsigned numReferences = referencesSet->count(imp);
     153       
     154        if (numReferences == 1) {
     155            JSLock lock;
     156            gcUnprotect(imp);
     157        }
     158        referencesSet->remove(imp);
     159    }
    138160}
    139161
     
    265287void RootObject::destroy()
    266288{
    267     ProtectCountSet* protectCountSet = getProtectCountSet(this);
    268    
    269     if (protectCountSet) {
    270         ProtectCountSet::iterator end = protectCountSet->end();
    271         for (ProtectCountSet::iterator it = protectCountSet->begin(); it != end; ++it) {
     289    ReferencesSet* referencesSet = getReferencesSet(this);
     290   
     291    if (referencesSet) {
     292        ReferencesSet::iterator end = referencesSet->end();
     293        for (ReferencesSet::iterator it = referencesSet->begin(); it != end; ++it) {
    272294            JSLock lock;
    273295            gcUnprotect(it->first);           
    274296        }
    275 
    276         destroyProtectCountSet(this, protectCountSet);
     297        referencesSet->clear();
     298        ReferencesByRootMap* refsByRoot = getReferencesByRootMap();
     299        refsByRoot->remove(this);
     300        delete referencesSet;
    277301    }
    278302
Note: See TracChangeset for help on using the changeset viewer.