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 5461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5472 int JSObject::GetEnumElementKeys(FixedArray* storage) { | 5472 int JSObject::GetEnumElementKeys(FixedArray* storage) { |
5473 return GetLocalElementKeys(storage, | 5473 return GetLocalElementKeys(storage, |
5474 static_cast<PropertyAttributes>(DONT_ENUM)); | 5474 static_cast<PropertyAttributes>(DONT_ENUM)); |
5475 } | 5475 } |
5476 | 5476 |
5477 | 5477 |
5478 // The NumberKey uses carries the uint32_t as key. | 5478 // The NumberKey uses carries the uint32_t as key. |
5479 // This avoids allocation in HasProperty. | 5479 // This avoids allocation in HasProperty. |
5480 class NumberKey : public HashTableKey { | 5480 class NumberKey : public HashTableKey { |
5481 public: | 5481 public: |
5482 explicit NumberKey(uint32_t number) { | 5482 explicit NumberKey(uint32_t number) : number_(number) { } |
5483 number_ = number; | |
5484 } | |
5485 | 5483 |
5486 private: | 5484 private: |
5487 bool IsMatch(Object* number) { | 5485 bool IsMatch(Object* number) { |
5488 return number_ == ToUint32(number); | 5486 return number_ == ToUint32(number); |
5489 } | 5487 } |
5490 | 5488 |
5491 // Thomas Wang, Integer Hash Functions. | 5489 // Thomas Wang, Integer Hash Functions. |
5492 // http://www.concentric.net/~Ttwang/tech/inthash.htm | 5490 // http://www.concentric.net/~Ttwang/tech/inthash.htm |
5493 static uint32_t ComputeHash(uint32_t key) { | 5491 static uint32_t ComputeHash(uint32_t key) { |
5494 uint32_t hash = key; | 5492 uint32_t hash = key; |
(...skipping 25 matching lines...) Expand all Loading... | |
5520 | 5518 |
5521 bool IsStringKey() { return false; } | 5519 bool IsStringKey() { return false; } |
5522 | 5520 |
5523 uint32_t number_; | 5521 uint32_t number_; |
5524 }; | 5522 }; |
5525 | 5523 |
5526 | 5524 |
5527 // StringKey simply carries a string object as key. | 5525 // StringKey simply carries a string object as key. |
5528 class StringKey : public HashTableKey { | 5526 class StringKey : public HashTableKey { |
5529 public: | 5527 public: |
5530 explicit StringKey(String* string) { | 5528 explicit StringKey(String* string) : string_(string) { } |
5531 string_ = string; | |
5532 } | |
5533 | 5529 |
5534 bool IsMatch(Object* string) { | 5530 bool IsMatch(Object* string) { |
5535 return string_->Equals(String::cast(string)); | 5531 return string_->Equals(String::cast(string)); |
5536 } | 5532 } |
5537 | 5533 |
5538 uint32_t Hash() { return StringHash(string_); } | 5534 uint32_t Hash() { return StringHash(string_); } |
5539 | 5535 |
5540 HashFunction GetHashFunction() { return StringHash; } | 5536 HashFunction GetHashFunction() { return StringHash; } |
5541 | 5537 |
5542 Object* GetObject() { return string_; } | 5538 Object* GetObject() { return string_; } |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5838 cache->set(EntryToIndex(entry), src); | 5834 cache->set(EntryToIndex(entry), src); |
5839 cache->set(EntryToIndex(entry) + 1, value); | 5835 cache->set(EntryToIndex(entry) + 1, value); |
5840 cache->ElementAdded(); | 5836 cache->ElementAdded(); |
5841 return cache; | 5837 return cache; |
5842 } | 5838 } |
5843 | 5839 |
5844 | 5840 |
5845 // SymbolsKey used for HashTable where key is array of symbols. | 5841 // SymbolsKey used for HashTable where key is array of symbols. |
5846 class SymbolsKey : public HashTableKey { | 5842 class SymbolsKey : public HashTableKey { |
5847 public: | 5843 public: |
5848 explicit SymbolsKey(FixedArray* symbols) { | 5844 explicit SymbolsKey(FixedArray* symbols) : symbols_(symbols) { } |
5849 symbols_ = symbols; | |
5850 } | |
5851 | 5845 |
5852 bool IsMatch(Object* symbols) { | 5846 bool IsMatch(Object* symbols) { |
5853 FixedArray* o = FixedArray::cast(symbols); | 5847 FixedArray* o = FixedArray::cast(symbols); |
5854 int len = symbols_->length(); | 5848 int len = symbols_->length(); |
5855 if (o->length() != len) return false; | 5849 if (o->length() != len) return false; |
5856 for (int i = 0; i < len; i++) { | 5850 for (int i = 0; i < len; i++) { |
5857 if (o->get(i) != symbols_->get(i)) return false; | 5851 if (o->get(i) != symbols_->get(i)) return false; |
5858 } | 5852 } |
5859 return true; | 5853 return true; |
5860 } | 5854 } |
5861 | 5855 |
5862 uint32_t Hash() { return SymbolsHash(symbols_); } | 5856 uint32_t Hash() { return SymbolsHash(symbols_); } |
5863 | 5857 |
5864 HashFunction GetHashFunction() { return SymbolsHash; } | 5858 HashFunction GetHashFunction() { return SymbolsHash; } |
5865 | 5859 |
5866 Object* GetObject() { return symbols_; } | 5860 Object* GetObject() { return symbols_; } |
5867 | 5861 |
5868 static uint32_t SymbolsHash(Object* obj) { | 5862 static uint32_t SymbolsHash(Object* obj) { |
5869 FixedArray* symbols_ = FixedArray::cast(obj); | 5863 FixedArray* symbols = FixedArray::cast(obj); |
5870 int len = symbols_->length(); | 5864 int len = symbols->length(); |
5871 uint32_t hash = 0; | 5865 uint32_t hash = 0; |
5872 for (int i = 0; i < len; i++) { | 5866 for (int i = 0; i < len; i++) { |
5873 hash ^= String::cast(symbols_->get(i))->Hash(); | 5867 hash ^= String::cast(symbols->get(i))->Hash(); |
5874 } | 5868 } |
5875 return hash; | 5869 return hash; |
5876 } | 5870 } |
5877 | 5871 |
5878 bool IsStringKey() { return false; } | 5872 bool IsStringKey() { return false; } |
5879 | 5873 |
5874 private: | |
5880 FixedArray* symbols_; | 5875 FixedArray* symbols_; |
5881 }; | 5876 }; |
5882 | 5877 |
5878 | |
5879 // MapNameKeys are used as keys in lookup caches. | |
5880 class MapNameKey : public HashTableKey { | |
5881 public: | |
5882 MapNameKey(Map* map, String* name) | |
5883 : map_(map), name_(name) { } | |
5884 | |
5885 virtual bool IsMatch(Object* other) { | |
bak
2008/10/23 06:08:11
Why do you use the virtual keyword in this class?
| |
5886 if (!other->IsFixedArray()) return false; | |
5887 FixedArray* pair = FixedArray::cast(other); | |
5888 Map* map = Map::cast(pair->get(0)); | |
5889 if (map != map_) return false; | |
5890 String* name = String::cast(pair->get(1)); | |
5891 return name->Equals(name_); | |
5892 } | |
5893 | |
5894 typedef uint32_t (*HashFunction)(Object* obj); | |
5895 | |
5896 virtual HashFunction GetHashFunction() { return MapNameHash; } | |
5897 | |
5898 static uint32_t MapNameHashHelper(Map* map, String* name) { | |
5899 return reinterpret_cast<uint32_t>(map) ^ name->Hash(); | |
5900 } | |
5901 | |
5902 static uint32_t MapNameHash(Object* obj) { | |
5903 FixedArray* pair = FixedArray::cast(obj); | |
5904 Map* map = Map::cast(pair->get(0)); | |
5905 String* name = String::cast(pair->get(1)); | |
5906 return MapNameHashHelper(map, name); | |
5907 } | |
5908 | |
5909 virtual uint32_t Hash() { | |
5910 return MapNameHashHelper(map_, name_); | |
5911 } | |
5912 | |
5913 virtual Object* GetObject() { | |
5914 Object* obj = Heap::AllocateFixedArray(2); | |
5915 if (obj->IsFailure()) return obj; | |
5916 FixedArray* pair = FixedArray::cast(obj); | |
5917 pair->set(0, map_); | |
5918 pair->set(1, name_); | |
5919 return pair; | |
5920 } | |
5921 | |
5922 virtual bool IsStringKey() { return false; } | |
5923 | |
5924 private: | |
5925 Map* map_; | |
5926 String* name_; | |
5927 }; | |
5928 | |
5929 | |
5883 Object* MapCache::Lookup(FixedArray* array) { | 5930 Object* MapCache::Lookup(FixedArray* array) { |
5884 SymbolsKey key(array); | 5931 SymbolsKey key(array); |
5885 int entry = FindEntry(&key); | 5932 int entry = FindEntry(&key); |
5886 if (entry != -1) { | 5933 if (entry != -1) { |
5887 return get(EntryToIndex(entry) + 1); | 5934 return get(EntryToIndex(entry) + 1); |
5888 } else { | 5935 } else { |
5889 return Heap::undefined_value(); | 5936 return Heap::undefined_value(); |
5890 } | 5937 } |
5891 } | 5938 } |
5892 | 5939 |
5893 | 5940 |
5894 Object* MapCache::Put(FixedArray* array, Map* value) { | 5941 Object* MapCache::Put(FixedArray* array, Map* value) { |
5895 SymbolsKey key(array); | 5942 SymbolsKey key(array); |
5896 Object* obj = EnsureCapacity(1, &key); | 5943 Object* obj = EnsureCapacity(1, &key); |
5897 if (obj->IsFailure()) return obj; | 5944 if (obj->IsFailure()) return obj; |
5898 | 5945 |
5899 MapCache* cache = reinterpret_cast<MapCache*>(obj); | 5946 MapCache* cache = reinterpret_cast<MapCache*>(obj); |
5900 int entry = cache->FindInsertionEntry(array, key.Hash()); | 5947 int entry = cache->FindInsertionEntry(array, key.Hash()); |
5901 cache->set(EntryToIndex(entry), array); | 5948 cache->set(EntryToIndex(entry), array); |
5902 cache->set(EntryToIndex(entry) + 1, value); | 5949 cache->set(EntryToIndex(entry) + 1, value); |
5903 cache->ElementAdded(); | 5950 cache->ElementAdded(); |
5904 return cache; | 5951 return cache; |
5905 } | 5952 } |
5906 | 5953 |
5907 | 5954 |
5955 int LookupCache::Lookup(Map* map, String* name) { | |
5956 MapNameKey key(map, name); | |
5957 int entry = FindEntry(&key); | |
5958 if (entry != -1) { | |
bak
2008/10/23 06:08:11
I find this easier to read.
if (entry == -1) retur
| |
5959 return Smi::cast(get(EntryToIndex(entry) + 1))->value(); | |
5960 } else { | |
5961 return -1; | |
5962 } | |
5963 } | |
5964 | |
5965 | |
5966 Object* LookupCache::Put(Map* map, String* name, int value) { | |
5967 MapNameKey key(map, name); | |
5968 Object* obj = EnsureCapacity(1, &key); | |
5969 if (obj->IsFailure()) return obj; | |
5970 Object* k = key.GetObject(); | |
5971 if (k->IsFailure()) return k; | |
5972 | |
5973 LookupCache* cache = reinterpret_cast<LookupCache*>(obj); | |
5974 int entry = cache->FindInsertionEntry(k, key.Hash()); | |
5975 int index = EntryToIndex(entry); | |
5976 cache->set(index, k); | |
5977 cache->set(index + 1, Smi::FromInt(value)); | |
5978 cache->ElementAdded(); | |
5979 return cache; | |
5980 } | |
5981 | |
5982 | |
5908 Object* Dictionary::Allocate(int at_least_space_for) { | 5983 Object* Dictionary::Allocate(int at_least_space_for) { |
5909 Object* obj = DictionaryBase::Allocate(at_least_space_for); | 5984 Object* obj = DictionaryBase::Allocate(at_least_space_for); |
5910 // Initialize the next enumeration index. | 5985 // Initialize the next enumeration index. |
5911 if (!obj->IsFailure()) { | 5986 if (!obj->IsFailure()) { |
5912 Dictionary::cast(obj)-> | 5987 Dictionary::cast(obj)-> |
5913 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); | 5988 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); |
5914 } | 5989 } |
5915 return obj; | 5990 return obj; |
5916 } | 5991 } |
5917 | 5992 |
5993 | |
5918 Object* Dictionary::GenerateNewEnumerationIndices() { | 5994 Object* Dictionary::GenerateNewEnumerationIndices() { |
5919 int length = NumberOfElements(); | 5995 int length = NumberOfElements(); |
5920 | 5996 |
5921 // Allocate and initialize iteration order array. | 5997 // Allocate and initialize iteration order array. |
5922 Object* obj = Heap::AllocateFixedArray(length); | 5998 Object* obj = Heap::AllocateFixedArray(length); |
5923 if (obj->IsFailure()) return obj; | 5999 if (obj->IsFailure()) return obj; |
5924 FixedArray* iteration_order = FixedArray::cast(obj); | 6000 FixedArray* iteration_order = FixedArray::cast(obj); |
5925 for (int i = 0; i < length; i++) iteration_order->set(i, Smi::FromInt(i)); | 6001 for (int i = 0; i < length; i++) iteration_order->set(i, Smi::FromInt(i)); |
5926 | 6002 |
5927 // Allocate array with enumeration order. | 6003 // Allocate array with enumeration order. |
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6564 // No break point. | 6640 // No break point. |
6565 if (break_point_objects()->IsUndefined()) return 0; | 6641 if (break_point_objects()->IsUndefined()) return 0; |
6566 // Single beak point. | 6642 // Single beak point. |
6567 if (!break_point_objects()->IsFixedArray()) return 1; | 6643 if (!break_point_objects()->IsFixedArray()) return 1; |
6568 // Multiple break points. | 6644 // Multiple break points. |
6569 return FixedArray::cast(break_point_objects())->length(); | 6645 return FixedArray::cast(break_point_objects())->length(); |
6570 } | 6646 } |
6571 | 6647 |
6572 | 6648 |
6573 } } // namespace v8::internal | 6649 } } // namespace v8::internal |
OLD | NEW |