| 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(); |
| 5956 hash += shared->start_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 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6852 ASSERT(obj->HasFastProperties()); | 6946 ASSERT(obj->HasFastProperties()); |
| 6853 | 6947 |
| 6854 return obj; | 6948 return obj; |
| 6855 } | 6949 } |
| 6856 | 6950 |
| 6857 | 6951 |
| 6858 // Init line_ends array with code positions of line ends inside script source | 6952 // Init line_ends array with code positions of line ends inside script source |
| 6859 void Script::InitLineEnds() { | 6953 void Script::InitLineEnds() { |
| 6860 if (!line_ends()->IsUndefined()) return; | 6954 if (!line_ends()->IsUndefined()) return; |
| 6861 | 6955 |
| 6956 if (!source()->IsString()) { |
| 6957 ASSERT(source()->IsUndefined()); |
| 6958 set_line_ends(*(Factory::NewJSArray(0))); |
| 6959 ASSERT(line_ends()->IsJSArray()); |
| 6960 return; |
| 6961 } |
| 6962 |
| 6862 Handle<String> src(String::cast(source())); | 6963 Handle<String> src(String::cast(source())); |
| 6863 const int src_len = src->length(); | 6964 const int src_len = src->length(); |
| 6864 Handle<String> new_line = Factory::NewStringFromAscii(CStrVector("\n")); | 6965 Handle<String> new_line = Factory::NewStringFromAscii(CStrVector("\n")); |
| 6865 | 6966 |
| 6866 // Pass 1: Identify line count | 6967 // Pass 1: Identify line count |
| 6867 int line_count = 0; | 6968 int line_count = 0; |
| 6868 int position = 0; | 6969 int position = 0; |
| 6869 while (position != -1 && position < src_len) { | 6970 while (position != -1 && position < src_len) { |
| 6870 position = Runtime::StringMatch(src, new_line, position); | 6971 position = Runtime::StringMatch(src, new_line, position); |
| 6871 if (position != -1) { | 6972 if (position != -1) { |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7157 // No break point. | 7258 // No break point. |
| 7158 if (break_point_objects()->IsUndefined()) return 0; | 7259 if (break_point_objects()->IsUndefined()) return 0; |
| 7159 // Single beak point. | 7260 // Single beak point. |
| 7160 if (!break_point_objects()->IsFixedArray()) return 1; | 7261 if (!break_point_objects()->IsFixedArray()) return 1; |
| 7161 // Multiple break points. | 7262 // Multiple break points. |
| 7162 return FixedArray::cast(break_point_objects())->length(); | 7263 return FixedArray::cast(break_point_objects())->length(); |
| 7163 } | 7264 } |
| 7164 | 7265 |
| 7165 | 7266 |
| 7166 } } // namespace v8::internal | 7267 } } // namespace v8::internal |
| OLD | NEW |