Index: src/objects.h |
=================================================================== |
--- src/objects.h (revision 2326) |
+++ src/objects.h (working copy) |
@@ -1207,7 +1207,7 @@ |
DECL_ACCESSORS(properties, FixedArray) // Get and set fast properties. |
inline void initialize_properties(); |
inline bool HasFastProperties(); |
- inline Dictionary* property_dictionary(); // Gets slow properties. |
+ inline StringDictionary* property_dictionary(); // Gets slow properties. |
// [elements]: The elements (properties with names that are integers). |
// elements is a FixedArray in the fast case, and a Dictionary in the slow |
@@ -1215,7 +1215,7 @@ |
DECL_ACCESSORS(elements, FixedArray) // Get and set fast elements. |
inline void initialize_elements(); |
inline bool HasFastElements(); |
- inline Dictionary* element_dictionary(); // Gets slow elements. |
+ inline NumberDictionary* element_dictionary(); // Gets slow elements. |
// Collects elements starting at index 0. |
// Undefined values are placed after non-undefined values. |
@@ -1875,32 +1875,29 @@ |
// - Elements with key == undefined have not been used yet. |
// - Elements with key == null have been deleted. |
// |
-// The hash table class is parameterized with a prefix size and with |
-// the size, including the key size, of the elements held in the hash |
+// The hash table class is parameterized with a Shape and a Key. |
+// Shape must be a class with the following interface: |
+// class ExampleShape { |
+// public: |
+// // Tells whether key matches other. |
+// static bool IsMatch(Key key, Object* other); |
+// // Returns the hash value for key. |
+// static uint32_t Hash(Key key); |
+// // Returns the hash value for object. |
+// static uint32_t HashForObject(Key key, Object* object); |
+// // Convert key to an object. |
+// static inline Object* AsObject(Key key); |
+// // The prefix size indicates number of elements in the beginning |
+// // of the backing storage. |
+// static const int kPrefixSize = ..; |
+// // The Element size indicates number of elements per entry. |
+// static const int kEntrySize = ..; |
+// }; |
// table. The prefix size indicates an amount of memory in the |
// beginning of the backing storage that can be used for non-element |
// information by subclasses. |
-// HashTableKey is an abstract superclass keys. |
-class HashTableKey { |
- public: |
- // Returns whether the other object matches this key. |
- virtual bool IsMatch(Object* other) = 0; |
- typedef uint32_t (*HashFunction)(Object* obj); |
- // Returns the hash function used for this key. |
- virtual HashFunction GetHashFunction() = 0; |
- // Returns the hash value for this key. |
- virtual uint32_t Hash() = 0; |
- // Returns the key object for storing into the dictionary. |
- // If allocations fails a failure object is returned. |
- virtual Object* GetObject() = 0; |
- virtual bool IsStringKey() = 0; |
- // Required. |
- virtual ~HashTableKey() {} |
-}; |
- |
- |
-template<int prefix_size, int element_size> |
+template<typename Shape, typename Key> |
class HashTable: public FixedArray { |
public: |
// Returns the number of elements in the dictionary. |
@@ -1949,25 +1946,27 @@ |
static const int kNumberOfElementsIndex = 0; |
static const int kCapacityIndex = 1; |
static const int kPrefixStartIndex = 2; |
- static const int kElementsStartIndex = kPrefixStartIndex + prefix_size; |
- static const int kElementSize = element_size; |
+ static const int kElementsStartIndex = |
+ kPrefixStartIndex + Shape::kPrefixSize; |
+ static const int kEntrySize = Shape::kEntrySize; |
static const int kElementsStartOffset = |
kHeaderSize + kElementsStartIndex * kPointerSize; |
// Constant used for denoting a absent entry. |
static const int kNotFound = -1; |
- protected: |
// Find entry for key otherwise return -1. |
- int FindEntry(HashTableKey* key); |
+ int FindEntry(Key key); |
+ protected: |
+ |
// Find the entry at which to insert element with the given key that |
// has the given hash value. |
- uint32_t FindInsertionEntry(Object* key, uint32_t hash); |
+ uint32_t FindInsertionEntry(uint32_t hash); |
// Returns the index for an entry (of the key) |
static inline int EntryToIndex(int entry) { |
- return (entry * kElementSize) + kElementsStartIndex; |
+ return (entry * kEntrySize) + kElementsStartIndex; |
} |
// Update the number of elements in the dictionary. |
@@ -1992,15 +1991,51 @@ |
} |
// Ensure enough space for n additional elements. |
- Object* EnsureCapacity(int n, HashTableKey* key); |
+ Object* EnsureCapacity(int n, Key key); |
}; |
+ |
+// HashTableKey is an abstract superclass for virtual key behavior. |
+class HashTableKey { |
+ public: |
+ // Returns whether the other object matches this key. |
+ virtual bool IsMatch(Object* other) = 0; |
+ // Returns the hash value for this key. |
+ virtual uint32_t Hash() = 0; |
+ // Returns the hash value for object. |
+ virtual uint32_t HashForObject(Object* key) = 0; |
+ // Returns the key object for storing into the dictionary. |
+ // If allocations fails a failure object is returned. |
+ virtual Object* AsObject() = 0; |
+ // Required. |
+ virtual ~HashTableKey() {} |
+}; |
+ |
+class SymbolTableShape { |
+ public: |
+ static bool IsMatch(HashTableKey* key, Object* value) { |
+ return key->IsMatch(value); |
+ } |
+ static uint32_t Hash(HashTableKey* key) { |
+ return key->Hash(); |
+ } |
+ static uint32_t HashForObject(HashTableKey* key, Object* object) { |
+ return key->HashForObject(object); |
+ } |
+ static Object* AsObject(HashTableKey* key) { |
+ return key->AsObject(); |
+ } |
+ |
+ static const int kPrefixSize = 0; |
+ static const int kEntrySize = 1; |
+}; |
+ |
// SymbolTable. |
// |
// No special elements in the prefix and the element size is 1 |
// because only the symbol itself (the key) needs to be stored. |
-class SymbolTable: public HashTable<0, 1> { |
+class SymbolTable: public HashTable<SymbolTableShape, HashTableKey*> { |
public: |
// Find symbol in the symbol table. If it is not there yet, it is |
// added. The return value is the symbol table which might have |
@@ -2024,11 +2059,33 @@ |
}; |
+class MapCacheShape { |
+ public: |
+ static bool IsMatch(HashTableKey* key, Object* value) { |
+ return key->IsMatch(value); |
+ } |
+ static uint32_t Hash(HashTableKey* key) { |
+ return key->Hash(); |
+ } |
+ |
+ static uint32_t HashForObject(HashTableKey* key, Object* object) { |
+ return key->HashForObject(object); |
+ } |
+ |
+ static Object* AsObject(HashTableKey* key) { |
+ return key->AsObject(); |
+ } |
+ |
+ static const int kPrefixSize = 0; |
+ static const int kEntrySize = 2; |
+}; |
+ |
+ |
// MapCache. |
// |
// Maps keys that are a fixed array of symbols to a map. |
// Used for canonicalize maps for object literals. |
-class MapCache: public HashTable<0, 2> { |
+class MapCache: public HashTable<MapCacheShape, HashTableKey*> { |
public: |
// Find cached value for a string key, otherwise return null. |
Object* Lookup(FixedArray* key); |
@@ -2040,74 +2097,42 @@ |
}; |
-// Dictionary for keeping properties and elements in slow case. |
-// |
-// One element in the prefix is used for storing non-element |
-// information about the dictionary. |
-// |
-// The rest of the array embeds triples of (key, value, details). |
-// if key == undefined the triple is empty. |
-// if key == null the triple has been deleted. |
-// otherwise key contains the name of a property. |
-class DictionaryBase: public HashTable<2, 3> {}; |
+template <typename Shape, typename Key> |
+class Dictionary: public HashTable<Shape, Key> { |
+ public: |
-class Dictionary: public DictionaryBase { |
- public: |
+ static inline Dictionary<Shape, Key>* cast(Object* obj) { |
+ return reinterpret_cast<Dictionary<Shape, Key>*>(obj); |
+ } |
+ |
// Returns the value at entry. |
Object* ValueAt(int entry) { |
- return get(EntryToIndex(entry)+1); |
+ return get(HashTable<Shape, Key>::EntryToIndex(entry)+1); |
} |
// Set the value for entry. |
void ValueAtPut(int entry, Object* value) { |
- set(EntryToIndex(entry)+1, value); |
+ set(HashTable<Shape, Key>::EntryToIndex(entry)+1, value); |
} |
// Returns the property details for the property at entry. |
PropertyDetails DetailsAt(int entry) { |
ASSERT(entry >= 0); // Not found is -1, which is not caught by get(). |
- return PropertyDetails(Smi::cast(get(EntryToIndex(entry) + 2))); |
+ return PropertyDetails( |
+ Smi::cast(get(HashTable<Shape, Key>::EntryToIndex(entry) + 2))); |
} |
// Set the details for entry. |
void DetailsAtPut(int entry, PropertyDetails value) { |
- set(EntryToIndex(entry) + 2, value.AsSmi()); |
+ set(HashTable<Shape, Key>::EntryToIndex(entry) + 2, value.AsSmi()); |
} |
- // Remove all entries were key is a number and (from <= key && key < to). |
- void RemoveNumberEntries(uint32_t from, uint32_t to); |
- |
// Sorting support |
void CopyValuesTo(FixedArray* elements); |
- // Casting. |
- static inline Dictionary* cast(Object* obj); |
- |
- // Find entry for string key otherwise return -1. |
- int FindStringEntry(String* key); |
- |
- // Find entry for number key otherwise return -1. |
- int FindNumberEntry(uint32_t index); |
- |
// Delete a property from the dictionary. |
Object* DeleteProperty(int entry, JSObject::DeleteMode mode); |
- // Type specific at put (default NONE attributes is used when adding). |
- Object* AtNumberPut(uint32_t key, Object* value); |
- |
- Object* AddStringEntry(String* key, Object* value, PropertyDetails details); |
- Object* AddNumberEntry(uint32_t key, Object* value, PropertyDetails details); |
- |
- // Set an existing entry or add a new one if needed. |
- Object* SetStringEntry(int entry, |
- String* key, |
- Object* value, |
- PropertyDetails details); |
- |
- Object* SetOrAddNumberEntry(uint32_t key, |
- Object* value, |
- PropertyDetails details); |
- |
// Returns the number of elements in the dictionary filtering out properties |
// with the specified attributes. |
int NumberOfElementsFilterAttributes(PropertyAttributes filter); |
@@ -2117,42 +2142,23 @@ |
// Copies keys to preallocated fixed array. |
void CopyKeysTo(FixedArray* storage, PropertyAttributes filter); |
- // Copies enumerable keys to preallocated fixed array. |
- void CopyEnumKeysTo(FixedArray* storage, FixedArray* sort_array); |
// Fill in details for properties into storage. |
void CopyKeysTo(FixedArray* storage); |
- // For transforming properties of a JSObject. |
- Object* TransformPropertiesToFastFor(JSObject* obj, |
- int unused_property_fields); |
- |
- // If slow elements are required we will never go back to fast-case |
- // for the elements kept in this dictionary. We require slow |
- // elements if an element has been added at an index larger than |
- // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called |
- // when defining a getter or setter with a number key. |
- inline bool requires_slow_elements(); |
- inline void set_requires_slow_elements(); |
- |
- // Get the value of the max number key that has been added to this |
- // dictionary. max_number_key can only be called if |
- // requires_slow_elements returns false. |
- inline uint32_t max_number_key(); |
- |
// Accessors for next enumeration index. |
void SetNextEnumerationIndex(int index) { |
fast_set(this, kNextEnumerationIndexIndex, Smi::FromInt(index)); |
} |
int NextEnumerationIndex() { |
- return Smi::cast(get(kNextEnumerationIndexIndex))->value(); |
+ return Smi::cast(FixedArray::get(kNextEnumerationIndexIndex))->value(); |
} |
// Returns a new array for dictionary usage. Might return Failure. |
static Object* Allocate(int at_least_space_for); |
// Ensure enough space for n additional elements. |
- Object* EnsureCapacity(int n, HashTableKey* key); |
+ Object* EnsureCapacity(int n, Key key); |
#ifdef DEBUG |
void Print(); |
@@ -2160,41 +2166,113 @@ |
// Returns the key (slow). |
Object* SlowReverseLookup(Object* value); |
- // Bit masks. |
- static const int kRequiresSlowElementsMask = 1; |
- static const int kRequiresSlowElementsTagSize = 1; |
- static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1; |
+ // Sets the entry to (key, value) pair. |
+ inline void SetEntry(int entry, |
+ Object* key, |
+ Object* value, |
+ PropertyDetails details); |
- void UpdateMaxNumberKey(uint32_t key); |
+ Object* Add(Key key, Object* value, PropertyDetails details); |
- private: |
+ protected: |
// Generic at put operation. |
- Object* AtPut(HashTableKey* key, Object* value); |
+ Object* AtPut(Key key, Object* value); |
- Object* Add(HashTableKey* key, Object* value, PropertyDetails details); |
- |
// Add entry to dictionary. |
- void AddEntry(Object* key, |
- Object* value, |
- PropertyDetails details, |
- uint32_t hash); |
+ Object* AddEntry(Key key, |
+ Object* value, |
+ PropertyDetails details, |
+ uint32_t hash); |
- // Sets the entry to (key, value) pair. |
- inline void SetEntry(int entry, |
- Object* key, |
- Object* value, |
- PropertyDetails details); |
- |
// Generate new enumeration indices to avoid enumeration index overflow. |
Object* GenerateNewEnumerationIndices(); |
- |
- static const int kMaxNumberKeyIndex = kPrefixStartIndex; |
+ static const int kMaxNumberKeyIndex = |
+ HashTable<Shape, Key>::kPrefixStartIndex; |
static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1; |
+}; |
- DISALLOW_IMPLICIT_CONSTRUCTORS(Dictionary); |
+ |
+class StringDictionaryShape { |
+ public: |
+ static inline bool IsMatch(String* key, Object* other); |
+ static inline uint32_t Hash(String* key); |
+ static inline uint32_t HashForObject(String* key, Object* object); |
+ static inline Object* AsObject(String* key); |
+ static const int kPrefixSize = 2; |
+ static const int kEntrySize = 3; |
+ static const bool kIsEnumerable = true; |
}; |
+class StringDictionary: public Dictionary<StringDictionaryShape, String*> { |
+ public: |
+ static inline StringDictionary* cast(Object* obj) { |
+ ASSERT(obj->IsDictionary()); |
+ return reinterpret_cast<StringDictionary*>(obj); |
+ } |
+ |
+ // Copies enumerable keys to preallocated fixed array. |
+ void CopyEnumKeysTo(FixedArray* storage, FixedArray* sort_array); |
+ |
+ // For transforming properties of a JSObject. |
+ Object* TransformPropertiesToFastFor(JSObject* obj, |
+ int unused_property_fields); |
+}; |
+ |
+ |
+class NumberDictionaryShape { |
+ public: |
+ static inline bool IsMatch(uint32_t key, Object* other); |
+ static inline uint32_t Hash(uint32_t key); |
+ static inline uint32_t HashForObject(uint32_t key, Object* object); |
+ static inline Object* AsObject(uint32_t key); |
+ static const int kPrefixSize = 2; |
+ static const int kEntrySize = 3; |
+ static const bool kIsEnumerable = false; |
+}; |
+ |
+ |
+class NumberDictionary: public Dictionary<NumberDictionaryShape, uint32_t> { |
+ public: |
+ static NumberDictionary* cast(Object* obj) { |
+ ASSERT(obj->IsDictionary()); |
+ return reinterpret_cast<NumberDictionary*>(obj); |
+ } |
+ |
+ // Type specific at put (default NONE attributes is used when adding). |
+ Object* AtNumberPut(uint32_t key, Object* value); |
+ Object* AddNumberEntry(uint32_t key, |
+ Object* value, |
+ PropertyDetails details); |
+ |
+ // Set an existing entry or add a new one if needed. |
+ Object* Set(uint32_t key, Object* value, PropertyDetails details); |
+ |
+ void UpdateMaxNumberKey(uint32_t key); |
+ |
+ // If slow elements are required we will never go back to fast-case |
+ // for the elements kept in this dictionary. We require slow |
+ // elements if an element has been added at an index larger than |
+ // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called |
+ // when defining a getter or setter with a number key. |
+ inline bool requires_slow_elements(); |
+ inline void set_requires_slow_elements(); |
+ |
+ // Get the value of the max number key that has been added to this |
+ // dictionary. max_number_key can only be called if |
+ // requires_slow_elements returns false. |
+ inline uint32_t max_number_key(); |
+ |
+ // Remove all entries were key is a number and (from <= key && key < to). |
+ void RemoveNumberEntries(uint32_t from, uint32_t to); |
+ |
+ // Bit masks. |
+ static const int kRequiresSlowElementsMask = 1; |
+ static const int kRequiresSlowElementsTagSize = 1; |
+ static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1; |
+}; |
+ |
+ |
// ByteArray represents fixed sized byte arrays. Used by the outside world, |
// such as PCRE, and also by the memory allocator and garbage collector to |
// fill in free blocks in the heap. |
@@ -3231,8 +3309,31 @@ |
}; |
-class CompilationCacheTable: public HashTable<0, 2> { |
+class CompilationCacheShape { |
public: |
+ static inline bool IsMatch(HashTableKey* key, Object* value) { |
+ return key->IsMatch(value); |
+ } |
+ |
+ static inline uint32_t Hash(HashTableKey* key) { |
+ return key->Hash(); |
+ } |
+ |
+ static inline uint32_t HashForObject(HashTableKey* key, Object* object) { |
+ return key->HashForObject(object); |
+ } |
+ |
+ static Object* AsObject(HashTableKey* key) { |
+ return key->AsObject(); |
+ } |
+ |
+ static const int kPrefixSize = 0; |
+ static const int kEntrySize = 2; |
+}; |
+ |
+class CompilationCacheTable: public HashTable<CompilationCacheShape, |
+ HashTableKey*> { |
+ public: |
// Find cached value for a string key, otherwise return null. |
Object* Lookup(String* src); |
Object* LookupEval(String* src, Context* context); |