Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(356)

Side by Side Diff: src/objects.h

Issue 220293002: OrderedHashTable implementation with Set and Map interfaces (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Patch for landing Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/factory.cc ('k') | src/objects.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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_
OLDNEW
« no previous file with comments | « src/factory.cc ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698