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 |