Chromium Code Reviews| Index: src/objects.h |
| =================================================================== |
| --- src/objects.h (revision 10379) |
| +++ src/objects.h (working copy) |
| @@ -1541,7 +1541,7 @@ |
| bool HasFastArgumentsElements(); |
| bool HasDictionaryArgumentsElements(); |
| inline bool AllowsSetElementsLength(); |
| - inline NumberDictionary* element_dictionary(); // Gets slow elements. |
| + inline SeededNumberDictionary* element_dictionary(); // Gets slow elements. |
| // Requires: HasFastElements(). |
| MUST_USE_RESULT inline MaybeObject* EnsureWritableFastElements(); |
| @@ -1902,8 +1902,6 @@ |
| PropertyNormalizationMode mode, |
| int expected_additional_properties); |
| - // Convert and update the elements backing store to be a NumberDictionary |
| - // dictionary. Returns the backing after conversion. |
|
Erik Corry
2012/01/19 15:35:00
Strange removal of this comment, but no big deal.
|
| MUST_USE_RESULT MaybeObject* NormalizeElements(); |
| MUST_USE_RESULT MaybeObject* UpdateMapCodeCache(String* name, Code* code); |
| @@ -2221,7 +2219,7 @@ |
| public: |
| inline void Initialize(FixedArray* from); |
| inline void Initialize(FixedDoubleArray* from); |
| - inline void Initialize(NumberDictionary* from); |
| + inline void Initialize(SeededNumberDictionary* from); |
| // Setter and getter for elements. |
| inline double get_scalar(int index); |
| @@ -2514,9 +2512,46 @@ |
| // beginning of the backing storage that can be used for non-element |
| // information by subclasses. |
| +template<typename Key> |
| +class BaseShape { |
| + public: |
| + static const bool UsesSeed = false; |
| + static uint32_t Hash(Key key) { return 0; } |
| + static uint32_t SeededHash(Key key, uint32_t seed) { |
| + ASSERT(UsesSeed); |
| + return Hash(key); |
| + } |
| + static uint32_t HashForObject(Key key, Object* object) { return 0; } |
| + static uint32_t SeededHashForObject(Key key, uint32_t seed, Object* object) { |
| + // Won't be called if UsesSeed isn't overridden by child class. |
| + return HashForObject(key, object); |
| + } |
| +}; |
| + |
| template<typename Shape, typename Key> |
| class HashTable: public FixedArray { |
| public: |
| + // Wrapper methods |
| + inline uint32_t Hash(Key key) { |
| + if (Shape::UsesSeed) { |
| + // I'm using map()->heap() to skip is_safe_to_read_maps assertion. |
|
Erik Corry
2012/01/19 15:35:00
This comment and the associated change should not
|
| + // That was done, because NumberDictionary is used inside GC. |
| + return Shape::SeededHash(key, map()->heap()->HashSeed()); |
| + } else { |
| + return Shape::Hash(key); |
| + } |
| + } |
| + |
| + inline uint32_t HashForObject(Key key, Object* object) { |
| + if (Shape::UsesSeed) { |
| + // I'm using map()->heap() to skip is_safe_to_read_maps assertion. |
| + // That was done, because NumberDictionary is used inside GC. |
| + return Shape::SeededHashForObject(key, map()->heap()->HashSeed(), object); |
| + } else { |
| + return Shape::HashForObject(key, object); |
| + } |
| + } |
| + |
| // Returns the number of elements in the hash table. |
| int NumberOfElements() { |
| return Smi::cast(get(kNumberOfElementsIndex))->value(); |
| @@ -2658,7 +2693,6 @@ |
| }; |
| - |
| // HashTableKey is an abstract superclass for virtual key behavior. |
| class HashTableKey { |
| public: |
| @@ -2675,7 +2709,8 @@ |
| virtual ~HashTableKey() {} |
| }; |
| -class SymbolTableShape { |
| + |
| +class SymbolTableShape : public BaseShape<HashTableKey*> { |
| public: |
| static inline bool IsMatch(HashTableKey* key, Object* value) { |
| return key->IsMatch(value); |
| @@ -2734,7 +2769,7 @@ |
| }; |
| -class MapCacheShape { |
| +class MapCacheShape : public BaseShape<HashTableKey*> { |
| public: |
| static inline bool IsMatch(HashTableKey* key, Object* value) { |
| return key->IsMatch(value); |
| @@ -2890,7 +2925,7 @@ |
| }; |
| -class StringDictionaryShape { |
| +class StringDictionaryShape : public BaseShape<String*> { |
| public: |
| static inline bool IsMatch(String* key, Object* other); |
| static inline uint32_t Hash(String* key); |
| @@ -2923,23 +2958,42 @@ |
| }; |
| -class NumberDictionaryShape { |
| +class NumberDictionaryShape : public BaseShape<uint32_t> { |
| 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); |
| MUST_USE_RESULT static inline MaybeObject* 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> { |
| +class SeededNumberDictionaryShape : public NumberDictionaryShape { |
| public: |
| - static NumberDictionary* cast(Object* obj) { |
| + static const bool UsesSeed = true; |
| + static const int kPrefixSize = 2; |
| + |
| + static inline uint32_t SeededHash(uint32_t key, uint32_t seed); |
| + static inline uint32_t SeededHashForObject(uint32_t key, |
| + uint32_t seed, |
| + Object* object); |
| +}; |
| + |
| + |
| +class UnseededNumberDictionaryShape : public NumberDictionaryShape { |
| + public: |
| + static const int kPrefixSize = 0; |
| + |
| + static inline uint32_t Hash(uint32_t key); |
| + static inline uint32_t HashForObject(uint32_t key, Object* object); |
| +}; |
| + |
| + |
| +class SeededNumberDictionary |
| + : public Dictionary<SeededNumberDictionaryShape, uint32_t> { |
| + public: |
| + static SeededNumberDictionary* cast(Object* obj) { |
| ASSERT(obj->IsDictionary()); |
| - return reinterpret_cast<NumberDictionary*>(obj); |
| + return reinterpret_cast<SeededNumberDictionary*>(obj); |
| } |
| // Type specific at put (default NONE attributes is used when adding). |
| @@ -2978,8 +3032,25 @@ |
| }; |
| -class ObjectHashTableShape { |
| +class UnseededNumberDictionary |
| + : public Dictionary<UnseededNumberDictionaryShape, uint32_t> { |
| public: |
| + static UnseededNumberDictionary* cast(Object* obj) { |
| + ASSERT(obj->IsDictionary()); |
| + return reinterpret_cast<UnseededNumberDictionary*>(obj); |
| + } |
| + |
| + // Type specific at put (default NONE attributes is used when adding). |
| + MUST_USE_RESULT MaybeObject* AtNumberPut(uint32_t key, Object* value); |
| + MUST_USE_RESULT MaybeObject* AddNumberEntry(uint32_t key, Object* value); |
| + |
| + // Set an existing entry or add a new one if needed. |
| + MUST_USE_RESULT MaybeObject* Set(uint32_t key, Object* value); |
| +}; |
| + |
| + |
| +class ObjectHashTableShape : public BaseShape<Object*> { |
| + public: |
| static inline bool IsMatch(JSObject* key, Object* other); |
| static inline uint32_t Hash(JSObject* key); |
| static inline uint32_t HashForObject(JSObject* key, Object* object); |
| @@ -5543,7 +5614,7 @@ |
| }; |
| -class CompilationCacheShape { |
| +class CompilationCacheShape : public BaseShape<HashTableKey*> { |
| public: |
| static inline bool IsMatch(HashTableKey* key, Object* value) { |
| return key->IsMatch(value); |
| @@ -5643,7 +5714,7 @@ |
| }; |
| -class CodeCacheHashTableShape { |
| +class CodeCacheHashTableShape : public BaseShape<HashTableKey*> { |
| public: |
| static inline bool IsMatch(HashTableKey* key, Object* value) { |
| return key->IsMatch(value); |