Changeset 15972 in webkit for trunk/JavaScriptCore/bindings/runtime_root.cpp
- Timestamp:
- Aug 22, 2006, 2:05:47 PM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/bindings/runtime_root.cpp
r14834 r15972 27 27 #include "object.h" 28 28 #include "runtime_root.h" 29 #include <wtf/HashCountedSet.h> 29 30 30 31 using namespace KJS; … … 39 40 // shutdown. 40 41 // 41 // To do this we keep a dictionarythat maps each applet instance42 // To do this we keep a map that maps each applet instance 42 43 // to the JavaScript objects it is referencing. For each JavaScript instance 43 44 // we also maintain a secondary reference count. When that reference count reaches … … 45 46 // are represented by a jlong. 46 47 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; 48 typedef HashMap<const Bindings::RootObject*, ReferencesSet*> ReferencesByRootMap; 49 50 static ReferencesByRootMap* getReferencesByRootMap() 51 { 52 static ReferencesByRootMap* referencesByRootMap = 0; 53 54 if (!referencesByRootMap) 55 referencesByRootMap = new ReferencesByRootMap; 56 57 return referencesByRootMap; 58 } 59 60 static 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; 68 71 } 69 72 … … 73 76 // FIXME: This is a potential performance bottleneck with many applets. We could fix be adding a 74 77 // imp to root dictionary. 75 CFMutableDictionaryRef KJS::Bindings::findReferenceDictionary(JSObject *imp) 76 { 77 CFMutableDictionaryRef refsByRoot = getReferencesByRootDictionary (); 78 CFMutableDictionaryRef foundDictionary = 0; 79 78 ReferencesSet* KJS::Bindings::findReferenceSet(JSObject *imp) 79 { 80 ReferencesByRootMap* refsByRoot = getReferencesByRootMap (); 80 81 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; 98 92 } 99 93 … … 102 96 const Bindings::RootObject *KJS::Bindings::rootForImp (JSObject *imp) 103 97 { 104 CFMutableDictionaryRef refsByRoot = getReferencesByRootDictionary();98 ReferencesByRootMap* refsByRoot = getReferencesByRootMap (); 105 99 const Bindings::RootObject *rootObject = 0; 106 100 107 101 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; 120 107 break; 121 108 } 122 109 } 110 } 111 112 return rootObject; 113 } 114 115 const 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 132 void KJS::Bindings::addNativeReference (const Bindings::RootObject *root, JSObject *imp) 133 { 134 if (root) { 135 ReferencesSet* referenceMap = getReferencesSet (root); 123 136 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); 164 138 if (numReferences == 0) { 165 139 JSLock lock; 166 140 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); 172 143 } 173 144 } … … 178 149 return; 179 150 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 184 155 if (numReferences == 1) { 185 156 JSLock lock; 186 157 gcUnprotect(imp); 187 CFDictionaryRemoveValue (referencesDictionary, imp); 188 } 189 else { 190 CFDictionaryReplaceValue (referencesDictionary, imp, (const void *)(numReferences-1)); 191 } 158 } 159 referencesSet->remove(imp); 192 160 } 193 161 } … … 318 286 void RootObject::removeAllNativeReferences () 319 287 { 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) { 330 293 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; 339 300 delete this; 340 301 }
Note:
See TracChangeset
for help on using the changeset viewer.