Ignore:
Timestamp:
Aug 22, 2006, 2:05:47 PM (19 years ago)
Author:
andersca
Message:

2006-08-22 Anders Carlsson <[email protected]>

Reviewed by Darin.

Move the npruntime code over to using HashMap and the runtime_root code over to using
HashMap and HashCountedSet.


  • bindings/NP_jsobject.cpp:
  • bindings/c/c_utility.cpp: (KJS::Bindings::identifierFromNPIdentifier):
  • bindings/c/c_utility.h:
  • bindings/jni/jni_jsobject.cpp: (JavaJSObject::invoke):
  • bindings/npruntime.cpp: (getStringIdentifierMap): (getIntIdentifierMap): (_NPN_GetStringIdentifier): (_NPN_GetIntIdentifier):
  • bindings/runtime_root.cpp: (getReferencesByRootMap): (getReferencesSet): (KJS::Bindings::findReferenceSet): (KJS::Bindings::rootForImp): (KJS::Bindings::rootForInterpreter): (KJS::Bindings::addNativeReference): (KJS::Bindings::removeNativeReference): (RootObject::removeAllNativeReferences):
  • bindings/runtime_root.h:
File:
1 edited

Legend:

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

    r14834 r15972  
    2727#include "object.h"
    2828#include "runtime_root.h"
     29#include <wtf/HashCountedSet.h>
    2930
    3031using namespace KJS;
     
    3940// shutdown.
    4041//
    41 // To do this we keep a dictionary that maps each applet instance
     42// To do this we keep a map that maps each applet instance
    4243// to the JavaScript objects it is referencing.  For each JavaScript instance
    4344// we also maintain a secondary reference count.  When that reference count reaches
     
    4546// are represented by a jlong.
    4647
    47 static CFMutableDictionaryRef referencesByRootDictionary = 0;
    48 
    49 static CFMutableDictionaryRef getReferencesByRootDictionary()
    50 {
    51     if (!referencesByRootDictionary)
    52         referencesByRootDictionary = CFDictionaryCreateMutable(NULL, 0, NULL, &kCFTypeDictionaryValueCallBacks);
    53     return referencesByRootDictionary;
    54 }
    55 
    56 static CFMutableDictionaryRef getReferencesDictionary(const Bindings::RootObject *root)
    57 {
    58     CFMutableDictionaryRef refsByRoot = getReferencesByRootDictionary();
    59     CFMutableDictionaryRef referencesDictionary = 0;
    60    
    61     referencesDictionary = (CFMutableDictionaryRef)CFDictionaryGetValue (refsByRoot, (const void *)root);
    62     if (!referencesDictionary) {
    63         referencesDictionary = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
    64         CFDictionaryAddValue (refsByRoot, root, referencesDictionary);
    65         CFRelease (referencesDictionary);
    66     }
    67     return referencesDictionary;
     48typedef HashMap<const Bindings::RootObject*, ReferencesSet*> ReferencesByRootMap;
     49
     50static ReferencesByRootMap* getReferencesByRootMap()
     51{
     52    static ReferencesByRootMap* referencesByRootMap = 0;
     53   
     54    if (!referencesByRootMap)
     55        referencesByRootMap = new ReferencesByRootMap;
     56   
     57    return referencesByRootMap;
     58}
     59
     60static ReferencesSet* getReferencesSet(const Bindings::RootObject *root)
     61{
     62    ReferencesByRootMap* refsByRoot = getReferencesByRootMap();
     63    ReferencesSet* referencesSet = 0;
     64   
     65    referencesSet = refsByRoot->get(root);
     66    if (!referencesSet) {
     67        referencesSet  = new ReferencesSet;
     68        refsByRoot->add(root, referencesSet);
     69    }
     70    return referencesSet;
    6871}
    6972
     
    7376// FIXME:  This is a potential performance bottleneck with many applets.  We could fix be adding a
    7477// imp to root dictionary.
    75 CFMutableDictionaryRef KJS::Bindings::findReferenceDictionary(JSObject *imp)
    76 {
    77     CFMutableDictionaryRef refsByRoot = getReferencesByRootDictionary ();
    78     CFMutableDictionaryRef foundDictionary = 0;
    79    
     78ReferencesSet* KJS::Bindings::findReferenceSet(JSObject *imp)
     79{
     80    ReferencesByRootMap* refsByRoot = getReferencesByRootMap ();
    8081    if (refsByRoot) {
    81         const void **allValues = 0;
    82         CFIndex count, i;
    83        
    84         count = CFDictionaryGetCount(refsByRoot);
    85         allValues = (const void **)malloc (sizeof(void *) * count);
    86         CFDictionaryGetKeysAndValues (refsByRoot, NULL, allValues);
    87         for(i = 0; i < count; i++) {
    88             CFMutableDictionaryRef referencesDictionary = (CFMutableDictionaryRef)allValues[i];
    89             if (CFDictionaryGetValue(referencesDictionary, imp) != 0) {
    90                 foundDictionary = referencesDictionary;
    91                 break;
    92             }
    93         }
    94        
    95         free ((void *)allValues);
    96     }
    97     return foundDictionary;
     82        ReferencesByRootMap::const_iterator end = refsByRoot->end();
     83        for (ReferencesByRootMap::const_iterator it = refsByRoot->begin(); it != end; ++it) {
     84            ReferencesSet* set = it->second;
     85           
     86            if (set->contains(imp))
     87                return set;
     88        }
     89    }
     90   
     91    return 0;
    9892}
    9993
     
    10296const Bindings::RootObject *KJS::Bindings::rootForImp (JSObject *imp)
    10397{
    104     CFMutableDictionaryRef refsByRoot = getReferencesByRootDictionary ();
     98    ReferencesByRootMap* refsByRoot = getReferencesByRootMap ();
    10599    const Bindings::RootObject *rootObject = 0;
    106100   
    107101    if (refsByRoot) {
    108         const void **allValues = 0;
    109         const void **allKeys = 0;
    110         CFIndex count, i;
    111        
    112         count = CFDictionaryGetCount(refsByRoot);
    113         allKeys = (const void **)malloc (sizeof(void *) * count);
    114         allValues = (const void **)malloc (sizeof(void *) * count);
    115         CFDictionaryGetKeysAndValues (refsByRoot, allKeys, allValues);
    116         for(i = 0; i < count; i++) {
    117             CFMutableDictionaryRef referencesDictionary = (CFMutableDictionaryRef)allValues[i];
    118             if (CFDictionaryGetValue(referencesDictionary, imp) != 0) {
    119                 rootObject = (const Bindings::RootObject *)allKeys[i];
     102        ReferencesByRootMap::const_iterator end = refsByRoot->end();
     103        for (ReferencesByRootMap::const_iterator it = refsByRoot->begin(); it != end; ++it) {
     104            ReferencesSet* set = it->second;
     105            if (set->contains(imp)) {
     106                rootObject = it->first;
    120107                break;
    121108            }
    122109        }
     110    }
     111   
     112    return rootObject;
     113}
     114
     115const Bindings::RootObject *KJS::Bindings::rootForInterpreter (KJS::Interpreter *interpreter)
     116{
     117    ReferencesByRootMap* refsByRoot = getReferencesByRootMap ();
     118   
     119    if (refsByRoot) {
     120        ReferencesByRootMap::const_iterator end = refsByRoot->end();
     121        for (ReferencesByRootMap::const_iterator it = refsByRoot->begin(); it != end; ++it) {
     122            const Bindings::RootObject* aRootObject = it->first;
     123           
     124            if (aRootObject->interpreter() == interpreter)
     125                return aRootObject;
     126        }
     127    }
     128   
     129    return 0;
     130}
     131
     132void KJS::Bindings::addNativeReference (const Bindings::RootObject *root, JSObject *imp)
     133{
     134    if (root) {
     135        ReferencesSet* referenceMap = getReferencesSet (root);
    123136       
    124         free ((void *)allKeys);
    125         free ((void *)allValues);
    126     }
    127     return rootObject;
    128 }
    129 
    130 const Bindings::RootObject *KJS::Bindings::rootForInterpreter (KJS::Interpreter *interpreter)
    131 {
    132     CFMutableDictionaryRef refsByRoot = getReferencesByRootDictionary ();
    133     const Bindings::RootObject *aRootObject = 0, *result = 0;
    134    
    135     if (refsByRoot) {
    136         const void **allValues = 0;
    137         const void **allKeys = 0;
    138         CFIndex count, i;
    139        
    140         count = CFDictionaryGetCount(refsByRoot);
    141         allKeys = (const void **)malloc (sizeof(void *) * count);
    142         allValues = (const void **)malloc (sizeof(void *) * count);
    143         CFDictionaryGetKeysAndValues (refsByRoot, allKeys, allValues);
    144         for(i = 0; i < count; i++) {
    145             aRootObject = (const Bindings::RootObject *)allKeys[i];
    146             if (aRootObject->interpreter() == interpreter) {
    147                 result = aRootObject;
    148                 break;
    149             }
    150         }
    151        
    152         free ((void *)allKeys);
    153         free ((void *)allValues);
    154     }
    155     return result;
    156 }
    157 
    158 void KJS::Bindings::addNativeReference (const Bindings::RootObject *root, JSObject *imp)
    159 {
    160     if (root) {
    161         CFMutableDictionaryRef referencesDictionary = getReferencesDictionary (root);
    162        
    163         unsigned long numReferences = (unsigned long)CFDictionaryGetValue (referencesDictionary, imp);
     137        unsigned numReferences = referenceMap->count(imp);
    164138        if (numReferences == 0) {
    165139            JSLock lock;
    166140            gcProtect(imp);
    167             CFDictionaryAddValue (referencesDictionary, imp,  (const void *)1);
    168         }
    169         else {
    170             CFDictionaryReplaceValue (referencesDictionary, imp, (const void *)(numReferences+1));
    171         }
     141        }
     142        referenceMap->add(imp);
    172143    }
    173144}
     
    178149        return;
    179150
    180     CFMutableDictionaryRef referencesDictionary = findReferenceDictionary (imp);
    181 
    182     if (referencesDictionary) {
    183         unsigned long numReferences = (unsigned long)CFDictionaryGetValue (referencesDictionary, imp);
     151    ReferencesSet *referencesSet = findReferenceSet(imp);
     152    if (referencesSet) {
     153        unsigned numReferences = referencesSet->count(imp);
     154       
    184155        if (numReferences == 1) {
    185156            JSLock lock;
    186157            gcUnprotect(imp);
    187             CFDictionaryRemoveValue (referencesDictionary, imp);
    188         }
    189         else {
    190             CFDictionaryReplaceValue (referencesDictionary, imp, (const void *)(numReferences-1));
    191         }
     158        }
     159        referencesSet->remove(imp);
    192160    }
    193161}
     
    318286void RootObject::removeAllNativeReferences ()
    319287{
    320     CFMutableDictionaryRef referencesDictionary = getReferencesDictionary (this);
    321    
    322     if (referencesDictionary) {
    323         void **allImps = 0;
    324         CFIndex count, i;
    325        
    326         count = CFDictionaryGetCount(referencesDictionary);
    327         allImps = (void **)malloc (sizeof(void *) * count);
    328         CFDictionaryGetKeysAndValues (referencesDictionary, (const void **)allImps, NULL);
    329         for(i = 0; i < count; i++) {
     288    ReferencesSet* referencesSet = getReferencesSet (this);
     289   
     290    if (referencesSet) {
     291        ReferencesSet::iterator end = referencesSet->end();
     292        for (ReferencesSet::iterator it = referencesSet->begin(); it != end; ++it) {
    330293            JSLock lock;
    331             JSObject *anImp = static_cast<JSObject*>(allImps[i]);
    332             gcUnprotect(anImp);
    333         }
    334         free ((void *)allImps);
    335         CFDictionaryRemoveAllValues (referencesDictionary);
    336 
    337         CFMutableDictionaryRef refsByRoot = getReferencesByRootDictionary();
    338         CFDictionaryRemoveValue (refsByRoot, (const void *)this);
     294            gcUnprotect(it->first);           
     295        }
     296        referencesSet->clear();
     297        ReferencesByRootMap* refsByRoot = getReferencesByRootMap();
     298        refsByRoot->remove(this);
     299        delete referencesSet;
    339300        delete this;
    340301    }
Note: See TracChangeset for help on using the changeset viewer.