Changeset 18811 in webkit for trunk/JavaScriptCore/bindings/runtime_root.cpp
- Timestamp:
- Jan 12, 2007, 1:11:22 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/bindings/runtime_root.cpp
r18795 r18811 45 45 // are represented by a jlong. 46 46 47 typedef HashMap<const RootObject*, ReferencesSet*> ReferencesByRootMap;48 49 static R eferencesByRootMap* getReferencesByRootMap()50 { 51 static R eferencesByRootMap* 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 a73 // reference to the imp, and if so, return it's reference count74 // 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 }47 typedef HashMap<const RootObject*, ProtectCountSet*> RootObjectMap; 48 49 static RootObjectMap* rootObjectMap() 50 { 51 static RootObjectMap staticRootObjectMap; 52 return &staticRootObjectMap; 53 } 54 55 static 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 66 static 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 75 ProtectCountSet* findProtectCountSet(JSObject* jsObject) 76 { 77 const RootObject* rootObject = findRootObject(jsObject); 78 return rootObject ? getProtectCountSet(rootObject) : 0; 79 } 80 81 const 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; 88 88 } 89 89 … … 91 91 } 92 92 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 } 93 const 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; 126 101 } 127 102 … … 129 104 } 130 105 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) 106 void addNativeReference(const RootObject* rootObject, JSObject* jsObject) 107 { 108 if (!rootObject) 148 109 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 119 void 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); 160 134 } 161 135 … … 287 261 void RootObject::destroy() 288 262 { 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) { 294 268 JSLock lock; 295 269 gcUnprotect(it->first); 296 270 } 297 referencesSet->clear(); 298 ReferencesByRootMap* refsByRoot = getReferencesByRootMap(); 299 refsByRoot->remove(this); 300 delete referencesSet; 271 272 destroyProtectCountSet(this, protectCountSet); 301 273 } 302 274
Note:
See TracChangeset
for help on using the changeset viewer.