Ignore:
Timestamp:
Jan 12, 2007, 1:11:22 PM (18 years ago)
Author:
ggaren
Message:

RS by Brady Eidson.


Rolling back in r18786 with leaks fixed, and these renames slightly reworked:

Because they can return 0:
rootObjectForImp => findRootObject (overloaded for JSObject* and Interpreter*)
rootObjectForInterpreter => findRootObject (ditto)
findReferenceSet => findProtectCountSet

File:
1 edited

Legend:

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

    r18795 r18811  
    4545// are represented by a jlong.
    4646
    47 typedef HashMap<const RootObject*, ReferencesSet*> ReferencesByRootMap;
    48 
    49 static ReferencesByRootMap* getReferencesByRootMap()
    50 {
    51     static ReferencesByRootMap* referencesByRootMap = 0;
    52    
    53     if (!referencesByRootMap)
    54         referencesByRootMap = new ReferencesByRootMap;
    55    
    56     return referencesByRootMap;
    57 }
    58 
    59 static 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.
    77 ReferencesSet* 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         }
     47typedef HashMap<const RootObject*, ProtectCountSet*> RootObjectMap;
     48
     49static RootObjectMap* rootObjectMap()
     50{
     51    static RootObjectMap staticRootObjectMap;
     52    return &staticRootObjectMap;
     53}
     54
     55static ProtectCountSet* getProtectCountSet(const RootObject* rootObject)
     56{
     57    ProtectCountSet* protectCountSet = rootObjectMap()->get(rootObject);
     58
     59    if (!protectCountSet) {
     60        protectCountSet = new ProtectCountSet;
     61        rootObjectMap()->add(rootObject, protectCountSet);
     62    }
     63    return protectCountSet;
     64}
     65
     66static void destroyProtectCountSet(const RootObject* rootObject, ProtectCountSet* protectCountSet)
     67{
     68    rootObjectMap()->remove(rootObject);
     69    delete protectCountSet;
     70}
     71
     72// FIXME:  These two functions are a potential performance problem.  We could
     73// fix them by adding a JSObject to RootObject dictionary.
     74
     75ProtectCountSet* findProtectCountSet(JSObject* jsObject)
     76{
     77    const RootObject* rootObject = findRootObject(jsObject);
     78    return rootObject ? getProtectCountSet(rootObject) : 0;
     79}
     80
     81const RootObject* findRootObject(JSObject* jsObject)
     82{
     83    RootObjectMap::const_iterator end = rootObjectMap()->end();
     84    for (RootObjectMap::const_iterator it = rootObjectMap()->begin(); it != end; ++it) {
     85        ProtectCountSet* set = it->second;
     86        if (set->contains(jsObject))
     87            return it->first;
    8888    }
    8989   
     
    9191}
    9292
    93 // FIXME:  This is a potential performance bottleneck with many applets.  We could fix be adding a
    94 // imp to root dictionary.
    95 const 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 
    114 const 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) {
    121             const RootObject* aRootObject = it->first;
    122            
    123             if (aRootObject->interpreter() == interpreter)
    124                 return aRootObject;
    125         }
     93const RootObject* findRootObject(Interpreter* interpreter)
     94{
     95    RootObjectMap::const_iterator end = rootObjectMap()->end();
     96    for (RootObjectMap::const_iterator it = rootObjectMap()->begin(); it != end; ++it) {
     97        const RootObject* aRootObject = it->first;
     98       
     99        if (aRootObject->interpreter() == interpreter)
     100            return aRootObject;
    126101    }
    127102   
     
    129104}
    130105
    131 void 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 
    145 void removeNativeReference(JSObject* imp)
    146 {
    147     if (!imp)
     106void addNativeReference(const RootObject* rootObject, JSObject* jsObject)
     107{
     108    if (!rootObject)
    148109        return;
    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     }
     110   
     111    ProtectCountSet* protectCountSet = getProtectCountSet(rootObject);
     112    if (!protectCountSet->contains(jsObject)) {
     113        JSLock lock;
     114        gcProtect(jsObject);
     115    }
     116    protectCountSet->add(jsObject);
     117}
     118
     119void removeNativeReference(JSObject* jsObject)
     120{
     121    if (!jsObject)
     122        return;
     123
     124    // We might have manually detroyed the root object and its protect set already
     125    ProtectCountSet* protectCountSet = findProtectCountSet(jsObject);
     126    if (!protectCountSet)
     127        return;
     128
     129    if (protectCountSet->count(jsObject) == 1) {
     130        JSLock lock;
     131        gcUnprotect(jsObject);
     132    }
     133    protectCountSet->remove(jsObject);
    160134}
    161135
     
    287261void RootObject::destroy()
    288262{
    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) {
     263    ProtectCountSet* protectCountSet = getProtectCountSet(this);
     264   
     265    if (protectCountSet) {
     266        ProtectCountSet::iterator end = protectCountSet->end();
     267        for (ProtectCountSet::iterator it = protectCountSet->begin(); it != end; ++it) {
    294268            JSLock lock;
    295269            gcUnprotect(it->first);           
    296270        }
    297         referencesSet->clear();
    298         ReferencesByRootMap* refsByRoot = getReferencesByRootMap();
    299         refsByRoot->remove(this);
    300         delete referencesSet;
     271
     272        destroyProtectCountSet(this, protectCountSet);
    301273    }
    302274
Note: See TracChangeset for help on using the changeset viewer.