Changeset 18795 in webkit for trunk/JavaScriptCore/bindings/runtime_root.cpp
- Timestamp:
- Jan 11, 2007, 10:25:15 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/bindings/runtime_root.cpp
r18786 r18795 45 45 // are represented by a jlong. 46 46 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; 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 } 92 88 } 93 89 … … 95 91 } 96 92 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. 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) { 104 121 const RootObject* aRootObject = it->first; 105 122 … … 112 129 } 113 130 114 void addNativeReference(const RootObject* rootObject, JSObject* jsObject) 115 { 116 if (!rootObject) 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) 117 148 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 } 138 160 } 139 161 … … 265 287 void RootObject::destroy() 266 288 { 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) { 272 294 JSLock lock; 273 295 gcUnprotect(it->first); 274 296 } 275 276 destroyProtectCountSet(this, protectCountSet); 297 referencesSet->clear(); 298 ReferencesByRootMap* refsByRoot = getReferencesByRootMap(); 299 refsByRoot->remove(this); 300 delete referencesSet; 277 301 } 278 302
Note:
See TracChangeset
for help on using the changeset viewer.