Changeset 4188 in webkit for trunk/JavaScriptCore/kjs
- Timestamp:
- Apr 25, 2003, 2:51:12 PM (22 years ago)
- Location:
- trunk/JavaScriptCore/kjs
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/property_map.cpp
r3373 r4188 42 42 static int numProbes; 43 43 static int numCollisions; 44 static int numRehashes; 45 static int numRemoves; 44 46 45 47 struct PropertyMapStatisticsExitLogger { ~PropertyMapStatisticsExitLogger(); }; … … 52 54 printf("%d probes\n", numProbes); 53 55 printf("%d collisions (%.1f%%)\n", numCollisions, 100.0 * numCollisions / numProbes); 56 printf("%d rehashes\n", numRehashes); 57 printf("%d removes\n", numRemoves); 54 58 } 55 59 … … 98 102 UString::Rep *key = _table->entries[i].key; 99 103 if (key) 100 104 key->deref(); 101 105 } 102 106 free(_table); … … 126 130 } 127 131 128 inline int PropertyMap::hash(const UString::Rep *s) const129 {130 return s->hash() & _table->sizeMask;131 }132 133 132 ValueImp *PropertyMap::get(const Identifier &name, int &attributes) const 134 133 { 134 assert(!name.isNull()); 135 135 136 UString::Rep *rep = name._ustring.rep; 136 137 … … 146 147 } 147 148 148 int i = hash(rep); 149 unsigned h = rep->hash(); 150 int i = h & _table->sizeMask; 151 int k = 0; 149 152 #if DUMP_STATISTICS 150 153 ++numProbes; … … 156 159 return _table->entries[i].value; 157 160 } 158 i = (i + 1) & _table->sizeMask; 161 if (k == 0) 162 k = 1 | (h % _table->sizeMask); 163 i = (i + k) & _table->sizeMask; 164 #if DUMP_STATISTICS 165 ++numRehashes; 166 #endif 159 167 } 160 168 return 0; … … 163 171 ValueImp *PropertyMap::get(const Identifier &name) const 164 172 { 173 assert(!name.isNull()); 174 165 175 UString::Rep *rep = name._ustring.rep; 166 176 … … 174 184 } 175 185 176 int i = hash(rep); 186 unsigned h = rep->hash(); 187 int i = h & _table->sizeMask; 188 int k = 0; 177 189 #if DUMP_STATISTICS 178 190 ++numProbes; … … 182 194 if (rep == key) 183 195 return _table->entries[i].value; 184 i = (i + 1) & _table->sizeMask; 196 if (k == 0) 197 k = 1 | (h % _table->sizeMask); 198 i = (i + k) & _table->sizeMask; 199 #if DUMP_STATISTICS 200 ++numRehashes; 201 #endif 185 202 } 186 203 return 0; … … 191 208 { 192 209 if (attributes == 0) 193 printf ("None "); 194 if (attributes & ReadOnly) 195 printf ("ReadOnly "); 196 if (attributes & DontEnum) 197 printf ("DontEnum "); 198 if (attributes & DontDelete) 199 printf ("DontDelete "); 200 if (attributes & Internal) 201 printf ("Internal "); 202 if (attributes & Function) 203 printf ("Function "); 210 printf("None"); 211 else { 212 if (attributes & ReadOnly) 213 printf("ReadOnly "); 214 if (attributes & DontEnum) 215 printf("DontEnum "); 216 if (attributes & DontDelete) 217 printf("DontDelete "); 218 if (attributes & Internal) 219 printf("Internal "); 220 if (attributes & Function) 221 printf("Function "); 222 } 204 223 } 205 224 #endif … … 207 226 void PropertyMap::put(const Identifier &name, ValueImp *value, int attributes) 208 227 { 228 assert(!name.isNull()); 229 assert(value != 0); 230 209 231 checkConsistency(); 210 232 … … 212 234 213 235 #if DEBUG_PROPERTIES 214 printf 236 printf("adding property %s, attributes = 0x%08x (", name.ascii(), attributes); 215 237 printAttributes(attributes); 216 printf 238 printf(")\n"); 217 239 #endif 218 240 … … 239 261 expand(); 240 262 241 int i = hash(rep); 263 unsigned h = rep->hash(); 264 int i = h & _table->sizeMask; 265 int k = 0; 242 266 #if DUMP_STATISTICS 243 267 ++numProbes; … … 251 275 return; 252 276 } 253 i = (i + 1) & _table->sizeMask; 277 // If we find the deleted-element sentinel, insert on top of it. 278 if (key == &UString::Rep::null) { 279 key->deref(); 280 break; 281 } 282 if (k == 0) 283 k = 1 | (h % _table->sizeMask); 284 i = (i + k) & _table->sizeMask; 285 #if DUMP_STATISTICS 286 ++numRehashes; 287 #endif 254 288 } 255 289 … … 264 298 } 265 299 266 inlinevoid PropertyMap::insert(UString::Rep *key, ValueImp *value, int attributes)300 void PropertyMap::insert(UString::Rep *key, ValueImp *value, int attributes) 267 301 { 268 302 assert(_table); 269 303 270 int i = hash(key); 304 unsigned h = key->hash(); 305 int i = h & _table->sizeMask; 306 int k = 0; 271 307 #if DUMP_STATISTICS 272 308 ++numProbes; 273 309 numCollisions += _table->entries[i].key && _table->entries[i].key != key; 274 310 #endif 275 while (_table->entries[i].key) 276 i = (i + 1) & _table->sizeMask; 311 while (_table->entries[i].key) { 312 assert(_table->entries[i].key != &UString::Rep::null); 313 if (k == 0) 314 k = 1 | (h % _table->sizeMask); 315 i = (i + k) & _table->sizeMask; 316 #if DUMP_STATISTICS 317 ++numRehashes; 318 #endif 319 } 277 320 278 321 _table->entries[i].key = key; … … 303 346 for (int i = 0; i != oldTableSize; ++i) { 304 347 UString::Rep *key = oldTable->entries[i].key; 305 if (key) 306 insert(key, oldTable->entries[i].value, oldTable->entries[i].attributes); 348 if (key) { 349 // Don't copy deleted-element sentinels. 350 if (key == &UString::Rep::null) 351 key->deref(); 352 else 353 insert(key, oldTable->entries[i].value, oldTable->entries[i].attributes); 354 } 307 355 } 308 356 … … 314 362 void PropertyMap::remove(const Identifier &name) 315 363 { 364 assert(!name.isNull()); 365 316 366 checkConsistency(); 317 367 … … 333 383 334 384 // Find the thing to remove. 335 int i = hash(rep); 385 unsigned h = rep->hash(); 386 int i = h & _table->sizeMask; 387 int k = 0; 336 388 #if DUMP_STATISTICS 337 389 ++numProbes; 390 ++numRemoves; 338 391 numCollisions += _table->entries[i].key && _table->entries[i].key != rep; 339 392 #endif … … 341 394 if (rep == key) 342 395 break; 343 i = (i + 1) & _table->sizeMask; 396 if (k == 0) 397 k = 1 | (h % _table->sizeMask); 398 i = (i + k) & _table->sizeMask; 399 #if DUMP_STATISTICS 400 ++numRehashes; 401 #endif 344 402 } 345 403 if (!key) 346 404 return; 347 405 348 // Remove the one key. 406 // Replace this one element with the deleted sentinel, 407 // &UString::Rep::null; also set value to 0 and attributes to DontEnum 408 // to help callers that iterate all keys not have to check for the sentinel. 349 409 key->deref(); 350 _table->entries[i].key = 0; 410 key = &UString::Rep::null; 411 key->ref(); 412 _table->entries[i].key = key; 413 _table->entries[i].value = 0; 414 _table->entries[i].attributes = DontEnum; 351 415 assert(_table->keyCount >= 1); 352 416 --_table->keyCount; 353 417 354 // Reinsert all the items to the right in the same cluster.355 while (1) {356 i = (i + 1) & _table->sizeMask;357 key = _table->entries[i].key;358 if (!key)359 break;360 _table->entries[i].key = 0;361 insert(key, _table->entries[i].value, _table->entries[i].attributes);362 }363 364 418 checkConsistency(); 365 419 } … … 379 433 380 434 for (int i = 0; i != _table->size; ++i) { 381 if (_table->entries[i].key) { 435 UString::Rep *key = _table->entries[i].key; 436 if (key) { 382 437 ValueImp *v = _table->entries[i].value; 383 if (!v->marked()) 438 // Check v against 0 to handle deleted elements 439 // without comparing key to UString::Rep::null. 440 if (v && !v->marked()) 384 441 v->mark(); 385 442 } … … 423 480 for (int i = 0; i != _table->size; ++i) { 424 481 UString::Rep *key = _table->entries[i].key; 425 if (key) { 482 if (key && key != &UString::Rep::null) 483 { 426 484 UString k(key); 427 485 bool fitsInUInt32; … … 500 558 if (!rep) 501 559 continue; 502 int i = hash(rep); 560 unsigned h = rep->hash(); 561 int i = h & _table->sizeMask; 503 562 while (UString::Rep *key = _table->entries[i].key) { 504 563 if (rep == key) -
trunk/JavaScriptCore/kjs/property_map.h
r3373 r4188 78 78 79 79 private: 80 int hash(const UString::Rep *) const;81 80 static bool keysMatch(const UString::Rep *, const UString::Rep *); 82 81 void expand(); -
trunk/JavaScriptCore/kjs/ustring.h
r3373 r4188 214 214 int size() const { return len; } 215 215 216 inthash() const { if (_hash == 0) _hash = computeHash(dat, len); return _hash; }216 unsigned hash() const { if (_hash == 0) _hash = computeHash(dat, len); return _hash; } 217 217 static unsigned computeHash(const UChar *, int length); 218 218 static unsigned computeHash(const char *); … … 225 225 int capacity; 226 226 int rc; 227 mutable int_hash;227 mutable unsigned _hash; 228 228 229 229 enum { capacityForIdentifier = 0x10000000 };
Note:
See TracChangeset
for help on using the changeset viewer.