Changeset 11920 in webkit for trunk/JavaScriptCore
- Timestamp:
- Jan 6, 2006, 3:51:00 PM (19 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r11908 r11920 1 2006-01-06 Maciej Stachowiak <[email protected]> 2 3 Reviewed by Darin. 4 5 - miscellaneous changes for 4% speedup on the JavaScript iBench 6 http://bugzilla.opendarwin.org/show_bug.cgi?id=6396 7 8 Changes mostly thanks to Maks Orlovich, tweaked a little by me. 9 10 * kjs/create_hash_table: Use the same hash as the one used buy Identifier. 11 * kjs/function.cpp: 12 (KJS::FunctionImp::processParameters): Use the new List::copyFrom 13 (KJS::ActivationImp::ActivationImp): track variable while iterating 14 * kjs/internal.cpp: 15 (KJS::StringImp::toObject): create StringInstance directly 16 * kjs/list.cpp: 17 (KJS::List::copy): implement in terms of copyFrom 18 (KJS::List::copyFrom): more efficient way to copy in another list 19 * kjs/list.h: 20 * kjs/lookup.cpp: 21 (keysMatch): updated to work with identifier hash 22 (findEntry): ditto 23 (Lookup::findEntry): ditto 24 (Lookup::find): ditto 25 * kjs/lookup.h: 26 1 27 2006-01-06 Maciej Stachowiak <[email protected]> 2 28 -
trunk/JavaScriptCore/kjs/create_hash_table
r10818 r11920 26 26 @attrs = (); 27 27 @params = (); 28 @hashes = (); 28 29 29 30 my $inside = 0; … … 64 65 @attrs = (); 65 66 @params = (); 67 @hashes = (); 66 68 $inside = 0; 67 69 } elsif (/^(\S+)\s*(\S+)\s*([\w\|]*)\s*(\w*)\s*$/ && $inside) { … … 72 74 push(@keys, $key); 73 75 push(@values, $val); 76 push(@hashes, hashValue($key)); 74 77 printf STDERR "WARNING: Number of arguments missing for $key/$val\n" 75 78 if ( $att =~ m/Function/ && length($param) == 0); … … 132 135 } 133 136 137 # Paul Hsieh's SuperFastHash 138 # http://www.azillionmonkeys.com/qed/hash.html 139 # Ported from UString.. 134 140 sub hashValue($) { 135 141 @chars = split(/ */, $_[0]); 136 my $val = 0; 137 foreach $c (@chars) { 138 $val += ord($c); 139 } 140 return $val; 142 143 # This hash is designed to work on 16-bit chunks at a time. But since the normal case 144 # (above) is to hash UTF-16 characters, we just treat the 8-bit chars as if they 145 # were 16-bit chunks, which should give matching results 146 147 my $EXP2_32 = 4294967296; 148 149 my $hash = 0x9e3779b9; 150 my $l = scalar @chars; #I wish this was in Ruby --- Maks 151 my $rem = $l & 1; 152 $l = $l >> 1; 153 154 my $s = 0; 155 156 # Main loop 157 for (; $l > 0; $l--) { 158 $hash += ord($chars[$s]); 159 my $tmp = (ord($chars[$s+1]) << 11) ^ $hash; 160 $hash = (($hash << 16)% $EXP2_32) ^ $tmp; 161 $s += 2; 162 $hash += $hash >> 11; 163 } 164 165 # Handle end case 166 if ($rem !=0) { 167 $hash += ord($chars[$s]); 168 $hash ^= (($hash << 11)% $EXP2_32); 169 $hash += $hash >> 17; 170 } 171 172 # Force "avalanching" of final 127 bits 173 $hash ^= ($hash << 3); 174 $hash += ($hash >> 5); 175 $hash = ($hash% $EXP2_32); 176 $hash ^= (($hash << 2)% $EXP2_32); 177 $hash += ($hash >> 15); 178 $hash = $hash% $EXP2_32; 179 $hash ^= (($hash << 10)% $EXP2_32); 180 181 # this avoids ever returning a hash code of 0, since that is used to 182 # signal "hash not computed yet", using a value that is likely to be 183 # effectively the same as 0 when the low bits are masked 184 $hash = 0x80000000 if ($hash == 0); 185 186 return $hash; 141 187 } 142 188 … … 173 219 print "0 \}" 174 220 } 221 print "/* " . $hashes[$entry] . " */ "; 175 222 } else { 176 223 print " \{ 0, 0, 0, 0, 0 \}"; -
trunk/JavaScriptCore/kjs/function.cpp
r11910 r11920 182 182 ListIterator it = args.begin(); 183 183 Parameter *p = param; 184 JSValue *v = *it; 184 185 while (p) { 185 186 if (it != args.end()) { … … 188 189 printInfo(exec,"to", *it); 189 190 #endif 190 variable->put(exec, p->name, *it);191 it++;191 variable->put(exec, p->name, v); 192 v = ++it; 192 193 } else 193 194 variable->put(exec, p->name, jsUndefined()); … … 486 487 : _function(function), _arguments(true), _argumentsObject(0) 487 488 { 488 _arguments = arguments.copy();489 _arguments.copyFrom(arguments); 489 490 // FIXME: Do we need to support enumerating the arguments property? 490 491 } -
trunk/JavaScriptCore/kjs/internal.cpp
r11919 r11920 183 183 JSObject *StringImp::toObject(ExecState *exec) const 184 184 { 185 List args; 186 args.append(const_cast<StringImp*>(this)); 187 return static_cast<JSObject *>(exec->lexicalInterpreter()->builtinString()->construct(exec, args)); 185 return new StringInstance(exec->lexicalInterpreter()->builtinStringPrototype(), val); 188 186 } 189 187 -
trunk/JavaScriptCore/kjs/list.cpp
r11527 r11920 289 289 { 290 290 List copy; 291 292 ListImp *imp = static_cast<ListImp *>(_impBase); 291 copy.copyFrom(*this); 292 return copy; 293 } 294 295 void List::copyFrom(const List& other) 296 { 297 ListImp *imp = static_cast<ListImp *>(other._impBase); 293 298 294 299 int size = imp->size; … … 296 301 int inlineSize = min(size, inlineValuesSize); 297 302 for (int i = 0; i != inlineSize; ++i) 298 copy.append(imp->values[i]);303 append(imp->values[i]); 299 304 300 305 JSValue **overflow = imp->overflow; 301 306 int overflowSize = size - inlineSize; 302 307 for (int i = 0; i != overflowSize; ++i) 303 copy.append(overflow[i]); 304 305 return copy; 308 append(overflow[i]); 306 309 } 307 310 -
trunk/JavaScriptCore/kjs/list.h
r11527 r11920 73 73 */ 74 74 List copy() const; 75 76 /** 77 * Copy all elements from the second list here 78 */ 79 void copyFrom(const List& other); 75 80 76 81 /** -
trunk/JavaScriptCore/kjs/lookup.cpp
r10701 r11920 34 34 static inline bool keysMatch(const UChar *c, unsigned len, const char *s) 35 35 { 36 for (unsigned i = 0; i != len; i++, c++, s++) 36 const char* end = s + len; 37 for (; s != end; c++, s++) 37 38 if (c->uc != (unsigned char)*s) 38 39 return false; … … 40 41 } 41 42 42 const HashEntry* Lookup::findEntry( const struct HashTable *table,43 const UChar *c, unsigned int len )43 static inline const HashEntry* findEntry(const struct HashTable *table, unsigned int hash, 44 const UChar *c, unsigned int len ) 44 45 { 45 46 #ifndef NDEBUG … … 49 50 } 50 51 #endif 51 52 int h = hash(c, len) % table->hashSize; 53 const HashEntry *e = &table->entries[h]; 52 hash %= table->hashSize; 53 const HashEntry *e = &table->entries[hash]; 54 54 55 55 // empty bucket ? … … 61 61 if (keysMatch(c, len, e->s)) 62 62 return e; 63 63 64 // try next bucket 64 65 e = e->next; 65 66 } while (e); 66 67 67 return 0; 68 68 } 69 69 70 const HashEntry* Lookup::findEntry( 71 const Identifier &s )70 const HashEntry* Lookup::findEntry(const struct HashTable *table, 71 const Identifier &s ) 72 72 { 73 return findEntry( table, s.data(), s.size() ); 73 const HashEntry* entry = ::findEntry(table, s.ustring().rep()->hash(), s.data(), s.size()); 74 return entry; 74 75 } 75 76 … … 77 78 const UChar *c, unsigned int len) 78 79 { 79 const HashEntry *entry = findEntry( table, c, len);80 const HashEntry *entry = ::findEntry(table, UString::Rep::computeHash(c, len), c, len); 80 81 if (entry) 81 82 return entry->value; … … 85 86 int Lookup::find(const struct HashTable *table, const Identifier &s) 86 87 { 87 return find(table, s.data(), s.size()); 88 //printf("looking for:%s\n", s.ascii()); 89 const HashEntry *entry = ::findEntry(table, s.ustring().rep()->hash(), s.data(), s.size()); 90 if (entry) 91 return entry->value; 92 return -1; 88 93 } 89 90 unsigned int Lookup::hash(const UChar *c, unsigned int len)91 {92 unsigned int val = 0;93 // ignoring higher byte94 for (unsigned int i = 0; i < len; i++, c++)95 val += c->low();96 97 return val;98 }99 100 unsigned int Lookup::hash(const Identifier &key)101 {102 return hash(key.data(), key.size());103 }104 105 unsigned int Lookup::hash(const char *s)106 {107 unsigned int val = 0;108 while (*s)109 val += *s++;110 111 return val;112 } -
trunk/JavaScriptCore/kjs/lookup.h
r11731 r11920 39 39 */ 40 40 const char *s; 41 41 42 /** 42 43 * value is the result value (usually an enum value) … … 103 104 const UChar *c, unsigned int len); 104 105 106 105 107 /** 106 108 * Find an entry in the table, and return the entry … … 110 112 static const HashEntry* findEntry(const struct HashTable *table, 111 113 const Identifier &s); 112 static const HashEntry* findEntry(const struct HashTable *table, 113 const UChar *c, unsigned int len); 114 115 /** 116 * Calculate the hash value for a given key 117 */ 118 static unsigned int hash(const Identifier &key); 119 static unsigned int hash(const UChar *c, unsigned int len); 120 static unsigned int hash(const char *s); 114 121 115 }; 122 116
Note:
See TracChangeset
for help on using the changeset viewer.