OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 1189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1200 class JSObject: public HeapObject { | 1200 class JSObject: public HeapObject { |
1201 public: | 1201 public: |
1202 enum DeleteMode { NORMAL_DELETION, FORCE_DELETION }; | 1202 enum DeleteMode { NORMAL_DELETION, FORCE_DELETION }; |
1203 | 1203 |
1204 // [properties]: Backing storage for properties. | 1204 // [properties]: Backing storage for properties. |
1205 // properties is a FixedArray in the fast case, and a Dictionary in the | 1205 // properties is a FixedArray in the fast case, and a Dictionary in the |
1206 // slow case. | 1206 // slow case. |
1207 DECL_ACCESSORS(properties, FixedArray) // Get and set fast properties. | 1207 DECL_ACCESSORS(properties, FixedArray) // Get and set fast properties. |
1208 inline void initialize_properties(); | 1208 inline void initialize_properties(); |
1209 inline bool HasFastProperties(); | 1209 inline bool HasFastProperties(); |
1210 inline Dictionary* property_dictionary(); // Gets slow properties. | 1210 inline StringDictionary* property_dictionary(); // Gets slow properties. |
1211 | 1211 |
1212 // [elements]: The elements (properties with names that are integers). | 1212 // [elements]: The elements (properties with names that are integers). |
1213 // elements is a FixedArray in the fast case, and a Dictionary in the slow | 1213 // elements is a FixedArray in the fast case, and a Dictionary in the slow |
1214 // case. | 1214 // case. |
1215 DECL_ACCESSORS(elements, FixedArray) // Get and set fast elements. | 1215 DECL_ACCESSORS(elements, FixedArray) // Get and set fast elements. |
1216 inline void initialize_elements(); | 1216 inline void initialize_elements(); |
1217 inline bool HasFastElements(); | 1217 inline bool HasFastElements(); |
1218 inline Dictionary* element_dictionary(); // Gets slow elements. | 1218 inline NumberDictionary* element_dictionary(); // Gets slow elements. |
1219 | 1219 |
1220 // Collects elements starting at index 0. | 1220 // Collects elements starting at index 0. |
1221 // Undefined values are placed after non-undefined values. | 1221 // Undefined values are placed after non-undefined values. |
1222 // Returns the number of non-undefined values. | 1222 // Returns the number of non-undefined values. |
1223 Object* PrepareElementsForSort(uint32_t limit); | 1223 Object* PrepareElementsForSort(uint32_t limit); |
1224 // As PrepareElementsForSort, but only on objects where elements is | 1224 // As PrepareElementsForSort, but only on objects where elements is |
1225 // a dictionary, and it will stay a dictionary. | 1225 // a dictionary, and it will stay a dictionary. |
1226 Object* PrepareSlowElementsForSort(uint32_t limit); | 1226 Object* PrepareSlowElementsForSort(uint32_t limit); |
1227 | 1227 |
1228 Object* SetProperty(String* key, | 1228 Object* SetProperty(String* key, |
(...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1868 // that uses open addressing and quadratic probing. | 1868 // that uses open addressing and quadratic probing. |
1869 // | 1869 // |
1870 // In order for the quadratic probing to work, elements that have not | 1870 // In order for the quadratic probing to work, elements that have not |
1871 // yet been used and elements that have been deleted are | 1871 // yet been used and elements that have been deleted are |
1872 // distinguished. Probing continues when deleted elements are | 1872 // distinguished. Probing continues when deleted elements are |
1873 // encountered and stops when unused elements are encountered. | 1873 // encountered and stops when unused elements are encountered. |
1874 // | 1874 // |
1875 // - Elements with key == undefined have not been used yet. | 1875 // - Elements with key == undefined have not been used yet. |
1876 // - Elements with key == null have been deleted. | 1876 // - Elements with key == null have been deleted. |
1877 // | 1877 // |
1878 // The hash table class is parameterized with a prefix size and with | 1878 // The hash table class is parameterized with a Shape and a Key. |
1879 // the size, including the key size, of the elements held in the hash | 1879 // Shape must be a class with the following interface: |
| 1880 // class ExampleShape { |
| 1881 // public: |
| 1882 // // Tells whether key matches other. |
| 1883 // static bool IsMatch(Key key, Object* other); |
| 1884 // // Returns the hash value for key. |
| 1885 // static uint32_t Hash(Key key); |
| 1886 // // Returns the hash value for object. |
| 1887 // static uint32_t HashForObject(Key key, Object* object); |
| 1888 // // Convert key to an object. |
| 1889 // static inline Object* AsObject(Key key); |
| 1890 // // The prefix size indicates number of elements in the beginning |
| 1891 // // of the backing storage. |
| 1892 // static const int kPrefixSize = ..; |
| 1893 // // The Element size indicates number of elements per entry. |
| 1894 // static const int kEntrySize = ..; |
| 1895 // }; |
1880 // table. The prefix size indicates an amount of memory in the | 1896 // table. The prefix size indicates an amount of memory in the |
1881 // beginning of the backing storage that can be used for non-element | 1897 // beginning of the backing storage that can be used for non-element |
1882 // information by subclasses. | 1898 // information by subclasses. |
1883 | 1899 |
1884 // HashTableKey is an abstract superclass keys. | 1900 template<typename Shape, typename Key> |
1885 class HashTableKey { | |
1886 public: | |
1887 // Returns whether the other object matches this key. | |
1888 virtual bool IsMatch(Object* other) = 0; | |
1889 typedef uint32_t (*HashFunction)(Object* obj); | |
1890 // Returns the hash function used for this key. | |
1891 virtual HashFunction GetHashFunction() = 0; | |
1892 // Returns the hash value for this key. | |
1893 virtual uint32_t Hash() = 0; | |
1894 // Returns the key object for storing into the dictionary. | |
1895 // If allocations fails a failure object is returned. | |
1896 virtual Object* GetObject() = 0; | |
1897 virtual bool IsStringKey() = 0; | |
1898 // Required. | |
1899 virtual ~HashTableKey() {} | |
1900 }; | |
1901 | |
1902 | |
1903 template<int prefix_size, int element_size> | |
1904 class HashTable: public FixedArray { | 1901 class HashTable: public FixedArray { |
1905 public: | 1902 public: |
1906 // Returns the number of elements in the dictionary. | 1903 // Returns the number of elements in the dictionary. |
1907 int NumberOfElements() { | 1904 int NumberOfElements() { |
1908 return Smi::cast(get(kNumberOfElementsIndex))->value(); | 1905 return Smi::cast(get(kNumberOfElementsIndex))->value(); |
1909 } | 1906 } |
1910 | 1907 |
1911 // Returns the capacity of the dictionary. | 1908 // Returns the capacity of the dictionary. |
1912 int Capacity() { | 1909 int Capacity() { |
1913 return Smi::cast(get(kCapacityIndex))->value(); | 1910 return Smi::cast(get(kCapacityIndex))->value(); |
(...skipping 28 matching lines...) Expand all Loading... |
1942 static inline HashTable* cast(Object* obj); | 1939 static inline HashTable* cast(Object* obj); |
1943 | 1940 |
1944 // Compute the probe offset (quadratic probing). | 1941 // Compute the probe offset (quadratic probing). |
1945 INLINE(static uint32_t GetProbeOffset(uint32_t n)) { | 1942 INLINE(static uint32_t GetProbeOffset(uint32_t n)) { |
1946 return (n + n * n) >> 1; | 1943 return (n + n * n) >> 1; |
1947 } | 1944 } |
1948 | 1945 |
1949 static const int kNumberOfElementsIndex = 0; | 1946 static const int kNumberOfElementsIndex = 0; |
1950 static const int kCapacityIndex = 1; | 1947 static const int kCapacityIndex = 1; |
1951 static const int kPrefixStartIndex = 2; | 1948 static const int kPrefixStartIndex = 2; |
1952 static const int kElementsStartIndex = kPrefixStartIndex + prefix_size; | 1949 static const int kElementsStartIndex = |
1953 static const int kElementSize = element_size; | 1950 kPrefixStartIndex + Shape::kPrefixSize; |
| 1951 static const int kEntrySize = Shape::kEntrySize; |
1954 static const int kElementsStartOffset = | 1952 static const int kElementsStartOffset = |
1955 kHeaderSize + kElementsStartIndex * kPointerSize; | 1953 kHeaderSize + kElementsStartIndex * kPointerSize; |
1956 | 1954 |
1957 // Constant used for denoting a absent entry. | 1955 // Constant used for denoting a absent entry. |
1958 static const int kNotFound = -1; | 1956 static const int kNotFound = -1; |
1959 | 1957 |
| 1958 // Find entry for key otherwise return -1. |
| 1959 int FindEntry(Key key); |
| 1960 |
1960 protected: | 1961 protected: |
1961 // Find entry for key otherwise return -1. | |
1962 int FindEntry(HashTableKey* key); | |
1963 | 1962 |
1964 // Find the entry at which to insert element with the given key that | 1963 // Find the entry at which to insert element with the given key that |
1965 // has the given hash value. | 1964 // has the given hash value. |
1966 uint32_t FindInsertionEntry(Object* key, uint32_t hash); | 1965 uint32_t FindInsertionEntry(uint32_t hash); |
1967 | 1966 |
1968 // Returns the index for an entry (of the key) | 1967 // Returns the index for an entry (of the key) |
1969 static inline int EntryToIndex(int entry) { | 1968 static inline int EntryToIndex(int entry) { |
1970 return (entry * kElementSize) + kElementsStartIndex; | 1969 return (entry * kEntrySize) + kElementsStartIndex; |
1971 } | 1970 } |
1972 | 1971 |
1973 // Update the number of elements in the dictionary. | 1972 // Update the number of elements in the dictionary. |
1974 void SetNumberOfElements(int nof) { | 1973 void SetNumberOfElements(int nof) { |
1975 fast_set(this, kNumberOfElementsIndex, Smi::FromInt(nof)); | 1974 fast_set(this, kNumberOfElementsIndex, Smi::FromInt(nof)); |
1976 } | 1975 } |
1977 | 1976 |
1978 // Sets the capacity of the hash table. | 1977 // Sets the capacity of the hash table. |
1979 void SetCapacity(int capacity) { | 1978 void SetCapacity(int capacity) { |
1980 // To scale a computed hash code to fit within the hash table, we | 1979 // To scale a computed hash code to fit within the hash table, we |
1981 // use bit-wise AND with a mask, so the capacity must be positive | 1980 // use bit-wise AND with a mask, so the capacity must be positive |
1982 // and non-zero. | 1981 // and non-zero. |
1983 ASSERT(capacity > 0); | 1982 ASSERT(capacity > 0); |
1984 fast_set(this, kCapacityIndex, Smi::FromInt(capacity)); | 1983 fast_set(this, kCapacityIndex, Smi::FromInt(capacity)); |
1985 } | 1984 } |
1986 | 1985 |
1987 | 1986 |
1988 // Returns probe entry. | 1987 // Returns probe entry. |
1989 static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) { | 1988 static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) { |
1990 ASSERT(IsPowerOf2(size)); | 1989 ASSERT(IsPowerOf2(size)); |
1991 return (hash + GetProbeOffset(number)) & (size - 1); | 1990 return (hash + GetProbeOffset(number)) & (size - 1); |
1992 } | 1991 } |
1993 | 1992 |
1994 // Ensure enough space for n additional elements. | 1993 // Ensure enough space for n additional elements. |
1995 Object* EnsureCapacity(int n, HashTableKey* key); | 1994 Object* EnsureCapacity(int n, Key key); |
1996 }; | 1995 }; |
1997 | 1996 |
1998 | 1997 |
| 1998 |
| 1999 // HashTableKey is an abstract superclass for virtual key behavior. |
| 2000 class HashTableKey { |
| 2001 public: |
| 2002 // Returns whether the other object matches this key. |
| 2003 virtual bool IsMatch(Object* other) = 0; |
| 2004 // Returns the hash value for this key. |
| 2005 virtual uint32_t Hash() = 0; |
| 2006 // Returns the hash value for object. |
| 2007 virtual uint32_t HashForObject(Object* key) = 0; |
| 2008 // Returns the key object for storing into the dictionary. |
| 2009 // If allocations fails a failure object is returned. |
| 2010 virtual Object* AsObject() = 0; |
| 2011 // Required. |
| 2012 virtual ~HashTableKey() {} |
| 2013 }; |
| 2014 |
| 2015 class SymbolTableShape { |
| 2016 public: |
| 2017 static bool IsMatch(HashTableKey* key, Object* value) { |
| 2018 return key->IsMatch(value); |
| 2019 } |
| 2020 static uint32_t Hash(HashTableKey* key) { |
| 2021 return key->Hash(); |
| 2022 } |
| 2023 static uint32_t HashForObject(HashTableKey* key, Object* object) { |
| 2024 return key->HashForObject(object); |
| 2025 } |
| 2026 static Object* AsObject(HashTableKey* key) { |
| 2027 return key->AsObject(); |
| 2028 } |
| 2029 |
| 2030 static const int kPrefixSize = 0; |
| 2031 static const int kEntrySize = 1; |
| 2032 }; |
| 2033 |
1999 // SymbolTable. | 2034 // SymbolTable. |
2000 // | 2035 // |
2001 // No special elements in the prefix and the element size is 1 | 2036 // No special elements in the prefix and the element size is 1 |
2002 // because only the symbol itself (the key) needs to be stored. | 2037 // because only the symbol itself (the key) needs to be stored. |
2003 class SymbolTable: public HashTable<0, 1> { | 2038 class SymbolTable: public HashTable<SymbolTableShape, HashTableKey*> { |
2004 public: | 2039 public: |
2005 // Find symbol in the symbol table. If it is not there yet, it is | 2040 // Find symbol in the symbol table. If it is not there yet, it is |
2006 // added. The return value is the symbol table which might have | 2041 // added. The return value is the symbol table which might have |
2007 // been enlarged. If the return value is not a failure, the symbol | 2042 // been enlarged. If the return value is not a failure, the symbol |
2008 // pointer *s is set to the symbol found. | 2043 // pointer *s is set to the symbol found. |
2009 Object* LookupSymbol(Vector<const char> str, Object** s); | 2044 Object* LookupSymbol(Vector<const char> str, Object** s); |
2010 Object* LookupString(String* key, Object** s); | 2045 Object* LookupString(String* key, Object** s); |
2011 | 2046 |
2012 // Looks up a symbol that is equal to the given string and returns | 2047 // Looks up a symbol that is equal to the given string and returns |
2013 // true if it is found, assigning the symbol to the given output | 2048 // true if it is found, assigning the symbol to the given output |
2014 // parameter. | 2049 // parameter. |
2015 bool LookupSymbolIfExists(String* str, String** symbol); | 2050 bool LookupSymbolIfExists(String* str, String** symbol); |
2016 | 2051 |
2017 // Casting. | 2052 // Casting. |
2018 static inline SymbolTable* cast(Object* obj); | 2053 static inline SymbolTable* cast(Object* obj); |
2019 | 2054 |
2020 private: | 2055 private: |
2021 Object* LookupKey(HashTableKey* key, Object** s); | 2056 Object* LookupKey(HashTableKey* key, Object** s); |
2022 | 2057 |
2023 DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolTable); | 2058 DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolTable); |
2024 }; | 2059 }; |
2025 | 2060 |
2026 | 2061 |
| 2062 class MapCacheShape { |
| 2063 public: |
| 2064 static bool IsMatch(HashTableKey* key, Object* value) { |
| 2065 return key->IsMatch(value); |
| 2066 } |
| 2067 static uint32_t Hash(HashTableKey* key) { |
| 2068 return key->Hash(); |
| 2069 } |
| 2070 |
| 2071 static uint32_t HashForObject(HashTableKey* key, Object* object) { |
| 2072 return key->HashForObject(object); |
| 2073 } |
| 2074 |
| 2075 static Object* AsObject(HashTableKey* key) { |
| 2076 return key->AsObject(); |
| 2077 } |
| 2078 |
| 2079 static const int kPrefixSize = 0; |
| 2080 static const int kEntrySize = 2; |
| 2081 }; |
| 2082 |
| 2083 |
2027 // MapCache. | 2084 // MapCache. |
2028 // | 2085 // |
2029 // Maps keys that are a fixed array of symbols to a map. | 2086 // Maps keys that are a fixed array of symbols to a map. |
2030 // Used for canonicalize maps for object literals. | 2087 // Used for canonicalize maps for object literals. |
2031 class MapCache: public HashTable<0, 2> { | 2088 class MapCache: public HashTable<MapCacheShape, HashTableKey*> { |
2032 public: | 2089 public: |
2033 // Find cached value for a string key, otherwise return null. | 2090 // Find cached value for a string key, otherwise return null. |
2034 Object* Lookup(FixedArray* key); | 2091 Object* Lookup(FixedArray* key); |
2035 Object* Put(FixedArray* key, Map* value); | 2092 Object* Put(FixedArray* key, Map* value); |
2036 static inline MapCache* cast(Object* obj); | 2093 static inline MapCache* cast(Object* obj); |
2037 | 2094 |
2038 private: | 2095 private: |
2039 DISALLOW_IMPLICIT_CONSTRUCTORS(MapCache); | 2096 DISALLOW_IMPLICIT_CONSTRUCTORS(MapCache); |
2040 }; | 2097 }; |
2041 | 2098 |
2042 | 2099 |
2043 // Dictionary for keeping properties and elements in slow case. | 2100 template <typename Shape, typename Key> |
2044 // | 2101 class Dictionary: public HashTable<Shape, Key> { |
2045 // One element in the prefix is used for storing non-element | 2102 public: |
2046 // information about the dictionary. | |
2047 // | |
2048 // The rest of the array embeds triples of (key, value, details). | |
2049 // if key == undefined the triple is empty. | |
2050 // if key == null the triple has been deleted. | |
2051 // otherwise key contains the name of a property. | |
2052 class DictionaryBase: public HashTable<2, 3> {}; | |
2053 | 2103 |
2054 class Dictionary: public DictionaryBase { | 2104 static inline Dictionary<Shape, Key>* cast(Object* obj) { |
2055 public: | 2105 return reinterpret_cast<Dictionary<Shape, Key>*>(obj); |
| 2106 } |
| 2107 |
2056 // Returns the value at entry. | 2108 // Returns the value at entry. |
2057 Object* ValueAt(int entry) { | 2109 Object* ValueAt(int entry) { |
2058 return get(EntryToIndex(entry)+1); | 2110 return get(HashTable<Shape, Key>::EntryToIndex(entry)+1); |
2059 } | 2111 } |
2060 | 2112 |
2061 // Set the value for entry. | 2113 // Set the value for entry. |
2062 void ValueAtPut(int entry, Object* value) { | 2114 void ValueAtPut(int entry, Object* value) { |
2063 set(EntryToIndex(entry)+1, value); | 2115 set(HashTable<Shape, Key>::EntryToIndex(entry)+1, value); |
2064 } | 2116 } |
2065 | 2117 |
2066 // Returns the property details for the property at entry. | 2118 // Returns the property details for the property at entry. |
2067 PropertyDetails DetailsAt(int entry) { | 2119 PropertyDetails DetailsAt(int entry) { |
2068 ASSERT(entry >= 0); // Not found is -1, which is not caught by get(). | 2120 ASSERT(entry >= 0); // Not found is -1, which is not caught by get(). |
2069 return PropertyDetails(Smi::cast(get(EntryToIndex(entry) + 2))); | 2121 return PropertyDetails( |
| 2122 Smi::cast(get(HashTable<Shape, Key>::EntryToIndex(entry) + 2))); |
2070 } | 2123 } |
2071 | 2124 |
2072 // Set the details for entry. | 2125 // Set the details for entry. |
2073 void DetailsAtPut(int entry, PropertyDetails value) { | 2126 void DetailsAtPut(int entry, PropertyDetails value) { |
2074 set(EntryToIndex(entry) + 2, value.AsSmi()); | 2127 set(HashTable<Shape, Key>::EntryToIndex(entry) + 2, value.AsSmi()); |
2075 } | 2128 } |
2076 | 2129 |
2077 // Remove all entries were key is a number and (from <= key && key < to). | |
2078 void RemoveNumberEntries(uint32_t from, uint32_t to); | |
2079 | |
2080 // Sorting support | 2130 // Sorting support |
2081 void CopyValuesTo(FixedArray* elements); | 2131 void CopyValuesTo(FixedArray* elements); |
2082 | 2132 |
2083 // Casting. | |
2084 static inline Dictionary* cast(Object* obj); | |
2085 | |
2086 // Find entry for string key otherwise return -1. | |
2087 int FindStringEntry(String* key); | |
2088 | |
2089 // Find entry for number key otherwise return -1. | |
2090 int FindNumberEntry(uint32_t index); | |
2091 | |
2092 // Delete a property from the dictionary. | 2133 // Delete a property from the dictionary. |
2093 Object* DeleteProperty(int entry, JSObject::DeleteMode mode); | 2134 Object* DeleteProperty(int entry, JSObject::DeleteMode mode); |
2094 | 2135 |
2095 // Type specific at put (default NONE attributes is used when adding). | |
2096 Object* AtNumberPut(uint32_t key, Object* value); | |
2097 | |
2098 Object* AddStringEntry(String* key, Object* value, PropertyDetails details); | |
2099 Object* AddNumberEntry(uint32_t key, Object* value, PropertyDetails details); | |
2100 | |
2101 // Set an existing entry or add a new one if needed. | |
2102 Object* SetStringEntry(int entry, | |
2103 String* key, | |
2104 Object* value, | |
2105 PropertyDetails details); | |
2106 | |
2107 Object* SetOrAddNumberEntry(uint32_t key, | |
2108 Object* value, | |
2109 PropertyDetails details); | |
2110 | |
2111 // Returns the number of elements in the dictionary filtering out properties | 2136 // Returns the number of elements in the dictionary filtering out properties |
2112 // with the specified attributes. | 2137 // with the specified attributes. |
2113 int NumberOfElementsFilterAttributes(PropertyAttributes filter); | 2138 int NumberOfElementsFilterAttributes(PropertyAttributes filter); |
2114 | 2139 |
2115 // Returns the number of enumerable elements in the dictionary. | 2140 // Returns the number of enumerable elements in the dictionary. |
2116 int NumberOfEnumElements(); | 2141 int NumberOfEnumElements(); |
2117 | 2142 |
2118 // Copies keys to preallocated fixed array. | 2143 // Copies keys to preallocated fixed array. |
2119 void CopyKeysTo(FixedArray* storage, PropertyAttributes filter); | 2144 void CopyKeysTo(FixedArray* storage, PropertyAttributes filter); |
2120 // Copies enumerable keys to preallocated fixed array. | |
2121 void CopyEnumKeysTo(FixedArray* storage, FixedArray* sort_array); | |
2122 // Fill in details for properties into storage. | 2145 // Fill in details for properties into storage. |
2123 void CopyKeysTo(FixedArray* storage); | 2146 void CopyKeysTo(FixedArray* storage); |
2124 | 2147 |
2125 // For transforming properties of a JSObject. | |
2126 Object* TransformPropertiesToFastFor(JSObject* obj, | |
2127 int unused_property_fields); | |
2128 | |
2129 // If slow elements are required we will never go back to fast-case | |
2130 // for the elements kept in this dictionary. We require slow | |
2131 // elements if an element has been added at an index larger than | |
2132 // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called | |
2133 // when defining a getter or setter with a number key. | |
2134 inline bool requires_slow_elements(); | |
2135 inline void set_requires_slow_elements(); | |
2136 | |
2137 // Get the value of the max number key that has been added to this | |
2138 // dictionary. max_number_key can only be called if | |
2139 // requires_slow_elements returns false. | |
2140 inline uint32_t max_number_key(); | |
2141 | |
2142 // Accessors for next enumeration index. | 2148 // Accessors for next enumeration index. |
2143 void SetNextEnumerationIndex(int index) { | 2149 void SetNextEnumerationIndex(int index) { |
2144 fast_set(this, kNextEnumerationIndexIndex, Smi::FromInt(index)); | 2150 fast_set(this, kNextEnumerationIndexIndex, Smi::FromInt(index)); |
2145 } | 2151 } |
2146 | 2152 |
2147 int NextEnumerationIndex() { | 2153 int NextEnumerationIndex() { |
2148 return Smi::cast(get(kNextEnumerationIndexIndex))->value(); | 2154 return Smi::cast(FixedArray::get(kNextEnumerationIndexIndex))->value(); |
2149 } | 2155 } |
2150 | 2156 |
2151 // Returns a new array for dictionary usage. Might return Failure. | 2157 // Returns a new array for dictionary usage. Might return Failure. |
2152 static Object* Allocate(int at_least_space_for); | 2158 static Object* Allocate(int at_least_space_for); |
2153 | 2159 |
2154 // Ensure enough space for n additional elements. | 2160 // Ensure enough space for n additional elements. |
2155 Object* EnsureCapacity(int n, HashTableKey* key); | 2161 Object* EnsureCapacity(int n, Key key); |
2156 | 2162 |
2157 #ifdef DEBUG | 2163 #ifdef DEBUG |
2158 void Print(); | 2164 void Print(); |
2159 #endif | 2165 #endif |
2160 // Returns the key (slow). | 2166 // Returns the key (slow). |
2161 Object* SlowReverseLookup(Object* value); | 2167 Object* SlowReverseLookup(Object* value); |
2162 | 2168 |
2163 // Bit masks. | |
2164 static const int kRequiresSlowElementsMask = 1; | |
2165 static const int kRequiresSlowElementsTagSize = 1; | |
2166 static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1; | |
2167 | |
2168 void UpdateMaxNumberKey(uint32_t key); | |
2169 | |
2170 private: | |
2171 // Generic at put operation. | |
2172 Object* AtPut(HashTableKey* key, Object* value); | |
2173 | |
2174 Object* Add(HashTableKey* key, Object* value, PropertyDetails details); | |
2175 | |
2176 // Add entry to dictionary. | |
2177 void AddEntry(Object* key, | |
2178 Object* value, | |
2179 PropertyDetails details, | |
2180 uint32_t hash); | |
2181 | |
2182 // Sets the entry to (key, value) pair. | 2169 // Sets the entry to (key, value) pair. |
2183 inline void SetEntry(int entry, | 2170 inline void SetEntry(int entry, |
2184 Object* key, | 2171 Object* key, |
2185 Object* value, | 2172 Object* value, |
2186 PropertyDetails details); | 2173 PropertyDetails details); |
2187 | 2174 |
| 2175 Object* Add(Key key, Object* value, PropertyDetails details); |
| 2176 |
| 2177 protected: |
| 2178 // Generic at put operation. |
| 2179 Object* AtPut(Key key, Object* value); |
| 2180 |
| 2181 // Add entry to dictionary. |
| 2182 Object* AddEntry(Key key, |
| 2183 Object* value, |
| 2184 PropertyDetails details, |
| 2185 uint32_t hash); |
| 2186 |
2188 // Generate new enumeration indices to avoid enumeration index overflow. | 2187 // Generate new enumeration indices to avoid enumeration index overflow. |
2189 Object* GenerateNewEnumerationIndices(); | 2188 Object* GenerateNewEnumerationIndices(); |
| 2189 static const int kMaxNumberKeyIndex = |
| 2190 HashTable<Shape, Key>::kPrefixStartIndex; |
| 2191 static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1; |
| 2192 }; |
2190 | 2193 |
2191 static const int kMaxNumberKeyIndex = kPrefixStartIndex; | |
2192 static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1; | |
2193 | 2194 |
2194 DISALLOW_IMPLICIT_CONSTRUCTORS(Dictionary); | 2195 class StringDictionaryShape { |
| 2196 public: |
| 2197 static inline bool IsMatch(String* key, Object* other); |
| 2198 static inline uint32_t Hash(String* key); |
| 2199 static inline uint32_t HashForObject(String* key, Object* object); |
| 2200 static inline Object* AsObject(String* key); |
| 2201 static const int kPrefixSize = 2; |
| 2202 static const int kEntrySize = 3; |
| 2203 static const bool kIsEnumerable = true; |
| 2204 }; |
| 2205 |
| 2206 |
| 2207 class StringDictionary: public Dictionary<StringDictionaryShape, String*> { |
| 2208 public: |
| 2209 static inline StringDictionary* cast(Object* obj) { |
| 2210 ASSERT(obj->IsDictionary()); |
| 2211 return reinterpret_cast<StringDictionary*>(obj); |
| 2212 } |
| 2213 |
| 2214 // Copies enumerable keys to preallocated fixed array. |
| 2215 void CopyEnumKeysTo(FixedArray* storage, FixedArray* sort_array); |
| 2216 |
| 2217 // For transforming properties of a JSObject. |
| 2218 Object* TransformPropertiesToFastFor(JSObject* obj, |
| 2219 int unused_property_fields); |
| 2220 }; |
| 2221 |
| 2222 |
| 2223 class NumberDictionaryShape { |
| 2224 public: |
| 2225 static inline bool IsMatch(uint32_t key, Object* other); |
| 2226 static inline uint32_t Hash(uint32_t key); |
| 2227 static inline uint32_t HashForObject(uint32_t key, Object* object); |
| 2228 static inline Object* AsObject(uint32_t key); |
| 2229 static const int kPrefixSize = 2; |
| 2230 static const int kEntrySize = 3; |
| 2231 static const bool kIsEnumerable = false; |
| 2232 }; |
| 2233 |
| 2234 |
| 2235 class NumberDictionary: public Dictionary<NumberDictionaryShape, uint32_t> { |
| 2236 public: |
| 2237 static NumberDictionary* cast(Object* obj) { |
| 2238 ASSERT(obj->IsDictionary()); |
| 2239 return reinterpret_cast<NumberDictionary*>(obj); |
| 2240 } |
| 2241 |
| 2242 // Type specific at put (default NONE attributes is used when adding). |
| 2243 Object* AtNumberPut(uint32_t key, Object* value); |
| 2244 Object* AddNumberEntry(uint32_t key, |
| 2245 Object* value, |
| 2246 PropertyDetails details); |
| 2247 |
| 2248 // Set an existing entry or add a new one if needed. |
| 2249 Object* Set(uint32_t key, Object* value, PropertyDetails details); |
| 2250 |
| 2251 void UpdateMaxNumberKey(uint32_t key); |
| 2252 |
| 2253 // If slow elements are required we will never go back to fast-case |
| 2254 // for the elements kept in this dictionary. We require slow |
| 2255 // elements if an element has been added at an index larger than |
| 2256 // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called |
| 2257 // when defining a getter or setter with a number key. |
| 2258 inline bool requires_slow_elements(); |
| 2259 inline void set_requires_slow_elements(); |
| 2260 |
| 2261 // Get the value of the max number key that has been added to this |
| 2262 // dictionary. max_number_key can only be called if |
| 2263 // requires_slow_elements returns false. |
| 2264 inline uint32_t max_number_key(); |
| 2265 |
| 2266 // Remove all entries were key is a number and (from <= key && key < to). |
| 2267 void RemoveNumberEntries(uint32_t from, uint32_t to); |
| 2268 |
| 2269 // Bit masks. |
| 2270 static const int kRequiresSlowElementsMask = 1; |
| 2271 static const int kRequiresSlowElementsTagSize = 1; |
| 2272 static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1; |
2195 }; | 2273 }; |
2196 | 2274 |
2197 | 2275 |
2198 // ByteArray represents fixed sized byte arrays. Used by the outside world, | 2276 // ByteArray represents fixed sized byte arrays. Used by the outside world, |
2199 // such as PCRE, and also by the memory allocator and garbage collector to | 2277 // such as PCRE, and also by the memory allocator and garbage collector to |
2200 // fill in free blocks in the heap. | 2278 // fill in free blocks in the heap. |
2201 class ByteArray: public Array { | 2279 class ByteArray: public Array { |
2202 public: | 2280 public: |
2203 // Setter and getter. | 2281 // Setter and getter. |
2204 inline byte get(int index); | 2282 inline byte get(int index); |
(...skipping 1019 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3224 // Maximal number of registers used by either ASCII or UC16. | 3302 // Maximal number of registers used by either ASCII or UC16. |
3225 // Only used to check that there is enough stack space | 3303 // Only used to check that there is enough stack space |
3226 static const int kIrregexpMaxRegisterCountIndex = kDataIndex + 2; | 3304 static const int kIrregexpMaxRegisterCountIndex = kDataIndex + 2; |
3227 // Number of captures in the compiled regexp. | 3305 // Number of captures in the compiled regexp. |
3228 static const int kIrregexpCaptureCountIndex = kDataIndex + 3; | 3306 static const int kIrregexpCaptureCountIndex = kDataIndex + 3; |
3229 | 3307 |
3230 static const int kIrregexpDataSize = kIrregexpCaptureCountIndex + 1; | 3308 static const int kIrregexpDataSize = kIrregexpCaptureCountIndex + 1; |
3231 }; | 3309 }; |
3232 | 3310 |
3233 | 3311 |
3234 class CompilationCacheTable: public HashTable<0, 2> { | 3312 class CompilationCacheShape { |
| 3313 public: |
| 3314 static inline bool IsMatch(HashTableKey* key, Object* value) { |
| 3315 return key->IsMatch(value); |
| 3316 } |
| 3317 |
| 3318 static inline uint32_t Hash(HashTableKey* key) { |
| 3319 return key->Hash(); |
| 3320 } |
| 3321 |
| 3322 static inline uint32_t HashForObject(HashTableKey* key, Object* object) { |
| 3323 return key->HashForObject(object); |
| 3324 } |
| 3325 |
| 3326 static Object* AsObject(HashTableKey* key) { |
| 3327 return key->AsObject(); |
| 3328 } |
| 3329 |
| 3330 static const int kPrefixSize = 0; |
| 3331 static const int kEntrySize = 2; |
| 3332 }; |
| 3333 |
| 3334 class CompilationCacheTable: public HashTable<CompilationCacheShape, |
| 3335 HashTableKey*> { |
3235 public: | 3336 public: |
3236 // Find cached value for a string key, otherwise return null. | 3337 // Find cached value for a string key, otherwise return null. |
3237 Object* Lookup(String* src); | 3338 Object* Lookup(String* src); |
3238 Object* LookupEval(String* src, Context* context); | 3339 Object* LookupEval(String* src, Context* context); |
3239 Object* LookupRegExp(String* source, JSRegExp::Flags flags); | 3340 Object* LookupRegExp(String* source, JSRegExp::Flags flags); |
3240 Object* Put(String* src, Object* value); | 3341 Object* Put(String* src, Object* value); |
3241 Object* PutEval(String* src, Context* context, Object* value); | 3342 Object* PutEval(String* src, Context* context, Object* value); |
3242 Object* PutRegExp(String* src, JSRegExp::Flags flags, FixedArray* value); | 3343 Object* PutRegExp(String* src, JSRegExp::Flags flags, FixedArray* value); |
3243 | 3344 |
3244 static inline CompilationCacheTable* cast(Object* obj); | 3345 static inline CompilationCacheTable* cast(Object* obj); |
(...skipping 1270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4515 } else { | 4616 } else { |
4516 value &= ~(1 << bit_position); | 4617 value &= ~(1 << bit_position); |
4517 } | 4618 } |
4518 return value; | 4619 return value; |
4519 } | 4620 } |
4520 }; | 4621 }; |
4521 | 4622 |
4522 } } // namespace v8::internal | 4623 } } // namespace v8::internal |
4523 | 4624 |
4524 #endif // V8_OBJECTS_H_ | 4625 #endif // V8_OBJECTS_H_ |
OLD | NEW |