Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 5832 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5843 return counter; | 5843 return counter; |
| 5844 } | 5844 } |
| 5845 | 5845 |
| 5846 | 5846 |
| 5847 int JSObject::GetEnumElementKeys(FixedArray* storage) { | 5847 int JSObject::GetEnumElementKeys(FixedArray* storage) { |
| 5848 return GetLocalElementKeys(storage, | 5848 return GetLocalElementKeys(storage, |
| 5849 static_cast<PropertyAttributes>(DONT_ENUM)); | 5849 static_cast<PropertyAttributes>(DONT_ENUM)); |
| 5850 } | 5850 } |
| 5851 | 5851 |
| 5852 | 5852 |
| 5853 // Thomas Wang, Integer Hash Functions. | |
| 5854 // http://www.concentric.net/~Ttwang/tech/inthash.htm | |
| 5855 static uint32_t ComputeIntegerHash(uint32_t key) { | |
| 5856 uint32_t hash = key; | |
| 5857 hash = ~hash + (hash << 15); // hash = (hash << 15) - hash - 1; | |
| 5858 hash = hash ^ (hash >> 12); | |
| 5859 hash = hash + (hash << 2); | |
| 5860 hash = hash ^ (hash >> 4); | |
| 5861 hash = hash * 2057; // hash = (hash + (hash << 3)) + (hash << 11); | |
| 5862 hash = hash ^ (hash >> 16); | |
| 5863 return hash; | |
| 5864 } | |
| 5865 | |
| 5866 | |
| 5853 // The NumberKey uses carries the uint32_t as key. | 5867 // The NumberKey uses carries the uint32_t as key. |
| 5854 // This avoids allocation in HasProperty. | 5868 // This avoids allocation in HasProperty. |
| 5855 class NumberKey : public HashTableKey { | 5869 class NumberKey : public HashTableKey { |
| 5856 public: | 5870 public: |
| 5857 explicit NumberKey(uint32_t number) : number_(number) { } | 5871 explicit NumberKey(uint32_t number) : number_(number) { } |
| 5858 | 5872 |
| 5859 private: | 5873 private: |
| 5860 bool IsMatch(Object* number) { | 5874 bool IsMatch(Object* number) { |
| 5861 return number_ == ToUint32(number); | 5875 return number_ == ToUint32(number); |
| 5862 } | 5876 } |
| 5863 | 5877 |
| 5864 // Thomas Wang, Integer Hash Functions. | 5878 uint32_t Hash() { return ComputeIntegerHash(number_); } |
| 5865 // http://www.concentric.net/~Ttwang/tech/inthash.htm | |
| 5866 static uint32_t ComputeHash(uint32_t key) { | |
| 5867 uint32_t hash = key; | |
| 5868 hash = ~hash + (hash << 15); // hash = (hash << 15) - hash - 1; | |
| 5869 hash = hash ^ (hash >> 12); | |
| 5870 hash = hash + (hash << 2); | |
| 5871 hash = hash ^ (hash >> 4); | |
| 5872 hash = hash * 2057; // hash = (hash + (hash << 3)) + (hash << 11); | |
| 5873 hash = hash ^ (hash >> 16); | |
| 5874 return hash; | |
| 5875 } | |
| 5876 | |
| 5877 uint32_t Hash() { return ComputeHash(number_); } | |
| 5878 | 5879 |
| 5879 HashFunction GetHashFunction() { return NumberHash; } | 5880 HashFunction GetHashFunction() { return NumberHash; } |
| 5880 | 5881 |
| 5881 Object* GetObject() { | 5882 Object* GetObject() { |
| 5882 return Heap::NumberFromDouble(number_); | 5883 return Heap::NumberFromDouble(number_); |
| 5883 } | 5884 } |
| 5884 | 5885 |
| 5885 static uint32_t NumberHash(Object* obj) { | 5886 static uint32_t NumberHash(Object* obj) { |
| 5886 return ComputeHash(ToUint32(obj)); | 5887 return ComputeIntegerHash(ToUint32(obj)); |
| 5887 } | 5888 } |
| 5888 | 5889 |
| 5889 static uint32_t ToUint32(Object* obj) { | 5890 static uint32_t ToUint32(Object* obj) { |
| 5890 ASSERT(obj->IsNumber()); | 5891 ASSERT(obj->IsNumber()); |
| 5891 return static_cast<uint32_t>(obj->Number()); | 5892 return static_cast<uint32_t>(obj->Number()); |
| 5892 } | 5893 } |
| 5893 | 5894 |
| 5894 bool IsStringKey() { return false; } | 5895 bool IsStringKey() { return false; } |
| 5895 | 5896 |
| 5896 uint32_t number_; | 5897 uint32_t number_; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 5914 | 5915 |
| 5915 static uint32_t StringHash(Object* obj) { | 5916 static uint32_t StringHash(Object* obj) { |
| 5916 return String::cast(obj)->Hash(); | 5917 return String::cast(obj)->Hash(); |
| 5917 } | 5918 } |
| 5918 | 5919 |
| 5919 bool IsStringKey() { return true; } | 5920 bool IsStringKey() { return true; } |
| 5920 | 5921 |
| 5921 String* string_; | 5922 String* string_; |
| 5922 }; | 5923 }; |
| 5923 | 5924 |
| 5925 | |
| 5926 // StringSharedKeys are used as keys in the eval cache. | |
| 5927 class StringSharedKey : public HashTableKey { | |
| 5928 public: | |
| 5929 StringSharedKey(String* source, SharedFunctionInfo* shared) | |
| 5930 : source_(source), shared_(shared) { } | |
| 5931 | |
| 5932 bool IsMatch(Object* other) { | |
| 5933 if (!other->IsFixedArray()) return false; | |
| 5934 FixedArray* pair = FixedArray::cast(other); | |
| 5935 SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0)); | |
| 5936 if (shared != shared_) return false; | |
| 5937 String* source = String::cast(pair->get(1)); | |
| 5938 return source->Equals(source_); | |
| 5939 } | |
| 5940 | |
| 5941 typedef uint32_t (*HashFunction)(Object* obj); | |
| 5942 | |
| 5943 virtual HashFunction GetHashFunction() { return StringSharedHash; } | |
| 5944 | |
| 5945 static uint32_t StringSharedHashHelper(String* source, | |
| 5946 SharedFunctionInfo* shared) { | |
| 5947 uint32_t hash = source->Hash(); | |
| 5948 if (shared->HasSourceCode()) { | |
| 5949 // Instead of using the SharedFunctionInfo pointer in the hash | |
| 5950 // code computation, we use a combination of the hash of the | |
| 5951 // script source code and the start and end positions. We do | |
| 5952 // this to ensure that the cache entries can survive garbage | |
| 5953 // collection. | |
| 5954 Script* script = Script::cast(shared->script()); | |
| 5955 hash ^= String::cast(script->source())->Hash(); | |
|
Kasper Lund
2009/02/24 11:21:08
It's not clear that this is a great way of mixing
| |
| 5956 hash ^= ((shared->start_position() << 16) | shared->end_position()); | |
| 5957 } | |
| 5958 return hash; | |
| 5959 } | |
| 5960 | |
| 5961 static uint32_t StringSharedHash(Object* obj) { | |
| 5962 FixedArray* pair = FixedArray::cast(obj); | |
| 5963 SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0)); | |
| 5964 String* source = String::cast(pair->get(1)); | |
| 5965 return StringSharedHashHelper(source, shared); | |
| 5966 } | |
| 5967 | |
| 5968 virtual uint32_t Hash() { | |
| 5969 return StringSharedHashHelper(source_, shared_); | |
| 5970 } | |
| 5971 | |
| 5972 virtual Object* GetObject() { | |
| 5973 Object* obj = Heap::AllocateFixedArray(2); | |
| 5974 if (obj->IsFailure()) return obj; | |
| 5975 FixedArray* pair = FixedArray::cast(obj); | |
| 5976 pair->set(0, shared_); | |
| 5977 pair->set(1, source_); | |
| 5978 return pair; | |
| 5979 } | |
| 5980 | |
| 5981 virtual bool IsStringKey() { return false; } | |
| 5982 | |
| 5983 private: | |
| 5984 String* source_; | |
| 5985 SharedFunctionInfo* shared_; | |
| 5986 }; | |
| 5987 | |
| 5988 | |
| 5924 // RegExpKey carries the source and flags of a regular expression as key. | 5989 // RegExpKey carries the source and flags of a regular expression as key. |
| 5925 class RegExpKey : public HashTableKey { | 5990 class RegExpKey : public HashTableKey { |
| 5926 public: | 5991 public: |
| 5927 RegExpKey(String* string, JSRegExp::Flags flags) | 5992 RegExpKey(String* string, JSRegExp::Flags flags) |
| 5928 : string_(string), | 5993 : string_(string), |
| 5929 flags_(Smi::FromInt(flags.value())) { } | 5994 flags_(Smi::FromInt(flags.value())) { } |
| 5930 | 5995 |
| 5931 bool IsMatch(Object* obj) { | 5996 bool IsMatch(Object* obj) { |
| 5932 FixedArray* val = FixedArray::cast(obj); | 5997 FixedArray* val = FixedArray::cast(obj); |
| 5933 return string_->Equals(String::cast(val->get(JSRegExp::kSourceIndex))) | 5998 return string_->Equals(String::cast(val->get(JSRegExp::kSourceIndex))) |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6227 | 6292 |
| 6228 | 6293 |
| 6229 Object* CompilationCacheTable::Lookup(String* src) { | 6294 Object* CompilationCacheTable::Lookup(String* src) { |
| 6230 StringKey key(src); | 6295 StringKey key(src); |
| 6231 int entry = FindEntry(&key); | 6296 int entry = FindEntry(&key); |
| 6232 if (entry == -1) return Heap::undefined_value(); | 6297 if (entry == -1) return Heap::undefined_value(); |
| 6233 return get(EntryToIndex(entry) + 1); | 6298 return get(EntryToIndex(entry) + 1); |
| 6234 } | 6299 } |
| 6235 | 6300 |
| 6236 | 6301 |
| 6302 Object* CompilationCacheTable::LookupEval(String* src, Context* context) { | |
| 6303 StringSharedKey key(src, context->closure()->shared()); | |
| 6304 int entry = FindEntry(&key); | |
| 6305 if (entry == -1) return Heap::undefined_value(); | |
| 6306 return get(EntryToIndex(entry) + 1); | |
| 6307 } | |
| 6308 | |
| 6309 | |
| 6237 Object* CompilationCacheTable::LookupRegExp(String* src, | 6310 Object* CompilationCacheTable::LookupRegExp(String* src, |
| 6238 JSRegExp::Flags flags) { | 6311 JSRegExp::Flags flags) { |
| 6239 RegExpKey key(src, flags); | 6312 RegExpKey key(src, flags); |
| 6240 int entry = FindEntry(&key); | 6313 int entry = FindEntry(&key); |
| 6241 if (entry == -1) return Heap::undefined_value(); | 6314 if (entry == -1) return Heap::undefined_value(); |
| 6242 return get(EntryToIndex(entry) + 1); | 6315 return get(EntryToIndex(entry) + 1); |
| 6243 } | 6316 } |
| 6244 | 6317 |
| 6245 | 6318 |
| 6246 Object* CompilationCacheTable::Put(String* src, Object* value) { | 6319 Object* CompilationCacheTable::Put(String* src, Object* value) { |
| 6247 StringKey key(src); | 6320 StringKey key(src); |
| 6248 Object* obj = EnsureCapacity(1, &key); | 6321 Object* obj = EnsureCapacity(1, &key); |
| 6249 if (obj->IsFailure()) return obj; | 6322 if (obj->IsFailure()) return obj; |
| 6250 | 6323 |
| 6251 CompilationCacheTable* cache = | 6324 CompilationCacheTable* cache = |
| 6252 reinterpret_cast<CompilationCacheTable*>(obj); | 6325 reinterpret_cast<CompilationCacheTable*>(obj); |
| 6253 int entry = cache->FindInsertionEntry(src, key.Hash()); | 6326 int entry = cache->FindInsertionEntry(src, key.Hash()); |
| 6254 cache->set(EntryToIndex(entry), src); | 6327 cache->set(EntryToIndex(entry), src); |
| 6255 cache->set(EntryToIndex(entry) + 1, value); | 6328 cache->set(EntryToIndex(entry) + 1, value); |
| 6256 cache->ElementAdded(); | 6329 cache->ElementAdded(); |
| 6257 return cache; | 6330 return cache; |
| 6258 } | 6331 } |
| 6259 | 6332 |
| 6260 | 6333 |
| 6334 Object* CompilationCacheTable::PutEval(String* src, | |
| 6335 Context* context, | |
| 6336 Object* value) { | |
| 6337 StringSharedKey key(src, context->closure()->shared()); | |
| 6338 Object* obj = EnsureCapacity(1, &key); | |
| 6339 if (obj->IsFailure()) return obj; | |
| 6340 | |
| 6341 CompilationCacheTable* cache = | |
| 6342 reinterpret_cast<CompilationCacheTable*>(obj); | |
| 6343 int entry = cache->FindInsertionEntry(src, key.Hash()); | |
| 6344 | |
| 6345 Object* k = key.GetObject(); | |
| 6346 if (k->IsFailure()) return k; | |
| 6347 | |
| 6348 cache->set(EntryToIndex(entry), k); | |
| 6349 cache->set(EntryToIndex(entry) + 1, value); | |
| 6350 cache->ElementAdded(); | |
| 6351 return cache; | |
| 6352 } | |
| 6353 | |
| 6354 | |
| 6261 Object* CompilationCacheTable::PutRegExp(String* src, | 6355 Object* CompilationCacheTable::PutRegExp(String* src, |
| 6262 JSRegExp::Flags flags, | 6356 JSRegExp::Flags flags, |
| 6263 FixedArray* value) { | 6357 FixedArray* value) { |
| 6264 RegExpKey key(src, flags); | 6358 RegExpKey key(src, flags); |
| 6265 Object* obj = EnsureCapacity(1, &key); | 6359 Object* obj = EnsureCapacity(1, &key); |
| 6266 if (obj->IsFailure()) return obj; | 6360 if (obj->IsFailure()) return obj; |
| 6267 | 6361 |
| 6268 CompilationCacheTable* cache = | 6362 CompilationCacheTable* cache = |
| 6269 reinterpret_cast<CompilationCacheTable*>(obj); | 6363 reinterpret_cast<CompilationCacheTable*>(obj); |
| 6270 int entry = cache->FindInsertionEntry(value, key.Hash()); | 6364 int entry = cache->FindInsertionEntry(value, key.Hash()); |
| (...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7157 // No break point. | 7251 // No break point. |
| 7158 if (break_point_objects()->IsUndefined()) return 0; | 7252 if (break_point_objects()->IsUndefined()) return 0; |
| 7159 // Single beak point. | 7253 // Single beak point. |
| 7160 if (!break_point_objects()->IsFixedArray()) return 1; | 7254 if (!break_point_objects()->IsFixedArray()) return 1; |
| 7161 // Multiple break points. | 7255 // Multiple break points. |
| 7162 return FixedArray::cast(break_point_objects())->length(); | 7256 return FixedArray::cast(break_point_objects())->length(); |
| 7163 } | 7257 } |
| 7164 | 7258 |
| 7165 | 7259 |
| 7166 } } // namespace v8::internal | 7260 } } // namespace v8::internal |
| OLD | NEW |