Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: src/objects.cc

Issue 7879: Introduce a lookup cache class in the runtime system and use it for... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698