Ignore:
Timestamp:
Jan 11, 2007, 4:46:36 PM (18 years ago)
Author:
ggaren
Message:

Reviewed by Anders Carlsson.

Even more cleanup in preparation for fixing <rdar://problem/4608404>
WebScriptObject's _executionContext lack of ownership policy causes
crashes (e.g., in Dashcode)


Layout tests pass.


Renames:

ReferencesSet | ProtectCounts => ProtectCountSet (because it's a typename for a set of GC protect counts)
ReferencesByRootMap => RootObjectMap (because RootObjectToProtectCountSetMap would have been confusing)
pv => protectedValues
rootObjectForImp => getRootObject (overloaded for JSObject* and Interpreter*)
rootObjectForInterpreter => getRootObject (ditto)
findReferenceSet => getProtectCountSet
imp => jsObject


(KJS::Bindings::getRootObjectMap): Changed to take advantage of built-in
facility for initializing static variables.

(KJS::Bindings::getProtectCountSet):
(KJS::Bindings::destroyProtectCountSet): Added. Helps encapsulate the fact
that getting a ProtectCountSet entails adding a RootObject to a hash table,
and destroying one entails the reverse.

(KJS::Bindings::getRootObject): Removed spurious NULL check.


(KJS::Bindings::findReferenceSet): Renamed. Changed to use getRootObject()
instead of iterating on its own.

(KJS::Bindings::addNativeReference): Changed to use an early return instead
of indenting the whole function.
(KJS::Bindings::removeNativeReference): Ditto.

File:
1 edited

Legend:

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

    r18782 r18786  
    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* getRootObjectMap()
     50{
     51    static RootObjectMap staticRootObjectMap;
     52    return &staticRootObjectMap;
     53}
     54
     55static 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
     67static 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
     77ProtectCountSet* getProtectCountSet(JSObject* jsObject)
     78{
     79    const RootObject* rootObject = getRootObject(jsObject);
     80    return getProtectCountSet(rootObject);
     81}
     82
     83const 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;
    8892    }
    8993   
     
    9195}
    9296
    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) {
     97const 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) {
    121104            const RootObject* aRootObject = it->first;
    122105           
     
    129112}
    130113
    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)
     114void addNativeReference(const RootObject* rootObject, JSObject* jsObject)
     115{
     116    if (!rootObject)
    148117        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     }
     118   
     119    ProtectCountSet* protectCountSet = getProtectCountSet(rootObject);
     120    if (!protectCountSet->contains(jsObject)) {
     121        JSLock lock;
     122        gcProtect(jsObject);
     123    }
     124    protectCountSet->add(jsObject);
     125}
     126
     127void 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);
    160138}
    161139
     
    287265void RootObject::destroy()
    288266{
    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) {
     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) {
    294272            JSLock lock;
    295273            gcUnprotect(it->first);           
    296274        }
    297         referencesSet->clear();
    298         ReferencesByRootMap* refsByRoot = getReferencesByRootMap();
    299         refsByRoot->remove(this);
    300         delete referencesSet;
     275
     276        destroyProtectCountSet(this, protectCountSet);
    301277    }
    302278
Note: See TracChangeset for help on using the changeset viewer.