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