Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 85 // - FixedArrayBase | 85 // - FixedArrayBase |
| 86 // - ByteArray | 86 // - ByteArray |
| 87 // - FixedArray | 87 // - FixedArray |
| 88 // - DescriptorArray | 88 // - DescriptorArray |
| 89 // - HashTable | 89 // - HashTable |
| 90 // - Dictionary | 90 // - Dictionary |
| 91 // - StringTable | 91 // - StringTable |
| 92 // - CompilationCacheTable | 92 // - CompilationCacheTable |
| 93 // - CodeCacheHashTable | 93 // - CodeCacheHashTable |
| 94 // - MapCache | 94 // - MapCache |
| 95 // - OrderedHashTable | |
| 96 // - OrderedHashSet | |
| 97 // - OrderedHashMap | |
| 95 // - Context | 98 // - Context |
| 96 // - JSFunctionResultCache | 99 // - JSFunctionResultCache |
| 97 // - ScopeInfo | 100 // - ScopeInfo |
| 98 // - TransitionArray | 101 // - TransitionArray |
| 99 // - FixedDoubleArray | 102 // - FixedDoubleArray |
| 100 // - ExternalArray | 103 // - ExternalArray |
| 101 // - ExternalUint8ClampedArray | 104 // - ExternalUint8ClampedArray |
| 102 // - ExternalInt8Array | 105 // - ExternalInt8Array |
| 103 // - ExternalUint8Array | 106 // - ExternalUint8Array |
| 104 // - ExternalInt16Array | 107 // - ExternalInt16Array |
| (...skipping 4137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4242 void AddEntry(int entry, Object* key, Object* value); | 4245 void AddEntry(int entry, Object* key, Object* value); |
| 4243 void RemoveEntry(int entry); | 4246 void RemoveEntry(int entry); |
| 4244 | 4247 |
| 4245 // Returns the index to the value of an entry. | 4248 // Returns the index to the value of an entry. |
| 4246 static inline int EntryToValueIndex(int entry) { | 4249 static inline int EntryToValueIndex(int entry) { |
| 4247 return EntryToIndex(entry) + 1; | 4250 return EntryToIndex(entry) + 1; |
| 4248 } | 4251 } |
| 4249 }; | 4252 }; |
| 4250 | 4253 |
| 4251 | 4254 |
| 4255 // OrderedHashTable is a HashTable with Object keys that preserves | |
| 4256 // insertion order. There are Map and Set interfaces (OrderedHashMap | |
| 4257 // and OrderedHashTable, below). It is meant to be used by JSMap/JSSet. | |
| 4258 // | |
| 4259 // Only Object* keys are supported, with Object::SameValue() used as the | |
|
arv (Not doing code reviews)
2014/04/07 00:01:21
ES6 Map/Set uses SameValueZero (which treats -0 an
| |
| 4260 // equality operator and Object::GetHash() for the hash function. | |
| 4261 // | |
| 4262 // Based on the "Deterministic Hash Table" as described by Jason Orendorff at | |
| 4263 // https://wiki.mozilla.org/User:Jorend/Deterministic_hash_tables | |
| 4264 // Originally attributed to Tyler Close. | |
| 4265 // | |
| 4266 // Memory layout: | |
| 4267 // [0]: bucket count | |
| 4268 // [1]: element count | |
| 4269 // [2]: deleted element count | |
| 4270 // [3..(NumberOfBuckets() - 1)]: "hash table", where each item is an offset | |
| 4271 // into the data table (see below) where the | |
| 4272 // first item in this bucket is stored. | |
| 4273 // [3 + NumberOfBuckets()..length]: "data table", an array of length | |
| 4274 // Capacity() * kEntrySize, where the first entrysize | |
| 4275 // items are handled by the derived class and the | |
| 4276 // item at kChainOffset is another entry into the | |
| 4277 // data table indicating the next entry in this hash | |
| 4278 // bucket. | |
| 4279 template<class Derived, int entrysize> | |
| 4280 class OrderedHashTable: public FixedArray { | |
| 4281 public: | |
| 4282 // Returns an OrderedHashTable with a capacity of at least |capacity|. | |
| 4283 static Handle<Derived> Allocate( | |
| 4284 Isolate* isolate, int capacity, PretenureFlag pretenure = NOT_TENURED); | |
| 4285 | |
| 4286 // Returns an OrderedHashTable (possibly |table|) with enough space | |
| 4287 // to add at least one new element, or returns a Failure if a GC occurs. | |
| 4288 static Handle<Derived> EnsureGrowable(Handle<Derived> table); | |
| 4289 | |
| 4290 // Returns an OrderedHashTable (possibly |table|) that's shrunken | |
| 4291 // if possible. | |
| 4292 static Handle<Derived> Shrink(Handle<Derived> table); | |
| 4293 | |
| 4294 // Returns kNotFound if the key isn't present. | |
| 4295 int FindEntry(Object* key); | |
| 4296 | |
| 4297 int NumberOfElements() { | |
| 4298 return Smi::cast(get(kNumberOfElementsIndex))->value(); | |
| 4299 } | |
| 4300 | |
| 4301 int NumberOfDeletedElements() { | |
| 4302 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value(); | |
| 4303 } | |
| 4304 | |
| 4305 int NumberOfBuckets() { | |
| 4306 return Smi::cast(get(kNumberOfBucketsIndex))->value(); | |
| 4307 } | |
| 4308 | |
| 4309 // Returns the index into the data table where the new entry | |
| 4310 // should be placed. The table is assumed to have enough space | |
| 4311 // for a new entry. | |
| 4312 int AddEntry(int hash); | |
| 4313 | |
| 4314 // Removes the entry, and puts the_hole in entrysize pointers | |
| 4315 // (leaving the hash table chain intact). | |
| 4316 void RemoveEntry(int entry); | |
| 4317 | |
| 4318 // Returns an index into |this| for the given entry. | |
| 4319 int EntryToIndex(int entry) { | |
| 4320 return kHashTableStartIndex + NumberOfBuckets() + (entry * kEntrySize); | |
| 4321 } | |
| 4322 | |
| 4323 static const int kNotFound = -1; | |
| 4324 | |
| 4325 private: | |
| 4326 static Handle<Derived> Rehash(Handle<Derived> table, int new_capacity); | |
| 4327 | |
| 4328 void SetNumberOfBuckets(int num) { | |
| 4329 set(kNumberOfBucketsIndex, Smi::FromInt(num)); | |
| 4330 } | |
| 4331 | |
| 4332 void SetNumberOfElements(int num) { | |
| 4333 set(kNumberOfElementsIndex, Smi::FromInt(num)); | |
| 4334 } | |
| 4335 | |
| 4336 void SetNumberOfDeletedElements(int num) { | |
| 4337 set(kNumberOfDeletedElementsIndex, Smi::FromInt(num)); | |
| 4338 } | |
| 4339 | |
| 4340 int Capacity() { | |
| 4341 return NumberOfBuckets() * kLoadFactor; | |
| 4342 } | |
| 4343 | |
| 4344 Object* KeyAt(int entry) { return get(EntryToIndex(entry)); } | |
| 4345 | |
| 4346 // Returns the next entry for the given entry. | |
| 4347 int ChainAt(int entry) { | |
| 4348 return Smi::cast(get(EntryToIndex(entry) + kChainOffset))->value(); | |
| 4349 } | |
| 4350 | |
| 4351 int HashToBucket(int hash) { | |
| 4352 return hash & (NumberOfBuckets() - 1); | |
| 4353 } | |
| 4354 | |
| 4355 int HashToEntry(int hash) { | |
| 4356 int bucket = HashToBucket(hash); | |
| 4357 return Smi::cast(get(kHashTableStartIndex + bucket))->value(); | |
| 4358 } | |
| 4359 | |
| 4360 static const int kNumberOfBucketsIndex = 0; | |
| 4361 static const int kNumberOfElementsIndex = kNumberOfBucketsIndex + 1; | |
| 4362 static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1; | |
| 4363 static const int kHashTableStartIndex = kNumberOfDeletedElementsIndex + 1; | |
| 4364 | |
| 4365 static const int kEntrySize = entrysize + 1; | |
| 4366 static const int kChainOffset = entrysize; | |
| 4367 | |
| 4368 static const int kLoadFactor = 2; | |
| 4369 static const int kMaxCapacity = | |
| 4370 (FixedArray::kMaxLength - kHashTableStartIndex) | |
| 4371 / (1 + (kEntrySize * kLoadFactor)); | |
| 4372 }; | |
| 4373 | |
| 4374 | |
| 4375 class OrderedHashSet: public OrderedHashTable<OrderedHashSet, 1> { | |
| 4376 public: | |
| 4377 static OrderedHashSet* cast(Object* obj) { | |
| 4378 ASSERT(obj->IsFixedArray()); // TODO(adamk): Make a map for this | |
| 4379 return reinterpret_cast<OrderedHashSet*>(obj); | |
| 4380 } | |
| 4381 | |
| 4382 bool Contains(Object* key); | |
| 4383 static Handle<OrderedHashSet> Add( | |
| 4384 Handle<OrderedHashSet> table, Handle<Object> key); | |
| 4385 static Handle<OrderedHashSet> Remove( | |
| 4386 Handle<OrderedHashSet> table, Handle<Object> key); | |
| 4387 }; | |
| 4388 | |
| 4389 | |
| 4390 class OrderedHashMap: public OrderedHashTable<OrderedHashMap, 2> { | |
| 4391 public: | |
| 4392 static OrderedHashMap* cast(Object* obj) { | |
| 4393 ASSERT(obj->IsFixedArray()); // TODO(adamk): Make a map for this | |
| 4394 return reinterpret_cast<OrderedHashMap*>(obj); | |
| 4395 } | |
| 4396 | |
| 4397 Object* Lookup(Object* key); | |
| 4398 static Handle<OrderedHashMap> Put( | |
| 4399 Handle<OrderedHashMap> table, | |
| 4400 Handle<Object> key, | |
| 4401 Handle<Object> value); | |
| 4402 | |
| 4403 private: | |
| 4404 Object* ValueAt(int entry) { | |
| 4405 return get(EntryToIndex(entry) + kValueOffset); | |
| 4406 } | |
| 4407 | |
| 4408 static const int kValueOffset = 1; | |
| 4409 }; | |
| 4410 | |
| 4411 | |
| 4252 template <int entrysize> | 4412 template <int entrysize> |
| 4253 class WeakHashTableShape : public BaseShape<Object*> { | 4413 class WeakHashTableShape : public BaseShape<Object*> { |
| 4254 public: | 4414 public: |
| 4255 static inline bool IsMatch(Object* key, Object* other); | 4415 static inline bool IsMatch(Object* key, Object* other); |
| 4256 static inline uint32_t Hash(Object* key); | 4416 static inline uint32_t Hash(Object* key); |
| 4257 static inline uint32_t HashForObject(Object* key, Object* object); | 4417 static inline uint32_t HashForObject(Object* key, Object* object); |
| 4258 MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap, | 4418 MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap, |
| 4259 Object* key); | 4419 Object* key); |
| 4260 static const int kPrefixSize = 0; | 4420 static const int kPrefixSize = 0; |
| 4261 static const int kEntrySize = entrysize; | 4421 static const int kEntrySize = entrysize; |
| (...skipping 6524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10786 } else { | 10946 } else { |
| 10787 value &= ~(1 << bit_position); | 10947 value &= ~(1 << bit_position); |
| 10788 } | 10948 } |
| 10789 return value; | 10949 return value; |
| 10790 } | 10950 } |
| 10791 }; | 10951 }; |
| 10792 | 10952 |
| 10793 } } // namespace v8::internal | 10953 } } // namespace v8::internal |
| 10794 | 10954 |
| 10795 #endif // V8_OBJECTS_H_ | 10955 #endif // V8_OBJECTS_H_ |
| OLD | NEW |